summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-02-07 01:06:25 +0100
committerAraq <rumpf_a@web.de>2015-02-07 10:48:07 +0100
commit74c6c8c903a2eb497ee74aaf9ba741b1abf40c88 (patch)
tree2f00cd5952852fc3c08867859ecc70b0b2c5ae38 /compiler
parente84834db79854c6ccc89263ec20d3749b8a87a05 (diff)
downloadNim-74c6c8c903a2eb497ee74aaf9ba741b1abf40c88.tar.gz
compiler distinguishes between 2 different 'var' types for C++ interop; code cleanups
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim9
-rw-r--r--compiler/ccgexprs.nim9
-rw-r--r--compiler/ccgtypes.nim38
-rw-r--r--compiler/cgen.nim89
-rw-r--r--compiler/semexprs.nim1
5 files changed, 44 insertions, 102 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index f7c1a07ed..1a5ae8aab 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -459,7 +459,7 @@ type
     
     tfNeedsInit,      # type constains a "not nil" constraint somewhere or some
                       # other type so that it requires inititalization
-    tfHasShared,      # type constains a "shared" constraint modifier somewhere
+    tfVarIsPtr,       # 'var' type is translated like 'ptr' even in C++ mode
     tfHasMeta,        # type contains "wildcard" sub-types such as generic params
                       # or other type classes
     tfHasGCedMem,     # type contains GC'ed memory
@@ -522,7 +522,7 @@ const
   skError* = skUnknown
   
   # type flags that are essential for type equality:
-  eqTypeFlags* = {tfIterator, tfShared, tfNotNil}
+  eqTypeFlags* = {tfIterator, tfShared, tfNotNil, tfVarIsPtr}
 
 type
   TMagic* = enum # symbols that require compiler magic:
@@ -1348,7 +1348,7 @@ proc isGCedMem*(t: PType): bool {.inline.} =
 
 proc propagateToOwner*(owner, elem: PType) =
   const HaveTheirOwnEmpty = {tySequence, tySet}
-  owner.flags = owner.flags + (elem.flags * {tfHasShared, tfHasMeta})
+  owner.flags = owner.flags + (elem.flags * {tfHasMeta})
   if tfNotNil in elem.flags:
     if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvokation}:
       owner.flags.incl tfNotNil
@@ -1359,9 +1359,6 @@ proc propagateToOwner*(owner, elem: PType) =
     if owner.kind in HaveTheirOwnEmpty: discard
     else: owner.flags.incl tfNeedsInit
     
-  if tfShared in elem.flags:
-    owner.flags.incl tfHasShared
-
   if elem.isMetaType:
     owner.flags.incl tfHasMeta
 
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 591dd96ec..32678d472 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -664,7 +664,8 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
 
 proc isCppRef(p: BProc; typ: PType): bool {.inline.} =
   result = p.module.compileToCpp and
-      skipTypes(typ, abstractInst).kind == tyVar
+      skipTypes(typ, abstractInst).kind == tyVar and
+      tfVarIsPtr notin skipTypes(typ, abstractInst).flags
 
 proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
   let mt = mapType(e.sons[0].typ)
@@ -677,12 +678,14 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
   else:
     var a: TLoc
     initLocExprSingleUse(p, e.sons[0], a)
-    case skipTypes(a.t, abstractInst).kind
+    let typ = skipTypes(a.t, abstractInst)
+    case typ.kind
     of tyRef:
       d.s = OnHeap
     of tyVar:
       d.s = OnUnknown
-      if p.module.compileToCpp and e.kind == nkHiddenDeref:
+      if tfVarIsPtr notin typ.flags and p.module.compileToCpp and
+          e.kind == nkHiddenDeref:
         putIntoDest(p, d, e.typ, rdLoc(a))
         return
     of tyPtr:
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index ce17da17e..0220d2066 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -27,17 +27,7 @@ proc isKeyword(w: PIdent): bool =
 
 proc mangleName(s: PSym): PRope = 
   result = s.loc.r
-  if result == nil: 
-    if gCmd == cmdCompileToLLVM: 
-      case s.kind
-      of skProc, skMethod, skConverter, skConst, skIterators:
-        result = ~"@"
-      of skVar, skForVar, skResult, skLet: 
-        if sfGlobal in s.flags: result = ~"@"
-        else: result = ~"%"
-      of skTemp, skParam, skType, skEnumField, skModule: 
-        result = ~"%"
-      else: internalError(s.info, "mangleName")
+  if result == nil:
     when oKeepVariableNames:
       let keepOrigName = s.kind in skLocalVars - {skForVar} and 
         {sfFromGeneric, sfGlobal, sfShadowed, sfGenSym} * s.flags == {} and
@@ -103,13 +93,11 @@ proc typeName(typ: PType): PRope =
            else: ~"TY"
 
 proc getTypeName(typ: PType): PRope = 
-  if (typ.sym != nil) and ({sfImportc, sfExportc} * typ.sym.flags != {}) and
-      (gCmd != cmdCompileToLLVM): 
+  if typ.sym != nil and {sfImportc, sfExportc} * typ.sym.flags != {}:
     result = typ.sym.loc.r
   else:
     if typ.loc.r == nil:
-      typ.loc.r = if gCmd != cmdCompileToLLVM: con(typ.typeName, typ.id.toRope)
-                  else: con([~"%", typ.typeName, typ.id.toRope])
+      typ.loc.r = con(typ.typeName, typ.id.toRope)
     result = typ.loc.r
   if result == nil: internalError("getTypeName: " & $typ.kind)
   
@@ -200,9 +188,6 @@ const
     "N_SYSCALL", # this is probably not correct for all platforms,
                  # but one can #define it to what one wants 
     "N_INLINE", "N_NOINLINE", "N_FASTCALL", "N_CLOSURE", "N_NOCONV"]
-  CallingConvToStrLLVM: array[TCallingConvention, string] = ["fastcc $1", 
-    "stdcall $1", "ccc $1", "safecall $1", "syscall $1", "$1 alwaysinline", 
-    "$1 noinline", "fastcc $1", "ccc $1", "$1"]
 
 proc cacheGetType(tab: TIdTable, key: PType): PRope = 
   # returns nil if we need to declare this type
@@ -284,23 +269,23 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
       # this fixes the 'sort' bug:
       if param.typ.kind == tyVar: param.loc.s = OnUnknown
       # need to pass hidden parameter:
-      appff(params, ", NI $1Len$2", ", @NI $1Len$2", [param.loc.r, j.toRope])
+      appf(params, ", NI $1Len$2", [param.loc.r, j.toRope])
       inc(j)
       arr = arr.sons[0]
-  if (t.sons[0] != nil) and isInvalidReturnType(t.sons[0]): 
+  if (t.sons[0] != nil) and isInvalidReturnType(t.sons[0]):
     var arr = t.sons[0]
     if params != nil: app(params, ", ")
     app(params, getTypeDescAux(m, arr, check))
-    if (mapReturnType(t.sons[0]) != ctArray) or (gCmd == cmdCompileToLLVM): 
+    if (mapReturnType(t.sons[0]) != ctArray):
       app(params, "*")
-    appff(params, " Result", " @Result", [])
+    appf(params, " Result", [])
   if t.callConv == ccClosure and declareEnvironment: 
     if params != nil: app(params, ", ")
     app(params, "void* ClEnv")
   if tfVarargs in t.flags: 
     if params != nil: app(params, ", ")
     app(params, "...")
-  if params == nil and gCmd != cmdCompileToLLVM: app(params, "void)")
+  if params == nil: app(params, "void)")
   else: app(params, ")")
   params = con("(", params)
 
@@ -505,8 +490,9 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
     # but determining when this needs to be done is hard. We should split
     # C type generation into an analysis and a code generation phase somehow.
   case t.kind
-  of tyRef, tyPtr, tyVar: 
-    var star = if t.kind == tyVar and compileToCpp(m): "&" else: "*"
+  of tyRef, tyPtr, tyVar:
+    var star = if t.kind == tyVar and tfVarIsPtr notin typ.flags and
+                    compileToCpp(m): "&" else: "*"
     var et = t.lastSon
     var etB = et.skipTypes(abstractInst)
     if etB.kind in {tyArrayConstr, tyArray, tyOpenArray, tyVarargs}: 
