ClangASTImporter.h revision 40960a7953ba723190de1be397ce9679df5b7a07
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    RequireCompleteType (clang::QualType type);
133
134    bool
135    ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx)
136    {
137        DeclOrigin origin = GetDeclOrigin(decl);
138
139        if (original_decl)
140            *original_decl = origin.decl;
141
142        if (original_ctx)
143            *original_ctx = origin.ctx;
144
145        return origin.Valid();
146    }
147
148    void
149    SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl);
150
151    ClangASTMetadata *
152    GetDeclMetadata (const clang::Decl *decl);
153
154    //
155    // Namespace maps
156    //
157
158    typedef std::vector < std::pair<lldb::ModuleSP, ClangNamespaceDecl> > NamespaceMap;
159    typedef STD_SHARED_PTR(NamespaceMap) NamespaceMapSP;
160
161    void RegisterNamespaceMap (const clang::NamespaceDecl *decl,
162                               NamespaceMapSP &namespace_map);
163
164    NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl);
165
166    void BuildNamespaceMap (const clang::NamespaceDecl *decl);
167
168    //
169    // Comleters for maps
170    //
171
172    class MapCompleter
173    {
174    public:
175        virtual ~MapCompleter ();
176
177        virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map,
178                                           const ConstString &name,
179                                           NamespaceMapSP &parent_map) const = 0;
180    };
181
182    void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer)
183    {
184        ASTContextMetadataSP context_md;
185        ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
186
187        if (context_md_iter == m_metadata_map.end())
188        {
189            context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
190            m_metadata_map[dst_ctx] = context_md;
191        }
192        else
193        {
194            context_md = context_md_iter->second;
195        }
196
197        context_md->m_map_completer = &completer;
198    }
199
200    void ForgetDestination (clang::ASTContext *dst_ctx);
201    void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
202private:
203    struct DeclOrigin
204    {
205        DeclOrigin () :
206            ctx(NULL),
207            decl(NULL)
208        {
209        }
210
211        DeclOrigin (clang::ASTContext *_ctx,
212                    clang::Decl *_decl) :
213            ctx(_ctx),
214            decl(_decl)
215        {
216        }
217
218        DeclOrigin (const DeclOrigin &rhs)
219        {
220            ctx = rhs.ctx;
221            decl = rhs.decl;
222        }
223
224        void operator= (const DeclOrigin &rhs)
225        {
226            ctx = rhs.ctx;
227            decl = rhs.decl;
228        }
229
230        bool
231        Valid ()
232        {
233            return (ctx != NULL || decl != NULL);
234        }
235
236        clang::ASTContext  *ctx;
237        clang::Decl        *decl;
238    };
239
240    typedef std::map<const clang::Decl *, DeclOrigin>   OriginMap;
241
242    class Minion : public clang::ASTImporter
243    {
244    public:
245        Minion (ClangASTImporter &master,
246                clang::ASTContext *target_ctx,
247                clang::ASTContext *source_ctx) :
248            clang::ASTImporter(*target_ctx,
249                               master.m_file_manager,
250                               *source_ctx,
251                               master.m_file_manager,
252                               true /*minimal*/),
253            m_master(master),
254            m_source_ctx(source_ctx)
255        {
256        }
257
258        void ImportDefinitionTo (clang::Decl *to, clang::Decl *from);
259
260        clang::Decl *Imported (clang::Decl *from, clang::Decl *to);
261
262        ClangASTImporter   &m_master;
263        clang::ASTContext  *m_source_ctx;
264    };
265
266    typedef STD_SHARED_PTR(Minion) MinionSP;
267    typedef std::map<clang::ASTContext *, MinionSP> MinionMap;
268    typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap;
269
270    struct ASTContextMetadata
271    {
272        ASTContextMetadata(clang::ASTContext *dst_ctx) :
273            m_dst_ctx (dst_ctx),
274            m_minions (),
275            m_origins (),
276            m_namespace_maps (),
277            m_map_completer (NULL)
278        {
279        }
280
281        clang::ASTContext      *m_dst_ctx;
282        MinionMap               m_minions;
283        OriginMap               m_origins;
284
285        NamespaceMetaMap        m_namespace_maps;
286        MapCompleter           *m_map_completer;
287    };
288
289    typedef STD_SHARED_PTR(ASTContextMetadata) ASTContextMetadataSP;
290    typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap;
291
292    ContextMetadataMap m_metadata_map;
293
294    ASTContextMetadataSP
295    GetContextMetadata (clang::ASTContext *dst_ctx)
296    {
297        ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
298
299        if (context_md_iter == m_metadata_map.end())
300        {
301            ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
302            m_metadata_map[dst_ctx] = context_md;
303            return context_md;
304        }
305        else
306        {
307            return context_md_iter->second;
308        }
309    }
310
311    ASTContextMetadataSP
312    MaybeGetContextMetadata (clang::ASTContext *dst_ctx)
313    {
314        ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
315
316        if (context_md_iter != m_metadata_map.end())
317            return context_md_iter->second;
318        else
319            return ASTContextMetadataSP();
320    }
321
322    MinionSP
323    GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx)
324    {
325        ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
326
327        MinionMap &minions = context_md->m_minions;
328        MinionMap::iterator minion_iter = minions.find(src_ctx);
329
330        if (minion_iter == minions.end())
331        {
332            MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx));
333            minions[src_ctx] = minion;
334            return minion;
335        }
336        else
337        {
338            return minion_iter->second;
339        }
340    }
341
342    DeclOrigin
343    GetDeclOrigin (const clang::Decl *decl);
344
345    clang::FileManager      m_file_manager;
346};
347
348}
349
350#endif
351