summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-11-20 23:58:45 +0100
committerAraq <rumpf_a@web.de>2012-11-20 23:58:45 +0100
commit022ff2e86e12b1920a73b67878cd9ee05293d15d (patch)
tree22445e62747e1f10a5112ea43071ccef0e01af94 /compiler
parent1dfc57c5fffc425ffe9c79551463de8a386f8697 (diff)
downloadNim-022ff2e86e12b1920a73b67878cd9ee05293d15d.tar.gz
almost every pragma is allowed in a 'push' pragma
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/main.nim1
-rwxr-xr-xcompiler/pragmas.nim477
-rwxr-xr-xcompiler/semdata.nim1
-rwxr-xr-xcompiler/semstmts.nim2
4 files changed, 254 insertions, 227 deletions
diff --git a/compiler/main.nim b/compiler/main.nim
index 9aefa3eb3..dabd5309b 100755
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -259,6 +259,7 @@ proc MainCommand =
     gCmd = cmdDoc
     LoadConfigs(DocConfig)
     wantMainModule()
+    DefineSymbol("nimdoc")
     CommandDoc2()
   of "rst2html": 
     gCmd = cmdRst2html
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index f874a0acf..8f06beecd 100755
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -262,11 +262,11 @@ proc processNote(c: PContext, n: PNode) =
   else: 
     invalidPragma(n)
   
-proc processOption(c: PContext, n: PNode) = 
-  if n.kind != nkExprColonExpr: invalidPragma(n)
+proc processOption(c: PContext, n: PNode): bool = 
+  if n.kind != nkExprColonExpr: result = true
   elif n.sons[0].kind == nkBracketExpr: processNote(c, n)
-  elif n.sons[0].kind != nkIdent: invalidPragma(n)
-  else: 
+  elif n.sons[0].kind != nkIdent: result = true
+  else:
     var sw = whichKeyword(n.sons[0].ident)
     case sw
     of wChecks: OnOff(c, n, checksOptions)
@@ -307,9 +307,11 @@ proc processOption(c: PContext, n: PNode) =
         else: LocalError(n.info, errNoneSpeedOrSizeExpected)
     of wImplicitStatic: OnOff(c, n, {optImplicitStatic})
     of wPatterns: OnOff(c, n, {optPatterns})
-    else: LocalError(n.info, errOptionExpected)
+    else: result = true
   
 proc processPush(c: PContext, n: PNode, start: int) = 
+  if n.sons[start-1].kind == nkExprColonExpr:
+    LocalError(n.info, errGenerated, "':' after 'push' not supported")
   var x = newOptionEntry()
   var y = POptionEntry(c.optionStack.tail)
   x.options = gOptions
@@ -318,15 +320,18 @@ proc processPush(c: PContext, n: PNode, start: int) =
   x.notes = gNotes
   append(c.optionStack, x)
   for i in countup(start, sonsLen(n) - 1): 
-    processOption(c, n.sons[i]) 
-    #liMessage(n.info, warnUser, ropeToStr(optionsToStr(gOptions)));
+    if processOption(c, n.sons[i]):
+      # simply store it somehwere:
+      if x.otherPragmas.isNil:
+        x.otherPragmas = newNodeI(nkPragma, n.info)
+      x.otherPragmas.add n.sons[i]
+    #LocalError(n.info, errOptionExpected)
   
 proc processPop(c: PContext, n: PNode) = 
   if c.optionStack.counter <= 1: 
     LocalError(n.info, errAtPopWithoutPush)
   else: 
     gOptions = POptionEntry(c.optionStack.tail).options 
-    #liMessage(n.info, warnUser, ropeToStr(optionsToStr(gOptions)));
     gNotes = POptionEntry(c.optionStack.tail).notes
     remove(c.optionStack, c.optionStack.tail)
 
@@ -481,227 +486,240 @@ proc pragmaRaisesOrTags(c: PContext, n: PNode) =
   else:
     invalidPragma(n)
 
-proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
-  if n == nil: return
-  for i in countup(0, sonsLen(n) - 1): 
-    var it = n.sons[i]
-    var key = if it.kind == nkExprColonExpr: it.sons[0] else: it
-    if key.kind == nkIdent: 
-      var userPragma = StrTableGet(c.userPragmas, key.ident)
-      if userPragma != nil: 
-        inc c.InstCounter
-        if c.InstCounter > 100: 
-          GlobalError(it.info, errRecursiveDependencyX, userPragma.name.s)
-        pragma(c, sym, userPragma.ast, validPragmas)
-        dec c.InstCounter
-      else:
-        var k = whichKeyword(key.ident)
-        if k in validPragmas: 
-          case k
-          of wExportc: 
-            makeExternExport(sym, getOptionalStr(c, it, sym.name.s))
-            incl(sym.flags, sfUsed) # avoid wrong hints
-          of wImportc: makeExternImport(sym, getOptionalStr(c, it, sym.name.s))
-          of wImportCompilerProc:
-            processImportCompilerProc(sym, getOptionalStr(c, it, sym.name.s))
-          of wExtern: setExternName(sym, expectStrLit(c, it))
-          of wImmediate:
-            if sym.kind in {skTemplate, skMacro}: incl(sym.flags, sfImmediate)
-            else: invalidPragma(it)
-          of wDirty:
-            if sym.kind == skTemplate: incl(sym.flags, sfDirty)
-            else: invalidPragma(it)
-          of wImportCpp:
-            processImportCpp(sym, getOptionalStr(c, it, sym.name.s))
-          of wImportObjC:
-            processImportObjC(sym, getOptionalStr(c, it, sym.name.s))
-          of wAlign:
-            if sym.typ == nil: invalidPragma(it)
-            var align = expectIntLit(c, it)
-            if not IsPowerOfTwo(align) and align != 0: 
-              LocalError(it.info, errPowerOfTwoExpected)
-            else: 
-              sym.typ.align = align              
-          of wSize: 
-            if sym.typ == nil: invalidPragma(it)
-            var size = expectIntLit(c, it)
-            if not IsPowerOfTwo(size) or size <= 0 or size > 8: 
-              LocalError(it.info, errPowerOfTwoExpected)
-            else:
-              sym.typ.size = size
-          of wNodecl: 
-            noVal(it)
-            incl(sym.loc.Flags, lfNoDecl)
-          of wPure, wNoStackFrame:
-            noVal(it)
-            if sym != nil: incl(sym.flags, sfPure)
-          of wVolatile: 
-            noVal(it)
-            incl(sym.flags, sfVolatile)
-          of wRegister: 
-            noVal(it)
-            incl(sym.flags, sfRegister)
-          of wThreadVar: 
-            noVal(it)
-            incl(sym.flags, sfThread)
-          of wDeadCodeElim: pragmaDeadCodeElim(c, it)
-          of wMagic: processMagic(c, it, sym)
-          of wCompileTime: 
-            noVal(it)
-            incl(sym.flags, sfCompileTime)
-            incl(sym.loc.Flags, lfNoDecl)
-          of wGlobal:
-            noVal(it)
-            incl(sym.flags, sfGlobal)
-          of wMerge: 
-            noval(it)
-            incl(sym.flags, sfMerge)
-          of wHeader: 
-            var lib = getLib(c, libHeader, getStrLitNode(c, it))
-            addToLib(lib, sym)
-            incl(sym.flags, sfImportc)
-            incl(sym.loc.flags, lfHeader)
-            incl(sym.loc.Flags, lfNoDecl) 
-            # implies nodecl, because otherwise header would not make sense
-            if sym.loc.r == nil: sym.loc.r = toRope(sym.name.s)
-          of wDestructor:
-            if sym.typ.sons.len == 2:
-              sym.flags.incl sfDestructor
-            else:
-              invalidPragma(it)
-          of wNosideeffect: 
-            noVal(it)
-            incl(sym.flags, sfNoSideEffect)
-            if sym.typ != nil: incl(sym.typ.flags, tfNoSideEffect)
-          of wSideEffect: 
-            noVal(it)
-            incl(sym.flags, sfSideEffect)
-          of wNoReturn: 
-            noVal(it)
-            incl(sym.flags, sfNoReturn)
-          of wDynLib: 
-            processDynLib(c, it, sym)
-          of wCompilerProc: 
-            noVal(it)           # compilerproc may not get a string!
-            makeExternExport(sym, sym.name.s)
-            incl(sym.flags, sfCompilerProc)
-            incl(sym.flags, sfUsed) # suppress all those stupid warnings
-            registerCompilerProc(sym)
-          of wProcvar: 
-            noVal(it)
-            incl(sym.flags, sfProcVar)
-          of wDeprecated: 
-            noVal(it)
-            if sym != nil: incl(sym.flags, sfDeprecated)
-            else: incl(c.module.flags, sfDeprecated)
-          of wVarargs: 
-            noVal(it)
-            if sym.typ == nil: invalidPragma(it)
-            else: incl(sym.typ.flags, tfVarargs)
-          of wBorrow: 
-            noVal(it)
-            incl(sym.flags, sfBorrow)
-          of wFinal: 
-            noVal(it)
-            if sym.typ == nil: invalidPragma(it)
-            else: incl(sym.typ.flags, tfFinal)
-          of wInheritable:
-            noVal(it)
-            if sym.typ == nil or tfFinal in sym.typ.flags: invalidPragma(it)
-            else: incl(sym.typ.flags, tfInheritable)
-          of wAcyclic:
-            noVal(it)
-            if sym.typ == nil: invalidPragma(it)
-            else: incl(sym.typ.flags, tfAcyclic)
-          of wShallow:
-            noVal(it)
-            if sym.typ == nil: invalidPragma(it)
-            else: incl(sym.typ.flags, tfShallow)
-          of wThread:
-            noVal(it)
-            incl(sym.flags, sfThread)
-            incl(sym.flags, sfProcVar)
-            if sym.typ != nil: incl(sym.typ.flags, tfThread)
-          of wHint: Message(it.info, hintUser, expectStrLit(c, it))
-          of wWarning: Message(it.info, warnUser, expectStrLit(c, it))
-          of wError: 
-            if sym != nil and sym.isRoutine:
-              # This is subtle but correct: the error *statement* is only
-              # allowed for top level statements. Seems to be easier than 
-              # distinguishing properly between
-              # ``proc p() {.error}`` and ``proc p() = {.error: "msg".}``
-              noVal(it)
-              incl(sym.flags, sfError)
-            else:
-              LocalError(it.info, errUser, expectStrLit(c, it))
-          of wFatal: Fatal(it.info, errUser, expectStrLit(c, it))
-          of wDefine: processDefine(c, it)
-          of wUndef: processUndef(c, it)
-          of wCompile: processCompile(c, it)
-          of wLink: processCommonLink(c, it, linkNormal)
-          of wLinkSys: processCommonLink(c, it, linkSys)
-          of wPassL: extccomp.addLinkOption(expectStrLit(c, it))
-          of wPassC: extccomp.addCompileOption(expectStrLit(c, it))
-          of wBreakpoint: PragmaBreakpoint(c, it)
-          of wWatchpoint: PragmaWatchpoint(c, it)
-          of wPush: 
-            processPush(c, n, i + 1)
-            break 
-          of wPop: processPop(c, it)
-          of wPragma: 
-            processPragma(c, n, i)
-            break
-          of wDiscardable:
-            noVal(it)
-            if sym != nil: incl(sym.flags, sfDiscardable)
-          of wNoInit:
-            noVal(it)
-            if sym != nil: incl(sym.flags, sfNoInit)
-          of wHoist:
-            noVal(it)
-            if sym != nil: incl(sym.flags, sfHoist)
-          of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, 
-             wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, 
-             wLinedir, wStacktrace, wLinetrace, wOptimization,
-             wCallConv, 
-             wDebugger, wProfiler, wFloatChecks, wNanChecks, wInfChecks,
-             wPatterns:
-            processOption(c, it) # calling conventions (boring...):
-          of firstCallConv..lastCallConv: 
-            assert(sym != nil)
-            if sym.typ == nil: invalidPragma(it)
-            else: sym.typ.callConv = wordToCallConv(k)
-          of wEmit: PragmaEmit(c, it)
-          of wUnroll: PragmaUnroll(c, it)
-          of wLinearScanEnd: PragmaLinearScanEnd(c, it)
-          of wEffects:
-            # is later processed in effect analysis:
-            noVal(it)
-          of wIncompleteStruct:
-            noVal(it)
-            if sym.typ == nil: invalidPragma(it)
-            else: incl(sym.typ.flags, tfIncompleteStruct)
-          of wByRef:
-            noVal(it)
-            if sym == nil or sym.typ == nil:
-              processOption(c, it)
-            else:
-              incl(sym.typ.flags, tfByRef)
-          of wByCopy:
-            noVal(it)
-            if sym.kind != skType or sym.typ == nil: invalidPragma(it)
-            else: incl(sym.typ.flags, tfByCopy)
-          of wInject, wGenSym:
-            # We check for errors, but do nothing with these pragmas otherwise
-            # as they are handled directly in 'evalTemplate'.
-            noVal(it)
-            if sym == nil: invalidPragma(it)
-          of wLine: PragmaLine(c, it)
-          of wRaises, wTags: pragmaRaisesOrTags(c, it)
+proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
+                  validPragmas: TSpecialWords): bool =
+  var it = n.sons[i]
+  var key = if it.kind == nkExprColonExpr: it.sons[0] else: it
+  if key.kind == nkIdent: 
+    var userPragma = StrTableGet(c.userPragmas, key.ident)
+    if userPragma != nil: 
+      inc c.InstCounter
+      if c.InstCounter > 100: 
+        GlobalError(it.info, errRecursiveDependencyX, userPragma.name.s)
+      pragma(c, sym, userPragma.ast, validPragmas)
+      dec c.InstCounter
+    else:
+      var k = whichKeyword(key.ident)
+      if k in validPragmas: 
+        case k
+        of wExportc: 
+          makeExternExport(sym, getOptionalStr(c, it, sym.name.s))
+          incl(sym.flags, sfUsed) # avoid wrong hints
+        of wImportc: makeExternImport(sym, getOptionalStr(c, it, sym.name.s))
+        of wImportCompilerProc:
+          processImportCompilerProc(sym, getOptionalStr(c, it, sym.name.s))
+        of wExtern: setExternName(sym, expectStrLit(c, it))
+        of wImmediate:
+          if sym.kind in {skTemplate, skMacro}: incl(sym.flags, sfImmediate)
+          else: invalidPragma(it)
+        of wDirty:
+          if sym.kind == skTemplate: incl(sym.flags, sfDirty)
           else: invalidPragma(it)
