Multiple C lines corresponding to a single nimrod line are joined together
This patch greatly improves the "step over" operation available in debuggers. In practice, there are often 4-8 lines of C code generated for each nimrod line Each such line will be responsible to a single step in the debugger that is a) not expected by the user b) taking the user to an incorrect line in the nimrod code To keep this working, all code generation should use the rope formatting facilities when producing new lines (i.e. $n and $N). New semantics for the format string are introduced: $n means "soft new line" that could be joined/broken when lineDir is enabled. $N means "hard new line" that will always appear as a new line. As an alternative to this approach, I also tested producing code like this: #line "code.nim" 154 foo = bar; \ foo(bar) \ This is better for readability of the final output, but unfortunately it didn't produce the desired result across all compilers/debuggers.
This commit is contained in:
parent
0f0dfd6379
commit
0b197ade6c
6 changed files with 81 additions and 61 deletions
|
|
@ -105,7 +105,7 @@ proc bitSetToWord(s: TBitSet, size: int): BiggestInt =
|
||||||
proc genRawSetData(cs: TBitSet, size: int): PRope =
|
proc genRawSetData(cs: TBitSet, size: int): PRope =
|
||||||
var frmt: TFormatStr
|
var frmt: TFormatStr
|
||||||
if size > 8:
|
if size > 8:
|
||||||
result = toRope('{' & tnl)
|
result = ropef("{$n")
|
||||||
for i in countup(0, size - 1):
|
for i in countup(0, size - 1):
|
||||||
if i < size - 1:
|
if i < size - 1:
|
||||||
# not last iteration?
|
# not last iteration?
|
||||||
|
|
@ -797,14 +797,14 @@ proc fixupCall(p: BProc, t: PNode, d: var TLoc, pl: PRope) =
|
||||||
app(pl, addrLoc(d))
|
app(pl, addrLoc(d))
|
||||||
app(pl, ")")
|
app(pl, ")")
|
||||||
app(p.s[cpsStmts], pl)
|
app(p.s[cpsStmts], pl)
|
||||||
app(p.s[cpsStmts], ';' & tnl)
|
appf(p.s[cpsStmts], ";$n")
|
||||||
else:
|
else:
|
||||||
var tmp: TLoc
|
var tmp: TLoc
|
||||||
getTemp(p, typ.sons[0], tmp)
|
getTemp(p, typ.sons[0], tmp)
|
||||||
app(pl, addrLoc(tmp))
|
app(pl, addrLoc(tmp))
|
||||||
app(pl, ")")
|
app(pl, ")")
|
||||||
app(p.s[cpsStmts], pl)
|
app(p.s[cpsStmts], pl)
|
||||||
app(p.s[cpsStmts], ';' & tnl)
|
appf(p.s[cpsStmts], ";$n")
|
||||||
genAssignment(p, d, tmp, {}) # no need for deep copying
|
genAssignment(p, d, tmp, {}) # no need for deep copying
|
||||||
else:
|
else:
|
||||||
app(pl, ")")
|
app(pl, ")")
|
||||||
|
|
@ -817,7 +817,7 @@ proc fixupCall(p: BProc, t: PNode, d: var TLoc, pl: PRope) =
|
||||||
else:
|
else:
|
||||||
app(pl, ")")
|
app(pl, ")")
|
||||||
app(p.s[cpsStmts], pl)
|
app(p.s[cpsStmts], pl)
|
||||||
app(p.s[cpsStmts], ';' & tnl)
|
appf(p.s[cpsStmts], ";$n")
|
||||||
|
|
||||||
proc openArrayLoc(a: TLoc): PRope =
|
proc openArrayLoc(a: TLoc): PRope =
|
||||||
case skipTypes(a.t, abstractVar).kind
|
case skipTypes(a.t, abstractVar).kind
|
||||||
|
|
@ -926,14 +926,14 @@ proc genNamedParamCall(p: BProc, t: PNode, d: var TLoc) =
|
||||||
app(pl, addrLoc(d))
|
app(pl, addrLoc(d))
|
||||||
app(pl, "]")
|
app(pl, "]")
|
||||||
app(p.s[cpsStmts], pl)
|
app(p.s[cpsStmts], pl)
|
||||||
app(p.s[cpsStmts], ';' & tnl)
|
appf(p.s[cpsStmts], ";$n")
|
||||||
else:
|
else:
|
||||||
var tmp: TLoc
|
var tmp: TLoc
|
||||||
getTemp(p, typ.sons[0], tmp)
|
getTemp(p, typ.sons[0], tmp)
|
||||||
app(pl, addrLoc(tmp))
|
app(pl, addrLoc(tmp))
|
||||||
app(pl, "]")
|
app(pl, "]")
|
||||||
app(p.s[cpsStmts], pl)
|
app(p.s[cpsStmts], pl)
|
||||||
app(p.s[cpsStmts], ';' & tnl)
|
appf(p.s[cpsStmts], ";$n")
|
||||||
genAssignment(p, d, tmp, {}) # no need for deep copying
|
genAssignment(p, d, tmp, {}) # no need for deep copying
|
||||||
else:
|
else:
|
||||||
app(pl, "]")
|
app(pl, "]")
|
||||||
|
|
@ -946,7 +946,7 @@ proc genNamedParamCall(p: BProc, t: PNode, d: var TLoc) =
|
||||||
else:
|
else:
|
||||||
app(pl, "]")
|
app(pl, "]")
|
||||||
app(p.s[cpsStmts], pl)
|
app(p.s[cpsStmts], pl)
|
||||||
app(p.s[cpsStmts], ';' & tnl)
|
appf(p.s[cpsStmts], ";$n")
|
||||||
|
|
||||||
proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
|
proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
|
||||||
# <Nimrod code>
|
# <Nimrod code>
|
||||||
|
|
@ -1839,7 +1839,7 @@ proc genConstSimpleList(p: BProc, n: PNode): PRope =
|
||||||
for i in countup(0, length - 2):
|
for i in countup(0, length - 2):
|
||||||
appf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])])
|
appf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])])
|
||||||
if length > 0: app(result, genNamedConstExpr(p, n.sons[length - 1]))
|
if length > 0: app(result, genNamedConstExpr(p, n.sons[length - 1]))
|
||||||
app(result, '}' & tnl)
|
appf(result, "}$n")
|
||||||
|
|
||||||
proc genConstExpr(p: BProc, n: PNode): PRope =
|
proc genConstExpr(p: BProc, n: PNode): PRope =
|
||||||
case n.Kind
|
case n.Kind
|
||||||
|
|
|
||||||
|
|
@ -13,22 +13,6 @@ const
|
||||||
stringCaseThreshold = 8
|
stringCaseThreshold = 8
|
||||||
# above X strings a hash-switch for strings is generated
|
# above X strings a hash-switch for strings is generated
|
||||||
|
|
||||||
proc genLineDir(p: BProc, t: PNode) =
|
|
||||||
var line = toLinenumber(t.info) # BUGFIX
|
|
||||||
if line < 0:
|
|
||||||
line = 0 # negative numbers are not allowed in #line
|
|
||||||
if optLineDir in p.Options and line > 0:
|
|
||||||
appff(p.s[cpsStmts], "#line $2 $1$n", "; line $2 \"$1\"$n",
|
|
||||||
[toRope(makeSingleLineCString(toFullPath(t.info))), toRope(line)])
|
|
||||||
if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and
|
|
||||||
(p.prc == nil or sfPure notin p.prc.flags):
|
|
||||||
appcg(p, cpsStmts, "#endb($1);$n", [toRope(line)])
|
|
||||||
elif ({optLineTrace, optStackTrace} * p.Options ==
|
|
||||||
{optLineTrace, optStackTrace}) and
|
|
||||||
(p.prc == nil or sfPure notin p.prc.flags):
|
|
||||||
appf(p.s[cpsStmts], "F.line = $1;F.filename = $2;$n",
|
|
||||||
[toRope(line), makeCString(toFilename(t.info).extractFilename)])
|
|
||||||
|
|
||||||
proc genVarTuple(p: BProc, n: PNode) =
|
proc genVarTuple(p: BProc, n: PNode) =
|
||||||
var tup, field: TLoc
|
var tup, field: TLoc
|
||||||
if n.kind != nkVarTuple: InternalError(n.info, "genVarTuple")
|
if n.kind != nkVarTuple: InternalError(n.info, "genVarTuple")
|
||||||
|
|
@ -171,14 +155,14 @@ proc genWhileStmt(p: BProc, t: PNode) =
|
||||||
setlen(p.blocks, length + 1)
|
setlen(p.blocks, length + 1)
|
||||||
p.blocks[length].id = - p.labels # negative because it isn't used yet
|
p.blocks[length].id = - p.labels # negative because it isn't used yet
|
||||||
p.blocks[length].nestedTryStmts = p.nestedTryStmts.len
|
p.blocks[length].nestedTryStmts = p.nestedTryStmts.len
|
||||||
app(p.s[cpsStmts], "while (1) {" & tnl)
|
appf(p.s[cpsStmts], "while (1) {$n")
|
||||||
initLocExpr(p, t.sons[0], a)
|
initLocExpr(p, t.sons[0], a)
|
||||||
if (t.sons[0].kind != nkIntLit) or (t.sons[0].intVal == 0):
|
if (t.sons[0].kind != nkIntLit) or (t.sons[0].intVal == 0):
|
||||||
p.blocks[length].id = abs(p.blocks[length].id)
|
p.blocks[length].id = abs(p.blocks[length].id)
|
||||||
appf(p.s[cpsStmts], "if (!$1) goto $2;$n", [rdLoc(a), Labl])
|
appf(p.s[cpsStmts], "if (!$1) goto $2;$n", [rdLoc(a), Labl])
|
||||||
genStmts(p, t.sons[1])
|
genStmts(p, t.sons[1])
|
||||||
if p.blocks[length].id > 0: appf(p.s[cpsStmts], "} $1: ;$n", [Labl])
|
if p.blocks[length].id > 0: appf(p.s[cpsStmts], "} $1: ;$n", [Labl])
|
||||||
else: app(p.s[cpsStmts], '}' & tnl)
|
else: appf(p.s[cpsStmts], "}$n")
|
||||||
setlen(p.blocks, len(p.blocks) - 1)
|
setlen(p.blocks, len(p.blocks) - 1)
|
||||||
dec(p.withinLoop)
|
dec(p.withinLoop)
|
||||||
|
|
||||||
|
|
@ -231,9 +215,9 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
# reraise the last exception:
|
# reraise the last exception:
|
||||||
#if gCmd == cmdCompileToCpp:
|
#if gCmd == cmdCompileToCpp:
|
||||||
# appcg(p, cpsStmts, "throw;" & tnl)
|
# appcg(p, cpsStmts, "throw;$n")
|
||||||
#else:
|
#else:
|
||||||
appcg(p, cpsStmts, "#reraiseException();" & tnl)
|
appcg(p, cpsStmts, "#reraiseException();$n")
|
||||||
|
|
||||||
proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
|
proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
|
||||||
rangeFormat, eqFormat: TFormatStr, labl: TLabel) =
|
rangeFormat, eqFormat: TFormatStr, labl: TLabel) =
|
||||||
|
|
@ -326,7 +310,7 @@ proc genStringCase(p: BProc, t: PNode) =
|
||||||
if branches[j] != nil:
|
if branches[j] != nil:
|
||||||
appf(p.s[cpsStmts], "case $1: $n$2break;$n",
|
appf(p.s[cpsStmts], "case $1: $n$2break;$n",
|
||||||
[intLiteral(j), branches[j]])
|
[intLiteral(j), branches[j]])
|
||||||
app(p.s[cpsStmts], '}' & tnl) # else statement:
|
appf(p.s[cpsStmts], "}$n") # else statement:
|
||||||
if t.sons[sonsLen(t) - 1].kind != nkOfBranch:
|
if t.sons[sonsLen(t) - 1].kind != nkOfBranch:
|
||||||
appf(p.s[cpsStmts], "goto LA$1;$n", [toRope(p.labels)])
|
appf(p.s[cpsStmts], "goto LA$1;$n", [toRope(p.labels)])
|
||||||
# third pass: generate statements
|
# third pass: generate statements
|
||||||
|
|
@ -388,13 +372,13 @@ proc genOrdinalCase(p: BProc, n: PNode) =
|
||||||
genStmts(p, branch[length-1])
|
genStmts(p, branch[length-1])
|
||||||
else:
|
else:
|
||||||
# else part of case statement:
|
# else part of case statement:
|
||||||
app(p.s[cpsStmts], "default:" & tnl)
|
appf(p.s[cpsStmts], "default:$n")
|
||||||
genStmts(p, branch[0])
|
genStmts(p, branch[0])
|
||||||
hasDefault = true
|
hasDefault = true
|
||||||
app(p.s[cpsStmts], "break;" & tnl)
|
appf(p.s[cpsStmts], "break;$n")
|
||||||
if (hasAssume in CC[ccompiler].props) and not hasDefault:
|
if (hasAssume in CC[ccompiler].props) and not hasDefault:
|
||||||
app(p.s[cpsStmts], "default: __assume(0);" & tnl)
|
appf(p.s[cpsStmts], "default: __assume(0);$n")
|
||||||
app(p.s[cpsStmts], '}' & tnl)
|
appf(p.s[cpsStmts], "}$n")
|
||||||
if Lend != nil: fixLabel(p, Lend)
|
if Lend != nil: fixLabel(p, Lend)
|
||||||
|
|
||||||
proc genCaseStmt(p: BProc, t: PNode) =
|
proc genCaseStmt(p: BProc, t: PNode) =
|
||||||
|
|
@ -453,7 +437,7 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
|
||||||
appf(p.s[cpsLocals], "volatile NIM_BOOL $1 = NIM_FALSE;$n", [rethrowFlag])
|
appf(p.s[cpsLocals], "volatile NIM_BOOL $1 = NIM_FALSE;$n", [rethrowFlag])
|
||||||
if optStackTrace in p.Options:
|
if optStackTrace in p.Options:
|
||||||
appcg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
|
appcg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
|
||||||
app(p.s[cpsStmts], "try {" & tnl)
|
appf(p.s[cpsStmts], "try {$n")
|
||||||
add(p.nestedTryStmts, t)
|
add(p.nestedTryStmts, t)
|
||||||
genStmts(p, t.sons[0])
|
genStmts(p, t.sons[0])
|
||||||
length = sonsLen(t)
|
length = sonsLen(t)
|
||||||
|
|
@ -467,7 +451,7 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
|
||||||
blen = sonsLen(t.sons[i])
|
blen = sonsLen(t.sons[i])
|
||||||
if blen == 1:
|
if blen == 1:
|
||||||
# general except section:
|
# general except section:
|
||||||
app(p.s[cpsStmts], "default: " & tnl)
|
appf(p.s[cpsStmts], "default:$n")
|
||||||
genStmts(p, t.sons[i].sons[0])
|
genStmts(p, t.sons[i].sons[0])
|
||||||
else:
|
else:
|
||||||
for j in countup(0, blen - 2):
|
for j in countup(0, blen - 2):
|
||||||
|
|
@ -476,10 +460,10 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
|
||||||
genStmts(p, t.sons[i].sons[blen - 1])
|
genStmts(p, t.sons[i].sons[blen - 1])
|
||||||
if rethrowFlag != nil:
|
if rethrowFlag != nil:
|
||||||
appf(p.s[cpsStmts], "$1 = NIM_FALSE; ", [rethrowFlag])
|
appf(p.s[cpsStmts], "$1 = NIM_FALSE; ", [rethrowFlag])
|
||||||
app(p.s[cpsStmts], "break;" & tnl)
|
appf(p.s[cpsStmts], "break;$n")
|
||||||
inc(i)
|
inc(i)
|
||||||
if t.sons[1].kind == nkExceptBranch:
|
if t.sons[1].kind == nkExceptBranch:
|
||||||
app(p.s[cpsStmts], "}}" & tnl) # end of catch-switch statement
|
appf(p.s[cpsStmts], "}}$n") # end of catch-switch statement
|
||||||
appcg(p, cpsStmts, "#popSafePoint();")
|
appcg(p, cpsStmts, "#popSafePoint();")
|
||||||
discard pop(p.nestedTryStmts)
|
discard pop(p.nestedTryStmts)
|
||||||
if (i < length) and (t.sons[i].kind == nkFinally):
|
if (i < length) and (t.sons[i].kind == nkFinally):
|
||||||
|
|
@ -528,10 +512,10 @@ proc genTryStmt(p: BProc, t: PNode) =
|
||||||
var blen = sonsLen(t.sons[i])
|
var blen = sonsLen(t.sons[i])
|
||||||
if blen == 1:
|
if blen == 1:
|
||||||
# general except section:
|
# general except section:
|
||||||
if i > 1: app(p.s[cpsStmts], "else {" & tnl)
|
if i > 1: appf(p.s[cpsStmts], "else {$n")
|
||||||
genStmts(p, t.sons[i].sons[0])
|
genStmts(p, t.sons[i].sons[0])
|
||||||
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();$n", [safePoint])
|
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();$n", [safePoint])
|
||||||
if i > 1: app(p.s[cpsStmts], '}' & tnl)
|
if i > 1: appf(p.s[cpsStmts], "}$n")
|
||||||
else:
|
else:
|
||||||
var orExpr: PRope = nil
|
var orExpr: PRope = nil
|
||||||
for j in countup(0, blen - 2):
|
for j in countup(0, blen - 2):
|
||||||
|
|
@ -547,7 +531,7 @@ proc genTryStmt(p: BProc, t: PNode) =
|
||||||
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();}$n",
|
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();}$n",
|
||||||
[safePoint])
|
[safePoint])
|
||||||
inc(i)
|
inc(i)
|
||||||
app(p.s[cpsStmts], '}' & tnl) # end of if statement
|
appf(p.s[cpsStmts], "}$n") # end of if statement
|
||||||
discard pop(p.nestedTryStmts)
|
discard pop(p.nestedTryStmts)
|
||||||
if i < length and t.sons[i].kind == nkFinally:
|
if i < length and t.sons[i].kind == nkFinally:
|
||||||
genStmts(p, t.sons[i].sons[0])
|
genStmts(p, t.sons[i].sons[0])
|
||||||
|
|
|
||||||
|
|
@ -520,7 +520,7 @@ proc finishTypeDescriptions(m: BModule) =
|
||||||
while i < len(m.typeStack):
|
while i < len(m.typeStack):
|
||||||
discard getTypeDesc(m, m.typeStack[i])
|
discard getTypeDesc(m, m.typeStack[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
||||||
proc genProcHeader(m: BModule, prc: PSym): PRope =
|
proc genProcHeader(m: BModule, prc: PSym): PRope =
|
||||||
var
|
var
|
||||||
rettype, params: PRope
|
rettype, params: PRope
|
||||||
|
|
@ -529,6 +529,7 @@ proc genProcHeader(m: BModule, prc: PSym): PRope =
|
||||||
var check = initIntSet()
|
var check = initIntSet()
|
||||||
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), OnUnknown)
|
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), OnUnknown)
|
||||||
genProcParams(m, prc.typ, rettype, params, check)
|
genProcParams(m, prc.typ, rettype, params, check)
|
||||||
|
genCLineDir(result, prc.ast.sons[codePos])
|
||||||
appf(result, "$1($2, $3)$4",
|
appf(result, "$1($2, $3)$4",
|
||||||
[toRope(CallingConvToStr[prc.typ.callConv]), rettype, prc.loc.r, params])
|
[toRope(CallingConvToStr[prc.typ.callConv]), rettype, prc.loc.r, params])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,10 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: openarray[PRope]): PRope =
|
||||||
if j > high(args) + 1:
|
if j > high(args) + 1:
|
||||||
internalError("ropes: invalid format string $" & $(j))
|
internalError("ropes: invalid format string $" & $(j))
|
||||||
app(result, args[j - 1])
|
app(result, args[j - 1])
|
||||||
of 'N', 'n':
|
of 'n':
|
||||||
|
if not (optLineDir in gOptions): app(result, tnl)
|
||||||
|
inc(i)
|
||||||
|
of 'N':
|
||||||
app(result, tnl)
|
app(result, tnl)
|
||||||
inc(i)
|
inc(i)
|
||||||
else: InternalError("ropes: invalid format string $" & frmt[i])
|
else: InternalError("ropes: invalid format string $" & frmt[i])
|
||||||
|
|
@ -241,6 +244,30 @@ proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr,
|
||||||
args: openarray[PRope]) =
|
args: openarray[PRope]) =
|
||||||
app(p.s[s], ropecg(p.module, frmt, args))
|
app(p.s[s], ropecg(p.module, frmt, args))
|
||||||
|
|
||||||
|
proc safeLineNm(t: PNode) : int =
|
||||||
|
result = toLinenumber(t.info) # BUGFIX
|
||||||
|
if result < 0: result = 0 # negative numbers are not allowed in #line
|
||||||
|
|
||||||
|
proc genCLineDir(r: var PRope, filename: string, line: int) =
|
||||||
|
assert line >= 0
|
||||||
|
if optLineDir in gOptions:
|
||||||
|
appff(r, "$N#line $2 $1$N", "; line $2 \"$1\"$n",
|
||||||
|
[toRope(makeSingleLineCString(filename)), toRope(line)])
|
||||||
|
|
||||||
|
proc genCLineDir(r: var PRope, t: PNode) =
|
||||||
|
genCLineDir(r, t.info.toFullPath, t.safeLineNm)
|
||||||
|
|
||||||
|
proc genLineDir(p: BProc, t: PNode) =
|
||||||
|
var line = t.safeLineNm
|
||||||
|
genCLineDir(p.s[cpsStmts], t.info.toFullPath, line)
|
||||||
|
if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and
|
||||||
|
(p.prc == nil or sfPure notin p.prc.flags):
|
||||||
|
appcg(p, cpsStmts, "#endb($1);$n", [toRope(line)])
|
||||||
|
elif ({optLineTrace, optStackTrace} * p.Options ==
|
||||||
|
{optLineTrace, optStackTrace}) and
|
||||||
|
(p.prc == nil or sfPure notin p.prc.flags):
|
||||||
|
appf(p.s[cpsStmts], "F.line = $1;F.filename = $2;$n",
|
||||||
|
[toRope(line), makeCString(toFilename(t.info).extractFilename)])
|
||||||
|
|
||||||
include "ccgtypes.nim"
|
include "ccgtypes.nim"
|
||||||
|
|
||||||
|
|
@ -546,13 +573,13 @@ proc cgsym(m: BModule, name: string): PRope =
|
||||||
result = sym.loc.r
|
result = sym.loc.r
|
||||||
|
|
||||||
proc generateHeaders(m: BModule) =
|
proc generateHeaders(m: BModule) =
|
||||||
app(m.s[cfsHeaders], "#include \"nimbase.h\"" & tnl & tnl)
|
app(m.s[cfsHeaders], tnl & "#include \"nimbase.h\"" & tnl)
|
||||||
var it = PStrEntry(m.headerFiles.head)
|
var it = PStrEntry(m.headerFiles.head)
|
||||||
while it != nil:
|
while it != nil:
|
||||||
if it.data[0] notin {'\"', '<'}:
|
if it.data[0] notin {'\"', '<'}:
|
||||||
appf(m.s[cfsHeaders], "#include \"$1\"$n", [toRope(it.data)])
|
appf(m.s[cfsHeaders], "$N#include \"$1\"$N", [toRope(it.data)])
|
||||||
else:
|
else:
|
||||||
appf(m.s[cfsHeaders], "#include $1$n", [toRope(it.data)])
|
appf(m.s[cfsHeaders], "$N#include $1$N", [toRope(it.data)])
|
||||||
it = PStrEntry(it.Next)
|
it = PStrEntry(it.Next)
|
||||||
|
|
||||||
proc getFrameDecl(p: BProc) =
|
proc getFrameDecl(p: BProc) =
|
||||||
|
|
@ -629,24 +656,24 @@ proc genProcAux(m: BModule, prc: PSym) =
|
||||||
if gProcProfile >= 64 * 1024:
|
if gProcProfile >= 64 * 1024:
|
||||||
InternalError(prc.info, "too many procedures for profiling")
|
InternalError(prc.info, "too many procedures for profiling")
|
||||||
discard cgsym(m, "profileData")
|
discard cgsym(m, "profileData")
|
||||||
app(p.s[cpsLocals], "ticks NIM_profilingStart;" & tnl)
|
appf(p.s[cpsLocals], "ticks NIM_profilingStart;$n")
|
||||||
if prc.loc.a < 0:
|
if prc.loc.a < 0:
|
||||||
appf(m.s[cfsDebugInit], "profileData[$1].procname = $2;$n", [
|
appf(m.s[cfsDebugInit], "profileData[$1].procname = $2;$n", [
|
||||||
toRope(gProcProfile),
|
toRope(gProcProfile),
|
||||||
makeCString(prc.name.s)])
|
makeCString(prc.name.s)])
|
||||||
prc.loc.a = gProcProfile
|
prc.loc.a = gProcProfile
|
||||||
inc(gProcProfile)
|
inc(gProcProfile)
|
||||||
prepend(p.s[cpsInit], toRope("NIM_profilingStart = getticks();" & tnl))
|
prepend(p.s[cpsInit], ropef("NIM_profilingStart = getticks();$n"))
|
||||||
app(generatedProc, p.s[cpsInit])
|
app(generatedProc, p.s[cpsInit])
|
||||||
app(generatedProc, p.s[cpsStmts])
|
app(generatedProc, p.s[cpsStmts])
|
||||||
if p.beforeRetNeeded: app(generatedProc, "BeforeRet: ;" & tnl)
|
if p.beforeRetNeeded: appf(generatedProc, "BeforeRet: $n;")
|
||||||
if optStackTrace in prc.options: app(generatedProc, deinitFrame(p))
|
if optStackTrace in prc.options: app(generatedProc, deinitFrame(p))
|
||||||
if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM):
|
if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM):
|
||||||
appf(generatedProc,
|
appf(generatedProc,
|
||||||
"profileData[$1].total += elapsed(getticks(), NIM_profilingStart);$n",
|
"profileData[$1].total += elapsed(getticks(), NIM_profilingStart);$n",
|
||||||
[toRope(prc.loc.a)])
|
[toRope(prc.loc.a)])
|
||||||
app(generatedProc, returnStmt)
|
app(generatedProc, returnStmt)
|
||||||
app(generatedProc, '}' & tnl)
|
appf(generatedProc, "}$n")
|
||||||
app(m.s[cfsProcs], generatedProc)
|
app(m.s[cfsProcs], generatedProc)
|
||||||
|
|
||||||
proc genProcPrototype(m: BModule, sym: PSym) =
|
proc genProcPrototype(m: BModule, sym: PSym) =
|
||||||
|
|
@ -667,8 +694,8 @@ proc genProcNoForward(m: BModule, prc: PSym) =
|
||||||
if lfImportCompilerProc in prc.loc.flags:
|
if lfImportCompilerProc in prc.loc.flags:
|
||||||
# dependency to a compilerproc:
|
# dependency to a compilerproc:
|
||||||
discard cgsym(m, prc.name.s)
|
discard cgsym(m, prc.name.s)
|
||||||
return
|
return
|
||||||
genProcPrototype(m, prc)
|
genProcPrototype(m, prc)
|
||||||
if lfNoDecl in prc.loc.Flags: nil
|
if lfNoDecl in prc.loc.Flags: nil
|
||||||
elif prc.typ.callConv == ccInline:
|
elif prc.typ.callConv == ccInline:
|
||||||
# We add inline procs to the calling module to enable C based inlining.
|
# We add inline procs to the calling module to enable C based inlining.
|
||||||
|
|
@ -854,7 +881,7 @@ proc genInitCode(m: BModule) =
|
||||||
app(prc, m.initProc.s[cpsStmts])
|
app(prc, m.initProc.s[cpsStmts])
|
||||||
if optStackTrace in m.initProc.options and not m.PreventStackTrace:
|
if optStackTrace in m.initProc.options and not m.PreventStackTrace:
|
||||||
app(prc, deinitFrame(m.initProc))
|
app(prc, deinitFrame(m.initProc))
|
||||||
app(prc, '}' & tnl & tnl)
|
appf(prc, "}$n$n")
|
||||||
app(m.s[cfsProcs], prc)
|
app(m.s[cfsProcs], prc)
|
||||||
|
|
||||||
proc genModule(m: BModule, cfilenoext: string): PRope =
|
proc genModule(m: BModule, cfilenoext: string): PRope =
|
||||||
|
|
|
||||||
|
|
@ -414,7 +414,7 @@ proc UnknownLineInfo*(): TLineInfo =
|
||||||
result.fileIndex = -1
|
result.fileIndex = -1
|
||||||
|
|
||||||
var
|
var
|
||||||
filenames: seq[string] = @[]
|
filenames: seq[tuple[filename: string, fullpath: string]] = @[]
|
||||||
msgContext: seq[TLineInfo] = @[]
|
msgContext: seq[TLineInfo] = @[]
|
||||||
|
|
||||||
proc pushInfoContext*(info: TLineInfo) =
|
proc pushInfoContext*(info: TLineInfo) =
|
||||||
|
|
@ -425,10 +425,16 @@ proc popInfoContext*() =
|
||||||
|
|
||||||
proc includeFilename*(f: string): int =
|
proc includeFilename*(f: string): int =
|
||||||
for i in countdown(high(filenames), low(filenames)):
|
for i in countdown(high(filenames), low(filenames)):
|
||||||
if filenames[i] == f:
|
if filenames[i].filename == f:
|
||||||
return i
|
return i
|
||||||
|
|
||||||
result = len(filenames)
|
result = len(filenames)
|
||||||
filenames.add(f)
|
|
||||||
|
var fullpath: string
|
||||||
|
try: fullpath = expandFilename(f)
|
||||||
|
except: fullpath = ""
|
||||||
|
|
||||||
|
filenames.add((filename: f, fullpath: fullpath))
|
||||||
|
|
||||||
proc newLineInfo*(filename: string, line, col: int): TLineInfo =
|
proc newLineInfo*(filename: string, line, col: int): TLineInfo =
|
||||||
result.fileIndex = includeFilename(filename)
|
result.fileIndex = includeFilename(filename)
|
||||||
|
|
@ -437,12 +443,11 @@ proc newLineInfo*(filename: string, line, col: int): TLineInfo =
|
||||||
|
|
||||||
proc ToFilename*(info: TLineInfo): string =
|
proc ToFilename*(info: TLineInfo): string =
|
||||||
if info.fileIndex < 0: result = "???"
|
if info.fileIndex < 0: result = "???"
|
||||||
else: result = filenames[info.fileIndex]
|
else: result = filenames[info.fileIndex].filename
|
||||||
|
|
||||||
proc toFullPath*(info: TLineInfo): string =
|
proc toFullPath*(info: TLineInfo): string =
|
||||||
result = info.toFilename
|
if info.fileIndex < 0: result = "???"
|
||||||
if not isAbsolute(result):
|
else: result = filenames[info.fileIndex].fullpath
|
||||||
result = JoinPath(options.projectPath, result)
|
|
||||||
|
|
||||||
proc ToLinenumber*(info: TLineInfo): int {.inline.} =
|
proc ToLinenumber*(info: TLineInfo): int {.inline.} =
|
||||||
result = info.line
|
result = info.line
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import
|
import
|
||||||
msgs, strutils, platform, hashes, crc
|
msgs, strutils, platform, hashes, crc, options
|
||||||
|
|
||||||
const
|
const
|
||||||
CacheLeafs* = true
|
CacheLeafs* = true
|
||||||
|
|
@ -319,7 +319,10 @@ proc ropef(frmt: TFormatStr, args: openarray[PRope]): PRope =
|
||||||
if j > high(args) + 1:
|
if j > high(args) + 1:
|
||||||
internalError("ropes: invalid format string $" & $(j))
|
internalError("ropes: invalid format string $" & $(j))
|
||||||
app(result, args[j - 1])
|
app(result, args[j - 1])
|
||||||
of 'N', 'n':
|
of 'n':
|
||||||
|
if not (optLineDir in gOptions): app(result, tnl)
|
||||||
|
inc i
|
||||||
|
of 'N':
|
||||||
app(result, tnl)
|
app(result, tnl)
|
||||||
inc(i)
|
inc(i)
|
||||||
else: InternalError("ropes: invalid format string $" & frmt[i])
|
else: InternalError("ropes: invalid format string $" & frmt[i])
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue