summary refs log tree commit diff stats
path: root/compiler/ast.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/ast.nim')
-rw-r--r--compiler/ast.nim93
1 files changed, 61 insertions, 32 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index d81ccf33b..a9793fb21 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -10,7 +10,7 @@
 # abstract syntax tree + symbol table
 
 import
-  lineinfos, hashes, options, ropes, idents, idgen, int128
+  lineinfos, hashes, options, ropes, idents, int128
 from strutils import toLowerAscii
 
 export int128
@@ -717,6 +717,14 @@ const
     mInSet, mRepr}
 
 type
+  ItemId* = object
+    module*: int32
+    item*: int32
+
+  TIdObj* = object of RootObj
+    itemId*: ItemId
+  PIdObj* = ref TIdObj
+
   PNode* = ref TNode
   TNodeSeq* = seq[PNode]
   PType* = ref TType
@@ -926,7 +934,7 @@ type
     loc*: TLoc
     typeInst*: PType          # for generic instantiations the tyGenericInst that led to this
                               # type.
-    uniqueId*: int            # due to a design mistake, we need to keep the real ID here as it
+    uniqueId*: ItemId         # due to a design mistake, we need to keep the real ID here as it
                               # required by the --incremental:on mode.
 
   TPair* = object
@@ -1060,6 +1068,35 @@ proc getnimblePkg*(a: PSym): PSym =
     else:
       assert false, $result.kind
 
+const
+  moduleShift = when defined(cpu32): 20 else: 24
+
+template id*(a: PIdObj): int =
+  let x = a
+  (x.itemId.module.int shl moduleShift) + x.itemId.item.int
+
+type
+  IdGenerator* = ref ItemId # unfortunately, we really need the 'shared mutable' aspect here.
+
+const
+  PackageModuleId* = -3'i32
+
+proc idGeneratorFromModule*(m: PSym): IdGenerator =
+  assert m.kind == skModule
+  result = IdGenerator(module: m.itemId.module, item: m.itemId.item)
+
+proc nextId*(x: IdGenerator): ItemId {.inline.} =
+  inc x.item
+  result = x[]
+
+when false:
+  proc storeBack*(dest: var IdGenerator; src: IdGenerator) {.inline.} =
+    assert dest.ItemId.module == src.ItemId.module
+    if dest.ItemId.item > src.ItemId.item:
+      echo dest.ItemId.item, " ", src.ItemId.item, " ", src.ItemId.module
+    assert dest.ItemId.item <= src.ItemId.item
+    dest = src
+
 proc getnimblePkgId*(a: PSym): int =
   let b = a.getnimblePkg
   result = if b == nil: -1 else: b.id
@@ -1164,13 +1201,11 @@ proc newTreeIT*(kind: TNodeKind; info: TLineInfo; typ: PType; children: varargs[
 template previouslyInferred*(t: PType): PType =
   if t.sons.len > 1: t.lastSon else: nil
 
-proc newSym*(symKind: TSymKind, name: PIdent, owner: PSym,
+proc newSym*(symKind: TSymKind, name: PIdent, id: ItemId, owner: PSym,
              info: TLineInfo; options: TOptions = {}): PSym =
   # generates a symbol and initializes the hash field too
-  result = PSym(name: name, kind: symKind, flags: {}, info: info, id: getID(),
+  result = PSym(name: name, kind: symKind, flags: {}, info: info, itemId: id,
                 options: options, owner: owner, offset: defaultOffset)
-  when debugIds:
-    registerId(result)
 
 proc astdef*(s: PSym): PNode =
   # get only the definition (initializer) portion of the ast
@@ -1344,13 +1379,11 @@ proc `$`*(s: PSym): string =
   else:
     result = "<nil>"
 
-proc newType*(kind: TTypeKind, owner: PSym): PType =
-  let id = getID()
+proc newType*(kind: TTypeKind, id: ItemId; owner: PSym): PType =
   result = PType(kind: kind, owner: owner, size: defaultSize,
-                 align: defaultAlignment, id: id, uniqueId: id,
-                 lockLevel: UnspecifiedLockLevel)
-  when debugIds:
-    registerId(result)
+                 align: defaultAlignment, itemId: id,
+                 lockLevel: UnspecifiedLockLevel,
+                 uniqueId: id)
   when false:
     if result.id == 76426:
       echo "KNID ", kind
@@ -1392,22 +1425,18 @@ proc assignType*(dest, src: PType) =
   newSons(dest, src.len)
   for i in 0..<src.len: dest[i] = src[i]
 
-proc copyType*(t: PType, owner: PSym, keepId: bool): PType =
-  result = newType(t.kind, owner)
+proc copyType*(t: PType, id: ItemId, owner: PSym): PType =
+  result = newType(t.kind, id, owner)
   assignType(result, t)
-  if keepId:
-    result.id = t.id
-  else:
-    when debugIds: registerId(result)
   result.sym = t.sym          # backend-info should not be copied
 
-proc exactReplica*(t: PType): PType = copyType(t, t.owner, true)
+proc exactReplica*(t: PType): PType =
+  result = copyType(t, t.itemId, t.owner)
 
-proc copySym*(s: PSym): PSym =
-  result = newSym(s.kind, s.name, s.owner, s.info, s.options)
+proc copySym*(s: PSym; id: ItemId): PSym =
+  result = newSym(s.kind, s.name, id, s.owner, s.info, s.options)
   #result.ast = nil            # BUGFIX; was: s.ast which made problems
   result.typ = s.typ
-  when debugIds: registerId(result)
   result.flags = s.flags
   result.magic = s.magic
   if s.kind == skModule:
@@ -1421,12 +1450,12 @@ proc copySym*(s: PSym): PSym =
     result.bitsize = s.bitsize
     result.alignment = s.alignment
 
-proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo;
+proc createModuleAlias*(s: PSym, id: ItemId, newIdent: PIdent, info: TLineInfo;
                         options: TOptions): PSym =
-  result = newSym(s.kind, newIdent, s.owner, info, options)
+  result = newSym(s.kind, newIdent, id, s.owner, info, options)
   # keep ID!
   result.ast = s.ast
-  result.id = s.id
+  #result.id = s.id # XXX figure out what to do with the ID.
   result.flags = s.flags
   system.shallowCopy(result.tab, s.tab)
   result.options = s.options
@@ -1576,7 +1605,7 @@ proc transitionNoneToSym*(n: PNode) =
 
 template transitionSymKindCommon*(k: TSymKind) =
   let obj {.inject.} = s[]
-  s[] = TSym(kind: k, id: obj.id, magic: obj.magic, typ: obj.typ, name: obj.name,
+  s[] = TSym(kind: k, itemId: obj.itemId, magic: obj.magic, typ: obj.typ, name: obj.name,
              info: obj.info, owner: obj.owner, flags: obj.flags, ast: obj.ast,
              options: obj.options, position: obj.position, offset: obj.offset,
              loc: obj.loc, annex: obj.annex, constraint: obj.constraint)
@@ -1797,19 +1826,19 @@ proc skipStmtList*(n: PNode): PNode =
   else:
     result = n
 
-proc toVar*(typ: PType; kind: TTypeKind): PType =
+proc toVar*(typ: PType; kind: TTypeKind; idgen: IdGenerator): PType =
   ## If ``typ`` is not a tyVar then it is converted into a `var <typ>` and
   ## returned. Otherwise ``typ`` is simply returned as-is.
   result = typ
   if typ.kind != kind:
-    result = newType(kind, typ.owner)
+    result = newType(kind, nextId(idgen), typ.owner)
     rawAddSon(result, typ)
 
-proc toRef*(typ: PType): PType =
+proc toRef*(typ: PType; idgen: IdGenerator): PType =
   ## If ``typ`` is a tyObject then it is converted into a `ref <typ>` and
   ## returned. Otherwise ``typ`` is simply returned as-is.
   if typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject:
-    result = newType(tyRef, typ.owner)
+    result = newType(tyRef, nextId(idgen), typ.owner)
     rawAddSon(result, typ)
 
 proc toObject*(typ: PType): PType =
@@ -1888,8 +1917,8 @@ proc isSinkParam*(s: PSym): bool {.inline.} =
 proc isSinkType*(t: PType): bool {.inline.} =
   t.kind == tySink or tfHasOwned in t.flags
 
-proc newProcType*(info: TLineInfo; owner: PSym): PType =
-  result = newType(tyProc, owner)
+proc newProcType*(info: TLineInfo; id: ItemId; owner: PSym): PType =
+  result = newType(tyProc, id, owner)
   result.n = newNodeI(nkFormalParams, info)
   rawAddSon(result, nil) # return type
   # result.n[0] used to be `nkType`, but now it's `nkEffectList` because