@@ -678,7 +664,7 @@ proc genProcHeader(m: BModule, prc: PSym): PRope =
     rettype, params: PRope
   genCLineDir(result, prc.info)
   # using static is needed for inline procs
-  if gCmd != cmdCompileToLLVM and lfExportLib in prc.loc.flags:
+  if lfExportLib in prc.loc.flags:
     if m.isHeaderFile:
       result.app "N_LIB_IMPORT "
     else:
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 676805958..a606cb5b9 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -25,15 +25,6 @@ when options.hasTinyCBackend:
 var
   generatedHeader: BModule
 
-proc ropeff(cformat, llvmformat: string, args: varargs[PRope]): PRope = 
-  if gCmd == cmdCompileToLLVM: result = ropef(llvmformat, args)
-  else: result = ropef(cformat, args)
-  
-proc appff(dest: var PRope, cformat, llvmformat: string, 
-           args: varargs[PRope]) = 
-  if gCmd == cmdCompileToLLVM: appf(dest, llvmformat, args)
-  else: appf(dest, cformat, args)
-  
 proc addForwardedProc(m: BModule, prc: PSym) = 
   m.forwardedProcs.add(prc)
   inc(gForwardedProcsCounter)
@@ -186,8 +177,8 @@ proc safeLineNm(info: TLineInfo): int =
 proc genCLineDir(r: var PRope, filename: string, line: int) =
   assert line >= 0
   if optLineDir in gOptions:
-    appff(r, "$N#line $2 $1$N", "; line $2 \"$1\"$n",
-          [toRope(makeSingleLineCString(filename)), toRope(line)])
+    appf(r, "$N#line $2 $1$N",
+        [toRope(makeSingleLineCString(filename)), toRope(line)])
 
 proc genCLineDir(r: var PRope, info: TLineInfo) = 
   genCLineDir(r, info.toFullPath, info.safeLineNm)
@@ -362,29 +353,6 @@ proc deinitGCFrame(p: BProc): PRope =
   if p.gcFrameId > 0:
     result = ropecg(p.module,
                     "if (((NU)&GCFRAME) < 4096) #nimGCFrame(&GCFRAME);$n")
-
-proc cstringLit(p: BProc, r: var PRope, s: string): PRope = 
-  if gCmd == cmdCompileToLLVM: 
-    inc(p.module.labels)
-    inc(p.labels)
-    result = ropef("%LOC$1", [toRope(p.labels)])
-    appf(p.module.s[cfsData], "@C$1 = private constant [$2 x i8] $3$n", 
-         [toRope(p.module.labels), toRope(len(s)), makeLLVMString(s)])
-    appf(r, "$1 = getelementptr [$2 x i8]* @C$3, %NI 0, %NI 0$n", 
-         [result, toRope(len(s)), toRope(p.module.labels)])
-  else: 
-    result = makeCString(s)
-  
-proc cstringLit(m: BModule, r: var PRope, s: string): PRope = 
-  if gCmd == cmdCompileToLLVM: 
-    inc(m.labels, 2)
-    result = ropef("%MOC$1", [toRope(m.labels - 1)])
-    appf(m.s[cfsData], "@MOC$1 = private constant [$2 x i8] $3$n", 
-         [toRope(m.labels), toRope(len(s)), makeLLVMString(s)])
-    appf(r, "$1 = getelementptr [$2 x i8]* @MOC$3, %NI 0, %NI 0$n", 
-         [result, toRope(len(s)), toRope(m.labels)])
-  else: 
-    result = makeCString(s)
   
 proc allocParam(p: BProc, s: PSym) = 
   assert(s.kind == skParam)
@@ -426,7 +394,7 @@ proc localVarDecl(p: BProc; s: PSym): PRope =
     result = ropef(s.cgDeclFrmt, result, s.loc.r)
 
 proc assignLocalVar(p: BProc, s: PSym) =
-  #assert(s.loc.k == locNone) // not yet assigned
+  #assert(s.loc.k == locNone) # not yet assigned
   # this need not be fullfilled for inline procs; they are regenerated
   # for each module that uses them!
   let decl = localVarDecl(p, s).con(";" & tnl)
