mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-10 06:54:16 +00:00
implemented user-defined pragmas
This commit is contained in:
@@ -2651,6 +2651,30 @@ Example:
|
||||
|
||||
.. code-block:: nimrod
|
||||
{.deadCodeElim: on.}
|
||||
|
||||
|
||||
Pragma pragma
|
||||
-------------
|
||||
|
||||
The `pragma`:idx: pragma can be used to declare user defined pragmas. This is
|
||||
useful because Nimrod's templates and macros do not affect pragmas. User
|
||||
defined pragmas are in a different module-wide scope than all other symbols.
|
||||
They cannot be imported from a module.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: nimrod
|
||||
when appType == "lib":
|
||||
{.pragma: rtl, exportc, dynlib, cdecl.}
|
||||
else:
|
||||
{.pragma: rtl, importc, dynlib: "client.dll", cdecl.}
|
||||
|
||||
proc p*(a, b: int): int {.rtl.} =
|
||||
return a+b
|
||||
|
||||
In the example a new pragma named ``rtl`` is introduced that either imports
|
||||
a symbol from a dynamic library or exports the symbol for dynamic library
|
||||
generation.
|
||||
|
||||
|
||||
Disabling certain messages
|
||||
@@ -2715,8 +2739,8 @@ strings automatically:
|
||||
printf("hallo %s", "world") # "world" will be passed as C string
|
||||
|
||||
|
||||
Dynlib pragma
|
||||
-------------
|
||||
Dynlib pragma for import
|
||||
------------------------
|
||||
With the `dynlib`:idx: pragma a procedure can be imported from
|
||||
a dynamic library (``.dll`` files for Windows, ``lib*.so`` files for UNIX). The
|
||||
non-optional argument has to be the name of the dynamic library:
|
||||
@@ -2762,3 +2786,17 @@ string expressions in general:
|
||||
|
||||
**Note**: Patterns like ``libtcl(|8.5|8.4).so`` are only supported in constant
|
||||
strings, because they are precompiled.
|
||||
|
||||
Dynlib pragma for export
|
||||
------------------------
|
||||
|
||||
With the ``dynlib`` pragma a procedure can also be exported to
|
||||
a dynamic library. The pragma then has no argument and has to be used in
|
||||
conjunction with the ``exportc`` pragma:
|
||||
|
||||
.. code-block:: Nimrod
|
||||
proc exportme(): int {.cdecl, export, dynlib.}
|
||||
|
||||
This is only useful if the program is compiled as a dynamic library via the
|
||||
``--app:lib`` command line option.
|
||||
|
||||
|
||||
@@ -288,7 +288,8 @@ type
|
||||
skIterator, # an iterator
|
||||
skConverter, # a type converter
|
||||
skMacro, # a macro
|
||||
skTemplate, # a template
|
||||
skTemplate, # a template; currently also misused for user-defined
|
||||
# pragmas
|
||||
skField, # a field in a record or object
|
||||
skEnumField, # an identifier in an enum
|
||||
skForVar, # a for loop variable
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
## It translates a C source file into a Nimrod AST. Then the renderer can be
|
||||
## used to convert the AST to its text representation.
|
||||
|
||||
## XXX cleanup of declaration handling. Standalone enums.
|
||||
|
||||
import
|
||||
os, llstream, rnimsyn, clex, idents, strutils, pegs, ast, astalgo, msgs,
|
||||
options, strtabs
|
||||
|
||||
17
rod/c2nim/tests/systest2.c
Normal file
17
rod/c2nim/tests/systest2.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifdef C2NIM
|
||||
# header "iup.h"
|
||||
# cdecl
|
||||
# mangle "'GTK_'{.*}" "TGtk$1"
|
||||
# mangle "'PGTK_'{.*}" "PGtk$1"
|
||||
#endif
|
||||
|
||||
typedef struct stupidTAG {
|
||||
mytype a, b;
|
||||
} GTK_MyStruct, *PGTK_MyStruct;
|
||||
|
||||
typedef struct {
|
||||
mytype a, b;
|
||||
} GTK_MyStruct, *PGTK_MyStruct;
|
||||
|
||||
int IupConvertXYToPos(PIhandle ih, int x, int y);
|
||||
|
||||
@@ -24,11 +24,8 @@ proc countDefinedSymbols*(): int
|
||||
# implementation
|
||||
|
||||
proc DefineSymbol(symbol: string) =
|
||||
var
|
||||
sym: PSym
|
||||
i: PIdent
|
||||
i = getIdent(symbol)
|
||||
sym = StrTableGet(gSymbols, i)
|
||||
var i = getIdent(symbol)
|
||||
var sym = StrTableGet(gSymbols, i)
|
||||
if sym == nil:
|
||||
new(sym) # circumvent the ID mechanism
|
||||
sym.kind = skConditional
|
||||
@@ -37,20 +34,16 @@ proc DefineSymbol(symbol: string) =
|
||||
sym.position = 1
|
||||
|
||||
proc UndefSymbol(symbol: string) =
|
||||
var sym: PSym
|
||||
sym = StrTableGet(gSymbols, getIdent(symbol))
|
||||
var sym = StrTableGet(gSymbols, getIdent(symbol))
|
||||
if sym != nil: sym.position = 0
|
||||
|
||||
proc isDefined(symbol: PIdent): bool =
|
||||
var sym: PSym
|
||||
sym = StrTableGet(gSymbols, symbol)
|
||||
var sym = StrTableGet(gSymbols, symbol)
|
||||
result = (sym != nil) and (sym.position == 1)
|
||||
|
||||
proc ListSymbols() =
|
||||
var
|
||||
it: TTabIter
|
||||
s: PSym
|
||||
s = InitTabIter(it, gSymbols)
|
||||
var it: TTabIter
|
||||
var s = InitTabIter(it, gSymbols)
|
||||
MessageOut("-- List of currently defined symbols --")
|
||||
while s != nil:
|
||||
if s.position == 1: MessageOut(s.name.s)
|
||||
@@ -58,10 +51,8 @@ proc ListSymbols() =
|
||||
MessageOut("-- End of list --")
|
||||
|
||||
proc countDefinedSymbols(): int =
|
||||
var
|
||||
it: TTabIter
|
||||
s: PSym
|
||||
s = InitTabIter(it, gSymbols)
|
||||
var it: TTabIter
|
||||
var s = InitTabIter(it, gSymbols)
|
||||
result = 0
|
||||
while s != nil:
|
||||
if s.position == 1: inc(result)
|
||||
|
||||
275
rod/pragmas.nim
275
rod/pragmas.nim
@@ -33,7 +33,7 @@ const
|
||||
wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal,
|
||||
wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop, wBreakpoint,
|
||||
wCheckpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated, wFloatChecks,
|
||||
wInfChecks, wNanChecks}
|
||||
wInfChecks, wNanChecks, wPragma}
|
||||
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||
wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wPure, wDeprecated}
|
||||
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
|
||||
@@ -303,10 +303,9 @@ proc processCompile(c: PContext, n: PNode) =
|
||||
extccomp.addFileToLink(completeCFilePath(trunc, false))
|
||||
|
||||
proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) =
|
||||
var f, found: string
|
||||
f = expectStrLit(c, n)
|
||||
var f = expectStrLit(c, n)
|
||||
if splitFile(f).ext == "": f = toObjFile(f)
|
||||
found = findFile(f)
|
||||
var found = findFile(f)
|
||||
if found == "": found = f # use the default
|
||||
case feature
|
||||
of linkNormal: extccomp.addFileToLink(found)
|
||||
@@ -325,137 +324,159 @@ proc PragmaCheckpoint(c: PContext, n: PNode) =
|
||||
|
||||
proc noVal(n: PNode) =
|
||||
if n.kind == nkExprColonExpr: invalidPragma(n)
|
||||
|
||||
proc processPragma(c: PContext, n: PNode, i: int) =
|
||||
var it = n.sons[i]
|
||||
if it.kind != nkExprColonExpr: invalidPragma(n)
|
||||
elif it.sons[0].kind != nkIdent: invalidPragma(n)
|
||||
elif it.sons[1].kind != nkIdent: invalidPragma(n)
|
||||
|
||||
var userPragma = NewSym(skTemplate, it.sons[1].ident, nil)
|
||||
userPragma.info = it.info
|
||||
var body = newNodeI(nkPragma, n.info)
|
||||
for j in i+1 .. sonsLen(n)-1: addSon(body, n.sons[j])
|
||||
userPragma.ast = body
|
||||
StrTableAdd(c.userPragmas, userPragma)
|
||||
|
||||
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 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 wAlign:
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
sym.typ.align = expectIntLit(c, it)
|
||||
if not IsPowerOfTwo(sym.typ.align) and (sym.typ.align != 0):
|
||||
liMessage(it.info, errPowerOfTwoExpected)
|
||||
of wSize:
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
var size = expectIntLit(c, it)
|
||||
if not IsPowerOfTwo(size) or size <= 0 or size > 8:
|
||||
liMessage(it.info, errPowerOfTwoExpected)
|
||||
else:
|
||||
sym.typ.size = size
|
||||
of wNodecl:
|
||||
noVal(it)
|
||||
incl(sym.loc.Flags, lfNoDecl)
|
||||
of wPure:
|
||||
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, sfThreadVar)
|
||||
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 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 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)
|
||||
incl(sym.typ.flags, tfVarargs)
|
||||
of wBorrow:
|
||||
noVal(it)
|
||||
incl(sym.flags, sfBorrow)
|
||||
of wFinal:
|
||||
noVal(it)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
incl(sym.typ.flags, tfFinal)
|
||||
of wAcyclic:
|
||||
noVal(it)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
incl(sym.typ.flags, tfAcyclic)
|
||||
of wTypeCheck:
|
||||
noVal(it)
|
||||
incl(sym.flags, sfTypeCheck)
|
||||
of wHint: liMessage(it.info, hintUser, expectStrLit(c, it))
|
||||
of wWarning: liMessage(it.info, warnUser, expectStrLit(c, it))
|
||||
of wError: liMessage(it.info, errUser, expectStrLit(c, it))
|
||||
of wFatal:
|
||||
liMessage(it.info, errUser, expectStrLit(c, it))
|
||||
quit(1)
|
||||
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 wCheckpoint: PragmaCheckpoint(c, it)
|
||||
of wPush:
|
||||
processPush(c, n, i + 1)
|
||||
break
|
||||
of wPop: processPop(c, it)
|
||||
of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks,
|
||||
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
||||
wLinedir, wStacktrace, wLinetrace, wOptimization, wByRef, wCallConv,
|
||||
wDebugger, wProfiler, wFloatChecks, wNanChecks, wInfChecks:
|
||||
processOption(c, it) # calling conventions (boring...):
|
||||
of firstCallConv..lastCallConv:
|
||||
assert(sym != nil)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
sym.typ.callConv = wordToCallConv(k)
|
||||
var userPragma = StrTableGet(c.userPragmas, key.ident)
|
||||
if userPragma != nil:
|
||||
pragma(c, sym, userPragma.ast, validPragmas)
|
||||
# XXX BUG: possible infinite recursion!
|
||||
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 wAlign:
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
sym.typ.align = expectIntLit(c, it)
|
||||
if not IsPowerOfTwo(sym.typ.align) and (sym.typ.align != 0):
|
||||
liMessage(it.info, errPowerOfTwoExpected)
|
||||
of wSize:
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
var size = expectIntLit(c, it)
|
||||
if not IsPowerOfTwo(size) or size <= 0 or size > 8:
|
||||
liMessage(it.info, errPowerOfTwoExpected)
|
||||
else:
|
||||
sym.typ.size = size
|
||||
of wNodecl:
|
||||
noVal(it)
|
||||
incl(sym.loc.Flags, lfNoDecl)
|
||||
of wPure:
|
||||
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, sfThreadVar)
|
||||
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 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 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)
|
||||
incl(sym.typ.flags, tfVarargs)
|
||||
of wBorrow:
|
||||
noVal(it)
|
||||
incl(sym.flags, sfBorrow)
|
||||
of wFinal:
|
||||
noVal(it)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
incl(sym.typ.flags, tfFinal)
|
||||
of wAcyclic:
|
||||
noVal(it)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
incl(sym.typ.flags, tfAcyclic)
|
||||
of wTypeCheck:
|
||||
noVal(it)
|
||||
incl(sym.flags, sfTypeCheck)
|
||||
of wHint: liMessage(it.info, hintUser, expectStrLit(c, it))
|
||||
of wWarning: liMessage(it.info, warnUser, expectStrLit(c, it))
|
||||
of wError: liMessage(it.info, errUser, expectStrLit(c, it))
|
||||
of wFatal:
|
||||
liMessage(it.info, errUser, expectStrLit(c, it))
|
||||
quit(1)
|
||||
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 wCheckpoint: PragmaCheckpoint(c, it)
|
||||
of wPush:
|
||||
processPush(c, n, i + 1)
|
||||
break
|
||||
of wPop: processPop(c, it)
|
||||
of wPragma:
|
||||
processPragma(c, n, i)
|
||||
break
|
||||
of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks,
|
||||
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
||||
wLinedir, wStacktrace, wLinetrace, wOptimization, wByRef,
|
||||
wCallConv,
|
||||
wDebugger, wProfiler, wFloatChecks, wNanChecks, wInfChecks:
|
||||
processOption(c, it) # calling conventions (boring...):
|
||||
of firstCallConv..lastCallConv:
|
||||
assert(sym != nil)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
sym.typ.callConv = wordToCallConv(k)
|
||||
else: invalidPragma(it)
|
||||
else: invalidPragma(it)
|
||||
else: invalidPragma(it)
|
||||
else: processNote(c, it)
|
||||
if (sym != nil) and (sym.kind != skModule):
|
||||
if (lfExportLib in sym.loc.flags) and not (sfExportc in sym.flags):
|
||||
|
||||
@@ -51,6 +51,7 @@ type
|
||||
semExpr*: proc (c: PContext, n: PNode): PNode # for the pragmas
|
||||
includedFiles*: TIntSet # used to detect recursive include files
|
||||
filename*: string # the module's filename
|
||||
userPragmas*: TStrTable
|
||||
|
||||
|
||||
var gInstTypes*: TIdTable # map PType to PType
|
||||
@@ -124,6 +125,7 @@ proc newContext(module: PSym, nimfile: string): PContext =
|
||||
result.converters = @ []
|
||||
result.filename = nimfile
|
||||
IntSetInit(result.includedFiles)
|
||||
initStrTable(result.userPragmas)
|
||||
|
||||
proc addConverter(c: PContext, conv: PSym) =
|
||||
var L = len(c.converters)
|
||||
|
||||
@@ -708,7 +708,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
pushOwner(s)
|
||||
s.options = gOptions
|
||||
if n.sons[codePos] != nil:
|
||||
if {sfImportc, sfBorrow} * s.flags != {}:
|
||||
# for DLL generation, it is annoying to check for sfImportc!
|
||||
if sfBorrow in s.flags:
|
||||
liMessage(n.sons[codePos].info, errImplOfXNotAllowed, s.name.s)
|
||||
if (n.sons[genericParamsPos] == nil):
|
||||
c.p = newProcCon(s)
|
||||
@@ -720,6 +721,9 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
if (s.typ.sons[0] != nil) and (kind != skIterator):
|
||||
addDecl(c, newSym(skUnknown, getIdent("result"), nil))
|
||||
n.sons[codePos] = semGenericStmtScope(c, n.sons[codePos])
|
||||
if sfImportc in s.flags:
|
||||
# so we just ignore the body after semantic checking for importc:
|
||||
n.sons[codePos] = nil
|
||||
else:
|
||||
if proto != nil: liMessage(n.info, errImplOfXexpected, proto.name.s)
|
||||
if {sfImportc, sfBorrow} * s.flags == {}: incl(s.flags, sfForward)
|
||||
|
||||
@@ -42,10 +42,11 @@ type
|
||||
wNimcall, wStdcall, wCdecl, wSafecall, wSyscall, wInline, wNoInline,
|
||||
wFastcall, wClosure, wNoconv, wOn, wOff, wChecks, wRangechecks,
|
||||
wBoundchecks, wOverflowchecks, wNilchecks,
|
||||
wFloatchecks, wNanChecks, wInfChecks,
|
||||
wFloatchecks, wNanChecks, wInfChecks,
|
||||
wAssertions, wWarnings, wW,
|
||||
wHints, wOptimization, wSpeed, wSize, wNone, wPath, wP, wD, wU, wDebuginfo,
|
||||
wCompileonly, wNolinking, wForcebuild, wF, wDeadCodeElim, wSafecode,
|
||||
wPragma,
|
||||
wCompileTime, wGc, wRefc, wBoehm, wA, wOpt, wO, wApp, wConsole, wGui,
|
||||
wPassc, wT, wPassl, wL, wListcmd, wGendoc, wGenmapping, wOs, wCpu,
|
||||
wGenerate, wG, wC, wCpp, wBorrow, wRun, wR, wVerbosity, wV, wHelp, wH,
|
||||
@@ -53,7 +54,7 @@ type
|
||||
wCc, wGenscript, wCheckPoint, wCheckPoints, wNoMain, wSubsChar,
|
||||
wAcyclic, wIndex,
|
||||
wCompileToC, wCompileToCpp, wCompileToEcmaScript, wCompileToLLVM, wPretty,
|
||||
wDoc, wPas, wGenDepend, wListDef, wCheck, wParse, wScan, wBoot, wLazy,
|
||||
wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wBoot, wLazy,
|
||||
wRst2html, wRst2tex, wI,
|
||||
wWrite, wPutEnv, wPrependEnv, wAppendEnv, wThreadVar
|
||||
|
||||
@@ -91,6 +92,7 @@ const
|
||||
"assertions", "warnings", "w", "hints",
|
||||
"optimization", "speed", "size", "none", "path", "p", "d", "u", "debuginfo",
|
||||
"compileonly", "nolinking", "forcebuild", "f", "deadcodeelim", "safecode",
|
||||
"pragma",
|
||||
"compiletime", "gc", "refc", "boehm", "a", "opt", "o", "app", "console",
|
||||
"gui", "passc", "t", "passl", "l", "listcmd", "gendoc", "genmapping", "os",
|
||||
"cpu", "generate", "g", "c", "cpp", "borrow", "run", "r", "verbosity", "v",
|
||||
@@ -98,7 +100,7 @@ const
|
||||
"skipcfg", "skipprojcfg", "cc", "genscript", "checkpoint", "checkpoints",
|
||||
"nomain", "subschar", "acyclic", "index",
|
||||
"compiletoc", "compiletocpp", "compiletoecmascript", "compiletollvm",
|
||||
"pretty", "doc", "pas", "gendepend", "listdef", "check", "parse", "scan",
|
||||
"pretty", "doc", "gendepend", "listdef", "check", "parse", "scan",
|
||||
"boot", "lazy", "rst2html", "rst2tex", "i",
|
||||
"write", "putenv", "prependenv", "appendenv", "threadvar"]
|
||||
|
||||
|
||||
7
tests/accept/compile/tuserpragma.nim
Normal file
7
tests/accept/compile/tuserpragma.nim
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
{.pragma: rtl, cdecl, exportc.}
|
||||
|
||||
proc myproc(x, y: int): int {.rtl} =
|
||||
nil
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ Additions
|
||||
- Implemented implicit type arguments for generics.
|
||||
- Implemented ``{.size: sizeof(cint).}`` pragma for enum types. This is useful
|
||||
for interfacing with C.
|
||||
- Implemented ``{.pragma.}`` pragma for user defined pragmas.
|
||||
|
||||
|
||||
2010-03-14 Version 0.8.8 released
|
||||
|
||||
Reference in New Issue
Block a user