]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/include/lldb/Symbol/ClangASTImporter.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / include / lldb / Symbol / ClangASTImporter.h
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 #include <set>
15
16 #include "lldb/lldb-types.h"
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
22 namespace lldb_private {
23     
24 class ClangASTMetrics
25 {
26 public:
27     static void DumpCounters (Log *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     
69 private:
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 (Log *log, Counters &counters);
84 };
85
86 class ClangASTImporter 
87 {
88 public:
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);
202 private:
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_decls_to_deport(NULL),
254             m_decls_already_deported(NULL),
255             m_master(master),
256             m_source_ctx(source_ctx)
257         {
258         }
259         
260         // A call to "InitDeportWorkQueues" puts the minion into deport mode.
261         // In deport mode, every copied Decl that could require completion is
262         // recorded and placed into the decls_to_deport set.
263         //
264         // A call to "ExecuteDeportWorkQueues" completes all the Decls that
265         // are in decls_to_deport, adding any Decls it sees along the way that
266         // it hasn't already deported.  It proceeds until decls_to_deport is
267         // empty.
268         //
269         // These calls must be paired.  Leaving a minion in deport mode or
270         // trying to start deport minion with a new pair of queues will result
271         // in an assertion failure.
272         
273         void InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport,
274                                    std::set<clang::NamedDecl *> *decls_already_deported);
275         void ExecuteDeportWorkQueues ();
276         
277         void ImportDefinitionTo (clang::Decl *to, clang::Decl *from);
278         
279         clang::Decl *Imported (clang::Decl *from, clang::Decl *to);
280         
281         clang::Decl *GetOriginalDecl (clang::Decl *To);
282         
283         std::set<clang::NamedDecl *>   *m_decls_to_deport;
284         std::set<clang::NamedDecl *>   *m_decls_already_deported;
285         ClangASTImporter               &m_master;
286         clang::ASTContext              *m_source_ctx;
287     };
288     
289     typedef std::shared_ptr<Minion> MinionSP;
290     typedef std::map<clang::ASTContext *, MinionSP> MinionMap;
291     typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap;
292     
293     struct ASTContextMetadata
294     {
295         ASTContextMetadata(clang::ASTContext *dst_ctx) :
296             m_dst_ctx (dst_ctx),
297             m_minions (),
298             m_origins (),
299             m_namespace_maps (),
300             m_map_completer (NULL)
301         {
302         }
303         
304         clang::ASTContext      *m_dst_ctx;
305         MinionMap               m_minions;
306         OriginMap               m_origins;
307         
308         NamespaceMetaMap        m_namespace_maps;
309         MapCompleter           *m_map_completer;
310     };
311     
312     typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP;    
313     typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap;
314     
315     ContextMetadataMap m_metadata_map;
316     
317     ASTContextMetadataSP
318     GetContextMetadata (clang::ASTContext *dst_ctx)
319     {
320         ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
321         
322         if (context_md_iter == m_metadata_map.end())
323         {
324             ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
325             m_metadata_map[dst_ctx] = context_md;
326             return context_md;
327         }
328         else
329         {
330             return context_md_iter->second;
331         }
332     }
333     
334     ASTContextMetadataSP
335     MaybeGetContextMetadata (clang::ASTContext *dst_ctx)
336     {
337         ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
338
339         if (context_md_iter != m_metadata_map.end())
340             return context_md_iter->second;
341         else
342             return ASTContextMetadataSP();
343     }
344     
345     MinionSP
346     GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx)
347     {
348         ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
349         
350         MinionMap &minions = context_md->m_minions;
351         MinionMap::iterator minion_iter = minions.find(src_ctx);
352         
353         if (minion_iter == minions.end())
354         {
355             MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx));
356             minions[src_ctx] = minion;
357             return minion;
358         }
359         else
360         {
361             return minion_iter->second;
362         }       
363     }
364     
365     DeclOrigin
366     GetDeclOrigin (const clang::Decl *decl);
367         
368     clang::FileManager      m_file_manager;
369 };
370     
371 }
372
373 #endif