diff options
author | Araq <rumpf_a@web.de> | 2015-02-07 01:06:25 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-02-07 10:48:07 +0100 |
commit | 74c6c8c903a2eb497ee74aaf9ba741b1abf40c88 (patch) | |
tree | 2f00cd5952852fc3c08867859ecc70b0b2c5ae38 /compiler | |
parent | e84834db79854c6ccc89263ec20d3749b8a87a05 (diff) | |
download | Nim-74c6c8c903a2eb497ee74aaf9ba741b1abf40c88.tar.gz |
compiler distinguishes between 2 different 'var' types for C++ interop; code cleanups
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 9 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 9 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 38 | ||||
-rw-r--r-- | compiler/cgen.nim | 89 | ||||
-rw-r--r-- | compiler/semexprs.nim | 1 |
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 |