diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-06-16 19:02:54 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-06-16 19:02:54 +0200 |
commit | 798a8bd45c6631864716566e0681590879015aeb (patch) | |
tree | 176d3de6fd5b49626b07553c53ac301be376a9c5 /compiler | |
parent | dba26656f6285bc0a0fc6767810981997dcdc68a (diff) | |
parent | ee16e6206167a0cdaca43369371eeb3fb8300e88 (diff) | |
download | Nim-798a8bd45c6631864716566e0681590879015aeb.tar.gz |
Merge branch 'devel' of github.com:nim-lang/Nim into devel
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/pragmas.nim | 129 | ||||
-rw-r--r-- | compiler/semstmts.nim | 6 |
2 files changed, 75 insertions, 60 deletions
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index bfb8e78eb..c78a3519c 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -223,9 +223,9 @@ proc isTurnedOn(c: PContext, n: PNode): bool = if x.kind == nkIntLit: return x.intVal != 0 localError(c.config, n.info, "'on' or 'off' expected") -proc onOff(c: PContext, n: PNode, op: TOptions) = - if isTurnedOn(c, n): c.config.options = c.config.options + op - else: c.config.options = c.config.options - op +proc onOff(c: PContext, n: PNode, op: TOptions, resOptions: var TOptions) = + if isTurnedOn(c, n): resOptions = resOptions + op + else: resOptions = resOptions - op proc pragmaNoForward(c: PContext, n: PNode; flag=sfNoForward) = if isTurnedOn(c, n): incl(c.module.flags, flag) @@ -313,54 +313,68 @@ proc processNote(c: PContext, n: PNode) = else: invalidPragma(c, n) -proc processOption(c: PContext, n: PNode): bool = - if n.kind notin nkPragmaCallKinds or n.len != 2: result = true +proc pragmaToOptions(w: TSpecialWord): TOptions {.inline.} = + case w + of wChecks: ChecksOptions + of wObjChecks: {optObjCheck} + of wFieldChecks: {optFieldCheck} + of wRangechecks: {optRangeCheck} + of wBoundchecks: {optBoundsCheck} + of wOverflowchecks: {optOverflowCheck} + of wNilchecks: {optNilCheck} + of wFloatchecks: {optNaNCheck, optInfCheck} + of wNanChecks: {optNaNCheck} + of wInfChecks: {optInfCheck} + of wMovechecks: {optMoveCheck} + of wAssertions: {optAssert} + of wWarnings: {optWarns} + of wHints: {optHints} + of wLinedir: {optLineDir} + of wStacktrace: {optStackTrace} + of wLinetrace: {optLineTrace} + of wDebugger: {optEndb} + of wProfiler: {optProfiler, optMemTracker} + of wMemTracker: {optMemTracker} + of wByRef: {optByRef} + of wImplicitStatic: {optImplicitStatic} + of wPatterns: {optPatterns} + else: {} + +proc tryProcessOption(c: PContext, n: PNode, resOptions: var TOptions): bool = + result = true + if n.kind notin nkPragmaCallKinds or n.len != 2: result = false elif n.sons[0].kind == nkBracketExpr: processNote(c, n) - elif n.sons[0].kind != nkIdent: result = true + elif n.sons[0].kind != nkIdent: result = false else: let sw = whichKeyword(n.sons[0].ident) - case sw - of wChecks: onOff(c, n, ChecksOptions) - of wObjChecks: onOff(c, n, {optObjCheck}) - of wFieldChecks: onOff(c, n, {optFieldCheck}) - of wRangechecks: onOff(c, n, {optRangeCheck}) - of wBoundchecks: onOff(c, n, {optBoundsCheck}) - of wOverflowchecks: onOff(c, n, {optOverflowCheck}) - of wNilchecks: onOff(c, n, {optNilCheck}) - of wFloatchecks: onOff(c, n, {optNaNCheck, optInfCheck}) - of wNanChecks: onOff(c, n, {optNaNCheck}) - of wInfChecks: onOff(c, n, {optInfCheck}) - of wMovechecks: onOff(c, n, {optMoveCheck}) - of wAssertions: onOff(c, n, {optAssert}) - of wWarnings: onOff(c, n, {optWarns}) - of wHints: onOff(c, n, {optHints}) - of wCallconv: processCallConv(c, n) - of wLinedir: onOff(c, n, {optLineDir}) - of wStacktrace: onOff(c, n, {optStackTrace}) - of wLinetrace: onOff(c, n, {optLineTrace}) - of wDebugger: onOff(c, n, {optEndb}) - of wProfiler: onOff(c, n, {optProfiler, optMemTracker}) - of wMemTracker: onOff(c, n, {optMemTracker}) - of wByRef: onOff(c, n, {optByRef}) - of wDynlib: processDynLib(c, n, nil) - of wOptimization: - if n.sons[1].kind != nkIdent: - invalidPragma(c, n) - else: - case n.sons[1].ident.s.normalize - of "speed": - incl(c.config.options, optOptimizeSpeed) - excl(c.config.options, optOptimizeSize) - of "size": - excl(c.config.options, optOptimizeSpeed) - incl(c.config.options, optOptimizeSize) - of "none": - excl(c.config.options, optOptimizeSpeed) - excl(c.config.options, optOptimizeSize) - else: localError(c.config, n.info, "'none', 'speed' or 'size' expected") - of wImplicitStatic: onOff(c, n, {optImplicitStatic}) - of wPatterns: onOff(c, n, {optPatterns}) - else: result = true + let opts = pragmaToOptions(sw) + if opts != {}: + onOff(c, n, opts, resOptions) + else: + case sw + of wCallconv: processCallConv(c, n) + of wDynlib: processDynLib(c, n, nil) + of wOptimization: + if n.sons[1].kind != nkIdent: + invalidPragma(c, n) + else: + case n.sons[1].ident.s.normalize + of "speed": + incl(resOptions, optOptimizeSpeed) + excl(resOptions, optOptimizeSize) + of "size": + excl(resOptions, optOptimizeSpeed) + incl(resOptions, optOptimizeSize) + of "none": + excl(resOptions, optOptimizeSpeed) + excl(resOptions, optOptimizeSize) + else: localError(c.config, n.info, "'none', 'speed' or 'size' expected") + else: result = false + +proc processOption(c: PContext, n: PNode, resOptions: var TOptions) = + if not tryProcessOption(c, n, resOptions): + # calling conventions (boring...): + localError(c.config, n.info, "option expected") proc processPush(c: PContext, n: PNode, start: int) = if n.sons[start-1].kind in nkPragmaCallKinds: @@ -373,7 +387,7 @@ proc processPush(c: PContext, n: PNode, start: int) = x.notes = c.config.notes c.optionStack.add(x) for i in countup(start, sonsLen(n) - 1): - if processOption(c, n.sons[i]): + if not tryProcessOption(c, n.sons[i], c.config.options): # simply store it somewhere: if x.otherPragmas.isNil: x.otherPragmas = newNodeI(nkPragma, n.info) @@ -964,13 +978,14 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, of wCodegenDecl: processCodegenDecl(c, it, sym) of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, - wLinedir, wStacktrace, wLinetrace, wOptimization, wMovechecks, - wCallconv, - wDebugger, wProfiler, wFloatchecks, wNanChecks, wInfChecks, - wPatterns: - if processOption(c, it): - # calling conventions (boring...): - localError(c.config, it.info, "option expected") + wLinedir, wOptimization, wMovechecks, wCallconv, wDebugger, wProfiler, + wFloatchecks, wNanChecks, wInfChecks, wPatterns: + processOption(c, it, c.config.options) + of wStacktrace, wLinetrace: + if sym.kind in {skProc, skMethod, skConverter}: + processOption(c, it, sym.options) + else: + processOption(c, it, c.config.options) of FirstCallConv..LastCallConv: assert(sym != nil) if sym.typ == nil: invalidPragma(c, it) @@ -1000,7 +1015,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, of wByRef: noVal(c, it) if sym == nil or sym.typ == nil: - if processOption(c, it): localError(c.config, it.info, "option expected") + processOption(c, it, c.config.options) else: incl(sym.typ.flags, tfByRef) of wByCopy: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 439ef8fca..292238dc9 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1486,10 +1486,11 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, s.ast = n #s.scope = c.currentScope + s.options = c.config.options + # before compiling the proc body, set as current the scope # where the proc was declared let oldScope = c.currentScope - let oldOptions = c.config.options #c.currentScope = s.scope pushOwner(c, s) openScope(c) @@ -1558,6 +1559,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, addParams(c, proto.typ.n, proto.kind) proto.info = s.info # more accurate line information s.typ = proto.typ + proto.options = s.options s = proto n.sons[genericParamsPos] = proto.ast.sons[genericParamsPos] n.sons[paramsPos] = proto.ast.sons[paramsPos] @@ -1569,8 +1571,6 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, proto.ast = n # needed for code generation popOwner(c) pushOwner(c, s) - s.options = c.config.options - c.config.options = oldOptions if sfOverriden in s.flags or s.name.s[0] == '=': semOverride(c, s, n) if s.name.s[0] in {'.', '('}: |