[Lldb-commits] [lldb] [lldb] Preparation for DWARF indexing speedup (PR #123732)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Jan 21 03:08:04 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Pavel Labath (labath)
<details>
<summary>Changes</summary>
This is part of the work proposed in
<https://discourse.llvm.org/t/rfc-speeding-up-dwarf-indexing-again/83979>. One of the change is that the there will be a different structure for holding the partial indexes and the final (consolidated) index. To prepare for this, I'm making the IndexSet structure a template. The index cache encoding/decoding methods are changed into free functions, as they only need to know how to work with the final index.
I've moved this functionality to a separate file as all this doesn't really depend on the rest of the ManualDWARFIndex and it needs to be public due to its use in the unit test (both of which indicate that it could be a component of its own).
---
Patch is 21.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/123732.diff
6 Files Affected:
- (modified) lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt (+1)
- (modified) lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp (+20-161)
- (modified) lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h (+5-26)
- (added) lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.cpp (+154)
- (added) lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.h (+54)
- (modified) lldb/unittests/SymbolFile/DWARF/DWARFIndexCachingTest.cpp (+6-8)
``````````diff
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
index e87194dfe74cb3..2d2eb73f4513bf 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ b/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -30,6 +30,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
DWARFUnit.cpp
LogChannelDWARF.cpp
ManualDWARFIndex.cpp
+ ManualDWARFIndexSet.cpp
NameToDIE.cpp
SymbolFileDWARF.cpp
SymbolFileDWARFDwo.cpp
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
index 6f2c45e74132c1..9e78b17b8f3a51 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -77,8 +77,10 @@ void ManualDWARFIndex::Index() {
lldb::eDescriptionLevelBrief);
// Include 2 passes per unit to index for extracting DIEs from the unit and
- // indexing the unit, and then 8 extra entries for finalizing each index set.
- const uint64_t total_progress = units_to_index.size() * 2 + 8;
+ // indexing the unit, and then extra entries for finalizing each index in the
+ // set.
+ const auto indices = IndexSet<NameToDIE>::Indices();
+ const uint64_t total_progress = units_to_index.size() * 2 + indices.size();
Progress progress("Manually indexing DWARF", module_desc.GetData(),
total_progress, /*debugger=*/nullptr,
/*minimum_report_time=*/std::chrono::milliseconds(20));
@@ -122,7 +124,7 @@ void ManualDWARFIndex::Index() {
});
// Now index all DWARF unit in parallel.
- std::vector<IndexSet> sets(num_threads);
+ std::vector<IndexSet<NameToDIE>> sets(num_threads);
for_each_unit(
[this, dwp_dwarf, &sets](size_t worker_id, size_t, DWARFUnit *unit) {
IndexUnit(*unit, dwp_dwarf, sets[worker_id]);
@@ -130,29 +132,22 @@ void ManualDWARFIndex::Index() {
// Merge partial indexes into a single index. Process each index in a set in
// parallel.
- auto finalize_fn = [this, &sets, &progress](NameToDIE(IndexSet::*index)) {
- NameToDIE &result = m_set.*index;
- for (auto &set : sets)
- result.Append(set.*index);
- result.Finalize();
- progress.Increment();
- };
-
- task_group.async(finalize_fn, &IndexSet::function_basenames);
- task_group.async(finalize_fn, &IndexSet::function_fullnames);
- task_group.async(finalize_fn, &IndexSet::function_methods);
- task_group.async(finalize_fn, &IndexSet::function_selectors);
- task_group.async(finalize_fn, &IndexSet::objc_class_selectors);
- task_group.async(finalize_fn, &IndexSet::globals);
- task_group.async(finalize_fn, &IndexSet::types);
- task_group.async(finalize_fn, &IndexSet::namespaces);
+ for (NameToDIE IndexSet<NameToDIE>::*index : indices) {
+ task_group.async([this, &sets, index, &progress]() {
+ NameToDIE &result = m_set.*index;
+ for (auto &set : sets)
+ result.Append(set.*index);
+ result.Finalize();
+ progress.Increment();
+ });
+ }
task_group.wait();
SaveToCache();
}
void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp,
- IndexSet &set) {
+ IndexSet<NameToDIE> &set) {
Log *log = GetLog(DWARFLog::Lookups);
if (log) {
@@ -210,7 +205,7 @@ void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp,
void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
const LanguageType cu_language,
- IndexSet &set) {
+ IndexSet<NameToDIE> &set) {
for (const DWARFDebugInfoEntry &die : unit.dies()) {
const dw_tag_t tag = die.Tag();
@@ -555,142 +550,6 @@ void ManualDWARFIndex::Dump(Stream &s) {
m_set.namespaces.Dump(&s);
}
-constexpr llvm::StringLiteral kIdentifierManualDWARFIndex("DIDX");
-// Define IDs for the different tables when encoding and decoding the
-// ManualDWARFIndex NameToDIE objects so we can avoid saving any empty maps.
-enum DataID {
- kDataIDFunctionBasenames = 1u,
- kDataIDFunctionFullnames,
- kDataIDFunctionMethods,
- kDataIDFunctionSelectors,
- kDataIDFunctionObjcClassSelectors,
- kDataIDGlobals,
- kDataIDTypes,
- kDataIDNamespaces,
- kDataIDEnd = 255u,
-
-};
-
-// Version 2 changes the encoding of DIERef objects used in the DWARF manual
-// index name tables. See DIERef class for details.
-constexpr uint32_t CURRENT_CACHE_VERSION = 2;
-
-bool ManualDWARFIndex::IndexSet::Decode(const DataExtractor &data,
- lldb::offset_t *offset_ptr) {
- StringTableReader strtab;
- // We now decode the string table for all strings in the data cache file.
- if (!strtab.Decode(data, offset_ptr))
- return false;
-
- llvm::StringRef identifier((const char *)data.GetData(offset_ptr, 4), 4);
- if (identifier != kIdentifierManualDWARFIndex)
- return false;
- const uint32_t version = data.GetU32(offset_ptr);
- if (version != CURRENT_CACHE_VERSION)
- return false;
-
- bool done = false;
- while (!done) {
- switch (data.GetU8(offset_ptr)) {
- default:
- // If we got here, this is not expected, we expect the data IDs to match
- // one of the values from the DataID enumeration.
- return false;
- case kDataIDFunctionBasenames:
- if (!function_basenames.Decode(data, offset_ptr, strtab))
- return false;
- break;
- case kDataIDFunctionFullnames:
- if (!function_fullnames.Decode(data, offset_ptr, strtab))
- return false;
- break;
- case kDataIDFunctionMethods:
- if (!function_methods.Decode(data, offset_ptr, strtab))
- return false;
- break;
- case kDataIDFunctionSelectors:
- if (!function_selectors.Decode(data, offset_ptr, strtab))
- return false;
- break;
- case kDataIDFunctionObjcClassSelectors:
- if (!objc_class_selectors.Decode(data, offset_ptr, strtab))
- return false;
- break;
- case kDataIDGlobals:
- if (!globals.Decode(data, offset_ptr, strtab))
- return false;
- break;
- case kDataIDTypes:
- if (!types.Decode(data, offset_ptr, strtab))
- return false;
- break;
- case kDataIDNamespaces:
- if (!namespaces.Decode(data, offset_ptr, strtab))
- return false;
- break;
- case kDataIDEnd:
- // We got to the end of our NameToDIE encodings.
- done = true;
- break;
- }
- }
- // Success!
- return true;
-}
-
-void ManualDWARFIndex::IndexSet::Encode(DataEncoder &encoder) const {
- ConstStringTable strtab;
-
- // Encoder the DWARF index into a separate encoder first. This allows us
- // gather all of the strings we willl need in "strtab" as we will need to
- // write the string table out before the symbol table.
- DataEncoder index_encoder(encoder.GetByteOrder(),
- encoder.GetAddressByteSize());
-
- index_encoder.AppendData(kIdentifierManualDWARFIndex);
- // Encode the data version.
- index_encoder.AppendU32(CURRENT_CACHE_VERSION);
-
- if (!function_basenames.IsEmpty()) {
- index_encoder.AppendU8(kDataIDFunctionBasenames);
- function_basenames.Encode(index_encoder, strtab);
- }
- if (!function_fullnames.IsEmpty()) {
- index_encoder.AppendU8(kDataIDFunctionFullnames);
- function_fullnames.Encode(index_encoder, strtab);
- }
- if (!function_methods.IsEmpty()) {
- index_encoder.AppendU8(kDataIDFunctionMethods);
- function_methods.Encode(index_encoder, strtab);
- }
- if (!function_selectors.IsEmpty()) {
- index_encoder.AppendU8(kDataIDFunctionSelectors);
- function_selectors.Encode(index_encoder, strtab);
- }
- if (!objc_class_selectors.IsEmpty()) {
- index_encoder.AppendU8(kDataIDFunctionObjcClassSelectors);
- objc_class_selectors.Encode(index_encoder, strtab);
- }
- if (!globals.IsEmpty()) {
- index_encoder.AppendU8(kDataIDGlobals);
- globals.Encode(index_encoder, strtab);
- }
- if (!types.IsEmpty()) {
- index_encoder.AppendU8(kDataIDTypes);
- types.Encode(index_encoder, strtab);
- }
- if (!namespaces.IsEmpty()) {
- index_encoder.AppendU8(kDataIDNamespaces);
- namespaces.Encode(index_encoder, strtab);
- }
- index_encoder.AppendU8(kDataIDEnd);
-
- // Now that all strings have been gathered, we will emit the string table.
- strtab.Encode(encoder);
- // Followed by the symbol table data.
- encoder.AppendData(index_encoder.GetData());
-}
-
bool ManualDWARFIndex::Decode(const DataExtractor &data,
lldb::offset_t *offset_ptr,
bool &signature_mismatch) {
@@ -702,10 +561,10 @@ bool ManualDWARFIndex::Decode(const DataExtractor &data,
signature_mismatch = true;
return false;
}
- IndexSet set;
- if (!set.Decode(data, offset_ptr))
+ std::optional<IndexSet<NameToDIE>> set = DecodeIndexSet(data, offset_ptr);
+ if (!set)
return false;
- m_set = std::move(set);
+ m_set = std::move(*set);
return true;
}
@@ -713,7 +572,7 @@ bool ManualDWARFIndex::Encode(DataEncoder &encoder) const {
CacheSignature signature(m_dwarf->GetObjectFile());
if (!signature.Encode(encoder))
return false;
- m_set.Encode(encoder);
+ EncodeIndexSet(m_set, encoder);
return true;
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
index 6a52c88a99220f..04627b0ad91e64 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
@@ -10,6 +10,7 @@
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H
#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.h"
#include "Plugins/SymbolFile/DWARF/NameToDIE.h"
#include "llvm/ADT/DenseSet.h"
@@ -58,29 +59,6 @@ class ManualDWARFIndex : public DWARFIndex {
void Dump(Stream &s) override;
- // Make IndexSet public so we can unit test the encoding and decoding logic.
- struct IndexSet {
- NameToDIE function_basenames;
- NameToDIE function_fullnames;
- NameToDIE function_methods;
- NameToDIE function_selectors;
- NameToDIE objc_class_selectors;
- NameToDIE globals;
- NameToDIE types;
- NameToDIE namespaces;
- bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr);
- void Encode(DataEncoder &encoder) const;
- bool operator==(const IndexSet &rhs) const {
- return function_basenames == rhs.function_basenames &&
- function_fullnames == rhs.function_fullnames &&
- function_methods == rhs.function_methods &&
- function_selectors == rhs.function_selectors &&
- objc_class_selectors == rhs.objc_class_selectors &&
- globals == rhs.globals && types == rhs.types &&
- namespaces == rhs.namespaces;
- }
- };
-
private:
void Index();
@@ -162,11 +140,12 @@ class ManualDWARFIndex : public DWARFIndex {
/// false if the symbol table wasn't cached or was out of date.
bool LoadFromCache();
- void IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, IndexSet &set);
+ void IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp,
+ IndexSet<NameToDIE> &set);
static void IndexUnitImpl(DWARFUnit &unit,
const lldb::LanguageType cu_language,
- IndexSet &set);
+ IndexSet<NameToDIE> &set);
/// Return true if this manual DWARF index is covering only part of the DWARF.
///
@@ -184,7 +163,7 @@ class ManualDWARFIndex : public DWARFIndex {
llvm::DenseSet<dw_offset_t> m_units_to_avoid;
llvm::DenseSet<uint64_t> m_type_sigs_to_avoid;
- IndexSet m_set;
+ IndexSet<NameToDIE> m_set;
bool m_indexed = false;
};
} // namespace dwarf
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.cpp
new file mode 100644
index 00000000000000..ac6f0815e8f032
--- /dev/null
+++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.cpp
@@ -0,0 +1,154 @@
+//===-- ManualDWARFIndex.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.h"
+#include "lldb/Core/DataFileCache.h"
+#include "lldb/Utility/DataEncoder.h"
+#include "lldb/Utility/DataExtractor.h"
+#include <cstdint>
+
+using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
+
+namespace {
+// Define IDs for the different tables when encoding and decoding the
+// ManualDWARFIndex NameToDIE objects so we can avoid saving any empty maps.
+enum DataID {
+ kDataIDFunctionBasenames = 1u,
+ kDataIDFunctionFullnames,
+ kDataIDFunctionMethods,
+ kDataIDFunctionSelectors,
+ kDataIDFunctionObjcClassSelectors,
+ kDataIDGlobals,
+ kDataIDTypes,
+ kDataIDNamespaces,
+ kDataIDEnd = 255u,
+};
+} // namespace
+
+// Version 2 changes the encoding of DIERef objects used in the DWARF manual
+// index name tables. See DIERef class for details.
+static constexpr uint32_t CURRENT_CACHE_VERSION = 2;
+
+static constexpr llvm::StringLiteral kIdentifierManualDWARFIndex("DIDX");
+
+std::optional<IndexSet<NameToDIE>>
+plugin::dwarf::DecodeIndexSet(const DataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ StringTableReader strtab;
+ // We now decode the string table for all strings in the data cache file.
+ if (!strtab.Decode(data, offset_ptr))
+ return std::nullopt;
+
+ llvm::StringRef identifier((const char *)data.GetData(offset_ptr, 4), 4);
+ if (identifier != kIdentifierManualDWARFIndex)
+ return std::nullopt;
+ const uint32_t version = data.GetU32(offset_ptr);
+ if (version != CURRENT_CACHE_VERSION)
+ return std::nullopt;
+
+ IndexSet<NameToDIE> result;
+ while (true) {
+ switch (data.GetU8(offset_ptr)) {
+ default:
+ // If we got here, this is not expected, we expect the data IDs to match
+ // one of the values from the DataID enumeration.
+ return std::nullopt;
+ case kDataIDFunctionBasenames:
+ if (!result.function_basenames.Decode(data, offset_ptr, strtab))
+ return std::nullopt;
+ break;
+ case kDataIDFunctionFullnames:
+ if (!result.function_fullnames.Decode(data, offset_ptr, strtab))
+ return std::nullopt;
+ break;
+ case kDataIDFunctionMethods:
+ if (!result.function_methods.Decode(data, offset_ptr, strtab))
+ return std::nullopt;
+ break;
+ case kDataIDFunctionSelectors:
+ if (!result.function_selectors.Decode(data, offset_ptr, strtab))
+ return std::nullopt;
+ break;
+ case kDataIDFunctionObjcClassSelectors:
+ if (!result.objc_class_selectors.Decode(data, offset_ptr, strtab))
+ return std::nullopt;
+ break;
+ case kDataIDGlobals:
+ if (!result.globals.Decode(data, offset_ptr, strtab))
+ return std::nullopt;
+ break;
+ case kDataIDTypes:
+ if (!result.types.Decode(data, offset_ptr, strtab))
+ return std::nullopt;
+ break;
+ case kDataIDNamespaces:
+ if (!result.namespaces.Decode(data, offset_ptr, strtab))
+ return std::nullopt;
+ break;
+ case kDataIDEnd:
+ // We got to the end of our NameToDIE encodings.
+ return std::move(result);
+ break;
+ }
+ }
+}
+
+void plugin::dwarf::EncodeIndexSet(const IndexSet<NameToDIE> &set,
+ DataEncoder &encoder) {
+ ConstStringTable strtab;
+
+ // Encoder the DWARF index into a separate encoder first. This allows us
+ // gather all of the strings we willl need in "strtab" as we will need to
+ // write the string table out before the symbol table.
+ DataEncoder index_encoder(encoder.GetByteOrder(),
+ encoder.GetAddressByteSize());
+
+ index_encoder.AppendData(kIdentifierManualDWARFIndex);
+ // Encode the data version.
+ index_encoder.AppendU32(CURRENT_CACHE_VERSION);
+
+ if (!set.function_basenames.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDFunctionBasenames);
+ set.function_basenames.Encode(index_encoder, strtab);
+ }
+ if (!set.function_fullnames.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDFunctionFullnames);
+ set.function_fullnames.Encode(index_encoder, strtab);
+ }
+ if (!set.function_methods.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDFunctionMethods);
+ set.function_methods.Encode(index_encoder, strtab);
+ }
+ if (!set.function_selectors.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDFunctionSelectors);
+ set.function_selectors.Encode(index_encoder, strtab);
+ }
+ if (!set.objc_class_selectors.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDFunctionObjcClassSelectors);
+ set.objc_class_selectors.Encode(index_encoder, strtab);
+ }
+ if (!set.globals.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDGlobals);
+ set.globals.Encode(index_encoder, strtab);
+ }
+ if (!set.types.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDTypes);
+ set.types.Encode(index_encoder, strtab);
+ }
+ if (!set.namespaces.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDNamespaces);
+ set.namespaces.Encode(index_encoder, strtab);
+ }
+ index_encoder.AppendU8(kDataIDEnd);
+
+ // Now that all strings have been gathered, we will emit the string table.
+ strtab.Encode(encoder);
+ // Followed by the symbol table data.
+ encoder.AppendData(index_encoder.GetData());
+}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.h
new file mode 100644
index 00000000000000..3a0fd84dc36b65
--- /dev/null
+++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndexSet.h
@@ -0,0 +1,54 @@
+//===-- ManualDWARFIndexSet.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEXSET_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEXSET_H
+
+#include "Plugins/SymbolFile/DWARF/NameToDIE.h"
+#include "lldb/Utility/DataEncoder.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "llvm/ADT/STLExtras.h"
+#include <optional>
+
+namespace lldb_private::plugin::dwarf {
+
+template <typename T> struct IndexSet {
+ T function_basenames;
+ T function_fullnames;
+ T function_methods;
+ T function_selectors;
+ T objc_class_selectors;
+ T globals;
+ T types;
+ T namespaces;
+
+ static std::array<T(IndexSet::*), 8> Indices() {
+ return {&IndexSet::function_basenames,
+ &IndexSet::function_fullnames,
+ &IndexSet::function_methods,
+ &IndexSet::function_selectors,
+ &IndexSet::objc_class_selectors,
+ &IndexSet::globals,
+ &IndexSet::types,
+ &IndexSet::namespaces};
+ }
+
+ friend bool operator==(const IndexSet &lhs, const IndexSet &rhs) {
+ return llvm::all_of(Indices(), [&lhs, &rhs](T(IndexSet::*index)) {
+ return lhs.*index == lhs.*index;
+ });
+ }
+};
+
+std::optional<IndexSet<NameToDIE>> DecodeIndexSet(const DataExtractor &data,
+ lldb::offset_t *offset_ptr);
+void EncodeIndexSet(const IndexSet<NameToDIE> &set, DataEncoder &encoder);
+
+} // namespace lldb_private::plugin::dwarf
+
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEXSET_H
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFIndexCachingTest.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFIndexCachingTest.cpp
index c5f25780a18f33..31cf9494eefc01 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFIndexCachingTest.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFIndexCachingTest.cpp
@@ -8,7 +8,7 @@
#include "Plugins/SymbolFile/DWARF/DIERef.h"
#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
-#...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/123732
More information about the lldb-commits
mailing list