diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index c9cbae2ec71cd..1ae17ec9b8741 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -2549,10 +2549,13 @@ void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name, Asm->emitDwarfLengthOrOffset(TheU->getLength()); // Emit the pubnames for this compilation unit. - for (const auto &GI : Globals) { - const char *Name = GI.getKeyData(); - const DIE *Entity = GI.second; - + SmallVector, 0> Vec; + for (const auto &GI : Globals) + Vec.emplace_back(GI.first(), GI.second); + llvm::sort(Vec, [](auto &A, auto &B) { + return A.second->getOffset() < B.second->getOffset(); + }); + for (const auto &[Name, Entity] : Vec) { Asm->OutStreamer->AddComment("DIE offset"); Asm->emitDwarfLengthOrOffset(Entity->getOffset()); @@ -2565,7 +2568,7 @@ void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name, } Asm->OutStreamer->AddComment("External Name"); - Asm->OutStreamer->emitBytes(StringRef(Name, GI.getKeyLength() + 1)); + Asm->OutStreamer->emitBytes(StringRef(Name.data(), Name.size() + 1)); } Asm->OutStreamer->AddComment("End Mark"); diff --git a/llvm/test/DebugInfo/X86/debug-pubtables-dwarf64.ll b/llvm/test/DebugInfo/X86/debug-pubtables-dwarf64.ll index 8fa46a82f6abe..5ac3551e68d35 100644 --- a/llvm/test/DebugInfo/X86/debug-pubtables-dwarf64.ll +++ b/llvm/test/DebugInfo/X86/debug-pubtables-dwarf64.ll @@ -19,8 +19,8 @@ ; CHECK: .debug_pubtypes contents: ; CHECK-NEXT: length = 0x0000000000000032, format = DWARF64, version = 0x0002, unit_offset = ; CHECK-NEXT: Offset Name -; CHECK-NEXT: 0x00000000[[BASET]] "int" ; CHECK-NEXT: 0x00000000[[STRUCT]] "Foo" +; CHECK-NEXT: 0x00000000[[BASET]] "int" ; IR generated and reduced from: ; $ cat foo.c diff --git a/llvm/test/DebugInfo/X86/gnu-public-names-gmlt.ll b/llvm/test/DebugInfo/X86/gnu-public-names-gmlt.ll index e46e2cf38b734..3984ad40f114f 100644 --- a/llvm/test/DebugInfo/X86/gnu-public-names-gmlt.ll +++ b/llvm/test/DebugInfo/X86/gnu-public-names-gmlt.ll @@ -17,8 +17,8 @@ ; GPUB: .debug_gnu_pubnames contents: ; GPUB-NEXT: unit_offset = 0x00000000 ; GPUB-NEXT: Name -; GPUB-NEXT: "f3" ; GPUB-NEXT: "f2" +; GPUB-NEXT: "f3" ; GPUB: .debug_gnu_pubtypes contents: ; GPUB-NEXT: length = 0x0000000e, format = DWARF32, version = 0x0002, unit_offset = 0x00000000 diff --git a/llvm/test/DebugInfo/X86/gnu-public-names-tu.ll b/llvm/test/DebugInfo/X86/gnu-public-names-tu.ll index 46bf89ced3350..7037d6bab7d6b 100644 --- a/llvm/test/DebugInfo/X86/gnu-public-names-tu.ll +++ b/llvm/test/DebugInfo/X86/gnu-public-names-tu.ll @@ -25,8 +25,8 @@ ; CHECK-LABEL: debug_gnu_pubtypes contents: ; CHECK-NEXT: length = {{.*}}, version = 0x0002, unit_offset = 0x00000000, unit_size = {{.*}} ; CHECK-NEXT: Offset Linkage Kind Name -; CHECK-NEXT: [[BAR]] EXTERNAL TYPE "bar" ; CHECK-NEXT: [[CU]] EXTERNAL TYPE "ns::foo" +; CHECK-NEXT: [[BAR]] EXTERNAL TYPE "bar" %struct.bar = type { %"struct.ns::foo" } %"struct.ns::foo" = type { i8 } diff --git a/llvm/test/DebugInfo/X86/gnu-public-names.ll b/llvm/test/DebugInfo/X86/gnu-public-names.ll index a8d8dd4b95ca3..5dd6449c44bb0 100644 --- a/llvm/test/DebugInfo/X86/gnu-public-names.ll +++ b/llvm/test/DebugInfo/X86/gnu-public-names.ll @@ -66,9 +66,11 @@ ; ASM: .section .debug_gnu_pubnames ; ASM: .byte 32 # Attributes: VARIABLE, EXTERNAL -; ASM-NEXT: .asciz "ns::global_namespace_variable" # External Name +; ASM-NEXT: .asciz "C::static_member_variable" # External Name ; ASM: .byte 32 # Attributes: VARIABLE, EXTERNAL ; ASM-NEXT: .asciz "global_variable" # External Name +; ASM: .byte 32 # Attributes: VARIABLE, EXTERNAL +; ASM-NEXT: .asciz "ns::global_namespace_variable" # External Name ; ASM: .section .debug_gnu_pubtypes ; ASM: .byte 16 # Attributes: TYPE, EXTERNAL @@ -196,42 +198,42 @@ ; CHECK-LABEL: .debug_gnu_pubnames contents: ; CHECK-NEXT: length = {{.*}}, version = 0x0002, unit_offset = 0x00000000, unit_size = {{.*}} ; CHECK-NEXT: Offset Linkage Kind Name -; CHECK-NEXT: [[ANON_INNER_B]] STATIC VARIABLE "(anonymous namespace)::inner::b" -; CHECK-NEXT: [[MEM_FUNC]] EXTERNAL FUNCTION "C::member_function" -; CHECK-NEXT: [[OUTER]] EXTERNAL TYPE "outer" -; CHECK-NEXT: [[GLOB_NS_VAR]] EXTERNAL VARIABLE "ns::global_namespace_variable" +; CHECK-NEXT: [[STATIC_MEM_VAR]] EXTERNAL VARIABLE "C::static_member_variable" ; CHECK-NEXT: [[GLOB_VAR]] EXTERNAL VARIABLE "global_variable" -; CHECK-NEXT: [[UNNAMED_ENUM_ENUMERATOR]] STATIC VARIABLE "unnamed_enum_enumerator" -; CHECK-NEXT: [[GLOBAL_F7]] EXTERNAL FUNCTION "f7" -; CHECK-NEXT: [[OUTER_ANON]] EXTERNAL TYPE "outer::(anonymous namespace)" -; FIXME: GCC produces enumerators as EXTERNAL, not STATIC -; CHECK-NEXT: [[NAMED_ENUM_CLASS_ENUMERATOR]] STATIC VARIABLE "named_enum_class_enumerator" -; CHECK-NEXT: [[GLOBAL_FUNC]] EXTERNAL FUNCTION "global_function" -; CHECK-NEXT: [[GLOB_NS_FUNC]] EXTERNAL FUNCTION "ns::global_namespace_function" ; CHECK-NEXT: [[NS]] EXTERNAL TYPE "ns" -; CHECK-NEXT: [[NAMED_ENUM_ENUMERATOR]] STATIC VARIABLE "named_enum_enumerator" -; CHECK-NEXT: [[ANON]] EXTERNAL TYPE "(anonymous namespace)" -; CHECK-NEXT: [[OUTER_ANON_C]] STATIC VARIABLE "outer::(anonymous namespace)::c" +; CHECK-NEXT: [[GLOB_NS_VAR]] EXTERNAL VARIABLE "ns::global_namespace_variable" ; CHECK-NEXT: [[D_VAR]] EXTERNAL VARIABLE "ns::d" -; CHECK-NEXT: [[STATIC_MEM_FUNC]] EXTERNAL FUNCTION "C::static_member_function" -; CHECK-NEXT: [[STATIC_MEM_VAR]] EXTERNAL VARIABLE "C::static_member_variable" -; CHECK-NEXT: [[ANON_I]] STATIC VARIABLE "(anonymous namespace)::i" -; CHECK-NEXT: [[ANON_INNER]] EXTERNAL TYPE "(anonymous namespace)::inner" +; CHECK-NEXT: [[GLOB_NS_FUNC]] EXTERNAL FUNCTION "ns::global_namespace_function" ; CHECK-NEXT: [[F3]] EXTERNAL FUNCTION "f3" ; GCC Doesn't put local statics in pubnames, but it seems not unreasonable and ; comes out naturally from LLVM's implementation, so I'm OK with it for now. If ; it's demonstrated that this is a major size concern or degrades debug info ; consumer behavior, feel free to change it. ; CHECK-NEXT: [[F3_Z]] STATIC VARIABLE "f3::z" +; CHECK-NEXT: [[ANON]] EXTERNAL TYPE "(anonymous namespace)" +; CHECK-NEXT: [[ANON_I]] STATIC VARIABLE "(anonymous namespace)::i" +; CHECK-NEXT: [[ANON_INNER]] EXTERNAL TYPE "(anonymous namespace)::inner" +; CHECK-NEXT: [[ANON_INNER_B]] STATIC VARIABLE "(anonymous namespace)::inner::b" +; CHECK-NEXT: [[OUTER]] EXTERNAL TYPE "outer" +; CHECK-NEXT: [[OUTER_ANON]] EXTERNAL TYPE "outer::(anonymous namespace)" +; CHECK-NEXT: [[OUTER_ANON_C]] STATIC VARIABLE "outer::(anonymous namespace)::c" +; CHECK-NEXT: [[UNNAMED_ENUM_ENUMERATOR]] STATIC VARIABLE "unnamed_enum_enumerator" +; CHECK-NEXT: [[NAMED_ENUM_ENUMERATOR]] STATIC VARIABLE "named_enum_enumerator" +; CHECK-NEXT: [[NAMED_ENUM_CLASS_ENUMERATOR]] STATIC VARIABLE "named_enum_class_enumerator" +; CHECK-NEXT: [[MEM_FUNC]] EXTERNAL FUNCTION "C::member_function" +; CHECK-NEXT: [[STATIC_MEM_FUNC]] EXTERNAL FUNCTION "C::static_member_function" +; FIXME: GCC produces enumerators as EXTERNAL, not STATIC +; CHECK-NEXT: [[GLOBAL_FUNC]] EXTERNAL FUNCTION "global_function" +; CHECK-NEXT: [[GLOBAL_F7]] EXTERNAL FUNCTION "f7" ; CHECK-LABEL: debug_gnu_pubtypes contents: ; CHECK: Offset Linkage Kind Name -; CHECK-NEXT: [[INT]] STATIC TYPE "int" ; CHECK-NEXT: [[C]] EXTERNAL TYPE "C" +; CHECK-NEXT: [[INT]] STATIC TYPE "int" +; CHECK-NEXT: [[D]] EXTERNAL TYPE "ns::D" ; CHECK-NEXT: [[UNSIGNED_INT]] STATIC TYPE "unsigned int" ; CHECK-NEXT: [[NAMED_ENUM]] EXTERNAL TYPE "named_enum" ; CHECK-NEXT: [[NAMED_ENUM_CLASS]] EXTERNAL TYPE "named_enum_class" -; CHECK-NEXT: [[D]] EXTERNAL TYPE "ns::D" %struct.C = type { i8 } %"struct.ns::D" = type { i32 }