diff options
Diffstat (limited to 'lldb/source/Symbol/ClangASTImporter.cpp')
| -rw-r--r-- | lldb/source/Symbol/ClangASTImporter.cpp | 240 |
1 files changed, 97 insertions, 143 deletions
diff --git a/lldb/source/Symbol/ClangASTImporter.cpp b/lldb/source/Symbol/ClangASTImporter.cpp index 92d51f79a007..8cb404231a8d 100644 --- a/lldb/source/Symbol/ClangASTImporter.cpp +++ b/lldb/source/Symbol/ClangASTImporter.cpp @@ -9,7 +9,7 @@ #include "lldb/Symbol/ClangASTImporter.h" #include "lldb/Core/Module.h" #include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangExternalASTSourceCommon.h" +#include "lldb/Symbol/ClangASTMetadata.h" #include "lldb/Symbol/ClangUtil.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" @@ -25,90 +25,46 @@ using namespace lldb_private; using namespace clang; -ClangASTMetrics::Counters ClangASTMetrics::global_counters = {0, 0, 0, 0, 0, 0}; -ClangASTMetrics::Counters ClangASTMetrics::local_counters = {0, 0, 0, 0, 0, 0}; - -void ClangASTMetrics::DumpCounters(Log *log, - ClangASTMetrics::Counters &counters) { - LLDB_LOGF(log, " Number of visible Decl queries by name : %" PRIu64, - counters.m_visible_query_count); - LLDB_LOGF(log, " Number of lexical Decl queries : %" PRIu64, - counters.m_lexical_query_count); - LLDB_LOGF(log, " Number of imports initiated by LLDB : %" PRIu64, - counters.m_lldb_import_count); - LLDB_LOGF(log, " Number of imports conducted by Clang : %" PRIu64, - counters.m_clang_import_count); - LLDB_LOGF(log, " Number of Decls completed : %" PRIu64, - counters.m_decls_completed_count); - LLDB_LOGF(log, " Number of records laid out : %" PRIu64, - counters.m_record_layout_count); -} - -void ClangASTMetrics::DumpCounters(Log *log) { - if (!log) - return; +CompilerType ClangASTImporter::CopyType(ClangASTContext &dst_ast, + const CompilerType &src_type) { + clang::ASTContext &dst_clang_ast = dst_ast.getASTContext(); - LLDB_LOGF(log, "== ClangASTMetrics output =="); - LLDB_LOGF(log, "-- Global metrics --"); - DumpCounters(log, global_counters); - LLDB_LOGF(log, "-- Local metrics --"); - DumpCounters(log, local_counters); -} + ClangASTContext *src_ast = + llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem()); + if (!src_ast) + return CompilerType(); -clang::QualType ClangASTImporter::CopyType(clang::ASTContext *dst_ast, - clang::ASTContext *src_ast, - clang::QualType type) { - ImporterDelegateSP delegate_sp(GetDelegate(dst_ast, src_ast)); + clang::ASTContext &src_clang_ast = src_ast->getASTContext(); - ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast); + clang::QualType src_qual_type = ClangUtil::GetQualType(src_type); + ImporterDelegateSP delegate_sp(GetDelegate(&dst_clang_ast, &src_clang_ast)); if (!delegate_sp) - return QualType(); + return CompilerType(); + + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, &dst_clang_ast); - llvm::Expected<QualType> ret_or_error = delegate_sp->Import(type); + llvm::Expected<QualType> ret_or_error = delegate_sp->Import(src_qual_type); if (!ret_or_error) { Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); LLDB_LOG_ERROR(log, ret_or_error.takeError(), "Couldn't import type: {0}"); - return QualType(); + return CompilerType(); } - return *ret_or_error; -} -lldb::opaque_compiler_type_t -ClangASTImporter::CopyType(clang::ASTContext *dst_ast, - clang::ASTContext *src_ast, - lldb::opaque_compiler_type_t type) { - return CopyType(dst_ast, src_ast, QualType::getFromOpaquePtr(type)) - .getAsOpaquePtr(); -} - -CompilerType ClangASTImporter::CopyType(ClangASTContext &dst_ast, - const CompilerType &src_type) { - clang::ASTContext *dst_clang_ast = dst_ast.getASTContext(); - if (dst_clang_ast) { - ClangASTContext *src_ast = - llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem()); - if (src_ast) { - clang::ASTContext *src_clang_ast = src_ast->getASTContext(); - if (src_clang_ast) { - lldb::opaque_compiler_type_t dst_clang_type = CopyType( - dst_clang_ast, src_clang_ast, src_type.GetOpaqueQualType()); + lldb::opaque_compiler_type_t dst_clang_type = ret_or_error->getAsOpaquePtr(); - if (dst_clang_type) - return CompilerType(&dst_ast, dst_clang_type); - } - } - } + if (dst_clang_type) + return CompilerType(&dst_ast, dst_clang_type); return CompilerType(); } clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast, - clang::ASTContext *src_ast, clang::Decl *decl) { ImporterDelegateSP delegate_sp; + clang::ASTContext *src_ast = &decl->getASTContext(); delegate_sp = GetDelegate(dst_ast, src_ast); ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast); @@ -151,7 +107,7 @@ private: clang::DeclContext *lexical_decl_context; }; - std::map<clang::Decl *, Backup> m_backups; + llvm::DenseMap<clang::Decl *, Backup> m_backups; void OverrideOne(clang::Decl *decl) { if (m_backups.find(decl) != m_backups.end()) { @@ -258,10 +214,8 @@ namespace { /// imported while completing the original Decls). class CompleteTagDeclsScope : public ClangASTImporter::NewDeclListener { ClangASTImporter::ImporterDelegateSP m_delegate; - // FIXME: Investigate how many decls we usually have in these sets and - // see if we can use SmallPtrSet instead here. - std::set<NamedDecl *> m_decls_to_complete; - std::set<NamedDecl *> m_decls_already_completed; + llvm::SmallVector<NamedDecl *, 32> m_decls_to_complete; + llvm::SmallPtrSet<NamedDecl *, 32> m_decls_already_completed; clang::ASTContext *m_dst_ctx; clang::ASTContext *m_src_ctx; ClangASTImporter &importer; @@ -285,10 +239,8 @@ public: // Complete all decls we collected until now. while (!m_decls_to_complete.empty()) { - NamedDecl *decl = *m_decls_to_complete.begin(); - + NamedDecl *decl = m_decls_to_complete.pop_back_val(); m_decls_already_completed.insert(decl); - m_decls_to_complete.erase(decl); // We should only complete decls coming from the source context. assert(to_context_md->m_origins[decl].ctx == m_src_ctx); @@ -333,46 +285,39 @@ public: // Check if we already completed this type. if (m_decls_already_completed.count(to_named_decl) != 0) return; - m_decls_to_complete.insert(to_named_decl); + m_decls_to_complete.push_back(to_named_decl); } }; } // namespace -lldb::opaque_compiler_type_t -ClangASTImporter::DeportType(clang::ASTContext *dst_ctx, - clang::ASTContext *src_ctx, - lldb::opaque_compiler_type_t type) { +CompilerType ClangASTImporter::DeportType(ClangASTContext &dst, + const CompilerType &src_type) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - LLDB_LOGF(log, - " [ClangASTImporter] DeportType called on (%sType*)0x%llx " - "from (ASTContext*)%p to (ASTContext*)%p", - QualType::getFromOpaquePtr(type)->getTypeClassName(), - (unsigned long long)type, static_cast<void *>(src_ctx), - static_cast<void *>(dst_ctx)); + ClangASTContext *src_ctxt = + llvm::cast<ClangASTContext>(src_type.GetTypeSystem()); + + LLDB_LOG(log, + " [ClangASTImporter] DeportType called on ({0}Type*){1:x} " + "from (ASTContext*){2:x} to (ASTContext*){3:x}", + src_type.GetTypeName(), src_type.GetOpaqueQualType(), + &src_ctxt->getASTContext(), &dst.getASTContext()); DeclContextOverride decl_context_override; - if (auto *t = QualType::getFromOpaquePtr(type)->getAs<TagType>()) + if (auto *t = ClangUtil::GetQualType(src_type)->getAs<TagType>()) decl_context_override.OverrideAllDeclsFromContainingFunction(t->getDecl()); - lldb::opaque_compiler_type_t result; - { - CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx); - result = CopyType(dst_ctx, src_ctx, type); - } - - if (!result) - return nullptr; - - return result; + CompleteTagDeclsScope complete_scope(*this, &dst.getASTContext(), + &src_ctxt->getASTContext()); + return CopyType(dst, src_type); } clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx, - clang::ASTContext *src_ctx, clang::Decl *decl) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + clang::ASTContext *src_ctx = &decl->getASTContext(); LLDB_LOGF(log, " [ClangASTImporter] DeportDecl called on (%sDecl*)%p from " "(ASTContext*)%p to (ASTContext*)%p", @@ -386,7 +331,7 @@ clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx, clang::Decl *result; { CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx); - result = CopyDecl(dst_ctx, src_ctx, decl); + result = CopyDecl(dst_ctx, decl); } if (!result) @@ -417,7 +362,7 @@ bool ClangASTImporter::CanImport(const CompilerType &type) { const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); if (cxx_record_decl) { - if (ResolveDeclOrigin(cxx_record_decl, nullptr, nullptr)) + if (GetDeclOrigin(cxx_record_decl).Valid()) return true; } } break; @@ -426,7 +371,7 @@ bool ClangASTImporter::CanImport(const CompilerType &type) { clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); if (enum_decl) { - if (ResolveDeclOrigin(enum_decl, nullptr, nullptr)) + if (GetDeclOrigin(enum_decl).Valid()) return true; } } break; @@ -441,7 +386,7 @@ bool ClangASTImporter::CanImport(const CompilerType &type) { // We currently can't complete objective C types through the newly added // ASTContext because it only supports TagDecl objects right now... if (class_interface_decl) { - if (ResolveDeclOrigin(class_interface_decl, nullptr, nullptr)) + if (GetDeclOrigin(class_interface_decl).Valid()) return true; } } @@ -493,7 +438,7 @@ bool ClangASTImporter::Import(const CompilerType &type) { const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); if (cxx_record_decl) { - if (ResolveDeclOrigin(cxx_record_decl, nullptr, nullptr)) + if (GetDeclOrigin(cxx_record_decl).Valid()) return CompleteAndFetchChildren(qual_type); } } break; @@ -502,7 +447,7 @@ bool ClangASTImporter::Import(const CompilerType &type) { clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); if (enum_decl) { - if (ResolveDeclOrigin(enum_decl, nullptr, nullptr)) + if (GetDeclOrigin(enum_decl).Valid()) return CompleteAndFetchChildren(qual_type); } } break; @@ -517,7 +462,7 @@ bool ClangASTImporter::Import(const CompilerType &type) { // We currently can't complete objective C types through the newly added // ASTContext because it only supports TagDecl objects right now... if (class_interface_decl) { - if (ResolveDeclOrigin(class_interface_decl, nullptr, nullptr)) + if (GetDeclOrigin(class_interface_decl).Valid()) return CompleteAndFetchChildren(qual_type); } } @@ -596,7 +541,7 @@ bool ClangASTImporter::LayoutRecordType( return success; } -void ClangASTImporter::InsertRecordDecl(clang::RecordDecl *decl, +void ClangASTImporter::SetRecordLayout(clang::RecordDecl *decl, const LayoutInfo &layout) { m_record_decl_to_layout_map.insert(std::make_pair(decl, layout)); } @@ -628,8 +573,6 @@ void ClangASTImporter::CompleteDecl(clang::Decl *decl) { } bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) { - ClangASTMetrics::RegisterDeclCompletion(); - DeclOrigin decl_origin = GetDeclOrigin(decl); if (!decl_origin.Valid()) @@ -651,8 +594,6 @@ bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) { bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin_decl) { - ClangASTMetrics::RegisterDeclCompletion(); - clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext(); if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl)) @@ -675,8 +616,6 @@ bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, bool ClangASTImporter::CompleteObjCInterfaceDecl( clang::ObjCInterfaceDecl *interface_decl) { - ClangASTMetrics::RegisterDeclCompletion(); - DeclOrigin decl_origin = GetDeclOrigin(interface_decl); if (!decl_origin.Valid()) @@ -729,9 +668,8 @@ bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { } } - if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) { + if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) record_decl->setHasLoadedFieldsFromExternalStorage(true); - } return true; } @@ -761,9 +699,8 @@ bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { } return true; - } else { - return false; } + return false; } return true; @@ -785,15 +722,12 @@ bool ClangASTImporter::RequireCompleteType(clang::QualType type) { if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface()) return CompleteObjCInterfaceDecl(objc_interface_decl); - else - return false; + return false; } - if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) { + if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) return RequireCompleteType(array_type->getElementType()); - } - if (const AtomicType *atomic_type = type->getAs<AtomicType>()) { + if (const AtomicType *atomic_type = type->getAs<AtomicType>()) return RequireCompleteType(atomic_type->getPointeeType()); - } return true; } @@ -801,10 +735,12 @@ bool ClangASTImporter::RequireCompleteType(clang::QualType type) { ClangASTMetadata *ClangASTImporter::GetDeclMetadata(const clang::Decl *decl) { DeclOrigin decl_origin = GetDeclOrigin(decl); - if (decl_origin.Valid()) - return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl); - else - return ClangASTContext::GetMetadata(&decl->getASTContext(), decl); + if (decl_origin.Valid()) { + ClangASTContext *ast = ClangASTContext::GetASTContext(decl_origin.ctx); + return ast->GetMetadata(decl_origin.decl); + } + ClangASTContext *ast = ClangASTContext::GetASTContext(&decl->getASTContext()); + return ast->GetMetadata(decl); } ClangASTImporter::DeclOrigin @@ -817,8 +753,7 @@ ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) { if (iter != origins.end()) return iter->second; - else - return DeclOrigin(); + return DeclOrigin(); } void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl, @@ -832,9 +767,9 @@ void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl, if (iter != origins.end()) { iter->second.decl = original_decl; iter->second.ctx = &original_decl->getASTContext(); - } else { - origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl); + return; } + origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl); } void ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl, @@ -854,8 +789,7 @@ ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) { if (iter != namespace_maps.end()) return iter->second; - else - return NamespaceMapSP(); + return NamespaceMapSP(); } void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) { @@ -936,6 +870,39 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { } } + // Check which ASTContext this declaration originally came from. + DeclOrigin origin = m_master.GetDeclOrigin(From); + // If it originally came from the target ASTContext then we can just + // pretend that the original is the one we imported. This can happen for + // example when inspecting a persistent declaration from the scratch + // ASTContext (which will provide the declaration when parsing the + // expression and then we later try to copy the declaration back to the + // scratch ASTContext to store the result). + // Without this check we would ask the ASTImporter to import a declaration + // into the same ASTContext where it came from (which doesn't make a lot of + // sense). + if (origin.Valid() && origin.ctx == &getToContext()) { + RegisterImportedDecl(From, origin.decl); + return origin.decl; + } + + // This declaration came originally from another ASTContext. Instead of + // copying our potentially incomplete 'From' Decl we instead go to the + // original ASTContext and copy the original to the target. This is not + // only faster than first completing our current decl and then copying it + // to the target, but it also prevents that indirectly copying the same + // declaration to the same target requires the ASTImporter to merge all + // the different decls that appear to come from different ASTContexts (even + // though all these different source ASTContexts just got a copy from + // one source AST). + if (origin.Valid()) { + auto R = m_master.CopyDecl(&getToContext(), origin.decl); + if (R) { + RegisterImportedDecl(From, R); + return R; + } + } + return ASTImporter::ImportImpl(From); } @@ -1037,8 +1004,6 @@ void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo( void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, clang::Decl *to) { - ClangASTMetrics::RegisterClangImport(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // Some decls shouldn't be tracked here because they were not created by @@ -1196,16 +1161,5 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, clang::Decl * ClangASTImporter::ASTImporterDelegate::GetOriginalDecl(clang::Decl *To) { - ASTContextMetadataSP to_context_md = - m_master.GetContextMetadata(&To->getASTContext()); - - if (!to_context_md) - return nullptr; - - OriginMap::iterator iter = to_context_md->m_origins.find(To); - - if (iter == to_context_md->m_origins.end()) - return nullptr; - - return const_cast<clang::Decl *>(iter->second.decl); + return m_master.GetDeclOrigin(To).decl; } |
