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