amends #21690 to fix broken Nim to C++ source line mappings (#21784)

resync fork
This commit is contained in:
heterodoxic
2023-05-04 14:09:53 +02:00
committed by GitHub
parent c34950f8f5
commit a929e513fa
4 changed files with 125 additions and 124 deletions

View File

@@ -199,12 +199,12 @@ proc canMove(p: BProc, n: PNode; dest: TLoc): bool =
proc genRefAssign(p: BProc, dest, src: TLoc) =
if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config):
linefmt(p, cpsStmts, "$1 = $2;\n", [rdLoc(dest), rdLoc(src)])
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
elif dest.storage == OnHeap:
linefmt(p, cpsStmts, "#asgnRef((void**) $1, $2);\n",
linefmt(p, cpsStmts, "#asgnRef((void**) $1, $2);$n",
[addrLoc(p.config, dest), rdLoc(src)])
else:
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);\n",
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n",
[addrLoc(p.config, dest), rdLoc(src)])
proc asgnComplexity(n: PNode): int =
@@ -270,19 +270,19 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
# (for objects, etc.):
if optSeqDestructors in p.config.globalOptions:
linefmt(p, cpsStmts,
"$1 = $2;\n",
"$1 = $2;$n",
[rdLoc(dest), rdLoc(src)])
elif needToCopy notin flags or
tfShallow in skipTypes(dest.t, abstractVarRange).flags:
if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config):
linefmt(p, cpsStmts,
"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($3));\n",
"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
[addrLoc(p.config, dest), addrLoc(p.config, src), rdLoc(dest)])
else:
linefmt(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);\n",
linefmt(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n",
[addrLoc(p.config, dest), addrLoc(p.config, src), genTypeInfoV1(p.module, dest.t, dest.lode.info)])
else:
linefmt(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);\n",
linefmt(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n",
[addrLoc(p.config, dest), addrLoc(p.config, src), genTypeInfoV1(p.module, dest.t, dest.lode.info)])
proc genOpenArrayConv(p: BProc; d: TLoc; a: TLoc) =
@@ -318,7 +318,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
# the assignment operation in C.
if src.t != nil and src.t.kind == tyPtr:
# little HACK to support the new 'var T' as return type:
linefmt(p, cpsStmts, "$1 = $2;\n", [rdLoc(dest), rdLoc(src)])
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
return
let ty = skipTypes(dest.t, abstractRange + tyUserTypeClasses + {tyStatic})
case ty.kind
@@ -330,7 +330,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
elif (needToCopy notin flags and src.storage != OnStatic) or canMove(p, src.lode, dest):
genRefAssign(p, dest, src)
else:
linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);\n",
linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n",
[addrLoc(p.config, dest), rdLoc(src),
genTypeInfoV1(p.module, dest.t, dest.lode.info)])
of tyString:
@@ -340,16 +340,16 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
genRefAssign(p, dest, src)
else:
if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config):
linefmt(p, cpsStmts, "$1 = #copyString($2);\n", [dest.rdLoc, src.rdLoc])
linefmt(p, cpsStmts, "$1 = #copyString($2);$n", [dest.rdLoc, src.rdLoc])
elif dest.storage == OnHeap:
# we use a temporary to care for the dreaded self assignment:
var tmp: TLoc
getTemp(p, ty, tmp)
linefmt(p, cpsStmts, "$3 = $1; $1 = #copyStringRC1($2);\n",
linefmt(p, cpsStmts, "$3 = $1; $1 = #copyStringRC1($2);$n",
[dest.rdLoc, src.rdLoc, tmp.rdLoc])
linefmt(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);\n", [tmp.rdLoc])
linefmt(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", [tmp.rdLoc])
else:
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));\n",
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n",
[addrLoc(p.config, dest), rdLoc(src)])
of tyProc:
if containsGarbageCollectedRef(dest.t):
@@ -357,19 +357,19 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
let a = optAsgnLoc(dest, dest.t, "ClE_0".rope)
let b = optAsgnLoc(src, dest.t, "ClE_0".rope)
genRefAssign(p, a, b)
linefmt(p, cpsStmts, "$1.ClP_0 = $2.ClP_0;\n", [rdLoc(dest), rdLoc(src)])
linefmt(p, cpsStmts, "$1.ClP_0 = $2.ClP_0;$n", [rdLoc(dest), rdLoc(src)])
else:
linefmt(p, cpsStmts, "$1 = $2;\n", [rdLoc(dest), rdLoc(src)])
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
of tyTuple:
if containsGarbageCollectedRef(dest.t):
if dest.t.len <= 4: genOptAsgnTuple(p, dest, src, flags)
else: genGenericAsgn(p, dest, src, flags)
else:
linefmt(p, cpsStmts, "$1 = $2;\n", [rdLoc(dest), rdLoc(src)])
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
of tyObject:
# XXX: check for subtyping?
if ty.isImportedCppType:
linefmt(p, cpsStmts, "$1 = $2;\n", [rdLoc(dest), rdLoc(src)])
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
elif not isObjLackingTypeField(ty):
genGenericAsgn(p, dest, src, flags)
elif containsGarbageCollectedRef(ty):
@@ -380,13 +380,13 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
else:
genGenericAsgn(p, dest, src, flags)
else:
linefmt(p, cpsStmts, "$1 = $2;\n", [rdLoc(dest), rdLoc(src)])
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
of tyArray:
if containsGarbageCollectedRef(dest.t) and p.config.selectedGC notin {gcArc, gcOrc, gcHooks}:
genGenericAsgn(p, dest, src, flags)
else:
linefmt(p, cpsStmts,
"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($3));\n",
"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
[rdLoc(dest), rdLoc(src), getTypeDesc(p.module, dest.t)])
of tyOpenArray, tyVarargs:
# open arrays are always on the stack - really? What if a sequence is
@@ -395,30 +395,30 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
genOpenArrayConv(p, dest, src)
elif containsGarbageCollectedRef(dest.t):
linefmt(p, cpsStmts, # XXX: is this correct for arrays?
"#genericAssignOpenArray((void*)$1, (void*)$2, $1Len_0, $3);\n",
"#genericAssignOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n",
[addrLoc(p.config, dest), addrLoc(p.config, src),
genTypeInfoV1(p.module, dest.t, dest.lode.info)])
else:
linefmt(p, cpsStmts,
# bug #4799, keep the nimCopyMem for a while
#"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len_0);\n",
"$1 = $2;\n",
"$1 = $2;$n",
[rdLoc(dest), rdLoc(src)])
of tySet:
if mapSetType(p.config, ty) == ctArray:
linefmt(p, cpsStmts, "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, $3);\n",
linefmt(p, cpsStmts, "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, $3);$n",
[rdLoc(dest), rdLoc(src), getSize(p.config, dest.t)])
else:
linefmt(p, cpsStmts, "$1 = $2;\n", [rdLoc(dest), rdLoc(src)])
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
of tyPtr, tyPointer, tyChar, tyBool, tyEnum, tyCstring,
tyInt..tyUInt64, tyRange, tyVar, tyLent, tyNil:
linefmt(p, cpsStmts, "$1 = $2;\n", [rdLoc(dest), rdLoc(src)])
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
else: internalError(p.config, "genAssignment: " & $ty.kind)
if optMemTracker in p.options and dest.storage in {OnHeap, OnUnknown}:
#writeStackTrace()
#echo p.currLineInfo, " requesting"
linefmt(p, cpsStmts, "#memTrackerWrite((void*)$1, $2, $3, $4);\n",
linefmt(p, cpsStmts, "#memTrackerWrite((void*)$1, $2, $3, $4);$n",
[addrLoc(p.config, dest), getSize(p.config, dest.t),
makeCString(toFullPath(p.config, p.currLineInfo)),
p.currLineInfo.safeLineNm])
@@ -437,32 +437,32 @@ proc genDeepCopy(p: BProc; dest, src: TLoc) =
case ty.kind
of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray:
# XXX optimize this
linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);\n",
linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);$n",
[addrLoc(p.config, dest), addrLocOrTemp(src),
genTypeInfoV1(p.module, dest.t, dest.lode.info)])
of tySequence, tyString:
if optTinyRtti in p.config.globalOptions:
linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);\n",
linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);$n",
[addrLoc(p.config, dest), addrLocOrTemp(src),
genTypeInfoV1(p.module, dest.t, dest.lode.info)])
else:
linefmt(p, cpsStmts, "#genericSeqDeepCopy($1, $2, $3);\n",
linefmt(p, cpsStmts, "#genericSeqDeepCopy($1, $2, $3);$n",
[addrLoc(p.config, dest), rdLoc(src),
genTypeInfoV1(p.module, dest.t, dest.lode.info)])
of tyOpenArray, tyVarargs:
linefmt(p, cpsStmts,
"#genericDeepCopyOpenArray((void*)$1, (void*)$2, $1Len_0, $3);\n",
"#genericDeepCopyOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n",
[addrLoc(p.config, dest), addrLocOrTemp(src),
genTypeInfoV1(p.module, dest.t, dest.lode.info)])
of tySet:
if mapSetType(p.config, ty) == ctArray:
linefmt(p, cpsStmts, "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, $3);\n",
linefmt(p, cpsStmts, "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, $3);$n",
[rdLoc(dest), rdLoc(src), getSize(p.config, dest.t)])
else:
linefmt(p, cpsStmts, "$1 = $2;\n", [rdLoc(dest), rdLoc(src)])
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
of tyPointer, tyChar, tyBool, tyEnum, tyCstring,
tyInt..tyUInt64, tyRange, tyVar, tyLent:
linefmt(p, cpsStmts, "$1 = $2;\n", [rdLoc(dest), rdLoc(src)])
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
else: internalError(p.config, "genDeepCopy: " & $ty.kind)
proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc) =
@@ -507,14 +507,14 @@ proc binaryStmt(p: BProc, e: PNode, d: var TLoc, op: string) =
if d.k != locNone: internalError(p.config, e.info, "binaryStmt")
initLocExpr(p, e[1], a)
initLocExpr(p, e[2], b)
lineCg(p, cpsStmts, "$1 $2 $3;\n", [rdLoc(a), op, rdLoc(b)])
lineCg(p, cpsStmts, "$1 $2 $3;$n", [rdLoc(a), op, rdLoc(b)])
proc binaryStmtAddr(p: BProc, e: PNode, d: var TLoc, cpname: string) =
var a, b: TLoc
if d.k != locNone: internalError(p.config, e.info, "binaryStmtAddr")
initLocExpr(p, e[1], a)
initLocExpr(p, e[2], b)
lineCg(p, cpsStmts, "#$1($2, $3);\n", [cpname, byRefLoc(p, a), rdLoc(b)])
lineCg(p, cpsStmts, "#$1($2, $3);$n", [cpname, byRefLoc(p, a), rdLoc(b)])
template unaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) =
var a: TLoc
@@ -1193,9 +1193,9 @@ proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
expr(p, e[1], tmp)
L = getLabel(p)
if m == mOr:
lineF(p, cpsStmts, "if ($1) goto $2;\n", [rdLoc(tmp), L])
lineF(p, cpsStmts, "if ($1) goto $2;$n", [rdLoc(tmp), L])
else:
lineF(p, cpsStmts, "if (!($1)) goto $2;\n", [rdLoc(tmp), L])
lineF(p, cpsStmts, "if (!($1)) goto $2;$n", [rdLoc(tmp), L])
expr(p, e[2], tmp)
fixLabel(p, L)
if d.k == locNone:
@@ -1276,15 +1276,15 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, e[i + 1], a)
if skipTypes(e[i + 1].typ, abstractVarRange).kind == tyChar:
inc(L)
appends.add(ropecg(p.module, "#appendChar($1, $2);\n", [strLoc(p, tmp), rdLoc(a)]))
appends.add(ropecg(p.module, "#appendChar($1, $2);$n", [strLoc(p, tmp), rdLoc(a)]))
else:
if e[i + 1].kind in {nkStrLit..nkTripleStrLit}:
inc(L, e[i + 1].strVal.len)
else:
lens.add(lenExpr(p, a))
lens.add(" + ")
appends.add(ropecg(p.module, "#appendString($1, $2);\n", [strLoc(p, tmp), rdLoc(a)]))
linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);\n", [tmp.r, lens, L])
appends.add(ropecg(p.module, "#appendString($1, $2);$n", [strLoc(p, tmp), rdLoc(a)]))
linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", [tmp.r, lens, L])
p.s(cpsStmts).add appends
if d.k == locNone:
d = tmp

