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 CompilerDeclContext &parent_decl_ctx, DWARFDIE die,
178 llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
179 if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
181 return callback(die);
182}
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:916
lldb::FunctionNameType GetNameTypeMask() const
Definition Module.h:931
lldb::LanguageType GetLanguageType() const
Definition Module.h:937
ConstString GetLookupName() const
Definition Module.h:927
bool NameMatchesLookupInfo(ConstString function_name, lldb::LanguageType language_type=lldb::eLanguageTypeUnknown) const
Definition Module.cpp:717
static bool IsPossibleObjCMethodName(const char *name)
A class that contains all state required for type lookups.
Definition Type.h:104
bool GetModuleSearch() const
The m_context can be used in two ways: normal types searching with the context containing a stanadard...
Definition Type.h:294
bool HasLanguage() const
Returns true if any matching languages have been specified in this type matching object.
Definition Type.h:252
bool LanguageMatches(lldb::LanguageType language) const
Check if the language matches any languages that have been added to this match object.
Definition Type.cpp:183
ConstString GetTypeBasename() const
Get the type basename to use when searching the type indexes in each SymbolFile object.
Definition Type.cpp:113
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.
Definition Type.cpp:129
bool GetSearchByMangledName() const
Returns true if the type query is supposed to treat the name to be searched as a mangled name.
Definition Type.h:308
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:124
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
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.