Skip to content

Commit ca715de

Browse files
[llvm][DebugInfo] Add DW_AT_type to DW_TAG_enumeration_type in non-strict DWARF v2 mode (#98335)
During testing of #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.
1 parent 6dc2c3d commit ca715de

File tree

4 files changed

+37
-21
lines changed

4 files changed

+37
-21
lines changed

llvm/docs/ReleaseNotes.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,13 @@ Changes to the Debug Info
319319
supported on a best-effort basis from here onwards; for more information, see
320320
the `migration docs <https://llvm.org/docs/RemoveDIsDebugInfo.html>`_.
321321

322+
* When emitting DWARF v2 and not in strict DWARF mode, LLVM will now add
323+
a ``DW_AT_type`` to instances of ``DW_TAG_enumeration_type``. This is actually
324+
a DWARF v3 feature which tells tools what the enum's underlying type is.
325+
Emitting this for v2 as well will help users who have to build binaries with
326+
DWARF v2 but are using tools that understand newer DWARF standards. Older
327+
tools will ignore it. (`#98335 <https://github.com/llvm/llvm-project/pull/98335>`_)
328+
322329
Changes to the LLVM tools
323330
---------------------------------
324331
* llvm-nm and llvm-objdump can now print symbol information from linked

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1585,7 +1585,7 @@ void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
15851585
const DIType *DTy = CTy->getBaseType();
15861586
bool IsUnsigned = DTy && DD->isUnsignedDIType(DTy);
15871587
if (DTy) {
1588-
if (DD->getDwarfVersion() >= 3)
1588+
if (!Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= 3)
15891589
addType(Buffer, DTy);
15901590
if (DD->getDwarfVersion() >= 4 && (CTy->getFlags() & DINode::FlagEnumClass))
15911591
addFlag(Buffer, dwarf::DW_AT_enum_class);

llvm/test/DebugInfo/Generic/debug-info-enum.ll

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22
; * test value representation for each possible underlying integer type
33
; * test the integer type is as expected
44
; * test the DW_AT_enum_class attribute is present (resp. absent) as expected.
5+
; * test that DW_AT_type is present for v3 and greater, and v2 when strict DWARF
6+
; is not enabled.
57

68
; RUN: llc -debugger-tune=gdb -dwarf-version=4 -filetype=obj -o %t.o < %s
7-
; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DW4
9+
; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefixes=CHECK,CHECK-DW4,CHECK-TYPE
10+
; RUN: llc -debugger-tune=gdb -dwarf-version=3 -filetype=obj -o %t.o < %s
11+
; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefixes=CHECK,CHECK-TYPE
812
; RUN: llc -debugger-tune=gdb -dwarf-version=2 -filetype=obj -o %t.o < %s
9-
; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DW2
13+
; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefixes=CHECK,CHECK-TYPE
14+
; RUN: llc -debugger-tune=gdb -dwarf-version=2 -strict-dwarf=true -filetype=obj -o %t.o < %s
15+
; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefixes=CHECK,CHECK-DW2-STRICT
1016

1117
@x0 = global i8 0, align 1, !dbg !0
1218
@x1 = global i8 0, align 1, !dbg !46
@@ -34,8 +40,8 @@
3440
!8 = !DIEnumerator(name: "A0", value: -128)
3541
!9 = !DIEnumerator(name: "B0", value: 127)
3642
; CHECK: DW_TAG_enumeration_type
37-
; CHECK-DW2-NOT: DW_AT_type
38-
; CHECK-DW4: DW_AT_type{{.*}}"signed char"
43+
; CHECK-DW2-STRICT-NOT: DW_AT_type
44+
; CHECK-TYPE: DW_AT_type{{.*}}"signed char"
3945
; CHECK-DW4: DW_AT_enum_class (true)
4046
; CHECK: DW_AT_name ("E0")
4147
; CHECK: DW_TAG_enumerator
@@ -51,8 +57,8 @@
5157
!12 = !{!13}
5258
!13 = !DIEnumerator(name: "A1", value: 255, isUnsigned: true)
5359
; CHECK: DW_TAG_enumeration_type
54-
; CHECK-DW2-NOT: DW_AT_type
55-
; CHECK-DW4: DW_AT_type{{.*}}"unsigned char"
60+
; CHECK-DW2-STRICT-NOT: DW_AT_type
61+
; CHECK-TYPE: DW_AT_type{{.*}}"unsigned char"
5662
; CHECK-DW4: DW_AT_enum_class (true)
5763
; CHECK: DW_AT_name ("E1")
5864
; CHECK: DW_TAG_enumerator
@@ -66,8 +72,8 @@
6672
!17 = !DIEnumerator(name: "A2", value: -32768)
6773
!18 = !DIEnumerator(name: "B2", value: 32767)
6874
; CHECK: DW_TAG_enumeration_type
69-
; CHECK-DW2-NOT: DW_AT_type
70-
; CHECK-DW4: DW_AT_type{{.*}} "short"
75+
; CHECK-DW2-STRICT-NOT: DW_AT_type
76+
; CHECK-TYPE: DW_AT_type{{.*}} "short"
7177
; CHECK-DW4: DW_AT_enum_class (true)
7278
; CHECK: DW_AT_name ("E2")
7379
; CHECK: DW_TAG_enumerator
@@ -83,8 +89,8 @@
8389
!21 = !{!22}
8490
!22 = !DIEnumerator(name: "A3", value: 65535, isUnsigned: true)
8591
; CHECK: DW_TAG_enumeration_type
86-
; CHECK-DW2-NOT: DW_AT_type
87-
; CHECK-DW4: DW_AT_type{{.*}}"unsigned short"
92+
; CHECK-DW2-STRICT-NOT: DW_AT_type
93+
; CHECK-TYPE DW_AT_type{{.*}}"unsigned short"
8894
; CHECK-DW4: DW_AT_enum_class (true)
8995
; CHECK: DW_AT_name ("E3")
9096
; CHECK: DW_TAG_enumerator
@@ -98,8 +104,8 @@
98104
!26 = !DIEnumerator(name: "A4", value: -2147483648)
99105
!27 = !DIEnumerator(name: "B4", value: 2147483647)
100106
; CHECK: DW_TAG_enumeration_type
101-
; CHECK-DW2-NOT: DW_AT_type
102-
; CHECK-DW4: DW_AT_type{{.*}}"int"
107+
; CHECK-DW2-STRICT-NOT: DW_AT_type
108+
; CHECK-TYPE: DW_AT_type{{.*}}"int"
103109
; CHECK-DW4: DW_AT_enum_class (true)
104110
; CHECK: DW_AT_name ("E4")
105111
; CHECK: DW_TAG_enumerator
@@ -115,8 +121,8 @@
115121
!30 = !{!31}
116122
!31 = !DIEnumerator(name: "A5", value: 4294967295, isUnsigned: true)
117123
; CHECK: DW_TAG_enumeration_type
118-
; CHECK-DW2-NOT: DW_AT_type
119-
; CHECK-DW4: DW_AT_type{{.*}}"unsigned int"
124+
; CHECK-DW2-STRICT-NOT: DW_AT_type
125+
; CHECK-TYPE: DW_AT_type{{.*}}"unsigned int"
120126
; CHECK-DW4: DW_AT_enum_class (true)
121127
; CHECK: DW_AT_name ("E5")
122128
; CHECK: DW_TAG_enumerator
@@ -130,8 +136,8 @@
130136
!35 = !DIEnumerator(name: "A6", value: -9223372036854775808)
131137
!36 = !DIEnumerator(name: "B6", value: 9223372036854775807)
132138
; CHECK: DW_TAG_enumeration_type
133-
; CHECK-DW2-NOT: DW_AT_type
134-
; CHECK-DW4: DW_AT_type{{.*}}"long long int"
139+
; CHECK-DW2-STRICT-NOT: DW_AT_type
140+
; CHECK-TYPE: DW_AT_type{{.*}}"long long int"
135141
; CHECK-DW4: DW_AT_enum_class (true)
136142
; CHECK: DW_AT_name ("E6")
137143
; CHECK: DW_TAG_enumerator
@@ -147,8 +153,8 @@
147153
!39 = !{!40}
148154
!40 = !DIEnumerator(name: "A7", value: 18446744073709551615, isUnsigned: true)
149155
; CHECK: DW_TAG_enumeration_type
150-
; CHECK-DW2-NOT: DW_AT_type
151-
; CHECK-DW4: DW_AT_type{{.*}}"long long unsigned int"
156+
; CHECK-DW2-STRICT-NOT: DW_AT_type
157+
; CHECK-TYPE: DW_AT_type{{.*}}"long long unsigned int"
152158
; CHECK-DW4: DW_AT_enum_class (true)
153159
; CHECK: DW_AT_name ("E7")
154160
; CHECK: DW_TAG_enumerator
@@ -163,8 +169,8 @@
163169
!43 = !DIEnumerator(name: "A8", value: -128)
164170
!44 = !DIEnumerator(name: "B8", value: 127)
165171
; CHECK: DW_TAG_enumeration_type
166-
; CHECK-DW2-NOT: DW_AT_type
167-
; CHECK-DW4: DW_AT_type{{.*}}"int"
172+
; CHECK-DW2-STRICT-NOT: DW_AT_type
173+
; CHECK-TYPE: DW_AT_type{{.*}}"int"
168174
; CHECK-NOT: DW_AT_enum_class
169175
; CHECK: DW_AT_name ("E8")
170176

llvm/test/DebugInfo/X86/dbg-rust-valid-enum-as-scope.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
; CHECK: DW_AT_language (DW_LANG_Rust)
44
; CHECK: DW_TAG_namespace
55
; CHECK: DW_TAG_enumeration_type
6+
; CHECK: DW_AT_type (0x{{[0-9A-Fa-f]+}} "u8")
67
; CHECK: DW_AT_name ("E")
78
; CHECK: DW_TAG_enumerator
89
; CHECK: DW_TAG_enumerator
@@ -12,6 +13,8 @@
1213
; CHECK: NULL
1314
; CHECK: NULL
1415
; CHECK: NULL
16+
; CHECK: DW_TAG_base_type
17+
; CHECK: DW_AT_name ("u8")
1518
; CHECK: DW_TAG_pointer_type
1619
; CHECK: NULL
1720

0 commit comments

Comments
 (0)