Description
As a part of #97085 which is itself a fix for #33172, @wesleywiser and I discovered that LLVM seems to be producing the incorrect debug information for no_mangle
statics on Windows.
For the following code:
#[no_mangle]
pub static TEST: u64 = 0xdeadbeef;
The correct debug information should not include a namespace. but it does:
S_GDATA32: [0002:000003D0], Type: T_UQUAD(0023), no_mangle_info::TEST
Here's the relevant LLVM IR which at least looks correct:
!25 = !DIGlobalVariableExpression(var: !26, expr: !DIExpression())
!26 = distinct !DIGlobalVariable(name: "TEST", scope: !27, file: !28, line: 20, type: !29, isLocal: false, isDefinition: true, align: 8)
!27 = !DINamespace(name: "no_mangle_info", scope: null)
!28 = !DIFile(filename: ".\\no_mangle-info.rs", directory: "C:\\Users\\ryanl\\Code\\rust\\src\\test\\debuginfo", checksumkind: CSK_SHA1, checksum: "cd1cbe539c7de2272a5b619eaa5fc983476c4229")
!29 = !DIDerivedType(tag: DW_TAG_typedef, name: "u64", file: !2, baseType: !30)
!30 = !DIBasicType(name: "unsigned __int64", size: 64, encoding: DW_ATE_unsigned)
This seems to be caused by an issue in LLVM which incorrectly walks the namespace hierarchy when building up statics.
Of particular suspicion is the following code in LVVM which seems to be switching on whether the code in question is fortran or not. The relevant code path for DWARF does not have such logic.
// For Fortran, the scoping portion is elided in its name so that we can
// reference the variable in the command line of the VS debugger.
std::string QualifiedName =
(moduleIsInFortran()) ? std::string(DIGV->getName())
: getFullyQualifiedName(Scope, DIGV->getName());
In order to fix this, we need to understand the logic inside of getFullyQualifiedName
and whether we can bail out early in the case of building a qualified name for a no_mangle
binding.