[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
Tue May 27 07:25:45 PDT 2025
https://github.com/jalopezg-git updated https://github.com/llvm/llvm-project/pull/137223
>From 5a8491ac3765a294a2bb181bd2f076f7fad9d77b Mon Sep 17 00:00:00 2001
From: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Date: Tue, 27 May 2025 16:25:31 +0200
Subject: [PATCH 1/2] [llvm-debuginfo-analyzer] Add support for parsing DWARF /
CodeView source language
---
.../CommandGuide/llvm-debuginfo-analyzer.rst | 4 +++-
.../DebugInfo/LogicalView/Core/LVElement.h | 20 +++++++++++++++++++
.../DebugInfo/LogicalView/Core/LVOptions.h | 2 ++
.../llvm/DebugInfo/LogicalView/Core/LVScope.h | 6 ++++++
.../DebugInfo/LogicalView/Core/LVElement.cpp | 18 +++++++++++++++++
.../DebugInfo/LogicalView/Core/LVOptions.cpp | 1 +
.../DebugInfo/LogicalView/Core/LVScope.cpp | 18 ++++++++++++-----
.../LogicalView/Readers/LVCodeViewVisitor.cpp | 6 ++++++
.../LogicalView/Readers/LVDWARFReader.cpp | 5 +++++
.../COFF/02-coff-logical-lines.test | 4 +++-
...-coff-incorrect-lexical-scope-typedef.test | 4 +++-
.../04-coff-missing-nested-enumerators.test | 4 +++-
...coff-incorrect-lexical-scope-variable.test | 4 +++-
.../COFF/06-coff-full-logical-view.test | 1 +
.../DWARF/02-dwarf-logical-lines.test | 4 +++-
...dwarf-incorrect-lexical-scope-typedef.test | 4 +++-
.../04-dwarf-missing-nested-enumerators.test | 4 +++-
...warf-incorrect-lexical-scope-variable.test | 4 +++-
.../DWARF/06-dwarf-full-logical-view.test | 1 +
...-57040-ignored-DW_FORM_implicit_const.test | 6 ++++--
.../pr-57040-incorrect-function-compare.test | 6 ++++--
.../WebAssembly/02-wasm-logical-lines.test | 3 ++-
...-wasm-incorrect-lexical-scope-typedef.test | 4 +++-
.../04-wasm-missing-nested-enumerators.test | 4 +++-
...wasm-incorrect-lexical-scope-variable.test | 4 +++-
.../06-wasm-full-logical-view.test | 1 +
.../llvm-debuginfo-analyzer/cmdline.test | 1 +
.../tools/llvm-debuginfo-analyzer/Options.cpp | 2 ++
.../LogicalView/CodeViewReaderTest.cpp | 6 ++++++
.../DebugInfo/LogicalView/DWARFReaderTest.cpp | 6 ++++++
30 files changed, 135 insertions(+), 22 deletions(-)
diff --git a/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst b/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst
index 7c15e65c1adf7..453af0751e2a1 100644
--- a/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst
+++ b/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst
@@ -134,12 +134,13 @@ toolchain name, binary file format, etc.
The following attributes describe the most common information for a
logical element. They help to identify the lexical scope level; the
element visibility across modules (global, local); the toolchain name
- that produced the binary file.
+ and source language that produced the binary file.
.. code-block:: text
=global: Element referenced across Compile Units.
=format: Object file format name.
+ =language: Source language name.
=level: Lexical scope level (File=0, Compile Unit=1).
=local: Element referenced only in the Compile Unit.
=producer: Toolchain identification name.
@@ -231,6 +232,7 @@ toolchain name, binary file format, etc.
=filename
=files
=format
+ =language
=level
=producer
=publics
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
index d3a6973bb7f04..7db28d71525f3 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
@@ -19,6 +19,7 @@
#include "llvm/Support/MathExtras.h"
#include <map>
#include <set>
+#include <variant>
#include <vector>
namespace llvm {
@@ -70,6 +71,22 @@ using LVElementRequest = std::vector<LVElementGetFunction>;
// lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp.
constexpr unsigned int DWARF_CHAR_BIT = 8u;
+/// 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.
@@ -220,6 +237,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/LVOptions.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVOptions.h
index 409e4652b2401..118ec9322b7bf 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVOptions.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVOptions.h
@@ -106,6 +106,7 @@ enum class LVAttributeKind {
Generated, // --attribute=generated
Global, // --attribute=global
Inserted, // --attribute=inserted
+ Language, // --attribute=language
Level, // --attribute=level
Linkage, // --attribute=linkage
Local, // --attribute=local
@@ -337,6 +338,7 @@ class LVOptions {
ATTRIBUTE_OPTION(Generated);
ATTRIBUTE_OPTION(Global);
ATTRIBUTE_OPTION(Inserted);
+ ATTRIBUTE_OPTION(Language);
ATTRIBUTE_OPTION(Level);
ATTRIBUTE_OPTION(Linkage);
ATTRIBUTE_OPTION(Location);
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
index a9bd7eef7b66b..a5726582707bc 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
@@ -418,6 +418,9 @@ class LVScopeCompileUnit final : public LVScope {
// Compilation directory name.
size_t CompilationDirectoryIndex = 0;
+ // Source language.
+ LVSourceLanguage SourceLanguage{};
+
// Used by the CodeView Reader.
codeview::CPUType CompilationCPUType = codeview::CPUType::X64;
@@ -548,6 +551,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/LVOptions.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp
index c08e887fde3e5..467bb98670b40 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp
@@ -39,6 +39,7 @@ void LVOptions::resolveDependencies() {
setAttributeFilename();
setAttributeFiles();
setAttributeFormat();
+ setAttributeLanguage();
setAttributeLevel();
setAttributeProducer();
setAttributePublics();
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
index 06a11635a629d..317686f6628ef 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
@@ -1717,11 +1717,19 @@ 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())
- printAttributes(OS, Full, "{Producer} ",
- const_cast<LVScopeCompileUnit *>(this), getProducer(),
- /*UseQuotes=*/true,
- /*PrintRef=*/false);
+ if (options().getPrintFormatting()) {
+ if (options().getAttributeProducer())
+ printAttributes(OS, Full, "{Producer} ",
+ const_cast<LVScopeCompileUnit *>(this), getProducer(),
+ /*UseQuotes=*/true,
+ /*PrintRef=*/false);
+ if (auto SL = getSourceLanguage();
+ options().getAttributeLanguage() && 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 4a1eb888095e2..24eaa1234727d 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
@@ -949,6 +949,9 @@ Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
Scope->setName(CurrentObjectName);
if (options().getAttributeProducer())
Scope->setProducer(Compile2.Version);
+ if (options().getAttributeLanguage())
+ 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
@@ -994,6 +997,9 @@ Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
Scope->setName(CurrentObjectName);
if (options().getAttributeProducer())
Scope->setProducer(Compile3.Version);
+ if (options().getAttributeLanguage())
+ 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 14538c1aefa18..76898600ce82e 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
@@ -389,6 +389,11 @@ void LVDWARFReader::processOneAttribute(const DWARFDie &Die,
if (options().getAttributeProducer())
CurrentElement->setProducer(dwarf::toStringRef(FormValue));
break;
+ case dwarf::DW_AT_language:
+ if (options().getAttributeLanguage())
+ 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..7bd816abe905f 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
@@ -15,7 +15,7 @@
; The logical views shows the intermixed lines and assembler instructions,
; allowing to compare the code generated by the different toolchains.
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer \
; RUN: --print=lines,instructions \
; RUN: %p/Inputs/hello-world-codeview-clang.o \
; RUN: %p/Inputs/hello-world-codeview-msvc.o 2>&1 | \
@@ -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..25f765b48f7de 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
@@ -30,7 +30,7 @@
; emits both typedefs at the same lexical scope (3), which is wrong.
; GCC and MSVC emit correct lexical scope for both typedefs.
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer \
; RUN: --output-sort=kind \
; RUN: --print=symbols,types,lines \
; RUN: %p/Inputs/pr-44884-codeview-clang.o \
@@ -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 a6862e31ad5d3..aecc0914b33ad 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
@@ -25,7 +25,7 @@
; references to the enumerators 'RED' and 'BLUE'. The CodeView generated
; by GCC and MSVC, does include such references.
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer,size \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer,size \
; RUN: --output-sort=name \
; RUN: --print=symbols,types \
; RUN: %p/Inputs/pr-46466-codeview-clang.o \
@@ -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' [Size = 1]
; 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' [Size = 1]
; 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..aa628f70bc503 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
@@ -31,7 +31,7 @@
; The CodeView generated by MSVC, show those variables at the correct
; lexical scope: '3' and '4' respectively.
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer \
; RUN: --output-sort=name \
; RUN: --print=symbols \
; RUN: %p/Inputs/pr-43860-codeview-clang.o \
@@ -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 42c6f124ce70a..34b9de71084de 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..533914f002827 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
@@ -15,7 +15,7 @@
; The logical views shows the intermixed lines and assembler instructions,
; allowing to compare the code generated by the different toolchains.
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer \
; RUN: --print=lines,instructions \
; RUN: %p/Inputs/hello-world-dwarf-clang.o \
; RUN: %p/Inputs/hello-world-dwarf-gcc.o 2>&1 | \
@@ -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_14'
; 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..dc57d01f3b8bb 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
@@ -30,7 +30,7 @@
; emits both typedefs at the same lexical scope (3), which is wrong.
; GCC emit correct lexical scope for both typedefs.
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer \
; RUN: --output-sort=kind \
; RUN: --print=symbols,types,lines \
; RUN: %p/Inputs/pr-44884-dwarf-clang.o \
@@ -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_14'
; 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 15d426f88a372..cd1ee436557ff 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
@@ -25,7 +25,7 @@
; references to the enumerators 'RED' and 'BLUE'. The DWARF generated
; by GCC, does include such references.
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer,size \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer,size \
; RUN: --output-sort=name \
; RUN: --print=symbols,types \
; RUN: %p/Inputs/pr-46466-dwarf-clang.o \
@@ -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_14'
; ONE-NEXT: [002] 8 {Variable} extern 'S' -> 'Struct'
; ONE-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
; 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' [Size = 1]
; 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..97f1d212bac4c 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
@@ -31,7 +31,7 @@
; The DWARF generated by GCC/Clang show those variables at the correct
; lexical scope: '3' and '4' respectively.
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer \
; RUN: --output-sort=name \
; RUN: --print=symbols \
; RUN: %p/Inputs/pr-43860-dwarf-clang.o \
@@ -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_14'
; 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 1d0843df52504..6616710a10045 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..6e8e720722f04 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
@@ -28,7 +28,7 @@
; 8 return ParamUnsigned;
; 9 }
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer \
; RUN: --print=scopes,symbols,types \
; RUN: %p/Inputs/pr-57040-test-dwarf-clang.o 2>&1 | \
; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s
@@ -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}
@@ -47,7 +48,7 @@
; ONE-NEXT: [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int'
; ONE-NEXT: [003] 4 {TypeAlias} 'INTEGER' -> 'int'
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer \
; RUN: --print=scopes,symbols,types \
; RUN: %p/Inputs/pr-57040-test-dwarf-gcc.o 2>&1 | \
; RUN: FileCheck --strict-whitespace -check-prefix=TWO %s
@@ -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..278d4f4850f5f 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
@@ -35,7 +35,7 @@
; 8 return ParamUnsigned;
; 9 }
-; RUN: llvm-debuginfo-analyzer --attribute=level,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,producer \
; RUN: --compare=types \
; RUN: --report=view \
; RUN: --print=symbols,types \
@@ -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}
@@ -90,7 +91,7 @@
; Changing the 'Reference' and 'Target' order:
-; RUN: llvm-debuginfo-analyzer --attribute=level,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,producer \
; RUN: --compare=types \
; RUN: --report=view \
; RUN: --print=symbols,types \
@@ -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..50a531ad7d823 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
@@ -18,7 +18,7 @@
; RUN: llvm-mc -arch=wasm32 -filetype=obj \
; RUN: %p/Inputs/hello-world-clang.s -o %t.hello-world-clang.o
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer \
; RUN: --print=lines,instructions \
; RUN: %t.hello-world-clang.o 2>&1 | \
; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s
@@ -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..1192a0cb7ca5a 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
@@ -33,7 +33,7 @@
; RUN: llvm-mc -arch=wasm32 -filetype=obj \
; RUN: %p/Inputs/pr-44884-clang.s -o %t.pr-44884-clang.o
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer \
; RUN: --output-sort=kind \
; RUN: --print=symbols,types,lines \
; RUN: %t.pr-44884-clang.o \
@@ -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_14'
; 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..58f80e06bd279 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
@@ -28,7 +28,7 @@
; RUN: llvm-mc -arch=wasm32 -filetype=obj \
; RUN: %p/Inputs/pr-46466-clang.s -o %t.pr-46466-clang.o
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer \
; RUN: --output-sort=name \
; RUN: --print=symbols,types \
; RUN: %t.pr-46466-clang.o \
@@ -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_14'
; 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..32a186004a362 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
@@ -34,7 +34,7 @@
; RUN: llvm-mc -arch=wasm32 -filetype=obj \
; RUN: %p/Inputs/pr-43860-clang.s -o %t.pr-43860-clang.o
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=language,level,format,producer \
; RUN: --output-sort=name \
; RUN: --print=symbols \
; RUN: %t.pr-43860-clang.o \
@@ -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_14'
; 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/test/tools/llvm-debuginfo-analyzer/cmdline.test b/llvm/test/tools/llvm-debuginfo-analyzer/cmdline.test
index 000c6e6b5ae3c..7763426142476 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/cmdline.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/cmdline.test
@@ -51,6 +51,7 @@ HELP-ALL: =gaps - Missing debug location (gaps).
HELP-ALL: =generated - Compiler generated elements.
HELP-ALL: =global - Element referenced across Compile Units.
HELP-ALL: =inserted - Generated inlined abstract references.
+HELP-ALL: =language - Source language name.
HELP-ALL: =level - Lexical scope level (File=0, Compile Unit=1).
HELP-ALL: =linkage - Linkage name.
HELP-ALL: =local - Element referenced only in the Compile Unit.
diff --git a/llvm/tools/llvm-debuginfo-analyzer/Options.cpp b/llvm/tools/llvm-debuginfo-analyzer/Options.cpp
index 86ca87376348d..79e2edccc50b8 100644
--- a/llvm/tools/llvm-debuginfo-analyzer/Options.cpp
+++ b/llvm/tools/llvm-debuginfo-analyzer/Options.cpp
@@ -89,6 +89,8 @@ cl::list<LVAttributeKind> cmdline::AttributeOptions(
"Element referenced across Compile Units."),
clEnumValN(LVAttributeKind::Inserted, "inserted",
"Generated inlined abstract references."),
+ clEnumValN(LVAttributeKind::Language, "language",
+ "Source language name."),
clEnumValN(LVAttributeKind::Level, "level",
"Lexical scope level (File=0, Compile Unit=1)."),
clEnumValN(LVAttributeKind::Linkage, "linkage", "Linkage name."),
diff --git a/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
index d11a25f1a18dd..53ba167916d49 100644
--- a/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
@@ -79,6 +79,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);
@@ -461,6 +466,7 @@ void elementProperties(SmallString<128> &InputsDir) {
ReaderOptions.setAttributeProducer();
ReaderOptions.setAttributePublics();
ReaderOptions.setAttributeRange();
+ ReaderOptions.setAttributeLanguage();
ReaderOptions.setAttributeLocation();
ReaderOptions.setAttributeSize();
ReaderOptions.setPrintAll();
diff --git a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
index 54a5bd400baf8..e2fb0984bcc74 100644
--- a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
@@ -76,6 +76,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);
@@ -319,6 +324,7 @@ void elementProperties(SmallString<128> &InputsDir) {
ReaderOptions.setAttributeProducer();
ReaderOptions.setAttributePublics();
ReaderOptions.setAttributeRange();
+ ReaderOptions.setAttributeLanguage();
ReaderOptions.setAttributeLocation();
ReaderOptions.setAttributeInserted();
ReaderOptions.setAttributeSize();
>From 424d87f3ea1bb3c6599e2e1472edad22321a7f99 Mon Sep 17 00:00:00 2001
From: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Date: Tue, 27 May 2025 16:25:31 +0200
Subject: [PATCH 2/2] [llvm-debuginfo-analyzer] LVSourceLanguage: use enum
instead of std::variant
---
.../llvm/DebugInfo/CodeView/CodeView.h | 32 +-----------
.../DebugInfo/CodeView/CodeViewLanguages.def | 51 +++++++++++++++++++
.../DebugInfo/LogicalView/Core/LVElement.h | 36 ++++++++++---
.../DebugInfo/LogicalView/Core/LVElement.cpp | 13 +++--
.../LogicalView/CodeViewReaderTest.cpp | 3 +-
.../DebugInfo/LogicalView/DWARFReaderTest.cpp | 3 +-
6 files changed, 89 insertions(+), 49 deletions(-)
create mode 100644 llvm/include/llvm/DebugInfo/CodeView/CodeViewLanguages.def
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CodeView.h b/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
index 5cdff5ff0e82f..12d589db03b25 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/CodeView.h
@@ -144,36 +144,8 @@ enum class CPUType : uint16_t {
/// Debug Interface Access SDK, and are documented here:
/// https://learn.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/cv-cfl-lang
enum SourceLanguage : uint8_t {
- C = 0x00,
- Cpp = 0x01,
- Fortran = 0x02,
- Masm = 0x03,
- Pascal = 0x04,
- Basic = 0x05,
- Cobol = 0x06,
- Link = 0x07,
- Cvtres = 0x08,
- Cvtpgd = 0x09,
- CSharp = 0x0a,
- VB = 0x0b,
- ILAsm = 0x0c,
- Java = 0x0d,
- JScript = 0x0e,
- MSIL = 0x0f,
- HLSL = 0x10,
- ObjC = 0x11,
- ObjCpp = 0x12,
- Swift = 0x13,
- AliasObj = 0x14,
- Rust = 0x15,
- Go = 0x16,
-
- /// The DMD compiler emits 'D' for the CV source language. Microsoft does not
- /// have an enumerator for it yet.
- D = 'D',
- /// The Swift compiler used to emit 'S' for the CV source language, but
- /// current versions emit the enumerator defined above.
- OldSwift = 'S',
+#define CV_LANGUAGE(NAME, ID) NAME = ID,
+#include "CodeViewLanguages.def"
};
/// These values correspond to the CV_call_e enumeration, and are documented
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CodeViewLanguages.def b/llvm/include/llvm/DebugInfo/CodeView/CodeViewLanguages.def
new file mode 100644
index 0000000000000..5c6335fffd4dd
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/CodeView/CodeViewLanguages.def
@@ -0,0 +1,51 @@
+//===-- CodeViewLanguages.def - All CodeView languages ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// These values correspond to the CV_CFL_LANG enumeration in the Microsoft
+// Debug Interface Access SDK, and are documented here:
+// https://learn.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/cv-cfl-lang
+// This should match the constants there.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CV_LANGUAGE
+#define CV_LANGUAGE(NAME, ID)
+#endif
+
+CV_LANGUAGE(C, 0x00)
+CV_LANGUAGE(Cpp, 0x01)
+CV_LANGUAGE(Fortran, 0x02)
+CV_LANGUAGE(Masm, 0x03)
+CV_LANGUAGE(Pascal, 0x04)
+CV_LANGUAGE(Basic, 0x05)
+CV_LANGUAGE(Cobol, 0x06)
+CV_LANGUAGE(Link, 0x07)
+CV_LANGUAGE(Cvtres, 0x08)
+CV_LANGUAGE(Cvtpgd, 0x09)
+CV_LANGUAGE(CSharp, 0x0a)
+CV_LANGUAGE(VB, 0x0b)
+CV_LANGUAGE(ILAsm, 0x0c)
+CV_LANGUAGE(Java, 0x0d)
+CV_LANGUAGE(JScript, 0x0e)
+CV_LANGUAGE(MSIL, 0x0f)
+CV_LANGUAGE(HLSL, 0x10)
+CV_LANGUAGE(ObjC, 0x11)
+CV_LANGUAGE(ObjCpp, 0x12)
+CV_LANGUAGE(Swift, 0x13)
+CV_LANGUAGE(AliasObj, 0x14)
+CV_LANGUAGE(Rust, 0x15)
+CV_LANGUAGE(Go, 0x16)
+
+// The DMD compiler emits 'D' for the CV source language. Microsoft does not
+// have an enumerator for it yet.
+CV_LANGUAGE(D, 'D')
+// The Swift compiler used to emit 'S' for the CV source language, but
+// current versions emit the enumerator defined above.
+CV_LANGUAGE(OldSwift, 'S')
+
+#undef CV_LANGUAGE
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
index 7db28d71525f3..df42476bbb33f 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
@@ -19,7 +19,6 @@
#include "llvm/Support/MathExtras.h"
#include <map>
#include <set>
-#include <variant>
#include <vector>
namespace llvm {
@@ -73,18 +72,39 @@ constexpr unsigned int DWARF_CHAR_BIT = 8u;
/// A source language supported by any of the debug info representations.
struct LVSourceLanguage {
+ static constexpr unsigned TagDwarf = 0x00;
+ static constexpr unsigned TagCodeView = 0x01;
+
+ enum TaggedLanguage : uint32_t {
+ Invalid = -1U
+
+ // DWARF
+#define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \
+ DW_LANG_##NAME = (TagDwarf << 16) | ID,
+#include "llvm/BinaryFormat/Dwarf.def"
+ // CodeView
+#define CV_LANGUAGE(NAME, ID) CV_LANG_##NAME = (TagCodeView << 16) | ID,
+#include "llvm/DebugInfo/CodeView/CodeViewLanguages.def"
+ };
+
LVSourceLanguage() = default;
- LVSourceLanguage(llvm::dwarf::SourceLanguage SL) : Language(SL) {}
- LVSourceLanguage(llvm::codeview::SourceLanguage SL) : Language(SL) {}
+ LVSourceLanguage(llvm::dwarf::SourceLanguage SL)
+ : Language(static_cast<TaggedLanguage>((TagDwarf << 16) | SL)) {}
+ LVSourceLanguage(llvm::codeview::SourceLanguage SL)
+ : Language(static_cast<TaggedLanguage>((TagCodeView << 16) | SL)) {}
+ bool operator==(const LVSourceLanguage &SL) const {
+ return get() == SL.get();
+ }
+ bool operator==(const LVSourceLanguage::TaggedLanguage &TL) const {
+ return get() == TL;
+ }
- bool isValid() const { return Language.index() != 0; }
- template <typename T> T getAs() { return std::get<T>(Language); }
+ bool isValid() const { return Language != Invalid; }
+ TaggedLanguage get() const { return Language; }
StringRef getName() const;
private:
- std::variant<std::monostate, llvm::dwarf::SourceLanguage,
- llvm::codeview::SourceLanguage>
- Language;
+ TaggedLanguage Language = Invalid;
};
class LVElement : public LVObject {
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp
index e65e711cb5b6e..f14b3a6076200 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp
@@ -23,14 +23,13 @@ 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
- {
+ const unsigned Tag = (Language >> 16);
+ switch (Tag) {
+ case LVSourceLanguage::TagDwarf:
+ return llvm::dwarf::LanguageString(Language & 0xffff);
+ case LVSourceLanguage::TagCodeView: {
static auto LangNames = llvm::codeview::getSourceLanguageNames();
- return LangNames[std::get<llvm::codeview::SourceLanguage>(Language)].Name;
+ return LangNames[Language & 0xffff].Name;
}
default:
llvm_unreachable("Unsupported language");
diff --git a/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
index 53ba167916d49..57e51e4121d95 100644
--- a/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
@@ -81,8 +81,7 @@ void checkElementPropertiesClangCodeview(LVReader *Reader) {
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, LVSourceLanguage::CV_LANG_Cpp);
ASSERT_EQ(Language.getName(), "Cpp");
EXPECT_EQ(Function->lineCount(), 16u);
diff --git a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
index e2fb0984bcc74..d9f6a06570833 100644
--- a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
@@ -78,8 +78,7 @@ void checkElementProperties(LVReader *Reader) {
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, LVSourceLanguage::DW_LANG_C_plus_plus_14);
EXPECT_EQ(Language.getName(), "DW_LANG_C_plus_plus_14");
EXPECT_EQ(CompileUnit->lineCount(), 0u);
More information about the llvm-commits
mailing list