[llvm] 909f429 - [llvm][dwarfdump] Pretty-print DW_AT_language_version (#164222)
    via llvm-commits 
    llvm-commits at lists.llvm.org
       
    Tue Oct 21 03:11:15 PDT 2025
    
    
  
Author: Michael Buch
Date: 2025-10-21T10:11:10Z
New Revision: 909f429b5e47aba3f67b4c1314974bd99c4483ef
URL: https://github.com/llvm/llvm-project/commit/909f429b5e47aba3f67b4c1314974bd99c4483ef
DIFF: https://github.com/llvm/llvm-project/commit/909f429b5e47aba3f67b4c1314974bd99c4483ef.diff
LOG: [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)                                                             
```
Added: 
    llvm/test/tools/llvm-dwarfdump/X86/DW_AT_language_version-pretty.s
Modified: 
    llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
    llvm/test/DebugInfo/Generic/compileunit-source-language-name.ll
    llvm/test/tools/llvm-dwarfdump/X86/DW_AT_language_version.s
Removed: 
    
################################################################################
diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 212a0c039298b..db5cc37c93f90 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -107,6 +107,28 @@ static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
   return D.getAttributeValueAsReferencedDie(F).resolveTypeUnitReference();
 }
 
+static llvm::StringRef
+prettyLanguageVersionString(const DWARFAttribute &AttrValue,
+                            const DWARFDie &Die) {
+  if (AttrValue.Attr != DW_AT_language_version)
+    return {};
+
+  auto NameForm = Die.find(DW_AT_language_name);
+  if (!NameForm)
+    return {};
+
+  auto LName = NameForm->getAsUnsignedConstant();
+  if (!LName)
+    return {};
+
+  auto LVersion = AttrValue.Value.getAsUnsignedConstant();
+  if (!LVersion)
+    return {};
+
+  return llvm::dwarf::LanguageDescription(
+      static_cast<SourceLanguageName>(*LName), *LVersion);
+}
+
 static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
                           const DWARFAttribute &AttrValue, unsigned Indent,
                           DIDumpOptions DumpOpts) {
@@ -146,15 +168,28 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
   } else if (std::optional<uint64_t> Val = FormValue.getAsUnsignedConstant())
     Name = AttributeValueString(Attr, *Val);
 
-  if (!Name.empty())
-    WithColor(OS, Color) << Name;
-  else if (Attr == DW_AT_decl_line || Attr == DW_AT_decl_column ||
-           Attr == DW_AT_call_line || Attr == DW_AT_call_column ||
-           Attr == DW_AT_language_version) {
+  auto DumpUnsignedConstant = [&OS,
+                               &DumpOpts](const DWARFFormValue &FormValue) {
     if (std::optional<uint64_t> Val = FormValue.getAsUnsignedConstant())
       OS << *Val;
     else
       FormValue.dump(OS, DumpOpts);
+  };
+
+  llvm::StringRef PrettyVersionName =
+      prettyLanguageVersionString(AttrValue, Die);
+  bool ShouldDumpRawLanguageVersion =
+      Attr == DW_AT_language_version &&
+      (DumpOpts.Verbose || PrettyVersionName.empty());
+
+  if (!Name.empty())
+    WithColor(OS, Color) << Name;
+  else if (Attr == DW_AT_decl_line || Attr == DW_AT_decl_column ||
+           Attr == DW_AT_call_line || Attr == DW_AT_call_column) {
+    DumpUnsignedConstant(FormValue);
+  } else if (Attr == DW_AT_language_version) {
+    if (ShouldDumpRawLanguageVersion)
+      DumpUnsignedConstant(FormValue);
   } else if (Attr == DW_AT_low_pc &&
              (FormValue.getAsAddress() ==
               dwarf::computeTombstoneAddress(U->getAddressByteSize()))) {
@@ -226,6 +261,10 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
       DumpOpts.RecoverableErrorHandler(createStringError(
           errc::invalid_argument, "decoding address ranges: %s",
           toString(RangesOrError.takeError()).c_str()));
+  } else if (Attr == DW_AT_language_version) {
+    if (!PrettyVersionName.empty())
+      WithColor(OS, Color) << (ShouldDumpRawLanguageVersion ? " " : "")
+                           << PrettyVersionName;
   }
 
   OS << ")\n";
diff  --git a/llvm/test/DebugInfo/Generic/compileunit-source-language-name.ll b/llvm/test/DebugInfo/Generic/compileunit-source-language-name.ll
index f5dcf01c7e89f..58b5104592931 100644
--- a/llvm/test/DebugInfo/Generic/compileunit-source-language-name.ll
+++ b/llvm/test/DebugInfo/Generic/compileunit-source-language-name.ll
@@ -1,11 +1,11 @@
 ; AIX doesn't have support for DWARF 6 DW_AT_language_name
 ; XFAIL: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}}
-; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-info - | FileCheck %s --implicit-check-not "DW_AT_language"
+; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-info -v - | FileCheck %s --implicit-check-not "DW_AT_language"
 
-; CHECK:     DW_AT_language_name (DW_LNAME_ObjC_plus_plus)
-; CHECK:     DW_AT_language_name (DW_LNAME_C_plus_plus)
-; CHECK:     DW_AT_language_version (201100)
-; CHECK:     DW_AT_language_name (DW_LNAME_Rust)
+; CHECK:     DW_AT_language_name [DW_FORM_data2] (DW_LNAME_ObjC_plus_plus)
+; CHECK:     DW_AT_language_name [DW_FORM_data2] (DW_LNAME_C_plus_plus)
+; CHECK:     DW_AT_language_version [DW_FORM_data4] (201100 C++11)
+; CHECK:     DW_AT_language_name [DW_FORM_data2] (DW_LNAME_Rust)
 ; CHECK-NOT: DW_AT_language_version
 
 @x = global i32 0, align 4, !dbg !0
diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/DW_AT_language_version-pretty.s b/llvm/test/tools/llvm-dwarfdump/X86/DW_AT_language_version-pretty.s
new file mode 100644
index 0000000000000..b889ce5cfdcc3
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/DW_AT_language_version-pretty.s
@@ -0,0 +1,44 @@
+# Demonstrate dumping DW_AT_language_version in human-readable form.
+# RUN: llvm-mc -triple=x86_64--linux -filetype=obj -o %t.o < %s
+# RUN: llvm-dwarfdump %t.o -v | FileCheck %s --check-prefix=VERBOSE
+# RUN: llvm-dwarfdump %t.o | FileCheck %s --check-prefix=NO-VERBOSE
+
+# VERBOSE: .debug_info contents:
+# VERBOSE: DW_AT_language_name [DW_FORM_data2] (DW_LNAME_C)
+# VERBOSE: DW_AT_language_version [DW_FORM_data4] (201112 C11)
+# VERBOSE: DW_AT_language_name [DW_FORM_data2] (0x0000)
+# VERBOSE: DW_AT_language_version [DW_FORM_data4] (12 Unknown)
+
+# NO-VERBOSE: .debug_info contents:
+# NO-VERBOSE: DW_AT_language_name (DW_LNAME_C)
+# NO-VERBOSE: DW_AT_language_version (C11)
+# NO-VERBOSE: DW_AT_language_name (0x0000)
+# NO-VERBOSE: DW_AT_language_version (Unknown)
+
+        .section        .debug_abbrev,"", at progbits
+        .byte   1                       # Abbreviation Code
+        .byte   17                      # DW_TAG_compile_unit
+        .byte   1                       # DW_CHILDREN_no 
+        .ascii  "\220\001"              # DW_AT_language_name
+        .byte   5                       # DW_FORM_data2
+        .ascii  "\221\001"              # DW_AT_language_version
+        .byte   6                       # DW_FORM_data4
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   0                       # EOM(3)
+
+        .section        .debug_info,"", at progbits
+        .long   .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+        .short  5                       # DWARF version number
+        .byte   1                       # Unit type
+        .byte   8                       # Address Size (in bytes)
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   1                       # Abbrev [1] DW_TAG_compile_unit
+        .short  3                       # DW_AT_language_name
+        .long   201112                  # DW_AT_language_version
+        .byte   1                       # Abbrev [1] DW_TAG_compile_unit
+        .short  0                       # DW_AT_language_name
+        .long   12                      # DW_AT_language_version
+        .byte   0 
+.Ldebug_info_end0:
diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/DW_AT_language_version.s b/llvm/test/tools/llvm-dwarfdump/X86/DW_AT_language_version.s
index f1be8fdf6cd3e..985836fcd1ef5 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/DW_AT_language_version.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/DW_AT_language_version.s
@@ -1,13 +1,19 @@
-# Demonstrate dumping DW_AT_language_version.
-# RUN: llvm-mc -triple=x86_64--linux -filetype=obj < %s | \
-# RUN:     llvm-dwarfdump -v - | FileCheck %s
+# Demonstrate dumping DW_AT_language_version without an
+# accompanying DW_AT_language_name.
+# RUN: llvm-mc -triple=x86_64--linux -filetype=obj -o %t.o < %s
+# RUN: llvm-dwarfdump -v %t.o | FileCheck %s --check-prefix=VERBOSE
+# RUN: llvm-dwarfdump %t.o | FileCheck %s --check-prefix=NO-VERBOSE
 
-# CHECK: .debug_abbrev contents:
-# CHECK: DW_AT_language_version DW_FORM_data4
-# CHECK: DW_AT_language_version DW_FORM_data2
-# CHECK: .debug_info contents:
-# CHECK: DW_AT_language_version [DW_FORM_data4] (201402)
-# CHECK: DW_AT_language_version [DW_FORM_data2] (0)
+# VERBOSE: .debug_abbrev contents:
+# VERBOSE: DW_AT_language_version DW_FORM_data4
+# VERBOSE: DW_AT_language_version DW_FORM_data2
+# VERBOSE: .debug_info contents:
+# VERBOSE: DW_AT_language_version [DW_FORM_data4] (201402)
+# VERBOSE: DW_AT_language_version [DW_FORM_data2] (0)
+
+# NO-VERBOSE: .debug_info contents:
+# NO-VERBOSE: DW_AT_language_version (201402)
+# NO-VERBOSE: DW_AT_language_version (0)
 
         .section        .debug_abbrev,"", at progbits
         .byte   1                       # Abbreviation Code
        
    
    
More information about the llvm-commits
mailing list