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 liblldb_ClangASTSource_h_
10 #define liblldb_ClangASTSource_h_
11 
12 #include <set>
13 
14 #include "lldb/Symbol/ClangASTImporter.h"
15 #include "lldb/Symbol/CompilerType.h"
16 #include "lldb/Target/Target.h"
17 #include "clang/AST/ExternalASTSource.h"
18 #include "clang/Basic/IdentifierTable.h"
19 
20 #include "llvm/ADT/SmallSet.h"
21 
22 namespace lldb_private {
23 
24 /// \class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"
25 /// Provider for named objects defined in the debug info for Clang
26 ///
27 /// As Clang parses an expression, it may encounter names that are not defined
28 /// inside the expression, including variables, functions, and types.  Clang
29 /// knows the name it is looking for, but nothing else. The ExternalSemaSource
30 /// class provides Decls (VarDecl, FunDecl, TypeDecl) to Clang for these
31 /// names, consulting the ClangExpressionDeclMap to do the actual lookups.
32 class ClangASTSource : public clang::ExternalASTSource,
33                        public ClangASTImporter::MapCompleter {
34 public:
35   /// Constructor
36   ///
37   /// Initializes class variables.
38   ///
39   /// \param[in] target
40   ///     A reference to the target containing debug information to use.
41   ///
42   /// \param[in] importer
43   ///     The ClangASTImporter to use.
44   ClangASTSource(const lldb::TargetSP &target,
45                  const lldb::ClangASTImporterSP &importer);
46 
47   /// Destructor
48   ~ClangASTSource() override;
49 
50   /// Interface stubs.
51   clang::Decl *GetExternalDecl(uint32_t) override { return nullptr; }
52   clang::Stmt *GetExternalDeclStmt(uint64_t) override { return nullptr; }
53   clang::Selector GetExternalSelector(uint32_t) override {
54     return clang::Selector();
55   }
56   uint32_t GetNumExternalSelectors() override { return 0; }
57   clang::CXXBaseSpecifier *
58   GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
59     return nullptr;
60   }
61   void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; }
62 
63   void InstallASTContext(ClangASTContext &ast_context);
64 
65   //
66   // APIs for ExternalASTSource
67   //
68 
69   /// Look up all Decls that match a particular name.  Only handles
70   /// Identifiers and DeclContexts that are either NamespaceDecls or
71   /// TranslationUnitDecls.  Calls SetExternalVisibleDeclsForName with the
72   /// result.
73   ///
74   /// The work for this function is done by
75   /// void FindExternalVisibleDecls (NameSearchContext &);
76   ///
77   /// \param[in] DC
78   ///     The DeclContext to register the found Decls in.
79   ///
80   /// \param[in] Name
81   ///     The name to find entries for.
82   ///
83   /// \return
84   ///     Whatever SetExternalVisibleDeclsForName returns.
85   bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
86                                       clang::DeclarationName Name) override;
87 
88   /// Enumerate all Decls in a given lexical context.
89   ///
90   /// \param[in] DC
91   ///     The DeclContext being searched.
92   ///
93   /// \param[in] IsKindWeWant
94   ///     A callback function that returns true given the
95   ///     DeclKinds of desired Decls, and false otherwise.
96   ///
97   /// \param[in] Decls
98   ///     A vector that is filled in with matching Decls.
99   void FindExternalLexicalDecls(
100       const clang::DeclContext *DC,
101       llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
102       llvm::SmallVectorImpl<clang::Decl *> &Decls) override;
103 
104   /// Specify the layout of the contents of a RecordDecl.
105   ///
106   /// \param[in] Record
107   ///     The record (in the parser's AST context) that needs to be
108   ///     laid out.
109   ///
110   /// \param[out] Size
111   ///     The total size of the record in bits.
112   ///
113   /// \param[out] Alignment
114   ///     The alignment of the record in bits.
115   ///
116   /// \param[in] FieldOffsets
117   ///     A map that must be populated with pairs of the record's
118   ///     fields (in the parser's AST context) and their offsets
119   ///     (measured in bits).
120   ///
121   /// \param[in] BaseOffsets
122   ///     A map that must be populated with pairs of the record's
123   ///     C++ concrete base classes (in the parser's AST context,
124   ///     and only if the record is a CXXRecordDecl and has base
125   ///     classes) and their offsets (measured in bytes).
126   ///
127   /// \param[in] VirtualBaseOffsets
128   ///     A map that must be populated with pairs of the record's
129   ///     C++ virtual base classes (in the parser's AST context,
130   ///     and only if the record is a CXXRecordDecl and has base
131   ///     classes) and their offsets (measured in bytes).
132   ///
133   /// \return
134   ///     True <=> the layout is valid.
135   bool layoutRecordType(
136       const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
137       llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
138       llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
139           &BaseOffsets,
140       llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
141           &VirtualBaseOffsets) override;
142 
143   /// Complete a TagDecl.
144   ///
145   /// \param[in] Tag
146   ///     The Decl to be completed in place.
147   void CompleteType(clang::TagDecl *Tag) override;
148 
149   /// Complete an ObjCInterfaceDecl.
150   ///
151   /// \param[in] Class
152   ///     The Decl to be completed in place.
153   void CompleteType(clang::ObjCInterfaceDecl *Class) override;
154 
155   /// Called on entering a translation unit.  Tells Clang by calling
156   /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() that
157   /// this object has something to say about undefined names.
158   ///
159   /// \param[in] Consumer
160   ///     Unused.
161   void StartTranslationUnit(clang::ASTConsumer *Consumer) override;
162 
163   //
164   // APIs for NamespaceMapCompleter
165   //
166 
167   /// Look up the modules containing a given namespace and put the appropriate
168   /// entries in the namespace map.
169   ///
170   /// \param[in] namespace_map
171   ///     The map to be completed.
172   ///
173   /// \param[in] name
174   ///     The name of the namespace to be found.
175   ///
176   /// \param[in] parent_map
177   ///     The map for the namespace's parent namespace, if there is
178   ///     one.
179   void CompleteNamespaceMap(
180       ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name,
181       ClangASTImporter::NamespaceMapSP &parent_map) const override;
182 
183   //
184   // Helper APIs
185   //
186 
187   clang::NamespaceDecl *
188   AddNamespace(NameSearchContext &context,
189                ClangASTImporter::NamespaceMapSP &namespace_decls);
190 
191   /// The worker function for FindExternalVisibleDeclsByName.
192   ///
193   /// \param[in] context
194   ///     The NameSearchContext to use when filing results.
195   virtual void FindExternalVisibleDecls(NameSearchContext &context);
196 
197   clang::Sema *getSema();
198 
199   void SetImportInProgress(bool import_in_progress) {
200     m_import_in_progress = import_in_progress;
201   }
202   bool GetImportInProgress() { return m_import_in_progress; }
203 
204   void SetLookupsEnabled(bool lookups_enabled) {
205     m_lookups_enabled = lookups_enabled;
206   }
207   bool GetLookupsEnabled() { return m_lookups_enabled; }
208 
209   /// \class ClangASTSourceProxy ClangASTSource.h
210   /// "lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource
211   ///
212   /// Clang AST contexts like to own their AST sources, so this is a state-
213   /// free proxy object.
214   class ClangASTSourceProxy : public clang::ExternalASTSource {
215   public:
216     ClangASTSourceProxy(ClangASTSource &original) : m_original(original) {}
217 
218     bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
219                                         clang::DeclarationName Name) override {
220       return m_original.FindExternalVisibleDeclsByName(DC, Name);
221     }
222 
223     void FindExternalLexicalDecls(
224         const clang::DeclContext *DC,
225         llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
226         llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
227       return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
228     }
229 
230     void CompleteType(clang::TagDecl *Tag) override {
231       return m_original.CompleteType(Tag);
232     }
233 
234     void CompleteType(clang::ObjCInterfaceDecl *Class) override {
235       return m_original.CompleteType(Class);
236     }
237 
238     bool layoutRecordType(
239         const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
240         llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
241         llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
242             &BaseOffsets,
243         llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
244             &VirtualBaseOffsets) override {
245       return m_original.layoutRecordType(Record, Size, Alignment, FieldOffsets,
246                                          BaseOffsets, VirtualBaseOffsets);
247     }
248 
249     void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
250       return m_original.StartTranslationUnit(Consumer);
251     }
252 
253   private:
254     ClangASTSource &m_original;
255   };
256 
257   clang::ExternalASTSource *CreateProxy() {
258     return new ClangASTSourceProxy(*this);
259   }
260 
261 protected:
262   /// Look for the complete version of an Objective-C interface, and return it
263   /// if found.
264   ///
265   /// \param[in] interface_decl
266   ///     An ObjCInterfaceDecl that may not be the complete one.
267   ///
268   /// \return
269   ///     NULL if the complete interface couldn't be found;
270   ///     the complete interface otherwise.
271   clang::ObjCInterfaceDecl *
272   GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl);
273 
274   /// Find all entities matching a given name in a given module, using a
275   /// NameSearchContext to make Decls for them.
276   ///
277   /// \param[in] context
278   ///     The NameSearchContext that can construct Decls for this name.
279   ///
280   /// \param[in] module
281   ///     If non-NULL, the module to query.
282   ///
283   /// \param[in] namespace_decl
284   ///     If valid and module is non-NULL, the parent namespace.
285   ///
286   /// \param[in] current_id
287   ///     The ID for the current FindExternalVisibleDecls invocation,
288   ///     for logging purposes.
289   void FindExternalVisibleDecls(NameSearchContext &context,
290                                 lldb::ModuleSP module,
291                                 CompilerDeclContext &namespace_decl,
292                                 unsigned int current_id);
293 
294   /// Find all Objective-C methods matching a given selector.
295   ///
296   /// \param[in] context
297   ///     The NameSearchContext that can construct Decls for this name.
298   ///     Its m_decl_name contains the selector and its m_decl_context
299   ///     is the containing object.
300   void FindObjCMethodDecls(NameSearchContext &context);
301 
302   /// Find all Objective-C properties and ivars with a given name.
303   ///
304   /// \param[in] context
305   ///     The NameSearchContext that can construct Decls for this name.
306   ///     Its m_decl_name contains the name and its m_decl_context
307   ///     is the containing object.
308   void FindObjCPropertyAndIvarDecls(NameSearchContext &context);
309 
310   /// A wrapper for ClangASTContext::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.
318   CompilerType GuardedCopyType(const CompilerType &src_type);
319 
320 public:
321   /// Returns true if a name should be ignored by name lookup.
322   ///
323   /// \param[in] name
324   ///     The name to be considered.
325   ///
326   /// \param[in] ignore_all_dollar_names
327   ///     True if $-names of all sorts should be ignored.
328   ///
329   /// \return
330   ///     True if the name is one of a class of names that are ignored by
331   ///     global lookup for performance reasons.
332   bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);
333 
334 public:
335   /// Copies a single Decl into the parser's AST context.
336   ///
337   /// \param[in] src_decl
338   ///     The Decl to copy.
339   ///
340   /// \return
341   ///     A copy of the Decl in m_ast_context, or NULL if the copy failed.
342   clang::Decl *CopyDecl(clang::Decl *src_decl);
343 
344   /// Determined the origin of a single Decl, if it can be found.
345   ///
346   /// \param[in] decl
347   ///     The Decl whose origin is to be found.
348   ///
349   /// \param[out] original_decl
350   ///     A pointer whose target is filled in with the original Decl.
351   ///
352   /// \param[in] original_ctx
353   ///     A pointer whose target is filled in with the original's ASTContext.
354   ///
355   /// \return
356   ///     True if lookup succeeded; false otherwise.
357   ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl);
358 
359 protected:
360   bool FindObjCMethodDeclsWithOrigin(
361       unsigned int current_id, NameSearchContext &context,
362       clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);
363 
364   friend struct NameSearchContext;
365 
366   bool m_import_in_progress;
367   bool m_lookups_enabled;
368 
369   /// The target to use in finding variables and types.
370   const lldb::TargetSP m_target;
371   /// The AST context requests are coming in for.
372   clang::ASTContext *m_ast_context;
373   /// The ClangASTContext for m_ast_context.
374   ClangASTContext *m_clang_ast_context;
375   /// The file manager paired with the AST context.
376   clang::FileManager *m_file_manager;
377   /// The target's AST importer.
378   lldb::ClangASTImporterSP m_ast_importer_sp;
379   std::set<const clang::Decl *> m_active_lexical_decls;
380   std::set<const char *> m_active_lookups;
381 };
382 
383 /// \class NameSearchContext ClangASTSource.h
384 /// "lldb/Expression/ClangASTSource.h" Container for all objects relevant to a
385 /// single name lookup
386 ///
387 /// LLDB needs to create Decls for entities it finds.  This class communicates
388 /// what name is being searched for and provides helper functions to construct
389 /// Decls given appropriate type information.
390 struct NameSearchContext {
391   /// The AST source making the request.
392   ClangASTSource &m_ast_source;
393   /// The list of declarations already constructed.
394   llvm::SmallVectorImpl<clang::NamedDecl *> &m_decls;
395   /// The mapping of all namespaces found for this request back to their
396   /// modules.
397   ClangASTImporter::NamespaceMapSP m_namespace_map;
398   /// The name being looked for.
399   const clang::DeclarationName &m_decl_name;
400   /// The DeclContext to put declarations into.
401   const clang::DeclContext *m_decl_context;
402   /// All the types of functions that have been reported, so we don't
403   /// report conflicts.
404   llvm::SmallSet<CompilerType, 5> m_function_types;
405 
406   struct {
407     bool variable : 1;
408     bool function_with_type_info : 1;
409     bool function : 1;
410     bool local_vars_nsp : 1;
411     bool type : 1;
412   } m_found;
413 
414   /// Constructor
415   ///
416   /// Initializes class variables.
417   ///
418   /// \param[in] astSource
419   ///     A reference to the AST source making a request.
420   ///
421   /// \param[in] decls
422   ///     A reference to a list into which new Decls will be placed.  This
423   ///     list is typically empty when the function is called.
424   ///
425   /// \param[in] name
426   ///     The name being searched for (always an Identifier).
427   ///
428   /// \param[in] dc
429   ///     The DeclContext to register Decls in.
430   NameSearchContext(ClangASTSource &astSource,
431                     llvm::SmallVectorImpl<clang::NamedDecl *> &decls,
432                     clang::DeclarationName &name, const clang::DeclContext *dc)
433       : m_ast_source(astSource), m_decls(decls), m_decl_name(name),
434         m_decl_context(dc) {
435     memset(&m_found, 0, sizeof(m_found));
436   }
437 
438   /// Create a VarDecl with the name being searched for and the provided type
439   /// and register it in the right places.
440   ///
441   /// \param[in] type
442   ///     The opaque QualType for the VarDecl being registered.
443   clang::NamedDecl *AddVarDecl(const CompilerType &type);
444 
445   /// Create a FunDecl with the name being searched for and the provided type
446   /// and register it in the right places.
447   ///
448   /// \param[in] type
449   ///     The opaque QualType for the FunDecl being registered.
450   ///
451   /// \param[in] extern_c
452   ///     If true, build an extern "C" linkage specification for this.
453   clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false);
454 
455   /// Create a FunDecl with the name being searched for and generic type (i.e.
456   /// intptr_t NAME_GOES_HERE(...)) and register it in the right places.
457   clang::NamedDecl *AddGenericFunDecl();
458 
459   /// Create a TypeDecl with the name being searched for and the provided type
460   /// and register it in the right places.
461   ///
462   /// \param[in] compiler_type
463   ///     The opaque QualType for the TypeDecl being registered.
464   clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
465 
466   /// Add Decls from the provided DeclContextLookupResult to the list of
467   /// results.
468   ///
469   /// \param[in] result
470   ///     The DeclContextLookupResult, usually returned as the result
471   ///     of querying a DeclContext.
472   void AddLookupResult(clang::DeclContextLookupResult result);
473 
474   /// Add a NamedDecl to the list of results.
475   ///
476   /// \param[in] decl
477   ///     The NamedDecl, usually returned as the result
478   ///     of querying a DeclContext.
479   void AddNamedDecl(clang::NamedDecl *decl);
480 };
481 
482 } // namespace lldb_private
483 
484 #endif // liblldb_ClangASTSource_h_
485