C++ backend: use .noInit pragma for non-public default constructors; refs #4687
This commit is contained in:
parent
7e86ed00ce
commit
dfa0699e73
5 changed files with 45 additions and 18 deletions
|
|
@ -437,7 +437,7 @@ type
|
||||||
nfExplicitCall # x.y() was used instead of x.y
|
nfExplicitCall # x.y() was used instead of x.y
|
||||||
nfExprCall # this is an attempt to call a regular expression
|
nfExprCall # this is an attempt to call a regular expression
|
||||||
nfIsRef # this node is a 'ref' node; used for the VM
|
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]
|
TNodeFlags* = set[TNodeFlag]
|
||||||
TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 28)
|
TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 28)
|
||||||
|
|
@ -925,7 +925,7 @@ const
|
||||||
skMacro, skTemplate, skConverter, skEnumField, skLet, skStub, skAlias}
|
skMacro, skTemplate, skConverter, skEnumField, skLet, skStub, skAlias}
|
||||||
PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16,
|
PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16,
|
||||||
nfDotSetter, nfDotField,
|
nfDotSetter, nfDotField,
|
||||||
nfIsRef, nfIsCursor, nfLL}
|
nfIsRef, nfPreventCg, nfLL}
|
||||||
namePos* = 0
|
namePos* = 0
|
||||||
patternPos* = 1 # empty except for term rewriting macros
|
patternPos* = 1 # empty except for term rewriting macros
|
||||||
genericParamsPos* = 2
|
genericParamsPos* = 2
|
||||||
|
|
|
||||||
|
|
@ -2084,8 +2084,11 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
of nkCaseStmt: genCase(p, n, d)
|
of nkCaseStmt: genCase(p, n, d)
|
||||||
of nkReturnStmt: genReturnStmt(p, n)
|
of nkReturnStmt: genReturnStmt(p, n)
|
||||||
of nkBreakStmt: genBreakStmt(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:
|
of nkFastAsgn:
|
||||||
|
if nfPreventCg notin n.flags:
|
||||||
# transf is overly aggressive with 'nkFastAsgn', so we work around here.
|
# transf is overly aggressive with 'nkFastAsgn', so we work around here.
|
||||||
# See tests/run/tcnstseq3 for an example that would fail otherwise.
|
# See tests/run/tcnstseq3 for an example that would fail otherwise.
|
||||||
genAsgn(p, n, fastAsgn=p.prc != nil)
|
genAsgn(p, n, fastAsgn=p.prc != nil)
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
||||||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
||||||
|
|
||||||
proc genReturnStmt(p: BProc, t: PNode) =
|
proc genReturnStmt(p: BProc, t: PNode) =
|
||||||
|
if nfPreventCg in t.flags: return
|
||||||
p.beforeRetNeeded = true
|
p.beforeRetNeeded = true
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0])
|
if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0])
|
||||||
|
|
|
||||||
|
|
@ -616,6 +616,24 @@ proc closureSetup(p: BProc, prc: PSym) =
|
||||||
linefmt(p, cpsStmts, "$1 = ($2) ClEnv;$n",
|
linefmt(p, cpsStmts, "$1 = ($2) ClEnv;$n",
|
||||||
rdLoc(env.loc), getTypeDesc(p.module, env.typ))
|
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) =
|
proc genProcAux(m: BModule, prc: PSym) =
|
||||||
var p = newProc(prc, m)
|
var p = newProc(prc, m)
|
||||||
var header = genProcHeader(m, prc)
|
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
|
var res = prc.ast.sons[resultPos].sym # get result symbol
|
||||||
if not isInvalidReturnType(prc.typ.sons[0]):
|
if not isInvalidReturnType(prc.typ.sons[0]):
|
||||||
if sfNoInit in prc.flags: incl(res.flags, sfNoInit)
|
if sfNoInit in prc.flags: incl(res.flags, sfNoInit)
|
||||||
|
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:
|
# declare the result symbol:
|
||||||
assignLocalVar(p, res)
|
assignLocalVar(p, res)
|
||||||
assert(res.loc.r != nil)
|
assert(res.loc.r != nil)
|
||||||
returnStmt = rfmt(nil, "\treturn $1;$n", rdLoc(res.loc))
|
|
||||||
initLocalVar(p, res, immediateAsgn=false)
|
initLocalVar(p, res, immediateAsgn=false)
|
||||||
|
returnStmt = rfmt(nil, "\treturn $1;$n", rdLoc(res.loc))
|
||||||
else:
|
else:
|
||||||
fillResult(res)
|
fillResult(res)
|
||||||
assignParam(p, res)
|
assignParam(p, res)
|
||||||
|
|
@ -791,12 +815,12 @@ proc addIntTypes(result: var Rope) {.inline.} =
|
||||||
proc getCopyright(cfile: string): Rope =
|
proc getCopyright(cfile: string): Rope =
|
||||||
if optCompileOnly in gGlobalOptions:
|
if optCompileOnly in gGlobalOptions:
|
||||||
result = ("/* Generated by Nim Compiler v$1 */$N" &
|
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") %
|
"/* The generated code is subject to the original license. */$N") %
|
||||||
[rope(VersionAsString)]
|
[rope(VersionAsString)]
|
||||||
else:
|
else:
|
||||||
result = ("/* Generated by Nim Compiler v$1 */$N" &
|
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" &
|
"/* The generated code is subject to the original license. */$N" &
|
||||||
"/* Compiled for: $2, $3, $4 */$N" &
|
"/* Compiled for: $2, $3, $4 */$N" &
|
||||||
"/* Command for C compiler:$n $5 */$N") %
|
"/* Command for C compiler:$n $5 */$N") %
|
||||||
|
|
|
||||||
|
|
@ -413,7 +413,6 @@ proc safeSemExpr*(c: PContext, n: PNode): PNode =
|
||||||
result = ast.emptyNode
|
result = ast.emptyNode
|
||||||
|
|
||||||
proc suggestExpr*(c: PContext, node: PNode) =
|
proc suggestExpr*(c: PContext, node: PNode) =
|
||||||
if nfIsCursor notin node.flags:
|
|
||||||
if gTrackPos.line < 0: return
|
if gTrackPos.line < 0: return
|
||||||
var cp = inCheckpoint(node.info)
|
var cp = inCheckpoint(node.info)
|
||||||
if cp == cpNone: return
|
if cp == cpNone: return
|
||||||
|
|
@ -423,7 +422,7 @@ proc suggestExpr*(c: PContext, node: PNode) =
|
||||||
inc(c.compilesContextId)
|
inc(c.compilesContextId)
|
||||||
|
|
||||||
if gIdeCmd == ideSug:
|
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 == nil: n = node
|
||||||
if n.kind == nkDotExpr:
|
if n.kind == nkDotExpr:
|
||||||
var obj = safeSemExpr(c, n.sons[0])
|
var obj = safeSemExpr(c, n.sons[0])
|
||||||
|
|
@ -436,7 +435,7 @@ proc suggestExpr*(c: PContext, node: PNode) =
|
||||||
suggestEverything(c, n, outputs)
|
suggestEverything(c, n, outputs)
|
||||||
|
|
||||||
elif gIdeCmd == ideCon:
|
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 == nil: n = node
|
||||||
if n.kind in nkCallKinds:
|
if n.kind in nkCallKinds:
|
||||||
var a = copyNode(n)
|
var a = copyNode(n)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue