fixes #25263; provides a new switch mangle:nim/cpp for debug name mangling (#25264)

fixes #25263

- [x] documentation and changelogs
This commit is contained in:
ringabout
2025-11-06 23:41:13 +08:00
committed by araq
parent 43ff7b1dc4
commit 116c220e3f
7 changed files with 215 additions and 3 deletions

View File

@@ -27,6 +27,8 @@ errors.
- With `-d:nimPreviewDuplicateModuleError`, importing two modules that share the same name becomes a compile-time error. This includes importing the same module more than once. Use `import foo as foo1` (or other aliases) to avoid collisions.
- Adds the switch `--mangle:nim|cpp`, which selects `nim` or `cpp` style name mangling when used with `debuginfo` on, defaults to `nim`. The default is changed from `cpp` to `nim`.
## Standard library additions and changes
[//]: # "Additions:"

View File

@@ -75,7 +75,7 @@ proc mangleProc(m: BModule; s: PSym; makeUnique: bool): string =
proc fillBackendName(m: BModule; s: PSym) =
if s.loc.snippet == "":
var result: Rope
if not m.compileToCpp and s.kind in routineKinds and optCDebug in m.g.config.globalOptions and
if s.kind in routineKinds and {optCDebug, optItaniumMangle} * m.g.config.globalOptions == {optCDebug, optItaniumMangle} and
m.g.config.symbolFiles == disabledSf:
result = mangleProc(m, s, false).rope
else:

View File

@@ -364,6 +364,7 @@ proc testCompileOption*(conf: ConfigRef; switch: string, info: TLineInfo): bool
result = false
of "panics": result = contains(conf.globalOptions, optPanics)
of "jsbigint64": result = contains(conf.globalOptions, optJsBigInt64)
of "mangle": result = contains(conf.globalOptions, optItaniumMangle)
else:
result = false
invalidCmdLineOption(conf, passCmd1, switch, info)
@@ -762,6 +763,14 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
conf.globalOptions.excl optCDebug
else:
localError(conf, info, "expected native|gdb|on|off but found " & arg)
of "mangle":
case arg.normalize
of "nim":
conf.globalOptions.excl optItaniumMangle
of "cpp":
conf.globalOptions.incl optItaniumMangle
else:
localError(conf, info, "expected nim|cpp but found " & arg)
of "g": # alias for --debugger:native
conf.globalOptions.incl optCDebug
conf.options.incl optLineDir

View File

@@ -110,6 +110,7 @@ type # please make sure we have under 32 options
optEnableDeepCopy # ORC specific: enable 'deepcopy' for all types.
optShowNonExportedFields # for documentation: show fields that are not exported
optJsBigInt64 # use bigints for 64-bit integers in JS
optItaniumMangle # mangling follows the Itanium spec
TGlobalOptions* = set[TGlobalOption]

View File

@@ -91,6 +91,7 @@ Advanced options:
--os:SYMBOL set the target operating system (cross-compilation)
--cpu:SYMBOL set the target processor (cross-compilation)
--debuginfo:on|off enables debug information
--mangle:nim|cpp selects `nim` or `cpp` style name mangling, defaults to `nim`
-t, --passC:OPTION pass an option to the C compiler
-l, --passL:OPTION pass an option to the linker
--cc:SYMBOL specify the C compiler

View File

@@ -1,6 +1,6 @@
discard """
targets: "c"
matrix: "--debugger:native"
targets: "c cpp"
matrix: "--debugger:native --mangle:cpp"
ccodecheck: "'_ZN14titaniummangle8testFuncE'"
ccodecheck: "'_ZN14titaniummangle8testFuncE6stringN14titaniummangle3FooE'"
ccodecheck: "'_ZN14titaniummangle8testFuncE3int7varargsI6stringE'"

View File

@@ -0,0 +1,199 @@
discard """
targets: "c"
matrix: "--debugger:native --mangle:nim; --debugger:native"
ccodecheck: "'testFunc__titaniummangle95nim_u1316'"
ccodecheck: "'testFunc__titaniummangle95nim_u156'"
ccodecheck: "'testFunc__titaniummangle95nim_u1305'"
ccodecheck: "'testFunc__titaniummangle95nim_u241'"
ccodecheck: "'testFunc__titaniummangle95nim_u1357'"
ccodecheck: "'testFunc__titaniummangle95nim_u292'"
ccodecheck: "'testFunc__titaniummangle95nim_u38'"
ccodecheck: "'testFunc__titaniummangle95nim_u175'"
ccodecheck: "'testFunc__titaniummangle95nim_u1302'"
ccodecheck: "'testFunc__titaniummangle95nim_u1305'"
ccodecheck: "'testFunc__titaniummangle95nim_u535'"
ccodecheck: "'testFunc__titaniummangle95nim_u1294'"
ccodecheck: "'testFunc__titaniummangle95nim_u336'"
ccodecheck: "'testFunc__titaniummangle95nim_u425'"
ccodecheck: "'testFunc__titaniummangle95nim_u308'"
ccodecheck: "'testFunc__titaniummangle95nim_u129'"
ccodecheck: "'testFunc__titaniummangle95nim_u320'"
ccodecheck: "'testFunc__titaniummangle95nim_u223'"
ccodecheck: "'testFunc__titaniummangle95nim_u545'"
ccodecheck: "'testFunc__titaniummangle95nim_u543'"
ccodecheck: "'testFunc__titaniummangle95nim_u895'"
ccodecheck: "'testFunc__titaniummangle95nim_u1104'"
ccodecheck: "'testFunc__titaniummangle95nim_u1155'"
ccodecheck: "'testFunc__titaniummangle95nim_u636'"
ccodecheck: "'testFunc__titaniummangle95nim_u705'"
ccodecheck: "'testFunc__titaniummangle95nim_u800'"
ccodecheck: "'new__titaniummangle95nim_u1320'"
ccodecheck: "'xxx__titaniummangle95nim_u1391'"
ccodecheck: "'xxx__titaniummangle95nim_u1394'"
"""
#When debugging this notice that if one check fails, it can be due to any of the above.
type
Comparable = concept x, y
(x < y) is bool
Foo = object
a: int32
b: int32
FooTuple = tuple
a: int
b: int
Container[T] = object
data: T
Container2[T, T2] = object
data: T
data2: T2
Boo = distinct Foo
Coo = Foo
Doo = Boo | Foo
TestProc = proc(a:string): string
type EnumSample = enum
a, b, c
type EnumAnotherSample = enum
a, b, c
proc testFunc(a: set[EnumSample]) =
echo $a
proc testFunc(a: typedesc) =
echo $a
proc testFunc(a: ptr Foo) =
echo repr a
proc testFunc(s: string, a: Coo) =
echo repr a
proc testFunc(s: int, a: Comparable) =
echo repr a
proc testFunc(a: TestProc) =
let b = ""
echo repr a("")
proc testFunc(a: ref Foo) =
echo repr a
proc testFunc(b: Boo) =
echo repr b
proc testFunc(a: ptr UncheckedArray[int]) =
echo repr a
proc testFunc(a: ptr int) =
echo repr a
proc testFunc(a: ptr ptr int) =
echo repr a
proc testFunc(e: FooTuple, str: cstring) =
echo e
proc testFunc(e: (float, float)) =
echo e
proc testFunc(e: EnumSample) =
echo e
proc testFunc(e: var int) =
echo e
proc testFunc(e: var Foo, a, b: int32, refFoo: ref Foo) =
echo e
proc testFunc(xs: Container[int]) =
let a = 2
echo xs
proc testFunc(xs: Container2[int32, int32]) =
let a = 2
echo xs
proc testFunc(xs: Container[Container2[int32, int32]]) =
let a = 2
echo xs
proc testFunc(xs: seq[int]) =
let a = 2
echo xs
proc testFunc(xs: openArray[string]) =
let a = 2
echo xs
proc testFunc(xs: array[2, int]) =
let a = 2
echo xs
proc testFunc(e: EnumAnotherSample) =
echo e
proc testFunc(a, b: int) =
echo "hola"
discard
proc testFunc(a: int, xs: varargs[string]) =
let a = 10
for x in xs:
echo x
proc xxx(v: static int) =
echo v
proc testFunc() =
var a = 2
var aPtr = a.addr
var foo = Foo()
let refFoo : ref Foo = new(Foo)
let b = Foo().Boo()
let d: Doo = Foo()
testFunc("", Coo())
testFunc(1, )
testFunc(b)
testFunc(EnumAnotherSample)
var t = [1, 2]
let uArr = cast[ptr UncheckedArray[int]](t.addr)
testFunc(uArr)
testFunc({})
testFunc(proc(s:string): string = "test")
testFunc(20, a.int32)
testFunc(20, 2)
testFunc(EnumSample.c)
testFunc(EnumAnotherSample.c)
testFunc((2, 1), "adios")
testFunc((22.1, 1.2))
testFunc(a.addr)
testFunc(foo.addr)
testFunc(aPtr.addr)
testFunc(refFoo)
testFunc(foo, 2, 1, refFoo)
testFunc(a)
testFunc(@[2, 1, 2])
testFunc(@["hola"])
testFunc(2, "hola", "adios")
let arr: array[2, int] = [2, 1]
testFunc(arr)
testFunc(Container[int](data: 10))
let c2 = Container2[int32, int32](data: 10, data2: 20)
testFunc(c2)
testFunc(Container[Container2[int32, int32]](data: c2))
xxx(10)
xxx(20)
testFunc()