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