new name mangling scheme implemented
This commit is contained in:
parent
d9cf9b079e
commit
56aa1ac5bc
5 changed files with 55 additions and 18 deletions
|
|
@ -116,13 +116,42 @@ proc mangleName(m: BModule; s: PSym): Rope =
|
||||||
add(result, m.idOrSig(s))
|
add(result, m.idOrSig(s))
|
||||||
s.loc.r = result
|
s.loc.r = result
|
||||||
|
|
||||||
template mangleParamName(m: BModule; s: PSym): Rope = mangleName(m, s)
|
proc mangleParamName(m: BModule; s: PSym): Rope =
|
||||||
|
## we cannot use 'sigConflicts' here since we have a BModule, not a BProc.
|
||||||
|
## Fortunately C's scoping rules are sane enough so that that doesn't
|
||||||
|
## cause any trouble.
|
||||||
|
result = s.loc.r
|
||||||
|
if result == nil:
|
||||||
|
result = s.name.s.mangle.rope
|
||||||
|
if isKeyword(s.name) or m.g.config.cppDefines.contains(s.name.s):
|
||||||
|
result.add "0"
|
||||||
|
s.loc.r = result
|
||||||
|
|
||||||
when false:
|
proc mangleLocalName(p: BProc; s: PSym): Rope =
|
||||||
proc mangleName(p: BProc; s: PSym): Rope =
|
assert s.kind in skLocalVars+{skTemp}
|
||||||
assert s.kind in skLocalVars
|
assert sfGlobal notin s.flags
|
||||||
if sfGlobal in s.flags: return mangleName(p.module, s)
|
result = s.loc.r
|
||||||
if isKeyword(s.name): discard
|
if result == nil:
|
||||||
|
var key = s.name.s.mangle
|
||||||
|
shallow(key)
|
||||||
|
let counter = p.sigConflicts.getOrDefault(key)
|
||||||
|
result = key.rope
|
||||||
|
if s.kind == skTemp:
|
||||||
|
# speed up conflict search for temps (these are quite common):
|
||||||
|
if counter != 0: result.add "_" & rope(counter+1)
|
||||||
|
elif counter != 0 or isKeyword(s.name) or p.module.g.config.cppDefines.contains(s.name.s):
|
||||||
|
result.add "_" & rope(counter+1)
|
||||||
|
p.sigConflicts.inc(key)
|
||||||
|
s.loc.r = result
|
||||||
|
|
||||||
|
proc scopeMangledParam(p: BProc; param: PSym) =
|
||||||
|
## parameter generation only takes BModule, not a BProc, so we have to
|
||||||
|
## remember these parameter names are already in scope to be able to
|
||||||
|
## generate unique identifiers reliably (consider that ``var a = a`` is
|
||||||
|
## even an idiom in Nim).
|
||||||
|
var key = param.name.s.mangle
|
||||||
|
shallow(key)
|
||||||
|
p.sigConflicts.inc(key)
|
||||||
|
|
||||||
const
|
const
|
||||||
irrelevantForBackend = {tyGenericBody, tyGenericInst, tyGenericInvocation,
|
irrelevantForBackend = {tyGenericBody, tyGenericInst, tyGenericInvocation,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import
|
||||||
nversion, nimsets, msgs, securehash, bitsets, idents, lists, types,
|
nversion, nimsets, msgs, securehash, bitsets, idents, lists, types,
|
||||||
ccgutils, os, ropes, math, passes, rodread, wordrecg, treetab, cgmeth,
|
ccgutils, os, ropes, math, passes, rodread, wordrecg, treetab, cgmeth,
|
||||||
condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases,
|
condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases,
|
||||||
lowerings, semparallel, tables
|
lowerings, semparallel, tables, sets
|
||||||
|
|
||||||
import strutils except `%` # collides with ropes.`%`
|
import strutils except `%` # collides with ropes.`%`
|
||||||
|
|
||||||
|
|
@ -369,7 +369,7 @@ proc localDebugInfo(p: BProc, s: PSym) =
|
||||||
|
|
||||||
proc localVarDecl(p: BProc; s: PSym): Rope =
|
proc localVarDecl(p: BProc; s: PSym): Rope =
|
||||||
if s.loc.k == locNone:
|
if s.loc.k == locNone:
|
||||||
fillLoc(s.loc, locLocalVar, s.typ, mangleName(p.module, s), OnStack)
|
fillLoc(s.loc, locLocalVar, s.typ, mangleLocalName(p, s), OnStack)
|
||||||
if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy)
|
if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy)
|
||||||
result = getTypeDesc(p.module, s.typ)
|
result = getTypeDesc(p.module, s.typ)
|
||||||
if s.constraint.isNil:
|
if s.constraint.isNil:
|
||||||
|
|
@ -434,6 +434,7 @@ proc assignGlobalVar(p: BProc, s: PSym) =
|
||||||
|
|
||||||
proc assignParam(p: BProc, s: PSym) =
|
proc assignParam(p: BProc, s: PSym) =
|
||||||
assert(s.loc.r != nil)
|
assert(s.loc.r != nil)
|
||||||
|
scopeMangledParam(p, s)
|
||||||
localDebugInfo(p, s)
|
localDebugInfo(p, s)
|
||||||
|
|
||||||
proc fillProcLoc(m: BModule; sym: PSym) =
|
proc fillProcLoc(m: BModule; sym: PSym) =
|
||||||
|
|
@ -1212,13 +1213,13 @@ proc newModule(g: BModuleList; module: PSym): BModule =
|
||||||
if (sfDeadCodeElim in module.flags):
|
if (sfDeadCodeElim in module.flags):
|
||||||
internalError("added pending module twice: " & module.filename)
|
internalError("added pending module twice: " & module.filename)
|
||||||
|
|
||||||
template injectG() {.dirty.} =
|
template injectG(config) {.dirty.} =
|
||||||
if graph.backend == nil:
|
if graph.backend == nil:
|
||||||
graph.backend = newModuleList()
|
graph.backend = newModuleList(config)
|
||||||
let g = BModuleList(graph.backend)
|
let g = BModuleList(graph.backend)
|
||||||
|
|
||||||
proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
|
proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
|
||||||
injectG()
|
injectG(graph.config)
|
||||||
result = newModule(g, module)
|
result = newModule(g, module)
|
||||||
if optGenIndex in gGlobalOptions and g.generatedHeader == nil:
|
if optGenIndex in gGlobalOptions and g.generatedHeader == nil:
|
||||||
let f = if graph.config.headerFile.len > 0: graph.config.headerFile else: gProjectFull
|
let f = if graph.config.headerFile.len > 0: graph.config.headerFile else: gProjectFull
|
||||||
|
|
@ -1258,7 +1259,7 @@ proc getCFile(m: BModule): string =
|
||||||
result = changeFileExt(completeCFilePath(m.cfilename.withPackageName), ext)
|
result = changeFileExt(completeCFilePath(m.cfilename.withPackageName), ext)
|
||||||
|
|
||||||
proc myOpenCached(graph: ModuleGraph; module: PSym, rd: PRodReader): PPassContext =
|
proc myOpenCached(graph: ModuleGraph; module: PSym, rd: PRodReader): PPassContext =
|
||||||
injectG()
|
injectG(graph.config)
|
||||||
assert optSymbolFiles in gGlobalOptions
|
assert optSymbolFiles in gGlobalOptions
|
||||||
var m = newModule(g, module)
|
var m = newModule(g, module)
|
||||||
readMergeInfo(getCFile(m), m)
|
readMergeInfo(getCFile(m), m)
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ type
|
||||||
# leaving such scopes by raise or by return must
|
# leaving such scopes by raise or by return must
|
||||||
# execute any applicable finally blocks
|
# execute any applicable finally blocks
|
||||||
finallySafePoints*: seq[Rope] # For correctly cleaning up exceptions when
|
finallySafePoints*: seq[Rope] # For correctly cleaning up exceptions when
|
||||||
# using return in finally statements
|
# using return in finally statements
|
||||||
labels*: Natural # for generating unique labels in the C proc
|
labels*: Natural # for generating unique labels in the C proc
|
||||||
blocks*: seq[TBlock] # nested blocks
|
blocks*: seq[TBlock] # nested blocks
|
||||||
breakIdx*: int # the block that will be exited
|
breakIdx*: int # the block that will be exited
|
||||||
|
|
@ -92,6 +92,7 @@ type
|
||||||
# (yes, C++ is weird like that)
|
# (yes, C++ is weird like that)
|
||||||
gcFrameId*: Natural # for the GC stack marking
|
gcFrameId*: Natural # for the GC stack marking
|
||||||
gcFrameType*: Rope # the struct {} we put the GC markers into
|
gcFrameType*: Rope # the struct {} we put the GC markers into
|
||||||
|
sigConflicts*: CountTable[string]
|
||||||
|
|
||||||
TTypeSeq* = seq[PType]
|
TTypeSeq* = seq[PType]
|
||||||
TypeCache* = Table[SigHash, Rope]
|
TypeCache* = Table[SigHash, Rope]
|
||||||
|
|
@ -163,9 +164,10 @@ proc newProc*(prc: PSym, module: BModule): BProc =
|
||||||
newSeq(result.blocks, 1)
|
newSeq(result.blocks, 1)
|
||||||
result.nestedTryStmts = @[]
|
result.nestedTryStmts = @[]
|
||||||
result.finallySafePoints = @[]
|
result.finallySafePoints = @[]
|
||||||
|
result.sigConflicts = initCountTable[string]()
|
||||||
|
|
||||||
proc newModuleList*(): BModuleList =
|
proc newModuleList*(config: ConfigRef): BModuleList =
|
||||||
BModuleList(modules: @[], typeInfoMarker: initTable[SigHash, Rope]())
|
BModuleList(modules: @[], typeInfoMarker: initTable[SigHash, Rope](), config: config)
|
||||||
|
|
||||||
iterator cgenModules*(g: BModuleList): BModule =
|
iterator cgenModules*(g: BModuleList): BModule =
|
||||||
for i in 0..high(g.modules):
|
for i in 0..high(g.modules):
|
||||||
|
|
|
||||||
|
|
@ -665,9 +665,14 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
of wExportc:
|
of wExportc:
|
||||||
makeExternExport(sym, getOptionalStr(c, it, "$1"), it.info)
|
makeExternExport(sym, getOptionalStr(c, it, "$1"), it.info)
|
||||||
incl(sym.flags, sfUsed) # avoid wrong hints
|
incl(sym.flags, sfUsed) # avoid wrong hints
|
||||||
of wImportc: makeExternImport(sym, getOptionalStr(c, it, "$1"), it.info)
|
of wImportc:
|
||||||
|
let name = getOptionalStr(c, it, "$1")
|
||||||
|
cppDefine(c.graph.config, name)
|
||||||
|
makeExternImport(sym, name, it.info)
|
||||||
of wImportCompilerProc:
|
of wImportCompilerProc:
|
||||||
processImportCompilerProc(sym, getOptionalStr(c, it, "$1"), it.info)
|
let name = getOptionalStr(c, it, "$1")
|
||||||
|
cppDefine(c.graph.config, name)
|
||||||
|
processImportCompilerProc(sym, name, it.info)
|
||||||
of wExtern: setExternName(sym, expectStrLit(c, it), it.info)
|
of wExtern: setExternName(sym, expectStrLit(c, it), it.info)
|
||||||
of wImmediate:
|
of wImmediate:
|
||||||
if sym.kind in {skTemplate, skMacro}:
|
if sym.kind in {skTemplate, skMacro}:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
output: "1"
|
output: "1"
|
||||||
cmd: r"nim c --hints:on $options -d:release $file"
|
cmd: r"nim c --hints:on $options -d:release $file"
|
||||||
ccodecheck: "'NI volatile state0;'"
|
ccodecheck: "'NI volatile state;'"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# bug #1539
|
# bug #1539
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue