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