[llvm] [llvm-debuginfo-analyzer] Add support for DWARF `DW_AT_byte_size` (PR #139110)
Javier Lopez-Gomez via llvm-commits
llvm-commits at lists.llvm.org
Tue May 13 06:12:06 PDT 2025
https://github.com/jalopezg-git updated https://github.com/llvm/llvm-project/pull/139110
>From 0a1da12c8b410041956a3ad61318badfc3c172c2 Mon Sep 17 00:00:00 2001
From: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Date: Tue, 13 May 2025 15:11:51 +0200
Subject: [PATCH] [llvm-debuginfo-analyzer] Add support for DWARF
`DW_AT_byte_size`
---
.../DebugInfo/LogicalView/Core/LVElement.h | 7 ++++
.../DebugInfo/LogicalView/Core/LVOptions.h | 2 +
.../llvm/DebugInfo/LogicalView/Core/LVScope.h | 6 +++
.../llvm/DebugInfo/LogicalView/Core/LVType.h | 7 ++++
.../DebugInfo/LogicalView/Core/LVOptions.cpp | 1 +
.../DebugInfo/LogicalView/Core/LVScope.cpp | 5 ++-
.../lib/DebugInfo/LogicalView/Core/LVType.cpp | 5 ++-
.../LogicalView/Readers/LVCodeViewVisitor.cpp | 6 +++
.../LogicalView/Readers/LVDWARFReader.cpp | 4 ++
.../04-coff-missing-nested-enumerators.test | 20 ++++-----
.../COFF/06-coff-full-logical-view.test | 6 +--
.../04-dwarf-missing-nested-enumerators.test | 14 +++----
.../DWARF/06-dwarf-full-logical-view.test | 6 +--
.../DWARF/dw-at-specification.test | 4 +-
.../tools/llvm-debuginfo-analyzer/Options.cpp | 1 +
.../LogicalView/CodeViewReaderTest.cpp | 42 +++++++++++++++++++
.../DebugInfo/LogicalView/DWARFReaderTest.cpp | 21 ++++++++++
17 files changed, 130 insertions(+), 27 deletions(-)
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
index 17fa04040ad77..b2ef6579caf41 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
@@ -64,6 +64,10 @@ using LVElementKindSet = std::set<LVElementKind>;
using LVElementDispatch = std::map<LVElementKind, LVElementGetFunction>;
using LVElementRequest = std::vector<LVElementGetFunction>;
+// Assume 8-bit bytes; this is consistent, e.g. with
+// lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp.
+constexpr unsigned int DWARF_CHAR_BIT = 8u;
+
class LVElement : public LVObject {
enum class Property {
IsLine, // A logical line.
@@ -239,6 +243,9 @@ class LVElement : public LVObject {
virtual bool isBase() const { return false; }
virtual bool isTemplateParam() const { return false; }
+ uint32_t getStorageSizeInBytes() const {
+ return (getBitSize() + (DWARF_CHAR_BIT - 1)) / DWARF_CHAR_BIT;
+ }
virtual uint32_t getBitSize() const { return 0; }
virtual void setBitSize(uint32_t Size) {}
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVOptions.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVOptions.h
index ac0dfba0f1ede..409e4652b2401 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVOptions.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVOptions.h
@@ -119,6 +119,7 @@ enum class LVAttributeKind {
Range, // --attribute=range
Reference, // --attribute=reference
Register, // --attribute=register
+ Size, // --attribute=size
Standard, // --attribute=standard
Subrange, // --attribute=subrange
System, // --attribute=system
@@ -349,6 +350,7 @@ class LVOptions {
ATTRIBUTE_OPTION(Range);
ATTRIBUTE_OPTION(Reference);
ATTRIBUTE_OPTION(Register);
+ ATTRIBUTE_OPTION(Size);
ATTRIBUTE_OPTION(Standard);
ATTRIBUTE_OPTION(Subrange);
ATTRIBUTE_OPTION(System);
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
index 1b3c377cd7dbb..1cf61d085d84f 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
@@ -93,6 +93,9 @@ class LVScope : public LVElement {
LVProperties<Property> Properties;
static LVScopeDispatch Dispatch;
+ // Size in bits if this scope represents also a compound type.
+ uint32_t BitSize = 0;
+
// Coverage factor in units (bytes).
unsigned CoverageFactor = 0;
@@ -269,6 +272,9 @@ class LVScope : public LVElement {
bool removeElement(LVElement *Element) override;
void updateLevel(LVScope *Parent, bool Moved) override;
+ uint32_t getBitSize() const override { return BitSize; }
+ void setBitSize(uint32_t Size) override { BitSize = Size; }
+
void resolve() override;
void resolveName() override;
void resolveReferences() override;
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
index 28881b3c95b17..58d5bc48c3a72 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
@@ -56,6 +56,9 @@ class LVType : public LVElement {
LVProperties<Property> Properties;
static LVTypeDispatch Dispatch;
+ // Size in bits of a symbol of this type.
+ uint32_t BitSize = 0;
+
// Find the current type in the given 'Targets'.
LVType *findIn(const LVTypes *Targets) const;
@@ -109,6 +112,10 @@ class LVType : public LVElement {
virtual LVElement *getUnderlyingType() { return nullptr; }
virtual void setUnderlyingType(LVElement *Element) {}
+ // Return the size in bits of an entity of this type.
+ uint32_t getBitSize() const override { return BitSize; }
+ void setBitSize(uint32_t Size) override { BitSize = Size; }
+
void resolveName() override;
void resolveReferences() override;
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp
index 8050c0efdd7cb..be1eabe376b18 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp
@@ -67,6 +67,7 @@ void LVOptions::resolveDependencies() {
setAttributeQualified();
setAttributeQualifier();
setAttributeRegister();
+ setAttributeSize();
setAttributeSubrange();
setAttributeSystem();
setAttributeTypename();
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
index 8bbaf93db0caa..d88b10e87f1d4 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
@@ -1011,9 +1011,12 @@ void LVScope::printExtra(raw_ostream &OS, bool Full) const {
// Do not print any type or name for a lexical block.
if (!getIsBlock()) {
OS << " " << formattedName(getName());
- if (!getIsAggregate())
+ if (!getIsAggregate()) {
OS << " -> " << typeOffsetAsString()
<< formattedNames(getTypeQualifiedName(), typeAsString());
+ }
+ if (uint32_t Size = getStorageSizeInBytes())
+ OS << " [Size = " << Size << "]";
}
OS << "\n";
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
index 28bccadce598c..e5c9936c008e2 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
@@ -292,7 +292,10 @@ void LVType::print(raw_ostream &OS, bool Full) const {
}
void LVType::printExtra(raw_ostream &OS, bool Full) const {
- OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
+ OS << formattedKind(kind()) << " " << formattedName(getName());
+ if (uint32_t Size = getStorageSizeInBytes())
+ OS << " [Size = " << Size << "]";
+ OS << "\n";
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
index 97214948d014a..0a3e4b52da2ef 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
@@ -1987,6 +1987,8 @@ Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ClassRecord &Class,
Scope->setName(Class.getName());
if (Class.hasUniqueName())
Scope->setLinkageName(Class.getUniqueName());
+ if (options().getAttributeSize())
+ Scope->setBitSize(Class.getSize() * DWARF_CHAR_BIT);
if (Class.isNested()) {
Scope->setIsNested();
@@ -2455,6 +2457,8 @@ Error LVLogicalVisitor::visitKnownRecord(CVType &Record, UnionRecord &Union,
Scope->setName(Union.getName());
if (Union.hasUniqueName())
Scope->setLinkageName(Union.getUniqueName());
+ if (options().getAttributeSize())
+ Scope->setBitSize(Union.getSize() * DWARF_CHAR_BIT);
if (Union.isNested()) {
Scope->setIsNested();
@@ -3208,6 +3212,8 @@ LVType *LVLogicalVisitor::createBaseType(TypeIndex TI, StringRef TypeName) {
if (createElement(TIR, SimpleKind)) {
CurrentType->setName(TypeName);
+ if (options().getAttributeSize())
+ CurrentType->setBitSize(getSizeInBytesForTypeIndex(TIR) * DWARF_CHAR_BIT);
Reader->getCompileUnit()->addElement(CurrentType);
}
return CurrentType;
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
index 42da957233667..fdfeca927c1bb 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
@@ -307,6 +307,10 @@ void LVDWARFReader::processOneAttribute(const DWARFDie &Die,
case dwarf::DW_AT_bit_size:
CurrentElement->setBitSize(GetAsUnsignedConstant());
break;
+ case dwarf::DW_AT_byte_size:
+ if (options().getAttributeSize())
+ CurrentElement->setBitSize(GetAsUnsignedConstant() * DWARF_CHAR_BIT);
+ break;
case dwarf::DW_AT_call_file:
CurrentElement->setCallFilenameIndex(IncrementFileIndex
? GetAsUnsignedConstant() + 1
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..a6862e31ad5d3 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 \
+; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer,size \
; RUN: --output-sort=name \
; RUN: --print=symbols,types \
; RUN: %p/Inputs/pr-46466-codeview-clang.o \
@@ -38,9 +38,9 @@
; ONE-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
; ONE-NEXT: [002] {Producer} 'clang version 15.0.0 {{.*}}'
; ONE-NEXT: [002] {Variable} extern 'S' -> 'Struct'
-; ONE-NEXT: [002] 1 {Struct} 'Struct'
+; ONE-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
; ONE-NEXT: [003] {Member} public 'U' -> 'Union'
-; ONE-NEXT: [003] 2 {Union} 'Union'
+; ONE-NEXT: [003] 2 {Union} 'Union' [Size = 1]
; ONE-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'int'
; ONE-NEXT: [005] {Enumerator} 'BLUE' = '0x1'
; ONE-NEXT: [005] {Enumerator} 'RED' = '0x0'
@@ -51,9 +51,9 @@
; ONE-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
; ONE-NEXT: [002] {Producer} 'Microsoft (R) Optimizing Compiler'
; ONE-NEXT: [002] {Variable} extern 'S' -> 'Struct'
-; ONE-NEXT: [002] 1 {Struct} 'Struct'
+; ONE-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
; ONE-NEXT: [003] {Member} public 'U' -> 'Union'
-; ONE-NEXT: [003] 2 {Union} 'Union'
+; ONE-NEXT: [003] 2 {Union} 'Union' [Size = 1]
; ONE-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'int'
; ONE-NEXT: [005] {Enumerator} 'BLUE' = '0x1'
; ONE-NEXT: [005] {Enumerator} 'RED' = '0x0'
@@ -62,7 +62,7 @@
; showing just the logical types that are 'Enumerator' and its
; parents. The logical view is sorted by the types name.
-; RUN: llvm-debuginfo-analyzer --attribute=level,format \
+; RUN: llvm-debuginfo-analyzer --attribute=level,format,size \
; RUN: --output-sort=name \
; RUN: --select-types=Enumerator \
; RUN: --report=parents \
@@ -74,8 +74,8 @@
; TWO-NEXT: [000] {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64
; TWO-EMPTY:
; TWO-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
-; TWO-NEXT: [002] 1 {Struct} 'Struct'
-; TWO-NEXT: [003] 2 {Union} 'Union'
+; TWO-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
+; TWO-NEXT: [003] 2 {Union} 'Union' [Size = 1]
; TWO-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'int'
; TWO-NEXT: [005] {Enumerator} 'BLUE' = '0x1'
; TWO-NEXT: [005] {Enumerator} 'RED' = '0x0'
@@ -84,8 +84,8 @@
; TWO-NEXT: [000] {File} 'pr-46466-codeview-msvc.o' -> COFF-x86-64
; TWO-EMPTY:
; TWO-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
-; TWO-NEXT: [002] 1 {Struct} 'Struct'
-; TWO-NEXT: [003] 2 {Union} 'Union'
+; TWO-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
+; TWO-NEXT: [003] 2 {Union} 'Union' [Size = 1]
; TWO-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'int'
; TWO-NEXT: [005] {Enumerator} 'BLUE' = '0x1'
; TWO-NEXT: [005] {Enumerator} 'RED' = '0x0'
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..42c6f124ce70a 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
@@ -34,7 +34,7 @@
; ONE-NEXT: {File} 'test.cpp'
; ONE-NEXT: {Public} 'foo' [0x0000000000:0x0000000046]
; ONE-NEXT: [0x0000000000][002] {TypeAlias} 'INTPTR' -> [0x0000001001]'* const int'
-; ONE-NEXT: [0x0000000030][002] {BaseType} 'bool'
+; ONE-NEXT: [0x0000000030][002] {BaseType} 'bool' [Size = 1]
; ONE-NEXT: [0x0000000000][002] {Function} extern not_inlined 'foo' -> [0x0000000074]'int'
; ONE-NEXT: [0x0000000000][003] {Range} Lines 2:9 [0x0000000000:0x0000000046]
; ONE-NEXT: [0x0000000000][003] {Linkage} 0x1 '?foo@@YAHPEBHI_N at Z'
@@ -80,8 +80,8 @@
; ONE-NEXT: [0x000000003e][003] {Code} 'movl 0x1c(%rsp), %eax'
; ONE-NEXT: [0x0000000042][003] {Code} 'addq $0x20, %rsp'
; ONE-NEXT: [0x0000000046][003] {Code} 'retq'
-; ONE-NEXT: [0x0000000074][002] {BaseType} 'int'
-; ONE-NEXT: [0x0000000075][002] {BaseType} 'unsigned'
+; ONE-NEXT: [0x0000000074][002] {BaseType} 'int' [Size = 4]
+; ONE-NEXT: [0x0000000075][002] {BaseType} 'unsigned' [Size = 4]
; ONE-EMPTY:
; ONE-NEXT: -----------------------------
; ONE-NEXT: Element Total Printed
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..15d426f88a372 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 \
+; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer,size \
; RUN: --output-sort=name \
; RUN: --print=symbols,types \
; RUN: %p/Inputs/pr-46466-dwarf-clang.o \
@@ -38,7 +38,7 @@
; ONE-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
; ONE-NEXT: [002] {Producer} 'clang version 15.0.0 {{.*}}'
; ONE-NEXT: [002] 8 {Variable} extern 'S' -> 'Struct'
-; ONE-NEXT: [002] 1 {Struct} 'Struct'
+; ONE-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
; ONE-NEXT: [003] 5 {Member} public 'U' -> 'Union'
; ONE-EMPTY:
; ONE-NEXT: Logical View:
@@ -47,9 +47,9 @@
; ONE-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
; ONE-NEXT: [002] {Producer} 'GNU C++14 10.3.0 {{.*}}'
; ONE-NEXT: [002] 8 {Variable} extern 'S' -> 'Struct'
-; ONE-NEXT: [002] 1 {Struct} 'Struct'
+; ONE-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
; ONE-NEXT: [003] 5 {Member} public 'U' -> 'Union'
-; ONE-NEXT: [003] 2 {Union} 'Union'
+; ONE-NEXT: [003] 2 {Union} 'Union' [Size = 1]
; ONE-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int'
; ONE-NEXT: [005] {Enumerator} 'BLUE' = '0x1'
; ONE-NEXT: [005] {Enumerator} 'RED' = '0x0'
@@ -58,7 +58,7 @@
; showing just the logical types that are 'Enumerator' and its
; parents. The logical view is sorted by the types name.
-; RUN: llvm-debuginfo-analyzer --attribute=level,format \
+; RUN: llvm-debuginfo-analyzer --attribute=level,format,size \
; RUN: --output-sort=name \
; RUN: --select-types=Enumerator \
; RUN: --report=parents \
@@ -75,8 +75,8 @@
; TWO-NEXT: [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64
; TWO-EMPTY:
; TWO-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
-; TWO-NEXT: [002] 1 {Struct} 'Struct'
-; TWO-NEXT: [003] 2 {Union} 'Union'
+; TWO-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
+; TWO-NEXT: [003] 2 {Union} 'Union' [Size = 1]
; TWO-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int'
; TWO-NEXT: [005] {Enumerator} 'BLUE' = '0x1'
; TWO-NEXT: [005] {Enumerator} 'RED' = '0x0'
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..1d0843df52504 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
@@ -32,9 +32,9 @@
; ONE-NEXT: {File} 'test.cpp'
; ONE-NEXT: {Public} 'foo' [0x0000000000:0x000000003a]
; ONE-NEXT: [0x000000000b][002] {Range} Lines 2:9 [0x0000000000:0x000000003a]
-; ONE-NEXT: [0x00000000bc][002] {BaseType} 'bool'
-; ONE-NEXT: [0x0000000099][002] {BaseType} 'int'
-; ONE-NEXT: [0x00000000b5][002] {BaseType} 'unsigned int'
+; ONE-NEXT: [0x00000000bc][002] {BaseType} 'bool' [Size = 1]
+; ONE-NEXT: [0x0000000099][002] {BaseType} 'int' [Size = 4]
+; ONE-NEXT: [0x00000000b5][002] {BaseType} 'unsigned int' [Size = 4]
; ONE-EMPTY:
; ONE-NEXT: [0x00000000a0][002] {Source} '/data/projects/tests/input/general/test.cpp'
; ONE-NEXT: [0x00000000a0][002] 1 {TypeAlias} 'INTPTR' -> [0x00000000ab]'* const int'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/dw-at-specification.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/dw-at-specification.test
index b1b35e4f4fe3e..17e6a4d33e5d3 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/dw-at-specification.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/dw-at-specification.test
@@ -13,7 +13,7 @@
; an assert in the LVDWARFReader:
; $ clang++ -g -c dw-at-specification.cpp -o dw-at-specification.o
-; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
+; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer,size \
; RUN: --output-sort=name \
; RUN: --print=symbols \
; RUN: %p/Inputs/dw-at-specification.o 2>&1 | \
@@ -25,5 +25,5 @@
; CHECK: [001] {CompileUnit} 'a.cpp'
; CHECK: [002] {Producer} 'clang version 11.0.0 ({{.*}})'
; CHECK: [002] {Variable} 'Arr' -> 'const int [3]'
-; CHECK: [002] 1 {Struct} 'S'
+; CHECK: [002] 1 {Struct} 'S' [Size = 1]
; CHECK: [003] 2 {Member} extern public 'Arr' -> 'const int [1]'
diff --git a/llvm/tools/llvm-debuginfo-analyzer/Options.cpp b/llvm/tools/llvm-debuginfo-analyzer/Options.cpp
index e5566b3390fd2..4f97f876c2b33 100644
--- a/llvm/tools/llvm-debuginfo-analyzer/Options.cpp
+++ b/llvm/tools/llvm-debuginfo-analyzer/Options.cpp
@@ -114,6 +114,7 @@ cl::list<LVAttributeKind> cmdline::AttributeOptions(
"Element declaration and definition references."),
clEnumValN(LVAttributeKind::Register, "register",
"Processor register names."),
+ clEnumValN(LVAttributeKind::Size, "size", "Type sizes."),
clEnumValN(LVAttributeKind::Standard, "standard",
"Basic attributes alias."),
clEnumValN(LVAttributeKind::Subrange, "subrange",
diff --git a/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
index c93a79094dce9..d11a25f1a18dd 100644
--- a/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
@@ -21,6 +21,7 @@
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
+#include <algorithm>
using namespace llvm;
using namespace llvm::logicalview;
@@ -128,6 +129,26 @@ void checkElementPropertiesClangCodeview(LVReader *Reader) {
const LVLines *Lines = Foo->getLines();
ASSERT_NE(Lines, nullptr);
EXPECT_EQ(Lines->size(), 0x10u);
+
+ // Check size of types in CompileUnit.
+ const LVTypes *Types = CompileUnit->getTypes();
+ ASSERT_NE(Types, nullptr);
+ EXPECT_EQ(Types->size(), 6u);
+
+ const auto BoolType =
+ std::find_if(Types->begin(), Types->end(), [](const LVElement *elt) {
+ return elt->getName() == "bool";
+ });
+ ASSERT_NE(BoolType, Types->end());
+ const auto IntType =
+ std::find_if(Types->begin(), Types->end(), [](const LVElement *elt) {
+ return elt->getName() == "int";
+ });
+ ASSERT_NE(IntType, Types->end());
+ EXPECT_EQ(static_cast<LVType *>(*BoolType)->getBitSize(), 8u);
+ EXPECT_EQ(static_cast<LVType *>(*BoolType)->getStorageSizeInBytes(), 1u);
+ EXPECT_EQ(static_cast<LVType *>(*IntType)->getBitSize(), 32u);
+ EXPECT_EQ(static_cast<LVType *>(*IntType)->getStorageSizeInBytes(), 4u);
}
// Check the logical elements basic properties (MSVC - Codeview).
@@ -194,6 +215,26 @@ void checkElementPropertiesMsvcCodeview(LVReader *Reader) {
const LVLines *Lines = Foo->getLines();
ASSERT_NE(Lines, nullptr);
EXPECT_EQ(Lines->size(), 0x0eu);
+
+ // Check size of types in CompileUnit.
+ const LVTypes *Types = CompileUnit->getTypes();
+ ASSERT_NE(Types, nullptr);
+ EXPECT_EQ(Types->size(), 8u);
+
+ const auto BoolType =
+ std::find_if(Types->begin(), Types->end(), [](const LVElement *elt) {
+ return elt->getName() == "bool";
+ });
+ ASSERT_NE(BoolType, Types->end());
+ const auto IntType =
+ std::find_if(Types->begin(), Types->end(), [](const LVElement *elt) {
+ return elt->getName() == "int";
+ });
+ ASSERT_NE(IntType, Types->end());
+ EXPECT_EQ(static_cast<LVType *>(*BoolType)->getBitSize(), 8u);
+ EXPECT_EQ(static_cast<LVType *>(*BoolType)->getStorageSizeInBytes(), 1u);
+ EXPECT_EQ(static_cast<LVType *>(*IntType)->getBitSize(), 32u);
+ EXPECT_EQ(static_cast<LVType *>(*IntType)->getStorageSizeInBytes(), 4u);
}
// Check the logical elements basic properties (MSVC library - Codeview).
@@ -421,6 +462,7 @@ void elementProperties(SmallString<128> &InputsDir) {
ReaderOptions.setAttributePublics();
ReaderOptions.setAttributeRange();
ReaderOptions.setAttributeLocation();
+ ReaderOptions.setAttributeSize();
ReaderOptions.setPrintAll();
ReaderOptions.resolveDependencies();
diff --git a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
index c062c15481da9..8971659275e9d 100644
--- a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
@@ -122,6 +122,26 @@ void checkElementProperties(LVReader *Reader) {
const LVLines *Lines = Function->getLines();
ASSERT_NE(Lines, nullptr);
ASSERT_EQ(Lines->size(), 0x12u);
+
+ // Check size of types in CompileUnit.
+ const LVTypes *Types = CompileUnit->getTypes();
+ ASSERT_NE(Types, nullptr);
+ EXPECT_EQ(Types->size(), 7u);
+
+ const auto BoolType =
+ std::find_if(Types->begin(), Types->end(), [](const LVElement *elt) {
+ return elt->getName() == "bool";
+ });
+ ASSERT_NE(BoolType, Types->end());
+ const auto IntType =
+ std::find_if(Types->begin(), Types->end(), [](const LVElement *elt) {
+ return elt->getName() == "int";
+ });
+ ASSERT_NE(IntType, Types->end());
+ EXPECT_EQ(static_cast<LVType *>(*BoolType)->getBitSize(), 8u);
+ EXPECT_EQ(static_cast<LVType *>(*BoolType)->getStorageSizeInBytes(), 1u);
+ EXPECT_EQ(static_cast<LVType *>(*IntType)->getBitSize(), 32u);
+ EXPECT_EQ(static_cast<LVType *>(*IntType)->getStorageSizeInBytes(), 4u);
}
// Check the logical elements selection.
@@ -253,6 +273,7 @@ void elementProperties(SmallString<128> &InputsDir) {
ReaderOptions.setAttributePublics();
ReaderOptions.setAttributeRange();
ReaderOptions.setAttributeLocation();
+ ReaderOptions.setAttributeSize();
ReaderOptions.setPrintAll();
ReaderOptions.resolveDependencies();
More information about the llvm-commits
mailing list