+        of wImportCpp:
+          processImportCpp(sym, getOptionalStr(c, it, sym.name.s))
+        of wImportObjC:
+          processImportObjC(sym, getOptionalStr(c, it, sym.name.s))
+        of wAlign:
+          if sym.typ == nil: invalidPragma(it)
+          var align = expectIntLit(c, it)
+          if not IsPowerOfTwo(align) and align != 0: 
+            LocalError(it.info, errPowerOfTwoExpected)
+          else: 
+            sym.typ.align = align              
+        of wSize: 
+          if sym.typ == nil: invalidPragma(it)
+          var size = expectIntLit(c, it)
+          if not IsPowerOfTwo(size) or size <= 0 or size > 8: 
+            LocalError(it.info, errPowerOfTwoExpected)
+          else:
+            sym.typ.size = size
+        of wNodecl: 
+          noVal(it)
+          incl(sym.loc.Flags, lfNoDecl)
+        of wPure, wNoStackFrame:
+          noVal(it)
+          if sym != nil: incl(sym.flags, sfPure)
+        of wVolatile: 
+          noVal(it)
+          incl(sym.flags, sfVolatile)
+        of wRegister: 
+          noVal(it)
+          incl(sym.flags, sfRegister)
+        of wThreadVar: 
+          noVal(it)
+          incl(sym.flags, sfThread)
+        of wDeadCodeElim: pragmaDeadCodeElim(c, it)
+        of wMagic: processMagic(c, it, sym)
+        of wCompileTime: 
+          noVal(it)
+          incl(sym.flags, sfCompileTime)
+          incl(sym.loc.Flags, lfNoDecl)
+        of wGlobal:
+          noVal(it)
+          incl(sym.flags, sfGlobal)
+        of wMerge: 
+          noval(it)
+          incl(sym.flags, sfMerge)
+        of wHeader: 
+          var lib = getLib(c, libHeader, getStrLitNode(c, it))
+          addToLib(lib, sym)
+          incl(sym.flags, sfImportc)
+          incl(sym.loc.flags, lfHeader)
+          incl(sym.loc.Flags, lfNoDecl) 
+          # implies nodecl, because otherwise header would not make sense
+          if sym.loc.r == nil: sym.loc.r = toRope(sym.name.s)
+        of wDestructor:
+          if sym.typ.sons.len == 2:
+            sym.flags.incl sfDestructor
+          else:
+            invalidPragma(it)
+        of wNosideeffect: 
+          noVal(it)
+          incl(sym.flags, sfNoSideEffect)
+          if sym.typ != nil: incl(sym.typ.flags, tfNoSideEffect)
+        of wSideEffect: 
+          noVal(it)
+          incl(sym.flags, sfSideEffect)
+        of wNoReturn: 
+          noVal(it)
+          incl(sym.flags, sfNoReturn)
+        of wDynLib: 
+          processDynLib(c, it, sym)
+        of wCompilerProc: 
+          noVal(it)           # compilerproc may not get a string!
+          makeExternExport(sym, sym.name.s)
+          incl(sym.flags, sfCompilerProc)
+          incl(sym.flags, sfUsed) # suppress all those stupid warnings
+          registerCompilerProc(sym)
+        of wProcvar: 
+          noVal(it)
+          incl(sym.flags, sfProcVar)
+        of wDeprecated: 
+          noVal(it)
+          if sym != nil: incl(sym.flags, sfDeprecated)
+          else: incl(c.module.flags, sfDeprecated)
+        of wVarargs: 
+          noVal(it)
+          if sym.typ == nil: invalidPragma(it)
+          else: incl(sym.typ.flags, tfVarargs)
+        of wBorrow: 
+          noVal(it)
+          incl(sym.flags, sfBorrow)
+        of wFinal: 
+          noVal(it)
+          if sym.typ == nil: invalidPragma(it)
+          else: incl(sym.typ.flags, tfFinal)
+        of wInheritable:
+          noVal(it)
+          if sym.typ == nil or tfFinal in sym.typ.flags: invalidPragma(it)
+          else: incl(sym.typ.flags, tfInheritable)
+        of wAcyclic:
+          noVal(it)
+          if sym.typ == nil: invalidPragma(it)
+          else: incl(sym.typ.flags, tfAcyclic)
+        of wShallow:
+          noVal(it)
+          if sym.typ == nil: invalidPragma(it)
+          else: incl(sym.typ.flags, tfShallow)
+        of wThread:
+          noVal(it)
+          incl(sym.flags, sfThread)
+          incl(sym.flags, sfProcVar)
+          if sym.typ != nil: incl(sym.typ.flags, tfThread)
+        of wHint: Message(it.info, hintUser, expectStrLit(c, it))
+        of wWarning: Message(it.info, warnUser, expectStrLit(c, it))
+        of wError: 
+          if sym != nil and sym.isRoutine:
+            # This is subtle but correct: the error *statement* is only
+            # allowed for top level statements. Seems to be easier than 
+            # distinguishing properly between
+            # ``proc p() {.error}`` and ``proc p() = {.error: "msg".}``
+            noVal(it)
+            incl(sym.flags, sfError)
+          else:
+            LocalError(it.info, errUser, expectStrLit(c, it))
+        of wFatal: Fatal(it.info, errUser, expectStrLit(c, it))
+        of wDefine: processDefine(c, it)
+        of wUndef: processUndef(c, it)
+        of wCompile: processCompile(c, it)
+        of wLink: processCommonLink(c, it, linkNormal)
+        of wLinkSys: processCommonLink(c, it, linkSys)
+        of wPassL: extccomp.addLinkOption(expectStrLit(c, it))
+        of wPassC: extccomp.addCompileOption(expectStrLit(c, it))
+        of wBreakpoint: PragmaBreakpoint(c, it)
+        of wWatchpoint: PragmaWatchpoint(c, it)
+        of wPush: 
+          processPush(c, n, i + 1)
+          result = true 
+        of wPop: processPop(c, it)
+        of wPragma: 
+          processPragma(c, n, i)
+          result = true
+        of wDiscardable:
+          noVal(it)
+          if sym != nil: incl(sym.flags, sfDiscardable)
+        of wNoInit:
+          noVal(it)
+          if sym != nil: incl(sym.flags, sfNoInit)
+        of wHoist:
+          noVal(it)
+          if sym != nil: incl(sym.flags, sfHoist)
+        of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, 
+           wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, 
+           wLinedir, wStacktrace, wLinetrace, wOptimization,
+           wCallConv, 
+           wDebugger, wProfiler, wFloatChecks, wNanChecks, wInfChecks,
+           wPatterns:
+          if processOption(c, it):
+            # calling conventions (boring...):
+            LocalError(it.info, errOptionExpected)
+        of firstCallConv..lastCallConv: 
+          assert(sym != nil)
+          if sym.typ == nil: invalidPragma(it)
+          else: sym.typ.callConv = wordToCallConv(k)
+        of wEmit: PragmaEmit(c, it)
+        of wUnroll: PragmaUnroll(c, it)
+        of wLinearScanEnd: PragmaLinearScanEnd(c, it)
+        of wEffects:
+          # is later processed in effect analysis:
+          noVal(it)
+        of wIncompleteStruct:
+          noVal(it)
+          if sym.typ == nil: invalidPragma(it)
+          else: incl(sym.typ.flags, tfIncompleteStruct)
+        of wByRef:
+          noVal(it)
+          if sym == nil or sym.typ == nil:
+            if processOption(c, it): LocalError(it.info, errOptionExpected)
+          else:
+            incl(sym.typ.flags, tfByRef)
+        of wByCopy:
+          noVal(it)
+          if sym.kind != skType or sym.typ == nil: invalidPragma(it)
+          else: incl(sym.typ.flags, tfByCopy)
+        of wInject, wGenSym:
+          # We check for errors, but do nothing with these pragmas otherwise
+          # as they are handled directly in 'evalTemplate'.
+          noVal(it)
+          if sym == nil: invalidPragma(it)
+        of wLine: PragmaLine(c, it)
+        of wRaises, wTags: pragmaRaisesOrTags(c, it)
         else: invalidPragma(it)
