Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
20 changes: 20 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "llvm/Support/MathExtras.h"
#include <map>
#include <set>
#include <variant>
#include <vector>

namespace llvm {
Expand Down Expand Up @@ -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;
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be explore the use of StringPool to store the Language string.
Basically, the setSourceLanguage function to use the logic from StringRef LVSourceLanguage::getName() to get the string and store it in the StringPool. And to get back the string in 'getSourceLanguage' query the StringPool.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds promising, and a bit simpler, given the existing infrastructure.

However, in the current state of this PR, we could write a switch statement on the returned value of getSourceLanguage.getAs<...>(); this particular use case would become a bit harder to support if using strings as the underlying representation.

Initially, I thought this could be supported by exposing the LanguageIndex data member (suggested below), but this is not reliable, as it depends on the interning order.

We could still go for StringPool + LanguageIndex at the cost of having to do string comparisons somewhere else (I would prefer to avoid this).

Copy link
Contributor Author

@jalopezg-git jalopezg-git May 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this a bit and came to the conclusion that we could, either

  • (1) Leave as-is, using std::variant<Ts...>, perhaps with some additional improvement.
  • (2) Make LVSourceLanguage essentially an enum which contains enumerators for every language supported by any of the readers. We could use the most-significant bits to store the format that defines such language (e.g. DWARF, CodeView, etc.). This may be simple, as we can do something similar to
static constexpr unsigned LVTagDwarf = (0x01 << 16);
static constexpr unsigned LVTagCodeView = (0x02 << 16);

enum LVSourceLanguage : uint32_t {
  /* DWARF */
#define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR)                 \
  DW_LANG_##NAME = LVTagDwarf | ID,
#include "llvm/BinaryFormat/Dwarf.def"

  /* Codeview */
  ...
};

Then, the SourceLanguage becomes just a uint32_t. Essentially, this tries to represent the same as above, but without using std::variant<Ts...>, and possibly being more space-efficient.

  • (3) Relying on StringPool, as you suggested. Then, it may be a bit uncomfortable for debuginfologicalview library users to do something conditionally on the source language of a compile unit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I tend to like (2) more, so if you also agree, I could switch to this option for the next revision.

class LVElement : public LVObject {
enum class Property {
IsLine, // A logical line.
Expand Down Expand Up @@ -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; }

Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,9 @@ class LVScopeCompileUnit final : public LVScope {
// Toolchain producer.
size_t ProducerIndex = 0;

// Source language.
LVSourceLanguage SourceLanguage{};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be just: size_t LanguageIndex = 0;

// Compilation directory name.
size_t CompilationDirectoryIndex = 0;

Expand Down Expand Up @@ -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; }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get/Set the language string from/into the StringPool.

void setCPUType(codeview::CPUType Type) { CompilationCPUType = Type; }
codeview::CPUType getCPUType() { return CompilationCPUType; }

Expand Down
18 changes: 18 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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");
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic can be used to store the language string in the StringPool.

#define DEBUG_TYPE "Element"

LVElementDispatch LVElement::Dispatch = {
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ void LVOptions::resolveDependencies() {
setAttributeFilename();
setAttributeFiles();
setAttributeFormat();
setAttributeLanguage();
setAttributeLevel();
setAttributeProducer();
setAttributePublics();
Expand Down
18 changes: 13 additions & 5 deletions llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 | \
Expand All @@ -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'
Expand All @@ -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'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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}
Expand All @@ -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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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'
Expand All @@ -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'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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'
Expand All @@ -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'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 | \
Expand All @@ -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'
Expand All @@ -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'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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}
Expand Down Expand Up @@ -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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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'
Expand All @@ -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'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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'
Expand All @@ -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'
Expand Down
Loading