diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index b7e547528d..7b1cddc287 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -38,22 +38,31 @@ when false: result = gDebugInfo.register(p.name.s, m.name.s) proc idOrSig(m: BModule; s: PSym): Rope = - if s.kind in routineKinds and s.typ != nil and - s.typ.callConv != ccInline: + 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 wrt # Nim changes: let sig = hashProc(s) result = rope($sig) - let m = findPendingModule(m, s) + #let m = if s.typ.callConv != ccInline: findPendingModule(m, s) else: m let counter = m.sigConflicts.getOrDefault(sig) #if sigs == "_jckmNePK3i2MFnWwZlp6Lg" and s.name.s == "contains": # echo "counter ", counter, " ", s.id if counter != 0: result.add "_" & rope(counter+1) + # this minor hack is necessary to make tests/collections/thashes compile. + # The inlined hash function's original module is ambiguous so we end up + # generating duplicate names otherwise: + if s.typ.callConv == ccInline: + result.add rope(m.module.name.s) m.sigConflicts.inc(sig) else: - result = "_" & rope s.id + let sig = hashNonProc(s) + result = rope($sig) + let counter = m.sigConflicts.getOrDefault(sig) + if counter != 0: + result.add "_" & rope(counter+1) + m.sigConflicts.inc(sig) proc mangleName(m: BModule; s: PSym): Rope = result = s.loc.r @@ -107,6 +116,8 @@ proc mangleName(m: BModule; s: PSym): Rope = add(result, m.idOrSig(s)) #add(result, ~"_") #add(result, rope(hashOwner(s).BiggestInt)) + #if s.typ != nil and s.typ.callConv == ccInline: + # result.add "/* " & rope(m.module.name.s) & " */" s.loc.r = result proc typeName(typ: PType): Rope = diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 6a60e87e90..0825127537 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -723,29 +723,49 @@ proc genProcPrototype(m: BModule, sym: PSym) = add(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header)) proc genProcNoForward(m: BModule, prc: PSym) = - fillProcLoc(m, prc) - useHeader(m, prc) if lfImportCompilerProc in prc.loc.flags: + fillProcLoc(m, prc) + useHeader(m, prc) # dependency to a compilerproc: discard cgsym(m, prc.name.s) return - genProcPrototype(m, prc) - if lfNoDecl in prc.loc.flags: discard + if lfNoDecl in prc.loc.flags: + fillProcLoc(m, prc) + useHeader(m, prc) + genProcPrototype(m, prc) elif prc.typ.callConv == ccInline: # We add inline procs to the calling module to enable C based inlining. # This also means that a check with ``q.declaredThings`` is wrong, we need # a check for ``m.declaredThings``. - if not containsOrIncl(m.declaredThings, prc.id): genProcAux(m, prc) + if not containsOrIncl(m.declaredThings, prc.id): + #if prc.loc.k == locNone: + fillProcLoc(m, prc) + #elif {sfExportc, sfImportc} * prc.flags == {}: + # # reset name to restore consistency in case of hashing collisions: + # echo "resetting ", prc.id, " by ", m.module.name.s + # prc.loc.r = nil + # prc.loc.r = mangleName(m, prc) + useHeader(m, prc) + genProcPrototype(m, prc) + genProcAux(m, prc) elif lfDynamicLib in prc.loc.flags: var q = findPendingModule(m, prc) + fillProcLoc(q, prc) + useHeader(m, prc) + genProcPrototype(m, prc) if q != nil and not containsOrIncl(q.declaredThings, prc.id): symInDynamicLib(q, prc) else: symInDynamicLibPartial(m, prc) elif sfImportc notin prc.flags: var q = findPendingModule(m, prc) + fillProcLoc(q, prc) + useHeader(m, prc) + genProcPrototype(m, prc) if q != nil and not containsOrIncl(q.declaredThings, prc.id): genProcAux(q, prc) + else: + fillProcLoc(m, prc) proc requestConstImpl(p: BProc, sym: PSym) = var m = p.module @@ -772,8 +792,9 @@ proc isActivated(prc: PSym): bool = prc.typ != nil proc genProc(m: BModule, prc: PSym) = if sfBorrow in prc.flags or not isActivated(prc): return - fillProcLoc(m, prc) - if sfForward in prc.flags: addForwardedProc(m, prc) + if sfForward in prc.flags: + addForwardedProc(m, prc) + fillProcLoc(m, prc) else: genProcNoForward(m, prc) if {sfExportc, sfCompilerProc} * prc.flags == {sfExportc} and diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index 04b3d7a340..02a548f875 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -175,6 +175,8 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = c.hashType s.typ, flags else: c &= t.id + if t.len > 0 and t.sons[0] != nil: + hashType c, t.sons[0], flags of tyRef, tyPtr, tyGenericBody, tyVar: c.hashType t.lastSon, flags if tfVarIsPtr in t.flags: c &= ".varisptr" @@ -267,6 +269,17 @@ proc hashProc*(s: PSym): SigHash = #c &= s.info.line md5Final c, result.Md5Digest +proc hashNonProc*(s: PSym): SigHash = + var c: MD5Context + md5Init c + hashSym(c, s) + var it = s + while it != nil: + c &= it.name.s + c &= "." + it = it.owner + md5Final c, result.Md5Digest + proc hashOwner*(s: PSym): SigHash = var c: MD5Context md5Init c