new name mangling scheme implemented

This commit is contained in:
Andreas Rumpf 2017-02-02 10:30:01 +01:00
commit 56aa1ac5bc
5 changed files with 55 additions and 18 deletions

View file

@ -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,

View file

@ -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)

View file

@ -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):

View file

@ -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}:

View file

@ -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