[llvm] [llvm-debuginfo-analyzer] Remove `LVScope::Children` container (PR #144750)
Javier Lopez-Gomez via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 24 06:49:13 PDT 2025
https://github.com/jalopezg-git updated https://github.com/llvm/llvm-project/pull/144750
>From 24cad3a59a85b596b57f395779903a8dc77f54e7 Mon Sep 17 00:00:00 2001
From: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Date: Tue, 24 Jun 2025 15:48:57 +0200
Subject: [PATCH 1/3] [ADT] Fix llvm::concat_iterator for `ValueT ==
common_base_class *`
Fix llvm::concat_iterator for the case of `ValueT` being a pointer
to a common base class to which the result of dereferencing any
iterator in `ItersT` can be casted to.
---
llvm/include/llvm/ADT/STLExtras.h | 29 ++++++++++++++++++++--------
llvm/unittests/ADT/STLExtrasTest.cpp | 29 ++++++++++++++++++++++++++++
2 files changed, 50 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h
index eea06cfb99ba2..d2010e663ebed 100644
--- a/llvm/include/llvm/ADT/STLExtras.h
+++ b/llvm/include/llvm/ADT/STLExtras.h
@@ -1032,13 +1032,22 @@ class concat_iterator
static constexpr bool ReturnsByValue =
!(std::is_reference_v<decltype(*std::declval<IterTs>())> && ...);
+ static constexpr bool ReturnsConvertiblePointer =
+ std::is_pointer_v<ValueT> &&
+ (std::is_convertible_v<decltype(*std::declval<IterTs>()), ValueT> && ...);
using reference_type =
- typename std::conditional_t<ReturnsByValue, ValueT, ValueT &>;
-
- using handle_type =
- typename std::conditional_t<ReturnsByValue, std::optional<ValueT>,
- ValueT *>;
+ typename std::conditional_t<ReturnsByValue || ReturnsConvertiblePointer,
+ ValueT, ValueT &>;
+
+ using optional_value_type =
+ std::conditional_t<ReturnsByValue, std::optional<ValueT>, ValueT *>;
+ // handle_type is used to return an optional value from `getHelper()`. If
+ // the type resulting from dereferencing all IterTs is a pointer that can be
+ // converted to `ValueT`, use that pointer type instead to avoid implicit
+ // conversion issues.
+ using handle_type = typename std::conditional_t<ReturnsConvertiblePointer,
+ ValueT, optional_value_type>;
/// We store both the current and end iterators for each concatenated
/// sequence in a tuple of pairs.
@@ -1088,7 +1097,7 @@ class concat_iterator
if (Begin == End)
return {};
- if constexpr (ReturnsByValue)
+ if constexpr (ReturnsByValue || ReturnsConvertiblePointer)
return *Begin;
else
return &*Begin;
@@ -1105,8 +1114,12 @@ class concat_iterator
// Loop over them, and return the first result we find.
for (auto &GetHelperFn : GetHelperFns)
- if (auto P = (this->*GetHelperFn)())
- return *P;
+ if (auto P = (this->*GetHelperFn)()) {
+ if constexpr (ReturnsConvertiblePointer)
+ return P;
+ else
+ return *P;
+ }
llvm_unreachable("Attempted to get a pointer from an end concat iterator!");
}
diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
index 286cfa745fd14..6d893c2295819 100644
--- a/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -398,6 +398,8 @@ struct some_struct {
std::string swap_val;
};
+struct derives_from_some_struct : some_struct {};
+
std::vector<int>::const_iterator begin(const some_struct &s) {
return s.data.begin();
}
@@ -532,6 +534,33 @@ TEST(STLExtrasTest, ConcatRangeADL) {
EXPECT_THAT(concat<const int>(S0, S1), ElementsAre(1, 2, 3, 4));
}
+TEST(STLExtrasTest, ConcatRangeRef) {
+ SmallVector<some_namespace::some_struct> V12{{{1, 2}, "V12[0]"}};
+ SmallVector<some_namespace::some_struct> V3456{{{3, 4}, "V3456[0]"},
+ {{5, 6}, "V3456[1]"}};
+
+ // Use concat with `iterator type = some_namespace::some_struct *` and value
+ // being a reference type.
+ std::vector<some_namespace::some_struct *> Expected = {&V12[0], &V3456[0],
+ &V3456[1]};
+ std::vector<some_namespace::some_struct *> Test;
+ for (auto &i : concat<some_namespace::some_struct>(V12, V3456))
+ Test.push_back(&i);
+ EXPECT_EQ(Expected, Test);
+}
+
+TEST(STLExtrasTest, ConcatRangePtrToDerivedClass) {
+ some_namespace::some_struct S0{};
+ some_namespace::derives_from_some_struct S1{};
+ SmallVector<some_namespace::some_struct *> V0{&S0};
+ SmallVector<some_namespace::derives_from_some_struct *> V1{&S1, &S1};
+
+ // Use concat over ranges of pointers to different (but related) types.
+ EXPECT_THAT(concat<some_namespace::some_struct *>(V0, V1),
+ ElementsAre(&S0, static_cast<some_namespace::some_struct *>(&S1),
+ static_cast<some_namespace::some_struct *>(&S1)));
+}
+
TEST(STLExtrasTest, MakeFirstSecondRangeADL) {
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
// using ADL.
>From c5cea0958e8ab36e944a2a815979630eb51ae2b0 Mon Sep 17 00:00:00 2001
From: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Date: Tue, 24 Jun 2025 15:48:57 +0200
Subject: [PATCH 2/3] [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`.
---
.../llvm/DebugInfo/LogicalView/Core/LVScope.h | 24 +++---
.../llvm/DebugInfo/LogicalView/Core/LVSort.h | 1 +
.../DebugInfo/LogicalView/Core/LVScope.cpp | 83 ++++++++++---------
.../lib/DebugInfo/LogicalView/Core/LVSort.cpp | 52 ++++++++----
.../01-dwarf-compare-logical-elements.test | 2 +-
.../pr-57040-incorrect-function-compare.test | 2 +-
.../01-wasm-compare-logical-elements.test | 2 +-
.../DebugInfo/LogicalView/DWARFReaderTest.cpp | 12 ++-
8 files changed, 99 insertions(+), 79 deletions(-)
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
index a453923d032e4..23ca291a00bbc 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
@@ -14,6 +14,7 @@
#ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H
#define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/LogicalView/Core/LVElement.h"
#include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"
#include "llvm/DebugInfo/LogicalView/Core/LVSort.h"
@@ -94,6 +95,11 @@ class LLVM_ABI LVScope : public LVElement {
LVProperties<LVScopeKind> Kinds;
LVProperties<Property> Properties;
static LVScopeDispatch Dispatch;
+ // Empty containers used in `getChildren()` in case there is no Types,
+ // Symbols, or Scopes.
+ static const LVTypes EmptyTypes;
+ static const LVSymbols EmptySymbols;
+ static const LVScopes EmptyScopes;
// Size in bits if this scope represents also a compound type.
uint32_t BitSize = 0;
@@ -128,14 +134,6 @@ class LLVM_ABI LVScope : public LVElement {
std::unique_ptr<LVLines> Lines;
std::unique_ptr<LVLocations> Ranges;
- // Vector of elements (types, scopes and symbols).
- // It is the union of (*Types, *Symbols and *Scopes) to be used for
- // the following reasons:
- // - Preserve the order the logical elements are read in.
- // - To have a single container with all the logical elements, when
- // the traversal does not require any specific element kind.
- std::unique_ptr<LVElements> Children;
-
// Resolve the template parameters/arguments relationship.
void resolveTemplate();
void printEncodedArgs(raw_ostream &OS, bool Full) const;
@@ -213,7 +211,14 @@ class LLVM_ABI LVScope : public LVElement {
const LVScopes *getScopes() const { return Scopes.get(); }
const LVSymbols *getSymbols() const { return Symbols.get(); }
const LVTypes *getTypes() const { return Types.get(); }
- const LVElements *getChildren() const { return Children.get(); }
+ // Return view over union of child Types, Symbols, and Scopes.
+ auto getUnsortedChildren() const {
+ return llvm::concat<LVElement *const>(Scopes ? *Scopes : EmptyScopes,
+ Types ? *Types : EmptyTypes,
+ Symbols ? *Symbols : EmptySymbols);
+ }
+ // Return sorted children (see `LVOptions::setSortMode()`).
+ LVElements getChildren() const;
void addElement(LVElement *Element);
void addElement(LVLine *Line);
@@ -222,7 +227,6 @@ class LLVM_ABI LVScope : public LVElement {
void addElement(LVType *Type);
void addObject(LVLocation *Location);
void addObject(LVAddress LowerAddress, LVAddress UpperAddress);
- void addToChildren(LVElement *Element);
// Add the missing elements from the given 'Reference', which is the
// scope associated with any DW_AT_specification, DW_AT_abstract_origin.
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSort.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSort.h
index c8c7310281566..e92fd809d4aeb 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSort.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSort.h
@@ -46,6 +46,7 @@ LLVM_ABI LVSortValue compareRange(const LVObject *LHS, const LVObject *RHS);
LLVM_ABI LVSortValue sortByKind(const LVObject *LHS, const LVObject *RHS);
LLVM_ABI LVSortValue sortByLine(const LVObject *LHS, const LVObject *RHS);
LLVM_ABI LVSortValue sortByName(const LVObject *LHS, const LVObject *RHS);
+LLVM_ABI LVSortValue sortByOffset(const LVObject *LHS, const LVObject *RHS);
} // end namespace logicalview
} // end namespace llvm
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
index 55880fab5e88e..a36315b2c513d 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
@@ -107,10 +107,23 @@ LVScopeDispatch LVScope::Dispatch = {
{LVScopeKind::IsTryBlock, &LVScope::getIsTryBlock},
{LVScopeKind::IsUnion, &LVScope::getIsUnion}};
-void LVScope::addToChildren(LVElement *Element) {
- if (!Children)
- Children = std::make_unique<LVElements>();
- Children->push_back(Element);
+const LVTypes LVScope::EmptyTypes{};
+const LVSymbols LVScope::EmptySymbols{};
+const LVScopes LVScope::EmptyScopes{};
+
+LVElements LVScope::getChildren() const {
+ const auto UnsortedChildren = getUnsortedChildren();
+ LVElements Elements{UnsortedChildren.begin(), UnsortedChildren.end()};
+ if (LVSortFunction SortFunction = getSortFunction()) {
+ llvm::stable_sort(Elements, SortFunction);
+ } else {
+ // No specific sort function, sort by `LVObject::ID` which replicates the
+ // order in which the elements were created.
+ llvm::stable_sort(Elements, [](const LVObject *LHS, const LVObject *RHS) {
+ return LHS->getID() < RHS->getID();
+ });
+ }
+ return Elements;
}
void LVScope::addElement(LVElement *Element) {
@@ -175,7 +188,6 @@ void LVScope::addElement(LVScope *Scope) {
// Add it to parent.
Scopes->push_back(Scope);
- addToChildren(Scope);
Scope->setParent(this);
// Notify the reader about the new element being added.
@@ -202,7 +214,6 @@ void LVScope::addElement(LVSymbol *Symbol) {
// Add it to parent.
Symbols->push_back(Symbol);
- addToChildren(Symbol);
Symbol->setParent(this);
// Notify the reader about the new element being added.
@@ -229,7 +240,6 @@ void LVScope::addElement(LVType *Type) {
// Add it to parent.
Types->push_back(Type);
- addToChildren(Type);
Type->setParent(this);
// Notify the reader about the new element being added.
@@ -277,15 +287,12 @@ bool LVScope::removeElement(LVElement *Element) {
if (Element->getIsLine())
return RemoveElement(Lines);
- if (RemoveElement(Children)) {
- if (Element->getIsSymbol())
- return RemoveElement(Symbols);
- if (Element->getIsType())
- return RemoveElement(Types);
- if (Element->getIsScope())
- return RemoveElement(Scopes);
- llvm_unreachable("Invalid element.");
- }
+ if (Element->getIsSymbol())
+ return RemoveElement(Symbols);
+ if (Element->getIsType())
+ return RemoveElement(Types);
+ if (Element->getIsScope())
+ return RemoveElement(Scopes);
return false;
}
@@ -356,9 +363,8 @@ void LVScope::updateLevel(LVScope *Parent, bool Moved) {
setLevel(Parent->getLevel() + 1);
// Update the children.
- if (Children)
- for (LVElement *Element : *Children)
- Element->updateLevel(this, Moved);
+ for (LVElement *Element : getUnsortedChildren())
+ Element->updateLevel(this, Moved);
// Update any lines.
if (Lines)
@@ -374,13 +380,12 @@ void LVScope::resolve() {
LVElement::resolve();
// Resolve the children.
- if (Children)
- for (LVElement *Element : *Children) {
- if (getIsGlobalReference())
- // If the scope is a global reference, mark all its children as well.
- Element->setIsGlobalReference();
- Element->resolve();
- }
+ for (LVElement *Element : getUnsortedChildren()) {
+ if (getIsGlobalReference())
+ // If the scope is a global reference, mark all its children as well.
+ Element->setIsGlobalReference();
+ Element->resolve();
+ }
}
void LVScope::resolveName() {
@@ -633,14 +638,13 @@ Error LVScope::doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
options().getPrintFormatting() &&
getLevel() < options().getOutputLevel()) {
// Print the children.
- if (Children)
- for (const LVElement *Element : *Children) {
- if (Match && !Element->getHasPattern())
- continue;
- if (Error Err =
- Element->doPrint(Split, Match, Print, *StreamSplit, Full))
- return Err;
- }
+ for (const LVElement *Element : getChildren()) {
+ if (Match && !Element->getHasPattern())
+ continue;
+ if (Error Err =
+ Element->doPrint(Split, Match, Print, *StreamSplit, Full))
+ return Err;
+ }
// Print the line records.
if (Lines)
@@ -692,7 +696,6 @@ void LVScope::sort() {
Traverse(Parent->Symbols, SortFunction);
Traverse(Parent->Scopes, SortFunction);
Traverse(Parent->Ranges, compareRange);
- Traverse(Parent->Children, SortFunction);
if (Parent->Scopes)
for (LVScope *Scope : *Parent->Scopes)
@@ -978,9 +981,8 @@ bool LVScope::equals(const LVScopes *References, const LVScopes *Targets) {
void LVScope::report(LVComparePass Pass) {
getComparator().printItem(this, Pass);
getComparator().push(this);
- if (Children)
- for (LVElement *Element : *Children)
- Element->report(Pass);
+ for (LVElement *Element : getChildren())
+ Element->report(Pass);
if (Lines)
for (LVLine *Line : *Lines)
@@ -1656,9 +1658,8 @@ void LVScopeCompileUnit::printMatchedElements(raw_ostream &OS,
// Print the view for the matched scopes.
for (const LVScope *Scope : MatchedScopes) {
Scope->print(OS);
- if (const LVElements *Elements = Scope->getChildren())
- for (LVElement *Element : *Elements)
- Element->print(OS);
+ for (LVElement *Element : Scope->getChildren())
+ Element->print(OS);
}
}
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVSort.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVSort.cpp
index a58ba4b3cdfbf..1ed951a2f4eed 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVSort.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVSort.cpp
@@ -64,11 +64,13 @@ LVSortValue llvm::logicalview::compareRange(const LVObject *LHS,
LVSortValue llvm::logicalview::sortByKind(const LVObject *LHS,
const LVObject *RHS) {
// Order in which the object attributes are used for comparison:
- // kind, name, line number, offset.
- std::tuple<std::string, StringRef, uint32_t, LVOffset> Left(
- LHS->kind(), LHS->getName(), LHS->getLineNumber(), LHS->getOffset());
- std::tuple<std::string, StringRef, uint32_t, LVOffset> Right(
- RHS->kind(), RHS->getName(), RHS->getLineNumber(), RHS->getOffset());
+ // kind, name, line number, offset, ID.
+ std::tuple<std::string, StringRef, uint32_t, LVOffset, uint32_t> Left(
+ LHS->kind(), LHS->getName(), LHS->getLineNumber(), LHS->getOffset(),
+ LHS->getID());
+ std::tuple<std::string, StringRef, uint32_t, LVOffset, uint32_t> Right(
+ RHS->kind(), RHS->getName(), RHS->getLineNumber(), RHS->getOffset(),
+ RHS->getID());
return Left < Right;
}
@@ -76,11 +78,13 @@ LVSortValue llvm::logicalview::sortByKind(const LVObject *LHS,
LVSortValue llvm::logicalview::sortByLine(const LVObject *LHS,
const LVObject *RHS) {
// Order in which the object attributes are used for comparison:
- // line number, name, kind, offset.
- std::tuple<uint32_t, StringRef, std::string, LVOffset> Left(
- LHS->getLineNumber(), LHS->getName(), LHS->kind(), LHS->getOffset());
- std::tuple<uint32_t, StringRef, std::string, LVOffset> Right(
- RHS->getLineNumber(), RHS->getName(), RHS->kind(), RHS->getOffset());
+ // line number, name, kind, offset, ID.
+ std::tuple<uint32_t, StringRef, std::string, LVOffset, uint32_t> Left(
+ LHS->getLineNumber(), LHS->getName(), LHS->kind(), LHS->getOffset(),
+ LHS->getID());
+ std::tuple<uint32_t, StringRef, std::string, LVOffset, uint32_t> Right(
+ RHS->getLineNumber(), RHS->getName(), RHS->kind(), RHS->getOffset(),
+ RHS->getID());
return Left < Right;
}
@@ -88,20 +92,32 @@ LVSortValue llvm::logicalview::sortByLine(const LVObject *LHS,
LVSortValue llvm::logicalview::sortByName(const LVObject *LHS,
const LVObject *RHS) {
// Order in which the object attributes are used for comparison:
- // name, line number, kind, offset.
- std::tuple<StringRef, uint32_t, std::string, LVOffset> Left(
- LHS->getName(), LHS->getLineNumber(), LHS->kind(), LHS->getOffset());
- std::tuple<StringRef, uint32_t, std::string, LVOffset> Right(
- RHS->getName(), RHS->getLineNumber(), RHS->kind(), RHS->getOffset());
+ // name, line number, kind, offset, ID.
+ std::tuple<StringRef, uint32_t, std::string, LVOffset, uint32_t> Left(
+ LHS->getName(), LHS->getLineNumber(), LHS->kind(), LHS->getOffset(),
+ LHS->getID());
+ std::tuple<StringRef, uint32_t, std::string, LVOffset, uint32_t> Right(
+ RHS->getName(), RHS->getLineNumber(), RHS->kind(), RHS->getOffset(),
+ RHS->getID());
+ return Left < Right;
+}
+
+// Callback comparator based on multiple keys (First: Offset).
+LVSortValue llvm::logicalview::sortByOffset(const LVObject *LHS,
+ const LVObject *RHS) {
+ // Order in which the object attributes are used for comparison:
+ // offset, ID.
+ std::tuple<LVOffset, uint32_t> Left(LHS->getOffset(), LHS->getID());
+ std::tuple<LVOffset, uint32_t> Right(RHS->getOffset(), RHS->getID());
return Left < Right;
}
LVSortFunction llvm::logicalview::getSortFunction() {
using LVSortInfo = std::map<LVSortMode, LVSortFunction>;
static LVSortInfo SortInfo = {
- {LVSortMode::None, nullptr}, {LVSortMode::Kind, sortByKind},
- {LVSortMode::Line, sortByLine}, {LVSortMode::Name, sortByName},
- {LVSortMode::Offset, compareOffset},
+ {LVSortMode::None, nullptr}, {LVSortMode::Kind, sortByKind},
+ {LVSortMode::Line, sortByLine}, {LVSortMode::Name, sortByName},
+ {LVSortMode::Offset, sortByOffset},
};
LVSortFunction SortFunction = nullptr;
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/01-dwarf-compare-logical-elements.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/01-dwarf-compare-logical-elements.test
index a076887140c28..1b790eeb3b691 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/01-dwarf-compare-logical-elements.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/01-dwarf-compare-logical-elements.test
@@ -35,8 +35,8 @@
; ONE-NEXT: [002] 1 {TypeAlias} 'INTPTR' -> '* const int'
; ONE-NEXT: [002] 2 {Function} extern not_inlined 'foo' -> 'int'
; ONE-NEXT: [003] {Block}
-; ONE-NEXT: [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'
; ONE-NEXT: +[004] 4 {TypeAlias} 'INTEGER' -> 'int'
+; ONE-NEXT: [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'
; ONE-NEXT: [003] 2 {Parameter} 'ParamBool' -> 'bool'
; ONE-NEXT: [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR'
; ONE-NEXT: [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/pr-57040-incorrect-function-compare.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/pr-57040-incorrect-function-compare.test
index 278d4f4850f5f..78604d9164c0f 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/pr-57040-incorrect-function-compare.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/pr-57040-incorrect-function-compare.test
@@ -55,8 +55,8 @@
; ONE-NEXT: [002] 1 {TypeAlias} 'INTPTR' -> '* const int'
; ONE-NEXT: [002] 2 {Function} extern not_inlined 'foo' -> 'int'
; ONE-NEXT: [003] {Block}
-; ONE-NEXT: [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'
; ONE-NEXT: +[004] 4 {TypeAlias} 'INTEGER' -> 'int'
+; ONE-NEXT: [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'
; ONE-NEXT: [003] 2 {Parameter} 'ParamBool' -> 'bool'
; ONE-NEXT: [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR'
; ONE-NEXT: [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int'
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/01-wasm-compare-logical-elements.test b/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/01-wasm-compare-logical-elements.test
index f52c9c7cc7164..98fc47e3d3c80 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/01-wasm-compare-logical-elements.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/01-wasm-compare-logical-elements.test
@@ -38,8 +38,8 @@
; ONE-NEXT: [002] 1 {TypeAlias} 'INTPTR' -> '* const int'
; ONE-NEXT: [002] 2 {Function} extern not_inlined 'foo' -> 'int'
; ONE-NEXT: [003] {Block}
-; ONE-NEXT: [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'
; ONE-NEXT: +[004] 4 {TypeAlias} 'INTEGER' -> 'int'
+; ONE-NEXT: [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'
; ONE-NEXT: [003] 2 {Parameter} 'ParamBool' -> 'bool'
; ONE-NEXT: [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR'
; ONE-NEXT: [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int'
diff --git a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
index 544c39a3c7b2e..ba6df7489b750 100644
--- a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
@@ -163,13 +163,12 @@ void checkUnspecifiedParameters(LVReader *Reader) {
LVPublicNames::const_iterator IterNames = PublicNames.cbegin();
LVScope *Function = (*IterNames).first;
EXPECT_EQ(Function->getName(), "foo_printf");
- const LVElements *Elements = Function->getChildren();
- ASSERT_NE(Elements, nullptr);
+ const auto Elements = Function->getChildren();
// foo_printf is a variadic function whose prototype is
// `int foo_printf(const char *, ...)`, where the '...' is represented by a
// DW_TAG_unspecified_parameters, i.e. we expect to find at least one child
// for which getIsUnspecified() returns true.
- EXPECT_TRUE(llvm::any_of(*Elements, [](const LVElement *elt) {
+ EXPECT_TRUE(llvm::any_of(Elements, [](const LVElement *elt) {
return elt->getIsSymbol() &&
static_cast<const LVSymbol *>(elt)->getIsUnspecified();
}));
@@ -183,10 +182,9 @@ void checkScopeModule(LVReader *Reader) {
EXPECT_EQ(Root->getFileFormatName(), "Mach-O 64-bit x86-64");
EXPECT_EQ(Root->getName(), DwarfClangModule);
- ASSERT_NE(CompileUnit->getChildren(), nullptr);
- LVElement *FirstChild = *(CompileUnit->getChildren()->begin());
- EXPECT_EQ(FirstChild->getIsScope(), 1);
- LVScopeModule *Module = static_cast<LVScopeModule *>(FirstChild);
+ ASSERT_NE(CompileUnit->getScopes(), nullptr);
+ LVElement *FirstScope = *(CompileUnit->getScopes()->begin());
+ LVScopeModule *Module = static_cast<LVScopeModule *>(FirstScope);
EXPECT_EQ(Module->getIsModule(), 1);
EXPECT_EQ(Module->getName(), "DebugModule");
}
>From 2e4bf83be1222d5ad7a7fcea70a2c87c59cabb39 Mon Sep 17 00:00:00 2001
From: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Date: Tue, 24 Jun 2025 15:48:57 +0200
Subject: [PATCH 3/3] [llvm-debuginfo-analyzer] Add `--output-sort=none` option
---
llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst | 1 +
llvm/tools/llvm-debuginfo-analyzer/Options.cpp | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst b/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst
index 1264f80206618..956a54e93f93e 100644
--- a/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst
+++ b/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst
@@ -365,6 +365,7 @@ output for a single compilation unit.
.. code-block:: text
+ =none: Unsorted output.
=kind: Sort by element kind.
=line: Sort by element line number.
=name: Sort by element name.
diff --git a/llvm/tools/llvm-debuginfo-analyzer/Options.cpp b/llvm/tools/llvm-debuginfo-analyzer/Options.cpp
index 79e2edccc50b8..b7e337bc21c61 100644
--- a/llvm/tools/llvm-debuginfo-analyzer/Options.cpp
+++ b/llvm/tools/llvm-debuginfo-analyzer/Options.cpp
@@ -198,7 +198,9 @@ static cl::opt<LVSortMode, true> OutputSort(
"output-sort", cl::cat(OutputCategory),
cl::desc("Primary key when ordering logical view (default: line)."),
cl::Hidden, cl::ZeroOrMore,
- values(clEnumValN(LVSortMode::Kind, "kind", "Sort by element kind."),
+ values(clEnumValN(LVSortMode::None, "none",
+ "Unsorted output (i.e. as read from input)."),
+ clEnumValN(LVSortMode::Kind, "kind", "Sort by element kind."),
clEnumValN(LVSortMode::Line, "line", "Sort by element line number."),
clEnumValN(LVSortMode::Name, "name", "Sort by element name."),
clEnumValN(LVSortMode::Offset, "offset", "Sort by element offset.")),
More information about the llvm-commits
mailing list