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