]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/llvm/tools/lldb/include/lldb/Symbol/ClangASTImporter.h
Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.
[FreeBSD/stable/10.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         std::set<clang::NamedDecl *>   *m_decls_to_deport;
282         std::set<clang::NamedDecl *>   *m_decls_already_deported;
283         ClangASTImporter               &m_master;
284         clang::ASTContext              *m_source_ctx;
285     };
286     
287     typedef std::shared_ptr<Minion> MinionSP;
288     typedef std::map<clang::ASTContext *, MinionSP> MinionMap;
289     typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap;
290     
291     struct ASTContextMetadata
292     {
293         ASTContextMetadata(clang::ASTContext *dst_ctx) :
294             m_dst_ctx (dst_ctx),
295             m_minions (),
296             m_origins (),
297             m_namespace_maps (),
298             m_map_completer (NULL)
299         {
300         }
301         
302         clang::ASTContext      *m_dst_ctx;
303         MinionMap               m_minions;
304         OriginMap               m_origins;
305         
306         NamespaceMetaMap        m_namespace_maps;
307         MapCompleter           *m_map_completer;
308     };
309     
310     typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP;    
311     typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap;
312     
313     ContextMetadataMap m_metadata_map;
314     
315     ASTContextMetadataSP
316     GetContextMetadata (clang::ASTContext *dst_ctx)
317     {
318         ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
319         
320         if (context_md_iter == m_metadata_map.end())
321         {
322             ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
323             m_metadata_map[dst_ctx] = context_md;
324             return context_md;
325         }
326         else
327         {
328             return context_md_iter->second;
329         }
330     }
331     
332     ASTContextMetadataSP
333     MaybeGetContextMetadata (clang::ASTContext *dst_ctx)
334     {
335         ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
336
337         if (context_md_iter != m_metadata_map.end())
338             return context_md_iter->second;
339         else
340             return ASTContextMetadataSP();
341     }
342     
343     MinionSP
344     GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx)
345     {
346         ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
347         
348         MinionMap &minions = context_md->m_minions;
349         MinionMap::iterator minion_iter = minions.find(src_ctx);
350         
351         if (minion_iter == minions.end())
352         {
353             MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx));
354             minions[src_ctx] = minion;
355             return minion;
356         }
357         else
358         {
359             return minion_iter->second;
360         }       
361     }
362     
363     DeclOrigin
364     GetDeclOrigin (const clang::Decl *decl);
365         
366     clang::FileManager      m_file_manager;
367 };
368     
369 }
370
371 #endif