mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-15 07:43:26 +00:00
new name mangling scheme implemented
This commit is contained in:
@@ -116,13 +116,42 @@ proc mangleName(m: BModule; s: PSym): Rope =
|
||||
add(result, m.idOrSig(s))
|
||||
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 mangleName(p: BProc; s: PSym): Rope =
|
||||
assert s.kind in skLocalVars
|
||||
if sfGlobal in s.flags: return mangleName(p.module, s)
|
||||
if isKeyword(s.name): discard
|
||||
proc mangleLocalName(p: BProc; s: PSym): Rope =
|
||||
assert s.kind in skLocalVars+{skTemp}
|
||||
assert sfGlobal notin s.flags
|
||||
result = s.loc.r
|
||||
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
|
||||
irrelevantForBackend = {tyGenericBody, tyGenericInst, tyGenericInvocation,
|
||||
|
||||
@@ -14,7 +14,7 @@ import
|
||||
nversion, nimsets, msgs, securehash, bitsets, idents, lists, types,
|
||||
ccgutils, os, ropes, math, passes, rodread, wordrecg, treetab, cgmeth,
|
||||
condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases,
|
||||
lowerings, semparallel, tables
|
||||
lowerings, semparallel, tables, sets
|
||||
|
||||
import strutils except `%` # collides with ropes.`%`
|
||||
|
||||
@@ -369,7 +369,7 @@ proc localDebugInfo(p: BProc, s: PSym) =
|
||||
|
||||
proc localVarDecl(p: BProc; s: PSym): Rope =
|
||||
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)
|
||||
result = getTypeDesc(p.module, s.typ)
|
||||
if s.constraint.isNil:
|
||||
@@ -434,6 +434,7 @@ proc assignGlobalVar(p: BProc, s: PSym) =
|
||||
|
||||
proc assignParam(p: BProc, s: PSym) =
|
||||
assert(s.loc.r != nil)
|
||||
scopeMangledParam(p, s)
|
||||
localDebugInfo(p, s)
|
||||
|
||||
proc fillProcLoc(m: BModule; sym: PSym) =
|
||||
@@ -1212,13 +1213,13 @@ proc newModule(g: BModuleList; module: PSym): BModule =
|
||||
if (sfDeadCodeElim in module.flags):
|
||||
internalError("added pending module twice: " & module.filename)
|
||||
|
||||
template injectG() {.dirty.} =
|
||||
template injectG(config) {.dirty.} =
|
||||
if graph.backend == nil:
|
||||
graph.backend = newModuleList()
|
||||
graph.backend = newModuleList(config)
|
||||
let g = BModuleList(graph.backend)
|
||||
|
||||
proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
|
||||
injectG()
|
||||
injectG(graph.config)
|
||||
result = newModule(g, module)
|
||||
if optGenIndex in gGlobalOptions and g.generatedHeader == nil:
|
||||
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)
|
||||
|
||||
proc myOpenCached(graph: ModuleGraph; module: PSym, rd: PRodReader): PPassContext =
|
||||
injectG()
|
||||
injectG(graph.config)
|
||||
assert optSymbolFiles in gGlobalOptions
|
||||
var m = newModule(g, module)
|
||||
readMergeInfo(getCFile(m), m)
|
||||
|
||||
@@ -76,7 +76,7 @@ type
|
||||
# leaving such scopes by raise or by return must
|
||||
# execute any applicable finally blocks
|
||||
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
|
||||
blocks*: seq[TBlock] # nested blocks
|
||||
breakIdx*: int # the block that will be exited
|
||||
@@ -92,6 +92,7 @@ type
|
||||
# (yes, C++ is weird like that)
|
||||
gcFrameId*: Natural # for the GC stack marking
|
||||
gcFrameType*: Rope # the struct {} we put the GC markers into
|
||||
sigConflicts*: CountTable[string]
|
||||
|
||||
TTypeSeq* = seq[PType]
|
||||
TypeCache* = Table[SigHash, Rope]
|
||||
@@ -163,9 +164,10 @@ proc newProc*(prc: PSym, module: BModule): BProc =
|
||||
newSeq(result.blocks, 1)
|
||||
result.nestedTryStmts = @[]
|
||||
result.finallySafePoints = @[]
|
||||
result.sigConflicts = initCountTable[string]()
|
||||
|
||||
proc newModuleList*(): BModuleList =
|
||||
BModuleList(modules: @[], typeInfoMarker: initTable[SigHash, Rope]())
|
||||
proc newModuleList*(config: ConfigRef): BModuleList =
|
||||
BModuleList(modules: @[], typeInfoMarker: initTable[SigHash, Rope](), config: config)
|
||||
|
||||
iterator cgenModules*(g: BModuleList): BModule =
|
||||
for i in 0..high(g.modules):
|
||||
|
||||
@@ -665,9 +665,14 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||
of wExportc:
|
||||
makeExternExport(sym, getOptionalStr(c, it, "$1"), it.info)
|
||||
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:
|
||||
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 wImmediate:
|
||||
if sym.kind in {skTemplate, skMacro}:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
discard """
|
||||
output: "1"
|
||||
cmd: r"nim c --hints:on $options -d:release $file"
|
||||
ccodecheck: "'NI volatile state0;'"
|
||||
ccodecheck: "'NI volatile state;'"
|
||||
"""
|
||||
|
||||
# bug #1539
|
||||
|
||||
Reference in New Issue
Block a user