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 
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,
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(uint32_t) 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) { return; }
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.
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.
181  ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name,
182  ClangASTImporter::NamespaceMapSP &parent_map) const override;
183 
184  //
185  // Helper APIs
186  //
187 
188  clang::NamespaceDecl *
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 SetImportInProgress(bool import_in_progress) {
201  m_import_in_progress = import_in_progress;
202  }
204 
205  void SetLookupsEnabled(bool lookups_enabled) {
206  m_lookups_enabled = lookups_enabled;
207  }
209 
210  /// \class ClangASTSourceProxy ClangASTSource.h
211  /// "lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource
212  ///
213  /// Clang AST contexts like to own their AST sources, so this is a state-
214  /// free proxy object.
215  class ClangASTSourceProxy : public clang::ExternalASTSource {
216  public:
218 
219  bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
220  clang::DeclarationName Name) override {
222  }
223 
225  const clang::DeclContext *DC,
226  llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
227  llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
228  return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
229  }
230 
231  void CompleteType(clang::TagDecl *Tag) override {
232  return m_original.CompleteType(Tag);
233  }
234 
235  void CompleteType(clang::ObjCInterfaceDecl *Class) override {
236  return m_original.CompleteType(Class);
237  }
238 
240  const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
241  llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
242  llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
243  &BaseOffsets,
244  llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
245  &VirtualBaseOffsets) override {
246  return m_original.layoutRecordType(Record, Size, Alignment, FieldOffsets,
247  BaseOffsets, VirtualBaseOffsets);
248  }
249 
250  void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
251  return m_original.StartTranslationUnit(Consumer);
252  }
253 
254  private:
256  };
257 
258  clang::ExternalASTSource *CreateProxy() {
259  return new ClangASTSourceProxy(*this);
260  }
261 
262 protected:
263  /// Look for the complete version of an Objective-C interface, and return it
264  /// if found.
265  ///
266  /// \param[in] interface_decl
267  /// An ObjCInterfaceDecl that may not be the complete one.
268  ///
269  /// \return
270  /// NULL if the complete interface couldn't be found;
271  /// the complete interface otherwise.
272  clang::ObjCInterfaceDecl *
273  GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl);
274 
275  /// Find all entities matching a given name in a given module, using a
276  /// NameSearchContext to make Decls for them.
277  ///
278  /// \param[in] context
279  /// The NameSearchContext that can construct Decls for this name.
280  ///
281  /// \param[in] module
282  /// If non-NULL, the module to query.
283  ///
284  /// \param[in] namespace_decl
285  /// If valid and module is non-NULL, the parent namespace.
287  lldb::ModuleSP module,
288  CompilerDeclContext &namespace_decl);
289 
290  /// Find all Objective-C methods matching a given selector.
291  ///
292  /// \param[in] context
293  /// The NameSearchContext that can construct Decls for this name.
294  /// Its m_decl_name contains the selector and its m_decl_context
295  /// is the containing object.
296  void FindObjCMethodDecls(NameSearchContext &context);
297 
298  /// Find all Objective-C properties and ivars with a given name.
299  ///
300  /// \param[in] context
301  /// The NameSearchContext that can construct Decls for this name.
302  /// Its m_decl_name contains the name and its m_decl_context
303  /// is the containing object.
305 
306  /// Performs lookup into a namespace.
307  ///
308  /// \param context
309  /// The NameSearchContext for a lookup inside a namespace.
310  void LookupInNamespace(NameSearchContext &context);
311 
312  /// A wrapper for TypeSystemClang::CopyType that sets a flag that
313  /// indicates that we should not respond to queries during import.
314  ///
315  /// \param[in] src_type
316  /// The source type.
317  ///
318  /// \return
319  /// The imported type.
320  CompilerType GuardedCopyType(const CompilerType &src_type);
321 
322 public:
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 public:
337  /// Copies a single Decl into the parser's AST context.
338  ///
339  /// \param[in] src_decl
340  /// The Decl to copy.
341  ///
342  /// \return
343  /// A copy of the Decl in m_ast_context, or NULL if the copy failed.
344  clang::Decl *CopyDecl(clang::Decl *src_decl);
345 
346  /// Determined the origin of a single Decl, if it can be found.
347  ///
348  /// \param[in] decl
349  /// The Decl whose origin is to be found.
350  ///
351  /// \return
352  /// True if lookup succeeded; false otherwise.
353  ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl);
354 
355  /// Returns the TypeSystem that uses this ClangASTSource instance as it's
356  /// ExternalASTSource.
358 
359 protected:
361  NameSearchContext &context,
362  clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);
363 
364  void FindDeclInModules(NameSearchContext &context, ConstString name);
366 
367  /// Fills the namespace map of the given NameSearchContext.
368  ///
369  /// \param context The NameSearchContext with the namespace map to fill.
370  /// \param module_sp The module to search for namespaces or a nullptr if
371  /// the current target should be searched.
372  /// \param namespace_decl The DeclContext in which to search for namespaces.
373  void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp,
374  const CompilerDeclContext &namespace_decl);
375 
376  friend struct NameSearchContext;
377 
380 
381  /// The target to use in finding variables and types.
382  const lldb::TargetSP m_target;
383  /// The AST context requests are coming in for.
384  clang::ASTContext *m_ast_context;
385  /// The TypeSystemClang for m_ast_context.
387  /// The file manager paired with the AST context.
388  clang::FileManager *m_file_manager;
389  /// The target's AST importer.
390  std::shared_ptr<ClangASTImporter> m_ast_importer_sp;
391  std::set<const clang::Decl *> m_active_lexical_decls;
392  std::set<const char *> m_active_lookups;
393 };
394 
395 } // namespace lldb_private
396 
397 #endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
void SetLookupsEnabled(bool lookups_enabled)
A class that represents a running process on the host machine.
Represents a generic declaration context in a program.
void FindDeclInObjCRuntime(NameSearchContext &context, ConstString name)
Provider for named objects defined in the debug info for Clang.
A TypeSystem implementation based on Clang.
void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp, const CompilerDeclContext &namespace_decl)
Fills the namespace map of the given NameSearchContext.
virtual void FindExternalVisibleDecls(NameSearchContext &context)
The worker function for FindExternalVisibleDeclsByName.
clang::Decl * GetExternalDecl(uint32_t) override
Interface stubs.
"lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource
"lldb/Expression/ClangASTSource.h" Container for all objects relevant to a single name lookup ...
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 FindDeclInModules(NameSearchContext &context, ConstString name)
clang::Stmt * GetExternalDeclStmt(uint64_t) override
void StartTranslationUnit(clang::ASTConsumer *Consumer) override
bool IgnoreName(const ConstString name, bool ignore_all_dollar_names)
Returns true if a name should be ignored by name lookup.
ClangASTSource(const lldb::TargetSP &target, const std::shared_ptr< ClangASTImporter > &importer)
Constructor.
clang::Decl * CopyDecl(clang::Decl *src_decl)
Copies a single Decl into the parser&#39;s AST context.
void LookupInNamespace(NameSearchContext &context)
Performs lookup into a namespace.
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
clang::NamespaceDecl * AddNamespace(NameSearchContext &context, ClangASTImporter::NamespaceMapSP &namespace_decls)
uint32_t GetNumExternalSelectors() override
std::shared_ptr< ClangASTImporter > m_ast_importer_sp
The target&#39;s AST importer.
std::set< const char * > m_active_lookups
~ClangASTSource() override
Destructor.
void CompleteType(clang::TagDecl *Tag) override
const lldb::TargetSP m_target
The target to use in finding variables and types.
clang::ExternalASTSource * CreateProxy()
TypeSystemClang * m_clang_ast_context
The TypeSystemClang for m_ast_context.
std::set< const clang::Decl * > m_active_lexical_decls
std::shared_ptr< NamespaceMap > NamespaceMapSP
void MaterializeVisibleDecls(const clang::DeclContext *DC)
clang::ASTContext * m_ast_context
The AST context requests are coming in for.
clang::FileManager * m_file_manager
The file manager paired with the AST context.
void StartTranslationUnit(clang::ASTConsumer *Consumer) override
Called on entering a translation unit.
clang::Selector GetExternalSelector(uint32_t) override
bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override
Look up all Decls that match a particular name.
ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl)
Determined the origin of a single Decl, if it can be found.
bool FindObjCMethodDeclsWithOrigin(NameSearchContext &context, clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info)
void FindExternalLexicalDecls(const clang::DeclContext *DC, llvm::function_ref< bool(clang::Decl::Kind)> IsKindWeWant, llvm::SmallVectorImpl< clang::Decl *> &Decls) override
void SetImportInProgress(bool import_in_progress)
A uniqued constant string class.
Definition: ConstString.h:40
void CompleteType(clang::TagDecl *Tag) override
Complete a TagDecl.
TypeSystemClang * GetTypeSystem() const
Returns the TypeSystem that uses this ClangASTSource instance as it&#39;s ExternalASTSource.
bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override
Represents a generic type in a programming language.
Definition: CompilerType.h:33
void InstallASTContext(TypeSystemClang &ast_context)
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.
void FindObjCMethodDecls(NameSearchContext &context)
Find all Objective-C methods matching a given selector.
CompilerType GuardedCopyType(const CompilerType &src_type)
A wrapper for TypeSystemClang::CopyType that sets a flag that indicates that we should not respond to...
void FindObjCPropertyAndIvarDecls(NameSearchContext &context)
Find all Objective-C properties and ivars with a given name.
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
Enumerate all Decls in a given lexical context.
clang::ObjCInterfaceDecl * GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl)
Look for the complete version of an Objective-C interface, and return it if found.
clang::CXXBaseSpecifier * GetExternalCXXBaseSpecifiers(uint64_t Offset) override