ClangASTImporter.h revision b2027ec7cc8c15dfdc7c945dc6aed4b5d684321e
1529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz//===-- ClangASTImporter.h --------------------------------------*- C++ -*-===//
2529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz//
3529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz//                     The LLVM Compiler Infrastructure
4529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz//
5529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz// This file is distributed under the University of Illinois Open Source
6529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz// License. See LICENSE.TXT for details.
7529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz//
8529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz//===----------------------------------------------------------------------===//
9529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz
10529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz#ifndef liblldb_ClangASTImporter_h_
11529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz#define liblldb_ClangASTImporter_h_
12529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz
13529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz#include <map>
14529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz
15529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz#include "lldb/lldb-types.h"
16529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz
17529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz#include "clang/AST/ASTImporter.h"
18529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz#include "clang/Basic/FileManager.h"
19#include "clang/Basic/FileSystemOptions.h"
20#if defined(__GNUC__) && !defined(__clang__)
21// Gcc complains about ClangNamespaceDecl being an incomplete type
22// without this.
23#include "lldb/Symbol/ClangNamespaceDecl.h"
24#endif
25
26namespace lldb_private {
27
28class ClangASTImporter
29{
30public:
31    ClangASTImporter () :
32        m_file_manager(clang::FileSystemOptions())
33    {
34    }
35
36    clang::QualType
37    CopyType (clang::ASTContext *dst_ctx,
38              clang::ASTContext *src_ctx,
39              clang::QualType type);
40
41    lldb::clang_type_t
42    CopyType (clang::ASTContext *dst_ctx,
43              clang::ASTContext *src_ctx,
44              lldb::clang_type_t type);
45
46    clang::Decl *
47    CopyDecl (clang::ASTContext *dst_ctx,
48              clang::ASTContext *src_ctx,
49              clang::Decl *decl);
50
51    clang::Decl *
52    DeportDecl (clang::ASTContext *dst_ctx,
53                clang::ASTContext *src_ctx,
54                clang::Decl *decl);
55
56    bool
57    CompleteTagDecl (clang::TagDecl *decl);
58
59    bool
60    CompleteTagDeclWithOrigin (clang::TagDecl *decl, clang::TagDecl *origin);
61
62    bool
63    CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl);
64
65    bool
66    ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx)
67    {
68        DeclOrigin origin = GetDeclOrigin(decl);
69
70        if (original_decl)
71            *original_decl = origin.decl;
72
73        if (original_ctx)
74            *original_ctx = origin.ctx;
75
76        return origin.Valid();
77    }
78
79    //
80    // Namespace maps
81    //
82
83    typedef std::vector < std::pair<lldb::ModuleSP, ClangNamespaceDecl> > NamespaceMap;
84    typedef lldb::SharedPtr<NamespaceMap>::Type NamespaceMapSP;
85
86    void RegisterNamespaceMap (const clang::NamespaceDecl *decl,
87                               NamespaceMapSP &namespace_map);
88
89    NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl);
90
91    void BuildNamespaceMap (const clang::NamespaceDecl *decl);
92
93    //
94    // Objective-C interface maps
95    //
96
97    typedef std::vector <ClangASTType> ObjCInterfaceMap;
98    typedef lldb::SharedPtr<ObjCInterfaceMap>::Type ObjCInterfaceMapSP;
99
100    void BuildObjCInterfaceMap (const clang::ObjCInterfaceDecl *decl);
101
102    ObjCInterfaceMapSP GetObjCInterfaceMap (const clang::ObjCInterfaceDecl *decl);
103
104    //
105    // Completers for the namespace and Objective-C interface maps
106    //
107
108    class MapCompleter
109    {
110    public:
111        virtual ~MapCompleter ();
112
113        virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map,
114                                           const ConstString &name,
115                                           NamespaceMapSP &parent_map) const = 0;
116
117        virtual void CompleteObjCInterfaceMap (ObjCInterfaceMapSP &objc_interface_map,
118                                               const ConstString &name) const = 0;
119    };
120
121    void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer)
122    {
123        ASTContextMetadataSP context_md;
124        ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
125
126        if (context_md_iter == m_metadata_map.end())
127        {
128            context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
129            m_metadata_map[dst_ctx] = context_md;
130        }
131        else
132        {
133            context_md = context_md_iter->second;
134        }
135
136        context_md->m_map_completer = &completer;
137    }
138
139    void ForgetDestination (clang::ASTContext *dst_ctx);
140    void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
141private:
142    struct DeclOrigin
143    {
144        DeclOrigin () :
145            ctx(NULL),
146            decl(NULL)
147        {
148        }
149
150        DeclOrigin (clang::ASTContext *_ctx,
151                    clang::Decl *_decl) :
152            ctx(_ctx),
153            decl(_decl)
154        {
155        }
156
157        DeclOrigin (const DeclOrigin &rhs)
158        {
159            ctx = rhs.ctx;
160            decl = rhs.decl;
161        }
162
163        void operator= (const DeclOrigin &rhs)
164        {
165            ctx = rhs.ctx;
166            decl = rhs.decl;
167        }
168
169        bool
170        Valid ()
171        {
172            return (ctx != NULL || decl != NULL);
173        }
174
175        clang::ASTContext  *ctx;
176        clang::Decl        *decl;
177    };
178
179    typedef std::map<const clang::Decl *, DeclOrigin>   OriginMap;
180
181    class Minion : public clang::ASTImporter
182    {
183    public:
184        Minion (ClangASTImporter &master,
185                clang::ASTContext *target_ctx,
186                clang::ASTContext *source_ctx) :
187            clang::ASTImporter(*target_ctx,
188                               master.m_file_manager,
189                               *source_ctx,
190                               master.m_file_manager,
191                               true /*minimal*/),
192            m_master(master),
193            m_source_ctx(source_ctx)
194        {
195        }
196
197        clang::Decl *Imported (clang::Decl *from, clang::Decl *to);
198
199        ClangASTImporter   &m_master;
200        clang::ASTContext  *m_source_ctx;
201    };
202
203    typedef lldb::SharedPtr<Minion>::Type                                   MinionSP;
204    typedef std::map<clang::ASTContext *, MinionSP>                         MinionMap;
205    typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP>          NamespaceMetaMap;
206    typedef std::map<const clang::ObjCInterfaceDecl *, ObjCInterfaceMapSP>  ObjCInterfaceMetaMap;
207
208    struct ASTContextMetadata
209    {
210        ASTContextMetadata(clang::ASTContext *dst_ctx) :
211            m_dst_ctx (dst_ctx),
212            m_minions (),
213            m_origins (),
214            m_namespace_maps (),
215            m_objc_interface_maps (),
216            m_map_completer (NULL)
217        {
218        }
219
220        clang::ASTContext      *m_dst_ctx;
221        MinionMap               m_minions;
222        OriginMap               m_origins;
223
224        NamespaceMetaMap        m_namespace_maps;
225        MapCompleter           *m_map_completer;
226
227        ObjCInterfaceMetaMap    m_objc_interface_maps;
228    };
229
230    typedef lldb::SharedPtr<ASTContextMetadata>::Type               ASTContextMetadataSP;
231
232    typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap;
233
234    ContextMetadataMap      m_metadata_map;
235
236    ASTContextMetadataSP
237    GetContextMetadata (clang::ASTContext *dst_ctx)
238    {
239        ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
240
241        if (context_md_iter == m_metadata_map.end())
242        {
243            ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
244            m_metadata_map[dst_ctx] = context_md;
245            return context_md;
246        }
247        else
248        {
249            return context_md_iter->second;
250        }
251    }
252
253    ASTContextMetadataSP
254    MaybeGetContextMetadata (clang::ASTContext *dst_ctx)
255    {
256        ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
257
258        if (context_md_iter != m_metadata_map.end())
259            return context_md_iter->second;
260        else
261            return ASTContextMetadataSP();
262    }
263
264    MinionSP
265    GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx)
266    {
267        ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
268
269        MinionMap &minions = context_md->m_minions;
270        MinionMap::iterator minion_iter = minions.find(src_ctx);
271
272        if (minion_iter == minions.end())
273        {
274            MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx));
275            minions[src_ctx] = minion;
276            return minion;
277        }
278        else
279        {
280            return minion_iter->second;
281        }
282    }
283
284    DeclOrigin
285    GetDeclOrigin (const clang::Decl *decl);
286
287    clang::FileManager      m_file_manager;
288};
289
290}
291
292#endif
293