-    else: processNote(c, it)
+      else: invalidPragma(it)
+  else: processNote(c, it)
+
+proc implictPragmas*(c: PContext, sym: PSym, n: PNode,
+                     validPragmas: TSpecialWords) =
   if sym != nil and sym.kind != skModule:
+    var it = POptionEntry(c.optionstack.head)
+    while it != nil:
+      let o = it.otherPragmas
+      if not o.isNil:
+        for i in countup(0, sonsLen(o) - 1):
+          if singlePragma(c, sym, o, i, validPragmas):
+            InternalError(n.info, "implicitPragmas")
+      it = it.next.POptionEntry
+
     if lfExportLib in sym.loc.flags and sfExportc notin sym.flags: 
       LocalError(n.info, errDynlibRequiresExportc)
     var lib = POptionEntry(c.optionstack.tail).dynlib
@@ -710,4 +728,9 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
       incl(sym.loc.flags, lfDynamicLib)
       addToLib(lib, sym)
       if sym.loc.r == nil: sym.loc.r = toRope(sym.name.s)
-  
+
+proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
+  if n == nil: return
+  for i in countup(0, sonsLen(n) - 1):
+    if singlePragma(c, sym, n, i, validPragmas): break
+  implictPragmas(c, sym, n, validPragmas)
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 57721bdc0..4ead9cf13 100755
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -22,6 +22,7 @@ type
     defaultCC*: TCallingConvention
     dynlib*: PLib
     Notes*: TNoteKinds
+    otherPragmas*: PNode      # every pragma can be pushed
 
   POptionEntry* = ref TOptionEntry
   PProcCon* = ref TProcCon
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index a08c39ce6..52d922b2d 100755
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -758,6 +758,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
       addInterfaceDeclAt(c, s, c.tab.tos - 2)
     if n.sons[pragmasPos].kind != nkEmpty:
       pragma(c, s, n.sons[pragmasPos], validPragmas)
+    else:
+      implictPragmas(c, s, n, validPragmas)
   else: 
     if n.sons[pragmasPos].kind != nkEmpty: 
       LocalError(n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProc)