diff options
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ast.nim | 17 | ||||
-rwxr-xr-x | compiler/c2nim/c2nim.nim | 3 | ||||
-rwxr-xr-x | compiler/c2nim/cparse.nim | 8 | ||||
-rwxr-xr-x | compiler/c2nim/tests/systest.c | 2 | ||||
-rw-r--r-- | compiler/ccgcalls.nim | 6 | ||||
-rwxr-xr-x | compiler/cgen.nim | 58 | ||||
-rw-r--r-- | compiler/cgendata.nim | 2 | ||||
-rwxr-xr-x | compiler/commands.nim | 2 | ||||
-rwxr-xr-x | compiler/extccomp.nim | 35 | ||||
-rwxr-xr-x | compiler/lookups.nim | 7 | ||||
-rwxr-xr-x | compiler/msgs.nim | 6 | ||||
-rwxr-xr-x | compiler/nimrod.nim | 12 | ||||
-rwxr-xr-x | compiler/parser.nim | 24 | ||||
-rwxr-xr-x | compiler/pragmas.nim | 3 | ||||
-rwxr-xr-x | compiler/semgnrc.nim | 20 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 8 | ||||
-rwxr-xr-x | compiler/semtypes.nim | 6 | ||||
-rwxr-xr-x | compiler/sigmatch.nim | 3 | ||||
-rwxr-xr-x | compiler/suggest.nim | 27 | ||||
-rwxr-xr-x | compiler/types.nim | 2 |
20 files changed, 153 insertions, 98 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 419d57562..aafd52098 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -273,6 +273,7 @@ type const tyPureObject* = tyTuple + GcTypeKinds* = {tyRef, tySequence, tyString} type TTypeKinds* = set[TTypeKind] @@ -771,6 +772,14 @@ proc NewType(kind: TTypeKind, owner: PSym): PType = #if result.id < 2000 then # MessageOut(typeKindToStr[kind] & ' has id: ' & toString(result.id)) +proc mergeLoc(a: var TLoc, b: TLoc) = + if a.k == low(a.k): a.k = b.k + if a.s == low(a.s): a.s = b.s + a.flags = a.flags + b.flags + if a.t == nil: a.t = b.t + if a.r == nil: a.r = b.r + if a.a == 0: a.a = b.a + proc assignType(dest, src: PType) = dest.kind = src.kind dest.flags = src.flags @@ -779,6 +788,14 @@ proc assignType(dest, src: PType) = dest.size = src.size dest.align = src.align dest.containerID = src.containerID + # this fixes 'type TLock = TSysLock': + if src.sym != nil: + if dest.sym != nil: + dest.sym.flags = dest.sym.flags + src.sym.flags + if dest.sym.annex == nil: dest.sym.annex = src.sym.annex + mergeLoc(dest.sym.loc, src.sym.loc) + else: + dest.sym = src.sym newSons(dest, sonsLen(src)) for i in countup(0, sonsLen(src) - 1): dest.sons[i] = src.sons[i] diff --git a/compiler/c2nim/c2nim.nim b/compiler/c2nim/c2nim.nim index 6d7a0d6c1..e408467ef 100755 --- a/compiler/c2nim/c2nim.nim +++ b/compiler/c2nim/c2nim.nim @@ -44,7 +44,8 @@ proc main(infile, outfile: string, options: PParserOptions) = var module = parseUnit(p) closeParser(p) renderModule(module, outfile) - rawMessage(hintSuccessX, [$gLinesCompiled, $(getTime() - start)]) + rawMessage(hintSuccessX, [$gLinesCompiled, $(getTime() - start), + formatSize(getTotalMem())]) var infile = "" diff --git a/compiler/c2nim/cparse.nim b/compiler/c2nim/cparse.nim index f8f58347d..ad583b92b 100755 --- a/compiler/c2nim/cparse.nim +++ b/compiler/c2nim/cparse.nim @@ -94,7 +94,7 @@ proc OpenParser(p: var TParser, filename: string, new(p.tok) proc parMessage(p: TParser, msg: TMsgKind, arg = "") = - #assert false + assert false lexMessage(p.lex, msg, arg) proc CloseParser(p: var TParser) = CloseLexer(p.lex) @@ -930,10 +930,8 @@ proc declaration(p: var TParser): PNode = parMessage(p, errTokenExpected, ";") if sonsLen(result.sons[pragmasPos]) == 0: result.sons[pragmasPos] = ast.emptyNode - of pxAsgn, pxSemicolon, pxComma: - result = parseVarDecl(p, baseTyp, rettyp, origName) else: - parMessage(p, errTokenExpected, ";") + result = parseVarDecl(p, baseTyp, rettyp, origName) assert result != nil proc createConst(name, typ, val: PNode, p: TParser): PNode = @@ -1594,7 +1592,7 @@ proc parseSwitch(p: var TParser): PNode = eat(p, pxCurlyRi) proc addStmt(sl, a: PNode) = - # merge type sections is possible: + # merge type sections if possible: if a.kind != nkTypeSection or sonsLen(sl) == 0 or lastSon(sl).kind != nkTypeSection: addSon(sl, a) diff --git a/compiler/c2nim/tests/systest.c b/compiler/c2nim/tests/systest.c index d1fbb6784..389fdfdc2 100755 --- a/compiler/c2nim/tests/systest.c +++ b/compiler/c2nim/tests/systest.c @@ -351,7 +351,7 @@ HWBType; static HWBType * RGB_to_HWB (RGBType RGB, HWBType * HWB) { - + HWBType* myArray[20]; /* * RGB are each on [0, 1]. W and B are returned on [0, 1] and H is * returned on [0, 6]. Exception: H is returned UNDEFINED if W == 1 - B. diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index b28765f8f..3ea539389 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -252,7 +252,8 @@ proc genCall(p: BProc, e: PNode, d: var TLoc) = genNamedParamCall(p, e, d) else: genPrefixCall(p, nil, e, d) - if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d) + when false: + if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d) proc genAsgnCall(p: BProc, le, ri: PNode, d: var TLoc) = if ri.sons[0].kind == nkSym and sfInfixCall in ri.sons[0].sym.flags and @@ -262,5 +263,6 @@ proc genAsgnCall(p: BProc, le, ri: PNode, d: var TLoc) = genNamedParamCall(p, ri, d) else: genPrefixCall(p, le, ri, d) - if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d) + when false: + if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 16210c026..7dfc259ef 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -297,23 +297,36 @@ proc getTemp(p: BProc, t: PType, result: var TLoc) = initTemp(p, result) proc keepAlive(p: BProc, toKeepAlive: TLoc) = - if optRefcGC notin gGlobalOptions: return - var result: TLoc - inc(p.labels) - result.r = con("LOC", toRope(p.labels)) - appf(p.s[cpsLocals], "volatile $1 $2;$n", - [getTypeDesc(p.module, toKeepAlive.t), result.r]) - result.k = locTemp - result.a = -1 - result.t = toKeepAlive.t - result.s = OnStack - result.flags = {} - if skipTypes(toKeepAlive.t, abstractVarRange).Kind notin complexValueType: - appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(result), rdLoc(toKeepAlive)]) - else: - appcg(p, cpsStmts, - "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", - [addrLoc(result), addrLoc(toKeepAlive), rdLoc(result)]) + when false: + # deactivated because of the huge slowdown this causes; GC will take care + # of interior pointers instead + if optRefcGC notin gGlobalOptions: return + var result: TLoc + var fid = toRope(p.gcFrameId) + result.r = con("GCFRAME.F", fid) + appf(p.gcFrameType, " $1 F$2;$n", + [getTypeDesc(p.module, toKeepAlive.t), fid]) + inc(p.gcFrameId) + result.k = locTemp + result.a = -1 + result.t = toKeepAlive.t + result.s = OnStack + result.flags = {} + + if skipTypes(toKeepAlive.t, abstractVarRange).Kind notin complexValueType: + appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(result), rdLoc(toKeepAlive)]) + else: + appcg(p, cpsStmts, + "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", + [addrLoc(result), addrLoc(toKeepAlive), rdLoc(result)]) + +proc initGCFrame(p: BProc): PRope = + if p.gcFrameId > 0: result = ropef("struct {$1} GCFRAME;$n", p.gcFrameType) + +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: @@ -370,6 +383,8 @@ proc assignLocalVar(p: BProc, s: PSym) = if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy) app(p.s[cpsLocals], getTypeDesc(p.module, s.loc.t)) if sfRegister in s.flags: app(p.s[cpsLocals], " register") + elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds: + app(p.s[cpsLocals], " GC_GUARD") if (sfVolatile in s.flags) or (p.nestedTryStmts.len > 0): app(p.s[cpsLocals], " volatile") appf(p.s[cpsLocals], " $1;$n", [s.loc.r]) @@ -428,7 +443,7 @@ include "ccgexprs.nim", "ccgstmts.nim" proc libCandidates(s: string, dest: var TStringSeq) = var le = strutils.find(s, '(') var ri = strutils.find(s, ')', le+1) - if le >= 0 and ri > le: + if le >= 0 and ri > le: var prefix = substr(s, 0, le - 1) var suffix = substr(s, ri + 1) for middle in split(substr(s, le + 1, ri - 1), '|'): @@ -583,8 +598,9 @@ proc genProcAux(m: BModule, prc: PSym) = if sfPure in prc.flags: generatedProc = ropeff("$1 {$n$2$3$4}$n", "define $1 {$n$2$3$4}$n", [header, p.s[cpsLocals], p.s[cpsInit], p.s[cpsStmts]]) - else: + else: generatedProc = ropeff("$1 {$n", "define $1 {$n", [header]) + app(generatedProc, initGCFrame(p)) if optStackTrace in prc.options: getFrameDecl(p) app(generatedProc, p.s[cpsLocals]) @@ -608,6 +624,7 @@ proc genProcAux(m: BModule, prc: PSym) = app(generatedProc, p.s[cpsInit]) app(generatedProc, p.s[cpsStmts]) if p.beforeRetNeeded: appf(generatedProc, "BeforeRet: $n;") + app(generatedProc, deinitGCFrame(p)) if optStackTrace in prc.options: app(generatedProc, deinitFrame(p)) if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM): appf(generatedProc, @@ -816,6 +833,8 @@ proc genInitCode(m: BModule) = m.FrameDeclared = true getFrameDecl(m.initProc) + app(prc, initGCFrame(m.initProc)) + app(prc, genSectionStart(cpsLocals)) app(prc, m.initProc.s[cpsLocals]) app(prc, genSectionEnd(cpsLocals)) @@ -842,6 +861,7 @@ proc genInitCode(m: BModule) = if optStackTrace in m.initProc.options and not m.PreventStackTrace: app(prc, deinitFrame(m.initProc)) app(prc, genSectionEnd(cpsStmts)) + app(prc, deinitGCFrame(m.initProc)) appf(prc, "}$n$n") # we cannot simply add the init proc to ``m.s[cfsProcs]`` anymore because # that would lead to a *nesting* of merge sections which the merger does diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index 54e1f5d1a..ecbec664e 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -72,6 +72,8 @@ type receiveClosure*: PType # closure record type that we get module*: BModule # used to prevent excessive parameter passing withinLoop*: int # > 0 if we are within a loop + gcFrameId*: natural # for the GC stack marking + gcFrameType*: PRope # the struct {} we put the GC markers into TTypeSeq* = seq[PType] TCGen = object of TPassContext # represents a C source file diff --git a/compiler/commands.nim b/compiler/commands.nim index f07361abe..14b943327 100755 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -207,7 +207,7 @@ proc addPathRec(dir: string, info: TLineInfo) = proc track(arg: string, info: TLineInfo) = var a = arg.split(',') - if a.len != 3: LocalError(info, errTokenExpected, "FILE,LINE,COLMUN") + if a.len != 3: LocalError(info, errTokenExpected, "FILE,LINE,COLUMN") var line, column: int if parseUtils.parseInt(a[1], line) <= 0: LocalError(info, errInvalidNumber, a[1]) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index facb22432..b7548a4b5 100755 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -21,7 +21,8 @@ type hasSwitchRange, # CC allows ranges in switch statements (GNU C) hasComputedGoto, # CC has computed goto (GNU C extension) hasCpp, # CC is/contains a C++ compiler - hasAssume # CC has __assume (Visual C extension) + hasAssume, # CC has __assume (Visual C extension) + hasGcGuard # CC supports GC_GUARD to keep stack roots TInfoCCProps* = set[TInfoCCProp] TInfoCC* = tuple[ name: string, # the short name of the compiler @@ -71,7 +72,7 @@ compiler gcc: debug: "", pic: "-fPIC", asmStmtFrmt: "asm($1);$n", - props: {hasSwitchRange, hasComputedGoto, hasCpp}) + props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard}) compiler gpp: result = gcc() @@ -79,11 +80,10 @@ compiler gpp: result.name = "gpp" result.compilerExe = "g++" result.linkerExe = "g++" - - result.debug.add " -g " # XXX: Why is this default for g++, but not for gcc? - result.buildDll = " -mdll" # XXX: Hmm, I'm keeping this from the previos version, - # but my gcc doesn't even have such an option (is this mingw?) + result.buildDll = " -mdll" + # XXX: Hmm, I'm keeping this from the previos version, + # but my gcc doesn't even have such an option (is this mingw?) compiler llvmGcc: result = gcc() @@ -422,6 +422,13 @@ proc getOptSize(c: TSystemCC): string = if result == "": result = cc[c].optSize # use default settings from this file +proc noAbsolutePaths: bool {.inline.} = + # We used to check current OS != specified OS, but this makes no sense + # really: Cross compilation from Linux to Linux for example is entirely + # reasonable. + # `optGenMapping` is included here for niminst. + result = gGlobalOptions * {optGenScript, optGenMapping} != {} + const specialFileA = 42 specialFileB = 42 @@ -461,7 +468,7 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string = add(options, ' ' & cc[c].pic) var includeCmd, compilePattern: string - if targetOS == platform.hostOS: + if not noAbsolutePaths(): # compute include paths: includeCmd = cc[c].includeCmd & quoteIfContainsWhite(libpath) @@ -474,9 +481,8 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string = compilePattern = cc[c].compilerExe # XXX fix the grammar finally, we need multi-line if expressions: - var cfile = if targetOS == platform.hostOS: cfilename else: extractFileName( - cfilename) - var objfile = if not isExternal or targetOS != platform.hostOS: toObjFile( + var cfile = if noAbsolutePaths(): extractFileName(cfilename) else: cfilename + var objfile = if not isExternal or noAbsolutePaths(): toObjFile( cfile) else: completeCFilePath(toObjFile(cfile)) cfile = quoteIfContainsWhite(AddFileExt(cfile, cExt)) objfile = quoteIfContainsWhite(objfile) @@ -532,9 +538,10 @@ proc CallCCompiler*(projectfile: string) = var it = PStrEntry(toLink.head) var objfiles = "" while it != nil: + let objFile = if noAbsolutePaths(): it.data.extractFilename else: it.data add(objfiles, ' ') add(objfiles, quoteIfContainsWhite( - addFileExt(it.data, cc[ccompiler].objExt))) + addFileExt(objFile, cc[ccompiler].objExt))) it = PStrEntry(it.next) if optGenStaticLib in gGlobalOptions: @@ -545,18 +552,18 @@ proc CallCCompiler*(projectfile: string) = var linkerExe = getConfigVar(cc[c].name & ".linkerexe") if len(linkerExe) == 0: linkerExe = cc[c].linkerExe if targetOS == osWindows: linkerExe = addFileExt(linkerExe, "exe") - if platform.hostOS != targetOS: linkCmd = quoteIfContainsWhite(linkerExe) + if noAbsolutePaths(): linkCmd = quoteIfContainsWhite(linkerExe) else: linkCmd = quoteIfContainsWhite(JoinPath(ccompilerpath, linkerExe)) if optGenGuiApp in gGlobalOptions: buildGui = cc[c].buildGui else: buildGui = "" var exefile: string if optGenDynLib in gGlobalOptions: - exefile = platform.os[targetOS].dllFrmt % [splitFile(projectFile).name] + exefile = platform.os[targetOS].dllFrmt % splitFile(projectFile).name buildDll = cc[c].buildDll else: exefile = splitFile(projectFile).name & platform.os[targetOS].exeExt buildDll = "" - if targetOS == platform.hostOS: + if not noAbsolutePaths(): exefile = joinPath(splitFile(projectFile).dir, exefile) exefile = quoteIfContainsWhite(exefile) for linkedLib in items(cLinkedLibs): diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 61b8ead4c..b2ae0d843 100755 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -53,7 +53,7 @@ proc CloseScope*(tab: var TSymTab) = var it: TTabIter var s = InitTabIter(it, tab.stack[tab.tos-1]) while s != nil: - if sfForward in s.flags: + if sfForward in s.flags: LocalError(s.info, errImplOfXexpected, getSymRepr(s)) elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options: # BUGFIX: check options in s! @@ -68,7 +68,10 @@ proc AddSym*(t: var TStrTable, n: PSym) = proc addDecl*(c: PContext, sym: PSym) = if SymTabAddUnique(c.tab, sym) == Failure: LocalError(sym.info, errAttemptToRedefine, sym.Name.s) - + +proc addPrelimDecl*(c: PContext, sym: PSym) = + discard SymTabAddUnique(c.tab, sym) + proc addDeclAt*(c: PContext, sym: PSym, at: Natural) = if SymTabAddUniqueAt(c.tab, sym, at) == Failure: LocalError(sym.info, errAttemptToRedefine, sym.Name.s) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index ff153c1c2..50afd47f9 100755 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -92,7 +92,8 @@ type errCannotInterpretNodeX, errFieldXNotFound, errInvalidConversionFromTypeX, errAssertionFailed, errCannotGenerateCodeForX, errXRequiresOneArgument, errUnhandledExceptionX, errCyclicTree, errXisNoMacroOrTemplate, - errXhasSideEffects, errIteratorExpected, errLetNeedsInit, errWrongSymbolX, + errXhasSideEffects, errIteratorExpected, errLetNeedsInit, + errThreadvarCannotInit, errWrongSymbolX, errUser, warnCannotOpenFile, warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit, @@ -321,6 +322,7 @@ const errXhasSideEffects: "\'$1\' can have side effects", errIteratorExpected: "iterator within for loop context expected", errLetNeedsInit: "'let' symbol requires an initialization", + errThreadvarCannotInit: "a thread var cannot be initialized explicitly", errWrongSymbolX: "usage of \'$1\' is a user-defined error", errUser: "$1", warnCannotOpenFile: "cannot open \'$1\' [CannotOpenFile]", @@ -342,7 +344,7 @@ const warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]", warnUser: "$1 [User]", hintSuccess: "operation successful [Success]", - hintSuccessX: "operation successful ($1 lines compiled; $2 sec total) [SuccessX]", + hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#) [SuccessX]", hintLineTooLong: "line too long [LineTooLong]", hintXDeclaredButNotUsed: "\'$1\' is declared but not used [XDeclaredButNotUsed]", hintConvToBaseNotNeeded: "conversion to base object is not needed [ConvToBaseNotNeeded]", diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim index 24dbc0617..a6918ce63 100755 --- a/compiler/nimrod.nim +++ b/compiler/nimrod.nim @@ -61,9 +61,9 @@ proc prependCurDir(f: string): string = else: result = f -proc HandleCmdLine() = +proc HandleCmdLine() = var start = epochTime() - if paramCount() == 0: + if paramCount() == 0: writeCommandLineUsage() else: # Process command line arguments: @@ -85,13 +85,15 @@ proc HandleCmdLine() = ProcessCmdLine(passCmd2) MainCommand() if gVerbosity >= 2: echo(GC_getStatistics()) + #echo(GC_getStatistics()) if msgs.gErrorCounter == 0: when hasTinyCBackend: if gCmd == cmdRun: tccgen.run() - if gCmd notin {cmdInterpret, cmdRun}: - rawMessage(hintSuccessX, [$gLinesCompiled, - formatFloat(epochTime() - start, ffDecimal, 3)]) + if gCmd notin {cmdInterpret, cmdRun}: + rawMessage(hintSuccessX, [$gLinesCompiled, + formatFloat(epochTime() - start, ffDecimal, 3), + formatSize(getTotalMem())]) if optRun in gGlobalOptions: var ex = quoteIfContainsWhite( changeFileExt(gProjectFull, "").prependCurDir) diff --git a/compiler/parser.nim b/compiler/parser.nim index e3bf3a748..ab715f029 100755 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -263,15 +263,16 @@ proc exprList(p: var TParser, endTok: TTokType, result: PNode) = optInd(p, a) eat(p, endTok) +proc newDotExpr(p: var TParser, a: PNode): PNode = + getTok(p) + optInd(p, a) + result = newNodeI(nkDotExpr, a.info) + addSon(result, a) + addSon(result, parseSymbol(p)) + proc qualifiedIdent(p: var TParser): PNode = result = parseSymbol(p) #optInd(p, result); - if p.tok.tokType == tkDot: - getTok(p) - optInd(p, result) - var a = result - result = newNodeI(nkDotExpr, a.info) - addSon(result, a) - addSon(result, parseSymbol(p)) + if p.tok.tokType == tkDot: result = newDotExpr(p, result) proc qualifiedIdentListAux(p: var TParser, endTok: TTokType, result: PNode) = getTok(p) @@ -465,13 +466,8 @@ proc primary(p: var TParser): PNode = result = newNodeP(nkCall, p) addSon(result, a) exprColonEqExprListAux(p, nkExprEqExpr, tkParRi, tkEquals, result) - of tkDot: - var a = result - result = newNodeP(nkDotExpr, p) - addSon(result, a) - getTok(p) # skip '.' - optInd(p, result) - addSon(result, parseSymbol(p)) + of tkDot: + result = newDotExpr(p, result) result = parseGStrLit(p, result) of tkBracketLe: result = indexExprList(p, result, nkBracketExpr, tkBracketRi) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index a291d4741..9877d4c52 100755 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -147,9 +147,6 @@ proc processMagic(c: PContext, n: PNode, s: PSym) = s.magic = m break if s.magic == mNone: Message(n.info, warnUnknownMagic, v) - # magics don't need an implementation, so we - # treat them as imported, instead of modifing a lot of working code: - incl(s.flags, sfImportc) proc wordToCallConv(sw: TSpecialWord): TCallingConvention = # this assumes that the order of special words and calling conventions is diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index a81347eda..216b5674d 100755 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -144,13 +144,15 @@ proc semGenericStmt(c: PContext, n: PNode, var L = sonsLen(n) openScope(c.tab) n.sons[L - 2] = semGenericStmt(c, n.sons[L-2], flags, toBind) - for i in countup(0, L - 3): addDecl(c, newSymS(skUnknown, n.sons[i], c)) + for i in countup(0, L - 3): + addPrelimDecl(c, newSymS(skUnknown, n.sons[i], c)) n.sons[L - 1] = semGenericStmt(c, n.sons[L-1], flags, toBind) closeScope(c.tab) of nkBlockStmt, nkBlockExpr, nkBlockType: checkSonsLen(n, 2) openScope(c.tab) - if n.sons[0].kind != nkEmpty: addDecl(c, newSymS(skUnknown, n.sons[0], c)) + if n.sons[0].kind != nkEmpty: + addPrelimDecl(c, newSymS(skUnknown, n.sons[0], c)) n.sons[1] = semGenericStmt(c, n.sons[1], flags, toBind) closeScope(c.tab) of nkTryStmt: @@ -174,7 +176,7 @@ proc semGenericStmt(c: PContext, n: PNode, toBind) a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, toBind) for j in countup(0, L-3): - addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c)) + addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c)) of nkGenericParams: for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] @@ -185,14 +187,14 @@ proc semGenericStmt(c: PContext, n: PNode, toBind) # do not perform symbol lookup for default expressions for j in countup(0, L-3): - addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c)) + addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c)) of nkConstSection: for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue if (a.kind != nkConstDef): IllFormedAst(a) checkSonsLen(a, 3) - addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[0]), c)) + addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[0]), c)) a.sons[1] = semGenericStmt(c, a.sons[1], flags+{withinTypeDesc}, toBind) a.sons[2] = semGenericStmt(c, a.sons[2], flags, toBind) of nkTypeSection: @@ -201,7 +203,7 @@ proc semGenericStmt(c: PContext, n: PNode, if a.kind == nkCommentStmt: continue if (a.kind != nkTypeDef): IllFormedAst(a) checkSonsLen(a, 3) - addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[0]), c)) + addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[0]), c)) for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue @@ -240,17 +242,17 @@ proc semGenericStmt(c: PContext, n: PNode, toBind) a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, toBind) for j in countup(0, L-3): - addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c)) + addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c)) of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef, nkIteratorDef, nkLambda: checkSonsLen(n, bodyPos + 1) - addDecl(c, newSymS(skUnknown, getIdentNode(n.sons[0]), c)) + addPrelimDecl(c, newSymS(skUnknown, getIdentNode(n.sons[0]), c)) openScope(c.tab) n.sons[genericParamsPos] = semGenericStmt(c, n.sons[genericParamsPos], flags, toBind) if n.sons[paramsPos].kind != nkEmpty: if n.sons[paramsPos].sons[0].kind != nkEmpty: - addDecl(c, newSym(skUnknown, getIdent("result"), nil)) + addPrelimDecl(c, newSym(skUnknown, getIdent("result"), nil)) n.sons[paramsPos] = semGenericStmt(c, n.sons[paramsPos], flags, toBind) n.sons[pragmasPos] = semGenericStmt(c, n.sons[pragmasPos], flags, toBind) var body: PNode diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 29bf48c19..d8336fc94 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -269,7 +269,8 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = if def != nil and def.kind != nkEmpty: # this is only needed for the evaluation pass: v.ast = def - if a.kind != nkVarTuple: + if sfThread in v.flags: LocalError(def.info, errThreadvarCannotInit) + if a.kind != nkVarTuple: v.typ = typ b = newNodeI(nkIdentDefs, a.info) addSon(b, newSymNode(v)) @@ -733,7 +734,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, n.sons[bodyPos] = ast.emptyNode else: if proto != nil: LocalError(n.info, errImplOfXexpected, proto.name.s) - if {sfImportc, sfBorrow} * s.flags == {}: incl(s.flags, sfForward) + if {sfImportc, sfBorrow} * s.flags == {} and s.magic == mNone: + incl(s.flags, sfForward) elif sfBorrow in s.flags: semBorrow(c, n, s) sideEffectsCheck(c, s) closeScope(c.tab) # close scope for parameters @@ -800,7 +802,7 @@ proc evalInclude(c: PContext, n: PNode): PNode = var f = checkModuleName(n.sons[i]) var fileIndex = f.fileInfoIdx if ContainsOrIncl(c.includedFiles, fileIndex): - GlobalError(n.info, errRecursiveDependencyX, f) + GlobalError(n.info, errRecursiveDependencyX, f.shortenDir) addSon(result, semStmt(c, gIncludeFile(f))) Excl(c.includedFiles, fileIndex) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 78a95c56b..b71f230eb 100755 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -781,7 +781,11 @@ proc semGenericConstraints(c: PContext, n: PNode, result: PType) = semGenericConstraints(c, n.sons[1], result) semGenericConstraints(c, n.sons[2], result) else: - result.addSon(semTypeNode(c, n, nil)) + var x = semTypeNode(c, n, nil) + if x.kind in StructuralEquivTypes and sonsLen(x) == 0: + x = newConstraint(c, x.kind) + #echo "came here for: ", typeToString(x) + result.addSon(x) proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = result = copyNode(n) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index a6bde6e40..9a8f3cee1 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -388,7 +388,8 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = of tyGenericInst: result = typeRel(mapping, lastSon(f), a) of tyGenericBody: - result = typeRel(mapping, lastSon(f), a) + let ff = lastSon(f) + if ff != nil: result = typeRel(mapping, ff, a) of tyGenericInvokation: assert(f.sons[0].kind == tyGenericBody) if a.kind == tyGenericInvokation: diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 86d91bc1c..971ff4d32 100755 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -10,7 +10,8 @@ ## This file implements features required for IDE support. import - lexer, idents, ast, astalgo, semdata, msgs, types, sigmatch, options + lexer, idents, ast, astalgo, semdata, msgs, types, sigmatch, options, + renderer const sep = '\t' @@ -150,27 +151,25 @@ proc suggestFieldAccess(c: PContext, n: PNode) = else: suggestOperations(c, n, typ) -proc findClosestDot(n: PNode): PNode = - if msgs.inCheckpoint(n.info) == cpExact: +proc findClosestDot(n: PNode): PNode = + if n.kind == nkDotExpr and msgs.inCheckpoint(n.info) == cpExact: result = n - elif n.kind notin {nkNone..nkNilLit}: - for i in 0.. <sonsLen(n): - if n.sons[i].kind == nkDotExpr: - result = findClosestDot(n.sons[i]) - if result != nil: return + else: + for i in 0.. <safeLen(n): + result = findClosestDot(n.sons[i]) + if result != nil: return const CallNodes = {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit, nkMacroStmt} proc findClosestCall(n: PNode): PNode = - if msgs.inCheckpoint(n.info) == cpExact: + if n.kind in callNodes and msgs.inCheckpoint(n.info) == cpExact: result = n - elif n.kind notin {nkNone..nkNilLit}: - for i in 0.. <sonsLen(n): - if n.sons[i].kind in callNodes: - result = findClosestCall(n.sons[i]) - if result != nil: return + else: + for i in 0.. <safeLen(n): + result = findClosestCall(n.sons[i]) + if result != nil: return proc findClosestSym(n: PNode): PNode = if n.kind == nkSym and msgs.inCheckpoint(n.info) == cpExact: diff --git a/compiler/types.nim b/compiler/types.nim index d3f2bd1b5..8bce4fc5f 100755 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -277,7 +277,7 @@ proc analyseObjectWithTypeField(t: PType): TTypeFieldResult = result = analyseObjectWithTypeFieldAux(t, marker) proc isGBCRef(t: PType): bool = - result = t.kind in {tyRef, tySequence, tyString} + result = t.kind in GcTypeKinds proc containsGarbageCollectedRef(typ: PType): bool = # returns true if typ contains a reference, sequence or string (all the |