@@ -472,13 +440,11 @@ proc assignGlobalVar(p: BProc, s: PSym) =
                                {optStackTrace, optEndb}: 
     appcg(p.module, p.module.s[cfsDebugInit], 
           "#dbgRegisterGlobal($1, &$2, $3);$n", 
-         [cstringLit(p, p.module.s[cfsDebugInit], 
-          normalize(s.owner.name.s & '.' & s.name.s)), 
+         [makeCString(normalize(s.owner.name.s & '.' & s.name.s)), 
           s.loc.r, genTypeInfo(p.module, s.typ)])
   
 proc assignParam(p: BProc, s: PSym) = 
   assert(s.loc.r != nil)
-  if sfAddrTaken in s.flags and gCmd == cmdCompileToLLVM: allocParam(p, s)
   localDebugInfo(p, s)
 
 proc fillProcLoc(sym: PSym) = 
@@ -572,7 +538,6 @@ proc symInDynamicLib(m: BModule, sym: PSym) =
   let isCall = isGetProcAddr(lib)
   var extname = sym.loc.r
   if not isCall: loadDynamicLib(m, lib)
-  if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
   var tmp = mangleDynLibProc(sym)
   sym.loc.r = tmp             # from now on we only need the internal name
   sym.typ.sym = nil           # generate a new name
@@ -588,7 +553,7 @@ proc symInDynamicLib(m: BModule, sym: PSym) =
       params.app(", ")
     let load = ropef("\t$1 = ($2) ($3$4));$n",
         [tmp, getTypeDesc(m, sym.typ),
-        params, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))])
+        params, makeCString(ropeToStr(extname))])
     var last = lastSon(n)
     if last.kind == nkHiddenStdConv: last = last.sons[1]
     internalAssert(last.kind == nkStrLit)
@@ -603,10 +568,8 @@ proc symInDynamicLib(m: BModule, sym: PSym) =
     appcg(m, m.s[cfsDynLibInit], 
         "\t$1 = ($2) #nimGetProcAddr($3, $4);$n", 
         [tmp, getTypeDesc(m, sym.typ), 
-        lib.name, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))])
-  appff(m.s[cfsVars], "$2 $1;$n", 
-      "$1 = linkonce global $2 zeroinitializer$n", 
-      [sym.loc.r, getTypeDesc(m, sym.loc.t)])
+        lib.name, makeCString(ropeToStr(extname))])
+  appf(m.s[cfsVars], "$2 $1;$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)])
 
 proc varInDynamicLib(m: BModule, sym: PSym) = 
   var lib = sym.annex
@@ -619,7 +582,7 @@ proc varInDynamicLib(m: BModule, sym: PSym) =
   appcg(m, m.s[cfsDynLibInit], 
       "$1 = ($2*) #nimGetProcAddr($3, $4);$n", 
       [tmp, getTypeDesc(m, sym.typ), 
-      lib.name, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))])
+      lib.name, makeCString(ropeToStr(extname))])
   appf(m.s[cfsVars], "$2* $1;$n",
       [sym.loc.r, getTypeDesc(m, sym.loc.t)])
 
@@ -721,11 +684,11 @@ proc genProcAux(m: BModule, prc: PSym) =
     app(generatedProc, initGCFrame(p))
     if optStackTrace in prc.options: 
       app(generatedProc, p.s(cpsLocals))
-      var procname = cstringLit(p, generatedProc, prc.name.s)
+      var procname = makeCString(prc.name.s)
       app(generatedProc, initFrame(p, procname, prc.info.quotedFilename))
     else: 
       app(generatedProc, p.s(cpsLocals))
-    if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM):
+    if optProfiler in prc.options:
       # invoke at proc entry for recursion:
       appcg(p, cpsInit, "\t#nimProfile();$n", [])
     if p.beforeRetNeeded: app(generatedProc, "{")
@@ -751,7 +714,6 @@ proc genProcPrototype(m: BModule, sym: PSym) =
         not containsOrIncl(m.declaredThings, sym.id): 
       app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n",
                         getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
-      if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
   elif not containsOrIncl(m.declaredProtos, sym.id):
     var header = genProcHeader(m, sym)
     if sym.typ.callConv != ccInline and crossesCppBoundary(m, sym):
