ClangASTSource.h revision e0028b827759c5ad2cbc45947371c362193a63bc
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    /// Complete a TagDecl.
125    ///
126    /// @param[in] Tag
127    ///     The Decl to be completed in place.
128    //------------------------------------------------------------------
129    virtual void
130    CompleteType (clang::TagDecl *Tag);
131
132    //------------------------------------------------------------------
133    /// Complete an ObjCInterfaceDecl.
134    ///
135    /// @param[in] Class
136    ///     The Decl to be completed in place.
137    //------------------------------------------------------------------
138    virtual void
139    CompleteType (clang::ObjCInterfaceDecl *Class);
140
141    //------------------------------------------------------------------
142    /// Called on entering a translation unit.  Tells Clang by calling
143    /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage()
144    /// that this object has something to say about undefined names.
145    ///
146    /// @param[in] ASTConsumer
147    ///     Unused.
148    //------------------------------------------------------------------
149    void StartTranslationUnit (clang::ASTConsumer *Consumer);
150
151    //
152    // APIs for NamespaceMapCompleter
153    //
154
155    //------------------------------------------------------------------
156    /// Look up the modules containing a given namespace and put the
157    /// appropriate entries in the namespace map.
158    ///
159    /// @param[in] namespace_map
160    ///     The map to be completed.
161    ///
162    /// @param[in] name
163    ///     The name of the namespace to be found.
164    ///
165    /// @param[in] parent_map
166    ///     The map for the namespace's parent namespace, if there is
167    ///     one.
168    //------------------------------------------------------------------
169    void CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map,
170                               const ConstString &name,
171                               ClangASTImporter::NamespaceMapSP &parent_map) const;
172
173    //
174    // Helper APIs
175    //
176
177    clang::NamespaceDecl *
178    AddNamespace (NameSearchContext &context,
179                  ClangASTImporter::NamespaceMapSP &namespace_decls);
180
181    //------------------------------------------------------------------
182    /// The worker function for FindExternalVisibleDeclsByName.
183    ///
184    /// @param[in] context
185    ///     The NameSearchContext to use when filing results.
186    //------------------------------------------------------------------
187    virtual void FindExternalVisibleDecls (NameSearchContext &context);
188
189    void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; }
190    bool GetImportInProgress () { return m_import_in_progress; }
191
192    void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; }
193    bool GetLookupsEnabled () { return m_lookups_enabled; }
194
195    //----------------------------------------------------------------------
196    /// @class ClangASTSourceProxy ClangASTSource.h "lldb/Expression/ClangASTSource.h"
197    /// @brief Proxy for ClangASTSource
198    ///
199    /// Clang AST contexts like to own their AST sources, so this is a
200    /// state-free proxy object.
201    //----------------------------------------------------------------------
202    class ClangASTSourceProxy : public ClangExternalASTSourceCommon
203    {
204    public:
205        ClangASTSourceProxy (ClangASTSource &original) :
206            m_original(original)
207        {
208        }
209
210        clang::DeclContextLookupResult
211        FindExternalVisibleDeclsByName (const clang::DeclContext *DC,
212                                        clang::DeclarationName Name)
213        {
214            return m_original.FindExternalVisibleDeclsByName(DC, Name);
215        }
216
217        clang::ExternalLoadResult
218        FindExternalLexicalDecls (const clang::DeclContext *DC,
219                                  bool (*isKindWeWant)(clang::Decl::Kind),
220                                  llvm::SmallVectorImpl<clang::Decl*> &Decls)
221        {
222            return m_original.FindExternalLexicalDecls(DC, isKindWeWant, Decls);
223        }
224
225        void
226        CompleteType (clang::TagDecl *Tag)
227        {
228            return m_original.CompleteType(Tag);
229        }
230
231        void
232        CompleteType (clang::ObjCInterfaceDecl *Class)
233        {
234            return m_original.CompleteType(Class);
235        }
236
237        void StartTranslationUnit (clang::ASTConsumer *Consumer)
238        {
239            return m_original.StartTranslationUnit(Consumer);
240        }
241
242        uint64_t GetMetadata(uintptr_t object)
243        {
244            return m_original.GetMetadata(object);
245        }
246
247        void SetMetadata(uintptr_t object, uint64_t metadata)
248        {
249            return m_original.SetMetadata(object, metadata);
250        }
251
252        bool HasMetadata(uintptr_t object)
253        {
254            return m_original.HasMetadata(object);
255        }
256    private:
257        ClangASTSource &m_original;
258    };
259
260    clang::ExternalASTSource *CreateProxy()
261    {
262        return new ClangASTSourceProxy(*this);
263    }
264
265protected:
266    //------------------------------------------------------------------
267    /// Find all entities matching a given name in a given module,
268    /// using a NameSearchContext to make Decls for them.
269    ///
270    /// @param[in] context
271    ///     The NameSearchContext that can construct Decls for this name.
272    ///
273    /// @param[in] module
274    ///     If non-NULL, the module to query.
275    ///
276    /// @param[in] namespace_decl
277    ///     If valid and module is non-NULL, the parent namespace.
278    ///
279    /// @param[in] current_id
280    ///     The ID for the current FindExternalVisibleDecls invocation,
281    ///     for logging purposes.
282    ///
283    /// @return
284    ///     True on success; false otherwise.
285    //------------------------------------------------------------------
286    void
287    FindExternalVisibleDecls (NameSearchContext &context,
288                              lldb::ModuleSP module,
289                              ClangNamespaceDecl &namespace_decl,
290                              unsigned int current_id);
291
292    //------------------------------------------------------------------
293    /// Find all Objective-C methods matching a given selector.
294    ///
295    /// @param[in] context
296    ///     The NameSearchContext that can construct Decls for this name.
297    ///     Its m_decl_name contains the selector and its m_decl_context
298    ///     is the containing object.
299    //------------------------------------------------------------------
300    void
301    FindObjCMethodDecls (NameSearchContext &context);
302
303    //------------------------------------------------------------------
304    /// Find all Objective-C properties with a given name.
305    ///
306    /// @param[in] context
307    ///     The NameSearchContext that can construct Decls for this name.
308    ///     Its m_decl_name contains the name and its m_decl_context
309    ///     is the containing object.
310    //------------------------------------------------------------------
311    void
312    FindObjCPropertyDecls (NameSearchContext &context);
313
314    //------------------------------------------------------------------
315    /// A wrapper for ClangASTContext::CopyType that sets a flag that
316    /// indicates that we should not respond to queries during import.
317    ///
318    /// @param[in] dest_context
319    ///     The target AST context, typically the parser's AST context.
320    ///
321    /// @param[in] source_context
322    ///     The source AST context, typically the AST context of whatever
323    ///     symbol file the type was found in.
324    ///
325    /// @param[in] clang_type
326    ///     The source type.
327    ///
328    /// @return
329    ///     The imported type.
330    //------------------------------------------------------------------
331    void *
332    GuardedCopyType (clang::ASTContext *dest_context,
333                     clang::ASTContext *source_context,
334                     void *clang_type);
335
336    friend struct NameSearchContext;
337
338    bool                    m_import_in_progress;
339    bool                    m_lookups_enabled;
340
341    const lldb::TargetSP                m_target;           ///< The target to use in finding variables and types.
342	clang::ASTContext                  *m_ast_context;      ///< The AST context requests are coming in for.
343    ClangASTImporter                   *m_ast_importer;     ///< The target's AST importer.
344    std::set<const char *>              m_active_lookups;
345};
346
347//----------------------------------------------------------------------
348/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h"
349/// @brief Container for all objects relevant to a single name lookup
350///
351/// LLDB needs to create Decls for entities it finds.  This class communicates
352/// what name is being searched for and provides helper functions to construct
353/// Decls given appropriate type information.
354//----------------------------------------------------------------------
355struct NameSearchContext {
356    ClangASTSource &m_ast_source;                       ///< The AST source making the request
357    llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls;  ///< The list of declarations already constructed
358    ClangASTImporter::NamespaceMapSP m_namespace_map;   ///< The mapping of all namespaces found for this request back to their modules
359    const clang::DeclarationName &m_decl_name;          ///< The name being looked for
360    const clang::DeclContext *m_decl_context;           ///< The DeclContext to put declarations into
361
362    struct {
363        bool variable                   : 1;
364        bool function_with_type_info    : 1;
365        bool function                   : 1;
366    } m_found;
367
368    //------------------------------------------------------------------
369    /// Constructor
370    ///
371    /// Initializes class variables.
372    ///
373    /// @param[in] astSource
374    ///     A reference to the AST source making a request.
375    ///
376    /// @param[in] decls
377    ///     A reference to a list into which new Decls will be placed.  This
378    ///     list is typically empty when the function is called.
379    ///
380    /// @param[in] name
381    ///     The name being searched for (always an Identifier).
382    ///
383    /// @param[in] dc
384    ///     The DeclContext to register Decls in.
385    //------------------------------------------------------------------
386    NameSearchContext (ClangASTSource &astSource,
387                       llvm::SmallVectorImpl<clang::NamedDecl*> &decls,
388                       clang::DeclarationName &name,
389                       const clang::DeclContext *dc) :
390        m_ast_source(astSource),
391        m_decls(decls),
392        m_decl_name(name),
393        m_decl_context(dc)
394    {
395        memset(&m_found, 0, sizeof(m_found));
396    }
397
398    //------------------------------------------------------------------
399    /// Create a VarDecl with the name being searched for and the provided
400    /// type and register it in the right places.
401    ///
402    /// @param[in] type
403    ///     The opaque QualType for the VarDecl being registered.
404    //------------------------------------------------------------------
405    clang::NamedDecl *AddVarDecl(void *type);
406
407    //------------------------------------------------------------------
408    /// Create a FunDecl with the name being searched for and the provided
409    /// type and register it in the right places.
410    ///
411    /// @param[in] type
412    ///     The opaque QualType for the FunDecl being registered.
413    //------------------------------------------------------------------
414    clang::NamedDecl *AddFunDecl(void *type);
415
416    //------------------------------------------------------------------
417    /// Create a FunDecl with the name being searched for and generic
418    /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
419    /// right places.
420    //------------------------------------------------------------------
421    clang::NamedDecl *AddGenericFunDecl();
422
423    //------------------------------------------------------------------
424    /// Create a TypeDecl with the name being searched for and the provided
425    /// type and register it in the right places.
426    ///
427    /// @param[in] type
428    ///     The opaque QualType for the TypeDecl being registered.
429    //------------------------------------------------------------------
430    clang::NamedDecl *AddTypeDecl(void *type);
431
432
433    //------------------------------------------------------------------
434    /// Add Decls from the provided DeclContextLookupResult to the list
435    /// of results.
436    ///
437    /// @param[in] result
438    ///     The DeclContextLookupResult, usually returned as the result
439    ///     of querying a DeclContext.
440    //------------------------------------------------------------------
441    void AddLookupResult (clang::DeclContextLookupConstResult result);
442
443    //------------------------------------------------------------------
444    /// Add a NamedDecl to the list of results.
445    ///
446    /// @param[in] decl
447    ///     The NamedDecl, usually returned as the result
448    ///     of querying a DeclContext.
449    //------------------------------------------------------------------
450    void AddNamedDecl (clang::NamedDecl *decl);
451};
452
453}
454
455#endif
456