Skip to content

Commit 2c8b270

Browse files
committed
[llvm-debuginfo-analyzer] Add support for parsing DWARF DW_TAG_module
1 parent 65fde25 commit 2c8b270

File tree

7 files changed

+62
-1
lines changed

7 files changed

+62
-1
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ enum class LVSubclassID : unsigned char {
4545
LV_SCOPE_NAMESPACE,
4646
LV_SCOPE_ROOT,
4747
LV_SCOPE_TEMPLATE_PACK,
48+
LV_SCOPE_MODULE,
4849
LV_SCOPE_LAST,
4950
LV_SYMBOL_FIRST,
5051
LV_SYMBOL,

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

+2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ class LVReader {
107107
LV_OBJECT_ALLOCATOR(ScopeNamespace)
108108
LV_OBJECT_ALLOCATOR(ScopeRoot)
109109
LV_OBJECT_ALLOCATOR(ScopeTemplatePack)
110+
LV_OBJECT_ALLOCATOR(ScopeModule)
110111

111112
// Symbols allocator.
112113
LV_OBJECT_ALLOCATOR(Symbol)
@@ -213,6 +214,7 @@ class LVReader {
213214
LV_CREATE_OBJECT(ScopeNamespace)
214215
LV_CREATE_OBJECT(ScopeRoot)
215216
LV_CREATE_OBJECT(ScopeTemplatePack)
217+
LV_CREATE_OBJECT(ScopeModule)
216218

217219
// Symbols creation.
218220
LV_CREATE_OBJECT(Symbol)

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

+19
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ enum class LVScopeKind {
5757
IsTemplatePack,
5858
IsTryBlock,
5959
IsUnion,
60+
IsModule,
6061
LastEntry
6162
};
6263
using LVScopeKindSet = std::set<LVScopeKind>;
@@ -184,6 +185,7 @@ class LVScope : public LVElement {
184185
KIND(LVScopeKind, IsTemplatePack);
185186
KIND_1(LVScopeKind, IsTryBlock, IsBlock);
186187
KIND_1(LVScopeKind, IsUnion, IsAggregate);
188+
KIND_3(LVScopeKind, IsModule, CanHaveRanges, CanHaveLines, TransformName);
187189

188190
PROPERTY(Property, HasDiscriminator);
189191
PROPERTY(Property, CanHaveRanges);
@@ -832,6 +834,23 @@ class LVScopeTemplatePack final : public LVScope {
832834
void printExtra(raw_ostream &OS, bool Full = true) const override;
833835
};
834836

837+
// Class to represent a DWARF Module.
838+
class LVScopeModule final : public LVScope {
839+
public:
840+
LVScopeModule() : LVScope() {
841+
setIsModule();
842+
setIsLexicalBlock();
843+
}
844+
LVScopeModule(const LVScopeModule &) = delete;
845+
LVScopeModule &operator=(const LVScopeModule &) = delete;
846+
~LVScopeModule() = default;
847+
848+
// Returns true if current scope is logically equal to the given 'Scope'.
849+
bool equals(const LVScope *Scope) const override;
850+
851+
void printExtra(raw_ostream &OS, bool Full = true) const override;
852+
};
853+
835854
} // end namespace logicalview
836855
} // end namespace llvm
837856

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

+17-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const char *const KindTemplateAlias = "TemplateAlias";
4040
const char *const KindTemplatePack = "TemplatePack";
4141
const char *const KindUndefined = "Undefined";
4242
const char *const KindUnion = "Union";
43+
const char *const KindModule = "Module";
4344
} // end anonymous namespace
4445

4546
//===----------------------------------------------------------------------===//
@@ -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())
@@ -101,7 +104,8 @@ LVScopeDispatch LVScope::Dispatch = {
101104
{LVScopeKind::IsTemplateAlias, &LVScope::getIsTemplateAlias},
102105
{LVScopeKind::IsTemplatePack, &LVScope::getIsTemplatePack},
103106
{LVScopeKind::IsTryBlock, &LVScope::getIsTryBlock},
104-
{LVScopeKind::IsUnion, &LVScope::getIsUnion}};
107+
{LVScopeKind::IsUnion, &LVScope::getIsUnion},
108+
{LVScopeKind::IsModule, &LVScope::getIsModule}};
105109

106110
void LVScope::addToChildren(LVElement *Element) {
107111
if (!Children)
@@ -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

+3
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/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp

+20
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();
@@ -270,6 +287,9 @@ void elementProperties(SmallString<128> &InputsDir) {
270287
std::unique_ptr<LVReader> Reader =
271288
createReader(ReaderHandler, InputsDir, DwarfClang);
272289
checkElementProperties(Reader.get());
290+
291+
Reader = createReader(ReaderHandler, InputsDir, DwarfClangModule);
292+
checkScopeModule(Reader.get());
273293
}
274294

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

0 commit comments

Comments
 (0)