Skip to content

Commit 909f429

Browse files
authored
[llvm][dwarfdump] Pretty-print DW_AT_language_version (#164222)
In both verbose and non-verbose mode we will now use the `llvm::dwarf::LanguageDescription` to turn the version into a human readable string. In verbose mode we also display the raw version code (similar to how we display addresses in verbose mode). To make the version code and prettified easier to distinguish, we print the prettified name in colour (if available), which is consistent with how `DW_AT_language` is printed in colour. Before: ``` 0x0000000c: DW_TAG_compile_unit DW_AT_language_name (DW_LNAME_C) DW_AT_language_version (201112) ``` After: ``` 0x0000000c: DW_TAG_compile_unit DW_AT_language_name (DW_LNAME_C) DW_AT_language_version (201112 C11) ```
1 parent 2bbc4ae commit 909f429

File tree

4 files changed

+108
-19
lines changed

4 files changed

+108
-19
lines changed

llvm/lib/DebugInfo/DWARF/DWARFDie.cpp

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,28 @@ static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
107107
return D.getAttributeValueAsReferencedDie(F).resolveTypeUnitReference();
108108
}
109109

110+
static llvm::StringRef
111+
prettyLanguageVersionString(const DWARFAttribute &AttrValue,
112+
const DWARFDie &Die) {
113+
if (AttrValue.Attr != DW_AT_language_version)
114+
return {};
115+
116+
auto NameForm = Die.find(DW_AT_language_name);
117+
if (!NameForm)
118+
return {};
119+
120+
auto LName = NameForm->getAsUnsignedConstant();
121+
if (!LName)
122+
return {};
123+
124+
auto LVersion = AttrValue.Value.getAsUnsignedConstant();
125+
if (!LVersion)
126+
return {};
127+
128+
return llvm::dwarf::LanguageDescription(
129+
static_cast<SourceLanguageName>(*LName), *LVersion);
130+
}
131+
110132
static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
111133
const DWARFAttribute &AttrValue, unsigned Indent,
112134
DIDumpOptions DumpOpts) {
@@ -146,15 +168,28 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
146168
} else if (std::optional<uint64_t> Val = FormValue.getAsUnsignedConstant())
147169
Name = AttributeValueString(Attr, *Val);
148170

149-
if (!Name.empty())
150-
WithColor(OS, Color) << Name;
151-
else if (Attr == DW_AT_decl_line || Attr == DW_AT_decl_column ||
152-
Attr == DW_AT_call_line || Attr == DW_AT_call_column ||
153-
Attr == DW_AT_language_version) {
171+
auto DumpUnsignedConstant = [&OS,
172+
&DumpOpts](const DWARFFormValue &FormValue) {
154173
if (std::optional<uint64_t> Val = FormValue.getAsUnsignedConstant())
155174
OS << *Val;
156175
else
157176
FormValue.dump(OS, DumpOpts);
177+
};
178+
179+
llvm::StringRef PrettyVersionName =
180+
prettyLanguageVersionString(AttrValue, Die);
181+
bool ShouldDumpRawLanguageVersion =
182+
Attr == DW_AT_language_version &&
183+
(DumpOpts.Verbose || PrettyVersionName.empty());
184+
185+
if (!Name.empty())
186+
WithColor(OS, Color) << Name;
187+
else if (Attr == DW_AT_decl_line || Attr == DW_AT_decl_column ||
188+
Attr == DW_AT_call_line || Attr == DW_AT_call_column) {
189+
DumpUnsignedConstant(FormValue);
190+
} else if (Attr == DW_AT_language_version) {
191+
if (ShouldDumpRawLanguageVersion)
192+
DumpUnsignedConstant(FormValue);
158193
} else if (Attr == DW_AT_low_pc &&
159194
(FormValue.getAsAddress() ==
160195
dwarf::computeTombstoneAddress(U->getAddressByteSize()))) {
@@ -226,6 +261,10 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
226261
DumpOpts.RecoverableErrorHandler(createStringError(
227262
errc::invalid_argument, "decoding address ranges: %s",
228263
toString(RangesOrError.takeError()).c_str()));
264+
} else if (Attr == DW_AT_language_version) {
265+
if (!PrettyVersionName.empty())
266+
WithColor(OS, Color) << (ShouldDumpRawLanguageVersion ? " " : "")
267+
<< PrettyVersionName;
229268
}
230269

231270
OS << ")\n";

llvm/test/DebugInfo/Generic/compileunit-source-language-name.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
; AIX doesn't have support for DWARF 6 DW_AT_language_name
22
; XFAIL: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}}
3-
; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-info - | FileCheck %s --implicit-check-not "DW_AT_language"
3+
; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-info -v - | FileCheck %s --implicit-check-not "DW_AT_language"
44