View File

@@ -61,7 +61,7 @@ proc startBlockInternal(p: BProc): int {.discardable.} =
p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16
p.blocks[result].nestedExceptStmts = p.inExceptBlockLen.int16
template startBlock(p: BProc, start: FormatStr = "{\n",
template startBlock(p: BProc, start: FormatStr = "{$n",
args: varargs[Rope]): int =
lineCg(p, cpsStmts, start, args)
startBlockInternal(p)
@@ -173,8 +173,7 @@ proc endBlock(p: BProc) =
if p.blocks[topBlock].label.len != 0:
blockEnd.addf("} $1: ;$n", [p.blocks[topBlock].label])
else:
#blockEnd.addf("}$n", [])
blockEnd.add("}\n")
blockEnd.addf("}$n", [])
endBlock(p, blockEnd)
proc genSimpleBlock(p: BProc, stmts: PNode) {.inline.} =
@@ -447,9 +446,9 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) =
[rdLoc(a), lelse])
if p.module.compileToCpp:
# avoid "jump to label crosses initialization" error:
p.s(cpsStmts).add "{\n"
p.s(cpsStmts).add "{"
expr(p, it[1], d)
p.s(cpsStmts).add "}\n"
p.s(cpsStmts).add "}"
else:
expr(p, it[1], d)
endBlock(p)
@@ -608,13 +607,13 @@ proc genWhileStmt(p: BProc, t: PNode) =
loopBody = loopBody[1]
genComputedGoto(p, loopBody)
else:
p.breakIdx = startBlock(p, "while (1) {\n")
p.breakIdx = startBlock(p, "while (1) {$n")
p.blocks[p.breakIdx].isLoop = true
initLocExpr(p, t[0], a)
if (t[0].kind != nkIntLit) or (t[0].intVal == 0):
lineF(p, cpsStmts, "if (!$1) goto ", [rdLoc(a)])
assignLabel(p.blocks[p.breakIdx], p.s(cpsStmts))
appcg(p, cpsStmts, ";\n", [])
appcg(p, cpsStmts, ";$n", [])
genStmts(p, loopBody)
if optProfiler in p.options:
@@ -978,8 +977,8 @@ proc genCase(p: BProc, t: PNode, d: var TLoc) =
of tyCstring:
genStringCase(p, t, tyCstring, d)
of tyFloat..tyFloat128:
genCaseGeneric(p, t, d, "if ($1 >= $2 && $1 <= $3) goto $4;\n",
"if ($1 == $2) goto $3;\n")
genCaseGeneric(p, t, d, "if ($1 >= $2 && $1 <= $3) goto $4;$n",
"if ($1 == $2) goto $3;$n")
else:
if t[0].kind == nkSym and sfGoto in t[0].sym.flags:
genGotoForCase(p, t)
@@ -990,9 +989,9 @@ proc genRestoreFrameAfterException(p: BProc) =
if optStackTrace in p.module.config.options:
if hasCurFramePointer notin p.flags:
p.flags.incl hasCurFramePointer
p.procSec(cpsLocals).add(ropecg(p.module, "\tTFrame* _nimCurFrame;\n", []))
p.procSec(cpsInit).add(ropecg(p.module, "\t_nimCurFrame = #getFrame();\n", []))
linefmt(p, cpsStmts, "#setFrame(_nimCurFrame);\n", [])
p.procSec(cpsLocals).add(ropecg(p.module, "\tTFrame* _nimCurFrame;$n", []))
p.procSec(cpsInit).add(ropecg(p.module, "\t_nimCurFrame = #getFrame();$n", []))
linefmt(p, cpsStmts, "#setFrame(_nimCurFrame);$n", [])
proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
#[ code to generate:
@@ -1028,26 +1027,25 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
inc(p.labels, 2)
let etmp = p.labels
p.procSec(cpsInit).add(ropecg(p.module, "\tstd::exception_ptr T$1_ = nullptr;\n", [etmp]))
p.procSec(cpsInit).add(ropecg(p.module, "\tstd::exception_ptr T$1_ = nullptr;$n", [etmp]))
let fin = if t[^1].kind == nkFinally: t[^1] else: nil
p.nestedTryStmts.add((fin, false, 0.Natural))
if t.kind == nkHiddenTryStmt:
lineCg(p, cpsStmts, "try {\n", [])
lineCg(p, cpsStmts, "try {$n", [])
expr(p, t[0], d)
lineCg(p, cpsStmts, "}\n", [])
lineCg(p, cpsStmts, "}$n", [])
else:
startBlock(p, "try {\n")
startBlock(p, "try {$n")
expr(p, t[0], d)
endBlock(p)
# First pass: handle Nim based exceptions:
#lineCg(p, cpsStmts, "catch (#Exception* T$1_) {\n", [etmp+1])
startBlock(p, "catch (#Exception* T$1_) {\n", rope(etmp+1))
lineCg(p, cpsStmts, "catch (#Exception* T$1_) {$n", [etmp+1])
genRestoreFrameAfterException(p)
# an unhandled exception happened!
lineCg(p, cpsStmts, "T$1_ = std::current_exception();\n", [etmp])
lineCg(p, cpsStmts, "T$1_ = std::current_exception();$n", [etmp])
p.nestedTryStmts[^1].inExcept = true
var hasImportedCppExceptions = false
var i = 1
@@ -1063,9 +1061,9 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
if hasIf: lineF(p, cpsStmts, "else ", [])
startBlock(p)
# we handled the error:
linefmt(p, cpsStmts, "T$1_ = nullptr;\n", [etmp])
linefmt(p, cpsStmts, "T$1_ = nullptr;$n", [etmp])
expr(p, t[i][0], d)
linefmt(p, cpsStmts, "#popCurrentException();\n", [])
linefmt(p, cpsStmts, "#popCurrentException();$n", [])
endBlock(p)
else:
var orExpr = newRopeAppender()
@@ -1090,25 +1088,24 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
if orExpr.len != 0:
if hasIf:
startBlock(p, "else if ($1) {\n", [orExpr])
startBlock(p, "else if ($1) {$n", [orExpr])
else:
startBlock(p, "if ($1) {\n", [orExpr])
startBlock(p, "if ($1) {$n", [orExpr])
hasIf = true
if exvar != nil:
fillLocalName(p, exvar.sym)
fillLoc(exvar.sym.loc, locTemp, exvar, OnStack)
linefmt(p, cpsStmts, "$1 $2 = T$3_;\n", [getTypeDesc(p.module, exvar.sym.typ),
linefmt(p, cpsStmts, "$1 $2 = T$3_;$n", [getTypeDesc(p.module, exvar.sym.typ),
rdLoc(exvar.sym.loc), rope(etmp+1)])
# we handled the error:
linefmt(p, cpsStmts, "T$1_ = nullptr;\n", [etmp])
linefmt(p, cpsStmts, "T$1_ = nullptr;$n", [etmp])
expr(p, t[i][^1], d)
linefmt(p, cpsStmts, "#popCurrentException();\n", [])
linefmt(p, cpsStmts, "#popCurrentException();$n", [])
endBlock(p)
inc(i)
if hasIf and not hasElse:
linefmt(p, cpsStmts, "else throw;\n", [etmp])
#linefmt(p, cpsStmts, "}\n", [])
endBlock(p)
linefmt(p, cpsStmts, "else throw;$n", [etmp])
linefmt(p, cpsStmts, "}$n", [])
# Second pass: handle C++ based exceptions:
template genExceptBranchBody(body: PNode) {.dirty.} =
@@ -1127,7 +1124,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
if t[i].len == 1:
# general except section:
startBlock(p, "catch (...) {\n", [])
startBlock(p, "catch (...) {$n", [])
genExceptBranchBody(t[i][0])
endBlock(p)
catchAllPresent = true
@@ -1140,11 +1137,11 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
let exvar = t[i][j][2] # ex1 in `except ExceptType as ex1:`
fillLocalName(p, exvar.sym)
fillLoc(exvar.sym.loc, locTemp, exvar, OnStack)
startBlock(p, "catch ($1& $2) {\n", getTypeDesc(p.module, typeNode.typ), rdLoc(exvar.sym.loc))
startBlock(p, "catch ($1& $2) {$n", getTypeDesc(p.module, typeNode.typ), rdLoc(exvar.sym.loc))
genExceptBranchBody(t[i][^1]) # exception handler body will duplicated for every type
endBlock(p)
elif isImportedException(typeNode.typ, p.config):
startBlock(p, "catch ($1&) {\n", getTypeDesc(p.module, t[i][j].typ))
startBlock(p, "catch ($1&) {$n", getTypeDesc(p.module, t[i][j].typ))
genExceptBranchBody(t[i][^1]) # exception handler body will duplicated for every type
endBlock(p)
@@ -1153,14 +1150,14 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
# general finally block:
if t.len > 0 and t[^1].kind == nkFinally:
if not catchAllPresent:
startBlock(p, "catch (...) {\n", [])
startBlock(p, "catch (...) {$n", [])
genRestoreFrameAfterException(p)
linefmt(p, cpsStmts, "T$1_ = std::current_exception();\n", [etmp])
linefmt(p, cpsStmts, "T$1_ = std::current_exception();$n", [etmp])
endBlock(p)
startBlock(p)
genStmts(p, t[^1][0])
linefmt(p, cpsStmts, "if (T$1_) std::rethrow_exception(T$1_);\n", [etmp])
linefmt(p, cpsStmts, "if (T$1_) std::rethrow_exception(T$1_);$n", [etmp])
endBlock(p)
proc genTryCppOld(p: BProc, t: PNode, d: var TLoc) =

View File

@@ -524,14 +524,14 @@ proc genRecordFieldsAux(m: BModule; n: PNode,
else:
unionBody.addf("#pragma pack(push, 1)$nstruct{", [])
unionBody.add(a)
unionBody.addf("} $1;\n", [structName])
unionBody.addf("} $1;$n", [structName])
if tfPacked in rectype.flags and hasAttribute notin CC[m.config.cCompiler].props:
unionBody.addf("#pragma pack(pop)\n", [])
unionBody.addf("#pragma pack(pop)$n", [])
else:
genRecordFieldsAux(m, k, rectype, check, unionBody, unionPrefix)
else: internalError(m.config, "genRecordFieldsAux(record case branch)")
if unionBody != "":
result.addf("union{\n$1};\n", [unionBody])
result.addf("union{\n$1};$n", [unionBody])
of nkSym:
let field = n.sym
if field.typ.kind == tyVoid: return
@@ -548,20 +548,20 @@ proc genRecordFieldsAux(m: BModule; n: PNode,
let fieldType = field.loc.lode.typ.skipTypes(abstractInst)
if fieldType.kind == tyUncheckedArray:
result.addf("\t$1 $2[SEQ_DECL_SIZE];\n",
result.addf("\t$1 $2[SEQ_DECL_SIZE];$n",
[getTypeDescAux(m, fieldType.elemType, check, skField), sname])
elif fieldType.kind == tySequence:
# we need to use a weak dependency here for trecursive_table.
result.addf("\t$1$3 $2;\n", [getTypeDescWeak(m, field.loc.t, check, skField), sname, noAlias])
result.addf("\t$1$3 $2;$n", [getTypeDescWeak(m, field.loc.t, check, skField), sname, noAlias])
elif field.bitsize != 0:
result.addf("\t$1$4 $2:$3;\n", [getTypeDescAux(m, field.loc.t, check, skField), sname, rope($field.bitsize), noAlias])
result.addf("\t$1$4 $2:$3;$n", [getTypeDescAux(m, field.loc.t, check, skField), sname, rope($field.bitsize), noAlias])
else:
# don't use fieldType here because we need the
# tyGenericInst for C++ template support
if fieldType.isOrHasImportedCppType():
result.addf("\t$1$3 $2{};\n", [getTypeDescAux(m, field.loc.t, check, skField), sname, noAlias])
result.addf("\t$1$3 $2{};$n", [getTypeDescAux(m, field.loc.t, check, skField), sname, noAlias])
else:
result.addf("\t$1$3 $2;\n", [getTypeDescAux(m, field.loc.t, check, skField), sname, noAlias])
result.addf("\t$1$3 $2;$n", [getTypeDescAux(m, field.loc.t, check, skField), sname, noAlias])
else: internalError(m.config, n.info, "genRecordFieldsAux()")
proc getRecordFields(m: BModule; typ: PType, check: var IntSet): Rope =
@@ -584,30 +584,30 @@ proc getRecordDescAux(m: BModule; typ: PType, name, baseType: Rope,
if typ.kind == tyObject:
if typ[0] == nil:
if lacksMTypeField(typ):
appcg(m, result, " {\n", [])
appcg(m, result, " {$n", [])
else:
if optTinyRtti in m.config.globalOptions:
appcg(m, result, " {$n#TNimTypeV2* m_type;\n", [])
appcg(m, result, " {$n#TNimTypeV2* m_type;$n", [])
else:
appcg(m, result, " {$n#TNimType* m_type;\n", [])
appcg(m, result, " {$n#TNimType* m_type;$n", [])
hasField = true
elif m.compileToCpp:
appcg(m, result, " : public $1 {\n", [baseType])
appcg(m, result, " : public $1 {$n", [baseType])
if typ.isException and m.config.exc == excCpp:
when false:
appcg(m, result, "virtual void raise() { throw *this; }\n", []) # required for polymorphic exceptions
appcg(m, result, "virtual void raise() { throw *this; }$n", []) # required for polymorphic exceptions
if typ.sym.magic == mException:
# Add cleanup destructor to Exception base class
appcg(m, result, "~$1();\n", [name])
appcg(m, result, "~$1();$n", [name])
# define it out of the class body and into the procs section so we don't have to
# artificially forward-declare popCurrentExceptionEx (very VERY troublesome for HCR)
appcg(m, cfsProcs, "inline $1::~$1() {if(this->raiseId) #popCurrentExceptionEx(this->raiseId);}\n", [name])
appcg(m, cfsProcs, "inline $1::~$1() {if(this->raiseId) #popCurrentExceptionEx(this->raiseId);}$n", [name])
hasField = true
else:
appcg(m, result, " {$n $1 Sup;\n", [baseType])
appcg(m, result, " {$n $1 Sup;$n", [baseType])
hasField = true
else:
result.addf(" {\n", [name])
result.addf(" {$n", [name])
proc getRecordDesc(m: BModule; typ: PType, name: Rope,
check: var IntSet): Rope =
@@ -629,7 +629,7 @@ proc getRecordDesc(m: BModule; typ: PType, name: Rope,
result.add(getRecordDescAux(m, typ, name, baseType, check, hasField))
let desc = getRecordFields(m, typ, check)
if desc == "" and not hasField:
result.addf("char dummy;\n", [])
result.addf("char dummy;$n", [])
else:
result.add(desc)
result.add("};\L")

View File

@@ -276,7 +276,7 @@ proc genCLineDir(r: var Rope, filename: string, line: int; conf: ConfigRef) =
r.addf("\n#line $2 $1\n",
[rope(makeSingleLineCString(filename)), rope(line)])
proc genCLineDir(r: var Rope, filename: string, line: int; p: BProc; info: TLineInfo; lastFileIndex: FileIndex; lastLine: uint16) =
proc genCLineDir(r: var Rope, filename: string, line: int; p: BProc; info: TLineInfo; lastFileIndex: FileIndex) =
assert line >= 0
if optLineDir in p.config.options and line > 0:
if lastFileIndex == info.fileIndex:
@@ -296,18 +296,24 @@ proc freshLineInfo(p: BProc; info: TLineInfo): bool =
p.lastLineInfo.fileIndex = info.fileIndex
result = true
proc genCLineDir(r: var Rope, p: BProc, info: TLineInfo; conf: ConfigRef) =
if optLineDir in conf.options:
let lastFileIndex = p.lastLineInfo.fileIndex
if freshLineInfo(p, info):
genCLineDir(r, toFullPath(conf, info), info.safeLineNm, p, info, lastFileIndex)
proc genLineDir(p: BProc, t: PNode) =
let line = t.info.safeLineNm
if optEmbedOrigSrc in p.config.globalOptions:
p.s(cpsStmts).add("//" & sourceLine(p.config, t.info) & "\L")
let lastFileIndex = p.lastLineInfo.fileIndex
let freshLine = freshLineInfo(p, t.info)
if freshLine:
genCLineDir(p.s(cpsStmts), toFullPath(p.config, t.info), line, p, t.info, lastFileIndex)
if ({optLineTrace, optStackTrace} * p.options == {optLineTrace, optStackTrace}) and
(p.prc == nil or sfPure notin p.prc.flags) and t.info.fileIndex != InvalidFileIdx:
let lastFileIndex = p.lastLineInfo.fileIndex
let lastLine = p.lastLineInfo.line
let freshLine = freshLineInfo(p, t.info)
if freshLine:
genCLineDir(p.s(cpsStmts), toFullPath(p.config, t.info), line, p, t.info, lastFileIndex, lastLine)
if lastFileIndex == t.info.fileIndex:
linefmt(p, cpsStmts, "nimln_($1);\n",
[line])
@@ -473,9 +479,9 @@ proc resetLoc(p: BProc, loc: var TLoc) =
let atyp = skipTypes(loc.t, abstractInst)
if atyp.kind in {tyVar, tyLent}:
linefmt(p, cpsStmts, "$1->len = 0; $1->p = NIM_NIL;\n", [rdLoc(loc)])
linefmt(p, cpsStmts, "$1->len = 0; $1->p = NIM_NIL;$n", [rdLoc(loc)])
else:
linefmt(p, cpsStmts, "$1.len = 0; $1.p = NIM_NIL;\n", [rdLoc(loc)])
linefmt(p, cpsStmts, "$1.len = 0; $1.p = NIM_NIL;$n", [rdLoc(loc)])
elif not isComplexValueType(typ):
if containsGcRef:
var nilLoc: TLoc
@@ -488,7 +494,7 @@ proc resetLoc(p: BProc, loc: var TLoc) =
if loc.storage != OnStack and containsGcRef:
specializeReset(p, loc)
when false:
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);\n",
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
[addrLoc(p.config, loc), genTypeInfoV1(p.module, loc.t, loc.lode.info)])
# XXX: generated reset procs should not touch the m_type
# field, so disabling this should be safe:
@@ -496,7 +502,7 @@ proc resetLoc(p: BProc, loc: var TLoc) =
else:
# array passed as argument decayed into pointer, bug #7332
# so we use getTypeDesc here rather than rdLoc(loc)
linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));\n",
linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n",
[addrLoc(p.config, loc),
getTypeDesc(p.module, loc.t, mapTypeChooser(loc))])
# XXX: We can be extra clever here and call memset only
@@ -506,7 +512,7 @@ proc resetLoc(p: BProc, loc: var TLoc) =
proc constructLoc(p: BProc, loc: var TLoc, isTemp = false) =
let typ = loc.t
if optSeqDestructors in p.config.globalOptions and skipTypes(typ, abstractInst + {tyStatic}).kind in {tyString, tySequence}:
linefmt(p, cpsStmts, "$1.len = 0; $1.p = NIM_NIL;\n", [rdLoc(loc)])
linefmt(p, cpsStmts, "$1.len = 0; $1.p = NIM_NIL;$n", [rdLoc(loc)])
elif not isComplexValueType(typ):
if containsGarbageCollectedRef(loc.t):
var nilLoc: TLoc
@@ -514,14 +520,14 @@ proc constructLoc(p: BProc, loc: var TLoc, isTemp = false) =
nilLoc.r = rope("NIM_NIL")
genRefAssign(p, loc, nilLoc)
else:
linefmt(p, cpsStmts, "$1 = ($2)0;\n", [rdLoc(loc),
linefmt(p, cpsStmts, "$1 = ($2)0;$n", [rdLoc(loc),
getTypeDesc(p.module, typ, mapTypeChooser(loc))])
else:
if not isTemp or containsGarbageCollectedRef(loc.t):
# don't use nimZeroMem for temporary values for performance if we can
# avoid it:
if not isOrHasImportedCppType(typ):
linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));\n",
linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n",
[addrLoc(p.config, loc), getTypeDesc(p.module, typ, mapTypeChooser(loc))])
genObjectInit(p, cpsStmts, loc.t, loc, constructObj)
@@ -541,9 +547,9 @@ proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) =
inc(p.labels)
result.r = "T" & rope(p.labels) & "_"
if p.module.compileToCpp and isOrHasImportedCppType(t):
linefmt(p, cpsLocals, "$1 $2{};\n", [getTypeDesc(p.module, t, skVar), result.r])
linefmt(p, cpsLocals, "$1 $2{};$n", [getTypeDesc(p.module, t, skVar), result.r])
else:
linefmt(p, cpsLocals, "$1 $2;\n", [getTypeDesc(p.module, t, skVar), result.r])
linefmt(p, cpsLocals, "$1 $2;$n", [getTypeDesc(p.module, t, skVar), result.r])
result.k = locTemp
result.lode = lodeTyp t
result.storage = OnStack
@@ -561,7 +567,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) =
proc getTempCpp(p: BProc, t: PType, result: var TLoc; value: Rope) =
inc(p.labels)
result.r = "T" & rope(p.labels) & "_"
linefmt(p, cpsStmts, "$1 $2 = $3;\n", [getTypeDesc(p.module, t, skVar), result.r, value])
linefmt(p, cpsStmts, "$1 $2 = $3;$n", [getTypeDesc(p.module, t, skVar), result.r, value])
result.k = locTemp
result.lode = lodeTyp t
result.storage = OnStack
@@ -570,7 +576,7 @@ proc getTempCpp(p: BProc, t: PType, result: var TLoc; value: Rope) =
proc getIntTemp(p: BProc, result: var TLoc) =
inc(p.labels)
result.r = "T" & rope(p.labels) & "_"
linefmt(p, cpsLocals, "NI $1;\n", [result.r])
linefmt(p, cpsLocals, "NI $1;$n", [result.r])
result.k = locTemp
result.storage = OnStack
result.lode = lodeTyp getSysType(p.module.g.graph, unknownLineInfo, tyInt)
@@ -585,13 +591,7 @@ proc localVarDecl(p: BProc; n: PNode): Rope =
if s.kind in {skLet, skVar, skField, skForVar} and s.alignment > 0:
result.addf("NIM_ALIGN($1) ", [rope(s.alignment)])
if optLineDir in p.config.options:
let line = n.info.safeLineNm
let lastFileIndex = p.lastLineInfo.fileIndex
let lastLine = p.lastLineInfo.line
discard freshLineInfo(p, n.info)
genCLineDir(result, toFullPath(p.config, n.info), line, p, n.info, lastFileIndex, lastLine)
addIndent(p, result)
genCLineDir(result, p, n.info, p.config)
result.add getTypeDesc(p.module, s.typ, skVar)
if s.constraint.isNil:
@@ -609,8 +609,8 @@ proc assignLocalVar(p: BProc, n: PNode) =
#assert(s.loc.k == locNone) # not yet assigned
# this need not be fulfilled for inline procs; they are regenerated
# for each module that uses them!
#let nl = if optLineDir in p.config.options: "" else: "\n"
let decl = localVarDecl(p, n) & (if p.module.compileToCpp and isOrHasImportedCppType(n.typ): "{};\n" else: ";\n")
let nl = if optLineDir in p.config.options: "" else: "\n"
let decl = localVarDecl(p, n) & (if p.module.compileToCpp and isOrHasImportedCppType(n.typ): "{};" else: ";") & nl
line(p, cpsLocals, decl)
include ccgthreadvars
@@ -707,7 +707,6 @@ proc getLabel(p: BProc): TLabel =
result = "LA" & rope(p.labels) & "_"
proc fixLabel(p: BProc, labl: TLabel) =
#lineF(p, cpsStmts, "$1: ;$n", [labl])
p.s(cpsStmts).add("$1: ;$n" % [labl])
proc genVarPrototype(m: BModule, n: PNode)
@@ -761,7 +760,7 @@ $1define nimfr_(proc, file) \
appcg(p.module, p.module.s[cfsFrameDefines], frameDefines, ["#"])
cgsym(p.module, "nimFrame")
result = ropecg(p.module, "\tnimfr_($1, $2);\n", [procname, filename])
result = ropecg(p.module, "\tnimfr_($1, $2);$n", [procname, filename])
proc initFrameNoDebug(p: BProc; frame, procname, filename: Rope; line: int): Rope =
cgsym(p.module, "nimFrame")
@@ -774,7 +773,7 @@ proc deinitFrameNoDebug(p: BProc; frame: Rope): Rope =
result = ropecg(p.module, "\t#popFrameOfAddr(&$1);$n", [frame])
proc deinitFrame(p: BProc): Rope =
result = ropecg(p.module, "\t#popFrame();\n", [])
result = ropecg(p.module, "\t#popFrame();$n", [])
include ccgexprs
@@ -1137,6 +1136,9 @@ proc genProcAux*(m: BModule, prc: PSym) =
if sfInjectDestructors in prc.flags:
procBody = injectDestructorCalls(m.g.graph, m.idgen, prc, procBody)
let tmpInfo = prc.info
discard freshLineInfo(p, prc.info)
if sfPure notin prc.flags and prc.typ[0] != nil:
if resultPos >= prc.ast.len:
internalError(m.config, prc.info, "proc has no result symbol")
@@ -1148,13 +1150,13 @@ proc genProcAux*(m: BModule, prc: PSym) =
var decl = localVarDecl(p, resNode)
var a: TLoc
initLocExprSingleUse(p, val, a)
linefmt(p, cpsStmts, "$1 = $2;\n", [decl, rdLoc(a)])
linefmt(p, cpsStmts, "$1 = $2;$n", [decl, rdLoc(a)])
else:
# declare the result symbol:
assignLocalVar(p, resNode)
assert(res.loc.r != "")
initLocalVar(p, res, immediateAsgn=false)
returnStmt = ropecg(p.module, "\treturn $1;\n", [rdLoc(res.loc)])
returnStmt = ropecg(p.module, "\treturn $1;$n", [rdLoc(res.loc)])
else:
fillResult(p.config, resNode, prc.typ)
assignParam(p, res, prc.typ[0])
@@ -1179,6 +1181,8 @@ proc genProcAux*(m: BModule, prc: PSym) =
closureSetup(p, prc)
genProcBody(p, procBody)
prc.info = tmpInfo
var generatedProc: Rope
generatedProc.genCLineDir prc.info, m.config
if isNoReturn(p.module, prc):
@@ -1195,7 +1199,7 @@ proc genProcAux*(m: BModule, prc: PSym) =
# This fixes the use of methods and also the case when 2 functions within the same module
# call each other using directly the "_actual" versions (an optimization) - see issue #11608
m.s[cfsProcHeaders].addf("$1;\n", [header])
generatedProc.add ropecg(p.module, "$1 {\n", [header])
generatedProc.add ropecg(p.module, "$1 {$n", [header])
if optStackTrace in prc.options:
generatedProc.add(p.s(cpsLocals))
var procname = makeCString(prc.name.s)
@@ -1210,7 +1214,7 @@ proc genProcAux*(m: BModule, prc: PSym) =
if beforeRetNeeded in p.flags: generatedProc.add("{")
generatedProc.add(p.s(cpsInit))
generatedProc.add(p.s(cpsStmts))
if beforeRetNeeded in p.flags: generatedProc.add("\t}\nBeforeRet_: ;\n")
if beforeRetNeeded in p.flags: generatedProc.add("\t}BeforeRet_: ;\n")
if optStackTrace in prc.options: generatedProc.add(deinitFrame(p))
generatedProc.add(returnStmt)
generatedProc.add("}\n")