Author: spyffe Date: Thu Sep 28 13:20:25 2017 New Revision: 314458 URL: http://llvm.org/viewvc/llvm-project?rev=314458&view=rev Log: [Expression parser] Setting to enable use of ExternalASTMerger
This setting can be enabled like this at the target level: (lldb) settings set target.experimental.use-modern-type-lookup true This causes several new behaviors in the Clang expression parser: - It completely disables use of ClangASTImporter. None are created at all, and all users of it are now conditionalized on its presence. - It instead constructs a per-expression ExternalASTMerger, which exists inside Clang and contains much of the type completion logic that hitherto lived in ExternalASTSource, ClangExpressionDeclMap, and ClangASTImporter. - The expression parser uses this Merger as a backend for copying and completing types. - It also constructs a persistent ExternalASTMerger which is connected to the Target's persistent AST context. This is a major chunk of LLDB functionality moved into Clang. It can be tested in two ways: 1. For an individual debug session, enable the setting before running a target. 2. For the testsuite, change the option to be default-true. This is done in Target.cpp's g_experimental_properties. The testsuite is not yet clean with this, so I have not committed that switch. I have filed a Bugzilla for extending the testsuite to allow custom settings for all tests: https://bugs.llvm.org/show_bug.cgi?id=34771 I have also filed a Bugzilla for fixing the remaining testsuite failures with this setting enabled: https://bugs.llvm.org/show_bug.cgi?id=34772 Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h lldb/trunk/include/lldb/Symbol/DeclVendor.h lldb/trunk/include/lldb/Target/Target.h lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h lldb/trunk/source/Symbol/ClangASTContext.cpp lldb/trunk/source/Target/Target.cpp Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Thu Sep 28 13:20:25 2017 @@ -25,6 +25,7 @@ // Other libraries and framework includes #include "clang/AST/ASTContext.h" +#include "clang/AST/ExternalASTMerger.h" #include "clang/AST/TemplateBase.h" #include "llvm/ADT/SmallVector.h" @@ -964,7 +965,10 @@ public: clang::DeclarationName GetDeclarationName(const char *name, const CompilerType &function_clang_type); - + + virtual const clang::ExternalASTMerger::OriginMap &GetOriginMap() { + return m_origins; + } protected: //------------------------------------------------------------------ // Classes that inherit from ClangASTContext can see and modify these @@ -990,6 +994,7 @@ protected: CompleteTagDeclCallback m_callback_tag_decl; CompleteObjCInterfaceDeclCallback m_callback_objc_decl; void * m_callback_baton; + clang::ExternalASTMerger::OriginMap m_origins; uint32_t m_pointer_byte_size; bool m_ast_owned; bool m_can_evaluate_expressions; @@ -1023,7 +1028,12 @@ public: const char *name) override; PersistentExpressionState *GetPersistentExpressionState() override; - + + clang::ExternalASTMerger &GetMergerUnchecked(); + + const clang::ExternalASTMerger::OriginMap &GetOriginMap() override { + return GetMergerUnchecked().GetOrigins(); + } private: lldb::TargetWP m_target_wp; lldb::ClangPersistentVariablesUP m_persistent_variables; ///< These are the Modified: lldb/trunk/include/lldb/Symbol/DeclVendor.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/DeclVendor.h?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/DeclVendor.h (original) +++ lldb/trunk/include/lldb/Symbol/DeclVendor.h Thu Sep 28 13:20:25 2017 @@ -13,6 +13,8 @@ #include "lldb/Core/ClangForward.h" #include "lldb/lldb-defines.h" +#include "clang/AST/ExternalASTMerger.h" + #include <vector> namespace lldb_private { @@ -53,6 +55,15 @@ public: uint32_t max_matches, std::vector<clang::NamedDecl *> &decls) = 0; + //------------------------------------------------------------------ + /// Interface for ExternalASTMerger. Returns an ImporterSource + /// allowing type completion. + /// + /// @return + /// An ImporterSource for this DeclVendor. + //------------------------------------------------------------------ + virtual clang::ExternalASTMerger::ImporterSource GetImporterSource() = 0; + private: //------------------------------------------------------------------ // For DeclVendor only Modified: lldb/trunk/include/lldb/Target/Target.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Target.h (original) +++ lldb/trunk/include/lldb/Target/Target.h Thu Sep 28 13:20:25 2017 @@ -196,6 +196,8 @@ public: void SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b); + bool GetUseModernTypeLookup() const; + private: //------------------------------------------------------------------ // Callbacks for m_launch_info. Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp Thu Sep 28 13:20:25 2017 @@ -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(TagDec 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. @@ -336,6 +429,22 @@ void ClangASTSource::CompleteType(clang: ASTDumper dumper((Decl *)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(!"No mechanism for completing a type!"); + } + return; + } Decl *original_decl = NULL; ASTContext *original_ctx = NULL; @@ -367,7 +476,7 @@ void ClangASTSource::CompleteType(clang: } 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::FindExternalLexical 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::FindExternalLexical 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::FindExternalVisible 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::FindExternalVisible 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 @@ -677,7 +820,7 @@ void ClangASTSource::FindExternalVisible 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()); @@ -780,9 +923,7 @@ void ClangASTSource::FindExternalVisible 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; @@ -837,8 +978,7 @@ void ClangASTSource::FindExternalVisible 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; @@ -881,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> { @@ -889,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(); @@ -973,8 +1110,7 @@ static bool FindObjCMethodDeclsWithOrigi 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; @@ -1001,6 +1137,21 @@ static bool FindObjCMethodDeclsWithOrigi 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++; @@ -1027,8 +1178,7 @@ void ClangASTSource::FindObjCMethodDecls 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); @@ -1166,8 +1316,7 @@ void ClangASTSource::FindObjCMethodDecls 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; @@ -1216,7 +1365,6 @@ void ClangASTSource::FindObjCMethodDecls 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; @@ -1244,8 +1392,7 @@ void ClangASTSource::FindObjCMethodDecls 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); @@ -1284,14 +1431,12 @@ void ClangASTSource::FindObjCMethodDecls 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)); @@ -1311,7 +1456,7 @@ static bool FindObjCPropertyAndIvarDecls 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); @@ -1329,7 +1474,7 @@ static bool FindObjCPropertyAndIvarDecls 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); @@ -1354,7 +1499,7 @@ void ClangASTSource::FindObjCPropertyAnd 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()); @@ -1366,8 +1511,7 @@ void ClangASTSource::FindObjCPropertyAnd 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) @@ -1403,8 +1547,7 @@ void ClangASTSource::FindObjCPropertyAnd 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; @@ -1441,9 +1584,8 @@ void ClangASTSource::FindObjCPropertyAnd 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); @@ -1489,8 +1631,7 @@ void ClangASTSource::FindObjCPropertyAnd 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); } @@ -1501,7 +1642,7 @@ typedef llvm::DenseMap<const CXXRecordDe 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 @@ -1522,7 +1663,7 @@ static bool ImportOffsetMap(llvm::DenseM 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( @@ -1599,7 +1740,7 @@ bool ClangASTSource::layoutRecordType(co 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; @@ -1635,7 +1776,7 @@ bool ClangASTSource::layoutRecordType(co 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)); @@ -1648,12 +1789,10 @@ bool ClangASTSource::layoutRecordType(co 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(); @@ -1817,8 +1956,7 @@ NamespaceDecl *ClangASTSource::AddNamesp 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; @@ -1836,6 +1974,54 @@ NamespaceDecl *ClangASTSource::AddNamesp 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(!"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(!"Couldn't find the importer for a source context!"); + return nullptr; + } + + return m_merger_up->ImporterForOrigin(from_context).Import(src_decl); + } else { + lldbassert("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); + return *m_merger_up; +} + CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) { ClangASTContext *src_ast = llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem()); @@ -1846,9 +2032,20 @@ CompilerType ClangASTSource::GuardedCopy 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("No mechanism for copying a type!"); + return CompilerType(); + } SetImportInProgress(false); Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h Thu Sep 28 13:20:25 2017 @@ -16,6 +16,7 @@ #include "lldb/Symbol/ClangExternalASTSourceCommon.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/Target.h" +#include "clang/AST/ExternalASTMerger.h" #include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/SmallSet.h" @@ -41,14 +42,10 @@ public: /// /// Initializes class variables. /// - /// @param[in] declMap - /// A reference to the LLDB object that handles entity lookup. + /// @param[in] target + /// A reference to the target containing debug information to use. //------------------------------------------------------------------ - 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() { - m_ast_importer_sp = m_target->GetClangASTImporter(); - } + ClangASTSource(const lldb::TargetSP &target); //------------------------------------------------------------------ /// Destructor @@ -70,10 +67,9 @@ public: } void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; } - void InstallASTContext(clang::ASTContext *ast_context) { - m_ast_context = ast_context; - m_ast_importer_sp->InstallMapCompleter(ast_context, *this); - } + void InstallASTContext(clang::ASTContext &ast_context, + clang::FileManager &file_manager, + bool is_shared_context = false); // // APIs for ExternalASTSource @@ -313,7 +309,7 @@ protected: /// the complete interface otherwise. //------------------------------------------------------------------ clang::ObjCInterfaceDecl * - GetCompleteObjCInterface(clang::ObjCInterfaceDecl *interface_decl); + GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl); //------------------------------------------------------------------ /// Find all entities matching a given name in a given module, @@ -376,7 +372,7 @@ protected: //------------------------------------------------------------------ CompilerType GuardedCopyType(const CompilerType &src_type); - +public: //------------------------------------------------------------------ /// Returns true if a name should be ignored by name lookup. /// @@ -392,6 +388,73 @@ protected: //------------------------------------------------------------------ bool IgnoreName(const ConstString name, bool ignore_all_dollar_names); +public: + //------------------------------------------------------------------ + /// Copies a single Decl into the parser's AST context. + /// + /// @param[in] src_decl + /// The Decl to copy. + /// + /// @return + /// A copy of the Decl in m_ast_context, or NULL if the copy failed. + //------------------------------------------------------------------ + clang::Decl *CopyDecl(clang::Decl *src_decl); + + //------------------------------------------------------------------ + /// Copies a single Type to the target of the given ExternalASTMerger. + /// + /// @param[in] src_context + /// The ASTContext containing the type. + /// + /// @param[in] merger + /// The merger to use. This isn't just *m_merger_up because it might be + /// the persistent AST context's merger. + /// + /// @param[in] type + /// The type to copy. + /// + /// @return + /// A copy of the Type in the merger's target context. + //------------------------------------------------------------------ + clang::QualType CopyTypeWithMerger(clang::ASTContext &src_context, + clang::ExternalASTMerger &merger, + clang::QualType type); + + //------------------------------------------------------------------ + /// Determined the origin of a single Decl, if it can be found. + /// + /// @param[in] decl + /// The Decl whose origin is to be found. + /// + /// @param[out] original_decl + /// A pointer whose target is filled in with the original Decl. + /// + /// @param[in] original_ctx + /// A pointer whose target is filled in with the original's ASTContext. + /// + /// @return + /// True if lookup succeeded; false otherwise. + //------------------------------------------------------------------ + bool ResolveDeclOrigin(const clang::Decl *decl, clang::Decl **original_decl, + clang::ASTContext **original_ctx); + + //------------------------------------------------------------------ + /// Returns m_merger_up. Only call this if the target is configured to use + /// modern lookup, + //------------------------------------------------------------------ + clang::ExternalASTMerger &GetMergerUnchecked(); + + //------------------------------------------------------------------ + /// Returns true if there is a merger. This only occurs if the target is + /// using modern lookup. + //------------------------------------------------------------------ + bool HasMerger() { return (bool)m_merger_up; } + +protected: + bool FindObjCMethodDeclsWithOrigin( + unsigned int current_id, NameSearchContext &context, + clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info); + friend struct NameSearchContext; bool m_import_in_progress; @@ -401,7 +464,11 @@ protected: m_target; ///< The target to use in finding variables and types. clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for. + clang::FileManager + *m_file_manager; ///< The file manager paired with the AST context. lldb::ClangASTImporterSP m_ast_importer_sp; ///< The target's AST importer. + std::unique_ptr<clang::ExternalASTMerger> m_merger_up; + ///< The ExternalASTMerger for this parse. std::set<const clang::Decl *> m_active_lexical_decls; std::set<const char *> m_active_lookups; }; Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp Thu Sep 28 13:20:25 2017 @@ -48,8 +48,10 @@ #include "lldb/lldb-private.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTImporter.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" @@ -178,6 +180,134 @@ ClangExpressionDeclMap::TargetInfo Clang return ret; } +namespace { +/// This class walks an AST and ensures that all DeclContexts defined inside the +/// current source file are properly complete. +/// +/// This is used to ensure that persistent types defined in the current source +/// file migrate completely to the persistent AST context before they are +/// reused. If that didn't happen, it would be impoossible to complete them +/// because their origin would be gone. +/// +/// The stragtegy used by this class is to check the SourceLocation (to be +/// specific, the FileID) and see if it's the FileID for the current expression. +/// Alternate strategies could include checking whether an ExternalASTMerger, +/// set up to not have the current context as a source, can find an original for +/// the type. +class Completer : public clang::RecursiveASTVisitor<Completer> { +private: + clang::ASTImporter &m_exporter; /// Used to import Decl contents + clang::FileID m_file; /// The file that's going away + llvm::DenseSet<clang::Decl *> m_completed; /// Visited Decls, to avoid cycles + + bool ImportAndCheckCompletable(clang::Decl *decl) { + (void)m_exporter.Import(decl); + if (m_completed.count(decl)) + return false; + if (!llvm::isa<DeclContext>(decl)) + return false; + const clang::SourceLocation loc = decl->getLocation(); + if (!loc.isValid()) + return false; + const clang::FileID file = + m_exporter.getFromContext().getSourceManager().getFileID(loc); + if (file != m_file) + return false; + // We are assuming the Decl was parsed in this very expression, so it should + // not have external storage. + lldbassert(!llvm::cast<DeclContext>(decl)->hasExternalLexicalStorage()); + return true; + } + + void Complete(clang::Decl *decl) { + m_completed.insert(decl); + auto *decl_context = llvm::cast<DeclContext>(decl); + (void)m_exporter.Import(decl); + m_exporter.CompleteDecl(decl); + for (Decl *child : decl_context->decls()) + if (ImportAndCheckCompletable(child)) + Complete(child); + } + + void MaybeComplete(clang::Decl *decl) { + if (ImportAndCheckCompletable(decl)) + Complete(decl); + } + +public: + Completer(clang::ASTImporter &exporter, clang::FileID file) + : m_exporter(exporter), m_file(file) {} + + // Implements the RecursiveASTVisitor's core API. It is called on each Decl + // that the RecursiveASTVisitor encounters, and returns true if the traversal + // should continue. + bool VisitDecl(clang::Decl *decl) { + MaybeComplete(decl); + return true; + } +}; +} + +static void CompleteAllDeclContexts(clang::ASTImporter &exporter, + clang::FileID file, + clang::QualType root) { + clang::QualType canonical_type = root.getCanonicalType(); + if (clang::TagDecl *tag_decl = canonical_type->getAsTagDecl()) { + Completer(exporter, file).TraverseDecl(tag_decl); + } else if (auto interface_type = llvm::dyn_cast<ObjCInterfaceType>( + canonical_type.getTypePtr())) { + Completer(exporter, file).TraverseDecl(interface_type->getDecl()); + } else { + Completer(exporter, file).TraverseType(canonical_type); + } +} + +static clang::QualType ExportAllDeclaredTypes( + clang::ExternalASTMerger &merger, + clang::ASTContext &source, clang::FileManager &source_file_manager, + const clang::ExternalASTMerger::OriginMap &source_origin_map, + clang::FileID file, clang::QualType root) { + clang::ExternalASTMerger::ImporterSource importer_source = + { source, source_file_manager, source_origin_map }; + merger.AddSources(importer_source); + clang::ASTImporter &exporter = merger.ImporterForOrigin(source); + CompleteAllDeclContexts(exporter, file, root); + clang::QualType ret = exporter.Import(root); + merger.RemoveSources(importer_source); + return ret; +} + +TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target, + ClangASTContext &source, + TypeFromParser parser_type) { + assert (&target == m_target->GetScratchClangASTContext()); + assert ((TypeSystem*)&source == parser_type.GetTypeSystem()); + assert (source.getASTContext() == m_ast_context); + + if (m_ast_importer_sp) { + return TypeFromUser(m_ast_importer_sp->DeportType( + target.getASTContext(), source.getASTContext(), + parser_type.GetOpaqueQualType()), + &target); + } else if (m_merger_up) { + clang::FileID source_file = + source.getASTContext()->getSourceManager().getFileID( + source.getASTContext()->getTranslationUnitDecl()->getLocation()); + auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>( + m_target->GetScratchClangASTContext()); + clang::QualType exported_type = ExportAllDeclaredTypes( + scratch_ast_context->GetMergerUnchecked(), + *source.getASTContext(), *source.getFileManager(), + m_merger_up->GetOrigins(), + source_file, + clang::QualType::getFromOpaquePtr(parser_type.GetOpaqueQualType())); + return TypeFromUser(exported_type.getAsOpaquePtr(), &target); + } else { + lldbassert(!"No mechanism for deporting a type!"); + return TypeFromUser(); + } +} + bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, const ConstString &name, TypeFromParser parser_type, @@ -198,12 +328,8 @@ bool ClangExpressionDeclMap::AddPersiste if (target == nullptr) return false; - ClangASTContext *context(target->GetScratchClangASTContext()); - - TypeFromUser user_type(m_ast_importer_sp->DeportType( - context->getASTContext(), ast->getASTContext(), - parser_type.GetOpaqueQualType()), - context); + TypeFromUser user_type = + DeportType(*target->GetScratchClangASTContext(), *ast, parser_type); uint32_t offset = m_parser_vars->m_materializer->AddResultVariable( user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err); @@ -240,10 +366,7 @@ bool ClangExpressionDeclMap::AddPersiste ClangASTContext *context(target->GetScratchClangASTContext()); - TypeFromUser user_type(m_ast_importer_sp->DeportType( - context->getASTContext(), ast->getASTContext(), - parser_type.GetOpaqueQualType()), - context); + TypeFromUser user_type = DeportType(*context, *ast, parser_type); if (!user_type.GetOpaqueQualType()) { if (log) @@ -688,16 +811,18 @@ void ClangExpressionDeclMap::FindExterna } ClangASTImporter::NamespaceMapSP namespace_map = - m_ast_importer_sp->GetNamespaceMap(namespace_context); + m_ast_importer_sp + ? m_ast_importer_sp->GetNamespaceMap(namespace_context) + : ClangASTImporter::NamespaceMapSP(); + + if (!namespace_map) + return; if (log && log->GetVerbose()) log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)", current_id, static_cast<void *>(namespace_map.get()), (int)namespace_map->size()); - - if (!namespace_map) - return; - + for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end(); i != e; ++i) { @@ -775,8 +900,7 @@ void ClangExpressionDeclMap::FindExterna if (!persistent_decl) break; - Decl *parser_persistent_decl = m_ast_importer_sp->CopyDecl( - m_ast_context, scratch_ast_context, persistent_decl); + Decl *parser_persistent_decl = CopyDecl(persistent_decl); if (!parser_persistent_decl) break; @@ -1320,8 +1444,7 @@ void ClangExpressionDeclMap::FindExterna for (clang::NamedDecl *decl : decls_from_modules) { if (llvm::isa<clang::FunctionDecl>(decl)) { clang::NamedDecl *copied_decl = - llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl( - m_ast_context, &decl->getASTContext(), decl)); + llvm::cast_or_null<FunctionDecl>(CopyDecl(decl)); if (copied_decl) { context.AddNamedDecl(copied_decl); context.m_found.function_with_type_info = true; @@ -1363,9 +1486,7 @@ void ClangExpressionDeclMap::FindExterna current_id, name.GetCString()); } - 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::FunctionDecl *copied_function_decl = copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl) : nullptr; @@ -1392,9 +1513,7 @@ void ClangExpressionDeclMap::FindExterna current_id, name.GetCString()); } - 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::VarDecl *copied_var_decl = copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl) : nullptr; @@ -1753,7 +1872,9 @@ bool ClangExpressionDeclMap::ResolveUnkn Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); - ClangASTContext *scratch_ast_context = target->GetScratchClangASTContext(); + ClangASTContextForExpressions *scratch_ast_context = + static_cast<ClangASTContextForExpressions*>( + target->GetScratchClangASTContext()); for (size_t index = 0, num_entities = m_found_entities.GetSize(); index < num_entities; ++index) { @@ -1784,9 +1905,20 @@ bool ClangExpressionDeclMap::ResolveUnkn var_type.getAsOpaquePtr(), ClangASTContext::GetASTContext(&var_decl->getASTContext())); - lldb::opaque_compiler_type_t copied_type = m_ast_importer_sp->CopyType( - scratch_ast_context->getASTContext(), &var_decl->getASTContext(), - var_type.getAsOpaquePtr()); + lldb::opaque_compiler_type_t copied_type = 0; + if (m_ast_importer_sp) { + copied_type = m_ast_importer_sp->CopyType( + scratch_ast_context->getASTContext(), &var_decl->getASTContext(), + var_type.getAsOpaquePtr()); + } else if (HasMerger()) { + copied_type = CopyTypeWithMerger( + var_decl->getASTContext(), + scratch_ast_context->GetMergerUnchecked(), + var_type).getAsOpaquePtr(); + } else { + lldbassert(!"No mechanism to copy a resolved unknown type!"); + return false; + } if (!copied_type) { if (log) @@ -1896,9 +2028,7 @@ void ClangExpressionDeclMap::AddOneFunct src_function_decl->getTemplateSpecializationInfo()->getTemplate(); clang::FunctionTemplateDecl *copied_function_template = llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>( - m_ast_importer_sp->CopyDecl(m_ast_context, - src_ast->getASTContext(), - function_template)); + CopyDecl(function_template)); if (copied_function_template) { if (log) { ASTDumper ast_dumper((clang::Decl *)copied_function_template); @@ -1919,9 +2049,7 @@ void ClangExpressionDeclMap::AddOneFunct } else if (src_function_decl) { if (clang::FunctionDecl *copied_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>( - m_ast_importer_sp->CopyDecl(m_ast_context, - src_ast->getASTContext(), - src_function_decl))) { + CopyDecl(src_function_decl))) { if (log) { ASTDumper ast_dumper((clang::Decl *)copied_function_decl); Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h Thu Sep 28 13:20:25 2017 @@ -613,6 +613,23 @@ private: void AddThisType(NameSearchContext &context, TypeFromUser &type, unsigned int current_id); + //------------------------------------------------------------------ + /// Move a type out of the current ASTContext into another, but make sure to + /// export all components of the type also. + /// + /// @param[in] target + /// The ClangASTContext to move to. + /// @param[in] source + /// The ClangASTContext to move from. This is assumed to be going away. + /// @param[in] parser_type + /// The type as it appears in the source context. + /// + /// @return + /// Returns the moved type, or an empty type if there was a problem. + //------------------------------------------------------------------ + TypeFromUser DeportType(ClangASTContext &target, ClangASTContext &source, + TypeFromParser parser_type); + ClangASTContext *GetClangASTContext(); }; Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp Thu Sep 28 13:20:25 2017 @@ -526,7 +526,7 @@ ClangExpressionParser::ClangExpressionPa if (decl_map) { llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source( decl_map->CreateProxy()); - decl_map->InstallASTContext(ast_context.get()); + decl_map->InstallASTContext(*ast_context, m_compiler->getFileManager()); ast_context->setExternalSource(ast_source); } Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp Thu Sep 28 13:20:25 2017 @@ -85,6 +85,7 @@ public: void ForEachMacro(const ModuleVector &modules, std::function<bool(const std::string &)> handler) override; + clang::ExternalASTMerger::ImporterSource GetImporterSource() override; private: void ReportModuleExportsHelper(std::set<ClangModulesDeclVendor::ModuleID> &exports, @@ -109,6 +110,7 @@ private: typedef std::set<ModuleID> ImportedModuleSet; ImportedModuleMap m_imported_modules; ImportedModuleSet m_user_imported_modules; + const clang::ExternalASTMerger::OriginMap m_origin_map; }; } // anonymous namespace @@ -548,6 +550,12 @@ ClangModulesDeclVendorImpl::DoGetModule( is_inclusion_directive); } +clang::ExternalASTMerger::ImporterSource +ClangModulesDeclVendorImpl::GetImporterSource() { + return {m_compiler_instance->getASTContext(), + m_compiler_instance->getFileManager(), m_origin_map}; +} + static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer"; lldb_private::ClangModulesDeclVendor * Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp Thu Sep 28 13:20:25 2017 @@ -653,3 +653,11 @@ AppleObjCDeclVendor::FindDecls(const Con return ret; } + +clang::ExternalASTMerger::ImporterSource +AppleObjCDeclVendor::GetImporterSource() { + return {*m_ast_ctx.getASTContext(), + *m_ast_ctx.getFileManager(), + m_ast_ctx.GetOriginMap() + }; +} Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h Thu Sep 28 13:20:25 2017 @@ -30,6 +30,8 @@ public: uint32_t FindDecls(const ConstString &name, bool append, uint32_t max_matches, std::vector<clang::NamedDecl *> &decls) override; + clang::ExternalASTMerger::ImporterSource GetImporterSource() override; + friend class AppleObjCExternalASTSource; private: Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Thu Sep 28 13:20:25 2017 @@ -596,8 +596,9 @@ lldb::TypeSystemSP ClangASTContext::Crea ast_sp->SetArchitecture(fixed_arch); ast_sp->m_scratch_ast_source_ap.reset( new ClangASTSource(target->shared_from_this())); + lldbassert(ast_sp->getFileManager()); ast_sp->m_scratch_ast_source_ap->InstallASTContext( - ast_sp->getASTContext()); + *ast_sp->getASTContext(), *ast_sp->getFileManager(), true); llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source( ast_sp->m_scratch_ast_source_ap->CreateProxy()); ast_sp->SetExternalSource(proxy_ast_source); @@ -10122,3 +10123,10 @@ PersistentExpressionState * ClangASTContextForExpressions::GetPersistentExpressionState() { return m_persistent_variables.get(); } + +clang::ExternalASTMerger & +ClangASTContextForExpressions::GetMergerUnchecked() { + lldbassert(m_scratch_ast_source_ap); + return m_scratch_ast_source_ap->GetMergerUnchecked(); +} + Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=314458&r1=314457&r2=314458&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Thu Sep 28 13:20:25 2017 @@ -3645,9 +3645,11 @@ static PropertyDefinition g_experimental "This will fix symbol resolution when there are name collisions between " "ivars and local variables. " "But it can make expressions run much more slowly."}, + {"use-modern-type-lookup", OptionValue::eTypeBoolean, true, false, nullptr, + nullptr, "If true, use Clang's modern type lookup infrastructure."}, {nullptr, OptionValue::eTypeInvalid, true, 0, nullptr, nullptr, nullptr}}; -enum { ePropertyInjectLocalVars = 0 }; +enum { ePropertyInjectLocalVars = 0, ePropertyUseModernTypeLookup }; class TargetExperimentalOptionValueProperties : public OptionValueProperties { public: @@ -3758,6 +3760,18 @@ void TargetProperties::SetInjectLocalVar true); } +bool TargetProperties::GetUseModernTypeLookup() const { + const Property *exp_property = m_collection_sp->GetPropertyAtIndex( + nullptr, false, ePropertyExperimental); + OptionValueProperties *exp_values = + exp_property->GetValue()->GetAsProperties(); + if (exp_values) + return exp_values->GetPropertyAtIndexAsBoolean( + nullptr, ePropertyUseModernTypeLookup, true); + else + return true; +} + ArchSpec TargetProperties::GetDefaultArchitecture() const { OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch( nullptr, ePropertyDefaultArch); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits