diff options
Diffstat (limited to 'source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp')
-rw-r--r-- | source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp | 357 |
1 files changed, 280 insertions, 77 deletions
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index 7622791778ba..7f031356b3c3 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -51,8 +51,94 @@ private: }; } +ClangASTSource::ClangASTSource(const lldb::TargetSP &target) + : m_import_in_progress(false), m_lookups_enabled(false), m_target(target), + m_ast_context(NULL), m_active_lexical_decls(), m_active_lookups() { + if (!target->GetUseModernTypeLookup()) { + m_ast_importer_sp = m_target->GetClangASTImporter(); + } +} + +void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context, + clang::FileManager &file_manager, + bool is_shared_context) { + m_ast_context = &ast_context; + m_file_manager = &file_manager; + if (m_target->GetUseModernTypeLookup()) { + // Configure the ExternalASTMerger. The merger needs to be able to import + // types from any source that we would do lookups in, which includes the + // persistent AST context as well as the modules and Objective-C runtime + // AST contexts. + + lldbassert(!m_merger_up); + clang::ExternalASTMerger::ImporterTarget target = {ast_context, + file_manager}; + std::vector<clang::ExternalASTMerger::ImporterSource> sources; + for (lldb::ModuleSP module_sp : m_target->GetImages().Modules()) { + if (auto *module_ast_ctx = llvm::cast_or_null<ClangASTContext>( + module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC))) { + lldbassert(module_ast_ctx->getASTContext()); + lldbassert(module_ast_ctx->getFileManager()); + sources.push_back({*module_ast_ctx->getASTContext(), + *module_ast_ctx->getFileManager(), + module_ast_ctx->GetOriginMap() + }); + } + } + + do { + lldb::ProcessSP process(m_target->GetProcessSP()); + + if (!process) + break; + + ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); + + if (!language_runtime) + break; + + DeclVendor *runtime_decl_vendor = language_runtime->GetDeclVendor(); + + if (!runtime_decl_vendor) + break; + + sources.push_back(runtime_decl_vendor->GetImporterSource()); + } while (0); + + do { + DeclVendor *modules_decl_vendor = + m_target->GetClangModulesDeclVendor(); + + if (!modules_decl_vendor) + break; + + sources.push_back(modules_decl_vendor->GetImporterSource()); + } while (0); + + if (!is_shared_context) { + // Update the scratch AST context's merger to reflect any new sources we + // might have come across since the last time an expression was parsed. + + auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>( + m_target->GetScratchClangASTContext()); + + scratch_ast_context->GetMergerUnchecked().AddSources(sources); + + sources.push_back({*scratch_ast_context->getASTContext(), + *scratch_ast_context->getFileManager(), + scratch_ast_context->GetOriginMap()}); + } while (0); + + m_merger_up = + llvm::make_unique<clang::ExternalASTMerger>(target, sources); + } else { + m_ast_importer_sp->InstallMapCompleter(&ast_context, *this); + } +} + ClangASTSource::~ClangASTSource() { - m_ast_importer_sp->ForgetDestination(m_ast_context); + if (m_ast_importer_sp) + m_ast_importer_sp->ForgetDestination(m_ast_context); // We are in the process of destruction, don't create clang ast context on // demand @@ -69,7 +155,7 @@ ClangASTSource::~ClangASTSource() { if (!scratch_ast_context) return; - if (m_ast_context != scratch_ast_context) + if (m_ast_context != scratch_ast_context && m_ast_importer_sp) m_ast_importer_sp->ForgetSource(scratch_ast_context, m_ast_context); } @@ -203,6 +289,13 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { m_active_lexical_decls.insert(tag_decl); ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl); + if (!m_ast_importer_sp) { + if (HasMerger()) { + GetMergerUnchecked().CompleteType(tag_decl); + } + return; + } + if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) { // We couldn't complete the type. Maybe there's a definition // somewhere else that can be completed. @@ -337,6 +430,22 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) { dumper.ToLog(log, " [COID] "); } + if (!m_ast_importer_sp) { + if (HasMerger()) { + ObjCInterfaceDecl *complete_iface_decl = + GetCompleteObjCInterface(interface_decl); + + if (complete_iface_decl && (complete_iface_decl != interface_decl)) { + m_merger_up->ForceRecordOrigin(interface_decl, {complete_iface_decl, &complete_iface_decl->getASTContext()}); + } + + GetMergerUnchecked().CompleteType(interface_decl); + } else { + lldbassert(0 && "No mechanism for completing a type!"); + } + return; + } + Decl *original_decl = NULL; ASTContext *original_ctx = NULL; @@ -367,7 +476,7 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) { } clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface( - clang::ObjCInterfaceDecl *interface_decl) { + const clang::ObjCInterfaceDecl *interface_decl) { lldb::ProcessSP process(m_target->GetProcessSP()); if (!process) @@ -411,6 +520,22 @@ void ClangASTSource::FindExternalLexicalDecls( const DeclContext *decl_context, llvm::function_ref<bool(Decl::Kind)> predicate, llvm::SmallVectorImpl<Decl *> &decls) { + + if (HasMerger()) { + if (auto *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_context)) { + ObjCInterfaceDecl *complete_iface_decl = + GetCompleteObjCInterface(interface_decl); + + if (complete_iface_decl && (complete_iface_decl != interface_decl)) { + m_merger_up->ForceRecordOrigin(interface_decl, {complete_iface_decl, &complete_iface_decl->getASTContext()}); + } + } + return GetMergerUnchecked().FindExternalLexicalDecls(decl_context, + predicate, + decls); + } else if (!m_ast_importer_sp) + return; + ClangASTMetrics::RegisterLexicalQuery(); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -507,8 +632,7 @@ void ClangASTSource::FindExternalLexicalDecls( decl->getDeclKindName(), ast_dumper.GetCString()); } - Decl *copied_decl = - m_ast_importer_sp->CopyDecl(m_ast_context, original_ctx, decl); + Decl *copied_decl = CopyDecl(decl); if (!copied_decl) continue; @@ -568,12 +692,31 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { name.GetCString(), context.m_decl_context->getDeclKindName()); } + if (HasMerger() && !isa<TranslationUnitDecl>(context.m_decl_context) + /* possibly handle NamespaceDecls here? */) { + if (auto *interface_decl = + dyn_cast<ObjCInterfaceDecl>(context.m_decl_context)) { + ObjCInterfaceDecl *complete_iface_decl = + GetCompleteObjCInterface(interface_decl); + + if (complete_iface_decl && (complete_iface_decl != interface_decl)) { + GetMergerUnchecked().ForceRecordOrigin( + interface_decl, + {complete_iface_decl, &complete_iface_decl->getASTContext()}); + } + } + + GetMergerUnchecked().FindExternalVisibleDeclsByName(context.m_decl_context, + context.m_decl_name); + return; // otherwise we may need to fall back + } + context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap); if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context)) { - ClangASTImporter::NamespaceMapSP namespace_map = - m_ast_importer_sp->GetNamespaceMap(namespace_context); + ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp ? + m_ast_importer_sp->GetNamespaceMap(namespace_context) : nullptr; if (log && log->GetVerbose()) log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)", @@ -593,7 +736,7 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { FindExternalVisibleDecls(context, i->first, i->second, current_id); } - } else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) { + } else if (isa<ObjCInterfaceDecl>(context.m_decl_context) && !HasMerger()) { FindObjCPropertyAndIvarDecls(context); } else if (!isa<TranslationUnitDecl>(context.m_decl_context)) { // we shouldn't be getting FindExternalVisibleDecls calls for these @@ -623,6 +766,25 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { } } +bool ClangASTSource::IgnoreName(const ConstString name, + bool ignore_all_dollar_names) { + static const ConstString id_name("id"); + static const ConstString Class_name("Class"); + + if (name == id_name || name == Class_name) + return true; + + StringRef name_string_ref = name.GetStringRef(); + + // The ClangASTSource is not responsible for finding $-names. + if (name_string_ref.empty() || + (ignore_all_dollar_names && name_string_ref.startswith("$")) || + name_string_ref.startswith("_$")) + return true; + + return false; +} + void ClangASTSource::FindExternalVisibleDecls( NameSearchContext &context, lldb::ModuleSP module_sp, CompilerDeclContext &namespace_decl, unsigned int current_id) { @@ -633,20 +795,7 @@ void ClangASTSource::FindExternalVisibleDecls( SymbolContextList sc_list; const ConstString name(context.m_decl_name.getAsString().c_str()); - - const char *name_unique_cstr = name.GetCString(); - - static ConstString id_name("id"); - static ConstString Class_name("Class"); - - if (name == id_name || name == Class_name) - return; - - if (name_unique_cstr == NULL) - return; - - // The ClangASTSource is not responsible for finding $-names. - if (name_unique_cstr[0] == '$') + if (IgnoreName(name, true)) return; if (module_sp && namespace_decl) { @@ -671,7 +820,7 @@ void ClangASTSource::FindExternalVisibleDecls( module_sp->GetFileSpec().GetFilename().GetCString()); } } - } else { + } else if (!HasMerger()) { const ModuleList &target_images = m_target->GetImages(); std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex()); @@ -774,9 +923,7 @@ void ClangASTSource::FindExternalVisibleDecls( if (llvm::isa<clang::TypeDecl>(decl_from_modules) || llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) || llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) { - clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl( - m_ast_context, &decl_from_modules->getASTContext(), - decl_from_modules); + clang::Decl *copied_decl = CopyDecl(decl_from_modules); clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr; @@ -831,8 +978,7 @@ void ClangASTSource::FindExternalVisibleDecls( current_id, name.GetCString()); } - clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl( - m_ast_context, &decls[0]->getASTContext(), decls[0]); + clang::Decl *copied_decl = CopyDecl(decls[0]); clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr; @@ -875,7 +1021,7 @@ public: DeclFromParser() : TaggedASTDecl<D>() {} DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) {} - DeclFromUser<D> GetOrigin(ClangASTImporter *importer); + DeclFromUser<D> GetOrigin(ClangASTSource &source); }; template <class D> class DeclFromUser : public TaggedASTDecl<D> { @@ -883,32 +1029,29 @@ public: DeclFromUser() : TaggedASTDecl<D>() {} DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) {} - DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx); + DeclFromParser<D> Import(ClangASTSource &source); }; template <class D> -DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTImporter *importer) { +DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTSource &source) { DeclFromUser<> origin_decl; - importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL); + source.ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL); if (origin_decl.IsInvalid()) return DeclFromUser<D>(); return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl)); } template <class D> -DeclFromParser<D> DeclFromUser<D>::Import(ClangASTImporter *importer, - ASTContext &dest_ctx) { - DeclFromParser<> parser_generic_decl( - importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl)); +DeclFromParser<D> DeclFromUser<D>::Import(ClangASTSource &source) { + DeclFromParser<> parser_generic_decl(source.CopyDecl(this->decl)); if (parser_generic_decl.IsInvalid()) return DeclFromParser<D>(); return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl)); } -static bool FindObjCMethodDeclsWithOrigin( +bool ClangASTSource::FindObjCMethodDeclsWithOrigin( unsigned int current_id, NameSearchContext &context, - ObjCInterfaceDecl *original_interface_decl, clang::ASTContext *ast_context, - ClangASTImporter *ast_importer, const char *log_info) { + ObjCInterfaceDecl *original_interface_decl, const char *log_info) { const DeclarationName &decl_name(context.m_decl_name); clang::ASTContext *original_ctx = &original_interface_decl->getASTContext(); @@ -967,8 +1110,7 @@ static bool FindObjCMethodDeclsWithOrigin( if (!result_method) continue; - Decl *copied_decl = ast_importer->CopyDecl( - ast_context, &result_method->getASTContext(), result_method); + Decl *copied_decl = CopyDecl(result_method); if (!copied_decl) continue; @@ -995,6 +1137,21 @@ static bool FindObjCMethodDeclsWithOrigin( void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + if (HasMerger()) { + if (auto *interface_decl = dyn_cast<ObjCInterfaceDecl>(context.m_decl_context)) { + ObjCInterfaceDecl *complete_iface_decl = + GetCompleteObjCInterface(interface_decl); + + if (complete_iface_decl && (complete_iface_decl != context.m_decl_context)) { + m_merger_up->ForceRecordOrigin(interface_decl, {complete_iface_decl, &complete_iface_decl->getASTContext()}); + } + } + + GetMergerUnchecked().FindExternalVisibleDeclsByName(context.m_decl_context, + context.m_decl_name); + return; + } + static unsigned int invocation_id = 0; unsigned int current_id = invocation_id++; @@ -1021,8 +1178,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { dyn_cast<ObjCInterfaceDecl>(original_decl); if (FindObjCMethodDeclsWithOrigin(current_id, context, - original_interface_decl, m_ast_context, - m_ast_importer_sp.get(), "at origin")) + original_interface_decl, "at origin")) return; // found it, no need to look any further } while (0); @@ -1160,8 +1316,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { continue; if (found_interface_decl->getName() == interface_decl->getName()) { - Decl *copied_decl = m_ast_importer_sp->CopyDecl( - m_ast_context, &method_decl->getASTContext(), method_decl); + Decl *copied_decl = CopyDecl(method_decl); if (!copied_decl) continue; @@ -1210,7 +1365,6 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { static_cast<void *>(&complete_iface_decl->getASTContext())); FindObjCMethodDeclsWithOrigin(current_id, context, complete_interface_decl, - m_ast_context, m_ast_importer_sp.get(), "in debug info"); return; @@ -1238,8 +1392,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { break; if (FindObjCMethodDeclsWithOrigin( - current_id, context, interface_decl_from_modules, m_ast_context, - m_ast_importer_sp.get(), "in modules")) + current_id, context, interface_decl_from_modules, "in modules")) return; } } while (0); @@ -1278,14 +1431,12 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { break; FindObjCMethodDeclsWithOrigin(current_id, context, runtime_interface_decl, - m_ast_context, m_ast_importer_sp.get(), "in runtime"); } while (0); } static bool FindObjCPropertyAndIvarDeclsWithOrigin( - unsigned int current_id, NameSearchContext &context, - clang::ASTContext &ast_context, ClangASTImporter *ast_importer, + unsigned int current_id, NameSearchContext &context, ClangASTSource &source, DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -1305,7 +1456,7 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin( if (origin_property_decl.IsValid()) { DeclFromParser<ObjCPropertyDecl> parser_property_decl( - origin_property_decl.Import(ast_importer, ast_context)); + origin_property_decl.Import(source)); if (parser_property_decl.IsValid()) { if (log) { ASTDumper dumper((Decl *)parser_property_decl.decl); @@ -1323,7 +1474,7 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin( if (origin_ivar_decl.IsValid()) { DeclFromParser<ObjCIvarDecl> parser_ivar_decl( - origin_ivar_decl.Import(ast_importer, ast_context)); + origin_ivar_decl.Import(source)); if (parser_ivar_decl.IsValid()) { if (log) { ASTDumper dumper((Decl *)parser_ivar_decl.decl); @@ -1348,7 +1499,7 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl( cast<ObjCInterfaceDecl>(context.m_decl_context)); DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl( - parser_iface_decl.GetOrigin(m_ast_importer_sp.get())); + parser_iface_decl.GetOrigin(*this)); ConstString class_name(parser_iface_decl->getNameAsString().c_str()); @@ -1360,8 +1511,7 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { context.m_decl_name.getAsString().c_str()); if (FindObjCPropertyAndIvarDeclsWithOrigin( - current_id, context, *m_ast_context, m_ast_importer_sp.get(), - origin_iface_decl)) + current_id, context, *this, origin_iface_decl)) return; if (log) @@ -1397,8 +1547,7 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { static_cast<const void *>(complete_iface_decl.decl), static_cast<void *>(&complete_iface_decl->getASTContext())); - FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *m_ast_context, - m_ast_importer_sp.get(), + FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this, complete_iface_decl); return; @@ -1435,9 +1584,8 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { static_cast<const void *>(interface_decl_from_modules.decl), static_cast<void *>(&interface_decl_from_modules->getASTContext())); - if (FindObjCPropertyAndIvarDeclsWithOrigin( - current_id, context, *m_ast_context, m_ast_importer_sp.get(), - interface_decl_from_modules)) + if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this, + interface_decl_from_modules)) return; } while (0); @@ -1483,8 +1631,7 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { static_cast<void *>(&interface_decl_from_runtime->getASTContext())); if (FindObjCPropertyAndIvarDeclsWithOrigin( - current_id, context, *m_ast_context, m_ast_importer_sp.get(), - interface_decl_from_runtime)) + current_id, context, *this, interface_decl_from_runtime)) return; } while (0); } @@ -1495,7 +1642,7 @@ typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetMap; template <class D, class O> static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map, llvm::DenseMap<const D *, O> &source_map, - ClangASTImporter *importer, ASTContext &dest_ctx) { + ClangASTSource &source) { // When importing fields into a new record, clang has a hard requirement that // fields be imported in field offset order. Since they are stored in a // DenseMap @@ -1516,7 +1663,7 @@ static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map, for (const auto &item : sorted_items) { DeclFromUser<D> user_decl(const_cast<D *>(item.first)); - DeclFromParser<D> parser_decl(user_decl.Import(importer, dest_ctx)); + DeclFromParser<D> parser_decl(user_decl.Import(source)); if (parser_decl.IsInvalid()) return false; destination_map.insert( @@ -1593,7 +1740,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, DeclFromParser<const RecordDecl> parser_record(record); DeclFromUser<const RecordDecl> origin_record( - parser_record.GetOrigin(m_ast_importer_sp.get())); + parser_record.GetOrigin(*this)); if (origin_record.IsInvalid()) return false; @@ -1629,7 +1776,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, field_idx++; } - ASTContext &parser_ast_context(record->getASTContext()); + lldbassert(&record->getASTContext() == m_ast_context); DeclFromUser<const CXXRecordDecl> origin_cxx_record( DynCast<const CXXRecordDecl>(origin_record)); @@ -1642,12 +1789,10 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, return false; } - if (!ImportOffsetMap(field_offsets, origin_field_offsets, - m_ast_importer_sp.get(), parser_ast_context) || - !ImportOffsetMap(base_offsets, origin_base_offsets, - m_ast_importer_sp.get(), parser_ast_context) || + if (!ImportOffsetMap(field_offsets, origin_field_offsets, *this) || + !ImportOffsetMap(base_offsets, origin_base_offsets, *this) || !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, - m_ast_importer_sp.get(), parser_ast_context)) + *this)) return false; size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth(); @@ -1811,8 +1956,7 @@ NamespaceDecl *ClangASTSource::AddNamespace( if (!src_namespace_decl) return nullptr; - Decl *copied_decl = - m_ast_importer_sp->CopyDecl(m_ast_context, src_ast, src_namespace_decl); + Decl *copied_decl = CopyDecl(src_namespace_decl); if (!copied_decl) return nullptr; @@ -1830,6 +1974,54 @@ NamespaceDecl *ClangASTSource::AddNamespace( return dyn_cast<NamespaceDecl>(copied_decl); } +clang::QualType ClangASTSource::CopyTypeWithMerger( + clang::ASTContext &from_context, + clang::ExternalASTMerger &merger, + clang::QualType type) { + if (!merger.HasImporterForOrigin(from_context)) { + lldbassert(0 && "Couldn't find the importer for a source context!"); + return QualType(); + } + + return merger.ImporterForOrigin(from_context).Import(type); +} + +clang::Decl *ClangASTSource::CopyDecl(Decl *src_decl) { + clang::ASTContext &from_context = src_decl->getASTContext(); + if (m_ast_importer_sp) { + return m_ast_importer_sp->CopyDecl(m_ast_context, &from_context, src_decl); + } else if (m_merger_up) { + if (!m_merger_up->HasImporterForOrigin(from_context)) { + lldbassert(0 && "Couldn't find the importer for a source context!"); + return nullptr; + } + + return m_merger_up->ImporterForOrigin(from_context).Import(src_decl); + } else { + lldbassert(0 && "No mechanism for copying a decl!"); + return nullptr; + } +} + +bool ClangASTSource::ResolveDeclOrigin(const clang::Decl *decl, + clang::Decl **original_decl, + clang::ASTContext **original_ctx) { + if (m_ast_importer_sp) { + return m_ast_importer_sp->ResolveDeclOrigin(decl, original_decl, + original_ctx); + } else if (m_merger_up) { + return false; // Implement this correctly in ExternalASTMerger + } else { + // this can happen early enough that no ExternalASTSource is installed. + return false; + } +} + +clang::ExternalASTMerger &ClangASTSource::GetMergerUnchecked() { + lldbassert(m_merger_up != nullptr); + return *m_merger_up; +} + CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) { ClangASTContext *src_ast = llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem()); @@ -1840,9 +2032,20 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) { SetImportInProgress(true); - QualType copied_qual_type = - m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(), - ClangUtil::GetQualType(src_type)); + QualType copied_qual_type; + + if (m_ast_importer_sp) { + copied_qual_type = + m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(), + ClangUtil::GetQualType(src_type)); + } else if (m_merger_up) { + copied_qual_type = + CopyTypeWithMerger(*src_ast->getASTContext(), *m_merger_up, + ClangUtil::GetQualType(src_type)); + } else { + lldbassert(0 && "No mechanism for copying a type!"); + return CompilerType(); + } SetImportInProgress(false); |