ClangASTImporter.h revision 314564
150276Speter//===-- ClangASTImporter.h --------------------------------------*- C++ -*-===// 2184989Srafan// 350276Speter// The LLVM Compiler Infrastructure 450276Speter// 550276Speter// This file is distributed under the University of Illinois Open Source 650276Speter// License. See LICENSE.TXT for details. 750276Speter// 850276Speter//===----------------------------------------------------------------------===// 950276Speter 1050276Speter#ifndef liblldb_ClangASTImporter_h_ 1150276Speter#define liblldb_ClangASTImporter_h_ 1250276Speter 1350276Speter// C Includes 1450276Speter// C++ Includes 1550276Speter#include <map> 1650276Speter#include <memory> 1750276Speter#include <set> 1850276Speter#include <vector> 1950276Speter 2050276Speter// Other libraries and framework includes 2150276Speter#include "clang/AST/ASTImporter.h" 2250276Speter#include "clang/AST/CharUnits.h" 2350276Speter#include "clang/AST/Decl.h" 2450276Speter#include "clang/AST/DeclCXX.h" 2550276Speter#include "clang/Basic/FileManager.h" 2650276Speter#include "clang/Basic/FileSystemOptions.h" 2750276Speter 2850276Speter// Project includes 2950276Speter#include "lldb/Symbol/CompilerDeclContext.h" 3050276Speter#include "lldb/lldb-types.h" 3150276Speter 32166128Srafan#include "llvm/ADT/DenseMap.h" 3397052Speter 3497052Speternamespace lldb_private { 3597052Speter 36166128Srafanclass ClangASTMetrics { 3750276Speterpublic: 3850276Speter static void DumpCounters(Log *log); 3956643Speter static void ClearLocalCounters() { local_counters = {0, 0, 0, 0, 0, 0}; } 4056643Speter 4198507Speter static void RegisterVisibleQuery() { 4250276Speter ++global_counters.m_visible_query_count; 4350276Speter ++local_counters.m_visible_query_count; 4450276Speter } 4550276Speter 4697052Speter static void RegisterLexicalQuery() { 4750276Speter ++global_counters.m_lexical_query_count; 4850276Speter ++local_counters.m_lexical_query_count; 4950276Speter } 50184989Srafan 5150276Speter static void RegisterLLDBImport() { 5297052Speter ++global_counters.m_lldb_import_count; 5397052Speter ++local_counters.m_lldb_import_count; 5450276Speter } 5550620Speter 5650620Speter static void RegisterClangImport() { 5750620Speter ++global_counters.m_clang_import_count; 5850620Speter ++local_counters.m_clang_import_count; 59174998Srafan } 60174998Srafan 61174998Srafan static void RegisterDeclCompletion() { 6297052Speter ++global_counters.m_decls_completed_count; 63174998Srafan ++local_counters.m_decls_completed_count; 64174998Srafan } 65174998Srafan 66174998Srafan static void RegisterRecordLayout() { 67174998Srafan ++global_counters.m_record_layout_count; 6897052Speter ++local_counters.m_record_layout_count; 6950276Speter } 7050276Speter 7150276Speterprivate: 7250276Speter struct Counters { 7350276Speter uint64_t m_visible_query_count; 7450276Speter uint64_t m_lexical_query_count; 7550276Speter uint64_t m_lldb_import_count; 7650276Speter uint64_t m_clang_import_count; 7750276Speter uint64_t m_decls_completed_count; 7850276Speter uint64_t m_record_layout_count; 7950276Speter }; 8050276Speter 8150276Speter static Counters global_counters; 8250276Speter static Counters local_counters; 8350276Speter 8476730Speter static void DumpCounters(Log *log, Counters &counters); 85166128Srafan}; 8650276Speter 8762453Speterclass ClangASTImporter { 88166128Srafanpublic: 89166128Srafan struct LayoutInfo { 9050276Speter LayoutInfo() 91166128Srafan : bit_size(0), alignment(0), field_offsets(), base_offsets(), 9262453Speter vbase_offsets() {} 9350276Speter uint64_t bit_size; 94166128Srafan uint64_t alignment; 9550276Speter llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets; 96166128Srafan llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets; 97166128Srafan llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> 98166128Srafan vbase_offsets; 99166128Srafan }; 100166128Srafan 101174998Srafan ClangASTImporter() : m_file_manager(clang::FileSystemOptions()) {} 102174998Srafan 103174998Srafan clang::QualType CopyType(clang::ASTContext *dst_ctx, 104174998Srafan clang::ASTContext *src_ctx, clang::QualType type); 105174998Srafan 106174998Srafan lldb::opaque_compiler_type_t CopyType(clang::ASTContext *dst_ctx, 107166128Srafan clang::ASTContext *src_ctx, 108174998Srafan lldb::opaque_compiler_type_t type); 109174998Srafan 110166128Srafan CompilerType CopyType(ClangASTContext &dst, const CompilerType &src_type); 111174998Srafan 112166128Srafan clang::Decl *CopyDecl(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx, 113166128Srafan clang::Decl *decl); 114166128Srafan 115166128Srafan lldb::opaque_compiler_type_t DeportType(clang::ASTContext *dst_ctx, 116166128Srafan clang::ASTContext *src_ctx, 117166128Srafan lldb::opaque_compiler_type_t type); 118166128Srafan 119166128Srafan clang::Decl *DeportDecl(clang::ASTContext *dst_ctx, 120166128Srafan clang::ASTContext *src_ctx, clang::Decl *decl); 121174998Srafan 122166128Srafan void InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout); 123166128Srafan 124174998Srafan bool LayoutRecordType( 125166128Srafan const clang::RecordDecl *record_decl, uint64_t &bit_size, 126166128Srafan uint64_t &alignment, 127166128Srafan llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, 128166128Srafan llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> 129166128Srafan &base_offsets, 130166128Srafan llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> 131166128Srafan &vbase_offsets); 132166128Srafan 133174998Srafan bool CanImport(const CompilerType &type); 134174998Srafan 135174998Srafan bool Import(const CompilerType &type); 136166128Srafan 137166128Srafan bool CompleteType(const CompilerType &compiler_type); 138174998Srafan 139166128Srafan void CompleteDecl(clang::Decl *decl); 140166128Srafan 141174998Srafan bool CompleteTagDecl(clang::TagDecl *decl); 142166128Srafan 14397052Speter bool CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin); 14497052Speter 14597052Speter bool CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl *interface_decl); 146166128Srafan 14797052Speter bool CompleteAndFetchChildren(clang::QualType type); 14862453Speter 14950276Speter bool RequireCompleteType(clang::QualType type); 15062453Speter 151184989Srafan bool ResolveDeclOrigin(const clang::Decl *decl, clang::Decl **original_decl, 15262453Speter clang::ASTContext **original_ctx) { 15350276Speter DeclOrigin origin = GetDeclOrigin(decl); 15462453Speter 15562453Speter if (original_decl) 15662453Speter *original_decl = origin.decl; 15762453Speter 15862453Speter if (original_ctx) 15962453Speter *original_ctx = origin.ctx; 16062453Speter 16150276Speter return origin.Valid(); 162166128Srafan } 163166128Srafan 164166128Srafan void SetDeclOrigin(const clang::Decl *decl, clang::Decl *original_decl); 165166128Srafan 16697052Speter ClangASTMetadata *GetDeclMetadata(const clang::Decl *decl); 167166128Srafan 16897052Speter // 16997052Speter // Namespace maps 170166128Srafan // 171174998Srafan 17297052Speter typedef std::vector<std::pair<lldb::ModuleSP, CompilerDeclContext>> 173184989Srafan NamespaceMap; 17462453Speter typedef std::shared_ptr<NamespaceMap> NamespaceMapSP; 17550276Speter 17650276Speter void RegisterNamespaceMap(const clang::NamespaceDecl *decl, 17750276Speter NamespaceMapSP &namespace_map); 17850276Speter 17950276Speter NamespaceMapSP GetNamespaceMap(const clang::NamespaceDecl *decl); 18050276Speter 18150276Speter void BuildNamespaceMap(const clang::NamespaceDecl *decl); 18262455Speter 18362455Speter // 18450620Speter // Completers for maps 18562455Speter // 18662455Speter 18762455Speter class MapCompleter { 18862455Speter public: 18962455Speter virtual ~MapCompleter(); 19062455Speter 19150620Speter virtual void CompleteNamespaceMap(NamespaceMapSP &namespace_map, 19250620Speter const ConstString &name, 19362453Speter NamespaceMapSP &parent_map) const = 0; 19450276Speter }; 19550276Speter 19650276Speter void InstallMapCompleter(clang::ASTContext *dst_ctx, 19750276Speter MapCompleter &completer) { 19850276Speter ASTContextMetadataSP context_md; 19950276Speter ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 20050276Speter 20150276Speter if (context_md_iter == m_metadata_map.end()) { 20250276Speter context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); 20350276Speter m_metadata_map[dst_ctx] = context_md; 20450276Speter } else { 20576730Speter context_md = context_md_iter->second; 20662453Speter } 20750276Speter 208166128Srafan context_md->m_map_completer = &completer; 20950276Speter } 21062453Speter 21162453Speter void ForgetDestination(clang::ASTContext *dst_ctx); 21262453Speter void ForgetSource(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx); 21362453Speter 21462453Speterprivate: 21562453Speter struct DeclOrigin { 21662453Speter DeclOrigin() : ctx(nullptr), decl(nullptr) {} 21762453Speter 21850276Speter DeclOrigin(clang::ASTContext *_ctx, clang::Decl *_decl) 21950276Speter : ctx(_ctx), decl(_decl) {} 22062453Speter 22162453Speter DeclOrigin(const DeclOrigin &rhs) { 22250276Speter ctx = rhs.ctx; 22350276Speter decl = rhs.decl; 22450276Speter } 22550276Speter 22650276Speter void operator=(const DeclOrigin &rhs) { 22750276Speter ctx = rhs.ctx; 22850276Speter decl = rhs.decl; 22950276Speter } 23050276Speter 23150276Speter bool Valid() { return (ctx != nullptr || decl != nullptr); } 23250276Speter 23376730Speter clang::ASTContext *ctx; 23462453Speter clang::Decl *decl; 23550276Speter }; 236166128Srafan 23750276Speter typedef std::map<const clang::Decl *, DeclOrigin> OriginMap; 23862453Speter 23962453Speter class Minion : public clang::ASTImporter { 24062453Speter public: 24162453Speter Minion(ClangASTImporter &master, clang::ASTContext *target_ctx, 24262453Speter clang::ASTContext *source_ctx) 24362453Speter : clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx, 24462453Speter master.m_file_manager, true /*minimal*/), 24562453Speter m_decls_to_deport(nullptr), m_decls_already_deported(nullptr), 24662453Speter m_master(master), m_source_ctx(source_ctx) {} 24750276Speter 24850276Speter // A call to "InitDeportWorkQueues" puts the minion into deport mode. 24962453Speter // In deport mode, every copied Decl that could require completion is 25062453Speter // recorded and placed into the decls_to_deport set. 25150276Speter // 25250276Speter // A call to "ExecuteDeportWorkQueues" completes all the Decls that 25350276Speter // are in decls_to_deport, adding any Decls it sees along the way that 25450276Speter // it hasn't already deported. It proceeds until decls_to_deport is 25550276Speter // empty. 25650276Speter // 25750276Speter // These calls must be paired. Leaving a minion in deport mode or 25850276Speter // trying to start deport minion with a new pair of queues will result 25950276Speter // in an assertion failure. 26050276Speter 26150276Speter void 26276730Speter InitDeportWorkQueues(std::set<clang::NamedDecl *> *decls_to_deport, 26397052Speter std::set<clang::NamedDecl *> *decls_already_deported); 26450276Speter void ExecuteDeportWorkQueues(); 265166128Srafan 26697052Speter void ImportDefinitionTo(clang::Decl *to, clang::Decl *from); 26750276Speter 26862453Speter clang::Decl *Imported(clang::Decl *from, clang::Decl *to) override; 26962453Speter 27062453Speter clang::Decl *GetOriginalDecl(clang::Decl *To) override; 27162453Speter 27262453Speter std::set<clang::NamedDecl *> *m_decls_to_deport; 27362453Speter std::set<clang::NamedDecl *> *m_decls_already_deported; 27497052Speter ClangASTImporter &m_master; 27597052Speter clang::ASTContext *m_source_ctx; 27662453Speter }; 27797052Speter 27897052Speter typedef std::shared_ptr<Minion> MinionSP; 279166128Srafan typedef std::map<clang::ASTContext *, MinionSP> MinionMap; 280166128Srafan typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> 28197052Speter NamespaceMetaMap; 28297052Speter 28397052Speter struct ASTContextMetadata { 28497052Speter ASTContextMetadata(clang::ASTContext *dst_ctx) 28597052Speter : m_dst_ctx(dst_ctx), m_minions(), m_origins(), m_namespace_maps(), 286166128Srafan m_map_completer(nullptr) {} 28797052Speter 28897052Speter clang::ASTContext *m_dst_ctx; 28950276Speter MinionMap m_minions; 29097052Speter OriginMap m_origins; 29150276Speter 29250276Speter NamespaceMetaMap m_namespace_maps; 29362453Speter MapCompleter *m_map_completer; 29497052Speter }; 29550276Speter 296166128Srafan typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP; 297166128Srafan typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> 298166128Srafan ContextMetadataMap; 299166128Srafan 300166128Srafan ContextMetadataMap m_metadata_map; 301174998Srafan 302166128Srafan ASTContextMetadataSP GetContextMetadata(clang::ASTContext *dst_ctx) { 303174998Srafan ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 304174998Srafan 305166128Srafan if (context_md_iter == m_metadata_map.end()) { 306166128Srafan ASTContextMetadataSP context_md = 307166128Srafan ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); 308 m_metadata_map[dst_ctx] = context_md; 309 return context_md; 310 } else { 311 return context_md_iter->second; 312 } 313 } 314 315 ASTContextMetadataSP MaybeGetContextMetadata(clang::ASTContext *dst_ctx) { 316 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 317 318 if (context_md_iter != m_metadata_map.end()) 319 return context_md_iter->second; 320 else 321 return ASTContextMetadataSP(); 322 } 323 324 MinionSP GetMinion(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx) { 325 ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx); 326 327 MinionMap &minions = context_md->m_minions; 328 MinionMap::iterator minion_iter = minions.find(src_ctx); 329 330 if (minion_iter == minions.end()) { 331 MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx)); 332 minions[src_ctx] = minion; 333 return minion; 334 } else { 335 return minion_iter->second; 336 } 337 } 338 339 DeclOrigin GetDeclOrigin(const clang::Decl *decl); 340 341 clang::FileManager m_file_manager; 342 typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo> 343 RecordDeclToLayoutMap; 344 345 RecordDeclToLayoutMap m_record_decl_to_layout_map; 346}; 347 348} // namespace lldb_private 349 350#endif // liblldb_ClangASTImporter_h_ 351