[llvm] [llvm-debuginfo-analyzer] Add support for parsing DWARF / CodeView SourceLanguage (PR #137223)

Javier Lopez-Gomez via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 25 03:19:10 PDT 2025


https://github.com/jalopezg-git updated https://github.com/llvm/llvm-project/pull/137223

>From 5dfcb957b4855dc683297114af28267ee6e7d93c Mon Sep 17 00:00:00 2001
From: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Date: Fri, 25 Apr 2025 12:18:55 +0200
Subject: [PATCH] [llvm-debuginfo-analyzer] Add support for parsing DWARF /
 CodeView source language

---
 .../DebugInfo/LogicalView/Core/LVElement.h    | 22 +++++++++++++++++++
 .../llvm/DebugInfo/LogicalView/Core/LVScope.h |  6 +++++
 .../DebugInfo/LogicalView/Core/LVElement.cpp  | 18 +++++++++++++++
 .../DebugInfo/LogicalView/Core/LVScope.cpp    |  8 ++++++-
 .../LogicalView/Readers/LVCodeViewVisitor.cpp | 10 +++++++--
 .../LogicalView/Readers/LVDWARFReader.cpp     |  5 +++++
 .../COFF/02-coff-logical-lines.test           |  2 ++
 ...-coff-incorrect-lexical-scope-typedef.test |  2 ++
 .../04-coff-missing-nested-enumerators.test   |  2 ++
 ...coff-incorrect-lexical-scope-variable.test |  2 ++
 .../COFF/06-coff-full-logical-view.test       |  1 +
 .../DWARF/02-dwarf-logical-lines.test         |  2 ++
 ...dwarf-incorrect-lexical-scope-typedef.test |  2 ++
 .../04-dwarf-missing-nested-enumerators.test  |  2 ++
 ...warf-incorrect-lexical-scope-variable.test |  2 ++
 .../DWARF/06-dwarf-full-logical-view.test     |  1 +
 ...-57040-ignored-DW_FORM_implicit_const.test |  2 ++
 .../pr-57040-incorrect-function-compare.test  |  2 ++
 .../WebAssembly/02-wasm-logical-lines.test    |  1 +
 ...-wasm-incorrect-lexical-scope-typedef.test |  2 ++
 .../04-wasm-missing-nested-enumerators.test   |  2 ++
 ...wasm-incorrect-lexical-scope-variable.test |  2 ++
 .../06-wasm-full-logical-view.test            |  1 +
 .../LogicalView/CodeViewReaderTest.cpp        |  5 +++++
 .../DebugInfo/LogicalView/DWARFReaderTest.cpp |  5 +++++
 25 files changed, 106 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
index 17fa04040ad77..22c24d0c0592c 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
@@ -14,10 +14,13 @@
 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVELEMENT_H
 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVELEMENT_H
 
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/LogicalView/Core/LVObject.h"
 #include "llvm/Support/Casting.h"
 #include <map>
 #include <set>
+#include <variant>
 #include <vector>
 
 namespace llvm {
@@ -64,6 +67,22 @@ using LVElementKindSet = std::set<LVElementKind>;
 using LVElementDispatch = std::map<LVElementKind, LVElementGetFunction>;
 using LVElementRequest = std::vector<LVElementGetFunction>;
 
+/// A source language supported by any of the debug info representations.
+struct LVSourceLanguage {
+  LVSourceLanguage() = default;
+  LVSourceLanguage(llvm::dwarf::SourceLanguage SL) : Language(SL) {}
+  LVSourceLanguage(llvm::codeview::SourceLanguage SL) : Language(SL) {}
+
+  bool isValid() const { return Language.index() != 0; }
+  template <typename T> T getAs() { return std::get<T>(Language); }
+  StringRef getName() const;
+
+private:
+  std::variant<std::monostate, llvm::dwarf::SourceLanguage,
+               llvm::codeview::SourceLanguage>
+      Language;
+};
+
 class LVElement : public LVObject {
   enum class Property {
     IsLine,   // A logical line.
@@ -214,6 +233,9 @@ class LVElement : public LVObject {
   virtual StringRef getProducer() const { return StringRef(); }
   virtual void setProducer(StringRef ProducerName) {}
 
+  virtual LVSourceLanguage getSourceLanguage() const { return {}; }
+  virtual void setSourceLanguage(LVSourceLanguage SL) {}
+
   virtual bool isCompileUnit() const { return false; }
   virtual bool isRoot() const { return false; }
 
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
index 1b3c377cd7dbb..378f249029730 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
@@ -407,6 +407,9 @@ class LVScopeCompileUnit final : public LVScope {
   // Toolchain producer.
   size_t ProducerIndex = 0;
 
+  // Source language.
+  LVSourceLanguage SourceLanguage{};
+
   // Compilation directory name.
   size_t CompilationDirectoryIndex = 0;
 
@@ -540,6 +543,9 @@ class LVScopeCompileUnit final : public LVScope {
     ProducerIndex = getStringPool().getIndex(ProducerName);
   }
 
+  LVSourceLanguage getSourceLanguage() const override { return SourceLanguage; }
+  void setSourceLanguage(LVSourceLanguage SL) override { SourceLanguage = SL; }
+
   void setCPUType(codeview::CPUType Type) { CompilationCPUType = Type; }
   codeview::CPUType getCPUType() { return CompilationCPUType; }
 
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp
index c6fb405baed1d..e65e711cb5b6e 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/LogicalView/Core/LVElement.h"
+#include "llvm/DebugInfo/CodeView/EnumTables.h"
 #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
 #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
 #include "llvm/DebugInfo/LogicalView/Core/LVType.h"
@@ -19,6 +20,23 @@ using namespace llvm;
 using namespace llvm::codeview;
 using namespace llvm::logicalview;
 
+StringRef LVSourceLanguage::getName() const {
+  if (!isValid())
+    return {};
+  switch (Language.index()) {
+  case 1: // DWARF
+    return llvm::dwarf::LanguageString(
+        std::get<llvm::dwarf::SourceLanguage>(Language));
+  case 2: // CodeView
+  {
+    static auto LangNames = llvm::codeview::getSourceLanguageNames();
+    return LangNames[std::get<llvm::codeview::SourceLanguage>(Language)].Name;
+  }
+  default:
+    llvm_unreachable("Unsupported language");
+  }
+}
+
 #define DEBUG_TYPE "Element"
 
 LVElementDispatch LVElement::Dispatch = {
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
index 8bbaf93db0caa..ae585567c9de9 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
@@ -1707,11 +1707,17 @@ void LVScopeCompileUnit::print(raw_ostream &OS, bool Full) const {
 
 void LVScopeCompileUnit::printExtra(raw_ostream &OS, bool Full) const {
   OS << formattedKind(kind()) << " '" << getName() << "'\n";
-  if (options().getPrintFormatting() && options().getAttributeProducer())
+  if (options().getPrintFormatting() && options().getAttributeProducer()) {
     printAttributes(OS, Full, "{Producer} ",
                     const_cast<LVScopeCompileUnit *>(this), getProducer(),
                     /*UseQuotes=*/true,
                     /*PrintRef=*/false);
+    if (auto SL = getSourceLanguage(); SL.isValid())
+      printAttributes(OS, Full, "{Language} ",
+                      const_cast<LVScopeCompileUnit *>(this), SL.getName(),
+                      /*UseQuotes=*/true,
+                      /*PrintRef=*/false);
+  }
 
   // Reset file index, to allow its children to print the correct filename.
   options().resetFilenameIndex();
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
index 97214948d014a..3359cb8751923 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
@@ -947,8 +947,11 @@ Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
     // The name of the CU, was extracted from the 'BuildInfo' subsection.
     Reader->setCompileUnitCPUType(Compile2.Machine);
     Scope->setName(CurrentObjectName);
-    if (options().getAttributeProducer())
+    if (options().getAttributeProducer()) {
       Scope->setProducer(Compile2.Version);
+      Scope->setSourceLanguage(LVSourceLanguage{
+          static_cast<llvm::codeview::SourceLanguage>(Compile2.getLanguage())});
+    }
     getReader().isSystemEntry(Scope, CurrentObjectName);
 
     // The line records in CodeView are recorded per Module ID. Update
@@ -992,8 +995,11 @@ Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
     // The name of the CU, was extracted from the 'BuildInfo' subsection.
     Reader->setCompileUnitCPUType(Compile3.Machine);
     Scope->setName(CurrentObjectName);
-    if (options().getAttributeProducer())
+    if (options().getAttributeProducer()) {
       Scope->setProducer(Compile3.Version);
+      Scope->setSourceLanguage(LVSourceLanguage{
+          static_cast<llvm::codeview::SourceLanguage>(Compile3.getLanguage())});
+    }
     getReader().isSystemEntry(Scope, CurrentObjectName);
 
     // The line records in CodeView are recorded per Module ID. Update
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
index 42da957233667..e5bdd1ba614d6 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
@@ -383,6 +383,11 @@ void LVDWARFReader::processOneAttribute(const DWARFDie &Die,
     if (options().getAttributeProducer())
       CurrentElement->setProducer(dwarf::toStringRef(FormValue));
     break;
+  case dwarf::DW_AT_language:
+    if (options().getAttributeProducer())
+      CurrentElement->setSourceLanguage(LVSourceLanguage{
+          static_cast<llvm::dwarf::SourceLanguage>(GetAsUnsignedConstant())});
+    break;
   case dwarf::DW_AT_upper_bound:
     CurrentElement->setUpperBound(GetBoundValue(FormValue));
     break;
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/COFF/02-coff-logical-lines.test b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/02-coff-logical-lines.test
index d2058c6b6be32..080004faa9541 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/COFF/02-coff-logical-lines.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/02-coff-logical-lines.test
@@ -26,6 +26,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'hello-world.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 15.0.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'Cpp'
 ; ONE-NEXT: [002]               {Function} extern not_inlined 'main' -> 'int'
 ; ONE-NEXT: [003]     4           {Line}
 ; ONE-NEXT: [003]                 {Code} 'subq	$0x28, %rsp'
@@ -43,6 +44,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'hello-world.cpp'
 ; ONE-NEXT: [002]               {Producer} 'Microsoft (R) Optimizing Compiler'
+; ONE-NEXT: [002]               {Language} 'Cpp'
 ; ONE-NEXT: [002]               {Function} extern not_inlined 'main' -> 'int'
 ; ONE-NEXT: [003]     4           {Line}
 ; ONE-NEXT: [003]                 {Code} 'subq	$0x28, %rsp'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/COFF/03-coff-incorrect-lexical-scope-typedef.test b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/03-coff-incorrect-lexical-scope-typedef.test
index b7c646a103019..fd01ad1be7035 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/COFF/03-coff-incorrect-lexical-scope-typedef.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/03-coff-incorrect-lexical-scope-typedef.test
@@ -42,6 +42,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-44884.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 15.0.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'Cpp'
 ; ONE-NEXT: [002]               {Function} extern not_inlined 'bar' -> 'int'
 ; ONE-NEXT: [003]                 {Parameter} 'Input' -> 'float'
 ; ONE-NEXT: [003]     1           {Line}
@@ -63,6 +64,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-44884.cpp'
 ; ONE-NEXT: [002]               {Producer} 'Microsoft (R) Optimizing Compiler'
+; ONE-NEXT: [002]               {Language} 'Cpp'
 ; ONE-NEXT: [002]               {Function} extern not_inlined 'bar' -> 'int'
 ; ONE-NEXT: [003]                 {Variable} 'Input' -> 'float'
 ; ONE-NEXT: [003]     1           {Line}
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/COFF/04-coff-missing-nested-enumerators.test b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/04-coff-missing-nested-enumerators.test
index aa84621683b43..64e6cc9d82b59 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/COFF/04-coff-missing-nested-enumerators.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/04-coff-missing-nested-enumerators.test
@@ -37,6 +37,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-46466.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 15.0.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'Cpp'
 ; ONE-NEXT: [002]               {Variable} extern 'S' -> 'Struct'
 ; ONE-NEXT: [002]     1         {Struct} 'Struct'
 ; ONE-NEXT: [003]                 {Member} public 'U' -> 'Union'
@@ -50,6 +51,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-46466.cpp'
 ; ONE-NEXT: [002]               {Producer} 'Microsoft (R) Optimizing Compiler'
+; ONE-NEXT: [002]               {Language} 'Cpp'
 ; ONE-NEXT: [002]               {Variable} extern 'S' -> 'Struct'
 ; ONE-NEXT: [002]     1         {Struct} 'Struct'
 ; ONE-NEXT: [003]                 {Member} public 'U' -> 'Union'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/COFF/05-coff-incorrect-lexical-scope-variable.test b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/05-coff-incorrect-lexical-scope-variable.test
index dea30c9f2b37d..f28acb8ddd351 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/COFF/05-coff-incorrect-lexical-scope-variable.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/05-coff-incorrect-lexical-scope-variable.test
@@ -43,6 +43,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-43860.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 15.0.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'Cpp'
 ; ONE-NEXT: [002]     2         {Function} inlined 'InlineFunction' -> 'int'
 ; ONE-NEXT: [003]                 {Parameter} '' -> 'int'
 ; ONE-NEXT: [002]               {Function} extern not_inlined 'test' -> 'int'
@@ -59,6 +60,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-43860.cpp'
 ; ONE-NEXT: [002]               {Producer} 'Microsoft (R) Optimizing Compiler'
+; ONE-NEXT: [002]               {Language} 'Cpp'
 ; ONE-NEXT: [002]               {Function} extern declared_inlined 'InlineFunction' -> 'int'
 ; ONE-NEXT: [003]                 {Block}
 ; ONE-NEXT: [004]                   {Variable} 'Var_2' -> 'int'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/COFF/06-coff-full-logical-view.test b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/06-coff-full-logical-view.test
index 4e6083be343a0..42385cbb2cbdc 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/COFF/06-coff-full-logical-view.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/COFF/06-coff-full-logical-view.test
@@ -28,6 +28,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [0x0000000000][001]              {CompileUnit} 'test.cpp'
 ; ONE-NEXT: [0x0000000000][002]                {Producer} 'clang version 15.0.0 {{.*}}'
+; ONE-NEXT: [0x0000000000][002]                {Language} 'Cpp'
 ; ONE-NEXT:                                    {Directory} 'test.cpp'
 ; ONE-NEXT:                                    {Directory} 'x:/tests/input'
 ; ONE-NEXT:                                    {File} 'general'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/02-dwarf-logical-lines.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/02-dwarf-logical-lines.test
index 62eaf593a16c2..a05c7ce0991e1 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/02-dwarf-logical-lines.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/02-dwarf-logical-lines.test
@@ -26,6 +26,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'hello-world.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 15.0.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     3         {Function} extern not_inlined 'main' -> 'int'
 ; ONE-NEXT: [003]     4           {Line}
 ; ONE-NEXT: [003]                 {Code} 'pushq	%rbp'
@@ -48,6 +49,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'hello-world.cpp'
 ; ONE-NEXT: [002]               {Producer} 'GNU C++14 10.3.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     3         {Function} extern not_inlined 'main' -> 'int'
 ; ONE-NEXT: [003]     4           {Line}
 ; ONE-NEXT: [003]                 {Code} 'endbr64'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/03-dwarf-incorrect-lexical-scope-typedef.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/03-dwarf-incorrect-lexical-scope-typedef.test
index f252a9a046f03..9a51cf9aa1eb9 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/03-dwarf-incorrect-lexical-scope-typedef.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/03-dwarf-incorrect-lexical-scope-typedef.test
@@ -42,6 +42,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-44884.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 15.0.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     1         {Function} extern not_inlined 'bar' -> 'int'
 ; ONE-NEXT: [003]     1           {Parameter} 'Input' -> 'float'
 ; ONE-NEXT: [003]     1           {Line}
@@ -76,6 +77,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-44884.cpp'
 ; ONE-NEXT: [002]               {Producer} 'GNU C++14 10.3.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     1         {Function} extern not_inlined 'bar' -> 'int'
 ; ONE-NEXT: [003]     1           {Parameter} 'Input' -> 'float'
 ; ONE-NEXT: [003]     1           {Line}
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/04-dwarf-missing-nested-enumerators.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/04-dwarf-missing-nested-enumerators.test
index dca1ff3326cc7..339f21c930856 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/04-dwarf-missing-nested-enumerators.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/04-dwarf-missing-nested-enumerators.test
@@ -37,6 +37,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-46466.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 15.0.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     8         {Variable} extern 'S' -> 'Struct'
 ; ONE-NEXT: [002]     1         {Struct} 'Struct'
 ; ONE-NEXT: [003]     5           {Member} public 'U' -> 'Union'
@@ -46,6 +47,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-46466.cpp'
 ; ONE-NEXT: [002]               {Producer} 'GNU C++14 10.3.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     8         {Variable} extern 'S' -> 'Struct'
 ; ONE-NEXT: [002]     1         {Struct} 'Struct'
 ; ONE-NEXT: [003]     5           {Member} public 'U' -> 'Union'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/05-dwarf-incorrect-lexical-scope-variable.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/05-dwarf-incorrect-lexical-scope-variable.test
index 3c3c5dcbda520..8ae465be628b5 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/05-dwarf-incorrect-lexical-scope-variable.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/05-dwarf-incorrect-lexical-scope-variable.test
@@ -43,6 +43,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-43860.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 15.0.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     2         {Function} extern inlined 'InlineFunction' -> 'int'
 ; ONE-NEXT: [003]                 {Block}
 ; ONE-NEXT: [004]     5             {Variable} 'Var_2' -> 'int'
@@ -63,6 +64,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-43860.cpp'
 ; ONE-NEXT: [002]               {Producer} 'GNU C++14 10.3.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     2         {Function} extern declared_inlined 'InlineFunction' -> 'int'
 ; ONE-NEXT: [003]                 {Block}
 ; ONE-NEXT: [004]     5             {Variable} 'Var_2' -> 'int'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/06-dwarf-full-logical-view.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/06-dwarf-full-logical-view.test
index e83592afd2ffa..8b58b1cff457c 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/06-dwarf-full-logical-view.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/06-dwarf-full-logical-view.test
@@ -28,6 +28,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [0x000000000b][001]              {CompileUnit} 'test.cpp'
 ; ONE-NEXT: [0x000000000b][002]                {Producer} 'clang version 15.0.0 {{.*}}'
+; ONE-NEXT: [0x000000000b][002]                {Language} 'DW_LANG_C_plus_plus_14'
 ; ONE-NEXT:                                    {Directory} '/data/projects/tests/input/general'
 ; ONE-NEXT:                                    {File} 'test.cpp'
 ; ONE-NEXT:                                    {Public} 'foo' [0x0000000000:0x000000003a]
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/pr-57040-ignored-DW_FORM_implicit_const.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/pr-57040-ignored-DW_FORM_implicit_const.test
index 9df058c559805..e5c21049e183e 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/pr-57040-ignored-DW_FORM_implicit_const.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/pr-57040-ignored-DW_FORM_implicit_const.test
@@ -38,6 +38,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'test.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 14.0.6'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus_14'
 ; ONE-NEXT: [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
 ; ONE-NEXT: [002]     2         {Function} extern not_inlined 'foo' -> 'int'
 ; ONE-NEXT: [003]                 {Block}
@@ -57,6 +58,7 @@
 ; TWO-EMPTY:
 ; TWO-NEXT: [001]             {CompileUnit} 'test.cpp'
 ; TWO-NEXT: [002]               {Producer} 'GNU C++17 11.3.0 {{.*}}'
+; TWO-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus_14'
 ; TWO-NEXT: [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
 ; TWO-NEXT: [002]     2         {Function} extern not_inlined 'foo' -> 'int'
 ; TWO-NEXT: [003]                 {Block}
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/pr-57040-incorrect-function-compare.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/pr-57040-incorrect-function-compare.test
index 46fbc703f7dee..bfc81a9c76b4b 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/pr-57040-incorrect-function-compare.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/pr-57040-incorrect-function-compare.test
@@ -51,6 +51,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT:  [001]             {CompileUnit} 'test.cpp'
 ; ONE-NEXT:  [002]               {Producer} 'clang version 14.0.6'
+; ONE-NEXT:  [002]               {Language} 'DW_LANG_C_plus_plus_14'
 ; ONE-NEXT:  [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
 ; ONE-NEXT:  [002]     2         {Function} extern not_inlined 'foo' -> 'int'
 ; ONE-NEXT:  [003]                 {Block}
@@ -106,6 +107,7 @@
 ; THR-EMPTY:
 ; THR-NEXT:  [001]             {CompileUnit} 'test.cpp'
 ; THR-NEXT:  [002]               {Producer} 'GNU C++17 11.3.0 {{.*}}'
+; THR-NEXT:  [002]               {Language} 'DW_LANG_C_plus_plus_14'
 ; THR-NEXT:  [002]     1         {TypeAlias} 'INTPTR' -> '* const int'
 ; THR-NEXT:  [002]     2         {Function} extern not_inlined 'foo' -> 'int'
 ; THR-NEXT:  [003]                 {Block}
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/02-wasm-logical-lines.test b/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/02-wasm-logical-lines.test
index 101f6abdc96b6..30dd13dfb4b4a 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/02-wasm-logical-lines.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/02-wasm-logical-lines.test
@@ -28,6 +28,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'hello-world.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 19{{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus_14'
 ; ONE-NEXT: [002]     3         {Function} extern not_inlined 'main' -> 'int'
 ; ONE-NEXT: [003]     4           {Line}
 ; ONE-NEXT: [003]                 {Code} 'nop'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/03-wasm-incorrect-lexical-scope-typedef.test b/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/03-wasm-incorrect-lexical-scope-typedef.test
index eb05ecae8ccf6..15c61adb0d12f 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/03-wasm-incorrect-lexical-scope-typedef.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/03-wasm-incorrect-lexical-scope-typedef.test
@@ -45,6 +45,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-44884.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 19{{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     1         {Function} extern not_inlined 'bar' -> 'int'
 ; ONE-NEXT: [003]     1           {Parameter} 'Input' -> 'float'
 ; ONE-NEXT: [003]     1           {Line}
@@ -84,6 +85,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-44884.cpp'
 ; ONE-NEXT: [002]               {Producer} 'GNU C++14 10.3.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     1         {Function} extern not_inlined 'bar' -> 'int'
 ; ONE-NEXT: [003]     1           {Parameter} 'Input' -> 'float'
 ; ONE-NEXT: [003]     1           {Line}
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/04-wasm-missing-nested-enumerators.test b/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/04-wasm-missing-nested-enumerators.test
index cafa51c41966c..c9c934137d412 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/04-wasm-missing-nested-enumerators.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/04-wasm-missing-nested-enumerators.test
@@ -40,6 +40,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-46466.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 19{{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     8         {Variable} extern 'S' -> 'Struct'
 ; ONE-NEXT: [002]     1         {Struct} 'Struct'
 ; ONE-NEXT: [003]     5           {Member} public 'U' -> 'Union'
@@ -49,6 +50,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-46466.cpp'
 ; ONE-NEXT: [002]               {Producer} 'GNU C++14 10.3.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     8         {Variable} extern 'S' -> 'Struct'
 ; ONE-NEXT: [002]     1         {Struct} 'Struct'
 ; ONE-NEXT: [003]     5           {Member} public 'U' -> 'Union'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/05-wasm-incorrect-lexical-scope-variable.test b/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/05-wasm-incorrect-lexical-scope-variable.test
index 4348161f8c5ba..e2a7902b0830a 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/05-wasm-incorrect-lexical-scope-variable.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/05-wasm-incorrect-lexical-scope-variable.test
@@ -46,6 +46,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-43860.cpp'
 ; ONE-NEXT: [002]               {Producer} 'clang version 19{{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     2         {Function} extern inlined 'InlineFunction' -> 'int'
 ; ONE-NEXT: [003]                 {Block}
 ; ONE-NEXT: [004]     5             {Variable} 'Var_2' -> 'int'
@@ -66,6 +67,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [001]             {CompileUnit} 'pr-43860.cpp'
 ; ONE-NEXT: [002]               {Producer} 'GNU C++14 10.3.0 {{.*}}'
+; ONE-NEXT: [002]               {Language} 'DW_LANG_C_plus_plus'
 ; ONE-NEXT: [002]     2         {Function} extern declared_inlined 'InlineFunction' -> 'int'
 ; ONE-NEXT: [003]                 {Block}
 ; ONE-NEXT: [004]     5             {Variable} 'Var_2' -> 'int'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/06-wasm-full-logical-view.test b/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/06-wasm-full-logical-view.test
index 81b78bac03215..ac4873f0a4d34 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/06-wasm-full-logical-view.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/06-wasm-full-logical-view.test
@@ -31,6 +31,7 @@
 ; ONE-EMPTY:
 ; ONE-NEXT: [0x000000000b][001]              {CompileUnit} 'test.cpp'
 ; ONE-NEXT: [0x000000000b][002]                {Producer} 'clang version 19{{.*}}'
+; ONE-NEXT: [0x000000000b][002]                {Language} 'DW_LANG_C_plus_plus_14'
 ; ONE-NEXT:                                    {Directory} '{{.*}}/general'
 ; ONE-NEXT:                                    {File} 'test.cpp'
 ; ONE-NEXT:                                    {Public} 'foo' [0x0000000002:0x000000007f]
diff --git a/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
index c93a79094dce9..c6bdda782a17f 100644
--- a/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
@@ -78,6 +78,11 @@ void checkElementPropertiesClangCodeview(LVReader *Reader) {
   EXPECT_EQ(CompileUnit->getBaseAddress(), 0u);
   EXPECT_TRUE(CompileUnit->getProducer().starts_with("clang"));
   EXPECT_EQ(CompileUnit->getName(), "test.cpp");
+  LVSourceLanguage Language = CompileUnit->getSourceLanguage();
+  EXPECT_TRUE(Language.isValid());
+  ASSERT_EQ(Language.getAs<llvm::codeview::SourceLanguage>(),
+            llvm::codeview::SourceLanguage::Cpp);
+  ASSERT_EQ(Language.getName(), "Cpp");
 
   EXPECT_EQ(Function->lineCount(), 16u);
   EXPECT_EQ(Function->scopeCount(), 1u);
diff --git a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
index c062c15481da9..72d4bc1c7b7e5 100644
--- a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
@@ -72,6 +72,11 @@ void checkElementProperties(LVReader *Reader) {
   EXPECT_EQ(CompileUnit->getBaseAddress(), 0u);
   EXPECT_TRUE(CompileUnit->getProducer().starts_with("clang"));
   EXPECT_EQ(CompileUnit->getName(), "test.cpp");
+  LVSourceLanguage Language = CompileUnit->getSourceLanguage();
+  EXPECT_TRUE(Language.isValid());
+  EXPECT_EQ(Language.getAs<llvm::dwarf::SourceLanguage>(),
+            llvm::dwarf::DW_LANG_C_plus_plus_14);
+  EXPECT_EQ(Language.getName(), "DW_LANG_C_plus_plus_14");
 
   EXPECT_EQ(CompileUnit->lineCount(), 0u);
   EXPECT_EQ(CompileUnit->scopeCount(), 1u);



More information about the llvm-commits mailing list