Skip to content

Commit ce0fb39

Browse files
committed
[llvm-debuginfo-analyzer] Remove LVScope::Children container
Remove the `LVScope::Children` container and use `llvm::concat()` instead to return a view over the types, symbols, and sub-scopes contained in a given `LVScope`.
1 parent 7d7a6a6 commit ce0fb39

File tree

3 files changed

+60
-58
lines changed

3 files changed

+60
-58
lines changed

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

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H
1515
#define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H
1616

17+
#include "llvm/ADT/STLExtras.h"
1718
#include "llvm/DebugInfo/LogicalView/Core/LVElement.h"
1819
#include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"
1920
#include "llvm/DebugInfo/LogicalView/Core/LVSort.h"
@@ -94,6 +95,11 @@ class LLVM_ABI LVScope : public LVElement {
9495
LVProperties<LVScopeKind> Kinds;
9596
LVProperties<Property> Properties;
9697
static LVScopeDispatch Dispatch;
98+
// Empty containers used in `getChildren()` in case there is no Types,
99+
// Symbols, or Scopes.
100+
static const LVTypes EmptyTypes;
101+
static const LVSymbols EmptySymbols;
102+
static const LVScopes EmptyScopes;
97103

98104
// Size in bits if this scope represents also a compound type.
99105
uint32_t BitSize = 0;
@@ -128,14 +134,6 @@ class LLVM_ABI LVScope : public LVElement {
128134
std::unique_ptr<LVLines> Lines;
129135
std::unique_ptr<LVLocations> Ranges;
130136

131-
// Vector of elements (types, scopes and symbols).
132-
// It is the union of (*Types, *Symbols and *Scopes) to be used for
133-
// the following reasons:
134-
// - Preserve the order the logical elements are read in.
135-
// - To have a single container with all the logical elements, when
136-
// the traversal does not require any specific element kind.
137-
std::unique_ptr<LVElements> Children;
138-
139137
// Resolve the template parameters/arguments relationship.
140138
void resolveTemplate();
141139
void printEncodedArgs(raw_ostream &OS, bool Full) const;
@@ -213,7 +211,14 @@ class LLVM_ABI LVScope : public LVElement {
213211
const LVScopes *getScopes() const { return Scopes.get(); }
214212
const LVSymbols *getSymbols() const { return Symbols.get(); }
215213
const LVTypes *getTypes() const { return Types.get(); }
216-
const LVElements *getChildren() const { return Children.get(); }
214+
// Return view over union of child Types, Symbols, and Scopes.
215+
auto getUnsortedChildren() const {
216+
return llvm::concat<LVElement *const>(Types ? *Types : EmptyTypes,
217+
Symbols ? *Symbols : EmptySymbols,
218+
Scopes ? *Scopes : EmptyScopes);
219+
}
220+
// Return sorted children (see `LVOptions::setSortMode()`).
221+
LVElements getChildren() const;
217222

218223
void addElement(LVElement *Element);
219224
void addElement(LVLine *Line);
@@ -222,7 +227,6 @@ class LLVM_ABI LVScope : public LVElement {
222227
void addElement(LVType *Type);
223228
void addObject(LVLocation *Location);
224229
void addObject(LVAddress LowerAddress, LVAddress UpperAddress);
225-
void addToChildren(LVElement *Element);
226230

227231
// Add the missing elements from the given 'Reference', which is the
228232
// scope associated with any DW_AT_specification, DW_AT_abstract_origin.

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

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,22 @@ LVScopeDispatch LVScope::Dispatch = {
107107
{LVScopeKind::IsTryBlock, &LVScope::getIsTryBlock},
108108
{LVScopeKind::IsUnion, &LVScope::getIsUnion}};
109109

110-
void LVScope::addToChildren(LVElement *Element) {
111-
if (!Children)
112-
Children = std::make_unique<LVElements>();
113-
Children->push_back(Element);
110+
const LVTypes LVScope::EmptyTypes{};
111+
const LVSymbols LVScope::EmptySymbols{};
112+
const LVScopes LVScope::EmptyScopes{};
113+
114+
LVElements LVScope::getChildren() const {
115+
LVElements Elements(getUnsortedChildren());
116+
if (LVSortFunction SortFunction = getSortFunction()) {
117+
llvm::stable_sort(Elements, SortFunction);
118+
} else {
119+
// No specific sort function, sort by `LVObject::ID` which replicates the
120+
// order in which the elements were created.
121+
llvm::stable_sort(Elements, [](const LVObject *LHS, const LVObject *RHS) {
122+
return LHS.ID < RHS.ID;
123+
});
124+
}
125+
return Elements;
114126
}
115127

116128
void LVScope::addElement(LVElement *Element) {
@@ -175,7 +187,6 @@ void LVScope::addElement(LVScope *Scope) {
175187

176188
// Add it to parent.
177189
Scopes->push_back(Scope);
178-
addToChildren(Scope);
179190
Scope->setParent(this);
180191

181192
// Notify the reader about the new element being added.
@@ -202,7 +213,6 @@ void LVScope::addElement(LVSymbol *Symbol) {
202213

203214
// Add it to parent.
204215
Symbols->push_back(Symbol);
205-
addToChildren(Symbol);
206216
Symbol->setParent(this);
207217

208218
// Notify the reader about the new element being added.
@@ -229,7 +239,6 @@ void LVScope::addElement(LVType *Type) {
229239

230240
// Add it to parent.
231241
Types->push_back(Type);
232-
addToChildren(Type);
233242
Type->setParent(this);
234243

235244
// Notify the reader about the new element being added.
@@ -277,15 +286,12 @@ bool LVScope::removeElement(LVElement *Element) {
277286
if (Element->getIsLine())
278287
return RemoveElement(Lines);
279288

280-
if (RemoveElement(Children)) {
281-
if (Element->getIsSymbol())
282-
return RemoveElement(Symbols);
283-
if (Element->getIsType())
284-
return RemoveElement(Types);
285-
if (Element->getIsScope())
286-
return RemoveElement(Scopes);
287-
llvm_unreachable("Invalid element.");
288-
}
289+
if (Element->getIsSymbol())
290+
return RemoveElement(Symbols);
291+
if (Element->getIsType())
292+
return RemoveElement(Types);
293+
if (Element->getIsScope())
294+
return RemoveElement(Scopes);
289295

290296
return false;
291297
}
@@ -356,9 +362,8 @@ void LVScope::updateLevel(LVScope *Parent, bool Moved) {
356362
setLevel(Parent->getLevel() + 1);
357363

358364
// Update the children.
359-
if (Children)
360-
for (LVElement *Element : *Children)
361-
Element->updateLevel(this, Moved);
365+
for (LVElement *Element : getChildren())
366+
Element->updateLevel(this, Moved);
362367

363368
// Update any lines.
364369
if (Lines)
@@ -374,13 +379,12 @@ void LVScope::resolve() {
374379
LVElement::resolve();
375380

376381
// Resolve the children.
377-
if (Children)
378-
for (LVElement *Element : *Children) {
379-
if (getIsGlobalReference())
380-
// If the scope is a global reference, mark all its children as well.
381-
Element->setIsGlobalReference();
382-
Element->resolve();
383-
}
382+
for (LVElement *Element : getChildren()) {
383+
if (getIsGlobalReference())
384+
// If the scope is a global reference, mark all its children as well.
385+
Element->setIsGlobalReference();
386+
Element->resolve();
387+
}
384388
}
385389

386390
void LVScope::resolveName() {
@@ -633,14 +637,13 @@ Error LVScope::doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
633637
options().getPrintFormatting() &&
634638
getLevel() < options().getOutputLevel()) {
635639
// Print the children.
636-
if (Children)
637-
for (const LVElement *Element : *Children) {
638-
if (Match && !Element->getHasPattern())
639-
continue;
640-
if (Error Err =
641-
Element->doPrint(Split, Match, Print, *StreamSplit, Full))
642-
return Err;
643-
}
640+
for (const LVElement *Element : getChildren()) {
641+
if (Match && !Element->getHasPattern())
642+
continue;
643+
if (Error Err =
644+
Element->doPrint(Split, Match, Print, *StreamSplit, Full))
645+
return Err;
646+
}
644647

645648
// Print the line records.
646649
if (Lines)
@@ -692,7 +695,6 @@ void LVScope::sort() {
692695
Traverse(Parent->Symbols, SortFunction);
693696
Traverse(Parent->Scopes, SortFunction);
694697
Traverse(Parent->Ranges, compareRange);
695-
Traverse(Parent->Children, SortFunction);
696698

697699
if (Parent->Scopes)
698700
for (LVScope *Scope : *Parent->Scopes)
@@ -978,9 +980,8 @@ bool LVScope::equals(const LVScopes *References, const LVScopes *Targets) {
978980
void LVScope::report(LVComparePass Pass) {
979981
getComparator().printItem(this, Pass);
980982
getComparator().push(this);
981-
if (Children)
982-
for (LVElement *Element : *Children)
983-
Element->report(Pass);
983+
for (LVElement *Element : getChildren())
984+
Element->report(Pass);
984985

985986
if (Lines)
986987
for (LVLine *Line : *Lines)
@@ -1656,9 +1657,8 @@ void LVScopeCompileUnit::printMatchedElements(raw_ostream &OS,
16561657
// Print the view for the matched scopes.
16571658
for (const LVScope *Scope : MatchedScopes) {
16581659
Scope->print(OS);
1659-
if (const LVElements *Elements = Scope->getChildren())
1660-
for (LVElement *Element : *Elements)
1661-
Element->print(OS);
1660+
for (LVElement *Element : Scope->getChildren())
1661+
Element->print(OS);
16621662
}
16631663
}
16641664

llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,12 @@ void checkUnspecifiedParameters(LVReader *Reader) {
163163
LVPublicNames::const_iterator IterNames = PublicNames.cbegin();
164164
LVScope *Function = (*IterNames).first;
165165
EXPECT_EQ(Function->getName(), "foo_printf");
166-
const LVElements *Elements = Function->getChildren();
167-
ASSERT_NE(Elements, nullptr);
166+
const auto Elements = Function->getChildren();
168167
// foo_printf is a variadic function whose prototype is
169168
// `int foo_printf(const char *, ...)`, where the '...' is represented by a
170169
// DW_TAG_unspecified_parameters, i.e. we expect to find at least one child
171170
// for which getIsUnspecified() returns true.
172-
EXPECT_TRUE(llvm::any_of(*Elements, [](const LVElement *elt) {
171+
EXPECT_TRUE(llvm::any_of(Elements, [](const LVElement *elt) {
173172
return elt->getIsSymbol() &&
174173
static_cast<const LVSymbol *>(elt)->getIsUnspecified();
175174
}));
@@ -183,10 +182,9 @@ void checkScopeModule(LVReader *Reader) {
183182
EXPECT_EQ(Root->getFileFormatName(), "Mach-O 64-bit x86-64");
184183
EXPECT_EQ(Root->getName(), DwarfClangModule);
185184

186-
ASSERT_NE(CompileUnit->getChildren(), nullptr);
187-
LVElement *FirstChild = *(CompileUnit->getChildren()->begin());
188-
EXPECT_EQ(FirstChild->getIsScope(), 1);
189-
LVScopeModule *Module = static_cast<LVScopeModule *>(FirstChild);
185+
ASSERT_NE(CompileUnit->getScopes(), nullptr);
186+
LVElement *FirstScope = *(CompileUnit->getScopes()->begin());
187+
LVScopeModule *Module = static_cast<LVScopeModule *>(FirstScope);
190188
EXPECT_EQ(Module->getIsModule(), 1);
191189
EXPECT_EQ(Module->getName(), "DebugModule");
192190
}

0 commit comments

Comments
 (0)