@@ -849,21 +811,17 @@ proc addIntTypes(result: var PRope) {.inline.} =
 
 proc getCopyright(cfile: string): PRope =
   if optCompileOnly in gGlobalOptions:
-    result = ropeff("/* Generated by Nim Compiler v$1 */$N" &
+    result = ropef("/* Generated by Nim Compiler v$1 */$N" &
         "/*   (c) 2015 Andreas Rumpf */$N" &
         "/* The generated code is subject to the original license. */$N",
-        "; Generated by Nim Compiler v$1$N" &
-        ";   (c) 2012 Andreas Rumpf$N", [toRope(VersionAsString)])
+        [toRope(VersionAsString)])
   else:
-    result = ropeff("/* Generated by Nim Compiler v$1 */$N" &
+    result = ropef("/* Generated by Nim Compiler v$1 */$N" &
         "/*   (c) 2015 Andreas Rumpf */$N" &
         "/* The generated code is subject to the original license. */$N" &
         "/* Compiled for: $2, $3, $4 */$N" &
         "/* Command for C compiler:$n   $5 */$N",
-        "; Generated by Nim Compiler v$1$N" &
-        ";   (c) 2015 Andreas Rumpf$N" &
-        "; Compiled for: $2, $3, $4$N" &
-        "; Command for LLVM compiler:$N   $5$N", [toRope(VersionAsString),
+        [toRope(VersionAsString),
         toRope(platform.OS[targetOS].name),
         toRope(platform.CPU[targetCPU].name),
         toRope(extccomp.CC[extccomp.cCompiler].name),
@@ -1014,13 +972,11 @@ proc registerModuleToMain(m: PSym) =
   var
     init = m.getInitName
     datInit = m.getDatInitName
-  appff(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N",
-                      "declare void $1() noinline$N", [init])
-  appff(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N",
-                      "declare void $1() noinline$N", [datInit])
+  appf(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N", [init])
+  appf(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N", [datInit])
   if sfSystemModule notin m.flags:
-    appff(mainDatInit, "\t$1();$N", "call void ()* $1$n", [datInit])
-    let initCall = ropeff("\t$1();$N", "call void ()* $1$n", [init])
+    appf(mainDatInit, "\t$1();$N", [datInit])
+    let initCall = ropef("\t$1();$N", [init])
     if sfMainModule in m.flags:
       app(mainModInit, initCall)
     else:
@@ -1028,8 +984,7 @@ proc registerModuleToMain(m: PSym) =
     
 proc genInitCode(m: BModule) = 
   var initname = getInitName(m.module)
-  var prc = ropeff("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N", 
-                   "define void $1() noinline {$n", [initname])
+  var prc = ropef("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N", [initname])
   if m.typeNodes > 0: 
     appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n", 
           [m.typeNodesName, toRope(m.typeNodes)])
@@ -1050,7 +1005,7 @@ proc genInitCode(m: BModule) =
     # declare it nevertheless:
     m.frameDeclared = true
     if not m.preventStackTrace:
-      var procname = cstringLit(m.initProc, prc, m.module.name.s)
+      var procname = makeCString(m.module.name.s)
       app(prc, initFrame(m.initProc, procname, m.module.info.quotedFilename))
     else:
       app(prc, ~"\tTFrame F; F.len = 0;$N")
@@ -1071,8 +1026,8 @@ proc genInitCode(m: BModule) =
   app(prc, deinitGCFrame(m.initProc))
   appf(prc, "}$N$N")
 
-  prc.appff("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
-            "define void $1() noinline {$n", [getDatInitName(m.module)])
+  prc.appf("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
+           [getDatInitName(m.module)])
 
   for i in cfsTypeInit1..cfsDynLibInit:
     app(prc, genSectionStart(i))
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 5761e9e88..26ca54239 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1209,6 +1209,7 @@ proc asgnToResultVar(c: PContext, n, le, ri: PNode) {.inline.} =
     if x.typ.kind == tyVar and x.kind == nkSym and x.sym.kind == skResult:
       n.sons[0] = x # 'result[]' --> 'result'
       n.sons[1] = takeImplicitAddr(c, ri)
+      x.typ.flags.incl tfVarIsPtr
 
 template resultTypeIsInferrable(typ: PType): expr =
   typ.isMetaType and typ.kind != tyTypeDesc