ClangASTImporter.h revision 6741173bf58eaeab4964226ba5a42b2a9bbc21b1
1//===-- ClangASTImporter.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_ClangASTImporter_h_
11#define liblldb_ClangASTImporter_h_
12
13#include <map>
14
15#include "lldb/lldb-types.h"
16
17#include "clang/AST/ASTImporter.h"
18#include "clang/Basic/FileManager.h"
19#include "clang/Basic/FileSystemOptions.h"
20#include "lldb/Symbol/ClangNamespaceDecl.h"
21
22namespace lldb_private {
23
24class ClangASTMetrics
25{
26public:
27    static void DumpCounters (lldb::LogSP log);
28    static void ClearLocalCounters ()
29    {
30        local_counters = { 0, 0, 0, 0, 0, 0 };
31    }
32
33    static void RegisterVisibleQuery ()
34    {
35        ++global_counters.m_visible_query_count;
36        ++local_counters.m_visible_query_count;
37    }
38
39    static void RegisterLexicalQuery ()
40    {
41        ++global_counters.m_lexical_query_count;
42        ++local_counters.m_lexical_query_count;
43    }
44
45    static void RegisterLLDBImport ()
46    {
47        ++global_counters.m_lldb_import_count;
48        ++local_counters.m_lldb_import_count;
49    }
50
51    static void RegisterClangImport ()
52    {
53        ++global_counters.m_clang_import_count;
54        ++local_counters.m_clang_import_count;
55    }
56
57    static void RegisterDeclCompletion ()
58    {
59        ++global_counters.m_decls_completed_count;
60        ++local_counters.m_decls_completed_count;
61    }
62
63    static void RegisterRecordLayout ()
64    {
65        ++global_counters.m_record_layout_count;
66        ++local_counters.m_record_layout_count;
67    }
68
69private:
70    struct Counters
71    {
72        uint64_t    m_visible_query_count;
73        uint64_t    m_lexical_query_count;
74        uint64_t    m_lldb_import_count;
75        uint64_t    m_clang_import_count;
76        uint64_t    m_decls_completed_count;
77        uint64_t    m_record_layout_count;
78    };
79
80    static Counters global_counters;
81    static Counters local_counters;
82
83    static void DumpCounters (lldb::LogSP log, Counters &counters);
84};
85
86class ClangASTImporter
87{
88public:
89    ClangASTImporter () :
90        m_file_manager(clang::FileSystemOptions())
91    {
92    }
93
94    clang::QualType
95    CopyType (clang::ASTContext *dst_ctx,
96              clang::ASTContext *src_ctx,
97              clang::QualType type);
98
99    lldb::clang_type_t
100    CopyType (clang::ASTContext *dst_ctx,
101              clang::ASTContext *src_ctx,
102              lldb::clang_type_t type);
103
104    clang::Decl *
105    CopyDecl (clang::ASTContext *dst_ctx,
106              clang::ASTContext *src_ctx,
107              clang::Decl *decl);
108
109    lldb::clang_type_t
110    DeportType (clang::ASTContext *dst_ctx,
111                clang::ASTContext *src_ctx,
112                lldb::clang_type_t type);
113
114    clang::Decl *
115    DeportDecl (clang::ASTContext *dst_ctx,
116                clang::ASTContext *src_ctx,
117                clang::Decl *decl);
118
119    void
120    CompleteDecl (clang::Decl *decl);
121
122    bool
123    CompleteTagDecl (clang::TagDecl *decl);
124
125    bool
126    CompleteTagDeclWithOrigin (clang::TagDecl *decl, clang::TagDecl *origin);
127
128    bool
129    CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl);
130
131    bool
132    ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx)
133    {
134        DeclOrigin origin = GetDeclOrigin(decl);
135
136        if (original_decl)
137            *original_decl = origin.decl;
138
139        if (original_ctx)
140            *original_ctx = origin.ctx;
141
142        return origin.Valid();
143    }
144
145    void
146    SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl);
147
148    ClangASTMetadata *
149    GetDeclMetadata (const clang::Decl *decl);
150
151    //
152    // Namespace maps
153    //
154
155    typedef std::vector < std::pair<lldb::ModuleSP, ClangNamespaceDecl> > NamespaceMap;
156    typedef STD_SHARED_PTR(NamespaceMap) NamespaceMapSP;
157
158    void RegisterNamespaceMap (const clang::NamespaceDecl *decl,
159                               NamespaceMapSP &namespace_map);
160
161    NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl);
162
163    void BuildNamespaceMap (const clang::NamespaceDecl *decl);
164
165    //
166    // Comleters for maps
167    //
168
169    class MapCompleter
170    {
171    public:
172        virtual ~MapCompleter ();
173
174        virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map,
175                                           const ConstString &name,
176                                           NamespaceMapSP &parent_map) const = 0;
177    };
178
179    void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer)
180    {
181        ASTContextMetadataSP context_md;
182        ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
183
184        if (context_md_iter == m_metadata_map.end())
185        {
186            context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
187            m_metadata_map[dst_ctx] = context_md;
188        }
189        else
190        {
191            context_md = context_md_iter->second;
192        }
193
194        context_md->m_map_completer = &completer;
195    }
196
197    void ForgetDestination (clang::ASTContext *dst_ctx);
198    void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
199private:
200    struct DeclOrigin
201    {
202        DeclOrigin () :
203            ctx(NULL),
204            decl(NULL)
205        {
206        }
207
208        DeclOrigin (clang::ASTContext *_ctx,
209                    clang::Decl *_decl) :
210            ctx(_ctx),
211            decl(_decl)
212        {
213        }
214
215        DeclOrigin (const DeclOrigin &rhs)
216        {
217            ctx = rhs.ctx;
218            decl = rhs.decl;
219        }
220
221        void operator= (const DeclOrigin &rhs)
222        {
223            ctx = rhs.ctx;
224            decl = rhs.decl;
225        }
226
227        bool
228        Valid ()
229        {
230            return (ctx != NULL || decl != NULL);
231        }
232
233        clang::ASTContext  *ctx;
234        clang::Decl        *decl;
235    };
236
237    typedef std::map<const clang::Decl *, DeclOrigin>   OriginMap;
238
239    class Minion : public clang::ASTImporter
240    {
241    public:
242        Minion (ClangASTImporter &master,
243                clang::ASTContext *target_ctx,
244                clang::ASTContext *source_ctx) :
245            clang::ASTImporter(*target_ctx,
246                               master.m_file_manager,
247                               *source_ctx,
248                               master.m_file_manager,
249                               true /*minimal*/),
250            m_master(master),
251            m_source_ctx(source_ctx)
252        {
253        }
254
255        void ImportDefinitionTo (clang::Decl *to, clang::Decl *from);
256
257        clang::Decl *Imported (clang::Decl *from, clang::Decl *to);
258
259        ClangASTImporter   &m_master;
260        clang::ASTContext  *m_source_ctx;
261    };
262
263    typedef STD_SHARED_PTR(Minion) MinionSP;
264    typedef std::map<clang::ASTContext *, MinionSP> MinionMap;
265    typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap;
266
267    struct ASTContextMetadata
268    {
269        ASTContextMetadata(clang::ASTContext *dst_ctx) :
270            m_dst_ctx (dst_ctx),
271            m_minions (),
272            m_origins (),
273            m_namespace_maps (),
274            m_map_completer (NULL)
275        {
276        }
277
278        clang::ASTContext      *m_dst_ctx;
279        MinionMap               m_minions;
280        OriginMap               m_origins;
281
282        NamespaceMetaMap        m_namespace_maps;
283        MapCompleter           *m_map_completer;
284    };
285
286    typedef STD_SHARED_PTR(ASTContextMetadata) ASTContextMetadataSP;
287    typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap;
288
289    ContextMetadataMap m_metadata_map;
290
291    ASTContextMetadataSP
292    GetContextMetadata (clang::ASTContext *dst_ctx)
293    {
294        ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
295
296        if (context_md_iter == m_metadata_map.end())
297        {
298            ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
299            m_metadata_map[dst_ctx] = context_md;
300            return context_md;
301        }
302        else
303        {
304            return context_md_iter->second;
305        }
306    }
307
308    ASTContextMetadataSP
309    MaybeGetContextMetadata (clang::ASTContext *dst_ctx)
310    {
311        ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
312
313        if (context_md_iter != m_metadata_map.end())
314            return context_md_iter->second;
315        else
316            return ASTContextMetadataSP();
317    }
318
319    MinionSP
320    GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx)
321    {
322        ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
323
324        MinionMap &minions = context_md->m_minions;
325        MinionMap::iterator minion_iter = minions.find(src_ctx);
326
327        if (minion_iter == minions.end())
328        {
329            MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx));
330            minions[src_ctx] = minion;
331            return minion;
332        }
333        else
334        {
335            return minion_iter->second;
336        }
337    }
338
339    DeclOrigin
340    GetDeclOrigin (const clang::Decl *decl);
341
342    clang::FileManager      m_file_manager;
343};
344
345}
346
347#endif
348