diff options
Diffstat (limited to 'compiler/pragmas.nim')
-rw-r--r-- | compiler/pragmas.nim | 99 |
1 files changed, 55 insertions, 44 deletions
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 3de12cfa9..e9a89bc44 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -19,25 +19,27 @@ const LastCallConv* = wNoconv const - procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, + declPragmas = {wImportc, wImportObjC, wImportCpp, wExportc, wExportCpp, + wExportNims, wExtern, wDeprecated, wNodecl, wError, wUsed} + ## common pragmas for declarations, to a good approximation + procPragmas* = declPragmas + {FirstCallConv..LastCallConv, wMagic, wNoSideEffect, wSideEffect, wNoreturn, wDynlib, wHeader, - wCompilerProc, wNonReloadable, wCore, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, - wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC, - wAsmNoStackFrame, wError, wDiscardable, wNoInit, wCodegenDecl, + wCompilerProc, wNonReloadable, wCore, wProcVar, wVarargs, wCompileTime, wMerge, + wBorrow, wImportCompilerProc, wThread, + wAsmNoStackFrame, wDiscardable, wNoInit, wCodegenDecl, wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe, - wConstructor, wExportNims, wUsed, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy} + wConstructor, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy} converterPragmas* = procPragmas - {wNoDestroy} methodPragmas* = procPragmas+{wBase}-{wImportCpp, wNoDestroy} templatePragmas* = {wDeprecated, wError, wGensym, wInject, wDirty, wDelegator, wExportNims, wUsed, wPragma} - macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, - wNodecl, wMagic, wNoSideEffect, wCompilerProc, wNonReloadable, wCore, wDeprecated, wExtern, - wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wDelegator, - wExportNims, wUsed} - iteratorPragmas* = {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect, - wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern, - wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises, - wTags, wLocks, wGcSafe, wExportNims, wUsed} + macroPragmas* = declPragmas + {FirstCallConv..LastCallConv, + wMagic, wNoSideEffect, wCompilerProc, wNonReloadable, wCore, + wDiscardable, wGensym, wInject, wDelegator} + iteratorPragmas* = declPragmas + {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect, + wMagic, wBorrow, + wDiscardable, wGensym, wInject, wRaises, + wTags, wLocks, wGcSafe} exprPragmas* = {wLine, wLocks, wNoRewrite, wGcSafe, wNoSideEffect} stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangeChecks, wBoundChecks, wOverflowChecks, wNilChecks, wStyleChecks, wAssertions, @@ -49,25 +51,25 @@ const wDeprecated, wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, wLinearScanEnd, wPatterns, wTrMacros, wEffects, wNoForward, wReorder, wComputedGoto, - wInjectStmt, wDeprecated, wExperimental, wThis, wUsed} - lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, + wInjectStmt, wExperimental, wThis, wUsed} + lambdaPragmas* = declPragmas + {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect, wNoreturn, wDynlib, wHeader, - wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame, - wRaises, wLocks, wTags, wGcSafe, wCodegenDecl} - typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, - wPure, wHeader, wCompilerProc, wCore, wFinal, wSize, wExtern, wShallow, - wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef, + wThread, wAsmNoStackFrame, + wRaises, wLocks, wTags, wGcSafe, wCodegenDecl} - {wExportNims, wError, wUsed} # why exclude these? + typePragmas* = declPragmas + {wMagic, wAcyclic, + wPure, wHeader, wCompilerProc, wCore, wFinal, wSize, wShallow, + wIncompleteStruct, wByCopy, wByRef, wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked, - wBorrow, wGcSafe, wExportNims, wPartial, wUsed, wExplain, wPackage} - fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, - wImportCpp, wImportObjC, wError, wGuard, wBitsize, wUsed} - varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, - wMagic, wHeader, wDeprecated, wCompilerProc, wCore, wDynlib, wExtern, - wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal, - wGensym, wInject, wCodegenDecl, wGuard, wGoto, wExportNims, wUsed, wCursor} - constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl, - wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject, wExportNims, - wIntDefine, wStrDefine, wBoolDefine, wUsed, wCompilerProc, wCore} + wBorrow, wGcSafe, wPartial, wExplain, wPackage} + fieldPragmas* = declPragmas + { + wGuard, wBitsize} - {wExportNims, wNodecl} # why exclude these? + varPragmas* = declPragmas + {wVolatile, wRegister, wThreadVar, + wMagic, wHeader, wCompilerProc, wCore, wDynlib, + wNoInit, wCompileTime, wGlobal, + wGensym, wInject, wCodegenDecl, wGuard, wGoto, wCursor} + constPragmas* = declPragmas + {wHeader, wMagic, + wGensym, wInject, + wIntDefine, wStrDefine, wBoolDefine, wCompilerProc, wCore} letPragmas* = varPragmas procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNoSideEffect, wThread, wRaises, wLocks, wTags, wGcSafe} @@ -83,7 +85,8 @@ proc getPragmaVal*(procAst: PNode; name: TSpecialWord): PNode = it[0].ident.id == ord(name): return it[1] -proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) +proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords; + isStatement: bool = false) proc recordPragma(c: PContext; n: PNode; key, val: string; val2 = "") = var recorded = newNodeI(nkCommentStmt, n.info) @@ -104,7 +107,7 @@ proc illegalCustomPragma*(c: PContext, n: PNode, s: PSym) = proc pragmaAsm*(c: PContext, n: PNode): char = result = '\0' if n != nil: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): let it = n.sons[i] if it.kind in nkPragmaCallKinds and it.len == 2 and it.sons[0].kind == nkIdent: case whichKeyword(it.sons[0].ident) @@ -423,7 +426,7 @@ proc processPush(c: PContext, n: PNode, start: int) = x.notes = c.config.notes x.features = c.features c.optionStack.add(x) - for i in start ..< sonsLen(n): + for i in start ..< len(n): if not tryProcessOption(c, n.sons[i], c.config.options): # simply store it somewhere: if x.otherPragmas.isNil: @@ -745,7 +748,8 @@ proc semCustomPragma(c: PContext, n: PNode): PNode = result.kind = n.kind proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, - validPragmas: TSpecialWords, comesFromPush: bool) : bool = + validPragmas: TSpecialWords, + comesFromPush, isStatement: bool) : bool = var it = n.sons[i] var key = if it.kind in nkPragmaCallKinds and it.len > 1: it.sons[0] else: it if key.kind == nkBracketExpr: @@ -765,7 +769,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, if c.instCounter > 100: globalError(c.config, it.info, "recursive dependency: " & userPragma.name.s) - pragma(c, sym, userPragma.ast, validPragmas) + pragma(c, sym, userPragma.ast, validPragmas, isStatement) n.sons[i..i] = userPragma.ast.sons # expand user pragma with its content i.inc(userPragma.ast.len - 1) # inc by -1 is ok, user pragmas was empty dec c.instCounter @@ -775,8 +779,13 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, if {optStyleHint, optStyleError} * c.config.globalOptions != {}: checkPragmaUse(c.config, key.info, k, ident.s) case k - of wExportc: + of wExportc, wExportCpp: makeExternExport(c, sym, getOptionalStr(c, it, "$1"), it.info) + if k == wExportCpp: + if c.config.cmd != cmdCompileToCpp: + localError(c.config, it.info, "exportcpp requires `nim cpp`, got " & $c.config.cmd) + else: + incl(sym.flags, sfMangleCpp) incl(sym.flags, sfUsed) # avoid wrong hints of wImportc: let name = getOptionalStr(c, it, "$1") @@ -839,7 +848,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, of wCompileTime: noVal(c, it) incl(sym.flags, sfCompileTime) - incl(sym.loc.flags, lfNoDecl) + #incl(sym.loc.flags, lfNoDecl) of wGlobal: noVal(c, it) incl(sym.flags, sfGlobal) @@ -962,7 +971,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, recordPragma(c, it, "warning", s) message(c.config, it.info, warnUser, s) of wError: - if sym != nil and (sym.isRoutine or sym.kind == skType) and wUsed in validPragmas: + if sym != nil and (sym.isRoutine or sym.kind == skType) and not isStatement: # This is subtle but correct: the error *statement* is only # allowed when 'wUsed' is not in validPragmas. Here this is the easiest way to # distinguish properly between @@ -1131,7 +1140,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, elif comesFromPush and whichKeyword(ident) in {wTags, wRaises}: discard "ignore the .push pragma; it doesn't apply" else: - if sym == nil or (sym != nil and sym.kind in {skVar, skLet, skParam, + if sym == nil or (sym.kind in {skVar, skLet, skParam, skField, skProc, skFunc, skConverter, skMethod, skType}): n.sons[i] = semCustomPragma(c, it) elif sym != nil: @@ -1161,7 +1170,7 @@ proc implicitPragmas*(c: PContext, sym: PSym, n: PNode, pushInfoContext(c.config, n.info) var i = 0 while i < o.len: - if singlePragma(c, sym, o, i, validPragmas, true): + if singlePragma(c, sym, o, i, validPragmas, true, false): internalError(c.config, n.info, "implicitPragmas") inc i popInfoContext(c.config) @@ -1186,14 +1195,16 @@ proc hasPragma*(n: PNode, pragma: TSpecialWord): bool = return false -proc pragmaRec(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = +proc pragmaRec(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords; + isStatement: bool) = if n == nil: return var i = 0 while i < n.len: - if singlePragma(c, sym, n, i, validPragmas, false): break + if singlePragma(c, sym, n, i, validPragmas, false, isStatement): break inc i -proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = +proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords; + isStatement: bool) = if n == nil: return - pragmaRec(c, sym, n, validPragmas) + pragmaRec(c, sym, n, validPragmas, isStatement) implicitPragmas(c, sym, n, validPragmas) |