16#include "llvm/ADT/Sequence.h"
24llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
28 auto index_up = std::make_unique<DebugNames>(debug_names.
GetAsLLVMDWARF(),
30 if (llvm::Error E = index_up->extract())
34 module, std::move(index_up), debug_names, debug_str,
dwarf));
37llvm::DenseSet<dw_offset_t>
39 llvm::DenseSet<dw_offset_t> result;
40 for (
const DebugNames::NameIndex &ni : debug_names) {
41 const uint32_t num_cus = ni.getCUCount();
42 for (uint32_t cu = 0; cu < num_cus; ++cu)
43 result.insert(ni.getCUOffset(cu));
44 const uint32_t num_tus = ni.getLocalTUCount();
45 for (uint32_t tu = 0; tu < num_tus; ++tu)
46 result.insert(ni.getLocalTUOffset(tu));
55 std::optional<uint64_t> unit_offset = entry.getCUOffset();
57 unit_offset = entry.getLocalTUOffset();
68 if (std::optional<uint64_t> die_offset = entry.getDIEUnitOffset())
76 const DebugNames::Entry &entry,
77 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
78 std::optional<DIERef> ref =
ToDIERef(entry);
90 const DebugNames::NameIndex &ni,
91 llvm::StringRef name) {
95 handleErrors(std::move(
error), [](
const DebugNames::SentinelError &) {}),
96 "Failed to parse index entries for index at {1:x}, name {2}: {0}",
97 ni.getUnitOffset(), name);
102 for (
const DebugNames::Entry &entry :
104 if (entry.tag() != DW_TAG_variable)
116 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
118 for (DebugNames::NameTableEntry nte: ni) {
119 Mangled mangled_name(nte.getString());
123 uint64_t entry_offset = nte.getEntryOffset();
124 llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
125 for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
126 if (entry_or->tag() != DW_TAG_variable)
142 bool found_entry_for_cu =
false;
145 bool cu_matches =
false;
146 for (uint32_t i = 0; i < ni.getCUCount(); ++i) {
147 if (ni.getCUOffset(i) == cu_offset) {
155 for (DebugNames::NameTableEntry nte : ni) {
156 uint64_t entry_offset = nte.getEntryOffset();
157 llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
158 for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
159 if (entry_or->tag() != DW_TAG_variable)
161 if (entry_or->getCUOffset() != cu_offset)
164 found_entry_for_cu =
true;
173 if (!found_entry_for_cu)
178 ConstString class_name,
bool must_be_implementation,
179 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
184 for (
const DebugNames::Entry &entry :
186 if (entry.tag() != DW_TAG_structure_type &&
187 entry.tag() != DW_TAG_class_type)
190 std::optional<DIERef> ref =
ToDIERef(entry);
196 incomplete_types.push_back(*ref);
211 incomplete_types.push_back(*ref);
215 for (
DIERef ref : incomplete_types)
216 if (!dierefcallback(ref))
223using Entry = llvm::DWARFDebugNames::Entry;
230std::optional<llvm::SmallVector<Entry, 4>>
231getParentChain(
Entry entry, uint32_t max_parents) {
232 llvm::SmallVector<Entry, 4> parent_entries;
235 if (!entry.hasParentInformation())
238 llvm::Expected<std::optional<Entry>> parent = entry.getParentDIEEntry();
243 "Failed to extract parent entry from a non-empty IDX_parent");
248 if (!parent->has_value())
251 parent_entries.push_back(**parent);
253 }
while (parent_entries.size() < max_parents);
255 return parent_entries;
261 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
265 llvm::StringRef leaf_name = context[0].name;
266 llvm::SmallVector<llvm::StringRef> parent_names;
267 for (
auto idx : llvm::seq<int>(1, context.
GetSize()))
268 parent_names.emplace_back(context[idx].name);
271 for (
const DebugNames::Entry &entry :
273 if (!isType(entry.tag()))
278 std::optional<llvm::SmallVector<Entry, 4>> parent_chain =
279 getParentChain(entry, parent_names.size() + 1);
297 llvm::ArrayRef<llvm::StringRef> parent_names,
298 llvm::ArrayRef<DebugNames::Entry> parent_entries)
const {
300 if (parent_entries.size() != parent_names.size())
303 auto SameAsEntryATName = [
this](llvm::StringRef name,
304 const DebugNames::Entry &entry) {
306 auto maybe_dieoffset = entry.getDIEUnitOffset();
307 if (!maybe_dieoffset)
317 for (
auto [parent_name, parent_entry] :
318 llvm::zip_equal(parent_names, parent_entries))
319 if (!SameAsEntryATName(parent_name, parent_entry))
326 for (
const DebugNames::Entry &entry :
328 if (isType(entry.tag())) {
339 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
340 auto name = context[0].name;
341 for (
const DebugNames::Entry &entry :
m_debug_names_up->equal_range(name)) {
342 if (entry.tag() == context[0].tag) {
353 for (
const DebugNames::Entry &entry :
355 lldb_private::dwarf::Tag entry_tag = entry.tag();
356 if (entry_tag == DW_TAG_namespace ||
357 entry_tag == DW_TAG_imported_declaration) {
369 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
371 std::set<DWARFDebugInfoEntry *> seen;
372 for (
const DebugNames::Entry &entry :
374 Tag tag = entry.tag();
375 if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
378 if (std::optional<DIERef> ref =
ToDIERef(entry)) {
381 if (!seen.insert(die.
GetDIE()).second)
383 return callback(die);
394 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
396 for (DebugNames::NameTableEntry nte: ni) {
397 if (!regex.
Execute(nte.getString()))
400 uint64_t entry_offset = nte.getEntryOffset();
401 llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
402 for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
403 Tag tag = entry_or->tag();
404 if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
421 llvm::raw_string_ostream os(data);
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
Represents a generic declaration context in a program.
A uniqued constant string class.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
A class that handles mangled names.
bool NameMatches(ConstString name) const
Check if "name" matches either the mangled or demangled name.
A class that encapsulates name lookup information.
ConstString GetLookupName() const
A class that describes an executable image and its associated object and symbol files.
virtual SymbolFile * GetSymbolFile(bool can_create=true, Stream *feedback_strm=nullptr)
Get the module's symbol file.
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
A stream class that can stream formatted output to a file.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
virtual SymbolFile * GetBackingSymbolFile()
SymbolFileOnDemand class overrides this to return the underlying backing SymbolFile implementation th...
Identifies a DWARF debug info entry within a given Module.
uint64_t GetAttributeValueAsUnsigned(const dw_attr_t attr, uint64_t fail_value) const
DWARFDIE GetDIE(dw_offset_t die_offset) const
DWARFUnit * GetUnitAtOffset(DIERef::Section section, dw_offset_t cu_offset, uint32_t *idx_ptr=nullptr)
llvm::StringRef PeekDIEName(const DIERef &die_ref)
Returns the AT_Name of this DIE, if it exists, without parsing the entire compile unit.
DWARFDIE GetDIE(const DIERef &die_ref)
DWARFUnit * GetUnit(const DIERef &die_ref)
bool ProcessFunctionDIE(const Module::LookupInfo &lookup_info, DIERef ref, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, llvm::function_ref< bool(DWARFDIE die)> callback)
Helper function implementing common logic for processing function dies.
DIERefCallbackImpl DIERefCallback(llvm::function_ref< bool(DWARFDIE die)> callback, llvm::StringRef name={}) const
void ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const
bool GetFullyQualifiedTypeImpl(const DWARFDeclContext &context, DWARFDIE die, llvm::function_ref< bool(DWARFDIE die)> callback)
Implementation of GetFullyQualifiedType to check a single entry, shareable with derived classes.
SymbolFileDWARF & GetSymbolFileDWARF() const
bool Supports_DW_AT_APPLE_objc_complete_type()
dw_offset_t GetOffset() const
DWARFUnit & GetNonSkeletonUnit()
static llvm::Expected< std::unique_ptr< DebugNamesDWARFIndex > > Create(Module &module, DWARFDataExtractor debug_names, DWARFDataExtractor debug_str, SymbolFileDWARF &dwarf)
std::optional< DIERef > ToDIERef(const DebugNames::Entry &entry) const
static void MaybeLogLookupError(llvm::Error error, const DebugNames::NameIndex &ni, llvm::StringRef name)
ManualDWARFIndex m_fallback
void GetTypes(ConstString name, llvm::function_ref< bool(DWARFDIE die)> callback) override
void GetFullyQualifiedType(const DWARFDeclContext &context, llvm::function_ref< bool(DWARFDIE die)> callback) override
Uses DWARF5's IDX_parent fields, when available, to speed up this query.
void GetNamespaces(ConstString name, llvm::function_ref< bool(DWARFDIE die)> callback) override
llvm::DWARFDebugNames DebugNames
void Dump(Stream &s) override
bool ProcessEntry(const DebugNames::Entry &entry, llvm::function_ref< bool(DWARFDIE die)> callback)
void GetGlobalVariables(ConstString basename, llvm::function_ref< bool(DWARFDIE die)> callback) override
Finds global variables with the given base name.
void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, llvm::function_ref< bool(DWARFDIE die)> callback) override
DWARFDebugInfo & m_debug_info
void GetFunctions(const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, llvm::function_ref< bool(DWARFDIE die)> callback) override
bool SameParentChain(llvm::ArrayRef< llvm::StringRef > parent_names, llvm::ArrayRef< DebugNames::Entry > parent_entries) const
Returns true if parent_entries have identical names to parent_names.
static llvm::DenseSet< dw_offset_t > GetUnits(const DebugNames &debug_names)
std::unique_ptr< DebugNames > m_debug_names_up
void Dump(Stream &s) override
void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, llvm::function_ref< bool(DWARFDIE die)> callback) override
void GetTypes(ConstString name, llvm::function_ref< bool(DWARFDIE die)> callback) override
void GetNamespaces(ConstString name, llvm::function_ref< bool(DWARFDIE die)> callback) override
void GetFunctions(const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, llvm::function_ref< bool(DWARFDIE die)> callback) override
void GetGlobalVariables(ConstString basename, llvm::function_ref< bool(DWARFDIE die)> callback) override
Finds global variables with the given base name.
std::optional< uint64_t > GetFileIndex() const
std::vector< DIERef > DIEArray
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.