diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:12:36 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:12:36 +0000 |
commit | ef5d0b5e97ec8e6fa395d377b09aa7755e345b4f (patch) | |
tree | 27916256fdeeb57d10d2f3d6948be5d71a703215 /source/Plugins/ExpressionParser | |
parent | 76e0736e7fcfeb179779e49c05604464b1ccd704 (diff) |
Notes
Diffstat (limited to 'source/Plugins/ExpressionParser')
11 files changed, 581 insertions, 202 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); diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/source/Plugins/ExpressionParser/Clang/ClangASTSource.h index 6362f04cf488..6f72ad92dc8c 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.h +++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.h @@ -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,6 +372,89 @@ protected: //------------------------------------------------------------------ CompilerType GuardedCopyType(const CompilerType &src_type); +public: + //------------------------------------------------------------------ + /// Returns true if a name should be ignored by name lookup. + /// + /// @param[in] name + /// The name to be considered. + /// + /// @param[in] ignore_all_dollar_nmmes + /// True if $-names of all sorts should be ignored. + /// + /// @return + /// True if the name is one of a class of names that are ignored by + /// global lookup for performance reasons. + //------------------------------------------------------------------ + 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; @@ -385,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; }; diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index 8fde41052192..07ff2e97aac7 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -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 ClangExpressionDeclMap::GetTargetInfo() { 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(0 && "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::AddPersistentVariable(const NamedDecl *decl, 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::AddPersistentVariable(const NamedDecl *decl, 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::FindExternalVisibleDecls( } 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) { @@ -739,16 +864,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( SymbolContextList sc_list; const ConstString name(context.m_decl_name.getAsString().c_str()); - - const char *name_unique_cstr = name.GetCString(); - - if (name_unique_cstr == NULL) - return; - - static ConstString id_name("id"); - static ConstString Class_name("Class"); - - if (name == id_name || name == Class_name) + if (IgnoreName(name, false)) return; // Only look for functions by name out in our symbols if the function @@ -784,8 +900,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( 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; @@ -809,7 +924,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( } while (0); } - if (name_unique_cstr[0] == '$' && !namespace_decl) { + if (name.GetCString()[0] == '$' && !namespace_decl) { static ConstString g_lldb_class_name("$__lldb_class"); if (name == g_lldb_class_name) { @@ -1041,7 +1156,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (ast) { clang::NamespaceDecl *namespace_decl = ClangASTContext::GetUniqueNamespaceDeclaration( - m_ast_context, name_unique_cstr, nullptr); + m_ast_context, name.GetCString(), nullptr); if (namespace_decl) { context.AddNamedDecl(namespace_decl); clang::DeclContext *clang_decl_ctx = @@ -1056,7 +1171,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( } // any other $__lldb names should be weeded out now - if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1)) + if (name.GetStringRef().startswith("$__lldb")) return; ExpressionVariableSP pvar_sp( @@ -1329,8 +1444,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( 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; @@ -1372,9 +1486,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( 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; @@ -1401,9 +1513,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( 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; @@ -1430,17 +1540,17 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( // a generic // data symbol, and -- if it is found -- treat it as a variable. Status error; - + const Symbol *data_symbol = m_parser_vars->m_sym_ctx.FindBestGlobalDataSymbol(name, error); - + if (!error.Success()) { const unsigned diag_id = m_ast_context->getDiagnostics().getCustomDiagID( clang::DiagnosticsEngine::Level::Error, "%0"); m_ast_context->getDiagnostics().Report(diag_id) << error.AsCString(); } - + if (data_symbol) { std::string warning("got name from symbols: "); warning.append(name.AsCString()); @@ -1455,49 +1565,6 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( } } -// static opaque_compiler_type_t -// MaybePromoteToBlockPointerType -//( -// ASTContext *ast_context, -// opaque_compiler_type_t candidate_type -//) -//{ -// if (!candidate_type) -// return candidate_type; -// -// QualType candidate_qual_type = QualType::getFromOpaquePtr(candidate_type); -// -// const PointerType *candidate_pointer_type = -// dyn_cast<PointerType>(candidate_qual_type); -// -// if (!candidate_pointer_type) -// return candidate_type; -// -// QualType pointee_qual_type = candidate_pointer_type->getPointeeType(); -// -// const RecordType *pointee_record_type = -// dyn_cast<RecordType>(pointee_qual_type); -// -// if (!pointee_record_type) -// return candidate_type; -// -// RecordDecl *pointee_record_decl = pointee_record_type->getDecl(); -// -// if (!pointee_record_decl->isRecord()) -// return candidate_type; -// -// if -// (!pointee_record_decl->getName().startswith(llvm::StringRef("__block_literal_"))) -// return candidate_type; -// -// QualType generic_function_type = -// ast_context->getFunctionNoProtoType(ast_context->UnknownAnyTy); -// QualType block_pointer_type = -// ast_context->getBlockPointerType(generic_function_type); -// -// return block_pointer_type.getAsOpaquePtr(); -//} - bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, lldb_private::Value &var_location, TypeFromUser *user_type, @@ -1537,7 +1604,6 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, "There is no AST context for the current execution context"); return false; } - // var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type); DWARFExpression &var_location_expr = var->LocationExpression(); @@ -1762,7 +1828,9 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() { 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) { @@ -1793,9 +1861,20 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() { 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(0 && "No mechanism to copy a resolved unknown type!"); + return false; + } if (!copied_type) { if (log) @@ -1892,8 +1971,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, if (!extern_c) { TypeSystem *type_system = function->GetDeclContext().GetTypeSystem(); - if (ClangASTContext *src_ast = - llvm::dyn_cast<ClangASTContext>(type_system)) { + if (llvm::isa<ClangASTContext>(type_system)) { clang::DeclContext *src_decl_context = (clang::DeclContext *)function->GetDeclContext() .GetOpaqueDeclContext(); @@ -1905,9 +1983,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, 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); @@ -1928,9 +2004,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, } 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); diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h index e8a9ba6862db..d163ad4f7e29 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -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(); }; diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index 4e20be79f68b..d9e53074b3fb 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -66,7 +66,6 @@ #include "ClangPersistentVariables.h" #include "IRForTarget.h" -#include "lldb/Core/ArchSpec.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/Module.h" @@ -351,7 +350,6 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope, LLDB_LOGV(log, "LinkerVersion: '{0}'", opts.LinkerVersion); StringList::LogDump(log, opts.FeaturesAsWritten, "FeaturesAsWritten"); StringList::LogDump(log, opts.Features, "Features"); - StringList::LogDump(log, opts.Reciprocals, "Reciprocals"); } // 4. Create and install the target on the compiler. @@ -391,6 +389,14 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope, // FIXME: the following language option is a temporary workaround, // to "ask for ObjC, get ObjC++" (see comment above). m_compiler->getLangOpts().CPlusPlus = true; + + // Clang now sets as default C++14 as the default standard (with + // GNU extensions), so we do the same here to avoid mismatches that + // cause compiler error when evaluating expressions (e.g. nullptr + // not found as it's a C++11 feature). Currently lldb evaluates + // C++14 as C++11 (see two lines below) so we decide to be consistent + // with that, but this could be re-evaluated in the future. + m_compiler->getLangOpts().CPlusPlus11 = true; break; case lldb::eLanguageTypeC_plus_plus: case lldb::eLanguageTypeC_plus_plus_11: @@ -526,7 +532,7 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope, 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); } diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h index 3e6a109a4af3..41f290f2e127 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h @@ -10,10 +10,10 @@ #ifndef liblldb_ClangExpressionParser_h_ #define liblldb_ClangExpressionParser_h_ -#include "lldb/Core/ArchSpec.h" #include "lldb/Core/ClangForward.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/ExpressionParser.h" +#include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-public.h" diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h index 56d1d8412f78..0596d8fde7b9 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h +++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h @@ -17,7 +17,6 @@ #include "ClangExpressionHelper.h" #include "lldb/Core/Address.h" -#include "lldb/Core/ArchSpec.h" #include "lldb/Core/ClangForward.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectList.h" diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp index bce0eaf6d57e..b42ceb9afee8 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp @@ -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(clang::ModuleIdPath path, 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 * diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h index fbabcd736865..23769ccfb0c0 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h +++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h @@ -10,7 +10,6 @@ #ifndef liblldb_ClangModulesDeclVendor_h #define liblldb_ClangModulesDeclVendor_h -#include "lldb/Core/ArchSpec.h" #include "lldb/Core/ClangForward.h" #include "lldb/Symbol/DeclVendor.h" #include "lldb/Target/Platform.h" diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index 2a6261a6df4d..18fe8b49227b 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -347,7 +347,6 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, // ApplyObjcCastHack(m_expr_text); - // ApplyUnicharHack(m_expr_text); std::string prefix = m_expr_prefix; diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp index 065e5db4c9f8..0f2aeef27e57 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp @@ -138,15 +138,6 @@ bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager, } } -#if 0 - // jingham: look here - StreamFile logfile ("/tmp/exprs.txt", "a"); - logfile.Printf ("0x%16.16" PRIx64 ": func = %s, source =\n%s\n", - m_jit_start_addr, - m_function_name.c_str(), - m_function_text.c_str()); -#endif - DeclMap()->DidParse(); ResetDeclMap(); |