ClangASTSource.h revision 79e9f965938ec5766b9caedfa85262ecb603c453
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    bool
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        bool
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        ClangASTMetadata *
300        GetMetadata(uintptr_t object)
301        {
302            return m_original.GetMetadata(object);
303        }
304
305        void SetMetadata(uintptr_t object, ClangASTMetadata &metadata)
306        {
307            return m_original.SetMetadata(object, metadata);
308        }
309
310        bool HasMetadata(uintptr_t object)
311        {
312            return m_original.HasMetadata(object);
313        }
314    private:
315        ClangASTSource &m_original;
316    };
317
318    clang::ExternalASTSource *CreateProxy()
319    {
320        return new ClangASTSourceProxy(*this);
321    }
322
323protected:
324    //------------------------------------------------------------------
325    /// Look for the complete version of an Objective-C interface, and
326    /// return it if found.
327    ///
328    /// @param[in] interface_decl
329    ///     An ObjCInterfaceDecl that may not be the complete one.
330    ///
331    /// @return
332    ///     NULL if the complete interface couldn't be found;
333    ///     the complete interface otherwise.
334    //------------------------------------------------------------------
335    clang::ObjCInterfaceDecl *
336    GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl);
337
338    //------------------------------------------------------------------
339    /// Find all entities matching a given name in a given module,
340    /// using a NameSearchContext to make Decls for them.
341    ///
342    /// @param[in] context
343    ///     The NameSearchContext that can construct Decls for this name.
344    ///
345    /// @param[in] module
346    ///     If non-NULL, the module to query.
347    ///
348    /// @param[in] namespace_decl
349    ///     If valid and module is non-NULL, the parent namespace.
350    ///
351    /// @param[in] current_id
352    ///     The ID for the current FindExternalVisibleDecls invocation,
353    ///     for logging purposes.
354    ///
355    /// @return
356    ///     True on success; false otherwise.
357    //------------------------------------------------------------------
358    void
359    FindExternalVisibleDecls (NameSearchContext &context,
360                              lldb::ModuleSP module,
361                              ClangNamespaceDecl &namespace_decl,
362                              unsigned int current_id);
363
364    //------------------------------------------------------------------
365    /// Find all Objective-C methods matching a given selector.
366    ///
367    /// @param[in] context
368    ///     The NameSearchContext that can construct Decls for this name.
369    ///     Its m_decl_name contains the selector and its m_decl_context
370    ///     is the containing object.
371    //------------------------------------------------------------------
372    void
373    FindObjCMethodDecls (NameSearchContext &context);
374
375    //------------------------------------------------------------------
376    /// Find all Objective-C properties and ivars with a given name.
377    ///
378    /// @param[in] context
379    ///     The NameSearchContext that can construct Decls for this name.
380    ///     Its m_decl_name contains the name and its m_decl_context
381    ///     is the containing object.
382    //------------------------------------------------------------------
383    void
384    FindObjCPropertyAndIvarDecls (NameSearchContext &context);
385
386    //------------------------------------------------------------------
387    /// A wrapper for ClangASTContext::CopyType that sets a flag that
388    /// indicates that we should not respond to queries during import.
389    ///
390    /// @param[in] dest_context
391    ///     The target AST context, typically the parser's AST context.
392    ///
393    /// @param[in] source_context
394    ///     The source AST context, typically the AST context of whatever
395    ///     symbol file the type was found in.
396    ///
397    /// @param[in] clang_type
398    ///     The source type.
399    ///
400    /// @return
401    ///     The imported type.
402    //------------------------------------------------------------------
403    void *
404    GuardedCopyType (clang::ASTContext *dest_context,
405                     clang::ASTContext *source_context,
406                     void *clang_type);
407
408    friend struct NameSearchContext;
409
410    bool                    m_import_in_progress;
411    bool                    m_lookups_enabled;
412
413    const lldb::TargetSP                m_target;           ///< The target to use in finding variables and types.
414	clang::ASTContext                  *m_ast_context;      ///< The AST context requests are coming in for.
415    ClangASTImporter                   *m_ast_importer;     ///< The target's AST importer.
416    std::set<const char *>              m_active_lookups;
417};
418
419//----------------------------------------------------------------------
420/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h"
421/// @brief Container for all objects relevant to a single name lookup
422///
423/// LLDB needs to create Decls for entities it finds.  This class communicates
424/// what name is being searched for and provides helper functions to construct
425/// Decls given appropriate type information.
426//----------------------------------------------------------------------
427struct NameSearchContext {
428    ClangASTSource &m_ast_source;                       ///< The AST source making the request
429    llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls;  ///< The list of declarations already constructed
430    ClangASTImporter::NamespaceMapSP m_namespace_map;   ///< The mapping of all namespaces found for this request back to their modules
431    const clang::DeclarationName &m_decl_name;          ///< The name being looked for
432    const clang::DeclContext *m_decl_context;           ///< The DeclContext to put declarations into
433
434    struct {
435        bool variable                   : 1;
436        bool function_with_type_info    : 1;
437        bool function                   : 1;
438    } m_found;
439
440    //------------------------------------------------------------------
441    /// Constructor
442    ///
443    /// Initializes class variables.
444    ///
445    /// @param[in] astSource
446    ///     A reference to the AST source making a request.
447    ///
448    /// @param[in] decls
449    ///     A reference to a list into which new Decls will be placed.  This
450    ///     list is typically empty when the function is called.
451    ///
452    /// @param[in] name
453    ///     The name being searched for (always an Identifier).
454    ///
455    /// @param[in] dc
456    ///     The DeclContext to register Decls in.
457    //------------------------------------------------------------------
458    NameSearchContext (ClangASTSource &astSource,
459                       llvm::SmallVectorImpl<clang::NamedDecl*> &decls,
460                       clang::DeclarationName &name,
461                       const clang::DeclContext *dc) :
462        m_ast_source(astSource),
463        m_decls(decls),
464        m_decl_name(name),
465        m_decl_context(dc)
466    {
467        memset(&m_found, 0, sizeof(m_found));
468    }
469
470    //------------------------------------------------------------------
471    /// Create a VarDecl with the name being searched for and the provided
472    /// type and register it in the right places.
473    ///
474    /// @param[in] type
475    ///     The opaque QualType for the VarDecl being registered.
476    //------------------------------------------------------------------
477    clang::NamedDecl *AddVarDecl(void *type);
478
479    //------------------------------------------------------------------
480    /// Create a FunDecl with the name being searched for and the provided
481    /// type and register it in the right places.
482    ///
483    /// @param[in] type
484    ///     The opaque QualType for the FunDecl being registered.
485    //------------------------------------------------------------------
486    clang::NamedDecl *AddFunDecl(void *type);
487
488    //------------------------------------------------------------------
489    /// Create a FunDecl with the name being searched for and generic
490    /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
491    /// right places.
492    //------------------------------------------------------------------
493    clang::NamedDecl *AddGenericFunDecl();
494
495    //------------------------------------------------------------------
496    /// Create a TypeDecl with the name being searched for and the provided
497    /// type and register it in the right places.
498    ///
499    /// @param[in] type
500    ///     The opaque QualType for the TypeDecl being registered.
501    //------------------------------------------------------------------
502    clang::NamedDecl *AddTypeDecl(void *type);
503
504
505    //------------------------------------------------------------------
506    /// Add Decls from the provided DeclContextLookupResult to the list
507    /// of results.
508    ///
509    /// @param[in] result
510    ///     The DeclContextLookupResult, usually returned as the result
511    ///     of querying a DeclContext.
512    //------------------------------------------------------------------
513    void AddLookupResult (clang::DeclContextLookupConstResult result);
514
515    //------------------------------------------------------------------
516    /// Add a NamedDecl to the list of results.
517    ///
518    /// @param[in] decl
519    ///     The NamedDecl, usually returned as the result
520    ///     of querying a DeclContext.
521    //------------------------------------------------------------------
522    void AddNamedDecl (clang::NamedDecl *decl);
523};
524
525}
526
527#endif
528