5-
; CHECK: DW_AT_language_name (DW_LNAME_ObjC_plus_plus)
6-
; CHECK: DW_AT_language_name (DW_LNAME_C_plus_plus)
7-
; CHECK: DW_AT_language_version (201100)
8-
; CHECK: DW_AT_language_name (DW_LNAME_Rust)
5+
; CHECK: DW_AT_language_name [DW_FORM_data2] (DW_LNAME_ObjC_plus_plus)
6+
; CHECK: DW_AT_language_name [DW_FORM_data2] (DW_LNAME_C_plus_plus)
7+
; CHECK: DW_AT_language_version [DW_FORM_data4] (201100 C++11)
8+
; CHECK: DW_AT_language_name [DW_FORM_data2] (DW_LNAME_Rust)
99
; CHECK-NOT: DW_AT_language_version
1010

1111
@x = global i32 0, align 4, !dbg !0
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Demonstrate dumping DW_AT_language_version in human-readable form.
2+
# RUN: llvm-mc -triple=x86_64--linux -filetype=obj -o %t.o < %s
3+
# RUN: llvm-dwarfdump %t.o -v | FileCheck %s --check-prefix=VERBOSE
4+
# RUN: llvm-dwarfdump %t.o | FileCheck %s --check-prefix=NO-VERBOSE
5+
6+
# VERBOSE: .debug_info contents:
7+
# VERBOSE: DW_AT_language_name [DW_FORM_data2] (DW_LNAME_C)
8+
# VERBOSE: DW_AT_language_version [DW_FORM_data4] (201112 C11)
9+
# VERBOSE: DW_AT_language_name [DW_FORM_data2] (0x0000)
10+
# VERBOSE: DW_AT_language_version [DW_FORM_data4] (12 Unknown)
11+
12+
# NO-VERBOSE: .debug_info contents:
13+
# NO-VERBOSE: DW_AT_language_name (DW_LNAME_C)
14+
# NO-VERBOSE: DW_AT_language_version (C11)
15+
# NO-VERBOSE: DW_AT_language_name (0x0000)
16+
# NO-VERBOSE: DW_AT_language_version (Unknown)
17+
18+
.section .debug_abbrev,"",@progbits
19+
.byte 1 # Abbreviation Code
20+
.byte 17 # DW_TAG_compile_unit
21+
.byte 1 # DW_CHILDREN_no
22+
.ascii "\220\001" # DW_AT_language_name
23+
.byte 5 # DW_FORM_data2
24+
.ascii "\221\001" # DW_AT_language_version
25+
.byte 6 # DW_FORM_data4
26+
.byte 0 # EOM(1)
27+
.byte 0 # EOM(2)
28+
.byte 0 # EOM(3)
29+
30+
.section .debug_info,"",@progbits
31+
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
32+
.Ldebug_info_start0:
33+
.short 5 # DWARF version number
34+
.byte 1 # Unit type
35+
.byte 8 # Address Size (in bytes)
36+
.long .debug_abbrev # Offset Into Abbrev. Section
37+
.byte 1 # Abbrev [1] DW_TAG_compile_unit
38+
.short 3 # DW_AT_language_name
39+
.long 201112 # DW_AT_language_version
40+
.byte 1 # Abbrev [1] DW_TAG_compile_unit
41+
.short 0 # DW_AT_language_name
42+
.long 12 # DW_AT_language_version
43+
.byte 0
44+
.Ldebug_info_end0:

llvm/test/tools/llvm-dwarfdump/X86/DW_AT_language_version.s

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
# Demonstrate dumping DW_AT_language_version.
2-
# RUN: llvm-mc -triple=x86_64--linux -filetype=obj < %s | \
3-
# RUN: llvm-dwarfdump -v - | FileCheck %s
1+
# Demonstrate dumping DW_AT_language_version without an
2+
# accompanying DW_AT_language_name.
3+
# RUN: llvm-mc -triple=x86_64--linux -filetype=obj -o %t.o < %s
4+
# RUN: llvm-dwarfdump -v %t.o | FileCheck %s --check-prefix=VERBOSE
5+
# RUN: llvm-dwarfdump %t.o | FileCheck %s --check-prefix=NO-VERBOSE
46

5-
# CHECK: .debug_abbrev contents:
6-
# CHECK: DW_AT_language_version DW_FORM_data4
7-
# CHECK: DW_AT_language_version DW_FORM_data2
8-
# CHECK: .debug_info contents:
9-
# CHECK: DW_AT_language_version [DW_FORM_data4] (201402)
10-
# CHECK: DW_AT_language_version [DW_FORM_data2] (0)
7+
# VERBOSE: .debug_abbrev contents:
8+
# VERBOSE: DW_AT_language_version DW_FORM_data4
9+
# VERBOSE: DW_AT_language_version DW_FORM_data2
10+
# VERBOSE: .debug_info contents:
11+
# VERBOSE: DW_AT_language_version [DW_FORM_data4] (201402)
12+
# VERBOSE: DW_AT_language_version [DW_FORM_data2] (0)
13+
14+
# NO-VERBOSE: .debug_info contents:
15+
# NO-VERBOSE: DW_AT_language_version (201402)
16+
# NO-VERBOSE: DW_AT_language_version (0)
1117

1218
.section .debug_abbrev,"",@progbits
1319
.byte 1 # Abbreviation Code

0 commit comments

Comments
 (0)