Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
39653 views
1
//===-- ClangASTSource.h ----------------------------------------*- C++ -*-===//
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
9
#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
10
#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
11
12
#include <set>
13
14
#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
15
#include "Plugins/ExpressionParser/Clang/NameSearchContext.h"
16
#include "lldb/Symbol/CompilerType.h"
17
#include "lldb/Target/Target.h"
18
#include "clang/AST/ExternalASTSource.h"
19
#include "clang/Basic/IdentifierTable.h"
20
21
#include "llvm/ADT/SmallSet.h"
22
23
namespace lldb_private {
24
25
/// \class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"
26
/// Provider for named objects defined in the debug info for Clang
27
///
28
/// As Clang parses an expression, it may encounter names that are not defined
29
/// inside the expression, including variables, functions, and types. Clang
30
/// knows the name it is looking for, but nothing else. The ExternalSemaSource
31
/// class provides Decls (VarDecl, FunDecl, TypeDecl) to Clang for these
32
/// names, consulting the ClangExpressionDeclMap to do the actual lookups.
33
class ClangASTSource : public clang::ExternalASTSource,
34
public ClangASTImporter::MapCompleter {
35
public:
36
/// Constructor
37
///
38
/// Initializes class variables.
39
///
40
/// \param[in] target
41
/// A reference to the target containing debug information to use.
42
///
43
/// \param[in] importer
44
/// The ClangASTImporter to use.
45
ClangASTSource(const lldb::TargetSP &target,
46
const std::shared_ptr<ClangASTImporter> &importer);
47
48
/// Destructor
49
~ClangASTSource() override;
50
51
/// Interface stubs.
52
clang::Decl *GetExternalDecl(clang::GlobalDeclID) override { return nullptr; }
53
clang::Stmt *GetExternalDeclStmt(uint64_t) override { return nullptr; }
54
clang::Selector GetExternalSelector(uint32_t) override {
55
return clang::Selector();
56
}
57
uint32_t GetNumExternalSelectors() override { return 0; }
58
clang::CXXBaseSpecifier *
59
GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
60
return nullptr;
61
}
62
void MaterializeVisibleDecls(const clang::DeclContext *DC) {}
63
64
void InstallASTContext(TypeSystemClang &ast_context);
65
66
//
67
// APIs for ExternalASTSource
68
//
69
70
/// Look up all Decls that match a particular name. Only handles
71
/// Identifiers and DeclContexts that are either NamespaceDecls or
72
/// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with the
73
/// result.
74
///
75
/// The work for this function is done by
76
/// void FindExternalVisibleDecls (NameSearchContext &);
77
///
78
/// \param[in] DC
79
/// The DeclContext to register the found Decls in.
80
///
81
/// \param[in] Name
82
/// The name to find entries for.
83
///
84
/// \return
85
/// Whatever SetExternalVisibleDeclsForName returns.
86
bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
87
clang::DeclarationName Name) override;
88
89
/// Enumerate all Decls in a given lexical context.
90
///
91
/// \param[in] DC
92
/// The DeclContext being searched.
93
///
94
/// \param[in] IsKindWeWant
95
/// A callback function that returns true given the
96
/// DeclKinds of desired Decls, and false otherwise.
97
///
98
/// \param[in] Decls
99
/// A vector that is filled in with matching Decls.
100
void FindExternalLexicalDecls(
101
const clang::DeclContext *DC,
102
llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
103
llvm::SmallVectorImpl<clang::Decl *> &Decls) override;
104
105
/// Specify the layout of the contents of a RecordDecl.
106
///
107
/// \param[in] Record
108
/// The record (in the parser's AST context) that needs to be
109
/// laid out.
110
///
111
/// \param[out] Size
112
/// The total size of the record in bits.
113
///
114
/// \param[out] Alignment
115
/// The alignment of the record in bits.
116
///
117
/// \param[in] FieldOffsets
118
/// A map that must be populated with pairs of the record's
119
/// fields (in the parser's AST context) and their offsets
120
/// (measured in bits).
121
///
122
/// \param[in] BaseOffsets
123
/// A map that must be populated with pairs of the record's
124
/// C++ concrete base classes (in the parser's AST context,
125
/// and only if the record is a CXXRecordDecl and has base
126
/// classes) and their offsets (measured in bytes).
127
///
128
/// \param[in] VirtualBaseOffsets
129
/// A map that must be populated with pairs of the record's
130
/// C++ virtual base classes (in the parser's AST context,
131
/// and only if the record is a CXXRecordDecl and has base
132
/// classes) and their offsets (measured in bytes).
133
///
134
/// \return
135
/// True <=> the layout is valid.
136
bool layoutRecordType(
137
const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
138
llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
139
llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
140
&BaseOffsets,
141
llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
142
&VirtualBaseOffsets) override;
143
144
/// Complete a TagDecl.
145
///
146
/// \param[in] Tag
147
/// The Decl to be completed in place.
148
void CompleteType(clang::TagDecl *Tag) override;
149
150
/// Complete an ObjCInterfaceDecl.
151
///
152
/// \param[in] Class
153
/// The Decl to be completed in place.
154
void CompleteType(clang::ObjCInterfaceDecl *Class) override;
155
156
/// Called on entering a translation unit. Tells Clang by calling
157
/// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() that
158
/// this object has something to say about undefined names.
159
///
160
/// \param[in] Consumer
161
/// Unused.
162
void StartTranslationUnit(clang::ASTConsumer *Consumer) override;
163
164
//
165
// APIs for NamespaceMapCompleter
166
//
167
168
/// Look up the modules containing a given namespace and put the appropriate
169
/// entries in the namespace map.
170
///
171
/// \param[in] namespace_map
172
/// The map to be completed.
173
///
174
/// \param[in] name
175
/// The name of the namespace to be found.
176
///
177
/// \param[in] parent_map
178
/// The map for the namespace's parent namespace, if there is
179
/// one.
180
void CompleteNamespaceMap(
181
ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name,
182
ClangASTImporter::NamespaceMapSP &parent_map) const override;
183
184
//
185
// Helper APIs
186
//
187
188
clang::NamespaceDecl *
189
AddNamespace(NameSearchContext &context,
190
ClangASTImporter::NamespaceMapSP &namespace_decls);
191
192
/// The worker function for FindExternalVisibleDeclsByName.
193
///
194
/// \param[in] context
195
/// The NameSearchContext to use when filing results.
196
virtual void FindExternalVisibleDecls(NameSearchContext &context);
197
198
clang::Sema *getSema();
199
200
void SetLookupsEnabled(bool lookups_enabled) {
201
m_lookups_enabled = lookups_enabled;
202
}
203
bool GetLookupsEnabled() { return m_lookups_enabled; }
204
205
/// \class ClangASTSourceProxy ClangASTSource.h
206
/// "lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource
207
///
208
/// Clang AST contexts like to own their AST sources, so this is a state-
209
/// free proxy object.
210
class ClangASTSourceProxy : public clang::ExternalASTSource {
211
public:
212
ClangASTSourceProxy(ClangASTSource &original) : m_original(original) {}
213
214
bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
215
clang::DeclarationName Name) override {
216
return m_original.FindExternalVisibleDeclsByName(DC, Name);
217
}
218
219
void FindExternalLexicalDecls(
220
const clang::DeclContext *DC,
221
llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
222
llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
223
return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
224
}
225
226
void CompleteType(clang::TagDecl *Tag) override {
227
return m_original.CompleteType(Tag);
228
}
229
230
void CompleteType(clang::ObjCInterfaceDecl *Class) override {
231
return m_original.CompleteType(Class);
232
}
233
234
bool layoutRecordType(
235
const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
236
llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
237
llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
238
&BaseOffsets,
239
llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
240
&VirtualBaseOffsets) override {
241
return m_original.layoutRecordType(Record, Size, Alignment, FieldOffsets,
242
BaseOffsets, VirtualBaseOffsets);
243
}
244
245
void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
246
return m_original.StartTranslationUnit(Consumer);
247
}
248
249
private:
250
ClangASTSource &m_original;
251
};
252
253
clang::ExternalASTSource *CreateProxy() {
254
return new ClangASTSourceProxy(*this);
255
}
256
257
protected:
258
/// Look for the complete version of an Objective-C interface, and return it
259
/// if found.
260
///
261
/// \param[in] interface_decl
262
/// An ObjCInterfaceDecl that may not be the complete one.
263
///
264
/// \return
265
/// NULL if the complete interface couldn't be found;
266
/// the complete interface otherwise.
267
clang::ObjCInterfaceDecl *
268
GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl);
269
270
/// Find all entities matching a given name in a given module, using a
271
/// NameSearchContext to make Decls for them.
272
///
273
/// \param[in] context
274
/// The NameSearchContext that can construct Decls for this name.
275
///
276
/// \param[in] module
277
/// If non-NULL, the module to query.
278
///
279
/// \param[in] namespace_decl
280
/// If valid and module is non-NULL, the parent namespace.
281
void FindExternalVisibleDecls(NameSearchContext &context,
282
lldb::ModuleSP module,
283
CompilerDeclContext &namespace_decl);
284
285
/// Find all Objective-C methods matching a given selector.
286
///
287
/// \param[in] context
288
/// The NameSearchContext that can construct Decls for this name.
289
/// Its m_decl_name contains the selector and its m_decl_context
290
/// is the containing object.
291
void FindObjCMethodDecls(NameSearchContext &context);
292
293
/// Find all Objective-C properties and ivars with a given name.
294
///
295
/// \param[in] context
296
/// The NameSearchContext that can construct Decls for this name.
297
/// Its m_decl_name contains the name and its m_decl_context
298
/// is the containing object.
299
void FindObjCPropertyAndIvarDecls(NameSearchContext &context);
300
301
/// Performs lookup into a namespace.
302
///
303
/// \param context
304
/// The NameSearchContext for a lookup inside a namespace.
305
void LookupInNamespace(NameSearchContext &context);
306
307
/// A wrapper for TypeSystemClang::CopyType that sets a flag that
308
/// indicates that we should not respond to queries during import.
309
///
310
/// \param[in] src_type
311
/// The source type.
312
///
313
/// \return
314
/// The imported type.
315
CompilerType GuardedCopyType(const CompilerType &src_type);
316
317
std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor();
318
319
public:
320
/// Returns true if a name should be ignored by name lookup.
321
///
322
/// \param[in] name
323
/// The name to be considered.
324
///
325
/// \param[in] ignore_all_dollar_names
326
/// True if $-names of all sorts should be ignored.
327
///
328
/// \return
329
/// True if the name is one of a class of names that are ignored by
330
/// global lookup for performance reasons.
331
bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);
332
333
/// Copies a single Decl into the parser's AST context.
334
///
335
/// \param[in] src_decl
336
/// The Decl to copy.
337
///
338
/// \return
339
/// A copy of the Decl in m_ast_context, or NULL if the copy failed.
340
clang::Decl *CopyDecl(clang::Decl *src_decl);
341
342
/// Determined the origin of a single Decl, if it can be found.
343
///
344
/// \param[in] decl
345
/// The Decl whose origin is to be found.
346
///
347
/// \return
348
/// True if lookup succeeded; false otherwise.
349
ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl);
350
351
/// Returns the TypeSystem that uses this ClangASTSource instance as it's
352
/// ExternalASTSource.
353
TypeSystemClang *GetTypeSystem() const { return m_clang_ast_context; }
354
355
private:
356
bool FindObjCPropertyAndIvarDeclsWithOrigin(
357
NameSearchContext &context,
358
DeclFromUser<const clang::ObjCInterfaceDecl> &origin_iface_decl);
359
360
protected:
361
bool FindObjCMethodDeclsWithOrigin(
362
NameSearchContext &context,
363
clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);
364
365
void FindDeclInModules(NameSearchContext &context, ConstString name);
366
void FindDeclInObjCRuntime(NameSearchContext &context, ConstString name);
367
368
/// Fills the namespace map of the given NameSearchContext.
369
///
370
/// \param context The NameSearchContext with the namespace map to fill.
371
/// \param module_sp The module to search for namespaces or a nullptr if
372
/// the current target should be searched.
373
/// \param namespace_decl The DeclContext in which to search for namespaces.
374
void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp,
375
const CompilerDeclContext &namespace_decl);
376
377
clang::TagDecl *FindCompleteType(const clang::TagDecl *decl);
378
379
friend struct NameSearchContext;
380
381
bool m_lookups_enabled;
382
383
/// The target to use in finding variables and types.
384
const lldb::TargetSP m_target;
385
/// The AST context requests are coming in for.
386
clang::ASTContext *m_ast_context;
387
/// The TypeSystemClang for m_ast_context.
388
TypeSystemClang *m_clang_ast_context;
389
/// The file manager paired with the AST context.
390
clang::FileManager *m_file_manager;
391
/// The target's AST importer.
392
std::shared_ptr<ClangASTImporter> m_ast_importer_sp;
393
std::set<const clang::Decl *> m_active_lexical_decls;
394
std::set<const char *> m_active_lookups;
395
};
396
397
} // namespace lldb_private
398
399
#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
400
401