LLDB mainline
ClangASTSource.h
Go to the documentation of this file.
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
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
23namespace 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.
33class ClangASTSource : public clang::ExternalASTSource,
35public:
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
87 FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
88 clang::DeclarationName Name,
89 const clang::DeclContext *OriginalDC) override;
90
91 /// Enumerate all Decls in a given lexical context.
92 ///
93 /// \param[in] DC
94 /// The DeclContext being searched.
95 ///
96 /// \param[in] IsKindWeWant
97 /// A callback function that returns true given the
98 /// DeclKinds of desired Decls, and false otherwise.
99 ///
100 /// \param[in] Decls
101 /// A vector that is filled in with matching Decls.
103 const clang::DeclContext *DC,
104 llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
106
107 /// Specify the layout of the contents of a RecordDecl.
108 ///
109 /// \param[in] Record
110 /// The record (in the parser's AST context) that needs to be
111 /// laid out.
112 ///
113 /// \param[out] Size
114 /// The total size of the record in bits.
115 ///
116 /// \param[out] Alignment
117 /// The alignment of the record in bits.
118 ///
119 /// \param[in] FieldOffsets
120 /// A map that must be populated with pairs of the record's
121 /// fields (in the parser's AST context) and their offsets
122 /// (measured in bits).
123 ///
124 /// \param[in] BaseOffsets
125 /// A map that must be populated with pairs of the record's
126 /// C++ concrete base classes (in the parser's AST context,
127 /// and only if the record is a CXXRecordDecl and has base
128 /// classes) and their offsets (measured in bytes).
129 ///
130 /// \param[in] VirtualBaseOffsets
131 /// A map that must be populated with pairs of the record's
132 /// C++ virtual base classes (in the parser's AST context,
133 /// and only if the record is a CXXRecordDecl and has base
134 /// classes) and their offsets (measured in bytes).
135 ///
136 /// \return
137 /// True <=> the layout is valid.
138 bool layoutRecordType(
139 const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
140 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
141 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
142 &BaseOffsets,
143 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
144 &VirtualBaseOffsets) override;
145
146 /// Complete a TagDecl.
147 ///
148 /// \param[in] Tag
149 /// The Decl to be completed in place.
150 void CompleteType(clang::TagDecl *Tag) override;
151
152 /// Complete an ObjCInterfaceDecl.
153 ///
154 /// \param[in] Class
155 /// The Decl to be completed in place.
156 void CompleteType(clang::ObjCInterfaceDecl *Class) override;
157
158 /// Called on entering a translation unit. Tells Clang by calling
159 /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() that
160 /// this object has something to say about undefined names.
161 ///
162 /// \param[in] Consumer
163 /// Unused.
164 void StartTranslationUnit(clang::ASTConsumer *Consumer) override;
165
166 //
167 // APIs for NamespaceMapCompleter
168 //
169
170 /// Look up the modules containing a given namespace and put the appropriate
171 /// entries in the namespace map.
172 ///
173 /// \param[in] namespace_map
174 /// The map to be completed.
175 ///
176 /// \param[in] name
177 /// The name of the namespace to be found.
178 ///
179 /// \param[in] parent_map
180 /// The map for the namespace's parent namespace, if there is
181 /// one.
184 ClangASTImporter::NamespaceMapSP &parent_map) const override;
185
186 //
187 // Helper APIs
188 //
189
190 clang::NamespaceDecl *
192 ClangASTImporter::NamespaceMapSP &namespace_decls);
193
194 /// The worker function for FindExternalVisibleDeclsByName.
195 ///
196 /// \param[in] context
197 /// The NameSearchContext to use when filing results.
198 virtual void FindExternalVisibleDecls(NameSearchContext &context);
199
200 clang::Sema *getSema();
201
202 void SetLookupsEnabled(bool lookups_enabled) {
203 m_lookups_enabled = lookups_enabled;
204 }
206
207 /// \class ClangASTSourceProxy ClangASTSource.h
208 /// "lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource
209 ///
210 /// Clang AST contexts like to own their AST sources, so this is a state-
211 /// free proxy object.
212 class ClangASTSourceProxy : public clang::ExternalASTSource {
213 public:
215
217 const clang::DeclContext *DC, clang::DeclarationName Name,
218 const clang::DeclContext *OriginalDC) override {
219 return m_original.FindExternalVisibleDeclsByName(DC, Name, OriginalDC);
220 }
221
223 const clang::DeclContext *DC,
224 llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
225 llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
226 return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
227 }
228
229 void CompleteType(clang::TagDecl *Tag) override {
230 return m_original.CompleteType(Tag);
231 }
232
233 void CompleteType(clang::ObjCInterfaceDecl *Class) override {
234 return m_original.CompleteType(Class);
235 }
236
238 const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
239 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
240 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
241 &BaseOffsets,
242 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
243 &VirtualBaseOffsets) override {
244 return m_original.layoutRecordType(Record, Size, Alignment, FieldOffsets,
245 BaseOffsets, VirtualBaseOffsets);
246 }
247
248 void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
249 return m_original.StartTranslationUnit(Consumer);
250 }
251
252 private:
254 };
255
256 clang::ExternalASTSource *CreateProxy() {
257 return new ClangASTSourceProxy(*this);
258 }
259
260protected:
261 /// Look for the complete version of an Objective-C interface, and return it
262 /// if found.
263 ///
264 /// \param[in] interface_decl
265 /// An ObjCInterfaceDecl that may not be the complete one.
266 ///
267 /// \return
268 /// NULL if the complete interface couldn't be found;
269 /// the complete interface otherwise.
270 clang::ObjCInterfaceDecl *
271 GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl);
272
273 /// Find all entities matching a given name in a given module, using a
274 /// NameSearchContext to make Decls for them.
275 ///
276 /// \param[in] context
277 /// The NameSearchContext that can construct Decls for this name.
278 ///
279 /// \param[in] module
280 /// If non-NULL, the module to query.
281 ///
282 /// \param[in] namespace_decl
283 /// If valid and module is non-NULL, the parent namespace.
285 lldb::ModuleSP module,
286 CompilerDeclContext &namespace_decl);
287
288 /// Find all Objective-C methods matching a given selector.
289 ///
290 /// \param[in] context
291 /// The NameSearchContext that can construct Decls for this name.
292 /// Its m_decl_name contains the selector and its m_decl_context
293 /// is the containing object.
295
296 /// Find all Objective-C properties and ivars with a given name.
297 ///
298 /// \param[in] context
299 /// The NameSearchContext that can construct Decls for this name.
300 /// Its m_decl_name contains the name and its m_decl_context
301 /// is the containing object.
303
304 /// Performs lookup into a namespace.
305 ///
306 /// \param context
307 /// The NameSearchContext for a lookup inside a namespace.
309
310 /// A wrapper for TypeSystemClang::CopyType that sets a flag that
311 /// indicates that we should not respond to queries during import.
312 ///
313 /// \param[in] src_type
314 /// The source type.
315 ///
316 /// \return
317 /// The imported type.
319
320 std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor();
321
322public:
323 /// Returns true if a name should be ignored by name lookup.
324 ///
325 /// \param[in] name
326 /// The name to be considered.
327 ///
328 /// \param[in] ignore_all_dollar_names
329 /// True if $-names of all sorts should be ignored.
330 ///
331 /// \return
332 /// True if the name is one of a class of names that are ignored by
333 /// global lookup for performance reasons.
334 bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);
335
336 /// Copies a single Decl into the parser's AST context.
337 ///
338 /// \param[in] src_decl
339 /// The Decl to copy.
340 ///
341 /// \return
342 /// A copy of the Decl in m_ast_context, or NULL if the copy failed.
343 clang::Decl *CopyDecl(clang::Decl *src_decl);
344
345 /// Determined the origin of a single Decl, if it can be found.
346 ///
347 /// \param[in] decl
348 /// The Decl whose origin is to be found.
349 ///
350 /// \return
351 /// True if lookup succeeded; false otherwise.
352 ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl);
353
354 /// Returns the TypeSystem that uses this ClangASTSource instance as it's
355 /// ExternalASTSource.
357
358private:
360 NameSearchContext &context,
362
363protected:
365 NameSearchContext &context,
366 clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);
367
370
371 /// Fills the namespace map of the given NameSearchContext.
372 ///
373 /// \param context The NameSearchContext with the namespace map to fill.
374 /// \param module_sp The module to search for namespaces or a nullptr if
375 /// the current target should be searched.
376 /// \param namespace_decl The DeclContext in which to search for namespaces.
377 void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp,
378 const CompilerDeclContext &namespace_decl);
379
380 clang::TagDecl *FindCompleteType(const clang::TagDecl *decl);
381
382 friend struct NameSearchContext;
383
385
386 /// The target to use in finding variables and types.
388 /// The AST context requests are coming in for.
389 clang::ASTContext *m_ast_context;
390 /// The TypeSystemClang for m_ast_context.
392 /// The file manager paired with the AST context.
393 clang::FileManager *m_file_manager;
394 /// The target's AST importer.
395 std::shared_ptr<ClangASTImporter> m_ast_importer_sp;
396 std::set<const clang::Decl *> m_active_lexical_decls;
397 std::set<const char *> m_active_lookups;
398};
399
400} // namespace lldb_private
401
402#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
std::shared_ptr< NamespaceMap > NamespaceMapSP
"lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource
bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name, const clang::DeclContext *OriginalDC) override
void CompleteType(clang::TagDecl *Tag) override
bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, llvm::DenseMap< const clang::FieldDecl *, uint64_t > &FieldOffsets, llvm::DenseMap< const clang::CXXRecordDecl *, clang::CharUnits > &BaseOffsets, llvm::DenseMap< const clang::CXXRecordDecl *, clang::CharUnits > &VirtualBaseOffsets) override
void CompleteType(clang::ObjCInterfaceDecl *Class) override
void FindExternalLexicalDecls(const clang::DeclContext *DC, llvm::function_ref< bool(clang::Decl::Kind)> IsKindWeWant, llvm::SmallVectorImpl< clang::Decl * > &Decls) override
void StartTranslationUnit(clang::ASTConsumer *Consumer) override
Provider for named objects defined in the debug info for Clang.
std::set< const char * > m_active_lookups
void LookupInNamespace(NameSearchContext &context)
Performs lookup into a namespace.
uint32_t GetNumExternalSelectors() override
void SetLookupsEnabled(bool lookups_enabled)
clang::TagDecl * FindCompleteType(const clang::TagDecl *decl)
clang::Decl * GetExternalDecl(clang::GlobalDeclID) override
Interface stubs.
clang::ASTContext * m_ast_context
The AST context requests are coming in for.
clang::Selector GetExternalSelector(uint32_t) override
std::set< const clang::Decl * > m_active_lexical_decls
void FindExternalLexicalDecls(const clang::DeclContext *DC, llvm::function_ref< bool(clang::Decl::Kind)> IsKindWeWant, llvm::SmallVectorImpl< clang::Decl * > &Decls) override
Enumerate all Decls in a given lexical context.
clang::CXXBaseSpecifier * GetExternalCXXBaseSpecifiers(uint64_t Offset) override
bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, llvm::DenseMap< const clang::FieldDecl *, uint64_t > &FieldOffsets, llvm::DenseMap< const clang::CXXRecordDecl *, clang::CharUnits > &BaseOffsets, llvm::DenseMap< const clang::CXXRecordDecl *, clang::CharUnits > &VirtualBaseOffsets) override
Specify the layout of the contents of a RecordDecl.
clang::Decl * CopyDecl(clang::Decl *src_decl)
Copies a single Decl into the parser's AST context.
bool IgnoreName(const ConstString name, bool ignore_all_dollar_names)
Returns true if a name should be ignored by name lookup.
virtual void FindExternalVisibleDecls(NameSearchContext &context)
The worker function for FindExternalVisibleDeclsByName.
void FindObjCPropertyAndIvarDecls(NameSearchContext &context)
Find all Objective-C properties and ivars with a given name.
TypeSystemClang * GetTypeSystem() const
Returns the TypeSystem that uses this ClangASTSource instance as it's ExternalASTSource.
ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl)
Determined the origin of a single Decl, if it can be found.
bool FindObjCPropertyAndIvarDeclsWithOrigin(NameSearchContext &context, DeclFromUser< const clang::ObjCInterfaceDecl > &origin_iface_decl)
bool FindObjCMethodDeclsWithOrigin(NameSearchContext &context, clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info)
std::shared_ptr< ClangModulesDeclVendor > GetClangModulesDeclVendor()
void CompleteNamespaceMap(ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name, ClangASTImporter::NamespaceMapSP &parent_map) const override
Look up the modules containing a given namespace and put the appropriate entries in the namespace map...
void FindDeclInObjCRuntime(NameSearchContext &context, ConstString name)
void CompleteType(clang::TagDecl *Tag) override
Complete a TagDecl.
~ClangASTSource() override
Destructor.
void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp, const CompilerDeclContext &namespace_decl)
Fills the namespace map of the given NameSearchContext.
void MaterializeVisibleDecls(const clang::DeclContext *DC)
CompilerType GuardedCopyType(const CompilerType &src_type)
A wrapper for TypeSystemClang::CopyType that sets a flag that indicates that we should not respond to...
void FindDeclInModules(NameSearchContext &context, ConstString name)
bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name, const clang::DeclContext *OriginalDC) override
Look up all Decls that match a particular name.
clang::NamespaceDecl * AddNamespace(NameSearchContext &context, ClangASTImporter::NamespaceMapSP &namespace_decls)
std::shared_ptr< ClangASTImporter > m_ast_importer_sp
The target's AST importer.
void InstallASTContext(TypeSystemClang &ast_context)
TypeSystemClang * m_clang_ast_context
The TypeSystemClang for m_ast_context.
void FindObjCMethodDecls(NameSearchContext &context)
Find all Objective-C methods matching a given selector.
const lldb::TargetSP m_target
The target to use in finding variables and types.
clang::ObjCInterfaceDecl * GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl)
Look for the complete version of an Objective-C interface, and return it if found.
void StartTranslationUnit(clang::ASTConsumer *Consumer) override
Called on entering a translation unit.
clang::FileManager * m_file_manager
The file manager paired with the AST context.
clang::Stmt * GetExternalDeclStmt(uint64_t) override
clang::ExternalASTSource * CreateProxy()
Represents a generic declaration context in a program.
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
A uniqued constant string class.
Definition: ConstString.h:40
A TypeSystem implementation based on Clang.
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::Target > TargetSP
Definition: lldb-forward.h:448
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:373
"lldb/Expression/ClangASTSource.h" Container for all objects relevant to a single name lookup