[llvm] [llvm][DebugInfo] Add DW_AT_type to DW_TAG_enumeration_type in non-strict DWARF v2 mode (PR #98335)
David Spickett via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 10 09:08:36 PDT 2024
https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/98335
>From 3ca12bb1f08afdc42b669b4b2c157a8877071a5a Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Wed, 10 Jul 2024 13:38:07 +0000
Subject: [PATCH 1/2] [llvm][DebugInfo] Add DW_AT_type to
DW_TAG_enumeration_type in non-strict DWARF v2 mode
During testing of https://github.com/llvm/llvm-project/pull/96202 we found that
when clang set to DWARF v2 was used to build the test file, lldb could not tell
that the unsigned enum type was in fact unsigned. So it defaulted to signed and
printed the wrong value.
The reason for this is that DWARFv2 does not include DW_AT_type in DW_TAG_enumeration_type.
This was added in DWARF v3:
"The enumeration type entry may also have a DW_AT_type attribute which refers to the
underlying data type used to implement the enumeration.
In C or C++, the underlying type will be the appropriate integral type determined by the
compiler from the properties of the enumeration literal values."
I noticed that gcc does emit this attribute for DWARF v2 but not when strict
DWARF is requested (more details in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=16063#c7).
This patch changes to clang to do the same. This will improve the experience of anyone
using tools that can understand the attribute but for whatever reason are stuck
building binaries containing v2 only.
You can see a current clang/gcc comparison here: https://godbolt.org/z/eG9Kc9WGf
https://reviews.llvm.org/D42734 added the original code that emitted this
for >= v3 only.
---
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 2 +-
.../test/DebugInfo/Generic/debug-info-enum.ll | 46 +++++++++++--------
.../X86/dbg-rust-valid-enum-as-scope.ll | 3 ++
3 files changed, 30 insertions(+), 21 deletions(-)
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 6c04fa1c67a95..e76b0fe2081c0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1585,7 +1585,7 @@ void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
const DIType *DTy = CTy->getBaseType();
bool IsUnsigned = DTy && DD->isUnsignedDIType(DTy);
if (DTy) {
- if (DD->getDwarfVersion() >= 3)
+ if (!Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= 3)
addType(Buffer, DTy);
if (DD->getDwarfVersion() >= 4 && (CTy->getFlags() & DINode::FlagEnumClass))
addFlag(Buffer, dwarf::DW_AT_enum_class);
diff --git a/llvm/test/DebugInfo/Generic/debug-info-enum.ll b/llvm/test/DebugInfo/Generic/debug-info-enum.ll
index 85e22931a5fc1..9af465d59b7d9 100644
--- a/llvm/test/DebugInfo/Generic/debug-info-enum.ll
+++ b/llvm/test/DebugInfo/Generic/debug-info-enum.ll
@@ -2,11 +2,17 @@
; * test value representation for each possible underlying integer type
; * test the integer type is as expected
; * test the DW_AT_enum_class attribute is present (resp. absent) as expected.
+; * test that DW_AT_type is present for v3 and greater, and v2 when strict DWARF
+; is not enabled.
; RUN: llc -debugger-tune=gdb -dwarf-version=4 -filetype=obj -o %t.o < %s
-; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DW4
+; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefixes=CHECK,CHECK-DW4,CHECK-TYPE
+; RUN: llc -debugger-tune=gdb -dwarf-version=3 -filetype=obj -o %t.o < %s
+; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefixes=CHECK,CHECK-TYPE
; RUN: llc -debugger-tune=gdb -dwarf-version=2 -filetype=obj -o %t.o < %s
-; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DW2
+; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefixes=CHECK,CHECK-TYPE
+; RUN: llc -debugger-tune=gdb -dwarf-version=2 -strict-dwarf=true -filetype=obj -o %t.o < %s
+; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefixes=CHECK,CHECK-DW2-STRICT
@x0 = global i8 0, align 1, !dbg !0
@x1 = global i8 0, align 1, !dbg !46
@@ -34,8 +40,8 @@
!8 = !DIEnumerator(name: "A0", value: -128)
!9 = !DIEnumerator(name: "B0", value: 127)
; CHECK: DW_TAG_enumeration_type
-; CHECK-DW2-NOT: DW_AT_type
-; CHECK-DW4: DW_AT_type{{.*}}"signed char"
+; CHECK-DW2-STRICT-NOT: DW_AT_type
+; CHECK-TYPE: DW_AT_type{{.*}}"signed char"
; CHECK-DW4: DW_AT_enum_class (true)
; CHECK: DW_AT_name ("E0")
; CHECK: DW_TAG_enumerator
@@ -51,8 +57,8 @@
!12 = !{!13}
!13 = !DIEnumerator(name: "A1", value: 255, isUnsigned: true)
; CHECK: DW_TAG_enumeration_type
-; CHECK-DW2-NOT: DW_AT_type
-; CHECK-DW4: DW_AT_type{{.*}}"unsigned char"
+; CHECK-DW2-STRICT-NOT: DW_AT_type
+; CHECK-TYPE: DW_AT_type{{.*}}"unsigned char"
; CHECK-DW4: DW_AT_enum_class (true)
; CHECK: DW_AT_name ("E1")
; CHECK: DW_TAG_enumerator
@@ -66,8 +72,8 @@
!17 = !DIEnumerator(name: "A2", value: -32768)
!18 = !DIEnumerator(name: "B2", value: 32767)
; CHECK: DW_TAG_enumeration_type
-; CHECK-DW2-NOT: DW_AT_type
-; CHECK-DW4: DW_AT_type{{.*}} "short"
+; CHECK-DW2-STRICT-NOT: DW_AT_type
+; CHECK-TYPE: DW_AT_type{{.*}} "short"
; CHECK-DW4: DW_AT_enum_class (true)
; CHECK: DW_AT_name ("E2")
; CHECK: DW_TAG_enumerator
@@ -83,8 +89,8 @@
!21 = !{!22}
!22 = !DIEnumerator(name: "A3", value: 65535, isUnsigned: true)
; CHECK: DW_TAG_enumeration_type
-; CHECK-DW2-NOT: DW_AT_type
-; CHECK-DW4: DW_AT_type{{.*}}"unsigned short"
+; CHECK-DW2-STRICT-NOT: DW_AT_type
+; CHECK-TYPE DW_AT_type{{.*}}"unsigned short"
; CHECK-DW4: DW_AT_enum_class (true)
; CHECK: DW_AT_name ("E3")
; CHECK: DW_TAG_enumerator
@@ -98,8 +104,8 @@
!26 = !DIEnumerator(name: "A4", value: -2147483648)
!27 = !DIEnumerator(name: "B4", value: 2147483647)
; CHECK: DW_TAG_enumeration_type
-; CHECK-DW2-NOT: DW_AT_type
-; CHECK-DW4: DW_AT_type{{.*}}"int"
+; CHECK-DW2-STRICT-NOT: DW_AT_type
+; CHECK-TYPE: DW_AT_type{{.*}}"int"
; CHECK-DW4: DW_AT_enum_class (true)
; CHECK: DW_AT_name ("E4")
; CHECK: DW_TAG_enumerator
@@ -115,8 +121,8 @@
!30 = !{!31}
!31 = !DIEnumerator(name: "A5", value: 4294967295, isUnsigned: true)
; CHECK: DW_TAG_enumeration_type
-; CHECK-DW2-NOT: DW_AT_type
-; CHECK-DW4: DW_AT_type{{.*}}"unsigned int"
+; CHECK-DW2-STRICT-NOT: DW_AT_type
+; CHECK-TYPE: DW_AT_type{{.*}}"unsigned int"
; CHECK-DW4: DW_AT_enum_class (true)
; CHECK: DW_AT_name ("E5")
; CHECK: DW_TAG_enumerator
@@ -130,8 +136,8 @@
!35 = !DIEnumerator(name: "A6", value: -9223372036854775808)
!36 = !DIEnumerator(name: "B6", value: 9223372036854775807)
; CHECK: DW_TAG_enumeration_type
-; CHECK-DW2-NOT: DW_AT_type
-; CHECK-DW4: DW_AT_type{{.*}}"long long int"
+; CHECK-DW2-STRICT-NOT: DW_AT_type
+; CHECK-TYPE: DW_AT_type{{.*}}"long long int"
; CHECK-DW4: DW_AT_enum_class (true)
; CHECK: DW_AT_name ("E6")
; CHECK: DW_TAG_enumerator
@@ -147,8 +153,8 @@
!39 = !{!40}
!40 = !DIEnumerator(name: "A7", value: 18446744073709551615, isUnsigned: true)
; CHECK: DW_TAG_enumeration_type
-; CHECK-DW2-NOT: DW_AT_type
-; CHECK-DW4: DW_AT_type{{.*}}"long long unsigned int"
+; CHECK-DW2-STRICT-NOT: DW_AT_type
+; CHECK-TYPE: DW_AT_type{{.*}}"long long unsigned int"
; CHECK-DW4: DW_AT_enum_class (true)
; CHECK: DW_AT_name ("E7")
; CHECK: DW_TAG_enumerator
@@ -163,8 +169,8 @@
!43 = !DIEnumerator(name: "A8", value: -128)
!44 = !DIEnumerator(name: "B8", value: 127)
; CHECK: DW_TAG_enumeration_type
-; CHECK-DW2-NOT: DW_AT_type
-; CHECK-DW4: DW_AT_type{{.*}}"int"
+; CHECK-DW2-STRICT-NOT: DW_AT_type
+; CHECK-TYPE: DW_AT_type{{.*}}"int"
; CHECK-NOT: DW_AT_enum_class
; CHECK: DW_AT_name ("E8")
diff --git a/llvm/test/DebugInfo/X86/dbg-rust-valid-enum-as-scope.ll b/llvm/test/DebugInfo/X86/dbg-rust-valid-enum-as-scope.ll
index f44ca04e0fd96..a6f24081d63ee 100644
--- a/llvm/test/DebugInfo/X86/dbg-rust-valid-enum-as-scope.ll
+++ b/llvm/test/DebugInfo/X86/dbg-rust-valid-enum-as-scope.ll
@@ -3,6 +3,7 @@
; CHECK: DW_AT_language (DW_LANG_Rust)
; CHECK: DW_TAG_namespace
; CHECK: DW_TAG_enumeration_type
+; CHECK: DW_AT_type (0x{{[0-9]+}} "u8")
; CHECK: DW_AT_name ("E")
; CHECK: DW_TAG_enumerator
; CHECK: DW_TAG_enumerator
@@ -12,6 +13,8 @@
; CHECK: NULL
; CHECK: NULL
; CHECK: NULL
+; CHECK: DW_TAG_base_type
+; CHECK: DW_AT_name ("u8")
; CHECK: DW_TAG_pointer_type
; CHECK: NULL
>From 4646b9e8d988b482a7b0f2851c98ff23202c913d Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Wed, 10 Jul 2024 16:08:11 +0000
Subject: [PATCH 2/2] Expect hex not just 0-9
---
llvm/test/DebugInfo/X86/dbg-rust-valid-enum-as-scope.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/DebugInfo/X86/dbg-rust-valid-enum-as-scope.ll b/llvm/test/DebugInfo/X86/dbg-rust-valid-enum-as-scope.ll
index a6f24081d63ee..263cbeee2a01f 100644
--- a/llvm/test/DebugInfo/X86/dbg-rust-valid-enum-as-scope.ll
+++ b/llvm/test/DebugInfo/X86/dbg-rust-valid-enum-as-scope.ll
@@ -3,7 +3,7 @@
; CHECK: DW_AT_language (DW_LANG_Rust)
; CHECK: DW_TAG_namespace
; CHECK: DW_TAG_enumeration_type
-; CHECK: DW_AT_type (0x{{[0-9]+}} "u8")
+; CHECK: DW_AT_type (0x{{[0-9A-Fa-f]+}} "u8")
; CHECK: DW_AT_name ("E")
; CHECK: DW_TAG_enumerator
; CHECK: DW_TAG_enumerator
More information about the llvm-commits
mailing list