@@ -62,6 +62,9 @@ from compiler/ast/report_enums import ReportKind,
6262
6363from compiler/ ic/ ic import addCompilerProc
6464
65+ type
66+ InvalidPragmaHandler = proc (c: PContext , n: PNode ): PNode {.closure .}
67+
6568const
6669 FirstCallConv * = wNimcall
6770 LastCallConv * = wTailcall
@@ -1020,7 +1023,7 @@ proc pragmaGuard(c: PContext; it: PNode; kind: TSymKind): PSym =
10201023 else :
10211024 result = qualifiedLookUp (c, n, {checkUndeclared})
10221025
1023- proc semCustomPragma (c: PContext , n: PNode ): PNode =
1026+ proc semCustomPragma (c: PContext , n: PNode , invalid: InvalidPragmaHandler ): PNode =
10241027 var callNode: PNode
10251028
10261029 case n.kind
@@ -1033,14 +1036,14 @@ proc semCustomPragma(c: PContext, n: PNode): PNode =
10331036 of nkPragmaCallKinds - {nkExprColonExpr}:
10341037 callNode = n
10351038 else :
1036- result = invalidPragma (c, n)
1039+ result = invalid (c, n)
10371040 return
10381041
10391042 let r = c.semOverloadedCall (c, callNode, callNode, {skTemplate}, {efNoUndeclared})
10401043 if r.isError:
10411044 return r
10421045 elif r.isNil or sfCustomPragma notin r[0 ].sym.flags:
1043- result = invalidPragma (c, n)
1046+ result = invalid (c, n)
10441047 return
10451048
10461049 result = r
@@ -1640,39 +1643,46 @@ proc applyStmtPragma(c: PContext, owner: PSym, it: PNode, k: TSpecialWord): PNod
16401643# statement. Doing so would slightly change the semantics, however.
16411644
16421645proc prepareSinglePragma (c: PContext ; it: PNode , result: var seq [PNode ],
1643- validPragmas: TSpecialWords , sym: PSym ) =
1646+ validPragmas: TSpecialWords , sym: PSym ,
1647+ tryCustom= true ,
1648+ invalid: InvalidPragmaHandler = invalidPragma) =
16441649 # # Pre-processes the single pragma `it`, but doesn't apply it yet. The pre-
16451650 # # processed pragma (multiple if the input pragma is a user-pragma) is
1646- # # appended to `result`.
1651+ # # appended to `result`. Unknown Custom pragmas are only considered when
1652+ # # `considerCustom` is 'true'; `invalid` is called for non-applicable
1653+ # # pragmas.
16471654 # #
16481655 # # `sym` (nil is allowed) is only provided for use by error diagnostics and
16491656 # # isn't mutated.
16501657 let key = it.key
16511658
1652- proc customPragma (c: PContext , n: PNode , s: PSym ): PNode =
1659+ proc customPragma (c: PContext , n: PNode , s: PSym ,
1660+ invalid: InvalidPragmaHandler ): PNode =
16531661 if s == nil or s.kind in allowsCustomPragma:
1654- semCustomPragma (c, n)
1662+ semCustomPragma (c, n, invalid )
16551663 else :
16561664 illegalCustomPragma (c, n, s)
16571665
16581666 let r =
16591667 case key.kind
16601668 of nkBracketExpr:
1661- invalidPragma (c, it)
1669+ invalid (c, it)
16621670 of nkCast:
16631671 # pass through the cast pragma. It's later going to be treated as a
16641672 # ``wCast``
16651673 it
16661674 of nkIdentKinds:
16671675 # uses normal processing
16681676 nil
1677+ elif tryCustom:
1678+ customPragma (c, it, sym, invalid)
16691679 else :
1670- # must be either a custom pragma or an error
1671- customPragma (c, it, sym)
1680+ invalid (c, it)
16721681
16731682 if r != nil :
16741683 # already processed
1675- result .add r
1684+ if r.kind != nkEmpty:
1685+ result .add r
16761686 return
16771687
16781688 let (ident, error) = considerQuotedIdent (c, key)
@@ -1695,7 +1705,8 @@ proc prepareSinglePragma(c: PContext; it: PNode, result: var seq[PNode],
16951705 else :
16961706 # expand the user pragma in-place:
16971707 for it in userPragma.ast.items:
1698- prepareSinglePragma (c, it, result , validPragmas, sym)
1708+ prepareSinglePragma (c, it, result , validPragmas, sym,
1709+ tryCustom, invalid)
16991710
17001711 dec c.instCounter
17011712 else :
@@ -1705,10 +1716,15 @@ proc prepareSinglePragma(c: PContext; it: PNode, result: var seq[PNode],
17051716 checkPragmaUse (c.config, key.info, k, ident.s)
17061717
17071718 result .add it
1719+ elif tryCustom:
1720+ # try to treat as a custom pragma
1721+ let got = customPragma (c, it, sym, invalid)
1722+ if got.kind != nkEmpty:
1723+ result .add got
17081724 else :
1709- # try to treat as a custom pragma, which will produce an error if it's
1710- # not a valid custom pragma
1711- result .add customPragma (c, it, sym)
1725+ let got = invalid (c, it)
1726+ if got.kind != nkEmpty:
1727+ result .add got
17121728
17131729proc semSinglePragmaInStmt (
17141730 c: PContext ; owner: PSym , it: PNode , validPragmas: TSpecialWords , r: var seq [PNode ]): TSpecialWord
@@ -1761,7 +1777,7 @@ proc semIdentPragmaInStmt(c: PContext, owner: PSym, it: PNode, r: var seq[PNode]
17611777 else :
17621778 # it might still be a custom pragma
17631779 result = wInvalid
1764- r.add semCustomPragma (c, it)
1780+ r.add semCustomPragma (c, it, invalidPragma )
17651781
17661782proc semSinglePragmaInStmt (
17671783 c: PContext ; owner: PSym , it: PNode , validPragmas: TSpecialWords , r: var seq [PNode ]): TSpecialWord =
@@ -1785,7 +1801,7 @@ proc semSinglePragmaInStmt(
17851801 of nkIdentKinds:
17861802 result = semIdentPragmaInStmt (c, owner, it, r, validPragmas)
17871803 else :
1788- r.add semCustomPragma (c, it)
1804+ r.add semCustomPragma (c, it, invalidPragma )
17891805
17901806proc overwriteLineInfo (n: PNode ; info: TLineInfo ) =
17911807 n.info = info
@@ -1864,18 +1880,16 @@ proc implicitPragmas*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWo
18641880 let o = it.otherPragmas
18651881 if o != nil :
18661882 for x in o.items:
1867- prepareSinglePragma (c, x, tmp, validPragmas, sym)
1883+ # pragmas not applicable to the symbol are silently ignored
1884+ prepareSinglePragma (c, x, tmp, validPragmas, sym,
1885+ tryCustom= (sym.kind in allowsCustomPragma),
1886+ proc (c: PContext , n: PNode ): PNode = c.graph.emptyNode)
18681887
1869- # filter the nodes. If they're erroneous, it means that the pragma
1870- # doesn't apply to the symbol
1888+ # the pragmas' AST is going to be mutated, so create a copy
18711889 for y in tmp.items:
1872- if not y.isError:
1873- # we're mutating the pragma's AST, so a copy is required
1874- let pragma = copyTree (y)
1875- overwriteLineInfo (pragma, n.info)
1876- result .add (pragma)
1877-
1878- tmp.setLen (0 )
1890+ let pragma = copyTree (y)
1891+ overwriteLineInfo (pragma, n.info)
1892+ result .add pragma
18791893
18801894 if result .len == 0 :
18811895 # there were no applicable pragmas; restore the original
0 commit comments