ClangASTSource.h revision 73b520f4f60dca58e58e446c9504d45384ee677b
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 "clang/AST/ExternalASTSource.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 clang::ExternalASTSource,
35    public ClangASTImporter::NamespaceMapCompleter
36{
37public:
38    //------------------------------------------------------------------
39    /// Constructor
40    ///
41    /// Initializes class variabes.
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_ast_context (NULL),
48        m_active_lookups (),
49        m_import_in_progress (false),
50        m_lookups_enabled (false),
51        m_target (target)
52    {
53    }
54
55    //------------------------------------------------------------------
56    /// Destructor
57    //------------------------------------------------------------------
58	~ClangASTSource();
59
60    //------------------------------------------------------------------
61    /// Interface stubs.
62    //------------------------------------------------------------------
63    clang::Decl *GetExternalDecl (uint32_t)         {   return NULL;                }
64    clang::Stmt *GetExternalDeclStmt (uint64_t)     {   return NULL;                }
65	clang::Selector GetExternalSelector (uint32_t)  {   return clang::Selector();   }
66    uint32_t GetNumExternalSelectors ()             {   return 0;                   }
67    clang::CXXBaseSpecifier *GetExternalCXXBaseSpecifiers (uint64_t Offset)
68                                                    {   return NULL;                }
69    void MaterializeVisibleDecls (const clang::DeclContext *DC)
70                                                    {   return;                     }
71
72    void InstallASTContext (clang::ASTContext *ast_context)
73    {
74        if (!m_ast_importer.get() ||
75            m_ast_importer->TargetASTContext() != ast_context)
76        {
77            m_ast_importer.reset(new ClangASTImporter(ast_context));
78            m_ast_importer->InstallMapCompleter(*this);
79        }
80
81        m_ast_context = ast_context;
82    }
83
84    //
85    // APIs for ExternalASTSource
86    //
87
88    //------------------------------------------------------------------
89    /// Look up all Decls that match a particular name.  Only handles
90    /// Identifiers and DeclContexts that are either NamespaceDecls or
91    /// TranslationUnitDecls.  Calls SetExternalVisibleDeclsForName with
92    /// the result.
93    ///
94    /// The work for this function is done by
95    /// void FindExternalVisibleDecls (NameSearchContext &);
96    ///
97    /// @param[in] DC
98    ///     The DeclContext to register the found Decls in.
99    ///
100    /// @param[in] Name
101    ///     The name to find entries for.
102    ///
103    /// @return
104    ///     Whatever SetExternalVisibleDeclsForName returns.
105    //------------------------------------------------------------------
106    clang::DeclContextLookupResult
107    FindExternalVisibleDeclsByName (const clang::DeclContext *DC,
108                                    clang::DeclarationName Name);
109
110    //------------------------------------------------------------------
111    /// Enumerate all Decls in a given lexical context.
112    ///
113    /// @param[in] DC
114    ///     The DeclContext being searched.
115    ///
116    /// @param[in] isKindWeWant
117    ///     If non-NULL, a callback function that returns true given the
118    ///     DeclKinds of desired Decls, and false otherwise.
119    ///
120    /// @param[in] Decls
121    ///     A vector that is filled in with matching Decls.
122    //------------------------------------------------------------------
123    virtual clang::ExternalLoadResult
124    FindExternalLexicalDecls (const clang::DeclContext *DC,
125                              bool (*isKindWeWant)(clang::Decl::Kind),
126                              llvm::SmallVectorImpl<clang::Decl*> &Decls);
127
128    //------------------------------------------------------------------
129    /// Complete a TagDecl.
130    ///
131    /// @param[in] Tag
132    ///     The Decl to be completed in place.
133    //------------------------------------------------------------------
134    virtual void
135    CompleteType (clang::TagDecl *Tag);
136
137    //------------------------------------------------------------------
138    /// Complete an ObjCInterfaceDecl.
139    ///
140    /// @param[in] Class
141    ///     The Decl to be completed in place.
142    //------------------------------------------------------------------
143    virtual void
144    CompleteType (clang::ObjCInterfaceDecl *Class);
145
146    //------------------------------------------------------------------
147    /// Called on entering a translation unit.  Tells Clang by calling
148    /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage()
149    /// that this object has something to say about undefined names.
150    ///
151    /// @param[in] ASTConsumer
152    ///     Unused.
153    //------------------------------------------------------------------
154    void StartTranslationUnit (clang::ASTConsumer *Consumer);
155
156    //
157    // APIs for NamespaceMapCompleter
158    //
159
160
161    //------------------------------------------------------------------
162    /// Look up the modules containing a given namespace and put the
163    /// appropriate entries in the namespace map.
164    ///
165    /// @param[in] namespace_map
166    ///     The map to be completed.
167    ///
168    /// @param[in] name
169    ///     The name of the namespace to be found.
170    ///
171    /// @param[in] parent_map
172    ///     The map for the namespace's parent namespace, if there is
173    ///     one.
174    //------------------------------------------------------------------
175    void CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map,
176                               const ConstString &name,
177                               ClangASTImporter::NamespaceMapSP &parent_map) const;
178
179    //
180    // Helper APIs
181    //
182
183    //------------------------------------------------------------------
184    /// The worker function for FindExternalVisibleDeclsByName.
185    ///
186    /// @param[in] context
187    ///     The NameSearchContext to use when filing results.
188    //------------------------------------------------------------------
189    virtual void FindExternalVisibleDecls (NameSearchContext &context);
190
191    void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; }
192    bool GetImportInProgress () { return m_import_in_progress; }
193
194    void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; }
195    bool GetLookupsEnabled () { return m_lookups_enabled; }
196
197    //----------------------------------------------------------------------
198    /// @class ClangASTSourceProxy ClangASTSource.h "lldb/Expression/ClangASTSource.h"
199    /// @brief Proxy for ClangASTSource
200    ///
201    /// Clang AST contexts like to own their AST sources, so this is a
202    /// state-free proxy object.
203    //----------------------------------------------------------------------
204    class ClangASTSourceProxy : public clang::ExternalASTSource
205    {
206    public:
207        ClangASTSourceProxy (ClangASTSource &original) :
208            m_original(original)
209        {
210        }
211
212        clang::DeclContextLookupResult
213        FindExternalVisibleDeclsByName (const clang::DeclContext *DC,
214                                        clang::DeclarationName Name)
215        {
216            return m_original.FindExternalVisibleDeclsByName(DC, Name);
217        }
218
219        virtual clang::ExternalLoadResult
220        FindExternalLexicalDecls (const clang::DeclContext *DC,
221                                  bool (*isKindWeWant)(clang::Decl::Kind),
222                                  llvm::SmallVectorImpl<clang::Decl*> &Decls)
223        {
224            return m_original.FindExternalLexicalDecls(DC, isKindWeWant, Decls);
225        }
226
227        virtual void
228        CompleteType (clang::TagDecl *Tag)
229        {
230            return m_original.CompleteType(Tag);
231        }
232
233        virtual void
234        CompleteType (clang::ObjCInterfaceDecl *Class)
235        {
236            return m_original.CompleteType(Class);
237        }
238
239        void StartTranslationUnit (clang::ASTConsumer *Consumer)
240        {
241            return m_original.StartTranslationUnit(Consumer);
242        }
243    private:
244        ClangASTSource &m_original;
245    };
246
247    clang::ExternalASTSource *CreateProxy()
248    {
249        return new ClangASTSourceProxy(*this);
250    }
251
252protected:
253    friend struct NameSearchContext;
254
255    bool                    m_import_in_progress;
256    bool                    m_lookups_enabled;
257
258    const lldb::TargetSP                m_target;           ///< The target to use in finding variables and types.
259	clang::ASTContext                  *m_ast_context;      ///< The parser's AST context, for copying types into
260    std::auto_ptr<ClangASTImporter>     m_ast_importer;
261    std::set<const char *>              m_active_lookups;
262};
263
264//----------------------------------------------------------------------
265/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h"
266/// @brief Container for all objects relevant to a single name lookup
267///
268/// LLDB needs to create Decls for entities it finds.  This class communicates
269/// what name is being searched for and provides helper functions to construct
270/// Decls given appropriate type information.
271//----------------------------------------------------------------------
272struct NameSearchContext {
273    ClangASTSource &m_ast_source;                       ///< The AST source making the request
274    llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls;  ///< The list of declarations already constructed
275    ClangASTImporter::NamespaceMapSP m_namespace_map;   ///< The mapping of all namespaces found for this request back to their modules
276    const clang::DeclarationName &m_decl_name;          ///< The name being looked for
277    const clang::DeclContext *m_decl_context;           ///< The DeclContext to put declarations into
278
279    struct {
280        bool variable                   : 1;
281        bool function_with_type_info    : 1;
282        bool function                   : 1;
283    } m_found;
284
285    //------------------------------------------------------------------
286    /// Constructor
287    ///
288    /// Initializes class variables.
289    ///
290    /// @param[in] astSource
291    ///     A reference to the AST source making a request.
292    ///
293    /// @param[in] decls
294    ///     A reference to a list into which new Decls will be placed.  This
295    ///     list is typically empty when the function is called.
296    ///
297    /// @param[in] name
298    ///     The name being searched for (always an Identifier).
299    ///
300    /// @param[in] dc
301    ///     The DeclContext to register Decls in.
302    //------------------------------------------------------------------
303    NameSearchContext (ClangASTSource &astSource,
304                       llvm::SmallVectorImpl<clang::NamedDecl*> &decls,
305                       clang::DeclarationName &name,
306                       const clang::DeclContext *dc) :
307        m_ast_source(astSource),
308        m_decls(decls),
309        m_decl_name(name),
310        m_decl_context(dc) {}
311
312    //------------------------------------------------------------------
313    /// Create a VarDecl with the name being searched for and the provided
314    /// type and register it in the right places.
315    ///
316    /// @param[in] type
317    ///     The opaque QualType for the VarDecl being registered.
318    //------------------------------------------------------------------
319    clang::NamedDecl *AddVarDecl(void *type);
320
321    //------------------------------------------------------------------
322    /// Create a FunDecl with the name being searched for and the provided
323    /// type and register it in the right places.
324    ///
325    /// @param[in] type
326    ///     The opaque QualType for the FunDecl being registered.
327    //------------------------------------------------------------------
328    clang::NamedDecl *AddFunDecl(void *type);
329
330    //------------------------------------------------------------------
331    /// Create a FunDecl with the name being searched for and generic
332    /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
333    /// right places.
334    //------------------------------------------------------------------
335    clang::NamedDecl *AddGenericFunDecl();
336
337    //------------------------------------------------------------------
338    /// Create a TypeDecl with the name being searched for and the provided
339    /// type and register it in the right places.
340    ///
341    /// @param[in] type
342    ///     The opaque QualType for the TypeDecl being registered.
343    //------------------------------------------------------------------
344    clang::NamedDecl *AddTypeDecl(void *type);
345
346
347    //------------------------------------------------------------------
348    /// Add Decls from the provided DeclContextLookupResult to the list
349    /// of results.
350    ///
351    /// @param[in] result
352    ///     The DeclContextLookupResult, usually returned as the result
353    ///     of querying a DeclContext.
354    //------------------------------------------------------------------
355    void AddLookupResult (clang::DeclContextLookupConstResult result);
356
357    //------------------------------------------------------------------
358    /// Add a NamedDecl to the list of results.
359    ///
360    /// @param[in] decl
361    ///     The NamedDecl, usually returned as the result
362    ///     of querying a DeclContext.
363    //------------------------------------------------------------------
364    void AddNamedDecl (clang::NamedDecl *decl);
365};
366
367}
368
369#endif
370