Skip to content

Commit c60b31e

Browse files
committed
[llvm-debuginfo-analyzer] Add support for parsing DWARF DW_TAG_module
1 parent d597452 commit c60b31e

File tree

9 files changed

+63
-0
lines changed

9 files changed

+63
-0
lines changed

llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ The following options allow printing of scopes that match the given <kind>.
519519
=InlinedFunction: An inlined function.
520520
=Label: A label.
521521
=LexicalBlock: A lexical block.
522+
=Module: A module.
522523
=Namespace: A namespace.
523524
=Root: The element representing the main scope.
524525
=Structure: A structure.

llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ enum class LVSubclassID : unsigned char {
4242
LV_SCOPE_FUNCTION,
4343
LV_SCOPE_FUNCTION_INLINED,
4444
LV_SCOPE_FUNCTION_TYPE,
45+
LV_SCOPE_MODULE,
4546
LV_SCOPE_NAMESPACE,
4647
LV_SCOPE_ROOT,
4748
LV_SCOPE_TEMPLATE_PACK,

llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class LVReader {
104104
LV_OBJECT_ALLOCATOR(ScopeFunction)
105105
LV_OBJECT_ALLOCATOR(ScopeFunctionInlined)
106106
LV_OBJECT_ALLOCATOR(ScopeFunctionType)
107+
LV_OBJECT_ALLOCATOR(ScopeModule)
107108
LV_OBJECT_ALLOCATOR(ScopeNamespace)
108109
LV_OBJECT_ALLOCATOR(ScopeRoot)
109110
LV_OBJECT_ALLOCATOR(ScopeTemplatePack)
@@ -210,6 +211,7 @@ class LVReader {
210211
LV_CREATE_OBJECT(ScopeFunction)
211212
LV_CREATE_OBJECT(ScopeFunctionInlined)
212213
LV_CREATE_OBJECT(ScopeFunctionType)
214+
LV_CREATE_OBJECT(ScopeModule)
213215
LV_CREATE_OBJECT(ScopeNamespace)
214216
LV_CREATE_OBJECT(ScopeRoot)
215217
LV_CREATE_OBJECT(ScopeTemplatePack)

llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ enum class LVScopeKind {
4848
IsLabel,
4949
IsLexicalBlock,
5050
IsMember,
51+
IsModule,
5152
IsNamespace,
5253
IsRoot,
5354
IsStructure,
@@ -181,6 +182,7 @@ class LVScope : public LVElement {
181182
KIND(LVScopeKind, IsTemplatePack);
182183
KIND_1(LVScopeKind, IsTryBlock, IsBlock);
183184
KIND_1(LVScopeKind, IsUnion, IsAggregate);
185+
KIND_2(LVScopeKind, IsModule, CanHaveRanges, CanHaveLines);
184186

185187
PROPERTY(Property, HasDiscriminator);
186188
PROPERTY(Property, CanHaveRanges);
@@ -826,6 +828,23 @@ class LVScopeTemplatePack final : public LVScope {
826828
void printExtra(raw_ostream &OS, bool Full = true) const override;
827829
};
828830

831+
// Class to represent a DWARF Module.
832+
class LVScopeModule final : public LVScope {
833+
public:
834+
LVScopeModule() : LVScope() {
835+
setIsModule();
836+
setIsLexicalBlock();
837+
}
838+
LVScopeModule(const LVScopeModule &) = delete;
839+
LVScopeModule &operator=(const LVScopeModule &) = delete;
840+
~LVScopeModule() = default;
841+
842+
// Returns true if current scope is logically equal to the given 'Scope'.
843+
bool equals(const LVScope *Scope) const override;
844+
845+
void printExtra(raw_ostream &OS, bool Full = true) const override;
846+
};
847+
829848
} // end namespace logicalview
830849
} // end namespace llvm
831850

llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const char *const KindEnumeration = "Enumeration";
3434
const char *const KindFile = "File";
3535
const char *const KindFunction = "Function";
3636
const char *const KindInlinedFunction = "InlinedFunction";
37+
const char *const KindModule = "Module";
3738
const char *const KindNamespace = "Namespace";
3839
const char *const KindStruct = "Struct";
3940
const char *const KindTemplateAlias = "TemplateAlias";
@@ -50,6 +51,8 @@ const char *LVScope::kind() const {
5051
const char *Kind = KindUndefined;
5152
if (getIsArray())
5253
Kind = KindArray;
54+
else if (getIsModule())
55+
Kind = KindModule;
5356
else if (getIsBlock())
5457
Kind = KindBlock;
5558
else if (getIsCallSite())
@@ -94,6 +97,7 @@ LVScopeDispatch LVScope::Dispatch = {
9497
{LVScopeKind::IsInlinedFunction, &LVScope::getIsInlinedFunction},
9598
{LVScopeKind::IsLabel, &LVScope::getIsLabel},
9699
{LVScopeKind::IsLexicalBlock, &LVScope::getIsLexicalBlock},
100+
{LVScopeKind::IsModule, &LVScope::getIsModule},
97101
{LVScopeKind::IsNamespace, &LVScope::getIsNamespace},
98102
{LVScopeKind::IsRoot, &LVScope::getIsRoot},
99103
{LVScopeKind::IsStructure, &LVScope::getIsStructure},
@@ -2107,3 +2111,15 @@ bool LVScopeTemplatePack::equals(const LVScope *Scope) const {
21072111
void LVScopeTemplatePack::printExtra(raw_ostream &OS, bool Full) const {
21082112
OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
21092113
}
2114+
2115+
//===----------------------------------------------------------------------===//
2116+
// DWARF module (DW_TAG_module).
2117+
//===----------------------------------------------------------------------===//
2118+
bool LVScopeModule::equals(const LVScope *Scope) const {
2119+
// For lexical blocks, LVScope::equals() compares the parent scope.
2120+
return LVScope::equals(Scope) && (Scope->getName() == getName());
2121+
}
2122+
2123+
void LVScopeModule::printExtra(raw_ostream &OS, bool Full) const {
2124+
OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
2125+
}

llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ LVElement *LVDWARFReader::createElement(dwarf::Tag Tag) {
233233
case dwarf::DW_TAG_GNU_template_parameter_pack:
234234
CurrentScope = createScopeTemplatePack();
235235
return CurrentScope;
236+
case dwarf::DW_TAG_module:
237+
CurrentScope = createScopeModule();
238+
return CurrentScope;
236239
default:
237240
// Collect TAGs not implemented.
238241
if (options().getInternalTag() && Tag)

llvm/tools/llvm-debuginfo-analyzer/Options.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ cl::list<LVScopeKind> cmdline::SelectScopes(
354354
clEnumValN(LVScopeKind::IsLabel, "Label", "Label."),
355355
clEnumValN(LVScopeKind::IsLexicalBlock, "LexicalBlock",
356356
"Lexical block."),
357+
clEnumValN(LVScopeKind::IsModule, "Module", "Module."),
357358
clEnumValN(LVScopeKind::IsNamespace, "Namespace", "Namespace."),
358359
clEnumValN(LVScopeKind::IsRoot, "Root", "Root."),
359360
clEnumValN(LVScopeKind::IsStructure, "Structure", "Structure."),

llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ extern const char *TestMainArgv0;
3030
namespace {
3131

3232
const char *DwarfClang = "test-dwarf-clang.o";
33+
const char *DwarfClangModule = "test-dwarf-clang-module.o";
3334
const char *DwarfGcc = "test-dwarf-gcc.o";
3435

3536
// Helper function to get the first compile unit.
@@ -124,6 +125,22 @@ void checkElementProperties(LVReader *Reader) {
124125
ASSERT_EQ(Lines->size(), 0x12u);
125126
}
126127

128+
// Check the basic properties on parsed DW_TAG_module.
129+
void checkScopeModule(LVReader *Reader) {
130+
LVScopeRoot *Root = Reader->getScopesRoot();
131+
LVScopeCompileUnit *CompileUnit = getFirstCompileUnit(Root);
132+
133+
EXPECT_EQ(Root->getFileFormatName(), "Mach-O 64-bit x86-64");
134+
EXPECT_EQ(Root->getName(), DwarfClangModule);
135+
136+
ASSERT_NE(CompileUnit->getChildren(), nullptr);
137+
LVElement *FirstChild = *(CompileUnit->getChildren()->begin());
138+
EXPECT_EQ(FirstChild->getIsScope(), 1);
139+
LVScopeModule *Module = static_cast<LVScopeModule *>(FirstChild);
140+
EXPECT_EQ(Module->getIsModule(), 1);
141+
EXPECT_EQ(Module->getName(), "DebugModule");
142+
}
143+
127144
// Check the logical elements selection.
128145
void checkElementSelection(LVReader *Reader) {
129146
LVScopeRoot *Root = Reader->getScopesRoot();
@@ -264,6 +281,9 @@ void elementProperties(SmallString<128> &InputsDir) {
264281
std::unique_ptr<LVReader> Reader =
265282
createReader(ReaderHandler, InputsDir, DwarfClang);
266283
checkElementProperties(Reader.get());
284+
285+
Reader = createReader(ReaderHandler, InputsDir, DwarfClangModule);
286+
checkScopeModule(Reader.get());
267287
}
268288

269289
// Logical elements selection.
Binary file not shown.

0 commit comments

Comments
 (0)