diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-06-02 09:41:27 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-06-02 09:41:27 +0200 |
commit | 826c1e2d7850026335d33e3be2fce54dee4f6698 (patch) | |
tree | 61b23c163c8cd9063ea8628798d727da404e1f1d /compiler/pragmas.nim | |
parent | cae19738562f14fbb76004748bed8d2f337d6f0b (diff) | |
download | Nim-826c1e2d7850026335d33e3be2fce54dee4f6698.tar.gz |
incremental compilation: implemented basic replay logic
Diffstat (limited to 'compiler/pragmas.nim')
-rw-r--r-- | compiler/pragmas.nim | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 061bbacfa..815ec67d7 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -84,6 +84,13 @@ proc getPragmaVal*(procAst: PNode; name: TSpecialWord): PNode = proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) # implementation +proc recordPragma(c: PContext; n: PNode; key, val: string; val2 = "") = + var recorded = newNodeI(nkCommentStmt, n.info) + recorded.add newStrNode(key, n.info) + recorded.add newStrNode(val, n.info) + if val2.len > 0: recorded.add newStrNode(val2, n.info) + c.graph.recordStmt(c.graph, c.module, recorded) + const errStringLiteralExpected = "string literal expected" errIntLiteralExpected = "integer literal expected" @@ -227,7 +234,7 @@ proc pragmaNoForward(c: PContext, n: PNode; flag=sfNoForward) = proc processCallConv(c: PContext, n: PNode) = if n.kind in nkPragmaCallKinds and n.len == 2 and n.sons[1].kind == nkIdent: - var sw = whichKeyword(n.sons[1].ident) + let sw = whichKeyword(n.sons[1].ident) case sw of FirstCallConv..LastCallConv: c.optionStack[^1].defaultCC = wordToCallConv(sw) @@ -412,6 +419,10 @@ proc relativeFile(c: PContext; n: PNode; ext=""): string = if result.len == 0: result = s proc processCompile(c: PContext, n: PNode) = + proc docompile(c: PContext; it: PNode; src, dest: string) = + var cf = Cfile(cname: src, obj: dest, flags: {CfileFlag.External}) + extccomp.addExternalFileToCompile(c.config, cf) + recordPragma(c, it, "compile", src, dest) proc getStrLit(c: PContext, n: PNode; i: int): string = n.sons[i] = c.semConstExpr(c, n[i]) @@ -428,11 +439,8 @@ proc processCompile(c: PContext, n: PNode) = let dest = getStrLit(c, it, 1) var found = parentDir(toFullPath(c.config, n.info)) / s for f in os.walkFiles(found): - let nameOnly = extractFilename(f) - var cf = Cfile(cname: f, - obj: completeCFilePath(c.config, dest % nameOnly), - flags: {CfileFlag.External}) - extccomp.addExternalFileToCompile(c.config, cf) + let obj = completeCFilePath(c.config, dest % extractFilename(f)) + docompile(c, it, f, obj) else: let s = expectStrLit(c, n) var found = parentDir(toFullPath(c.config, n.info)) / s @@ -441,15 +449,19 @@ proc processCompile(c: PContext, n: PNode) = else: found = findFile(c.config, s) if found.len == 0: found = s - extccomp.addExternalFileToCompile(c.config, found) + let obj = toObjFile(c.config, completeCFilePath(c.config, changeFileExt(found, ""), false)) + docompile(c, it, found, obj) proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) = let found = relativeFile(c, n, CC[c.config.cCompiler].objExt) case feature - of linkNormal: extccomp.addExternalFileToLink(c.config, found) + of linkNormal: + extccomp.addExternalFileToLink(c.config, found) + recordPragma(c, n, "link", found) of linkSys: - extccomp.addExternalFileToLink(c.config, - c.config.libpath / completeCFilePath(c.config, found, false)) + let dest = c.config.libpath / completeCFilePath(c.config, found, false) + extccomp.addExternalFileToLink(c.config, dest) + recordPragma(c, n, "link", dest) else: internalError(c.config, n.info, "processCommonLink") proc pragmaBreakpoint(c: PContext, n: PNode) = @@ -724,7 +736,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, i.inc(userPragma.ast.len - 1) # inc by -1 is ok, user pragmas was empty dec c.instCounter else: - var k = whichKeyword(ident) + let k = whichKeyword(ident) if k in validPragmas: case k of wExportc: @@ -891,8 +903,14 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, noVal(c, it) if sym.typ == nil: invalidPragma(c, it) else: incl(sym.typ.flags, tfPacked) - of wHint: message(c.config, it.info, hintUser, expectStrLit(c, it)) - of wWarning: message(c.config, it.info, warnUser, expectStrLit(c, it)) + of wHint: + let s = expectStrLit(c, it) + recordPragma(c, it, "hint", s) + message(c.config, it.info, hintUser, s) + of wWarning: + let s = expectStrLit(c, it) + recordPragma(c, it, "warning", s) + message(c.config, it.info, warnUser, s) of wError: if sym != nil and sym.isRoutine: # This is subtle but correct: the error *statement* is only @@ -902,7 +920,9 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, noVal(c, it) incl(sym.flags, sfError) else: - localError(c.config, it.info, errUser, expectStrLit(c, it)) + let s = expectStrLit(c, it) + recordPragma(c, it, "error", s) + localError(c.config, it.info, errUser, s) of wFatal: fatal(c.config, it.info, errUser, expectStrLit(c, it)) of wDefine: processDefine(c, it) of wUndef: processUndef(c, it) @@ -1066,8 +1086,7 @@ proc implicitPragmas*(c: PContext, sym: PSym, n: PNode, if sym.loc.r == nil: sym.loc.r = rope(sym.name.s) proc hasPragma*(n: PNode, pragma: TSpecialWord): bool = - if n == nil or n.sons == nil: - return false + if n == nil: return false for p in n: var key = if p.kind in nkPragmaCallKinds and p.len > 1: p[0] else: p @@ -1079,7 +1098,7 @@ proc hasPragma*(n: PNode, pragma: TSpecialWord): bool = proc pragmaRec(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = if n == nil: return var i = 0 - while i < n.len(): + while i < n.len: if singlePragma(c, sym, n, i, validPragmas): break inc i |