diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgexprs.nim | 21 | ||||
-rw-r--r-- | compiler/ccgstmts.nim | 4 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 2 | ||||
-rw-r--r-- | compiler/condsyms.nim | 1 | ||||
-rw-r--r-- | compiler/destroyer.nim | 47 | ||||
-rw-r--r-- | compiler/dfa.nim | 1 | ||||
-rw-r--r-- | compiler/docgen.nim | 12 | ||||
-rw-r--r-- | compiler/passes.nim | 25 | ||||
-rw-r--r-- | compiler/pragmas.nim | 5 | ||||
-rw-r--r-- | compiler/sem.nim | 12 | ||||
-rw-r--r-- | compiler/semasgn.nim | 3 | ||||
-rw-r--r-- | compiler/semfold.nim | 5 | ||||
-rw-r--r-- | compiler/semgnrc.nim | 10 | ||||
-rw-r--r-- | compiler/semstmts.nim | 6 | ||||
-rw-r--r-- | compiler/suggest.nim | 31 | ||||
-rw-r--r-- | compiler/transf.nim | 8 | ||||
-rw-r--r-- | compiler/vmgen.nim | 6 |
17 files changed, 136 insertions, 63 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index fbedf6cc6..1789ce4f1 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1732,7 +1732,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) = getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), i) # our counter initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[2], b) - if d.k == locNone: getTemp(p, a.t, d) + if d.k == locNone: getTemp(p, setType, d) lineF(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) $n" & " $3[$1] = $4[$1] $6 $5[$1];$n", [ @@ -1864,6 +1864,23 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) = else: binaryArith(p, e, d, m) +proc skipAddr(n: PNode): PNode = + result = if n.kind in {nkAddr, nkHiddenAddr}: n[0] else: n + +proc genWasMoved(p: BProc; n: PNode) = + var a: TLoc + initLocExpr(p, n[1].skipAddr, a) + resetLoc(p, a) + #linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n", + # addrLoc(p.config, a), getTypeDesc(p.module, a.t)) + +proc genMove(p: BProc; n: PNode; d: var TLoc) = + if d.k == locNone: getTemp(p, n.typ, d) + var a: TLoc + initLocExpr(p, n[1].skipAddr, a) + genAssignment(p, d, a, {}) + resetLoc(p, a) + proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = case op of mOr, mAnd: genAndOr(p, e, d, op) @@ -1991,6 +2008,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = initLocExpr(p, e.sons[2], b) genDeepCopy(p, a, b) of mDotDot, mEqCString: genCall(p, e, d) + of mWasMoved: genWasMoved(p, e) + of mMove: genMove(p, e, d) else: when defined(debugMagics): echo p.prc.name.s, " ", p.prc.id, " ", p.prc.flags, " ", p.prc.ast[genericParamsPos].kind diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 69e6558bb..df8f95b75 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -277,7 +277,7 @@ proc genSingleVar(p: BProc, a: PNode) = not containsHiddenPointer(v.typ): # C++ really doesn't like things like 'Foo f; f = x' as that invokes a # parameterless constructor followed by an assignment operator. So we - # generate better code here: + # generate better code here: 'Foo f = x;' genLineDir(p, a) let decl = localVarDecl(p, vn) var tmp: TLoc @@ -1159,4 +1159,4 @@ proc genStmts(p: BProc, t: PNode) = if isPush: pushInfoContext(p.config, t.info) expr(p, t, a) if isPush: popInfoContext(p.config) - internalAssert p.config, a.k in {locNone, locTemp, locLocalVar} + internalAssert p.config, a.k in {locNone, locTemp, locLocalVar, locExpr} diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 52a4a72f2..3c7a0d26e 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -1206,7 +1206,7 @@ proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope = let x = fakeClosureType(m, t.owner) genTupleInfo(m, x, x, result, info) of tySequence: - if tfHasAsgn notin t.flags: + if m.config.selectedGC != gcDestructors: genTypeInfoAux(m, t, t, result, info) if m.config.selectedGC >= gcMarkAndSweep: let markerProc = genTraverseProc(m, origType, sig) diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index a22b613f0..62c55de3d 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -81,6 +81,7 @@ proc initDefines*(symbols: StringTableRef) = defineSymbol("nimAshr") defineSymbol("nimNoNilSeqs") defineSymbol("nimNoNilSeqs2") + defineSymbol("nimHasUserErrors") defineSymbol("nimHasNilSeqs") for f in low(Feature)..high(Feature): diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim index bd735560a..fc8e760bc 100644 --- a/compiler/destroyer.nim +++ b/compiler/destroyer.nim @@ -181,7 +181,7 @@ proc isHarmlessVar*(s: PSym; c: Con): bool = if c.g[i].sym == s: if defsite < 0: defsite = i else: return false - of use: + of use, useWithinCall: if c.g[i].sym == s: if defsite < 0: return false for j in defsite .. i: @@ -190,10 +190,11 @@ proc isHarmlessVar*(s: PSym; c: Con): bool = # if we want to die after the first 'use': if usages > 1: return false inc usages - of useWithinCall: - if c.g[i].sym == s: return false + #of useWithinCall: + # if c.g[i].sym == s: return false of goto, fork: discard "we do not perform an abstract interpretation yet" + result = usages <= 1 template interestingSym(s: PSym): bool = s.owner == c.owner and s.kind in InterestingSyms and hasDestructor(s.typ) @@ -222,26 +223,35 @@ proc patchHead(s: PSym) = if sfFromGeneric in s.flags: patchHead(s.ast[bodyPos]) -template genOp(opr, opname) = +proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string) = + var m = "'" & opname & "' is not available for type <" & typeToString(t) & ">" + if opname == "=" and ri != nil: + m.add "; requires a copy because it's not the last read of '" + m.add renderTree(ri) + m.add '\'' + localError(c.graph.config, ri.info, errGenerated, m) + +template genOp(opr, opname, ri) = let op = opr if op == nil: globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator not found for type " & typeToString(t)) elif op.ast[genericParamsPos].kind != nkEmpty: globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator is generic") patchHead op + if sfError in op.flags: checkForErrorPragma(c, t, ri, opname) result = newTree(nkCall, newSymNode(op), newTree(nkHiddenAddr, dest)) -proc genSink(c: Con; t: PType; dest: PNode): PNode = +proc genSink(c: Con; t: PType; dest, ri: PNode): PNode = let t = t.skipTypes({tyGenericInst, tyAlias, tySink}) - genOp(if t.sink != nil: t.sink else: t.assignment, "=sink") + genOp(if t.sink != nil: t.sink else: t.assignment, "=sink", ri) -proc genCopy(c: Con; t: PType; dest: PNode): PNode = +proc genCopy(c: Con; t: PType; dest, ri: PNode): PNode = let t = t.skipTypes({tyGenericInst, tyAlias, tySink}) - genOp(t.assignment, "=") + genOp(t.assignment, "=", ri) proc genDestroy(c: Con; t: PType; dest: PNode): PNode = let t = t.skipTypes({tyGenericInst, tyAlias, tySink}) - genOp(t.destructor, "=destroy") + genOp(t.destructor, "=destroy", nil) proc addTopVar(c: var Con; v: PNode) = c.topLevelVars.add newTree(nkIdentDefs, v, c.emptyNode, c.emptyNode) @@ -291,33 +301,33 @@ proc genMagicCall(n: PNode; c: var Con; magicname: string; m: TMagic): PNode = proc moveOrCopy(dest, ri: PNode; c: var Con): PNode = if ri.kind in constrExprs: - result = genSink(c, ri.typ, dest) + result = genSink(c, dest.typ, dest, ri) # watch out and no not transform 'ri' twice if it's a call: let ri2 = copyNode(ri) recurse(ri, ri2) result.add ri2 - elif ri.kind == nkSym and isHarmlessVar(ri.sym, c): + elif ri.kind == nkSym and ri.sym.kind != skParam and isHarmlessVar(ri.sym, c): # Rule 3: `=sink`(x, z); wasMoved(z) - var snk = genSink(c, ri.typ, dest) + var snk = genSink(c, dest.typ, dest, ri) snk.add p(ri, c) result = newTree(nkStmtList, snk, genMagicCall(ri, c, "wasMoved", mWasMoved)) elif ri.kind == nkSym and isSinkParam(ri.sym): - result = genSink(c, ri.typ, dest) + result = genSink(c, dest.typ, dest, ri) result.add destructiveMoveSink(ri, c) else: - result = genCopy(c, ri.typ, dest) + result = genCopy(c, dest.typ, dest, ri) result.add p(ri, c) proc passCopyToSink(n: PNode; c: var Con): PNode = result = newNodeIT(nkStmtListExpr, n.info, n.typ) let tmp = getTemp(c, n.typ, n.info) if hasDestructor(n.typ): - var m = genCopy(c, n.typ, tmp) + var m = genCopy(c, n.typ, tmp, n) m.add p(n, c) result.add m message(c.graph.config, n.info, hintPerformance, - "passing '$1' to a sink parameter introduces an implicit copy; " & - "use 'move($1)' to prevent it" % $n) + ("passing '$1' to a sink parameter introduces an implicit copy; " & + "use 'move($1)' to prevent it") % $n) else: result.add newTree(nkAsgn, tmp, p(n, c)) result.add tmp @@ -331,6 +341,7 @@ proc destructiveMoveVar(n: PNode; c: var Con): PNode = result = newNodeIT(nkStmtListExpr, n.info, n.typ) var temp = newSym(skLet, getIdent(c.graph.cache, "blitTmp"), c.owner, n.info) + temp.typ = n.typ var v = newNodeI(nkLetSection, n.info) let tempAsNode = newSymNode(temp) @@ -410,7 +421,7 @@ proc p(n: PNode; c: var Con): PNode = discard "produce temp creation" result = newNodeIT(nkStmtListExpr, n.info, n.typ) let tmp = getTemp(c, n.typ, n.info) - var sinkExpr = genSink(c, n.typ, tmp) + var sinkExpr = genSink(c, n.typ, tmp, n) sinkExpr.add n result.add sinkExpr result.add tmp diff --git a/compiler/dfa.nim b/compiler/dfa.nim index 013242f62..44c89b881 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -442,4 +442,5 @@ proc dataflowAnalysis*(s: PSym; body: PNode; conf: ConfigRef) = proc constructCfg*(s: PSym; body: PNode): ControlFlowGraph = ## constructs a control flow graph for ``body``. var c = Con(code: @[], blocks: @[]) + gen(c, body) shallowCopy(result, c.code) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 83dd5de2a..e815bf7a1 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -112,7 +112,7 @@ proc getOutFile2(conf: ConfigRef; filename: RelativeFile, else: result = getOutFile(conf, filename, ext) -proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef): PDoc = +proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef, outExt: string = HtmlExt): PDoc = declareClosures() new(result) result.conf = conf @@ -146,7 +146,7 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef): warnUser, "only 'rst2html' supports the ':test:' attribute") result.emitted = initIntSet() result.destFile = getOutFile2(conf, relativeTo(filename, conf.projectPath), - HtmlExt, RelativeDir"htmldocs", false) + outExt, RelativeDir"htmldocs", false) result.thisDir = result.destFile.splitFile.dir proc dispA(conf: ConfigRef; dest: var Rope, xml, tex: string, args: openArray[Rope]) = @@ -304,7 +304,7 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRe d.target == outHtml: let external = externalDep(d, s.owner) result.addf "<a href=\"$1#$2\"><span class=\"Identifier\">$3</span></a>", - [rope changeFileExt(external, "html").string, rope literal, + [rope changeFileExt(external, "html"), rope literal, rope(esc(d.target, literal))] else: dispA(d.conf, result, "<span class=\"Identifier\">$1</span>", @@ -610,7 +610,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) = var seeSrcRope: Rope = nil let docItemSeeSrc = getConfigVar(d.conf, "doc.item.seesrc") if docItemSeeSrc.len > 0: - let path = relativeTo(AbsoluteFile toFullPath(d.conf, n.info), d.conf.projectPath, '/') + let path = relativeTo(AbsoluteFile toFullPath(d.conf, n.info), AbsoluteDir getCurrentDir(), '/') when false: let cwd = canonicalizePath(d.conf, getCurrentDir()) var path = toFullPath(d.conf, n.info) @@ -711,7 +711,7 @@ proc exportSym(d: PDoc; s: PSym) = "<a class=\"reference external\" href=\"$2\">$1</a>", "$1", [rope esc(d.target, changeFileExt(external, "")), rope changeFileExt(external, "html")]) - elif s.owner != nil: + elif s.kind != skModule and s.owner != nil: let module = originatingModule(s) if belongsToPackage(d.conf, module): let external = externalDep(d, module) @@ -960,7 +960,7 @@ proc commandDoc*(cache: IdentCache, conf: ConfigRef) = proc commandRstAux(cache: IdentCache, conf: ConfigRef; filename: AbsoluteFile, outExt: string) = var filen = addFileExt(filename, "txt") - var d = newDocumentor(filen, cache, conf) + var d = newDocumentor(filen, cache, conf, outExt) d.onTestSnippet = proc (d: var RstGenerator; filename, cmd: string; status: int; content: string) = var outp: AbsoluteFile diff --git a/compiler/passes.nim b/compiler/passes.nim index 365731669..718b42c2a 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -125,6 +125,11 @@ proc processImplicits(conf: ConfigRef; implicits: seq[string], nodeKind: TNodeKi importStmt.addSon str if not processTopLevelStmt(importStmt, a): break +const + imperativeCode = {low(TNodeKind)..high(TNodeKind)} - {nkTemplateDef, nkProcDef, nkMethodDef, + nkMacroDef, nkConverterDef, nkIteratorDef, nkFuncDef, nkPragma, + nkExportStmt, nkExportExceptStmt, nkFromStmt, nkImportStmt, nkImportExceptStmt} + proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {.discardable.} = if graph.stopCompile(): return true var @@ -191,7 +196,25 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool { sl = reorder(graph, sl, module) discard processTopLevelStmt(sl, a) break - elif not processTopLevelStmt(n, a): break + elif n.kind in imperativeCode: + # read everything until the next proc declaration etc. + var sl = newNodeI(nkStmtList, n.info) + sl.add n + var rest: PNode = nil + while true: + var n = parseTopLevelStmt(p) + if n.kind == nkEmpty or n.kind notin imperativeCode: + rest = n + break + sl.add n + #echo "-----\n", sl + if not processTopLevelStmt(sl, a): break + if rest != nil: + #echo "-----\n", rest + if not processTopLevelStmt(rest, a): break + else: + #echo "----- single\n", n + if not processTopLevelStmt(n, a): break closeParsers(p) if s.kind != llsStdIn: break closePasses(graph, a) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 36c79bc9e..94790440f 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -954,13 +954,14 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, recordPragma(c, it, "warning", s) message(c.config, it.info, warnUser, s) of wError: - if sym != nil and sym.isRoutine: + if sym != nil and (sym.isRoutine or sym.kind == skType): # This is subtle but correct: the error *statement* is only # allowed for top level statements. Seems to be easier than # distinguishing properly between # ``proc p() {.error}`` and ``proc p() = {.error: "msg".}`` - noVal(c, it) + if it.kind in nkPragmaCallKinds: discard getStrLitNode(c, it) incl(sym.flags, sfError) + excl(sym.flags, sfForward) else: let s = expectStrLit(c, it) recordPragma(c, it, "error", s) diff --git a/compiler/sem.nim b/compiler/sem.nim index 5e5205c20..dbc174d50 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -542,12 +542,20 @@ proc isImportSystemStmt(g: ModuleGraph; n: PNode): bool = return true else: discard +proc isEmptyTree(n: PNode): bool = + case n.kind + of nkStmtList: + for it in n: + if not isEmptyTree(it): return false + result = true + of nkEmpty, nkCommentStmt: result = true + else: result = false + proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = if n.kind == nkDefer: localError(c.config, n.info, "defer statement not supported at top level") if c.topStmts == 0 and not isImportSystemStmt(c.graph, n): - if sfSystemModule notin c.module.flags and - n.kind notin {nkEmpty, nkCommentStmt}: + if sfSystemModule notin c.module.flags and not isEmptyTree(n): c.importTable.addSym c.graph.systemModule # import the "System" identifier importAllSymbols(c, c.graph.systemModule) inc c.topStmts diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim index 8b2e20efc..f781972a5 100644 --- a/compiler/semasgn.nim +++ b/compiler/semasgn.nim @@ -216,7 +216,8 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) = if c.c.config.selectedGC == gcDestructors: discard considerOverloadedOp(c, t, body, x, y) elif tfHasAsgn in t.flags: - body.add newSeqCall(c.c, x, y) + if c.kind != attachedDestructor: + body.add newSeqCall(c.c, x, y) let i = declareCounter(c, body, firstOrd(c.c.config, t)) let whileLoop = genWhileLoop(c, i, x) let elemType = t.lastSon diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 0018f0755..627877cbe 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -37,10 +37,7 @@ proc newIntNodeT*(intVal: BiggestInt, n: PNode; g: ModuleGraph): PNode = proc newFloatNodeT*(floatVal: BiggestFloat, n: PNode; g: ModuleGraph): PNode = result = newFloatNode(nkFloatLit, floatVal) - if skipTypes(n.typ, abstractVarRange).kind == tyFloat: - result.typ = getFloatLitType(g, result) - else: - result.typ = n.typ + result.typ = n.typ result.info = n.info proc newStrNodeT*(strVal: string, n: PNode; g: ModuleGraph): PNode = diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 7be0610a2..e1a8390e1 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -225,7 +225,7 @@ proc semGenericStmt(c: PContext, n: PNode, var mixinContext = false if s != nil: incl(s.flags, sfUsed) - mixinContext = s.magic in {mDefined, mDefinedInScope, mCompiles, mRunnableExamples} + mixinContext = s.magic in {mDefined, mDefinedInScope, mCompiles} let sc = symChoice(c, fn, s, if s.isMixedIn: scForceOpen else: scOpen) case s.kind of skMacro: @@ -255,11 +255,11 @@ proc semGenericStmt(c: PContext, n: PNode, discard of skProc, skFunc, skMethod, skIterator, skConverter, skModule: result.sons[0] = sc - # do not check of 's.magic==mRoof' here because it might be some - # other '^' but after overload resolution the proper one: - if ctx.bracketExpr != nil and n.len == 2 and s.name.s == "^": - result.add ctx.bracketExpr first = 1 + # We're not interested in the example code during this pass so let's + # skip it + if s.magic == mRunnableExamples: + inc first of skGenericParam: result.sons[0] = newSymNodeTypeDesc(s, fn.info) styleCheckUse(fn.info, s) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 75a4198a5..f2cb2dcb3 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -114,7 +114,7 @@ const skipForDiscardable = {nkIfStmt, nkIfExpr, nkCaseStmt, nkOfBranch, nkElse, nkStmtListExpr, nkTryStmt, nkFinally, nkExceptBranch, nkElifBranch, nkElifExpr, nkElseExpr, nkBlockStmt, nkBlockExpr, - nkHiddenStdConv} + nkHiddenStdConv, nkHiddenDeref} proc implicitlyDiscardable(n: PNode): bool = var n = n @@ -601,6 +601,8 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode = inc(c.p.nestedLoopCounter) openScope(c) n.sons[length-1] = semExprBranch(c, n.sons[length-1], flags) + if efInTypeof notin flags: + discardCheck(c, n.sons[length-1], flags) closeScope(c) dec(c.p.nestedLoopCounter) @@ -1675,7 +1677,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, else: if s.kind == skMethod: semMethodPrototype(c, s, n) if proto != nil: localError(c.config, n.info, errImplOfXexpected % proto.name.s) - if {sfImportc, sfBorrow} * s.flags == {} and s.magic == mNone: + if {sfImportc, sfBorrow, sfError} * s.flags == {} and s.magic == mNone: incl(s.flags, sfForward) elif sfBorrow in s.flags: semBorrow(c, n, s) sideEffectsCheck(c, s) diff --git a/compiler/suggest.nim b/compiler/suggest.nim index b6b8d713c..b264415d8 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -33,7 +33,7 @@ # included from sigmatch.nim import algorithm, prefixmatches, lineinfos, pathutils -from wordrecg import wDeprecated +from wordrecg import wDeprecated, wError when defined(nimsuggest): import passes, tables # importer @@ -453,33 +453,42 @@ proc suggestSym*(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym; isDecl: suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideOutline, info, 100, PrefixMatch.None, false, 0)) -proc warnAboutDeprecated(conf: ConfigRef; info: TLineInfo; s: PSym) = - var pragmaNode: PNode - +proc extractPragma(s: PSym): PNode = if s.kind in routineKinds: - pragmaNode = s.ast[pragmasPos] + result = s.ast[pragmasPos] elif s.kind in {skType}: # s.ast = nkTypedef / nkPragmaExpr / [nkSym, nkPragma] - pragmaNode = s.ast[0][1] - - doAssert pragmaNode == nil or pragmaNode.kind == nkPragma + result = s.ast[0][1] + doAssert result == nil or result.kind == nkPragma +proc warnAboutDeprecated(conf: ConfigRef; info: TLineInfo; s: PSym) = + let pragmaNode = extractPragma(s) if pragmaNode != nil: for it in pragmaNode: if whichPragma(it) == wDeprecated and it.safeLen == 2 and - it[1].kind in {nkStrLit..nkTripleStrLit}: + it[1].kind in {nkStrLit..nkTripleStrLit}: message(conf, info, warnDeprecated, it[1].strVal & "; " & s.name.s) return - message(conf, info, warnDeprecated, s.name.s) +proc userError(conf: ConfigRef; info: TLineInfo; s: PSym) = + let pragmaNode = extractPragma(s) + + if pragmaNode != nil: + for it in pragmaNode: + if whichPragma(it) == wError and it.safeLen == 2 and + it[1].kind in {nkStrLit..nkTripleStrLit}: + localError(conf, info, it[1].strVal & "; usage of '$1' is a user-defined error" % s.name.s) + return + localError(conf, info, "usage of '$1' is a user-defined error" % s.name.s) + proc markUsed(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym) = incl(s.flags, sfUsed) if s.kind == skEnumField and s.owner != nil: incl(s.owner.flags, sfUsed) if {sfDeprecated, sfError} * s.flags != {}: if sfDeprecated in s.flags: warnAboutDeprecated(conf, info, s) - if sfError in s.flags: localError(conf, info, "usage of '$1' is a user-defined error" % s.name.s) + if sfError in s.flags: userError(conf, info, s) when defined(nimsuggest): suggestSym(conf, info, s, usageSym, false) diff --git a/compiler/transf.nim b/compiler/transf.nim index b31be71a3..83e66a069 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -1054,8 +1054,8 @@ proc transformStmt*(g: ModuleGraph; module: PSym, n: PNode): PNode = when useEffectSystem: trackTopLevelStmt(g, module, result) #if n.info ?? "temp.nim": # echo renderTree(result, {renderIds}) - #if c.needsDestroyPass: - # result = injectDestructorCalls(g, module, result) + if c.needsDestroyPass: + result = injectDestructorCalls(g, module, result) incl(result.flags, nfTransf) proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode = @@ -1067,6 +1067,6 @@ proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode = liftDefer(c, result) # expressions are not to be injected with destructor calls as that # the list of top level statements needs to be collected before. - #if c.needsDestroyPass: - # result = injectDestructorCalls(g, module, result) + if c.needsDestroyPass: + result = injectDestructorCalls(g, module, result) incl(result.flags, nfTransf) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index b6b5bf4f2..e612d7a2a 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1529,7 +1529,7 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) = template needsRegLoad(): untyped = {gfNode, gfNodeAddr} * flags == {} and - fitsRegister(n.typ.skipTypes({tyVar, tyLent})) + fitsRegister(n.typ.skipTypes({tyVar, tyLent, tyStatic})) proc genArrAccess2(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode; flags: TGenFlags) = @@ -1590,7 +1590,7 @@ proc getNullValueAux(obj: PNode, result: PNode; conf: ConfigRef) = else: globalError(conf, result.info, "cannot create null element for: " & $obj) proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = - var t = skipTypes(typ, abstractRange-{tyTypeDesc}) + var t = skipTypes(typ, abstractRange+{tyStatic}-{tyTypeDesc}) case t.kind of tyBool, tyEnum, tyChar, tyInt..tyInt64: result = newNodeIT(nkIntLit, info, t) @@ -1602,7 +1602,7 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = result = newNodeIT(nkStrLit, info, t) result.strVal = "" of tyVar, tyLent, tyPointer, tyPtr, tyExpr, - tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil: + tyStmt, tyTypeDesc, tyRef, tyNil: result = newNodeIT(nkNilLit, info, t) of tyProc: if t.callConv != ccClosure: |