ClangASTImporter.h revision 8f2e392e8937aaf66f91201dc5f4190d61902c67
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#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    lldb::clang_type_t
52    DeportType (clang::ASTContext *dst_ctx,
53                clang::ASTContext *src_ctx,
54                lldb::clang_type_t type);
55
56    clang::Decl *
57    DeportDecl (clang::ASTContext *dst_ctx,
58                clang::ASTContext *src_ctx,
59                clang::Decl *decl);
60
61    void
62    CompleteDecl (clang::Decl *decl);
63
64    bool
65    CompleteTagDecl (clang::TagDecl *decl);
66
67    bool
68    CompleteTagDeclWithOrigin (clang::TagDecl *decl, clang::TagDecl *origin);
69
70    bool
71    CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl);
72
73    bool
74    ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx)
75    {
76        DeclOrigin origin = GetDeclOrigin(decl);
77
78        if (original_decl)
79            *original_decl = origin.decl;
80
81        if (original_ctx)
82            *original_ctx = origin.ctx;
83
84        return origin.Valid();
85    }
86
87    //
88    // Namespace maps
89    //
90
91    typedef std::vector < std::pair<lldb::ModuleSP, ClangNamespaceDecl> > NamespaceMap;
92    typedef SHARED_PTR(NamespaceMap) NamespaceMapSP;
93
94    void RegisterNamespaceMap (const clang::NamespaceDecl *decl,
95                               NamespaceMapSP &namespace_map);
96
97    NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl);
98
99    void BuildNamespaceMap (const clang::NamespaceDecl *decl);
100
101    //
102    // Comleters for maps
103    //
104
105    class MapCompleter
106    {
107    public:
108        virtual ~MapCompleter ();
109
110        virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map,
111                                           const ConstString &name,
112                                           NamespaceMapSP &parent_map) const = 0;
113    };
114
115    void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer)
116    {
117        ASTContextMetadataSP context_md;
118        ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
119
120        if (context_md_iter == m_metadata_map.end())
121        {
122            context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
123            m_metadata_map[dst_ctx] = context_md;
124        }
125        else
126        {
127            context_md = context_md_iter->second;
128        }
129
130        context_md->m_map_completer = &completer;
131    }
132
133    void ForgetDestination (clang::ASTContext *dst_ctx);
134    void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
135private:
136    struct DeclOrigin
137    {
138        DeclOrigin () :
139            ctx(NULL),
140            decl(NULL)
141        {
142        }
143
144        DeclOrigin (clang::ASTContext *_ctx,
145                    clang::Decl *_decl) :
146            ctx(_ctx),
147            decl(_decl)
148        {
149        }
150
151        DeclOrigin (const DeclOrigin &rhs)
152        {
153            ctx = rhs.ctx;
154            decl = rhs.decl;
155        }
156
157        void operator= (const DeclOrigin &rhs)
158        {
159            ctx = rhs.ctx;
160            decl = rhs.decl;
161        }
162
163        bool
164        Valid ()
165        {
166            return (ctx != NULL || decl != NULL);
167        }
168
169        clang::ASTContext  *ctx;
170        clang::Decl        *decl;
171    };
172
173    typedef std::map<const clang::Decl *, DeclOrigin>   OriginMap;
174
175    class Minion : public clang::ASTImporter
176    {
177    public:
178        Minion (ClangASTImporter &master,
179                clang::ASTContext *target_ctx,
180                clang::ASTContext *source_ctx) :
181            clang::ASTImporter(*target_ctx,
182                               master.m_file_manager,
183                               *source_ctx,
184                               master.m_file_manager,
185                               true /*minimal*/),
186            m_master(master),
187            m_source_ctx(source_ctx)
188        {
189        }
190
191        void ImportDefinitionTo (clang::Decl *to, clang::Decl *from);
192
193        clang::Decl *Imported (clang::Decl *from, clang::Decl *to);
194
195        ClangASTImporter   &m_master;
196        clang::ASTContext  *m_source_ctx;
197    };
198
199    typedef SHARED_PTR(Minion) MinionSP;
200    typedef std::map<clang::ASTContext *, MinionSP> MinionMap;
201    typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap;
202
203    struct ASTContextMetadata
204    {
205        ASTContextMetadata(clang::ASTContext *dst_ctx) :
206            m_dst_ctx (dst_ctx),
207            m_minions (),
208            m_origins (),
209            m_namespace_maps (),
210            m_map_completer (NULL)
211        {
212        }
213
214        clang::ASTContext      *m_dst_ctx;
215        MinionMap               m_minions;
216        OriginMap               m_origins;
217
218        NamespaceMetaMap        m_namespace_maps;
219        MapCompleter           *m_map_completer;
220    };
221
222    typedef SHARED_PTR(ASTContextMetadata) ASTContextMetadataSP;
223    typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap;
224
225    ContextMetadataMap m_metadata_map;
226
227    ASTContextMetadataSP
228    GetContextMetadata (clang::ASTContext *dst_ctx)
229    {
230        ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
231
232        if (context_md_iter == m_metadata_map.end())
233        {
234            ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
235            m_metadata_map[dst_ctx] = context_md;
236            return context_md;
237        }
238        else
239        {
240            return context_md_iter->second;
241        }
242    }
243
244    ASTContextMetadataSP
245    MaybeGetContextMetadata (clang::ASTContext *dst_ctx)
246    {
247        ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
248
249        if (context_md_iter != m_metadata_map.end())
250            return context_md_iter->second;
251        else
252            return ASTContextMetadataSP();
253    }
254
255    MinionSP
256    GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx)
257    {
258        ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
259
260        MinionMap &minions = context_md->m_minions;
261        MinionMap::iterator minion_iter = minions.find(src_ctx);
262
263        if (minion_iter == minions.end())
264        {
265            MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx));
266            minions[src_ctx] = minion;
267            return minion;
268        }
269        else
270        {
271            return minion_iter->second;
272        }
273    }
274
275    DeclOrigin
276    GetDeclOrigin (const clang::Decl *decl);
277
278    clang::FileManager      m_file_manager;
279};
280
281}
282
283#endif
284