17#include "llvm/ADT/Sequence.h"
25llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
29 auto index_up = std::make_unique<DebugNames>(debug_names.
GetAsLLVMDWARF(),
31 if (llvm::Error E = index_up->extract())
35 module, std::move(index_up), debug_names, debug_str,
dwarf));
38llvm::DenseSet<uint64_t>
40 llvm::DenseSet<uint64_t> result;
41 for (
const DebugNames::NameIndex &ni : debug_names) {
42 const uint32_t num_tus = ni.getForeignTUCount();
43 for (uint32_t tu = 0; tu < num_tus; ++tu)
44 result.insert(ni.getForeignTUSignature(tu));
49llvm::DenseSet<dw_offset_t>
51 llvm::DenseSet<dw_offset_t> result;
52 for (
const DebugNames::NameIndex &ni : debug_names) {
53 const uint32_t num_cus = ni.getCUCount();
54 for (uint32_t cu = 0; cu < num_cus; ++cu)
55 result.insert(ni.getCUOffset(cu));
56 const uint32_t num_tus = ni.getLocalTUCount();
57 for (uint32_t tu = 0; tu < num_tus; ++tu)
58 result.insert(ni.getLocalTUOffset(tu));
63std::optional<DWARFTypeUnit *>
65 std::optional<uint64_t> type_sig = entry.getForeignTUTypeSignature();
66 if (!type_sig.has_value())
73 std::optional<uint64_t> cu_offset = entry.getRelatedCUOffset();
105 DWARFTypeUnit *foreign_tu = dwp_sp->DebugInfo().GetTypeUnitForHash(*type_sig);
111 llvm::StringRef cu_dwo_name =
113 llvm::StringRef tu_dwo_name =
115 if (cu_dwo_name == tu_dwo_name)
124 return foreign_tu.value();
128 std::optional<uint64_t> unit_offset = entry.getCUOffset();
130 unit_offset = entry.getLocalTUOffset();
141 std::optional<uint64_t> die_offset = entry.getDIEUnitOffset();
142 if (!unit || !die_offset)
148 "the DWARF debug information has been modified (bad offset {0:x} in "
149 "debug_names section)\n",
155 const DebugNames::Entry &entry,
156 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
165 return callback(die);
169 const DebugNames::NameIndex &ni,
170 llvm::StringRef name) {
174 handleErrors(std::move(
error), [](
const DebugNames::SentinelError &) {}),
175 "Failed to parse index entries for index at {1:x}, name {2}: {0}",
176 ni.getUnitOffset(), name);
181 for (
const DebugNames::Entry &entry :
183 if (entry.tag() != DW_TAG_variable)
195 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
197 for (DebugNames::NameTableEntry nte: ni) {
198 Mangled mangled_name(nte.getString());
202 uint64_t entry_offset = nte.getEntryOffset();
203 llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
204 for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
205 if (entry_or->tag() != DW_TAG_variable)
221 bool found_entry_for_cu =
false;
224 bool cu_matches =
false;
225 for (uint32_t i = 0; i < ni.getCUCount(); ++i) {
226 if (ni.getCUOffset(i) == cu_offset) {
234 for (DebugNames::NameTableEntry nte : ni) {
235 uint64_t entry_offset = nte.getEntryOffset();
236 llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
237 for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
238 if (entry_or->tag() != DW_TAG_variable)
240 if (entry_or->getCUOffset() != cu_offset)
243 found_entry_for_cu =
true;
252 if (!found_entry_for_cu)
257 ConstString class_name,
bool must_be_implementation,
258 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
261 std::vector<DWARFDIE> incomplete_types;
263 for (
const DebugNames::Entry &entry :
265 if (entry.tag() != DW_TAG_structure_type &&
266 entry.tag() != DW_TAG_class_type)
276 incomplete_types.push_back(die);
285 incomplete_types.push_back(die);
288 for (
DWARFDIE die : incomplete_types)
296using Entry = llvm::DWARFDebugNames::Entry;
303std::optional<llvm::SmallVector<Entry, 4>>
304getParentChain(
Entry entry, uint32_t max_parents) {
305 llvm::SmallVector<Entry, 4> parent_entries;
308 if (!entry.hasParentInformation())
311 llvm::Expected<std::optional<Entry>> parent = entry.getParentDIEEntry();
316 "Failed to extract parent entry from a non-empty IDX_parent");
321 if (!parent->has_value())
324 parent_entries.push_back(**parent);
326 }
while (parent_entries.size() < max_parents);
328 return parent_entries;
334 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
338 llvm::StringRef leaf_name = context[0].name;
339 llvm::SmallVector<llvm::StringRef> parent_names;
340 for (
auto idx : llvm::seq<int>(1, context.
GetSize()))
341 parent_names.emplace_back(context[idx].name);
344 for (
const DebugNames::Entry &entry :
346 if (!isType(entry.tag()))
353 if (foreign_tu && foreign_tu.value() ==
nullptr)
358 std::optional<llvm::SmallVector<Entry, 4>> parent_chain =
359 getParentChain(entry, parent_names.size() + 1);
378 llvm::ArrayRef<llvm::StringRef> parent_names,
379 llvm::ArrayRef<DebugNames::Entry> parent_entries)
const {
381 if (parent_entries.size() != parent_names.size())
384 auto SameAsEntryATName = [
this](llvm::StringRef name,
385 const DebugNames::Entry &entry) {
387 auto maybe_dieoffset = entry.getDIEUnitOffset();
388 if (!maybe_dieoffset)
398 for (
auto [parent_name, parent_entry] :
399 llvm::zip_equal(parent_names, parent_entries))
400 if (!SameAsEntryATName(parent_name, parent_entry))
407 for (
const DebugNames::Entry &entry :
409 if (isType(entry.tag())) {
420 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
421 auto name = context[0].name;
422 for (
const DebugNames::Entry &entry :
m_debug_names_up->equal_range(name)) {
423 if (entry.tag() == context[0].tag) {
434 for (
const DebugNames::Entry &entry :
436 lldb_private::dwarf::Tag entry_tag = entry.tag();
437 if (entry_tag == DW_TAG_namespace ||
438 entry_tag == DW_TAG_imported_declaration) {
450 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
452 std::set<DWARFDebugInfoEntry *> seen;
453 for (
const DebugNames::Entry &entry :
455 Tag tag = entry.tag();
456 if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
462 if (!seen.insert(die.
GetDIE()).second)
464 return callback(die);
475 llvm::function_ref<
bool(
DWARFDIE die)> callback) {
477 for (DebugNames::NameTableEntry nte: ni) {
478 if (!regex.
Execute(nte.getString()))
481 uint64_t entry_offset = nte.getEntryOffset();
482 llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
483 for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
484 Tag tag = entry_or->tag();
485 if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
502 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.
void ReportErrorIfModifyDetected(const char *format, Args &&...args)
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.
const char * GetAttributeValueAsString(const dw_attr_t attr, const char *fail_value) const
DWARFUnit * GetCU() const
uint64_t GetAttributeValueAsUnsigned(const dw_attr_t attr, uint64_t fail_value) const
DWARFDIE GetDIE(dw_offset_t die_offset) const
bool IsStructUnionOrClass() const
const std::shared_ptr< SymbolFileDWARFDwo > & GetDwpSymbolFile()
DWARFTypeUnit * GetTypeUnitForHash(uint64_t hash)
DWARFUnit * GetUnitAtOffset(DIERef::Section section, dw_offset_t cu_offset, uint32_t *idx_ptr=nullptr)
bool ProcessFunctionDIE(const Module::LookupInfo &lookup_info, DWARFDIE die, const CompilerDeclContext &parent_decl_ctx, llvm::function_ref< bool(DWARFDIE die)> callback)
Helper function implementing common logic for processing function dies.
virtual void GetFullyQualifiedType(const DWARFDeclContext &context, llvm::function_ref< bool(DWARFDIE die)> callback)
Finds all DIEs whose fully qualified name matches context.
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.
DWARFBaseDIE GetUnitDIEOnly()
SymbolFileDWARF & GetSymbolFileDWARF() const
bool Supports_DW_AT_APPLE_objc_complete_type()
llvm::StringRef PeekDIEName(dw_offset_t die_offset)
Returns the AT_Name of the DIE at die_offset, if it exists, without parsing the entire compile unit.
dw_offset_t GetOffset() const
DWARFUnit & GetNonSkeletonUnit()
DWARFDIE GetDIE(dw_offset_t die_offset)
static llvm::Expected< std::unique_ptr< DebugNamesDWARFIndex > > Create(Module &module, DWARFDataExtractor debug_names, DWARFDataExtractor debug_str, SymbolFileDWARF &dwarf)
static llvm::DenseSet< uint64_t > GetTypeUnitSignatures(const DebugNames &debug_names)
static void MaybeLogLookupError(llvm::Error error, const DebugNames::NameIndex &ni, llvm::StringRef name)
DWARFDIE GetDIE(const DebugNames::Entry &entry) const
std::optional< DWARFTypeUnit * > GetForeignTypeUnit(const DebugNames::Entry &entry) const
Checks if an entry is a foreign TU and fetch the type unit.
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)
DWARFUnit * GetNonSkeletonUnit(const DebugNames::Entry &entry) const
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.
DWARFDebugInfo & DebugInfo()
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.