backported .deprecated statement
This commit is contained in:
parent
028a62e2ba
commit
661c51682a
6 changed files with 169 additions and 134 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nim Compiler
|
||||||
# (c) Copyright 2013 Andreas Rumpf
|
# (c) Copyright 2013 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# 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
|
sfNoRoot* = sfBorrow # a local variable is provably no root so it doesn't
|
||||||
# require RC ops
|
# require RC ops
|
||||||
|
sfCompileToCpp* = sfInfixCall # compile the module as C++ code
|
||||||
|
sfCompileToObjc* = sfNamedParamCall # compile the module as Objective-C code
|
||||||
|
|
||||||
const
|
const
|
||||||
# getting ready for the future expr/stmt merge
|
# getting ready for the future expr/stmt merge
|
||||||
|
|
@ -476,7 +478,7 @@ type
|
||||||
# and first phase symbol lookup in generics
|
# and first phase symbol lookup in generics
|
||||||
skConditional, # symbol for the preprocessor (may become obsolete)
|
skConditional, # symbol for the preprocessor (may become obsolete)
|
||||||
skDynLib, # symbol represents a dynamic library; this is used
|
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
|
skParam, # a parameter
|
||||||
skGenericParam, # a generic parameter; eq in ``proc x[eq=`==`]()``
|
skGenericParam, # a generic parameter; eq in ``proc x[eq=`==`]()``
|
||||||
skTemp, # a temporary variable (introduced by compiler)
|
skTemp, # a temporary variable (introduced by compiler)
|
||||||
|
|
@ -501,7 +503,8 @@ type
|
||||||
skStub, # symbol is a stub and not yet loaded from the ROD
|
skStub, # symbol is a stub and not yet loaded from the ROD
|
||||||
# file (it is loaded on demand, which may
|
# file (it is loaded on demand, which may
|
||||||
# mean: never)
|
# 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]
|
TSymKinds* = set[TSymKind]
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
@ -678,7 +681,7 @@ type
|
||||||
heapRoot*: PRope # keeps track of the enclosing heap object that
|
heapRoot*: PRope # keeps track of the enclosing heap object that
|
||||||
# owns this location (required by GC algorithms
|
# owns this location (required by GC algorithms
|
||||||
# employing heap snapshots or sliding views)
|
# employing heap snapshots or sliding views)
|
||||||
a*: int # location's "address", i.e. slot for temporaries
|
a*: int
|
||||||
|
|
||||||
# ---------------- end of backend information ------------------------------
|
# ---------------- end of backend information ------------------------------
|
||||||
|
|
||||||
|
|
@ -731,8 +734,9 @@ type
|
||||||
# check for the owner when touching 'usedGenerics'.
|
# check for the owner when touching 'usedGenerics'.
|
||||||
usedGenerics*: seq[PInstantiation]
|
usedGenerics*: seq[PInstantiation]
|
||||||
tab*: TStrTable # interface table for modules
|
tab*: TStrTable # interface table for modules
|
||||||
|
of skLet, skVar, skField:
|
||||||
|
guard*: PSym
|
||||||
else: nil
|
else: nil
|
||||||
|
|
||||||
magic*: TMagic
|
magic*: TMagic
|
||||||
typ*: PType
|
typ*: PType
|
||||||
name*: PIdent
|
name*: PIdent
|
||||||
|
|
@ -872,7 +876,7 @@ const
|
||||||
tyProc, tyString, tyError}
|
tyProc, tyString, tyError}
|
||||||
ExportableSymKinds* = {skVar, skConst, skProc, skMethod, skType,
|
ExportableSymKinds* = {skVar, skConst, skProc, skMethod, skType,
|
||||||
skIterator, skClosureIterator,
|
skIterator, skClosureIterator,
|
||||||
skMacro, skTemplate, skConverter, skEnumField, skLet, skStub}
|
skMacro, skTemplate, skConverter, skEnumField, skLet, skStub, skAlias}
|
||||||
PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16,
|
PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16,
|
||||||
nfDotSetter, nfDotField,
|
nfDotSetter, nfDotField,
|
||||||
nfIsRef}
|
nfIsRef}
|
||||||
|
|
@ -1162,7 +1166,6 @@ proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode,
|
||||||
result.sons = @[name, pattern, genericParams, params,
|
result.sons = @[name, pattern, genericParams, params,
|
||||||
pragmas, exceptions, body]
|
pragmas, exceptions, body]
|
||||||
|
|
||||||
|
|
||||||
proc newType(kind: TTypeKind, owner: PSym): PType =
|
proc newType(kind: TTypeKind, owner: PSym): PType =
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = kind
|
result.kind = kind
|
||||||
|
|
@ -1172,8 +1175,8 @@ proc newType(kind: TTypeKind, owner: PSym): PType =
|
||||||
result.id = getID()
|
result.id = getID()
|
||||||
when debugIds:
|
when debugIds:
|
||||||
registerId(result)
|
registerId(result)
|
||||||
#if result.id < 2000 then
|
#if result.id < 2000:
|
||||||
# MessageOut(typeKindToStr[kind] & ' has id: ' & toString(result.id))
|
# messageOut(typeKindToStr[kind] & ' has id: ' & toString(result.id))
|
||||||
|
|
||||||
proc mergeLoc(a: var TLoc, b: TLoc) =
|
proc mergeLoc(a: var TLoc, b: TLoc) =
|
||||||
if a.k == low(a.k): a.k = b.k
|
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.position = s.position
|
||||||
result.loc = s.loc
|
result.loc = s.loc
|
||||||
result.annex = s.annex # BUGFIX
|
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 =
|
proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo): PSym =
|
||||||
result = newSym(s.kind, newIdent, s.owner, info)
|
result = newSym(s.kind, newIdent, s.owner, info)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nim Compiler
|
||||||
# (c) Copyright 2014 Andreas Rumpf
|
# (c) Copyright 2014 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
|
|
@ -60,7 +60,7 @@ const
|
||||||
quick
|
quick
|
||||||
release debug
|
release debug
|
||||||
useWinAnsi useFork useNimRtl useMalloc useRealtimeGC ssl memProfiler
|
useWinAnsi useFork useNimRtl useMalloc useRealtimeGC ssl memProfiler
|
||||||
nodejs kwin
|
nodejs kwin nimfix
|
||||||
|
|
||||||
usesysassert usegcassert tinyC useFFI
|
usesysassert usegcassert tinyC useFFI
|
||||||
useStdoutAsStdmsg createNimRtl
|
useStdoutAsStdmsg createNimRtl
|
||||||
|
|
@ -70,7 +70,7 @@ const
|
||||||
debugExecProcesses pcreDll useLipzipSrc
|
debugExecProcesses pcreDll useLipzipSrc
|
||||||
preventDeadlocks UNICODE winUnicode trackGcHeaders posixRealtime
|
preventDeadlocks UNICODE winUnicode trackGcHeaders posixRealtime
|
||||||
|
|
||||||
nimSigSetjmp nimStdSetjmp nimRawSetjmp
|
nimStdSetjmp nimRawSetjmp nimSigSetjmp
|
||||||
""".split
|
""".split
|
||||||
|
|
||||||
proc initDefines*() =
|
proc initDefines*() =
|
||||||
|
|
@ -87,6 +87,7 @@ proc initDefines*() =
|
||||||
defineSymbol("nimnewshared")
|
defineSymbol("nimnewshared")
|
||||||
defineSymbol("nimrequiresnimframe")
|
defineSymbol("nimrequiresnimframe")
|
||||||
defineSymbol("nimparsebiggestfloatmagic")
|
defineSymbol("nimparsebiggestfloatmagic")
|
||||||
|
defineSymbol("nimalias")
|
||||||
|
|
||||||
# add platform specific symbols:
|
# add platform specific symbols:
|
||||||
for c in low(CPU)..high(CPU):
|
for c in low(CPU)..high(CPU):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nim Compiler
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2012 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread,
|
intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread,
|
||||||
renderer, wordrecg, idgen
|
renderer, wordrecg, idgen, nimfix.prettybase
|
||||||
|
|
||||||
proc ensureNoMissingOrUnusedSymbols(scope: PScope)
|
proc ensureNoMissingOrUnusedSymbols(scope: PScope)
|
||||||
|
|
||||||
|
|
@ -40,11 +40,8 @@ proc considerQuotedIdent*(n: PNode): PIdent =
|
||||||
template addSym*(scope: PScope, s: PSym) =
|
template addSym*(scope: PScope, s: PSym) =
|
||||||
strTableAdd(scope.symbols, s)
|
strTableAdd(scope.symbols, s)
|
||||||
|
|
||||||
proc addUniqueSym*(scope: PScope, s: PSym): TResult =
|
proc addUniqueSym*(scope: PScope, s: PSym): bool =
|
||||||
if strTableIncl(scope.symbols, s):
|
result = not strTableIncl(scope.symbols, s)
|
||||||
result = Failure
|
|
||||||
else:
|
|
||||||
result = Success
|
|
||||||
|
|
||||||
proc openScope*(c: PContext): PScope {.discardable.} =
|
proc openScope*(c: PContext): PScope {.discardable.} =
|
||||||
result = PScope(parent: c.currentScope,
|
result = PScope(parent: c.currentScope,
|
||||||
|
|
@ -65,6 +62,17 @@ iterator walkScopes*(scope: PScope): PScope =
|
||||||
yield current
|
yield current
|
||||||
current = current.parent
|
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 =
|
proc localSearchInScope*(c: PContext, s: PIdent): PSym =
|
||||||
result = strTableGet(c.currentScope.symbols, s)
|
result = strTableGet(c.currentScope.symbols, s)
|
||||||
|
|
||||||
|
|
@ -139,14 +147,14 @@ proc wrongRedefinition*(info: TLineInfo, s: string) =
|
||||||
localError(info, errAttemptToRedefine, s)
|
localError(info, errAttemptToRedefine, s)
|
||||||
|
|
||||||
proc addDecl*(c: PContext, sym: PSym) =
|
proc addDecl*(c: PContext, sym: PSym) =
|
||||||
if c.currentScope.addUniqueSym(sym) == Failure:
|
if not c.currentScope.addUniqueSym(sym):
|
||||||
wrongRedefinition(sym.info, sym.name.s)
|
wrongRedefinition(sym.info, sym.name.s)
|
||||||
|
|
||||||
proc addPrelimDecl*(c: PContext, sym: PSym) =
|
proc addPrelimDecl*(c: PContext, sym: PSym) =
|
||||||
discard c.currentScope.addUniqueSym(sym)
|
discard c.currentScope.addUniqueSym(sym)
|
||||||
|
|
||||||
proc addDeclAt*(scope: PScope, sym: PSym) =
|
proc addDeclAt*(scope: PScope, sym: PSym) =
|
||||||
if scope.addUniqueSym(sym) == Failure:
|
if not scope.addUniqueSym(sym):
|
||||||
wrongRedefinition(sym.info, sym.name.s)
|
wrongRedefinition(sym.info, sym.name.s)
|
||||||
|
|
||||||
proc addInterfaceDeclAux(c: PContext, sym: PSym) =
|
proc addInterfaceDeclAux(c: PContext, sym: PSym) =
|
||||||
|
|
@ -163,7 +171,7 @@ proc addOverloadableSymAt*(scope: PScope, fn: PSym) =
|
||||||
if fn.kind notin OverloadableSyms:
|
if fn.kind notin OverloadableSyms:
|
||||||
internalError(fn.info, "addOverloadableSymAt")
|
internalError(fn.info, "addOverloadableSymAt")
|
||||||
return
|
return
|
||||||
var check = strTableGet(scope.symbols, fn.name)
|
let check = strTableGet(scope.symbols, fn.name)
|
||||||
if check != nil and check.kind notin OverloadableSyms:
|
if check != nil and check.kind notin OverloadableSyms:
|
||||||
wrongRedefinition(fn.info, fn.name.s)
|
wrongRedefinition(fn.info, fn.name.s)
|
||||||
else:
|
else:
|
||||||
|
|
@ -179,20 +187,41 @@ proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) =
|
||||||
addOverloadableSymAt(scope, sym)
|
addOverloadableSymAt(scope, sym)
|
||||||
addInterfaceDeclAux(c, 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 =
|
proc lookUp*(c: PContext, n: PNode): PSym =
|
||||||
# Looks up a symbol. Generates an error in case of nil.
|
# Looks up a symbol. Generates an error in case of nil.
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
result = searchInScopes(c, n.ident)
|
result = searchInScopes(c, n.ident).skipAlias(n)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
|
fixSpelling(n, n.ident, searchInScopes)
|
||||||
localError(n.info, errUndeclaredIdentifier, n.ident.s)
|
localError(n.info, errUndeclaredIdentifier, n.ident.s)
|
||||||
result = errorSym(c, n)
|
result = errorSym(c, n)
|
||||||
of nkSym:
|
of nkSym:
|
||||||
result = n.sym
|
result = n.sym
|
||||||
of nkAccQuoted:
|
of nkAccQuoted:
|
||||||
var ident = considerQuotedIdent(n)
|
var ident = considerQuotedIdent(n)
|
||||||
result = searchInScopes(c, ident)
|
result = searchInScopes(c, ident).skipAlias(n)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
|
fixSpelling(n, ident, searchInScopes)
|
||||||
localError(n.info, errUndeclaredIdentifier, ident.s)
|
localError(n.info, errUndeclaredIdentifier, ident.s)
|
||||||
result = errorSym(c, n)
|
result = errorSym(c, n)
|
||||||
else:
|
else:
|
||||||
|
|
@ -210,8 +239,9 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkIdent, nkAccQuoted:
|
of nkIdent, nkAccQuoted:
|
||||||
var ident = considerQuotedIdent(n)
|
var ident = considerQuotedIdent(n)
|
||||||
result = searchInScopes(c, ident)
|
result = searchInScopes(c, ident).skipAlias(n)
|
||||||
if result == nil and checkUndeclared in flags:
|
if result == nil and checkUndeclared in flags:
|
||||||
|
fixSpelling(n, ident, searchInScopes)
|
||||||
localError(n.info, errUndeclaredIdentifier, ident.s)
|
localError(n.info, errUndeclaredIdentifier, ident.s)
|
||||||
result = errorSym(c, n)
|
result = errorSym(c, n)
|
||||||
elif checkAmbiguity in flags and result != nil and
|
elif checkAmbiguity in flags and result != nil and
|
||||||
|
|
@ -224,7 +254,7 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
|
||||||
of nkDotExpr:
|
of nkDotExpr:
|
||||||
result = nil
|
result = nil
|
||||||
var m = qualifiedLookUp(c, n.sons[0], flags*{checkUndeclared})
|
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
|
var ident: PIdent = nil
|
||||||
if n.sons[1].kind == nkIdent:
|
if n.sons[1].kind == nkIdent:
|
||||||
ident = n.sons[1].ident
|
ident = n.sons[1].ident
|
||||||
|
|
@ -232,10 +262,11 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
|
||||||
ident = considerQuotedIdent(n.sons[1])
|
ident = considerQuotedIdent(n.sons[1])
|
||||||
if ident != nil:
|
if ident != nil:
|
||||||
if m == c.module:
|
if m == c.module:
|
||||||
result = strTableGet(c.topLevelScope.symbols, ident)
|
result = strTableGet(c.topLevelScope.symbols, ident).skipAlias(n)
|
||||||
else:
|
else:
|
||||||
result = strTableGet(m.tab, ident)
|
result = strTableGet(m.tab, ident).skipAlias(n)
|
||||||
if result == nil and checkUndeclared in flags:
|
if result == nil and checkUndeclared in flags:
|
||||||
|
fixSpelling(n.sons[1], ident, searchInScopes)
|
||||||
localError(n.sons[1].info, errUndeclaredIdentifier, ident.s)
|
localError(n.sons[1].info, errUndeclaredIdentifier, ident.s)
|
||||||
result = errorSym(c, n.sons[1])
|
result = errorSym(c, n.sons[1])
|
||||||
elif n.sons[1].kind == nkSym:
|
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.scope = c.currentScope
|
||||||
o.mode = oimNoQualifier
|
o.mode = oimNoQualifier
|
||||||
while true:
|
while true:
|
||||||
result = initIdentIter(o.it, o.scope.symbols, ident)
|
result = initIdentIter(o.it, o.scope.symbols, ident).skipAlias(n)
|
||||||
if result != nil:
|
if result != nil:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
|
@ -277,10 +308,11 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
||||||
if ident != nil:
|
if ident != nil:
|
||||||
if o.m == c.module:
|
if o.m == c.module:
|
||||||
# a module may access its private members:
|
# 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
|
o.mode = oimSelfModule
|
||||||
else:
|
else:
|
||||||
result = initIdentIter(o.it, o.m.tab, ident)
|
result = initIdentIter(o.it, o.m.tab, ident).skipAlias(n)
|
||||||
else:
|
else:
|
||||||
localError(n.sons[1].info, errIdentifierExpected,
|
localError(n.sons[1].info, errIdentifierExpected,
|
||||||
renderTree(n.sons[1]))
|
renderTree(n.sons[1]))
|
||||||
|
|
@ -307,18 +339,18 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
||||||
result = nil
|
result = nil
|
||||||
of oimNoQualifier:
|
of oimNoQualifier:
|
||||||
if o.scope != nil:
|
if o.scope != nil:
|
||||||
result = nextIdentIter(o.it, o.scope.symbols)
|
result = nextIdentIter(o.it, o.scope.symbols).skipAlias(n)
|
||||||
while result == nil:
|
while result == nil:
|
||||||
o.scope = o.scope.parent
|
o.scope = o.scope.parent
|
||||||
if o.scope == nil: break
|
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
|
# BUGFIX: o.it.name <-> n.ident
|
||||||
else:
|
else:
|
||||||
result = nil
|
result = nil
|
||||||
of oimSelfModule:
|
of oimSelfModule:
|
||||||
result = nextIdentIter(o.it, c.topLevelScope.symbols)
|
result = nextIdentIter(o.it, c.topLevelScope.symbols).skipAlias(n)
|
||||||
of oimOtherModule:
|
of oimOtherModule:
|
||||||
result = nextIdentIter(o.it, o.m.tab)
|
result = nextIdentIter(o.it, o.m.tab).skipAlias(n)
|
||||||
of oimSymChoice:
|
of oimSymChoice:
|
||||||
if o.symChoiceIndex < sonsLen(n):
|
if o.symChoiceIndex < sonsLen(n):
|
||||||
result = n.sons[o.symChoiceIndex].sym
|
result = n.sons[o.symChoiceIndex].sym
|
||||||
|
|
@ -329,31 +361,27 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
||||||
o.mode = oimSymChoiceLocalLookup
|
o.mode = oimSymChoiceLocalLookup
|
||||||
o.scope = c.currentScope
|
o.scope = c.currentScope
|
||||||
result = firstIdentExcluding(o.it, o.scope.symbols,
|
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:
|
while result == nil:
|
||||||
o.scope = o.scope.parent
|
o.scope = o.scope.parent
|
||||||
if o.scope == nil: break
|
if o.scope == nil: break
|
||||||
result = firstIdentExcluding(o.it, o.scope.symbols,
|
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:
|
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:
|
while result == nil:
|
||||||
o.scope = o.scope.parent
|
o.scope = o.scope.parent
|
||||||
if o.scope == nil: break
|
if o.scope == nil: break
|
||||||
result = firstIdentExcluding(o.it, o.scope.symbols,
|
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)
|
if result != nil and result.kind == skStub: loadStub(result)
|
||||||
|
|
||||||
when false:
|
proc pickSym*(c: PContext, n: PNode; kind: TSymKind;
|
||||||
proc qualifiedLookUpPreferImmediate*(c: PContext, n: PNode,
|
flags: TSymFlags = {}): PSym =
|
||||||
flags = {checkUndeclared}): PSym =
|
var o: TOverloadIter
|
||||||
var o: TOverloadIter
|
var a = initOverloadIter(o, c, n)
|
||||||
result = initOverloadIter(o, c, n)
|
while a != nil:
|
||||||
var a = result
|
if a.kind == kind and flags <= a.flags:
|
||||||
while a != nil:
|
return a
|
||||||
if sfImmediate in a.flags: return a
|
a = nextOverloadIter(o, c, n)
|
||||||
a = nextOverloadIter(o, c, n)
|
|
||||||
if result == nil and checkUndeclared in flags:
|
|
||||||
localError(n.info, errUndeclaredIdentifier, n.considerQuotedIdent.s)
|
|
||||||
result = errorSym(c, n)
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nim Compiler
|
||||||
# (c) Copyright 2014 Andreas Rumpf
|
# (c) Copyright 2014 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
|
|
@ -24,7 +24,7 @@ const
|
||||||
wCompilerproc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
|
wCompilerproc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
|
||||||
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
|
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
|
||||||
wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
|
wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
|
||||||
wGensym, wInject, wRaises, wTags, wUses, wOperator, wDelegator, wGcSafe,
|
wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
|
||||||
wOverride}
|
wOverride}
|
||||||
converterPragmas* = procPragmas
|
converterPragmas* = procPragmas
|
||||||
methodPragmas* = procPragmas
|
methodPragmas* = procPragmas
|
||||||
|
|
@ -36,8 +36,8 @@ const
|
||||||
iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideeffect, wSideeffect,
|
iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideeffect, wSideeffect,
|
||||||
wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
|
wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
|
||||||
wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises,
|
wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises,
|
||||||
wTags, wUses, wOperator, wGcSafe}
|
wTags, wLocks, wGcSafe}
|
||||||
exprPragmas* = {wLine}
|
exprPragmas* = {wLine, wLocks}
|
||||||
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks,
|
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks,
|
||||||
wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
||||||
wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError,
|
wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError,
|
||||||
|
|
@ -45,27 +45,27 @@ const
|
||||||
wBreakpoint, wWatchPoint, wPassl, wPassc, wDeadCodeElim, wDeprecated,
|
wBreakpoint, wWatchPoint, wPassl, wPassc, wDeadCodeElim, wDeprecated,
|
||||||
wFloatchecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
|
wFloatchecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
|
||||||
wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto,
|
wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto,
|
||||||
wInjectStmt}
|
wInjectStmt, wDeprecated}
|
||||||
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||||
wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader,
|
wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader,
|
||||||
wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame,
|
wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame,
|
||||||
wRaises, wUses, wTags, wGcSafe}
|
wRaises, wLocks, wTags, wGcSafe}
|
||||||
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
|
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
|
||||||
wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow,
|
wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow,
|
||||||
wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
|
wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
|
||||||
wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
|
wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
|
||||||
wBorrow, wGcSafe}
|
wBorrow, wGcSafe}
|
||||||
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
|
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
|
||||||
wImportCpp, wImportObjC, wError}
|
wImportCpp, wImportObjC, wError, wGuard}
|
||||||
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
|
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
|
||||||
wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern,
|
wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern,
|
||||||
wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal,
|
wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal,
|
||||||
wGensym, wInject, wCodegenDecl}
|
wGensym, wInject, wCodegenDecl, wGuard}
|
||||||
constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
|
constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
|
||||||
wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject}
|
wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject}
|
||||||
letPragmas* = varPragmas
|
letPragmas* = varPragmas
|
||||||
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideeffect,
|
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideeffect,
|
||||||
wThread, wRaises, wUses, wTags, wGcSafe}
|
wThread, wRaises, wLocks, wTags, wGcSafe}
|
||||||
allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas
|
allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas
|
||||||
|
|
||||||
proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords)
|
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, sfImportc)
|
||||||
incl(s.flags, sfInfixCall)
|
incl(s.flags, sfInfixCall)
|
||||||
excl(s.flags, sfForward)
|
excl(s.flags, sfForward)
|
||||||
|
let m = s.getModule()
|
||||||
|
incl(m.flags, sfCompileToCpp)
|
||||||
|
|
||||||
proc processImportObjC(s: PSym, extname: string) =
|
proc processImportObjC(s: PSym, extname: string) =
|
||||||
setExternName(s, extname)
|
setExternName(s, extname)
|
||||||
incl(s.flags, sfImportc)
|
incl(s.flags, sfImportc)
|
||||||
incl(s.flags, sfNamedParamCall)
|
incl(s.flags, sfNamedParamCall)
|
||||||
excl(s.flags, sfForward)
|
excl(s.flags, sfForward)
|
||||||
|
let m = s.getModule()
|
||||||
|
incl(m.flags, sfCompileToObjC)
|
||||||
|
|
||||||
proc newEmptyStrNode(n: PNode): PNode {.noinline.} =
|
proc newEmptyStrNode(n: PNode): PNode {.noinline.} =
|
||||||
result = newNodeIT(nkStrLit, n.info, getSysType(tyString))
|
result = newNodeIT(nkStrLit, n.info, getSysType(tyString))
|
||||||
|
|
@ -514,27 +518,6 @@ proc pragmaRaisesOrTags(c: PContext, n: PNode) =
|
||||||
else:
|
else:
|
||||||
invalidPragma(n)
|
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) =
|
proc typeBorrow(sym: PSym, n: PNode) =
|
||||||
if n.kind == nkExprColonExpr:
|
if n.kind == nkExprColonExpr:
|
||||||
let it = n.sons[1]
|
let it = n.sons[1]
|
||||||
|
|
@ -542,6 +525,45 @@ proc typeBorrow(sym: PSym, n: PNode) =
|
||||||
localError(n.info, "a type can only borrow `.` for now")
|
localError(n.info, "a type can only borrow `.` for now")
|
||||||
incl(sym.typ.flags, tfBorrowDot)
|
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,
|
proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
validPragmas: TSpecialWords): bool =
|
validPragmas: TSpecialWords): bool =
|
||||||
var it = n.sons[i]
|
var it = n.sons[i]
|
||||||
|
|
@ -578,10 +600,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
of wAlign:
|
of wAlign:
|
||||||
if sym.typ == nil: invalidPragma(it)
|
if sym.typ == nil: invalidPragma(it)
|
||||||
var align = expectIntLit(c, 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)
|
localError(it.info, errPowerOfTwoExpected)
|
||||||
else:
|
else:
|
||||||
sym.typ.align = align
|
sym.typ.align = align.int16
|
||||||
of wSize:
|
of wSize:
|
||||||
if sym.typ == nil: invalidPragma(it)
|
if sym.typ == nil: invalidPragma(it)
|
||||||
var size = expectIntLit(c, it)
|
var size = expectIntLit(c, it)
|
||||||
|
|
@ -648,17 +670,13 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
processDynLib(c, it, sym)
|
processDynLib(c, it, sym)
|
||||||
of wCompilerproc:
|
of wCompilerproc:
|
||||||
noVal(it) # compilerproc may not get a string!
|
noVal(it) # compilerproc may not get a string!
|
||||||
if sfFromGeneric notin sym.flags:
|
if sfFromGeneric notin sym.flags: markCompilerProc(sym)
|
||||||
makeExternExport(sym, "$1", it.info)
|
|
||||||
incl(sym.flags, sfCompilerProc)
|
|
||||||
incl(sym.flags, sfUsed) # suppress all those stupid warnings
|
|
||||||
registerCompilerProc(sym)
|
|
||||||
of wProcVar:
|
of wProcVar:
|
||||||
noVal(it)
|
noVal(it)
|
||||||
incl(sym.flags, sfProcvar)
|
incl(sym.flags, sfProcvar)
|
||||||
of wDeprecated:
|
of wDeprecated:
|
||||||
noVal(it)
|
if it.kind == nkExprColonExpr: deprecatedStmt(c, it)
|
||||||
if sym != nil: incl(sym.flags, sfDeprecated)
|
elif sym != nil: incl(sym.flags, sfDeprecated)
|
||||||
else: incl(c.module.flags, sfDeprecated)
|
else: incl(c.module.flags, sfDeprecated)
|
||||||
of wVarargs:
|
of wVarargs:
|
||||||
noVal(it)
|
noVal(it)
|
||||||
|
|
@ -789,10 +807,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
if sym == nil: invalidPragma(it)
|
if sym == nil: invalidPragma(it)
|
||||||
of wLine: pragmaLine(c, it)
|
of wLine: pragmaLine(c, it)
|
||||||
of wRaises, wTags: pragmaRaisesOrTags(c, it)
|
of wRaises, wTags: pragmaRaisesOrTags(c, it)
|
||||||
of wUses: pragmaUses(c, it)
|
of wGuard:
|
||||||
of wOperator:
|
if sym == nil or sym.kind notin {skVar, skLet, skField}:
|
||||||
if sym == nil: invalidPragma(it)
|
invalidPragma(it)
|
||||||
else: sym.position = expectIntLit(c, it)
|
else:
|
||||||
|
sym.guard = pragmaGuard(c, it, sym.kind)
|
||||||
of wInjectStmt:
|
of wInjectStmt:
|
||||||
if it.kind != nkExprColonExpr:
|
if it.kind != nkExprColonExpr:
|
||||||
localError(it.info, errExprExpected)
|
localError(it.info, errExprExpected)
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,6 @@ proc documentRaises*(n: PNode) =
|
||||||
if n.sons[namePos].kind != nkSym: return
|
if n.sons[namePos].kind != nkSym: return
|
||||||
documentEffect(n, n.sons[pragmasPos], wRaises, exceptionEffects)
|
documentEffect(n, n.sons[pragmasPos], wRaises, exceptionEffects)
|
||||||
documentEffect(n, n.sons[pragmasPos], wTags, tagEffects)
|
documentEffect(n, n.sons[pragmasPos], wTags, tagEffects)
|
||||||
documentEffect(n, n.sons[pragmasPos], wUses, usesEffects)
|
|
||||||
|
|
||||||
template notGcSafe(t): expr = {tfGcSafe, tfNoSideEffect} * t.flags == {}
|
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))
|
if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n))
|
||||||
tracked.gcUnsafe = true
|
tracked.gcUnsafe = true
|
||||||
|
|
||||||
when trackGlobals:
|
|
||||||
let usesSpec = effectSpec(pragma, wUses)
|
|
||||||
mergeUses(tracked, usesSpec, n)
|
|
||||||
|
|
||||||
proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) =
|
proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) =
|
||||||
let n = n.skipConv
|
let n = n.skipConv
|
||||||
if paramType != nil and tfNotNil in paramType.flags and
|
if paramType != nil and tfNotNil in paramType.flags and
|
||||||
|
|
@ -641,10 +636,6 @@ proc checkMethodEffects*(disp, branch: PSym) =
|
||||||
if not isNil(tagsSpec):
|
if not isNil(tagsSpec):
|
||||||
checkRaisesSpec(tagsSpec, actual.sons[tagEffects],
|
checkRaisesSpec(tagsSpec, actual.sons[tagEffects],
|
||||||
"can have an unlisted effect: ", hints=off, subtypeRelation)
|
"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):
|
if sfThread in disp.flags and notGcSafe(branch.typ):
|
||||||
localError(branch.info, "base method is GC-safe, but '$1' is not" %
|
localError(branch.info, "base method is GC-safe, but '$1' is not" %
|
||||||
branch.name.s)
|
branch.name.s)
|
||||||
|
|
@ -656,16 +647,13 @@ proc setEffectsForProcType*(t: PType, n: PNode) =
|
||||||
let
|
let
|
||||||
raisesSpec = effectSpec(n, wRaises)
|
raisesSpec = effectSpec(n, wRaises)
|
||||||
tagsSpec = effectSpec(n, wTags)
|
tagsSpec = effectSpec(n, wTags)
|
||||||
usesSpec = effectSpec(n, wUses)
|
if not isNil(raisesSpec) or not isNil(tagsSpec):
|
||||||
if not isNil(raisesSpec) or not isNil(tagsSpec) or not isNil(usesSpec):
|
|
||||||
internalAssert effects.len == 0
|
internalAssert effects.len == 0
|
||||||
newSeq(effects.sons, effectListLen)
|
newSeq(effects.sons, effectListLen)
|
||||||
if not isNil(raisesSpec):
|
if not isNil(raisesSpec):
|
||||||
effects.sons[exceptionEffects] = raisesSpec
|
effects.sons[exceptionEffects] = raisesSpec
|
||||||
if not isNil(tagsSpec):
|
if not isNil(tagsSpec):
|
||||||
effects.sons[tagEffects] = tagsSpec
|
effects.sons[tagEffects] = tagsSpec
|
||||||
if not isNil(usesSpec):
|
|
||||||
effects.sons[usesEffects] = usesSpec
|
|
||||||
|
|
||||||
proc initEffects(effects: PNode; s: PSym; t: var TEffects) =
|
proc initEffects(effects: PNode; s: PSym; t: var TEffects) =
|
||||||
newSeq(effects.sons, effectListLen)
|
newSeq(effects.sons, effectListLen)
|
||||||
|
|
@ -710,12 +698,6 @@ proc trackProc*(s: PSym, body: PNode) =
|
||||||
# after the check, use the formal spec:
|
# after the check, use the formal spec:
|
||||||
effects.sons[tagEffects] = tagsSpec
|
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 optThreadAnalysis in gGlobalOptions:
|
||||||
if sfThread in s.flags and t.gcUnsafe:
|
if sfThread in s.flags and t.gcUnsafe:
|
||||||
#localError(s.info, warnGcUnsafe2, s.name.s)
|
#localError(s.info, warnGcUnsafe2, s.name.s)
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ type
|
||||||
wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, wInjectStmt,
|
wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, wInjectStmt,
|
||||||
wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
|
wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
|
||||||
wAsmNoStackFrame,
|
wAsmNoStackFrame,
|
||||||
wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wUses,
|
wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks,
|
||||||
|
|
||||||
wAuto, wBool, wCatch, wChar, wClass,
|
wAuto, wBool, wCatch, wChar, wClass,
|
||||||
wConst_cast, wDefault, wDelete, wDouble, wDynamic_cast,
|
wConst_cast, wDefault, wDelete, wDouble, wDynamic_cast,
|
||||||
|
|
@ -147,7 +147,7 @@ const
|
||||||
"computedgoto", "injectstmt",
|
"computedgoto", "injectstmt",
|
||||||
"write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
|
"write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
|
||||||
"asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked",
|
"asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked",
|
||||||
"guard", "uses",
|
"guard", "locks",
|
||||||
|
|
||||||
"auto", "bool", "catch", "char", "class",
|
"auto", "bool", "catch", "char", "class",
|
||||||
"const_cast", "default", "delete", "double",
|
"const_cast", "default", "delete", "double",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue