summary refs log tree commit diff stats
path: root/compiler/sighashes.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/sighashes.nim')
-rw-r--r--compiler/sighashes.nim86
1 files changed, 44 insertions, 42 deletions
diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim
index 3508a146a..7e2a0b660 100644
--- a/compiler/sighashes.nim
+++ b/compiler/sighashes.nim
@@ -9,10 +9,12 @@
 
 ## Computes hash values for routine (proc, method etc) signatures.
 
-import ast, tables, ropes, md5, modulegraphs
+import ast, tables, ropes, md5, modulegraphs, options, msgs, packages, pathutils
 from hashes import Hash
 import types
 
+import std/os
+
 when defined(nimPreviewSlimSystem):
   import std/assertions
 
@@ -42,8 +44,7 @@ type
     CoDistinct
     CoHashTypeInsideNode
 
-proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag])
-
+proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: ConfigRef)
 proc hashSym(c: var MD5Context, s: PSym) =
   if sfAnon in s.flags or s.kind == skGenericParam:
     c &= ":anon"
@@ -54,20 +55,21 @@ proc hashSym(c: var MD5Context, s: PSym) =
       c &= "."
       it = it.owner
 
-proc hashTypeSym(c: var MD5Context, s: PSym) =
+proc hashTypeSym(c: var MD5Context, s: PSym; conf: ConfigRef) =
   if sfAnon in s.flags or s.kind == skGenericParam:
     c &= ":anon"
   else:
     var it = s
+    c &= customPath(conf.toFullPath(s.info))
     while it != nil:
       if sfFromGeneric in it.flags and it.kind in routineKinds and
           it.typ != nil:
-        hashType c, it.typ, {CoProc}
+        hashType c, it.typ, {CoProc}, conf
       c &= it.name.s
       c &= "."
       it = it.owner
 
-proc hashTree(c: var MD5Context, n: PNode; flags: set[ConsiderFlag]) =
+proc hashTree(c: var MD5Context, n: PNode; flags: set[ConsiderFlag]; conf: ConfigRef) =
   if n == nil:
     c &= "\255"
     return
@@ -82,7 +84,7 @@ proc hashTree(c: var MD5Context, n: PNode; flags: set[ConsiderFlag]) =
   of nkSym:
     hashSym(c, n.sym)
     if CoHashTypeInsideNode in flags and n.sym.typ != nil:
-      hashType(c, n.sym.typ, flags)
+      hashType(c, n.sym.typ, flags, conf)
   of nkCharLit..nkUInt64Lit:
     let v = n.intVal
     lowlevel v
@@ -92,9 +94,9 @@ proc hashTree(c: var MD5Context, n: PNode; flags: set[ConsiderFlag]) =
   of nkStrLit..nkTripleStrLit:
     c &= n.strVal
   else:
-    for i in 0..<n.len: hashTree(c, n[i], flags)
+    for i in 0..<n.len: hashTree(c, n[i], flags, conf)
 
-proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
+proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: ConfigRef) =
   if t == nil:
     c &= "\254"
     return
@@ -102,14 +104,14 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
   case t.kind
   of tyGenericInvocation:
     for i in 0..<t.len:
-      c.hashType t[i], flags
+      c.hashType t[i], flags, conf
   of tyDistinct:
     if CoDistinct in flags:
       if t.sym != nil: c.hashSym(t.sym)
       if t.sym == nil or tfFromGeneric in t.flags:
-        c.hashType t.lastSon, flags
+        c.hashType t.lastSon, flags, conf
     elif CoType in flags or t.sym == nil:
-      c.hashType t.lastSon, flags
+      c.hashType t.lastSon, flags, conf
     else:
       c.hashSym(t.sym)
   of tyGenericInst:
@@ -119,15 +121,15 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
       # value for each instantiation, so we hash the generic parameters here:
       let normalizedType = t.skipGenericAlias
       for i in 0..<normalizedType.len - 1:
-        c.hashType t[i], flags
+        c.hashType t[i], flags, conf
     else:
-      c.hashType t.lastSon, flags
+      c.hashType t.lastSon, flags, conf
   of tyAlias, tySink, tyUserTypeClasses, tyInferred:
-    c.hashType t.lastSon, flags
+    c.hashType t.lastSon, flags, conf
   of tyOwned:
     if CoConsiderOwned in flags:
       c &= char(t.kind)
-    c.hashType t.lastSon, flags
+    c.hashType t.lastSon, flags, conf
   of tyBool, tyChar, tyInt..tyUInt64:
     # no canonicalization for integral types, so that e.g. ``pid_t`` is
     # produced instead of ``NI``:
@@ -141,7 +143,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
       t.typeInst = nil
       assert inst.kind == tyGenericInst
       for i in 0..<inst.len - 1:
-        c.hashType inst[i], flags
+        c.hashType inst[i], flags, conf
       t.typeInst = inst
       return
     c &= char(t.kind)
@@ -153,7 +155,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
         # The user has set a specific name for this type
         c &= t.sym.loc.r
       elif CoOwnerSig in flags:
-        c.hashTypeSym(t.sym)
+        c.hashTypeSym(t.sym, conf)
       else:
         c.hashSym(t.sym)
 
@@ -172,7 +174,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
           # xxx instead, use a hash table to indicate we've already visited a type, which
           # would also be more efficient.
           symWithFlags.flags.excl {sfAnon, sfGenSym}
-          hashTree(c, t.n, flags + {CoHashTypeInsideNode})
+          hashTree(c, t.n, flags + {CoHashTypeInsideNode}, conf)
           symWithFlags.flags = oldFlags
         else:
           # The object has no fields: we _must_ add something here in order to
@@ -182,15 +184,15 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
     else:
       c &= t.id
     if t.len > 0 and t[0] != nil:
-      hashType c, t[0], flags
+      hashType c, t[0], flags, conf
   of tyRef, tyPtr, tyGenericBody, tyVar:
     c &= char(t.kind)
     if t.sons.len > 0:
-      c.hashType t.lastSon, flags
+      c.hashType t.lastSon, flags, conf
     if tfVarIsPtr in t.flags: c &= ".varisptr"
   of tyFromExpr:
     c &= char(t.kind)
-    c.hashTree(t.n, {})
+    c.hashTree(t.n, {}, conf)
   of tyTuple:
     c &= char(t.kind)
     if t.n != nil and CoType notin flags:
@@ -199,19 +201,19 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
         assert(t.n[i].kind == nkSym)
         c &= t.n[i].sym.name.s
         c &= ':'
-        c.hashType(t[i], flags+{CoIgnoreRange})
+        c.hashType(t[i], flags+{CoIgnoreRange}, conf)
         c &= ','
     else:
-      for i in 0..<t.len: c.hashType t[i], flags+{CoIgnoreRange}
+      for i in 0..<t.len: c.hashType t[i], flags+{CoIgnoreRange}, conf
   of tyRange:
     if CoIgnoreRange notin flags:
       c &= char(t.kind)
-      c.hashTree(t.n, {})
-    c.hashType(t[0], flags)
+      c.hashTree(t.n, {}, conf)
+    c.hashType(t[0], flags, conf)
   of tyStatic:
     c &= char(t.kind)
-    c.hashTree(t.n, {})
-    c.hashType(t[0], flags)
+    c.hashTree(t.n, {}, conf)
+    c.hashType(t[0], flags, conf)
   of tyProc:
     c &= char(t.kind)
     c &= (if tfIterator in t.flags: "iterator " else: "proc ")
@@ -221,11 +223,11 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
         let param = params[i].sym
         c &= param.name.s
         c &= ':'
-        c.hashType(param.typ, flags)
+        c.hashType(param.typ, flags, conf)
         c &= ','
-      c.hashType(t[0], flags)
+      c.hashType(t[0], flags, conf)
     else:
-      for i in 0..<t.len: c.hashType(t[i], flags)
+      for i in 0..<t.len: c.hashType(t[i], flags, conf)
     c &= char(t.callConv)
     # purity of functions doesn't have to affect the mangling (which is in fact
     # problematic for HCR - someone could have cached a pointer to another
@@ -237,10 +239,10 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
     if tfVarargs in t.flags: c &= ".varargs"
   of tyArray:
     c &= char(t.kind)
-    for i in 0..<t.len: c.hashType(t[i], flags-{CoIgnoreRange})
+    for i in 0..<t.len: c.hashType(t[i], flags-{CoIgnoreRange}, conf)
   else:
     c &= char(t.kind)
-    for i in 0..<t.len: c.hashType(t[i], flags)
+    for i in 0..<t.len: c.hashType(t[i], flags, conf)
   if tfNotNil in t.flags and CoType notin flags: c &= "not nil"
 
 when defined(debugSigHashes):
@@ -257,19 +259,19 @@ when defined(debugSigHashes):
   #  select hash, type from sighashes where hash in
   # (select hash from sighashes group by hash having count(*) > 1) order by hash;
 
-proc hashType*(t: PType; flags: set[ConsiderFlag] = {CoType}): SigHash =
+proc hashType*(t: PType; conf: ConfigRef; flags: set[ConsiderFlag] = {CoType}): SigHash =
   var c: MD5Context
   md5Init c
-  hashType c, t, flags+{CoOwnerSig}
+  hashType c, t, flags+{CoOwnerSig}, conf
   md5Final c, result.MD5Digest
   when defined(debugSigHashes):
     db.exec(sql"INSERT OR IGNORE INTO sighashes(type, hash) VALUES (?, ?)",
             typeToString(t), $result)
 
-proc hashProc*(s: PSym): SigHash =
+proc hashProc*(s: PSym; conf: ConfigRef): SigHash =
   var c: MD5Context
   md5Init c
-  hashType c, s.typ, {CoProc}
+  hashType c, s.typ, {CoProc}, conf
 
   var m = s
   while m.kind != skModule: m = m.owner
@@ -315,9 +317,9 @@ proc hashOwner*(s: PSym): SigHash =
 
   md5Final c, result.MD5Digest
 
-proc sigHash*(s: PSym): SigHash =
+proc sigHash*(s: PSym; conf: ConfigRef): SigHash =
   if s.kind in routineKinds and s.typ != nil:
-    result = hashProc(s)
+    result = hashProc(s, conf)
   else:
     result = hashNonProc(s)
 
@@ -378,7 +380,7 @@ proc symBodyDigest*(graph: ModuleGraph, sym: PSym): SigHash =
 
   var c: MD5Context
   md5Init(c)
-  c.hashType(sym.typ, {CoProc})
+  c.hashType(sym.typ, {CoProc}, graph.config)
   c &= char(sym.kind)
   c.md5Final(result.MD5Digest)
   graph.symBodyHashes[sym.id] = result # protect from recursion in the body
@@ -391,12 +393,12 @@ proc symBodyDigest*(graph: ModuleGraph, sym: PSym): SigHash =
     graph.symBodyHashes[sym.id] = result
 
 proc idOrSig*(s: PSym, currentModule: string,
-              sigCollisions: var CountTable[SigHash]): Rope =
+              sigCollisions: var CountTable[SigHash]; conf: ConfigRef): Rope =
   if s.kind in routineKinds and s.typ != nil:
     # signatures for exported routines are reliable enough to
     # produce a unique name and this means produced C++ is more stable regarding
     # Nim changes:
-    let sig = hashProc(s)
+    let sig = hashProc(s, conf)
     result = rope($sig)
     #let m = if s.typ.callConv != ccInline: findPendingModule(m, s) else: m
     let counter = sigCollisions.getOrDefault(sig)