LLDB mainline
DWARFIndex.cpp
Go to the documentation of this file.
1//===-- DWARFIndex.cpp ----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "DWARFDebugInfoEntry.h"
11#include "DWARFDeclContext.h"
15
16#include "lldb/Core/Mangled.h"
17#include "lldb/Core/Module.h"
20
21using namespace lldb_private;
22using namespace lldb;
23using namespace lldb_private::plugin::dwarf;
24
25DWARFIndex::~DWARFIndex() = default;
26
28 const Module::LookupInfo &lookup_info, DWARFDIE die,
29 const CompilerDeclContext &parent_decl_ctx,
30 llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
31 llvm::StringRef name = lookup_info.GetLookupName().GetStringRef();
32 FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();
33
34 if (!(name_type_mask & eFunctionNameTypeFull)) {
35 ConstString name_to_match_against;
36 if (const char *mangled_die_name = die.GetMangledName()) {
37 name_to_match_against = ConstString(mangled_die_name);
38 } else {
39 SymbolFileDWARF *symbols = die.GetDWARF();
40 if (ConstString demangled_die_name =
42 name_to_match_against = demangled_die_name;
43 }
44
45 if (!lookup_info.NameMatchesLookupInfo(name_to_match_against,
46 lookup_info.GetLanguageType()))
48 }
49
50 // Exit early if we're searching exclusively for methods or selectors and
51 // we have a context specified (no methods in namespaces).
52 uint32_t looking_for_nonmethods =
53 name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector);
54 if (!looking_for_nonmethods && parent_decl_ctx.IsValid())
56
57 // Otherwise, we need to also check that the context matches. If it does not
58 // match, we do nothing.
59 if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
61
62 // In case of a full match, we just insert everything we find.
63 if (name_type_mask & eFunctionNameTypeFull && die.GetMangledName() == name)
64 return callback(die);
65
66 // If looking for ObjC selectors, we need to also check if the name is a
67 // possible selector.
68 if (name_type_mask & eFunctionNameTypeSelector &&
70 return callback(die);
71
72 bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod;
73 bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase;
74 if (looking_for_methods || looking_for_functions) {
75 // If we're looking for either methods or functions, we definitely want this
76 // die. Otherwise, only keep it if the die type matches what we are
77 // searching for.
78 if ((looking_for_methods && looking_for_functions) ||
79 looking_for_methods == die.IsMethod())
80 return callback(die);
81 }
82
84}
85
87 const DWARFIndex &index,
88 llvm::function_ref<IterationAction(DWARFDIE die)> callback,
89 llvm::StringRef name)
90 : m_index(index),
92 index.m_module.GetSymbolFile()->GetBackingSymbolFile())),
93 m_callback(callback), m_name(name) {}
94
96 if (DWARFDIE die = m_dwarf.GetDIE(ref))
97 return m_callback(die);
98 m_index.ReportInvalidDIERef(ref, m_name);
100}
101
103 const llvm::AppleAcceleratorTable::Entry &entry) const {
104 return this->operator()(DIERef(std::nullopt, DIERef::Section::DebugInfo,
105 *entry.getDIESectionOffset()));
106}
107
108void DWARFIndex::ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const {
109 m_module.ReportErrorIfModifyDetected(
110 "the DWARF debug information has been modified (accelerator table had "
111 "bad die {0:x16} for '{1}')\n",
112 ref.die_offset(), name.str().c_str());
113}
114
116 const DWARFDeclContext &context,
117 llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
118 GetTypes(context, [&](DWARFDIE die) {
119 return GetFullyQualifiedTypeImpl(context, die, callback);
120 });
121}
122
124 const DWARFDeclContext &context, DWARFDIE die,
125 llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
126 DWARFDeclContext dwarf_decl_ctx = die.GetDWARFDeclContext();
127 if (dwarf_decl_ctx == context)
128 return callback(die);
130}
131
133 TypeQuery &query,
134 llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
135 GetTypes(query.GetTypeBasename(), [&](DWARFDIE die) {
136 return ProcessTypeDIEMatchQuery(query, die, callback);
137 });
138}
139
141 TypeQuery &query, DWARFDIE die,
142 llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
143 // Check the language, but only if we have a language filter.
144 if (query.HasLanguage() &&
147
148 // Since mangled names are unique, we only need to check if the names are
149 // the same.
150 if (query.GetSearchByMangledName()) {
151 if (die.GetMangledName(/*substitute_name_allowed=*/false) !=
154 return callback(die);
155 }
156
157 std::vector<lldb_private::CompilerContext> die_context;
158 if (query.GetModuleSearch())
159 die_context = die.GetDeclContext();
160 else
161 die_context = die.GetTypeLookupContext();
162
163 if (!query.ContextMatches(die_context))
165 return callback(die);
166}
167
169 ConstString name, const CompilerDeclContext &parent_decl_ctx,
170 llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
171 GetNamespaces(name, [&](DWARFDIE die) {
172 return ProcessNamespaceDieMatchParents(parent_decl_ctx, die, callback);
173 });
174}
175
177 const std::vector<Module::LookupInfo> &lookup_infos, SymbolFileDWARF &dwarf,
178 const CompilerDeclContext &parent_decl_ctx,
179 llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
180 for (auto &lookup_info : lookup_infos)
181 GetFunctions(lookup_info, dwarf, parent_decl_ctx, callback);
182}
183
185 const CompilerDeclContext &parent_decl_ctx, DWARFDIE die,
186 llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
187 if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
189 return callback(die);
190}
Represents a generic declaration context in a program.
A uniqued constant string class.
Definition ConstString.h:40
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
A class that encapsulates name lookup information.
Definition Module.h:935
lldb::FunctionNameType GetNameTypeMask() const
Definition Module.h:976
lldb::LanguageType GetLanguageType() const
Definition Module.h:978
ConstString GetLookupName() const
Definition Module.h:974
bool NameMatchesLookupInfo(ConstString function_name, lldb::LanguageType language_type=lldb::eLanguageTypeUnknown) const
Definition Module.cpp:713
static bool IsPossibleObjCMethodName(llvm::StringRef name)
A class that contains all state required for type lookups.
bool GetModuleSearch() const
The m_context can be used in two ways: normal types searching with the context containing a stanadard...
bool HasLanguage() const
Returns true if any matching languages have been specified in this type matching object.
bool LanguageMatches(lldb::LanguageType language) const
Check if the language matches any languages that have been added to this match object.
ConstString GetTypeBasename() const
Get the type basename to use when searching the type indexes in each SymbolFile object.
bool ContextMatches(llvm::ArrayRef< lldb_private::CompilerContext > context) const
Check of a CompilerContext array from matching type from a symbol file matches the m_context.
bool GetSearchByMangledName() const
Returns true if the type query is supposed to treat the name to be searched as a mangled name.
Identifies a DWARF debug info entry within a given Module.
Definition DIERef.h:31
dw_offset_t die_offset() const
Definition DIERef.h:68
const char * GetMangledName(bool substitute_name_allowed=true) const
Definition DWARFDIE.cpp:212
std::vector< CompilerContext > GetDeclContext(bool derive_template_names=false) const
Return this DIE's decl context as it is needed to look up types in Clang modules.
Definition DWARFDIE.cpp:456
DWARFDeclContext GetDWARFDeclContext() const
Definition DWARFDIE.cpp:526
std::vector< CompilerContext > GetTypeLookupContext(bool derive_template_names=false) const
Get a context to a type so it can be looked up.
Definition DWARFDIE.cpp:503
DIERefCallbackImpl(const DWARFIndex &index, llvm::function_ref< IterationAction(DWARFDIE die)> callback, llvm::StringRef name)
const llvm::function_ref< IterationAction(DWARFDIE die)> m_callback
Definition DWARFIndex.h:129
IterationAction GetFullyQualifiedTypeImpl(const DWARFDeclContext &context, DWARFDIE die, llvm::function_ref< IterationAction(DWARFDIE die)> callback)
Implementation of GetFullyQualifiedType to check a single entry, shareable with derived classes.
virtual void GetFullyQualifiedType(const DWARFDeclContext &context, llvm::function_ref< IterationAction(DWARFDIE die)> callback)
Finds all DIEs whose fully qualified name matches context.
virtual void GetTypesWithQuery(TypeQuery &query, llvm::function_ref< IterationAction(DWARFDIE die)> callback)
Get type DIEs meeting requires of query.
virtual void GetNamespaces(ConstString name, llvm::function_ref< IterationAction(DWARFDIE die)> callback)=0
IterationAction ProcessFunctionDIE(const Module::LookupInfo &lookup_info, DWARFDIE die, const CompilerDeclContext &parent_decl_ctx, llvm::function_ref< IterationAction(DWARFDIE die)> callback)
Helper function implementing common logic for processing function dies.
void ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const
virtual void GetNamespacesWithParents(ConstString name, const CompilerDeclContext &parent_decl_ctx, llvm::function_ref< IterationAction(DWARFDIE die)> callback)
Get namespace DIEs whose base name match.
virtual void GetTypes(ConstString name, llvm::function_ref< IterationAction(DWARFDIE die)> callback)=0
virtual void GetFunctions(const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, llvm::function_ref< IterationAction(DWARFDIE die)> callback)=0
IterationAction ProcessTypeDIEMatchQuery(TypeQuery &query, DWARFDIE die, llvm::function_ref< IterationAction(DWARFDIE die)> callback)
Check if the type die can meet the requirements of query.
IterationAction ProcessNamespaceDieMatchParents(const CompilerDeclContext &parent_decl_ctx, DWARFDIE die, llvm::function_ref< IterationAction(DWARFDIE die)> callback)
static lldb::LanguageType GetLanguageFamily(DWARFUnit &unit)
Same as GetLanguage() but reports all C++ versions as C++ (no version).
ConstString ConstructFunctionDemangledName(const DWARFDIE &die)
static bool DIEInDeclContext(const CompilerDeclContext &parent_decl_ctx, const DWARFDIE &die, bool only_root_namespaces=false)
A class that represents a running process on the host machine.
IterationAction
Useful for callbacks whose return type indicates whether to continue iteration or short-circuit.