backported .deprecated statement

This commit is contained in:
Araq
2014-10-11 20:31:24 +02:00
parent 028a62e2ba
commit 661c51682a
6 changed files with 169 additions and 134 deletions

View File

@@ -1,6 +1,6 @@
#
#
# The Nimrod Compiler
# The Nim Compiler
# (c) Copyright 2013 Andreas Rumpf
#
# See the file "copying.txt", included in this
@@ -291,6 +291,8 @@ const
sfNoRoot* = sfBorrow # a local variable is provably no root so it doesn't
# require RC ops
sfCompileToCpp* = sfInfixCall # compile the module as C++ code
sfCompileToObjc* = sfNamedParamCall # compile the module as Objective-C code
const
# getting ready for the future expr/stmt merge
@@ -476,7 +478,7 @@ type
# and first phase symbol lookup in generics
skConditional, # symbol for the preprocessor (may become obsolete)
skDynLib, # symbol represents a dynamic library; this is used
# internally; it does not exist in Nimrod code
# internally; it does not exist in Nim code
skParam, # a parameter
skGenericParam, # a generic parameter; eq in ``proc x[eq=`==`]()``
skTemp, # a temporary variable (introduced by compiler)
@@ -501,7 +503,8 @@ type
skStub, # symbol is a stub and not yet loaded from the ROD
# file (it is loaded on demand, which may
# mean: never)
skPackage # symbol is a package (used for canonicalization)
skPackage, # symbol is a package (used for canonicalization)
skAlias # an alias (needs to be resolved immediately)
TSymKinds* = set[TSymKind]
const
@@ -678,7 +681,7 @@ type
heapRoot*: PRope # keeps track of the enclosing heap object that
# owns this location (required by GC algorithms
# employing heap snapshots or sliding views)
a*: int # location's "address", i.e. slot for temporaries
a*: int
# ---------------- end of backend information ------------------------------
@@ -731,8 +734,9 @@ type
# check for the owner when touching 'usedGenerics'.
usedGenerics*: seq[PInstantiation]
tab*: TStrTable # interface table for modules
of skLet, skVar, skField:
guard*: PSym
else: nil
magic*: TMagic
typ*: PType
name*: PIdent
@@ -872,7 +876,7 @@ const
tyProc, tyString, tyError}
ExportableSymKinds* = {skVar, skConst, skProc, skMethod, skType,
skIterator, skClosureIterator,
skMacro, skTemplate, skConverter, skEnumField, skLet, skStub}
skMacro, skTemplate, skConverter, skEnumField, skLet, skStub, skAlias}
PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16,
nfDotSetter, nfDotField,
nfIsRef}
@@ -1162,7 +1166,6 @@ proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode,
result.sons = @[name, pattern, genericParams, params,
pragmas, exceptions, body]
proc newType(kind: TTypeKind, owner: PSym): PType =
new(result)
result.kind = kind
@@ -1172,8 +1175,8 @@ proc newType(kind: TTypeKind, owner: PSym): PType =
result.id = getID()
when debugIds:
registerId(result)
#if result.id < 2000 then
# MessageOut(typeKindToStr[kind] & ' has id: ' & toString(result.id))
#if result.id < 2000:
# messageOut(typeKindToStr[kind] & ' has id: ' & toString(result.id))
proc mergeLoc(a: var TLoc, b: TLoc) =
if a.k == low(a.k): a.k = b.k
@@ -1229,6 +1232,8 @@ proc copySym(s: PSym, keepId: bool = false): PSym =
result.position = s.position
result.loc = s.loc
result.annex = s.annex # BUGFIX
if result.kind in {skVar, skLet, skField}:
result.guard = s.guard
proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo): PSym =
result = newSym(s.kind, newIdent, s.owner, info)

View File

@@ -1,6 +1,6 @@
#
#
# The Nimrod Compiler
# The Nim Compiler
# (c) Copyright 2014 Andreas Rumpf
#
# See the file "copying.txt", included in this
@@ -60,7 +60,7 @@ const
quick
release debug
useWinAnsi useFork useNimRtl useMalloc useRealtimeGC ssl memProfiler
nodejs kwin
nodejs kwin nimfix
usesysassert usegcassert tinyC useFFI
useStdoutAsStdmsg createNimRtl
@@ -70,7 +70,7 @@ const
debugExecProcesses pcreDll useLipzipSrc
preventDeadlocks UNICODE winUnicode trackGcHeaders posixRealtime
nimSigSetjmp nimStdSetjmp nimRawSetjmp
nimStdSetjmp nimRawSetjmp nimSigSetjmp
""".split
proc initDefines*() =
@@ -87,6 +87,7 @@ proc initDefines*() =
defineSymbol("nimnewshared")
defineSymbol("nimrequiresnimframe")
defineSymbol("nimparsebiggestfloatmagic")
defineSymbol("nimalias")
# add platform specific symbols:
for c in low(CPU)..high(CPU):

View File

@@ -1,6 +1,6 @@
#
#
# The Nimrod Compiler
# The Nim Compiler
# (c) Copyright 2012 Andreas Rumpf
#
# See the file "copying.txt", included in this
@@ -11,7 +11,7 @@
import
intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread,
renderer, wordrecg, idgen
renderer, wordrecg, idgen, nimfix.prettybase
proc ensureNoMissingOrUnusedSymbols(scope: PScope)
@@ -40,11 +40,8 @@ proc considerQuotedIdent*(n: PNode): PIdent =
template addSym*(scope: PScope, s: PSym) =
strTableAdd(scope.symbols, s)
proc addUniqueSym*(scope: PScope, s: PSym): TResult =
if strTableIncl(scope.symbols, s):
result = Failure
else:
result = Success
proc addUniqueSym*(scope: PScope, s: PSym): bool =
result = not strTableIncl(scope.symbols, s)
proc openScope*(c: PContext): PScope {.discardable.} =
result = PScope(parent: c.currentScope,
@@ -65,6 +62,17 @@ iterator walkScopes*(scope: PScope): PScope =
yield current
current = current.parent
proc skipAlias*(s: PSym; n: PNode): PSym =
if s == nil or s.kind != skAlias:
result = s
else:
result = s.owner
if gCmd == cmdPretty:
prettybase.replaceDeprecated(n.info, s, result)
else:
message(n.info, warnDeprecated, "use " & result.name.s & " instead; " &
s.name.s)
proc localSearchInScope*(c: PContext, s: PIdent): PSym =
result = strTableGet(c.currentScope.symbols, s)
@@ -139,14 +147,14 @@ proc wrongRedefinition*(info: TLineInfo, s: string) =
localError(info, errAttemptToRedefine, s)
proc addDecl*(c: PContext, sym: PSym) =
if c.currentScope.addUniqueSym(sym) == Failure:
if not c.currentScope.addUniqueSym(sym):
wrongRedefinition(sym.info, sym.name.s)
proc addPrelimDecl*(c: PContext, sym: PSym) =
discard c.currentScope.addUniqueSym(sym)
proc addDeclAt*(scope: PScope, sym: PSym) =
if scope.addUniqueSym(sym) == Failure:
if not scope.addUniqueSym(sym):
wrongRedefinition(sym.info, sym.name.s)
proc addInterfaceDeclAux(c: PContext, sym: PSym) =
@@ -163,7 +171,7 @@ proc addOverloadableSymAt*(scope: PScope, fn: PSym) =
if fn.kind notin OverloadableSyms:
internalError(fn.info, "addOverloadableSymAt")
return
var check = strTableGet(scope.symbols, fn.name)
let check = strTableGet(scope.symbols, fn.name)
if check != nil and check.kind notin OverloadableSyms:
wrongRedefinition(fn.info, fn.name.s)
else:
@@ -179,20 +187,41 @@ proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) =
addOverloadableSymAt(scope, sym)
addInterfaceDeclAux(c, sym)
when defined(nimfix):
import strutils
# when we cannot find the identifier, retry with a changed identifer:
proc altSpelling(x: PIdent): PIdent =
case x.s[0]
of 'A'..'Z': result = getIdent(toLower(x.s[0]) & x.s.substr(1))
of 'a'..'z': result = getIdent(toLower(x.s[0]) & x.s.substr(1))
else: result = x
template fixSpelling(n: PNode; ident: PIdent; op: expr) =
let alt = ident.altSpelling
result = op(c, alt).skipAlias(n)
if result != nil:
prettybase.replaceDeprecated(n.info, ident, alt)
return result
else:
template fixSpelling(n: PNode; ident: PIdent; op: expr) = discard
proc lookUp*(c: PContext, n: PNode): PSym =
# Looks up a symbol. Generates an error in case of nil.
case n.kind
of nkIdent:
result = searchInScopes(c, n.ident)
if result == nil:
result = searchInScopes(c, n.ident).skipAlias(n)
if result == nil:
fixSpelling(n, n.ident, searchInScopes)
localError(n.info, errUndeclaredIdentifier, n.ident.s)
result = errorSym(c, n)
of nkSym:
result = n.sym
of nkAccQuoted:
var ident = considerQuotedIdent(n)
result = searchInScopes(c, ident)
result = searchInScopes(c, ident).skipAlias(n)
if result == nil:
fixSpelling(n, ident, searchInScopes)
localError(n.info, errUndeclaredIdentifier, ident.s)
result = errorSym(c, n)
else:
@@ -206,36 +235,38 @@ type
TLookupFlag* = enum
checkAmbiguity, checkUndeclared
proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
case n.kind
of nkIdent, nkAccQuoted:
var ident = considerQuotedIdent(n)
result = searchInScopes(c, ident)
if result == nil and checkUndeclared in flags:
result = searchInScopes(c, ident).skipAlias(n)
if result == nil and checkUndeclared in flags:
fixSpelling(n, ident, searchInScopes)
localError(n.info, errUndeclaredIdentifier, ident.s)
result = errorSym(c, n)
elif checkAmbiguity in flags and result != nil and
contains(c.ambiguousSymbols, result.id):
elif checkAmbiguity in flags and result != nil and
contains(c.ambiguousSymbols, result.id):
localError(n.info, errUseQualifier, ident.s)
of nkSym:
result = n.sym
if checkAmbiguity in flags and contains(c.ambiguousSymbols, result.id):
if checkAmbiguity in flags and contains(c.ambiguousSymbols, result.id):
localError(n.info, errUseQualifier, n.sym.name.s)
of nkDotExpr:
of nkDotExpr:
result = nil
var m = qualifiedLookUp(c, n.sons[0], flags*{checkUndeclared})
if (m != nil) and (m.kind == skModule):
if m != nil and m.kind == skModule:
var ident: PIdent = nil
if n.sons[1].kind == nkIdent:
if n.sons[1].kind == nkIdent:
ident = n.sons[1].ident
elif n.sons[1].kind == nkAccQuoted:
elif n.sons[1].kind == nkAccQuoted:
ident = considerQuotedIdent(n.sons[1])
if ident != nil:
if m == c.module:
result = strTableGet(c.topLevelScope.symbols, ident)
else:
result = strTableGet(m.tab, ident)
if result == nil and checkUndeclared in flags:
if ident != nil:
if m == c.module:
result = strTableGet(c.topLevelScope.symbols, ident).skipAlias(n)
else:
result = strTableGet(m.tab, ident).skipAlias(n)
if result == nil and checkUndeclared in flags:
fixSpelling(n.sons[1], ident, searchInScopes)
localError(n.sons[1].info, errUndeclaredIdentifier, ident.s)
result = errorSym(c, n.sons[1])
elif n.sons[1].kind == nkSym:
@@ -256,7 +287,7 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
o.scope = c.currentScope
o.mode = oimNoQualifier
while true:
result = initIdentIter(o.it, o.scope.symbols, ident)
result = initIdentIter(o.it, o.scope.symbols, ident).skipAlias(n)
if result != nil:
break
else:
@@ -277,11 +308,12 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
if ident != nil:
if o.m == c.module:
# a module may access its private members:
result = initIdentIter(o.it, c.topLevelScope.symbols, ident)
result = initIdentIter(o.it, c.topLevelScope.symbols,
ident).skipAlias(n)
o.mode = oimSelfModule
else:
result = initIdentIter(o.it, o.m.tab, ident)
else:
else:
result = initIdentIter(o.it, o.m.tab, ident).skipAlias(n)
else:
localError(n.sons[1].info, errIdentifierExpected,
renderTree(n.sons[1]))
result = errorSym(c, n.sons[1])
@@ -307,18 +339,18 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
result = nil
of oimNoQualifier:
if o.scope != nil:
result = nextIdentIter(o.it, o.scope.symbols)
result = nextIdentIter(o.it, o.scope.symbols).skipAlias(n)
while result == nil:
o.scope = o.scope.parent
if o.scope == nil: break
result = initIdentIter(o.it, o.scope.symbols, o.it.name)
result = initIdentIter(o.it, o.scope.symbols, o.it.name).skipAlias(n)
# BUGFIX: o.it.name <-> n.ident
else:
result = nil
of oimSelfModule:
result = nextIdentIter(o.it, c.topLevelScope.symbols)
result = nextIdentIter(o.it, c.topLevelScope.symbols).skipAlias(n)
of oimOtherModule:
result = nextIdentIter(o.it, o.m.tab)
result = nextIdentIter(o.it, o.m.tab).skipAlias(n)
of oimSymChoice:
if o.symChoiceIndex < sonsLen(n):
result = n.sons[o.symChoiceIndex].sym
@@ -329,31 +361,27 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
o.mode = oimSymChoiceLocalLookup
o.scope = c.currentScope
result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice)
n.sons[0].sym.name, o.inSymChoice).skipAlias(n)
while result == nil:
o.scope = o.scope.parent
if o.scope == nil: break
result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice)
n.sons[0].sym.name, o.inSymChoice).skipAlias(n)
of oimSymChoiceLocalLookup:
result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice)
result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice).skipAlias(n)
while result == nil:
o.scope = o.scope.parent
if o.scope == nil: break
result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice)
n.sons[0].sym.name, o.inSymChoice).skipAlias(n)
if result != nil and result.kind == skStub: loadStub(result)
when false:
proc qualifiedLookUpPreferImmediate*(c: PContext, n: PNode,
flags = {checkUndeclared}): PSym =
var o: TOverloadIter
result = initOverloadIter(o, c, n)
var a = result
while a != nil:
if sfImmediate in a.flags: return a
a = nextOverloadIter(o, c, n)
if result == nil and checkUndeclared in flags:
localError(n.info, errUndeclaredIdentifier, n.considerQuotedIdent.s)
result = errorSym(c, n)
proc pickSym*(c: PContext, n: PNode; kind: TSymKind;
flags: TSymFlags = {}): PSym =
var o: TOverloadIter
var a = initOverloadIter(o, c, n)
while a != nil:
if a.kind == kind and flags <= a.flags:
return a
a = nextOverloadIter(o, c, n)

View File

@@ -1,6 +1,6 @@
#
#
# The Nimrod Compiler
# The Nim Compiler
# (c) Copyright 2014 Andreas Rumpf
#
# See the file "copying.txt", included in this
@@ -24,7 +24,7 @@ const
wCompilerproc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
wGensym, wInject, wRaises, wTags, wUses, wOperator, wDelegator, wGcSafe,
wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
wOverride}
converterPragmas* = procPragmas
methodPragmas* = procPragmas
@@ -36,8 +36,8 @@ const
iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideeffect, wSideeffect,
wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises,
wTags, wUses, wOperator, wGcSafe}
exprPragmas* = {wLine}
wTags, wLocks, wGcSafe}
exprPragmas* = {wLine, wLocks}
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks,
wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError,
@@ -45,27 +45,27 @@ const
wBreakpoint, wWatchPoint, wPassl, wPassc, wDeadCodeElim, wDeprecated,
wFloatchecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto,
wInjectStmt}
wInjectStmt, wDeprecated}
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader,
wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame,
wRaises, wUses, wTags, wGcSafe}
wRaises, wLocks, wTags, wGcSafe}
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow,
wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
wBorrow, wGcSafe}
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
wImportCpp, wImportObjC, wError}
wImportCpp, wImportObjC, wError, wGuard}
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern,
wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal,
wGensym, wInject, wCodegenDecl}
wGensym, wInject, wCodegenDecl, wGuard}
constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject}
letPragmas* = varPragmas
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideeffect,
wThread, wRaises, wUses, wTags, wGcSafe}
wThread, wRaises, wLocks, wTags, wGcSafe}
allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas
proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords)
@@ -128,12 +128,16 @@ proc processImportCpp(s: PSym, extname: string) =
incl(s.flags, sfImportc)
incl(s.flags, sfInfixCall)
excl(s.flags, sfForward)
let m = s.getModule()
incl(m.flags, sfCompileToCpp)
proc processImportObjC(s: PSym, extname: string) =
setExternName(s, extname)
incl(s.flags, sfImportc)
incl(s.flags, sfNamedParamCall)
excl(s.flags, sfForward)
let m = s.getModule()
incl(m.flags, sfCompileToObjC)
proc newEmptyStrNode(n: PNode): PNode {.noinline.} =
result = newNodeIT(nkStrLit, n.info, getSysType(tyString))
@@ -514,27 +518,6 @@ proc pragmaRaisesOrTags(c: PContext, n: PNode) =
else:
invalidPragma(n)
proc pragmaUses(c: PContext, n: PNode) =
proc processExc(c: PContext, x: PNode): PNode =
if x.kind in {nkAccQuoted, nkIdent, nkSym,
nkOpenSymChoice, nkClosedSymChoice}:
if considerQuotedIdent(x).s == "*":
return newSymNode(ast.anyGlobal)
result = c.semExpr(c, x)
if result.kind != nkSym or sfGlobal notin result.sym.flags:
localError(x.info, "'$1' is not a global variable" % result.renderTree)
result = newSymNode(ast.anyGlobal)
if n.kind == nkExprColonExpr:
let it = n.sons[1]
if it.kind notin {nkCurly, nkBracket}:
n.sons[1] = processExc(c, it)
else:
for i in 0 .. <it.len:
it.sons[i] = processExc(c, it.sons[i])
else:
invalidPragma(n)
proc typeBorrow(sym: PSym, n: PNode) =
if n.kind == nkExprColonExpr:
let it = n.sons[1]
@@ -542,11 +525,50 @@ proc typeBorrow(sym: PSym, n: PNode) =
localError(n.info, "a type can only borrow `.` for now")
incl(sym.typ.flags, tfBorrowDot)
proc markCompilerProc(s: PSym) =
makeExternExport(s, "$1", s.info)
incl(s.flags, sfCompilerProc)
incl(s.flags, sfUsed)
registerCompilerProc(s)
proc deprecatedStmt(c: PContext; pragma: PNode) =
let pragma = pragma[1]
if pragma.kind != nkBracket:
localError(pragma.info, "list of key:value pairs expected"); return
for n in pragma:
if n.kind in {nkExprColonExpr, nkExprEqExpr}:
let dest = qualifiedLookUp(c, n[1])
let src = considerQuotedIdent(n[0])
let alias = newSym(skAlias, src, dest, n[0].info)
incl(alias.flags, sfExported)
if sfCompilerProc in dest.flags: markCompilerProc(alias)
addInterfaceDecl(c, alias)
else:
localError(n.info, "key:value pair expected")
proc pragmaGuard(c: PContext; it: PNode; kind: TSymKind): PSym =
if it.kind != nkExprColonExpr:
invalidPragma(it); return
let n = it[1]
if n.kind == nkSym:
result = n.sym
elif kind == skField:
# First check if the guard is a global variable:
result = qualifiedLookUp(c, n, {})
if result.isNil or result.kind notin {skLet, skVar} or
sfGlobal notin result.flags:
# We return a dummy symbol; later passes over the type will repair it.
# Generic instantiation needs to know about this too. But we're lazy
# and perform the lookup on demand instead.
result = newSym(skUnknown, considerQuotedIdent(n), nil, n.info)
else:
result = qualifiedLookUp(c, n)
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:
if key.kind == nkIdent:
var userPragma = strTableGet(c.userPragmas, key.ident)
if userPragma != nil:
inc c.instCounter
@@ -578,11 +600,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
of wAlign:
if sym.typ == nil: invalidPragma(it)
var align = expectIntLit(c, it)
if not isPowerOfTwo(align) and align != 0:
if (not isPowerOfTwo(align) and align != 0) or align >% high(int16):
localError(it.info, errPowerOfTwoExpected)
else:
sym.typ.align = align
of wSize:
sym.typ.align = align.int16
of wSize:
if sym.typ == nil: invalidPragma(it)
var size = expectIntLit(c, it)
if not isPowerOfTwo(size) or size <= 0 or size > 8:
@@ -648,17 +670,13 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
processDynLib(c, it, sym)
of wCompilerproc:
noVal(it) # compilerproc may not get a string!
if sfFromGeneric notin sym.flags:
makeExternExport(sym, "$1", it.info)
incl(sym.flags, sfCompilerProc)
incl(sym.flags, sfUsed) # suppress all those stupid warnings
registerCompilerProc(sym)
of wProcVar:
if sfFromGeneric notin sym.flags: markCompilerProc(sym)
of wProcVar:
noVal(it)
incl(sym.flags, sfProcvar)
of wDeprecated:
noVal(it)
if sym != nil: incl(sym.flags, sfDeprecated)
of wDeprecated:
if it.kind == nkExprColonExpr: deprecatedStmt(c, it)
elif sym != nil: incl(sym.flags, sfDeprecated)
else: incl(c.module.flags, sfDeprecated)
of wVarargs:
noVal(it)
@@ -789,10 +807,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
if sym == nil: invalidPragma(it)
of wLine: pragmaLine(c, it)
of wRaises, wTags: pragmaRaisesOrTags(c, it)
of wUses: pragmaUses(c, it)
of wOperator:
if sym == nil: invalidPragma(it)
else: sym.position = expectIntLit(c, it)
of wGuard:
if sym == nil or sym.kind notin {skVar, skLet, skField}:
invalidPragma(it)
else:
sym.guard = pragmaGuard(c, it, sym.kind)
of wInjectStmt:
if it.kind != nkExprColonExpr:
localError(it.info, errExprExpected)

View File

@@ -315,7 +315,6 @@ proc documentRaises*(n: PNode) =
if n.sons[namePos].kind != nkSym: return
documentEffect(n, n.sons[pragmasPos], wRaises, exceptionEffects)
documentEffect(n, n.sons[pragmasPos], wTags, tagEffects)
documentEffect(n, n.sons[pragmasPos], wUses, usesEffects)
template notGcSafe(t): expr = {tfGcSafe, tfNoSideEffect} * t.flags == {}
@@ -335,10 +334,6 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) =
if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n))
tracked.gcUnsafe = true
when trackGlobals:
let usesSpec = effectSpec(pragma, wUses)
mergeUses(tracked, usesSpec, n)
proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) =
let n = n.skipConv
if paramType != nil and tfNotNil in paramType.flags and
@@ -641,10 +636,6 @@ proc checkMethodEffects*(disp, branch: PSym) =
if not isNil(tagsSpec):
checkRaisesSpec(tagsSpec, actual.sons[tagEffects],
"can have an unlisted effect: ", hints=off, subtypeRelation)
let usesSpec = effectSpec(p, wUses)
if not isNil(usesSpec):
checkRaisesSpec(usesSpec, actual.sons[usesEffects],
"may use an unlisted global variable: ", hints=off, symbolPredicate)
if sfThread in disp.flags and notGcSafe(branch.typ):
localError(branch.info, "base method is GC-safe, but '$1' is not" %
branch.name.s)
@@ -656,16 +647,13 @@ proc setEffectsForProcType*(t: PType, n: PNode) =
let
raisesSpec = effectSpec(n, wRaises)
tagsSpec = effectSpec(n, wTags)
usesSpec = effectSpec(n, wUses)
if not isNil(raisesSpec) or not isNil(tagsSpec) or not isNil(usesSpec):
if not isNil(raisesSpec) or not isNil(tagsSpec):
internalAssert effects.len == 0
newSeq(effects.sons, effectListLen)
if not isNil(raisesSpec):
effects.sons[exceptionEffects] = raisesSpec
if not isNil(tagsSpec):
effects.sons[tagEffects] = tagsSpec
if not isNil(usesSpec):
effects.sons[usesEffects] = usesSpec
proc initEffects(effects: PNode; s: PSym; t: var TEffects) =
newSeq(effects.sons, effectListLen)
@@ -710,12 +698,6 @@ proc trackProc*(s: PSym, body: PNode) =
# after the check, use the formal spec:
effects.sons[tagEffects] = tagsSpec
when trackGlobals:
let usesSpec = effectSpec(p, wUses)
if not isNil(usesSpec):
checkRaisesSpec(usesSpec, t.uses,
"uses an unlisted global variable: ", hints=on, symbolPredicate)
effects.sons[usesEffects] = usesSpec
if optThreadAnalysis in gGlobalOptions:
if sfThread in s.flags and t.gcUnsafe:
#localError(s.info, warnGcUnsafe2, s.name.s)

View File

@@ -64,7 +64,7 @@ type
wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, wInjectStmt,
wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
wAsmNoStackFrame,
wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wUses,
wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks,
wAuto, wBool, wCatch, wChar, wClass,
wConst_cast, wDefault, wDelete, wDouble, wDynamic_cast,
@@ -147,7 +147,7 @@ const
"computedgoto", "injectstmt",
"write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
"asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked",
"guard", "uses",
"guard", "locks",
"auto", "bool", "catch", "char", "class",
"const_cast", "default", "delete", "double",