mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-12 10:05:24 +00:00
experiment: big refactoring
This commit is contained in:
379
compiler/ast.nim
379
compiler/ast.nim
@@ -695,32 +695,33 @@ type
|
||||
ItemState* = enum
|
||||
Complete # completely in memory
|
||||
Partial # partially in memory
|
||||
Sealed # complete in memory, already written to NIF file, so further mutations are not allowed
|
||||
|
||||
PLib* = ref TLib
|
||||
TSym* {.acyclic.} = object # Keep in sync with PackedSym
|
||||
TSym* {.acyclic.} = object # Keep in sync with ast2nif.nim
|
||||
itemId*: ItemId
|
||||
# proc and type instantiations are cached in the generic symbol
|
||||
state*: ItemState
|
||||
case kind*: TSymKind
|
||||
case kindImpl*: TSymKind # Note: kept as 'kind' for case statement, but accessor checks state
|
||||
of routineKinds:
|
||||
#procInstCache*: seq[PInstantiation]
|
||||
gcUnsafetyReason*: PSym # for better error messages regarding gcsafe
|
||||
transformedBody*: PNode # cached body after transf pass
|
||||
gcUnsafetyReasonImpl*: PSym # for better error messages regarding gcsafe
|
||||
transformedBodyImpl*: PNode # cached body after transf pass
|
||||
of skLet, skVar, skField, skForVar:
|
||||
guard*: PSym
|
||||
bitsize*: int
|
||||
alignment*: int # for alignment
|
||||
guardImpl*: PSym
|
||||
bitsizeImpl*: int
|
||||
alignmentImpl*: int # for alignment
|
||||
else: nil
|
||||
magic*: TMagic
|
||||
typ*: PType
|
||||
magicImpl*: TMagic
|
||||
typImpl*: PType
|
||||
name*: PIdent
|
||||
info*: TLineInfo
|
||||
infoImpl*: TLineInfo
|
||||
when defined(nimsuggest):
|
||||
endInfo*: TLineInfo
|
||||
hasUserSpecifiedType*: bool # used for determining whether to display inlay type hints
|
||||
ownerField: PSym
|
||||
flags*: TSymFlags
|
||||
ast*: PNode # syntax tree of proc, iterator, etc.:
|
||||
endInfoImpl*: TLineInfo
|
||||
hasUserSpecifiedTypeImpl*: bool # used for determining whether to display inlay type hints
|
||||
ownerFieldImpl: PSym
|
||||
flagsImpl*: TSymFlags
|
||||
astImpl*: PNode # syntax tree of proc, iterator, etc.:
|
||||
# the whole proc including header; this is used
|
||||
# for easy generation of proper error messages
|
||||
# for variant record fields the discriminant
|
||||
@@ -728,8 +729,8 @@ type
|
||||
# for modules, it's a placeholder for compiler
|
||||
# generated code that will be appended to the
|
||||
# module after the sem pass (see appendToModule)
|
||||
options*: TOptions
|
||||
position*: int # used for many different things:
|
||||
optionsImpl*: TOptions
|
||||
positionImpl*: int # used for many different things:
|
||||
# for enum fields its position;
|
||||
# for fields its offset
|
||||
# for parameters its position (starting with 0)
|
||||
@@ -739,23 +740,23 @@ type
|
||||
# for modules, an unique index corresponding
|
||||
# to the module's fileIdx
|
||||
# for variables a slot index for the evaluator
|
||||
offset*: int32 # offset of record field
|
||||
offsetImpl*: int32 # offset of record field
|
||||
disamb*: int32 # disambiguation number; the basic idea is that
|
||||
# `<procname>__<module>_<disamb>` is unique
|
||||
loc*: TLoc
|
||||
annex*: PLib # additional fields (seldom used, so we use a
|
||||
locImpl*: TLoc
|
||||
annexImpl*: PLib # additional fields (seldom used, so we use a
|
||||
# reference to another object to save space)
|
||||
when hasFFI:
|
||||
cname*: string # resolved C declaration name in importc decl, e.g.:
|
||||
cnameImpl*: string # resolved C declaration name in importc decl, e.g.:
|
||||
# proc fun() {.importc: "$1aux".} => cname = funaux
|
||||
constraint*: PNode # additional constraints like 'lit|result'; also
|
||||
constraintImpl*: PNode # additional constraints like 'lit|result'; also
|
||||
# misused for the codegenDecl and virtual pragmas in the hope
|
||||
# it won't cause problems
|
||||
# for skModule the string literal to output for
|
||||
# deprecated modules.
|
||||
instantiatedFrom*: PSym # for instances, the generic symbol where it came from.
|
||||
instantiatedFromImpl*: PSym # for instances, the generic symbol where it came from.
|
||||
when defined(nimsuggest):
|
||||
allUsages*: seq[TLineInfo]
|
||||
allUsagesImpl*: seq[TLineInfo]
|
||||
|
||||
TTypeSeq* = seq[PType]
|
||||
|
||||
@@ -840,11 +841,226 @@ template nodeId(n: PNode): int = cast[int](n)
|
||||
template typ*(n: PNode): PType =
|
||||
n.typField
|
||||
|
||||
proc loadSym*(s: PSym) {.inline.} =
|
||||
## Loads a symbol from NIF file if it's in Partial state.
|
||||
## This is a forward declaration - implementation should be provided elsewhere.
|
||||
discard
|
||||
|
||||
proc owner*(s: PSym|PType): PSym {.inline.} =
|
||||
result = s.ownerField
|
||||
when s is PSym:
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.ownerFieldImpl
|
||||
else:
|
||||
result = s.ownerField
|
||||
|
||||
proc setOwner*(s: PSym|PType, owner: PSym) {.inline.} =
|
||||
s.ownerField = owner
|
||||
when s is PSym:
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.ownerFieldImpl = owner
|
||||
else:
|
||||
s.ownerField = owner
|
||||
|
||||
# Accessor procs for TSym fields
|
||||
# Note: kind is kept as a direct field for case statement compatibility
|
||||
# but we still provide an accessor that checks state
|
||||
proc kind*(s: PSym): TSymKind {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.kind
|
||||
|
||||
proc `kind=`*(s: PSym, val: TSymKind) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.kind = val
|
||||
|
||||
proc gcUnsafetyReason*(s: PSym): PSym {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.gcUnsafetyReasonImpl
|
||||
|
||||
proc `gcUnsafetyReason=`*(s: PSym, val: PSym) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.gcUnsafetyReasonImpl = val
|
||||
|
||||
proc transformedBody*(s: PSym): PNode {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.transformedBodyImpl
|
||||
|
||||
proc `transformedBody=`*(s: PSym, val: PNode) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.transformedBodyImpl = val
|
||||
|
||||
proc guard*(s: PSym): PSym {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.guardImpl
|
||||
|
||||
proc `guard=`*(s: PSym, val: PSym) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.guardImpl = val
|
||||
|
||||
proc bitsize*(s: PSym): int {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.bitsizeImpl
|
||||
|
||||
proc `bitsize=`*(s: PSym, val: int) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.bitsizeImpl = val
|
||||
|
||||
proc alignment*(s: PSym): int {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.alignmentImpl
|
||||
|
||||
proc `alignment=`*(s: PSym, val: int) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.alignmentImpl = val
|
||||
|
||||
proc magic*(s: PSym): TMagic {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.magicImpl
|
||||
|
||||
proc `magic=`*(s: PSym, val: TMagic) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.magicImpl = val
|
||||
|
||||
proc typ*(s: PSym): PType {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.typImpl
|
||||
|
||||
proc `typ=`*(s: PSym, val: PType) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.typImpl = val
|
||||
|
||||
proc info*(s: PSym): TLineInfo {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.infoImpl
|
||||
|
||||
proc `info=`*(s: PSym, val: TLineInfo) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.infoImpl = val
|
||||
|
||||
when defined(nimsuggest):
|
||||
proc endInfo*(s: PSym): TLineInfo {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.endInfoImpl
|
||||
|
||||
proc `endInfo=`*(s: PSym, val: TLineInfo) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.endInfoImpl = val
|
||||
|
||||
proc hasUserSpecifiedType*(s: PSym): bool {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.hasUserSpecifiedTypeImpl
|
||||
|
||||
proc `hasUserSpecifiedType=`*(s: PSym, val: bool) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.hasUserSpecifiedTypeImpl = val
|
||||
|
||||
proc flags*(s: PSym): TSymFlags {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.flagsImpl
|
||||
|
||||
proc `flags=`*(s: PSym, val: TSymFlags) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.flagsImpl = val
|
||||
|
||||
proc ast*(s: PSym): PNode {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.astImpl
|
||||
|
||||
proc `ast=`*(s: PSym, val: PNode) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.astImpl = val
|
||||
|
||||
proc options*(s: PSym): TOptions {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.optionsImpl
|
||||
|
||||
proc `options=`*(s: PSym, val: TOptions) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.optionsImpl = val
|
||||
|
||||
proc position*(s: PSym): int {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.positionImpl
|
||||
|
||||
proc `position=`*(s: PSym, val: int) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.positionImpl = val
|
||||
|
||||
proc offset*(s: PSym): int32 {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.offsetImpl
|
||||
|
||||
proc `offset=`*(s: PSym, val: int32) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.offsetImpl = val
|
||||
|
||||
proc loc*(s: PSym): TLoc {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.locImpl
|
||||
|
||||
proc `loc=`*(s: PSym, val: TLoc) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.locImpl = val
|
||||
|
||||
proc annex*(s: PSym): PLib {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.annexImpl
|
||||
|
||||
proc `annex=`*(s: PSym, val: PLib) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.annexImpl = val
|
||||
|
||||
when hasFFI:
|
||||
proc cname*(s: PSym): string {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.cnameImpl
|
||||
|
||||
proc `cname=`*(s: PSym, val: string) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.cnameImpl = val
|
||||
|
||||
proc constraint*(s: PSym): PNode {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.constraintImpl
|
||||
|
||||
proc `constraint=`*(s: PSym, val: PNode) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.constraintImpl = val
|
||||
|
||||
proc instantiatedFrom*(s: PSym): PSym {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.instantiatedFromImpl
|
||||
|
||||
proc `instantiatedFrom=`*(s: PSym, val: PSym) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.instantiatedFromImpl = val
|
||||
|
||||
proc setSnippet*(s: PSym; val: sink string) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.locImpl.snippet = val
|
||||
|
||||
proc incl*(s: PSym; flag: TSymFlag) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.flagsImpl.incl(flag)
|
||||
|
||||
proc incl*(s: PSym; flags: set[TSymFlag]) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.flagsImpl.incl(flag)
|
||||
|
||||
proc incl*(s: PSym; flag: TLocFlag) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.locImpl.flags.incl(flag)
|
||||
|
||||
proc excl*(s: PSym; flag: TSymFlag) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.flagsImpl.excl(flag)
|
||||
|
||||
when defined(nimsuggest):
|
||||
proc allUsages*(s: PSym): seq[TLineInfo] {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
result = s.allUsagesImpl
|
||||
|
||||
proc `allUsages=`*(s: PSym, val: seq[TLineInfo]) {.inline.} =
|
||||
if s.state == Partial: loadSym(s)
|
||||
s.allUsagesImpl = val
|
||||
|
||||
type Gconfig = object
|
||||
# we put comments in a side channel to avoid increasing `sizeof(TNode)`, which
|
||||
@@ -1091,15 +1307,17 @@ proc getDeclPragma*(n: PNode): PNode =
|
||||
proc extractPragma*(s: PSym): PNode =
|
||||
## gets the pragma node of routine/type/var/let/const symbol `s`
|
||||
if s.kind in routineKinds: # bug #24167
|
||||
if s.ast[pragmasPos] != nil and s.ast[pragmasPos].kind != nkEmpty:
|
||||
result = s.ast[pragmasPos]
|
||||
let astVal = s.ast
|
||||
if astVal != nil and astVal[pragmasPos] != nil and astVal[pragmasPos].kind != nkEmpty:
|
||||
result = astVal[pragmasPos]
|
||||
else:
|
||||
result = nil
|
||||
elif s.kind in {skType, skVar, skLet, skConst}:
|
||||
if s.ast != nil and s.ast.len > 0:
|
||||
if s.ast[0].kind == nkPragmaExpr and s.ast[0].len > 1:
|
||||
let astVal = s.ast
|
||||
if astVal != nil and astVal.len > 0:
|
||||
if astVal[0].kind == nkPragmaExpr and astVal[0].len > 1:
|
||||
# s.ast = nkTypedef / nkPragmaExpr / [nkSym, nkPragma]
|
||||
result = s.ast[0][1]
|
||||
result = astVal[0][1]
|
||||
else:
|
||||
result = nil
|
||||
else:
|
||||
@@ -1126,7 +1344,7 @@ when defined(useNodeIds):
|
||||
const nodeIdToDebug* = -1 # 2322968
|
||||
var gNodeId: int
|
||||
|
||||
template newNodeImpl(info2) =
|
||||
template newNodeImpl(info2) {.dirty.} =
|
||||
result = PNode(kind: kind, info: info2)
|
||||
when false:
|
||||
# this would add overhead, so we skip it; it results in a small amount of leaked entries
|
||||
@@ -1229,8 +1447,8 @@ proc newSym*(symKind: TSymKind, name: PIdent, idgen: IdGenerator; owner: PSym,
|
||||
# generates a symbol and initializes the hash field too
|
||||
assert not name.isNil
|
||||
let id = nextSymId idgen
|
||||
result = PSym(name: name, kind: symKind, flags: {}, info: info, itemId: id,
|
||||
options: options, ownerField: owner, offset: defaultOffset,
|
||||
result = PSym(name: name, kindImpl: symKind, flagsImpl: {}, infoImpl: info, itemId: id,
|
||||
optionsImpl: options, ownerFieldImpl: owner, offsetImpl: defaultOffset,
|
||||
disamb: getOrDefault(idgen.disambTable, name).int32)
|
||||
idgen.disambTable.inc name
|
||||
when false:
|
||||
@@ -1241,10 +1459,11 @@ proc newSym*(symKind: TSymKind, name: PIdent, idgen: IdGenerator; owner: PSym,
|
||||
|
||||
proc astdef*(s: PSym): PNode =
|
||||
# get only the definition (initializer) portion of the ast
|
||||
if s.ast != nil and s.ast.kind in {nkIdentDefs, nkConstDef}:
|
||||
s.ast[2]
|
||||
let astVal = s.ast
|
||||
if astVal != nil and astVal.kind in {nkIdentDefs, nkConstDef}:
|
||||
astVal[2]
|
||||
else:
|
||||
s.ast
|
||||
astVal
|
||||
|
||||
proc isMetaType*(t: PType): bool =
|
||||
return t.kind in tyMetaTypes or
|
||||
@@ -1256,31 +1475,33 @@ proc isUnresolvedStatic*(t: PType): bool =
|
||||
|
||||
proc linkTo*(t: PType, s: PSym): PType {.discardable.} =
|
||||
t.sym = s
|
||||
s.typ = t
|
||||
s.typImpl = t
|
||||
result = t
|
||||
|
||||
proc linkTo*(s: PSym, t: PType): PSym {.discardable.} =
|
||||
t.sym = s
|
||||
s.typ = t
|
||||
s.typImpl = t
|
||||
result = s
|
||||
|
||||
template fileIdx*(c: PSym): FileIndex =
|
||||
# XXX: this should be used only on module symbols
|
||||
c.position.FileIndex
|
||||
c.position().FileIndex
|
||||
|
||||
template filename*(c: PSym): string =
|
||||
# XXX: this should be used only on module symbols
|
||||
c.position.FileIndex.toFilename
|
||||
c.position().FileIndex.toFilename
|
||||
|
||||
proc appendToModule*(m: PSym, n: PNode) =
|
||||
## The compiler will use this internally to add nodes that will be
|
||||
## appended to the module after the sem pass
|
||||
if m.ast == nil:
|
||||
m.ast = newNode(nkStmtList)
|
||||
m.ast.sons = @[n]
|
||||
var astVal = m.ast
|
||||
if astVal == nil:
|
||||
astVal = newNode(nkStmtList)
|
||||
astVal.sons = @[n]
|
||||
m.astImpl = astVal
|
||||
else:
|
||||
assert m.ast.kind == nkStmtList
|
||||
m.ast.sons.add(n)
|
||||
assert astVal.kind == nkStmtList
|
||||
astVal.sons.add(n)
|
||||
|
||||
const # for all kind of hash tables:
|
||||
GrowthFactor* = 2 # must be power of 2, > 0
|
||||
@@ -1582,9 +1803,11 @@ proc assignType*(dest, src: PType) =
|
||||
# this fixes 'type TLock = TSysLock':
|
||||
if src.sym != nil:
|
||||
if dest.sym != nil:
|
||||
dest.sym.flags.incl src.sym.flags-{sfUsed, sfExported}
|
||||
if dest.sym.annex == nil: dest.sym.annex = src.sym.annex
|
||||
mergeLoc(dest.sym.loc, src.sym.loc)
|
||||
var destFlags = dest.sym.flags
|
||||
var srcFlags = src.sym.flags
|
||||
dest.sym.flagsImpl = destFlags + (srcFlags - {sfUsed, sfExported})
|
||||
if dest.sym.annex == nil: dest.sym.annexImpl = src.sym.annex
|
||||
mergeLoc(dest.sym.locImpl, src.sym.loc)
|
||||
else:
|
||||
dest.sym = src.sym
|
||||
newSons(dest, src.sons.len)
|
||||
@@ -1604,31 +1827,31 @@ proc exactReplica*(t: PType): PType =
|
||||
|
||||
proc copySym*(s: PSym; idgen: IdGenerator): PSym =
|
||||
result = newSym(s.kind, s.name, idgen, s.owner, s.info, s.options)
|
||||
#result.ast = nil # BUGFIX; was: s.ast which made problems
|
||||
result.typ = s.typ
|
||||
result.flags = s.flags
|
||||
result.magic = s.magic
|
||||
result.options = s.options
|
||||
result.position = s.position
|
||||
result.loc = s.loc
|
||||
result.annex = s.annex # BUGFIX
|
||||
result.constraint = s.constraint
|
||||
#result.astImpl = nil # BUGFIX; was: s.ast which made problems
|
||||
result.typImpl = s.typ
|
||||
result.flagsImpl = s.flags
|
||||
result.magicImpl = s.magic
|
||||
result.optionsImpl = s.options
|
||||
result.positionImpl = s.position
|
||||
result.locImpl = s.loc
|
||||
result.annexImpl = s.annex # BUGFIX
|
||||
result.constraintImpl = s.constraint
|
||||
if result.kind in {skVar, skLet, skField}:
|
||||
result.guard = s.guard
|
||||
result.bitsize = s.bitsize
|
||||
result.alignment = s.alignment
|
||||
result.guardImpl = s.guard
|
||||
result.bitsizeImpl = s.bitsize
|
||||
result.alignmentImpl = s.alignment
|
||||
|
||||
proc createModuleAlias*(s: PSym, idgen: IdGenerator, newIdent: PIdent, info: TLineInfo;
|
||||
options: TOptions): PSym =
|
||||
result = newSym(s.kind, newIdent, idgen, s.owner, info, options)
|
||||
# keep ID!
|
||||
result.ast = s.ast
|
||||
result.astImpl = s.ast
|
||||
#result.id = s.id # XXX figure out what to do with the ID.
|
||||
result.flags = s.flags
|
||||
result.options = s.options
|
||||
result.position = s.position
|
||||
result.loc = s.loc
|
||||
result.annex = s.annex
|
||||
result.flagsImpl = s.flags
|
||||
result.optionsImpl = s.options
|
||||
result.positionImpl = s.position
|
||||
result.locImpl = s.loc
|
||||
result.annexImpl = s.annex
|
||||
|
||||
proc initStrTable*(): TStrTable =
|
||||
result = TStrTable(counter: 0)
|
||||
@@ -1754,28 +1977,28 @@ proc transitionNoneToSym*(n: PNode) =
|
||||
|
||||
template transitionSymKindCommon*(k: TSymKind) =
|
||||
let obj {.inject.} = s[]
|
||||
s[] = TSym(kind: k, itemId: obj.itemId, magic: obj.magic, typ: obj.typ, name: obj.name,
|
||||
info: obj.info, ownerField: obj.ownerField, flags: obj.flags, ast: obj.ast,
|
||||
options: obj.options, position: obj.position, offset: obj.offset,
|
||||
loc: obj.loc, annex: obj.annex, constraint: obj.constraint)
|
||||
s[] = TSym(kindImpl: k, itemId: obj.itemId, magicImpl: obj.magicImpl, typImpl: obj.typImpl, name: obj.name,
|
||||
infoImpl: obj.infoImpl, ownerFieldImpl: obj.ownerFieldImpl, flagsImpl: obj.flagsImpl, astImpl: obj.astImpl,
|
||||
optionsImpl: obj.optionsImpl, positionImpl: obj.positionImpl, offsetImpl: obj.offsetImpl,
|
||||
locImpl: obj.locImpl, annexImpl: obj.annexImpl, constraintImpl: obj.constraintImpl)
|
||||
when hasFFI:
|
||||
s.cname = obj.cname
|
||||
s.cnameImpl = obj.cnameImpl
|
||||
when defined(nimsuggest):
|
||||
s.allUsages = obj.allUsages
|
||||
s.allUsagesImpl = obj.allUsagesImpl
|
||||
|
||||
proc transitionGenericParamToType*(s: PSym) =
|
||||
transitionSymKindCommon(skType)
|
||||
|
||||
proc transitionRoutineSymKind*(s: PSym, kind: range[skProc..skTemplate]) =
|
||||
transitionSymKindCommon(kind)
|
||||
s.gcUnsafetyReason = obj.gcUnsafetyReason
|
||||
s.transformedBody = obj.transformedBody
|
||||
s.gcUnsafetyReasonImpl = obj.gcUnsafetyReasonImpl
|
||||
s.transformedBodyImpl = obj.transformedBodyImpl
|
||||
|
||||
proc transitionToLet*(s: PSym) =
|
||||
transitionSymKindCommon(skLet)
|
||||
s.guard = obj.guard
|
||||
s.bitsize = obj.bitsize
|
||||
s.alignment = obj.alignment
|
||||
s.guardImpl = obj.guardImpl
|
||||
s.bitsizeImpl = obj.bitsizeImpl
|
||||
s.alignmentImpl = obj.alignmentImpl
|
||||
|
||||
template copyNodeImpl(dst, src, processSonsStmt) =
|
||||
if src == nil: return
|
||||
|
||||
@@ -118,8 +118,6 @@ type
|
||||
deps: TokenBuf # include&import deps
|
||||
infos: LineInfoWriter
|
||||
currentModule: int32
|
||||
writtenSyms: HashSet[ItemId]
|
||||
writtenTypes: HashSet[ItemId]
|
||||
decodedFileIndices: HashSet[FileIndex]
|
||||
moduleToNifSuffix: Table[FileIndex, string]
|
||||
locals: HashSet[ItemId] # track proc-local symbols
|
||||
@@ -233,7 +231,8 @@ proc writeTypeDef(w: var Writer; dest: var TokenBuf; typ: PType) =
|
||||
proc writeType(w: var Writer; dest: var TokenBuf; typ: PType) =
|
||||
if typ == nil:
|
||||
dest.addDotToken()
|
||||
elif typ.itemId.module == w.currentModule and not w.writtenTypes.containsOrIncl(typ.uniqueId):
|
||||
elif typ.itemId.module == w.currentModule and typ.state == Complete:
|
||||
typ.state = Sealed
|
||||
writeTypeDef(w, dest, typ)
|
||||
else:
|
||||
dest.buildTree tuseTag:
|
||||
@@ -288,7 +287,8 @@ proc writeSymDef(w: var Writer; dest: var TokenBuf; sym: PSym) =
|
||||
proc writeSym(w: var Writer; dest: var TokenBuf; sym: PSym) =
|
||||
if sym == nil:
|
||||
dest.addDotToken()
|
||||
elif sym.itemId.module == w.currentModule and not w.writtenSyms.containsOrIncl(sym.itemId):
|
||||
elif sym.itemId.module == w.currentModule and sym.state == Complete:
|
||||
sym.state = Sealed
|
||||
writeSymDef(w, dest, sym)
|
||||
else:
|
||||
# NIF has direct support for symbol references so we don't need to use a tag here,
|
||||
@@ -298,7 +298,8 @@ proc writeSym(w: var Writer; dest: var TokenBuf; sym: PSym) =
|
||||
proc writeSymNode(w: var Writer; dest: var TokenBuf; n: PNode; sym: PSym) =
|
||||
if sym == nil:
|
||||
dest.addDotToken()
|
||||
elif sym.itemId.module == w.currentModule and not w.writtenSyms.containsOrIncl(sym.itemId):
|
||||
elif sym.itemId.module == w.currentModule and sym.state == Complete:
|
||||
sym.state = Sealed
|
||||
if n.typ != n.sym.typ:
|
||||
dest.buildTree hiddenTypeTag, trLineInfo(w, n.info):
|
||||
writeSymDef(w, dest, sym)
|
||||
@@ -629,7 +630,7 @@ proc loadSymStub(c: var DecodeContext; t: SymId): PSym =
|
||||
result = c.syms.getOrDefault(id)[0]
|
||||
if result == nil:
|
||||
let offs = c.getOffset(module, symAsStr)
|
||||
result = PSym(itemId: id, kind: skStub, name: c.cache.getIdent(sn.name), disamb: sn.count.int32, state: Partial)
|
||||
result = PSym(itemId: id, kindImpl: skStub, name: c.cache.getIdent(sn.name), disamb: sn.count.int32, state: Partial)
|
||||
c.syms[id] = (result, offs)
|
||||
|
||||
proc loadSymStub(c: var DecodeContext; n: var Cursor): PSym =
|
||||
@@ -689,6 +690,7 @@ proc loadLoc(c: var DecodeContext; n: var Cursor; loc: var TLoc) =
|
||||
|
||||
proc loadType*(c: var DecodeContext; t: PType) =
|
||||
if t.state != Partial: return
|
||||
t.state = Sealed
|
||||
var buf = createTokenBuf(30)
|
||||
var n = cursorFromIndexEntry(c, t.itemId.module, c.types[t.itemId][1], buf)
|
||||
|
||||
@@ -739,7 +741,8 @@ proc loadAnnex(c: var DecodeContext; n: var Cursor): PLib =
|
||||
raiseAssert "`lib/annex` information expected"
|
||||
|
||||
proc loadSym*(c: var DecodeContext; s: PSym) =
|
||||
if s.kind != skStub: return
|
||||
if s.state != Partial: return
|
||||
s.state = Sealed
|
||||
var buf = createTokenBuf(30)
|
||||
var n = cursorFromIndexEntry(c, s.itemId.module, c.syms[s.itemId][1], buf)
|
||||
|
||||
@@ -777,7 +780,7 @@ proc loadSym*(c: var DecodeContext; s: PSym) =
|
||||
s.setOwner loadSymStub(c, n)
|
||||
# We do not store `sym.ast` here but instead set it in the deserializer
|
||||
#writeNode(w, sym.ast)
|
||||
loadLoc c, n, s.loc
|
||||
loadLoc c, n, s.locImpl
|
||||
s.constraint = loadNode(c, n)
|
||||
s.instantiatedFrom = loadSymStub(c, n)
|
||||
skipParRi n
|
||||
|
||||
@@ -899,11 +899,11 @@ proc moduleIndex*(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: in
|
||||
proc symHeaderFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
|
||||
s: PackedSym; si, item: int32): PSym =
|
||||
result = PSym(itemId: ItemId(module: si, item: item),
|
||||
kind: s.kind, magic: s.magic, flags: s.flags,
|
||||
info: translateLineInfo(c, g, si, s.info),
|
||||
options: s.options,
|
||||
position: if s.kind in {skForVar, skVar, skLet, skTemp}: 0 else: s.position,
|
||||
offset: if s.kind in routineKinds: defaultOffset else: s.offset,
|
||||
kindImpl: s.kind, magicImpl: s.magic, flagsImpl: s.flags,
|
||||
infoImpl: translateLineInfo(c, g, si, s.info),
|
||||
optionsImpl: s.options,
|
||||
positionImpl: if s.kind in {skForVar, skVar, skLet, skTemp}: 0 else: s.position,
|
||||
offsetImpl: if s.kind in routineKinds: defaultOffset else: s.offset,
|
||||
disamb: s.disamb,
|
||||
name: getIdent(c.cache, g[si].fromDisk.strings[s.name])
|
||||
)
|
||||
@@ -945,8 +945,8 @@ proc symBodyFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
|
||||
setOwner(result, loadSym(c, g, si, s.owner))
|
||||
let externalName = g[si].fromDisk.strings[s.externalName]
|
||||
if externalName != "":
|
||||
result.loc.snippet = externalName
|
||||
result.loc.flags = s.locFlags
|
||||
result.locImpl.snippet = externalName
|
||||
result.locImpl.flags = s.locFlags
|
||||
result.instantiatedFrom = loadSym(c, g, si, s.instantiatedFrom)
|
||||
|
||||
proc needsRecompile(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
|
||||
@@ -1058,12 +1058,12 @@ proc setupLookupTables(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCa
|
||||
let filename = AbsoluteFile toFullPath(conf, fileIdx)
|
||||
# We cannot call ``newSym`` here, because we have to circumvent the ID
|
||||
# mechanism, which we do in order to assign each module a persistent ID.
|
||||
m.module = PSym(kind: skModule, itemId: ItemId(module: int32(fileIdx), item: 0'i32),
|
||||
m.module = PSym(kindImpl: skModule, itemId: ItemId(module: int32(fileIdx), item: 0'i32),
|
||||
name: getIdent(cache, splitFile(filename).name),
|
||||
info: newLineInfo(fileIdx, 1, 1),
|
||||
position: int(fileIdx))
|
||||
infoImpl: newLineInfo(fileIdx, 1, 1),
|
||||
positionImpl: int(fileIdx))
|
||||
setOwner(m.module, getPackage(conf, cache, fileIdx))
|
||||
m.module.flags = m.fromDisk.moduleFlags
|
||||
m.module.flagsImpl = m.fromDisk.moduleFlags
|
||||
|
||||
proc loadToReplayNodes(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
|
||||
fileIdx: FileIndex; m: var LoadedModule) =
|
||||
|
||||
@@ -311,7 +311,7 @@ proc errorSym*(c: PContext, ident: PIdent, info: TLineInfo): PSym =
|
||||
## creates an error symbol to avoid cascading errors (for IDE support)
|
||||
result = newSym(skError, ident, c.idgen, getCurrOwner(c), info, {})
|
||||
result.typ = errorType(c)
|
||||
incl(result.flags, sfDiscardable)
|
||||
incl(result.flagsImpl, sfDiscardable)
|
||||
# pretend it's from the top level scope to prevent cascading errors:
|
||||
if c.config.cmd != cmdInteractive and c.compilesContextId == 0:
|
||||
c.moduleScope.addSym(result)
|
||||
|
||||
@@ -82,7 +82,7 @@ proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: P
|
||||
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), idgen,
|
||||
owner, value.info, g.config.options)
|
||||
temp.typ = skipTypes(value.typ, abstractInst)
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
incl(temp.flagsImpl, sfFromGeneric)
|
||||
tempAsNode = newSymNode(temp)
|
||||
|
||||
var v = newNodeI(nkVarSection, value.info)
|
||||
@@ -103,7 +103,7 @@ proc evalOnce*(g: ModuleGraph; value: PNode; idgen: IdGenerator; owner: PSym): P
|
||||
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), idgen,
|
||||
owner, value.info, g.config.options)
|
||||
temp.typ = skipTypes(value.typ, abstractInst)
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
incl(temp.flagsImpl, sfFromGeneric)
|
||||
|
||||
var v = newNodeI(nkLetSection, value.info)
|
||||
let tempAsNode = newSymNode(temp)
|
||||
@@ -127,8 +127,8 @@ proc lowerSwap*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNod
|
||||
# note: cannot use 'skTemp' here cause we really need the copy for the VM :-(
|
||||
var temp = newSym(skVar, getIdent(g.cache, genPrefix), idgen, owner, n.info, owner.options)
|
||||
temp.typ = n[1].typ
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
incl(temp.flags, sfGenSym)
|
||||
incl(temp.flagsImpl, sfFromGeneric)
|
||||
incl(temp.flagsImpl, sfGenSym)
|
||||
|
||||
var v = newNodeI(nkVarSection, n.info)
|
||||
let tempAsNode = newSymNode(temp)
|
||||
@@ -153,7 +153,7 @@ proc createObj*(g: ModuleGraph; idgen: IdGenerator; owner: PSym, info: TLineInfo
|
||||
result.n = newNodeI(nkRecList, info)
|
||||
let s = newSym(skType, getIdent(g.cache, "Env_" & toFilename(g.config, info) & "_" & $owner.name.s),
|
||||
idgen, owner, info, owner.options)
|
||||
incl s.flags, sfAnon
|
||||
incl s.flagsImpl, sfAnon
|
||||
s.typ = result
|
||||
result.sym = s
|
||||
|
||||
|
||||
@@ -681,13 +681,13 @@ proc markDirty*(g: ModuleGraph; fileIdx: FileIndex) =
|
||||
if m != nil:
|
||||
g.suggestSymbols.del(fileIdx)
|
||||
g.suggestErrors.del(fileIdx)
|
||||
incl m.flags, sfDirty
|
||||
incl m.flagsImpl, sfDirty
|
||||
|
||||
proc unmarkAllDirty*(g: ModuleGraph) =
|
||||
for i in 0i32..<g.ifaces.len.int32:
|
||||
let m = g.ifaces[i].module
|
||||
if m != nil:
|
||||
m.flags.excl sfDirty
|
||||
m.flagsImpl.excl sfDirty
|
||||
|
||||
proc isDirty*(g: ModuleGraph; m: PSym): bool =
|
||||
result = g.suggestMode and sfDirty in m.flags
|
||||
|
||||
@@ -148,7 +148,7 @@ proc pragmaEnsures(c: PContext, n: PNode) =
|
||||
if o.kind in routineKinds and o.typ != nil and o.typ.returnType != nil:
|
||||
var s = newSym(skResult, getIdent(c.cache, "result"), c.idgen, o, n.info)
|
||||
s.typ = o.typ.returnType
|
||||
incl(s.flags, sfUsed)
|
||||
incl(s.flagsImpl, sfUsed)
|
||||
addDecl(c, s)
|
||||
n[1] = c.semExpr(c, n[1])
|
||||
closeScope(c)
|
||||
@@ -156,12 +156,12 @@ proc pragmaEnsures(c: PContext, n: PNode) =
|
||||
proc setExternName(c: PContext; s: PSym, extname: string, info: TLineInfo) =
|
||||
# special cases to improve performance:
|
||||
if extname == "$1":
|
||||
s.loc.snippet = rope(s.name.s)
|
||||
s.setSnippet(rope(s.name.s))
|
||||
elif '$' notin extname:
|
||||
s.loc.snippet = rope(extname)
|
||||
s.setSnippet(rope(extname))
|
||||
else:
|
||||
try:
|
||||
s.loc.snippet = rope(extname % s.name.s)
|
||||
s.setSnippet(rope(extname % s.name.s))
|
||||
except ValueError:
|
||||
localError(c.config, info, "invalid extern name: '" & extname & "'. (Forgot to escape '$'?)")
|
||||
when hasFFI:
|
||||
@@ -170,36 +170,36 @@ proc setExternName(c: PContext; s: PSym, extname: string, info: TLineInfo) =
|
||||
|
||||
proc makeExternImport(c: PContext; s: PSym, extname: string, info: TLineInfo) =
|
||||
setExternName(c, s, extname, info)
|
||||
incl(s.flags, sfImportc)
|
||||
excl(s.flags, sfForward)
|
||||
s.incl(sfImportc)
|
||||
s.excl(sfForward)
|
||||
|
||||
proc makeExternExport(c: PContext; s: PSym, extname: string, info: TLineInfo) =
|
||||
setExternName(c, s, extname, info)
|
||||
incl(s.flags, sfExportc)
|
||||
s.incl(sfExportc)
|
||||
|
||||
proc processImportCompilerProc(c: PContext; s: PSym, extname: string, info: TLineInfo) =
|
||||
setExternName(c, s, extname, info)
|
||||
incl(s.flags, sfImportc)
|
||||
excl(s.flags, sfForward)
|
||||
incl(s.loc.flags, lfImportCompilerProc)
|
||||
s.incl(sfImportc)
|
||||
s.excl(sfForward)
|
||||
incl(s.locImpl.flags, lfImportCompilerProc)
|
||||
|
||||
proc processImportCpp(c: PContext; s: PSym, extname: string, info: TLineInfo) =
|
||||
setExternName(c, s, extname, info)
|
||||
incl(s.flags, sfImportc)
|
||||
incl(s.flags, sfInfixCall)
|
||||
excl(s.flags, sfForward)
|
||||
s.incl(sfImportc)
|
||||
incl(s.flagsImpl, sfInfixCall)
|
||||
excl(s.flagsImpl, sfForward)
|
||||
if c.config.backend == backendC:
|
||||
let m = s.getModule()
|
||||
incl(m.flags, sfCompileToCpp)
|
||||
incl(m.flagsImpl, sfCompileToCpp)
|
||||
incl c.config.globalOptions, optMixedMode
|
||||
|
||||
proc processImportObjC(c: PContext; s: PSym, extname: string, info: TLineInfo) =
|
||||
setExternName(c, s, extname, info)
|
||||
incl(s.flags, sfImportc)
|
||||
incl(s.flags, sfNamedParamCall)
|
||||
excl(s.flags, sfForward)
|
||||
s.incl(sfImportc)
|
||||
incl(s.flagsImpl, sfNamedParamCall)
|
||||
excl(s.flagsImpl, sfForward)
|
||||
let m = s.getModule()
|
||||
incl(m.flags, sfCompileToObjc)
|
||||
m.incl(sfCompileToObjc)
|
||||
|
||||
proc newEmptyStrNode(c: PContext; n: PNode, strVal: string = ""): PNode {.noinline.} =
|
||||
result = newNodeIT(nkStrLit, n.info, getSysType(c.graph, n.info, tyString))
|
||||
@@ -239,14 +239,14 @@ proc getOptionalStr(c: PContext, n: PNode, defaultStr: string): string =
|
||||
proc processVirtual(c: PContext, n: PNode, s: PSym, flag: TSymFlag) =
|
||||
s.constraint = newEmptyStrNode(c, n, getOptionalStr(c, n, "$1"))
|
||||
s.constraint.strVal = s.constraint.strVal % s.name.s
|
||||
s.flags.incl {flag, sfInfixCall, sfExportc, sfMangleCpp}
|
||||
s.flagsImpl.incl {flag, sfInfixCall, sfExportc, sfMangleCpp}
|
||||
|
||||
s.typ.callConv = ccMember
|
||||
incl c.config.globalOptions, optMixedMode
|
||||
|
||||
proc processCodegenDecl(c: PContext, n: PNode, sym: PSym) =
|
||||
sym.constraint = getStrLitNode(c, n)
|
||||
sym.flags.incl sfCodegenDecl
|
||||
sym.flagsImpl.incl sfCodegenDecl
|
||||
|
||||
proc processMagic(c: PContext, n: PNode, s: PSym) =
|
||||
#if sfSystemModule notin c.module.flags:
|
||||
@@ -282,10 +282,10 @@ proc onOff(c: PContext, n: PNode, op: TOptions, resOptions: var TOptions) =
|
||||
|
||||
proc pragmaNoForward*(c: PContext, n: PNode; flag=sfNoForward) =
|
||||
if isTurnedOn(c, n):
|
||||
incl(c.module.flags, flag)
|
||||
incl(c.module.flagsImpl, flag)
|
||||
c.features.incl codeReordering
|
||||
else:
|
||||
excl(c.module.flags, flag)
|
||||
excl(c.module.flagsImpl, flag)
|
||||
# c.features.excl codeReordering
|
||||
|
||||
# deprecated as of 0.18.1
|
||||
@@ -357,9 +357,9 @@ proc processDynLib(c: PContext, n: PNode, sym: PSym) =
|
||||
var lib = getLib(c, libDynamic, expectDynlibNode(c, n))
|
||||
if not lib.isOverridden:
|
||||
addToLib(lib, sym)
|
||||
incl(sym.loc.flags, lfDynamicLib)
|
||||
sym.incl(lfDynamicLib)
|
||||
else:
|
||||
incl(sym.loc.flags, lfExportLib)
|
||||
sym.incl(lfExportLib)
|
||||
# since we'll be loading the dynlib symbols dynamically, we must use
|
||||
# a calling convention that doesn't introduce custom name mangling
|
||||
# cdecl is the default - the user can override this explicitly
|
||||
@@ -435,7 +435,7 @@ proc processExperimental(c: PContext; n: PNode) =
|
||||
if not isTopLevel(c):
|
||||
localError(c.config, n.info,
|
||||
"Code reordering experimental pragma only valid at toplevel")
|
||||
c.module.flags.incl sfReorder
|
||||
c.module.flagsImpl.incl sfReorder
|
||||
except ValueError:
|
||||
localError(c.config, n[1].info, "unknown experimental feature")
|
||||
else:
|
||||
@@ -636,7 +636,7 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
|
||||
var e = searchInScopes(con, getIdent(con.cache, sub), amb)
|
||||
# XXX what to do here if 'amb' is true?
|
||||
if e != nil:
|
||||
incl(e.flags, sfUsed)
|
||||
incl(e.flagsImpl, sfUsed)
|
||||
if isDefined(con.config, "nimPreviewAsmSemSymbol"):
|
||||
result.add con.semExprWithType(con, newSymNode(e), {efTypeAllowed})
|
||||
else:
|
||||
@@ -764,8 +764,8 @@ proc markCompilerProc(c: PContext; s: PSym) =
|
||||
# should not have an external name set:
|
||||
if s.kind != skType or s.name.s != "FlowVar":
|
||||
makeExternExport(c, s, "$1", s.info)
|
||||
incl(s.flags, sfCompilerProc)
|
||||
incl(s.flags, sfUsed)
|
||||
incl(s, sfCompilerProc)
|
||||
incl(s.flagsImpl, sfUsed)
|
||||
registerCompilerProc(c.graph, s)
|
||||
if c.config.symbolFiles != disabledSf:
|
||||
addCompilerProc(c.encoder, c.packedRepr, s)
|
||||
@@ -773,7 +773,7 @@ proc markCompilerProc(c: PContext; s: PSym) =
|
||||
proc deprecatedStmt(c: PContext; outerPragma: PNode) =
|
||||
let pragma = outerPragma[1]
|
||||
if pragma.kind in {nkStrLit..nkTripleStrLit}:
|
||||
incl(c.module.flags, sfDeprecated)
|
||||
incl(c.module, sfDeprecated)
|
||||
c.module.constraint = getStrLitNode(c, outerPragma)
|
||||
return
|
||||
if pragma.kind != nkBracket:
|
||||
@@ -842,7 +842,7 @@ proc processEffectsOf(c: PContext, n: PNode; owner: PSym) =
|
||||
let r = c.semExpr(c, n)
|
||||
if r.kind == nkSym and r.sym.kind == skParam:
|
||||
if r.sym.owner == owner:
|
||||
incl r.sym.flags, sfEffectsDelayed
|
||||
incl r.sym, sfEffectsDelayed
|
||||
else:
|
||||
localError(c.config, n.info, errGenerated, "parameter cannot be declared as .effectsOf")
|
||||
else:
|
||||
@@ -907,8 +907,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
if c.config.backend != backendCpp:
|
||||
localError(c.config, it.info, "exportcpp requires `cpp` backend, got: " & $c.config.backend)
|
||||
else:
|
||||
incl(sym.flags, sfMangleCpp)
|
||||
incl(sym.flags, sfUsed) # avoid wrong hints
|
||||
incl(sym, sfMangleCpp)
|
||||
incl(sym.flagsImpl, sfUsed) # avoid wrong hints
|
||||
of wImportc:
|
||||
let name = getOptionalStr(c, it, "$1")
|
||||
cppDefine(c.config, name)
|
||||
@@ -921,24 +921,24 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
processImportCompilerProc(c, sym, name, it.info)
|
||||
of wExtern: setExternName(c, sym, expectStrLit(c, it), it.info)
|
||||
of wDirty:
|
||||
if sym.kind == skTemplate: incl(sym.flags, sfDirty)
|
||||
if sym.kind == skTemplate: incl(sym, sfDirty)
|
||||
else: invalidPragma(c, it)
|
||||
of wRedefine:
|
||||
if sym.kind == skTemplate: incl(sym.flags, sfTemplateRedefinition)
|
||||
if sym.kind == skTemplate: incl(sym, sfTemplateRedefinition)
|
||||
else: invalidPragma(c, it)
|
||||
of wCallsite:
|
||||
if sym.kind == skTemplate: incl(sym.flags, sfCallsite)
|
||||
if sym.kind == skTemplate: incl(sym, sfCallsite)
|
||||
else: invalidPragma(c, it)
|
||||
of wImportCpp:
|
||||
processImportCpp(c, sym, getOptionalStr(c, it, "$1"), it.info)
|
||||
of wCppNonPod:
|
||||
incl(sym.flags, sfCppNonPod)
|
||||
incl(sym, sfCppNonPod)
|
||||
of wImportJs:
|
||||
if c.config.backend != backendJs:
|
||||
localError(c.config, it.info, "`importjs` pragma requires the JavaScript target")
|
||||
let name = getOptionalStr(c, it, "$1")
|
||||
incl(sym.flags, sfImportc)
|
||||
incl(sym.flags, sfInfixCall)
|
||||
incl(sym, sfImportc)
|
||||
incl(sym.flagsImpl, sfInfixCall)
|
||||
if sym.kind in skProcKinds and {'(', '#', '@'} notin name:
|
||||
localError(c.config, n.info, "`importjs` for routines requires a pattern")
|
||||
setExternName(c, sym, name, it.info)
|
||||
@@ -968,29 +968,29 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
localError(c.config, it.info, "power of two expected")
|
||||
of wNodecl:
|
||||
noVal(c, it)
|
||||
incl(sym.loc.flags, lfNoDecl)
|
||||
sym.incl(lfNoDecl)
|
||||
of wPure, wAsmNoStackFrame:
|
||||
noVal(c, it)
|
||||
if sym != nil:
|
||||
if k == wPure and sym.kind in routineKinds: invalidPragma(c, it)
|
||||
else: incl(sym.flags, sfPure)
|
||||
else: incl(sym, sfPure)
|
||||
of wVolatile:
|
||||
noVal(c, it)
|
||||
incl(sym.flags, sfVolatile)
|
||||
incl(sym, sfVolatile)
|
||||
of wCursor:
|
||||
noVal(c, it)
|
||||
incl(sym.flags, sfCursor)
|
||||
incl(sym, sfCursor)
|
||||
of wRegister:
|
||||
noVal(c, it)
|
||||
incl(sym.flags, sfRegister)
|
||||
incl(sym, sfRegister)
|
||||
of wNoalias:
|
||||
noVal(c, it)
|
||||
incl(sym.flags, sfNoalias)
|
||||
incl(sym, sfNoalias)
|
||||
of wEffectsOf:
|
||||
processEffectsOf(c, it, sym)
|
||||
of wThreadVar:
|
||||
noVal(c, it)
|
||||
incl(sym.flags, {sfThread, sfGlobal})
|
||||
incl(sym, {sfThread, sfGlobal})
|
||||
of wDeadCodeElimUnused:
|
||||
warningDeprecated(c.config, n.info, "'{.deadcodeelim: on.}' is deprecated, now a noop") # deprecated, dead code elim always on
|
||||
of wNoForward: pragmaNoForward(c, it)
|
||||
@@ -1000,20 +1000,19 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
noVal(c, it)
|
||||
if comesFromPush:
|
||||
if sym.kind in {skProc, skFunc}:
|
||||
incl(sym.flags, sfCompileTime)
|
||||
incl(sym, sfCompileTime)
|
||||
else:
|
||||
incl(sym.flags, sfCompileTime)
|
||||
incl(sym, sfCompileTime)
|
||||
#incl(sym.loc.flags, lfNoDecl)
|
||||
of wGlobal:
|
||||
noVal(c, it)
|
||||
incl(sym.flags, sfGlobal)
|
||||
incl(sym.flags, sfPure)
|
||||
incl(sym, {sfGlobal, sfPure})
|
||||
of wConstructor:
|
||||
incl(sym.flags, sfConstructor)
|
||||
incl(sym, sfConstructor)
|
||||
if sfImportc notin sym.flags:
|
||||
sym.constraint = newEmptyStrNode(c, it, getOptionalStr(c, it, ""))
|
||||
sym.constraint.strVal = sym.constraint.strVal
|
||||
sym.flags.incl {sfExportc, sfMangleCpp}
|
||||
sym.flagsImpl.incl {sfExportc, sfMangleCpp}
|
||||
sym.typ.callConv = ccNoConvention
|
||||
of wHeader:
|
||||
var lib = getLib(c, libHeader, getStrLitNode(c, it))
|
||||
|
||||
@@ -568,7 +568,7 @@ proc makeTypeDesc*(c: PContext, typ: PType): PType =
|
||||
proc symFromType*(c: PContext; t: PType, info: TLineInfo): PSym =
|
||||
if t.sym != nil: return t.sym
|
||||
result = newSym(skType, getIdent(c.cache, "AnonType"), c.idgen, t.owner, info)
|
||||
result.flags.incl sfAnon
|
||||
result.flagsImpl.incl sfAnon
|
||||
result.typ = t
|
||||
|
||||
proc symNodeFromType*(c: PContext, t: PType, info: TLineInfo): PNode =
|
||||
@@ -577,7 +577,7 @@ proc symNodeFromType*(c: PContext, t: PType, info: TLineInfo): PNode =
|
||||
|
||||
proc markIndirect*(c: PContext, s: PSym) {.inline.} =
|
||||
if s.kind in {skProc, skFunc, skConverter, skMethod, skIterator}:
|
||||
incl(s.flags, sfAddrTaken)
|
||||
incl(s.flagsImpl, sfAddrTaken)
|
||||
# XXX add to 'c' for global analysis
|
||||
|
||||
proc illFormedAst*(n: PNode; conf: ConfigRef) =
|
||||
@@ -685,7 +685,7 @@ proc analyseIfAddressTaken(c: PContext, n: PNode, isOutParam: bool): PNode =
|
||||
# n.sym.typ can be nil in 'check' mode ...
|
||||
if n.sym.typ != nil and
|
||||
skipTypes(n.sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
|
||||
incl(n.sym.flags, sfAddrTaken)
|
||||
incl(n.sym.flagsImpl, sfAddrTaken)
|
||||
result = newHiddenAddrTaken(c, n, isOutParam)
|
||||
of nkDotExpr:
|
||||
checkSonsLen(n, 2, c.config)
|
||||
@@ -693,12 +693,12 @@ proc analyseIfAddressTaken(c: PContext, n: PNode, isOutParam: bool): PNode =
|
||||
internalError(c.config, n.info, "analyseIfAddressTaken")
|
||||
return
|
||||
if skipTypes(n[1].sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
|
||||
incl(n[1].sym.flags, sfAddrTaken)
|
||||
incl(n[1].sym.flagsImpl, sfAddrTaken)
|
||||
result = newHiddenAddrTaken(c, n, isOutParam)
|
||||
of nkBracketExpr:
|
||||
checkMinSonsLen(n, 1, c.config)
|
||||
if skipTypes(n[0].typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
|
||||
if n[0].kind == nkSym: incl(n[0].sym.flags, sfAddrTaken)
|
||||
if n[0].kind == nkSym: incl(n[0].sym.flagsImpl, sfAddrTaken)
|
||||
result = newHiddenAddrTaken(c, n, isOutParam)
|
||||
else:
|
||||
result = newHiddenAddrTaken(c, n, isOutParam)
|
||||
|
||||
@@ -279,8 +279,10 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PT
|
||||
if result.sym.kind == skField and result.sym.ast != nil and
|
||||
(cl.owner == nil or result.sym.owner == cl.owner):
|
||||
# instantiate default value of object/tuple field
|
||||
cl.c.fitDefaultNode(cl.c, result.sym.ast, result.sym.typ)
|
||||
result.sym.typ = result.sym.ast.typ.skipIntLit(cl.c.idgen)
|
||||
var n = result.sym.ast
|
||||
cl.c.fitDefaultNode(cl.c, n, result.sym.typ)
|
||||
result.sym.ast = n
|
||||
result.sym.typ = n.typ.skipIntLit(cl.c.idgen)
|
||||
# sym type can be nil if was gensym created by macro, see #24048
|
||||
if result.sym.typ != nil and result.sym.typ.kind == tyVoid:
|
||||
# don't add the 'void' field
|
||||
@@ -361,7 +363,7 @@ proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym, t: PType): PSym =
|
||||
|
||||
]#
|
||||
result = copySym(s, cl.c.idgen)
|
||||
incl(result.flags, sfFromGeneric)
|
||||
incl(result.flagsImpl, sfFromGeneric)
|
||||
#idTablePut(cl.symMap, s, result)
|
||||
setOwner(result, s.owner)
|
||||
result.typ = t
|
||||
@@ -682,7 +684,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType, isInstValue = false):
|
||||
|
||||
of tyUserTypeClass:
|
||||
result = t
|
||||
|
||||
|
||||
of tyStatic:
|
||||
if cl.c.matchedConcept != nil:
|
||||
# allow concepts to not instantiate statics for now
|
||||
|
||||
@@ -1671,7 +1671,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
|
||||
let roota = if skipBoth or deptha > depthf: a.skipGenericAlias else: a
|
||||
let rootf = if skipBoth or depthf > deptha: f.skipGenericAlias else: f
|
||||
|
||||
|
||||
if f.isConcept:
|
||||
result = enterConceptMatch(c, rootf, roota, flags)
|
||||
elif a.kind == tyGenericInst:
|
||||
@@ -2316,7 +2316,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
|
||||
let fdest = typeRel(m, f, dest)
|
||||
if fdest in {isEqual, isGeneric} and not (dest.kind == tyLent and f.kind in {tyVar}):
|
||||
# can't fully mark used yet, may not be used in final call
|
||||
incl(c.converters[i].flags, sfUsed)
|
||||
incl(c.converters[i].flagsImpl, sfUsed)
|
||||
markOwnerModuleAsUsed(c, c.converters[i])
|
||||
var s = newSymNode(c.converters[i])
|
||||
s.typ() = c.converters[i].typ
|
||||
|
||||
@@ -43,7 +43,7 @@ when defined(nimsuggest):
|
||||
const
|
||||
sep = '\t'
|
||||
|
||||
type
|
||||
type
|
||||
ImportContext = object
|
||||
isMultiImport: bool # True if we're in a [...] context
|
||||
baseDir: string # e.g., "folder/" in "import folder/[..."
|
||||
@@ -707,9 +707,9 @@ proc markOwnerModuleAsUsed(c: PContext; s: PSym) =
|
||||
proc markUsed(c: PContext; info: TLineInfo; s: PSym; checkStyle = true; isGenericInstance = false) =
|
||||
if not isGenericInstance:
|
||||
let conf = c.config
|
||||
incl(s.flags, sfUsed)
|
||||
incl(s.flagsImpl, sfUsed)
|
||||
if s.kind == skEnumField and s.owner != nil:
|
||||
incl(s.owner.flags, sfUsed)
|
||||
incl(s.owner.flagsImpl, sfUsed)
|
||||
if sfDeprecated in s.owner.flags:
|
||||
warnAboutDeprecated(conf, info, s)
|
||||
if {sfDeprecated, sfError} * s.flags != {}:
|
||||
@@ -788,7 +788,7 @@ proc extractImportContextFromAst(n: PNode, cursorCol: int): ImportContext =
|
||||
proc findModuleFile(c: PContext, partialPath: string): seq[string] =
|
||||
result = @[]
|
||||
let currentModuleDir = parentDir(toFullPath(c.config, FileIndex(c.module.position)))
|
||||
|
||||
|
||||
proc tryAddModule(path, baseName: string) =
|
||||
if fileExists(path & ".nim"):
|
||||
result.add(baseName)
|
||||
@@ -800,7 +800,7 @@ proc findModuleFile(c: PContext, partialPath: string): seq[string] =
|
||||
let (_, name, ext) = splitFile(path)
|
||||
if kind == pcFile:
|
||||
if ext == ".nim" and name.startsWith(file):
|
||||
result.add(name)
|
||||
result.add(name)
|
||||
|
||||
proc collectImportModulesFromDir(dir: string, result: var seq[string]) =
|
||||
for kind, path in walkDir(dir):
|
||||
@@ -809,10 +809,10 @@ proc findModuleFile(c: PContext, partialPath: string): seq[string] =
|
||||
if kind == pcFile:
|
||||
if ext == ".nim" and name.startsWith(partialPath):
|
||||
result.add(name)
|
||||
else:
|
||||
else:
|
||||
if name.startsWith(partialPath):
|
||||
result.add(name)
|
||||
|
||||
|
||||
if '/' in partialPath:
|
||||
let parts = partialPath.split('/')
|
||||
let dir = parts[0]
|
||||
@@ -839,13 +839,13 @@ proc suggestModuleNames(c: PContext, n: PNode) =
|
||||
column: n.info.col.int,
|
||||
doc: "",
|
||||
quality: 100,
|
||||
contextFits: true,
|
||||
contextFits: true,
|
||||
prefix: if partialPath.len > 0: prefixMatch(path, partialPath)
|
||||
else: PrefixMatch.None,
|
||||
symkind: byte skModule
|
||||
)
|
||||
suggestions.add(suggest)
|
||||
|
||||
|
||||
let importCtx = extractImportContextFromAst(n, c.config.m.trackPos.col)
|
||||
var searchPath = ""
|
||||
if importCtx.baseDir.len > 0:
|
||||
@@ -901,7 +901,7 @@ proc suggestExprNoCheck*(c: PContext, n: PNode) =
|
||||
if outputs.len > 0 and c.config.ideCmd in {ideSug, ideCon, ideDef}:
|
||||
produceOutput(outputs, c.config)
|
||||
suggestQuit()
|
||||
|
||||
|
||||
proc suggestExpr*(c: PContext, n: PNode) =
|
||||
if exactEquals(c.config.m.trackPos, n.info): suggestExprNoCheck(c, n)
|
||||
|
||||
|
||||
@@ -1014,6 +1014,6 @@ proc computeCursors*(s: PSym; n: PNode; g: ModuleGraph) =
|
||||
if par.s[rid].con.kind == isRootOf and dangerousMutation(par.graphs[par.s[rid].con.graphIndex], par.s[i]):
|
||||
discard "cannot cursor into a graph that is mutated"
|
||||
else:
|
||||
v.sym.flags.incl sfCursor
|
||||
v.sym.flagsImpl.incl sfCursor
|
||||
when false:
|
||||
echo "this is now a cursor ", v.sym, " ", par.s[rid].flags, " ", g.config $ v.sym.info
|
||||
|
||||
Reference in New Issue
Block a user