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