diff --git a/compiler/ast.nim b/compiler/ast.nim index 444c51b199..67f111c984 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -549,12 +549,19 @@ proc add*(father, son: PType) = proc addAllowNil*(father, son: PType) {.inline.} = father.sonsImpl.add son -template `[]`*(n: PType, i: int): PType = n.sonsImpl[i] +template `[]`*(n: PType, i: int): PType = + if n.state == Partial: loadType(n) + n.sonsImpl[i] template `[]=`*(n: PType, i: int; x: PType) = + if n.state == Partial: loadType(n) n.sonsImpl[i] = x -template `[]`*(n: PType, i: BackwardsIndex): PType = n[n.len - i.int] -template `[]=`*(n: PType, i: BackwardsIndex; x: PType) = n[n.len - i.int] = x +template `[]`*(n: PType, i: BackwardsIndex): PType = + if n.state == Partial: loadType(n) + n[n.len - i.int] +template `[]=`*(n: PType, i: BackwardsIndex; x: PType) = + if n.state == Partial: loadType(n) + n[n.len - i.int] = x proc getDeclPragma*(n: PNode): PNode = ## return the `nkPragma` node for declaration `n`, or `nil` if no pragma was found. @@ -791,29 +798,57 @@ proc replaceFirstSon*(n, newson: PNode) {.inline.} = proc replaceSon*(n: PNode; i: int; newson: PNode) {.inline.} = n.sons[i] = newson -proc last*(n: PType): PType {.inline.} = n.sonsImpl[^1] +proc last*(n: PType): PType {.inline.} = + if n.state == Partial: loadType(n) + n.sonsImpl[^1] -proc elementType*(n: PType): PType {.inline.} = n.sonsImpl[^1] -proc skipModifier*(n: PType): PType {.inline.} = n.sonsImpl[^1] +proc elementType*(n: PType): PType {.inline.} = + if n.state == Partial: loadType(n) + n.sonsImpl[^1] -proc indexType*(n: PType): PType {.inline.} = n.sonsImpl[0] -proc baseClass*(n: PType): PType {.inline.} = n.sonsImpl[0] +proc skipModifier*(n: PType): PType {.inline.} = + if n.state == Partial: loadType(n) + n.sonsImpl[^1] + +proc indexType*(n: PType): PType {.inline.} = + if n.state == Partial: loadType(n) + n.sonsImpl[0] + +proc baseClass*(n: PType): PType {.inline.} = + if n.state == Partial: loadType(n) + n.sonsImpl[0] proc base*(t: PType): PType {.inline.} = + if t.state == Partial: loadType(t) result = t.sonsImpl[0] -proc returnType*(n: PType): PType {.inline.} = n.sonsImpl[0] +proc returnType*(n: PType): PType {.inline.} = + if n.state == Partial: loadType(n) + n.sonsImpl[0] + proc setReturnType*(n, r: PType) {.inline.} = + if n.state == Partial: loadType(n) n.sonsImpl[0] = r + proc setIndexType*(n, idx: PType) {.inline.} = + if n.state == Partial: loadType(n) n.sonsImpl[0] = idx -proc firstParamType*(n: PType): PType {.inline.} = n.sonsImpl[1] -proc firstGenericParam*(n: PType): PType {.inline.} = n.sonsImpl[1] +proc firstParamType*(n: PType): PType {.inline.} = + if n.state == Partial: loadType(n) + n.sonsImpl[1] -proc typeBodyImpl*(n: PType): PType {.inline.} = n.sonsImpl[^1] +proc firstGenericParam*(n: PType): PType {.inline.} = + if n.state == Partial: loadType(n) + n.sonsImpl[1] -proc genericHead*(n: PType): PType {.inline.} = n.sonsImpl[0] +proc typeBodyImpl*(n: PType): PType {.inline.} = + if n.state == Partial: loadType(n) + n.sonsImpl[^1] + +proc genericHead*(n: PType): PType {.inline.} = + if n.state == Partial: loadType(n) + n.sonsImpl[0] proc skipTypes*(t: PType, kinds: TTypeKinds): PType = ## Used throughout the compiler code to test whether a type tree contains or diff --git a/compiler/ast2nif.nim b/compiler/ast2nif.nim index 4ca2a2c94e..da62aeee15 100644 --- a/compiler/ast2nif.nim +++ b/compiler/ast2nif.nim @@ -268,13 +268,6 @@ proc writeSymDef(w: var Writer; dest: var TokenBuf; sym: PSym) = dest.addIdent "x" else: dest.addDotToken - if sym.magicImpl == mNone: - dest.addDotToken - else: - dest.addIdent toNifTag(sym.magicImpl) - writeFlags(dest, sym.flagsImpl) - writeFlags(dest, sym.optionsImpl) - dest.addIntLit sym.offsetImpl # field `disamb` made part of the name, so do not store it here dest.buildTree sym.kindImpl.toNifTag: case sym.kindImpl @@ -284,6 +277,15 @@ proc writeSymDef(w: var Writer; dest: var TokenBuf; sym: PSym) = dest.addIntLit sym.alignmentImpl else: discard + + if sym.magicImpl == mNone: + dest.addDotToken + else: + dest.addIdent toNifTag(sym.magicImpl) + writeFlags(dest, sym.flagsImpl) + writeFlags(dest, sym.optionsImpl) + dest.addIntLit sym.offsetImpl + if sym.kindImpl == skModule: dest.addDotToken() # position will be set by the loader! else: @@ -786,13 +788,9 @@ proc loadSymFromCursor(c: var DecodeContext; s: PSym; n: var Cursor; thisModule: else: raiseAssert "expected `x` or '.' but got " & $n.kind - loadField s.magicImpl - loadField s.flagsImpl - loadField s.optionsImpl - loadField s.offsetImpl - expect n, ParLe - s.kindImpl = parse(TSymKind, pool.tags[n.tagId]) + {.cast(uncheckedAssign).}: + s.kindImpl = parse(TSymKind, pool.tags[n.tagId]) inc n case s.kindImpl @@ -804,6 +802,11 @@ proc loadSymFromCursor(c: var DecodeContext; s: PSym; n: var Cursor; thisModule: discard skipParRi n + loadField s.magicImpl + loadField s.flagsImpl + loadField s.optionsImpl + loadField s.offsetImpl + if s.kindImpl == skModule: expect n, DotToken inc n @@ -829,6 +832,8 @@ proc loadSym*(c: var DecodeContext; s: PSym) = expect n, ParLe if n.tagId != sdefTag: raiseAssert "(sd) expected" + # Extract line info from the sdef tag before moving past it + s.infoImpl = c.infos.oldLineInfo(n.info) inc n loadSymFromCursor(c, s, n, c.moduleToNifSuffix[symsModule])