pragma on/off improvements; endb rewritten
This commit is contained in:
parent
e92693ec8d
commit
8d19a93f1a
23 changed files with 517 additions and 202 deletions
|
|
@ -662,7 +662,7 @@ proc genArrayElem(p: BProc, e: PNode, d: var TLoc) =
|
|||
[rdCharLoc(b), first, intLiteral(lastOrd(ty))])
|
||||
if d.k == locNone: d.s = a.s
|
||||
putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)),
|
||||
ropef("$1[($2)-$3]", [rdLoc(a), rdCharLoc(b), first]))
|
||||
ropef("$1[($2)- $3]", [rdLoc(a), rdCharLoc(b), first]))
|
||||
|
||||
proc genCStringElem(p: BProc, e: PNode, d: var TLoc) =
|
||||
var a, b: TLoc
|
||||
|
|
@ -691,7 +691,7 @@ proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) =
|
|||
var ty = skipTypes(a.t, abstractVarRange)
|
||||
if ty.kind in {tyRef, tyPtr}:
|
||||
ty = skipTypes(ty.sons[0], abstractVarRange) # emit range check:
|
||||
if (optBoundsCheck in p.options):
|
||||
if optBoundsCheck in p.options:
|
||||
if ty.kind == tyString:
|
||||
appcg(p, cpsStmts,
|
||||
"if ((NU)($1) > (NU)($2->$3)) #raiseIndexError();$n",
|
||||
|
|
|
|||
|
|
@ -615,6 +615,15 @@ proc genBreakPoint(p: BProc, t: PNode) =
|
|||
toRope(toLinenumber(t.info)), makeCString(toFilename(t.info)),
|
||||
makeCString(name)])
|
||||
|
||||
proc genWatchpoint(p: BProc, n: PNode) =
|
||||
if optEndb notin p.Options: return
|
||||
var a: TLoc
|
||||
initLocExpr(p, n.sons[1], a)
|
||||
let typ = skipTypes(n.sons[1].typ, abstractVarRange)
|
||||
appcg(p, cpsStmts, "#dbgRegisterWatchpoint($1, (NCSTRING)$2, $3);$n",
|
||||
[a.addrLoc, makeCString(renderTree(n.sons[1])),
|
||||
genTypeInfo(p.module, typ)])
|
||||
|
||||
proc genPragma(p: BProc, n: PNode) =
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
var it = n.sons[i]
|
||||
|
|
@ -628,6 +637,8 @@ proc genPragma(p: BProc, n: PNode) =
|
|||
# we need to keep track of ``deadCodeElim`` pragma
|
||||
if (sfDeadCodeElim in p.module.module.flags):
|
||||
addPendingModule(p.module)
|
||||
of wWatchpoint:
|
||||
genWatchpoint(p, it)
|
||||
else: nil
|
||||
|
||||
proc FieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool =
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ const
|
|||
wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
||||
wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError,
|
||||
wFatal, wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop,
|
||||
wBreakpoint, wCheckpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated,
|
||||
wBreakpoint, wWatchpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated,
|
||||
wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
|
||||
wLinearScanEnd}
|
||||
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||
|
|
@ -59,17 +59,16 @@ const
|
|||
allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas
|
||||
|
||||
proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords)
|
||||
proc pragmaAsm*(c: PContext, n: PNode): char
|
||||
# implementation
|
||||
|
||||
proc invalidPragma(n: PNode) =
|
||||
LocalError(n.info, errInvalidPragmaX, renderTree(n, {renderNoComments}))
|
||||
|
||||
proc pragmaAsm(c: PContext, n: PNode): char =
|
||||
proc pragmaAsm*(c: PContext, n: PNode): char =
|
||||
result = '\0'
|
||||
if n != nil:
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
var it = n.sons[i]
|
||||
let it = n.sons[i]
|
||||
if (it.kind == nkExprColonExpr) and (it.sons[0].kind == nkIdent):
|
||||
case whichKeyword(it.sons[0].ident)
|
||||
of wSubsChar:
|
||||
|
|
@ -155,13 +154,11 @@ proc wordToCallConv(sw: TSpecialWord): TCallingConvention =
|
|||
result = TCallingConvention(ord(ccDefault) + ord(sw) - ord(wNimcall))
|
||||
|
||||
proc IsTurnedOn(c: PContext, n: PNode): bool =
|
||||
if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
|
||||
case whichKeyword(n.sons[1].ident)
|
||||
of wOn: result = true
|
||||
of wOff: result = false
|
||||
else: LocalError(n.info, errOnOrOffExpected)
|
||||
else:
|
||||
LocalError(n.info, errOnOrOffExpected)
|
||||
if n.kind == nkExprColonExpr:
|
||||
let x = c.semConstBoolExpr(c, n.sons[1])
|
||||
n.sons[1] = x
|
||||
if x.kind == nkIntLit: return x.intVal != 0
|
||||
LocalError(n.info, errOnOrOffExpected)
|
||||
|
||||
proc onOff(c: PContext, n: PNode, op: TOptions) =
|
||||
if IsTurnedOn(c, n): gOptions = gOptions + op
|
||||
|
|
@ -211,28 +208,29 @@ proc processDynLib(c: PContext, n: PNode, sym: PSym) =
|
|||
else:
|
||||
incl(sym.loc.flags, lfExportLib)
|
||||
|
||||
proc processNote(c: PContext, n: PNode) =
|
||||
proc processNote(c: PContext, n: PNode) =
|
||||
if (n.kind == nkExprColonExpr) and (sonsLen(n) == 2) and
|
||||
(n.sons[0].kind == nkBracketExpr) and
|
||||
(n.sons[0].sons[1].kind == nkIdent) and
|
||||
(n.sons[0].sons[0].kind == nkIdent) and (n.sons[1].kind == nkIdent):
|
||||
(n.sons[0].sons[0].kind == nkIdent) and (n.sons[1].kind == nkIdent):
|
||||
var nk: TNoteKind
|
||||
case whichKeyword(n.sons[0].sons[0].ident)
|
||||
of wHint:
|
||||
of wHint:
|
||||
var x = findStr(msgs.HintsToStr, n.sons[0].sons[1].ident.s)
|
||||
if x >= 0: nk = TNoteKind(x + ord(hintMin))
|
||||
else: invalidPragma(n)
|
||||
of wWarning:
|
||||
of wWarning:
|
||||
var x = findStr(msgs.WarningsToStr, n.sons[0].sons[1].ident.s)
|
||||
if x >= 0: nk = TNoteKind(x + ord(warnMin))
|
||||
else: InvalidPragma(n)
|
||||
else:
|
||||
else:
|
||||
invalidPragma(n)
|
||||
return
|
||||
case whichKeyword(n.sons[1].ident)
|
||||
of wOn: incl(gNotes, nk)
|
||||
of wOff: excl(gNotes, nk)
|
||||
else: LocalError(n.info, errOnOrOffExpected)
|
||||
return
|
||||
|
||||
let x = c.semConstBoolExpr(c, n.sons[1])
|
||||
n.sons[1] = x
|
||||
if x.kind == nkIntLit and x.intVal != 0: incl(gNotes, nk)
|
||||
else: excl(gNotes, nk)
|
||||
else:
|
||||
invalidPragma(n)
|
||||
|
||||
|
|
@ -335,8 +333,8 @@ proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) =
|
|||
if found == "": found = f # use the default
|
||||
case feature
|
||||
of linkNormal: extccomp.addFileToLink(found)
|
||||
of linkSys:
|
||||
extccomp.addFileToLink(joinPath(libpath, completeCFilePath(found, false)))
|
||||
of linkSys:
|
||||
extccomp.addFileToLink(libpath / completeCFilePath(found, false))
|
||||
else: internalError(n.info, "processCommonLink")
|
||||
|
||||
proc PragmaBreakpoint(c: PContext, n: PNode) =
|
||||
|
|
@ -348,6 +346,12 @@ proc PragmaCheckpoint(c: PContext, n: PNode) =
|
|||
inc(info.line) # next line is affected!
|
||||
msgs.addCheckpoint(info)
|
||||
|
||||
proc PragmaWatchpoint(c: PContext, n: PNode) =
|
||||
if n.kind == nkExprColonExpr:
|
||||
n.sons[1] = c.semExpr(c, n.sons[1])
|
||||
else:
|
||||
invalidPragma(n)
|
||||
|
||||
proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
|
||||
case n.sons[1].kind
|
||||
of nkStrLit, nkRStrLit, nkTripleStrLit:
|
||||
|
|
@ -562,7 +566,7 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
|||
of wPassL: extccomp.addLinkOption(expectStrLit(c, it))
|
||||
of wPassC: extccomp.addCompileOption(expectStrLit(c, it))
|
||||
of wBreakpoint: PragmaBreakpoint(c, it)
|
||||
of wCheckpoint: PragmaCheckpoint(c, it)
|
||||
of wWatchpoint: PragmaWatchpoint(c, it)
|
||||
of wPush:
|
||||
processPush(c, n, i + 1)
|
||||
break
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ proc lsons(n: PNode, start: int = 0, theEnd: int = - 1): int =
|
|||
|
||||
proc lsub(n: PNode): int =
|
||||
# computes the length of a tree
|
||||
if isNil(n): return 0
|
||||
if n.comment != nil: return maxLineLen + 1
|
||||
case n.kind
|
||||
of nkEmpty: result = 0
|
||||
|
|
@ -663,6 +664,7 @@ proc gident(g: var TSrcGen, n: PNode) =
|
|||
if n.kind == nkSym and renderIds in g.flags: put(g, tkIntLit, $n.sym.id)
|
||||
|
||||
proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||
if isNil(n): return
|
||||
var
|
||||
L: int
|
||||
a: TContext
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ proc myOpen(module: PSym, filename: string): PPassContext =
|
|||
if (c.p != nil): InternalError(module.info, "sem.myOpen")
|
||||
c.semConstExpr = semConstExpr
|
||||
c.semExpr = semExprNoFlags
|
||||
c.semConstBoolExpr = semConstBoolExpr
|
||||
pushProcCon(c, module)
|
||||
pushOwner(c.module)
|
||||
openScope(c.tab) # scope for imported symbols
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ type
|
|||
libs*: TLinkedList # all libs used by this module
|
||||
semConstExpr*: proc (c: PContext, n: PNode): PNode # for the pragmas
|
||||
semExpr*: proc (c: PContext, n: PNode): PNode # for the pragmas
|
||||
semConstBoolExpr*: proc (c: PContext, n: PNode): PNode # XXX bite the bullet
|
||||
includedFiles*: TIntSet # used to detect recursive include files
|
||||
filename*: string # the module's filename
|
||||
userPragmas*: TStrTable
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
|||
# the correct branch. Otherwise the AST will be passed through semStmt.
|
||||
result = nil
|
||||
|
||||
template set_result(e: expr) =
|
||||
template setResult(e: expr) =
|
||||
if semCheck: result = semStmt(c, e) # do not open a new scope!
|
||||
else: result = e
|
||||
|
||||
|
|
@ -27,17 +27,17 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
|||
of nkElifBranch:
|
||||
checkSonsLen(it, 2)
|
||||
var e = semAndEvalConstExpr(c, it.sons[0])
|
||||
if (e.kind != nkIntLit): InternalError(n.info, "semWhen")
|
||||
if (e.intVal != 0) and (result == nil):
|
||||
set_result(it.sons[1])
|
||||
of nkElse:
|
||||
if e.kind != nkIntLit: InternalError(n.info, "semWhen")
|
||||
if e.intVal != 0 and result == nil:
|
||||
setResult(it.sons[1])
|
||||
of nkElse:
|
||||
checkSonsLen(it, 1)
|
||||
if result == nil:
|
||||
set_result(it.sons[0])
|
||||
setResult(it.sons[0])
|
||||
else: illFormedAst(n)
|
||||
if result == nil:
|
||||
result = newNodeI(nkNilLit, n.info)
|
||||
# The ``when`` statement implements the mechanism for platform dependant
|
||||
# The ``when`` statement implements the mechanism for platform dependent
|
||||
# code. Thus we try to ensure here consistent ID allocation after the
|
||||
# ``when`` statement.
|
||||
IDsynchronizationPoint(200)
|
||||
|
|
|
|||
|
|
@ -125,8 +125,7 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
|||
var a = semConstExpr(c, n[1])
|
||||
var b = semConstExpr(c, n[2])
|
||||
if not sameType(a.typ, b.typ): GlobalError(n.info, errPureTypeMismatch)
|
||||
if not (a.typ.kind in
|
||||
{tyInt..tyInt64, tyEnum, tyBool, tyChar, tyFloat..tyFloat128}):
|
||||
if a.typ.kind notin {tyInt..tyInt64,tyEnum,tyBool,tyChar,tyFloat..tyFloat128}:
|
||||
GlobalError(n.info, errOrdinalTypeExpected)
|
||||
if enumHasHoles(a.typ):
|
||||
GlobalError(n.info, errEnumXHasHoles, a.typ.sym.name.s)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ type
|
|||
wCompileTime, wNoInit,
|
||||
wPassc, wPassl, wBorrow, wDiscardable,
|
||||
wFieldChecks,
|
||||
wCheckPoint, wSubsChar,
|
||||
wWatchPoint, wSubsChar,
|
||||
wAcyclic, wShallow, wUnroll, wLinearScanEnd,
|
||||
wWrite, wPutEnv, wPrependEnv, wAppendEnv, wThreadVar, wEmit, wNoStackFrame
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ const
|
|||
"pragma",
|
||||
"compiletime", "noinit",
|
||||
"passc", "passl", "borrow", "discardable", "fieldchecks",
|
||||
"checkpoint",
|
||||
"watchpoint",
|
||||
"subschar", "acyclic", "shallow", "unroll", "linearscanend",
|
||||
"write", "putenv", "prependenv", "appendenv", "threadvar", "emit",
|
||||
"nostackframe"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue