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