1 //===-- ClangASTImporter.h --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_ClangASTImporter_h_
11 #define liblldb_ClangASTImporter_h_
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"
22 namespace lldb_private {
27 static void DumpCounters (Log *log);
28 static void ClearLocalCounters ()
30 local_counters = { 0, 0, 0, 0, 0, 0 };
33 static void RegisterVisibleQuery ()
35 ++global_counters.m_visible_query_count;
36 ++local_counters.m_visible_query_count;
39 static void RegisterLexicalQuery ()
41 ++global_counters.m_lexical_query_count;
42 ++local_counters.m_lexical_query_count;
45 static void RegisterLLDBImport ()
47 ++global_counters.m_lldb_import_count;
48 ++local_counters.m_lldb_import_count;
51 static void RegisterClangImport ()
53 ++global_counters.m_clang_import_count;
54 ++local_counters.m_clang_import_count;
57 static void RegisterDeclCompletion ()
59 ++global_counters.m_decls_completed_count;
60 ++local_counters.m_decls_completed_count;
63 static void RegisterRecordLayout ()
65 ++global_counters.m_record_layout_count;
66 ++local_counters.m_record_layout_count;
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;
80 static Counters global_counters;
81 static Counters local_counters;
83 static void DumpCounters (Log *log, Counters &counters);
86 class ClangASTImporter
90 m_file_manager(clang::FileSystemOptions())
95 CopyType (clang::ASTContext *dst_ctx,
96 clang::ASTContext *src_ctx,
97 clang::QualType type);
100 CopyType (clang::ASTContext *dst_ctx,
101 clang::ASTContext *src_ctx,
102 lldb::clang_type_t type);
105 CopyDecl (clang::ASTContext *dst_ctx,
106 clang::ASTContext *src_ctx,
110 DeportType (clang::ASTContext *dst_ctx,
111 clang::ASTContext *src_ctx,
112 lldb::clang_type_t type);
115 DeportDecl (clang::ASTContext *dst_ctx,
116 clang::ASTContext *src_ctx,
120 CompleteDecl (clang::Decl *decl);
123 CompleteTagDecl (clang::TagDecl *decl);
126 CompleteTagDeclWithOrigin (clang::TagDecl *decl, clang::TagDecl *origin);
129 CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl);
132 RequireCompleteType (clang::QualType type);
135 ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx)
137 DeclOrigin origin = GetDeclOrigin(decl);
140 *original_decl = origin.decl;
143 *original_ctx = origin.ctx;
145 return origin.Valid();
149 SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl);
152 GetDeclMetadata (const clang::Decl *decl);
158 typedef std::vector < std::pair<lldb::ModuleSP, ClangNamespaceDecl> > NamespaceMap;
159 typedef std::shared_ptr<NamespaceMap> NamespaceMapSP;
161 void RegisterNamespaceMap (const clang::NamespaceDecl *decl,
162 NamespaceMapSP &namespace_map);
164 NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl);
166 void BuildNamespaceMap (const clang::NamespaceDecl *decl);
169 // Comleters for maps
175 virtual ~MapCompleter ();
177 virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map,
178 const ConstString &name,
179 NamespaceMapSP &parent_map) const = 0;
182 void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer)
184 ASTContextMetadataSP context_md;
185 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
187 if (context_md_iter == m_metadata_map.end())
189 context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
190 m_metadata_map[dst_ctx] = context_md;
194 context_md = context_md_iter->second;
197 context_md->m_map_completer = &completer;
200 void ForgetDestination (clang::ASTContext *dst_ctx);
201 void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
211 DeclOrigin (clang::ASTContext *_ctx,
212 clang::Decl *_decl) :
218 DeclOrigin (const DeclOrigin &rhs)
224 void operator= (const DeclOrigin &rhs)
233 return (ctx != NULL || decl != NULL);
236 clang::ASTContext *ctx;
240 typedef std::map<const clang::Decl *, DeclOrigin> OriginMap;
242 class Minion : public clang::ASTImporter
245 Minion (ClangASTImporter &master,
246 clang::ASTContext *target_ctx,
247 clang::ASTContext *source_ctx) :
248 clang::ASTImporter(*target_ctx,
249 master.m_file_manager,
251 master.m_file_manager,
253 m_decls_to_deport(NULL),
254 m_decls_already_deported(NULL),
256 m_source_ctx(source_ctx)
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.
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
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.
273 void InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport,
274 std::set<clang::NamedDecl *> *decls_already_deported);
275 void ExecuteDeportWorkQueues ();
277 void ImportDefinitionTo (clang::Decl *to, clang::Decl *from);
279 clang::Decl *Imported (clang::Decl *from, clang::Decl *to);
281 clang::Decl *GetOriginalDecl (clang::Decl *To);
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;
289 typedef std::shared_ptr<Minion> MinionSP;
290 typedef std::map<clang::ASTContext *, MinionSP> MinionMap;
291 typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap;
293 struct ASTContextMetadata
295 ASTContextMetadata(clang::ASTContext *dst_ctx) :
300 m_map_completer (NULL)
304 clang::ASTContext *m_dst_ctx;
308 NamespaceMetaMap m_namespace_maps;
309 MapCompleter *m_map_completer;
312 typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP;
313 typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap;
315 ContextMetadataMap m_metadata_map;
318 GetContextMetadata (clang::ASTContext *dst_ctx)
320 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
322 if (context_md_iter == m_metadata_map.end())
324 ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
325 m_metadata_map[dst_ctx] = context_md;
330 return context_md_iter->second;
335 MaybeGetContextMetadata (clang::ASTContext *dst_ctx)
337 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
339 if (context_md_iter != m_metadata_map.end())
340 return context_md_iter->second;
342 return ASTContextMetadataSP();
346 GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx)
348 ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
350 MinionMap &minions = context_md->m_minions;
351 MinionMap::iterator minion_iter = minions.find(src_ctx);
353 if (minion_iter == minions.end())
355 MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx));
356 minions[src_ctx] = minion;
361 return minion_iter->second;
366 GetDeclOrigin (const clang::Decl *decl);
368 clang::FileManager m_file_manager;