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 SetLookupsEnabled(bool lookups_enabled) {
201  m_lookups_enabled = lookups_enabled;
202  }
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:
213 
214  bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
215  clang::DeclarationName Name) override {
217  }
218 
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 
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:
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.
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.
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 public:
318  /// Returns true if a name should be ignored by name lookup.
319  ///
320  /// \param[in] name
321  /// The name to be considered.
322  ///
323  /// \param[in] ignore_all_dollar_names
324  /// True if $-names of all sorts should be ignored.
325  ///
326  /// \return
327  /// True if the name is one of a class of names that are ignored by
328  /// global lookup for performance reasons.
329  bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);
330 
331  /// Copies a single Decl into the parser's AST context.
332  ///
333  /// \param[in] src_decl
334  /// The Decl to copy.
335  ///
336  /// \return
337  /// A copy of the Decl in m_ast_context, or NULL if the copy failed.
338  clang::Decl *CopyDecl(clang::Decl *src_decl);
339 
340  /// Determined the origin of a single Decl, if it can be found.
341  ///
342  /// \param[in] decl
343  /// The Decl whose origin is to be found.
344  ///
345  /// \return
346  /// True if lookup succeeded; false otherwise.
347  ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl);
348 
349  /// Returns the TypeSystem that uses this ClangASTSource instance as it's
350  /// ExternalASTSource.
352 
353 protected:
355  NameSearchContext &context,
356  clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);
357 
358  void FindDeclInModules(NameSearchContext &context, ConstString name);
360 
361  /// Fills the namespace map of the given NameSearchContext.
362  ///
363  /// \param context The NameSearchContext with the namespace map to fill.
364  /// \param module_sp The module to search for namespaces or a nullptr if
365  /// the current target should be searched.
366  /// \param namespace_decl The DeclContext in which to search for namespaces.
367  void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp,
368  const CompilerDeclContext &namespace_decl);
369 
370  clang::TagDecl *FindCompleteType(const clang::TagDecl *decl);
371 
372  friend struct NameSearchContext;
373 
375 
376  /// The target to use in finding variables and types.
377  const lldb::TargetSP m_target;
378  /// The AST context requests are coming in for.
379  clang::ASTContext *m_ast_context;
380  /// The TypeSystemClang for m_ast_context.
382  /// The file manager paired with the AST context.
383  clang::FileManager *m_file_manager;
384  /// The target's AST importer.
385  std::shared_ptr<ClangASTImporter> m_ast_importer_sp;
386  std::set<const clang::Decl *> m_active_lexical_decls;
387  std::set<const char *> m_active_lookups;
388 };
389 
390 } // namespace lldb_private
391 
392 #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
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
Generic representation of a type in a programming language.
Definition: CompilerType.h:33
void InstallASTContext(TypeSystemClang &ast_context)
clang::TagDecl * FindCompleteType(const clang::TagDecl *decl)
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