diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 4 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 11 | ||||
-rw-r--r-- | compiler/ccgstmts.nim | 1 | ||||
-rw-r--r-- | compiler/cgen.nim | 36 | ||||
-rw-r--r-- | compiler/suggest.nim | 11 |
5 files changed, 45 insertions, 18 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 347060248..131c2a38f 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -437,7 +437,7 @@ type nfExplicitCall # x.y() was used instead of x.y nfExprCall # this is an attempt to call a regular expression nfIsRef # this node is a 'ref' node; used for the VM - nfIsCursor # this node is attached a cursor; used for idetools + nfPreventCg # this node should be ignored by the codegen TNodeFlags* = set[TNodeFlag] TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 28) @@ -925,7 +925,7 @@ const skMacro, skTemplate, skConverter, skEnumField, skLet, skStub, skAlias} PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16, nfDotSetter, nfDotField, - nfIsRef, nfIsCursor, nfLL} + nfIsRef, nfPreventCg, nfLL} namePos* = 0 patternPos* = 1 # empty except for term rewriting macros genericParamsPos* = 2 diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index e1ee6f1de..0ba775b25 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -2084,11 +2084,14 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = of nkCaseStmt: genCase(p, n, d) of nkReturnStmt: genReturnStmt(p, n) of nkBreakStmt: genBreakStmt(p, n) - of nkAsgn: genAsgn(p, n, fastAsgn=false) + of nkAsgn: + if nfPreventCg notin n.flags: + genAsgn(p, n, fastAsgn=false) of nkFastAsgn: - # transf is overly aggressive with 'nkFastAsgn', so we work around here. - # See tests/run/tcnstseq3 for an example that would fail otherwise. - genAsgn(p, n, fastAsgn=p.prc != nil) + if nfPreventCg notin n.flags: + # transf is overly aggressive with 'nkFastAsgn', so we work around here. + # See tests/run/tcnstseq3 for an example that would fail otherwise. + genAsgn(p, n, fastAsgn=p.prc != nil) of nkDiscardStmt: if n.sons[0].kind != nkEmpty: genLineDir(p, n) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 1b21e641a..294235ae9 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -359,6 +359,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) = linefmt(p, cpsStmts, "#popCurrentException();$n") proc genReturnStmt(p: BProc, t: PNode) = + if nfPreventCg in t.flags: return p.beforeRetNeeded = true genLineDir(p, t) if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0]) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 4a3113edf..7333c77c3 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -616,6 +616,24 @@ proc closureSetup(p: BProc, prc: PSym) = linefmt(p, cpsStmts, "$1 = ($2) ClEnv;$n", rdLoc(env.loc), getTypeDesc(p.module, env.typ)) +proc easyResultAsgn(n: PNode): PNode = + const harmless = {nkConstSection, nkTypeSection, nkEmpty, nkCommentStmt} + + declarativeDefs + case n.kind + of nkStmtList, nkStmtListExpr: + var i = 0 + while i < n.len and n[i].kind in harmless: inc i + if i < n.len: result = easyResultAsgn(n[i]) + of nkAsgn, nkFastAsgn: + if n[0].kind == nkSym and skResult == n[0].sym.kind: + incl n.flags, nfPreventCg + return n[1] + of nkReturnStmt: + if n.len > 0: + result = easyResultAsgn(n[0]) + if result != nil: incl n.flags, nfPreventCg + else: discard + proc genProcAux(m: BModule, prc: PSym) = var p = newProc(prc, m) var header = genProcHeader(m, prc) @@ -627,11 +645,17 @@ proc genProcAux(m: BModule, prc: PSym) = var res = prc.ast.sons[resultPos].sym # get result symbol if not isInvalidReturnType(prc.typ.sons[0]): if sfNoInit in prc.flags: incl(res.flags, sfNoInit) - # declare the result symbol: - assignLocalVar(p, res) - assert(res.loc.r != nil) + if sfNoInit in prc.flags and p.module.compileToCpp and (let val = easyResultAsgn(prc.getBody); val != nil): + var decl = localVarDecl(p, res) + var a: TLoc + initLocExprSingleUse(p, val, a) + linefmt(p, cpsStmts, "$1 = $2;$n", decl, rdLoc(a)) + else: + # declare the result symbol: + assignLocalVar(p, res) + assert(res.loc.r != nil) + initLocalVar(p, res, immediateAsgn=false) returnStmt = rfmt(nil, "\treturn $1;$n", rdLoc(res.loc)) - initLocalVar(p, res, immediateAsgn=false) else: fillResult(res) assignParam(p, res) @@ -791,12 +815,12 @@ proc addIntTypes(result: var Rope) {.inline.} = proc getCopyright(cfile: string): Rope = if optCompileOnly in gGlobalOptions: result = ("/* Generated by Nim Compiler v$1 */$N" & - "/* (c) 2015 Andreas Rumpf */$N" & + "/* (c) 2016 Andreas Rumpf */$N" & "/* The generated code is subject to the original license. */$N") % [rope(VersionAsString)] else: result = ("/* Generated by Nim Compiler v$1 */$N" & - "/* (c) 2015 Andreas Rumpf */$N" & + "/* (c) 2016 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") % diff --git a/compiler/suggest.nim b/compiler/suggest.nim index f331fce69..52f00550b 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -413,17 +413,16 @@ proc safeSemExpr*(c: PContext, n: PNode): PNode = result = ast.emptyNode proc suggestExpr*(c: PContext, node: PNode) = - if nfIsCursor notin node.flags: - if gTrackPos.line < 0: return - var cp = inCheckpoint(node.info) - if cp == cpNone: return + if gTrackPos.line < 0: return + var cp = inCheckpoint(node.info) + if cp == cpNone: return var outputs = 0 # This keeps semExpr() from coming here recursively: if c.compilesContextId > 0: return inc(c.compilesContextId) if gIdeCmd == ideSug: - var n = if nfIsCursor in node.flags: node else: findClosestDot(node) + var n = findClosestDot(node) if n == nil: n = node if n.kind == nkDotExpr: var obj = safeSemExpr(c, n.sons[0]) @@ -436,7 +435,7 @@ proc suggestExpr*(c: PContext, node: PNode) = suggestEverything(c, n, outputs) elif gIdeCmd == ideCon: - var n = if nfIsCursor in node.flags: node else: findClosestCall(node) + var n = findClosestCall(node) if n == nil: n = node if n.kind in nkCallKinds: var a = copyNode(n) |