diff options
Diffstat (limited to 'source/Symbol/ClangASTImporter.cpp')
-rw-r--r-- | source/Symbol/ClangASTImporter.cpp | 250 |
1 files changed, 170 insertions, 80 deletions
diff --git a/source/Symbol/ClangASTImporter.cpp b/source/Symbol/ClangASTImporter.cpp index 621441449c208..32d0c47693b0e 100644 --- a/source/Symbol/ClangASTImporter.cpp +++ b/source/Symbol/ClangASTImporter.cpp @@ -1,9 +1,8 @@ //===-- ClangASTImporter.cpp ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -17,8 +16,12 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/Sema/Lookup.h" +#include "clang/Sema/Sema.h" #include "llvm/Support/raw_ostream.h" +#include <memory> + using namespace lldb_private; using namespace clang; @@ -55,12 +58,22 @@ void ClangASTMetrics::DumpCounters(Log *log) { clang::QualType ClangASTImporter::CopyType(clang::ASTContext *dst_ast, clang::ASTContext *src_ast, clang::QualType type) { - MinionSP minion_sp(GetMinion(dst_ast, src_ast)); + ImporterDelegateSP delegate_sp(GetDelegate(dst_ast, src_ast)); - if (minion_sp) - return minion_sp->Import(type); + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast); - return QualType(); + if (!delegate_sp) + return QualType(); + + llvm::Expected<QualType> ret_or_error = delegate_sp->Import(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 *ret_or_error; } lldb::opaque_compiler_type_t @@ -94,38 +107,39 @@ CompilerType ClangASTImporter::CopyType(ClangASTContext &dst_ast, clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast, clang::ASTContext *src_ast, clang::Decl *decl) { - MinionSP minion_sp; + ImporterDelegateSP delegate_sp; - minion_sp = GetMinion(dst_ast, src_ast); + delegate_sp = GetDelegate(dst_ast, src_ast); - if (minion_sp) { - clang::Decl *result = minion_sp->Import(decl); + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast); - if (!result) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + if (!delegate_sp) + return nullptr; - if (log) { - lldb::user_id_t user_id = LLDB_INVALID_UID; - ClangASTMetadata *metadata = GetDeclMetadata(decl); - if (metadata) - user_id = metadata->GetUserID(); - - if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl)) - log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s " - "'%s', metadata 0x%" PRIx64, - decl->getDeclKindName(), - named_decl->getNameAsString().c_str(), user_id); - else - log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, " - "metadata 0x%" PRIx64, - decl->getDeclKindName(), user_id); - } + llvm::Expected<clang::Decl *> result = delegate_sp->Import(decl); + if (!result) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + LLDB_LOG_ERROR(log, result.takeError(), "Couldn't import decl: {0}"); + if (log) { + lldb::user_id_t user_id = LLDB_INVALID_UID; + ClangASTMetadata *metadata = GetDeclMetadata(decl); + if (metadata) + user_id = metadata->GetUserID(); + + if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl)) + log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s " + "'%s', metadata 0x%" PRIx64, + decl->getDeclKindName(), + named_decl->getNameAsString().c_str(), user_id); + else + log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, " + "metadata 0x%" PRIx64, + decl->getDeclKindName(), user_id); } - - return result; + return nullptr; } - return nullptr; + return *result; } class DeclContextOverride { @@ -247,9 +261,9 @@ ClangASTImporter::DeportType(clang::ASTContext *dst_ctx, (unsigned long long)type, static_cast<void *>(src_ctx), static_cast<void *>(dst_ctx)); - MinionSP minion_sp(GetMinion(dst_ctx, src_ctx)); + ImporterDelegateSP delegate_sp(GetDelegate(dst_ctx, src_ctx)); - if (!minion_sp) + if (!delegate_sp) return nullptr; std::set<NamedDecl *> decls_to_deport; @@ -263,11 +277,11 @@ ClangASTImporter::DeportType(clang::ASTContext *dst_ctx, tag_type->getDecl()); } - minion_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported); + delegate_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported); lldb::opaque_compiler_type_t result = CopyType(dst_ctx, src_ctx, type); - minion_sp->ExecuteDeportWorkQueues(); + delegate_sp->ExecuteDeportWorkQueues(); if (!result) return nullptr; @@ -286,9 +300,9 @@ clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx, decl->getDeclKindName(), static_cast<void *>(decl), static_cast<void *>(src_ctx), static_cast<void *>(dst_ctx)); - MinionSP minion_sp(GetMinion(dst_ctx, src_ctx)); + ImporterDelegateSP delegate_sp(GetDelegate(dst_ctx, src_ctx)); - if (!minion_sp) + if (!delegate_sp) return nullptr; std::set<NamedDecl *> decls_to_deport; @@ -298,11 +312,11 @@ clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx, decl_context_override.OverrideAllDeclsFromContainingFunction(decl); - minion_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported); + delegate_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported); clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl); - minion_sp->ExecuteDeportWorkQueues(); + delegate_sp->ExecuteDeportWorkQueues(); if (!result) return nullptr; @@ -332,7 +346,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, NULL, NULL)) + if (ResolveDeclOrigin(cxx_record_decl, nullptr, nullptr)) return true; } } break; @@ -341,7 +355,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, NULL, NULL)) + if (ResolveDeclOrigin(enum_decl, nullptr, nullptr)) return true; } } break; @@ -356,7 +370,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, NULL, NULL)) + if (ResolveDeclOrigin(class_interface_decl, nullptr, nullptr)) return true; } } @@ -408,7 +422,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, NULL, NULL)) + if (ResolveDeclOrigin(cxx_record_decl, nullptr, nullptr)) return CompleteAndFetchChildren(qual_type); } } break; @@ -417,7 +431,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, NULL, NULL)) + if (ResolveDeclOrigin(enum_decl, nullptr, nullptr)) return CompleteAndFetchChildren(qual_type); } } break; @@ -432,7 +446,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, NULL, NULL)) + if (ResolveDeclOrigin(class_interface_decl, nullptr, nullptr)) return CompleteAndFetchChildren(qual_type); } } @@ -554,10 +568,13 @@ bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) { if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) return false; - MinionSP minion_sp(GetMinion(&decl->getASTContext(), decl_origin.ctx)); + ImporterDelegateSP delegate_sp( + GetDelegate(&decl->getASTContext(), decl_origin.ctx)); - if (minion_sp) - minion_sp->ImportDefinitionTo(decl, decl_origin.decl); + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, + &decl->getASTContext()); + if (delegate_sp) + delegate_sp->ImportDefinitionTo(decl, decl_origin.decl); return true; } @@ -571,10 +588,11 @@ bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl)) return false; - MinionSP minion_sp(GetMinion(&decl->getASTContext(), origin_ast_ctx)); + ImporterDelegateSP delegate_sp( + GetDelegate(&decl->getASTContext(), origin_ast_ctx)); - if (minion_sp) - minion_sp->ImportDefinitionTo(decl, origin_decl); + if (delegate_sp) + delegate_sp->ImportDefinitionTo(decl, origin_decl); ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); @@ -597,11 +615,11 @@ bool ClangASTImporter::CompleteObjCInterfaceDecl( if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) return false; - MinionSP minion_sp( - GetMinion(&interface_decl->getASTContext(), decl_origin.ctx)); + ImporterDelegateSP delegate_sp( + GetDelegate(&interface_decl->getASTContext(), decl_origin.ctx)); - if (minion_sp) - minion_sp->ImportDefinitionTo(interface_decl, decl_origin.decl); + if (delegate_sp) + delegate_sp->ImportDefinitionTo(interface_decl, decl_origin.decl); if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass()) RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0)); @@ -613,6 +631,8 @@ bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { if (!RequireCompleteType(type)) return false; + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + if (const TagType *tag_type = type->getAs<TagType>()) { TagDecl *tag_decl = tag_type->getDecl(); @@ -621,12 +641,22 @@ bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { if (!decl_origin.Valid()) return false; - MinionSP minion_sp(GetMinion(&tag_decl->getASTContext(), decl_origin.ctx)); + ImporterDelegateSP delegate_sp( + GetDelegate(&tag_decl->getASTContext(), decl_origin.ctx)); + + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, + &tag_decl->getASTContext()); TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl); for (Decl *origin_child_decl : origin_tag_decl->decls()) { - minion_sp->Import(origin_child_decl); + llvm::Expected<Decl *> imported_or_err = + delegate_sp->Import(origin_child_decl); + if (!imported_or_err) { + LLDB_LOG_ERROR(log, imported_or_err.takeError(), + "Couldn't import decl: {0}"); + return false; + } } if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) { @@ -644,14 +674,20 @@ bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { if (!decl_origin.Valid()) return false; - MinionSP minion_sp( - GetMinion(&objc_interface_decl->getASTContext(), decl_origin.ctx)); + ImporterDelegateSP delegate_sp( + GetDelegate(&objc_interface_decl->getASTContext(), decl_origin.ctx)); ObjCInterfaceDecl *origin_interface_decl = llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl); for (Decl *origin_child_decl : origin_interface_decl->decls()) { - minion_sp->Import(origin_child_decl); + llvm::Expected<Decl *> imported_or_err = + delegate_sp->Import(origin_child_decl); + if (!imported_or_err) { + LLDB_LOG_ERROR(log, imported_or_err.takeError(), + "Couldn't import decl: {0}"); + return false; + } } return true; @@ -766,7 +802,7 @@ void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) { NamespaceMapSP new_map; - new_map.reset(new NamespaceMap); + new_map = std::make_shared<NamespaceMap>(); if (context_md->m_map_completer) { std::string namespace_string = decl->getDeclName().getAsString(); @@ -802,7 +838,7 @@ void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast, if (!md) return; - md->m_minions.erase(src_ast); + md->m_delegates.erase(src_ast); for (OriginMap::iterator iter = md->m_origins.begin(); iter != md->m_origins.end();) { @@ -815,7 +851,25 @@ void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast, ClangASTImporter::MapCompleter::~MapCompleter() { return; } -void ClangASTImporter::Minion::InitDeportWorkQueues( +llvm::Expected<Decl *> +ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { + if (m_std_handler) { + llvm::Optional<Decl *> D = m_std_handler->Import(From); + if (D) { + // Make sure we don't use this decl later to map it back to it's original + // decl. The decl the CxxModuleHandler created has nothing to do with + // the one from debug info, and linking those two would just cause the + // ASTImporter to try 'updating' the module decl with the minimal one from + // the debug info. + m_decls_to_ignore.insert(*D); + return *D; + } + } + + return ASTImporter::ImportImpl(From); +} + +void ClangASTImporter::ASTImporterDelegate::InitDeportWorkQueues( std::set<clang::NamedDecl *> *decls_to_deport, std::set<clang::NamedDecl *> *decls_already_deported) { assert(!m_decls_to_deport); @@ -825,7 +879,7 @@ void ClangASTImporter::Minion::InitDeportWorkQueues( m_decls_already_deported = decls_already_deported; } -void ClangASTImporter::Minion::ExecuteDeportWorkQueues() { +void ClangASTImporter::ASTImporterDelegate::ExecuteDeportWorkQueues() { assert(m_decls_to_deport); assert(m_decls_already_deported); @@ -872,8 +926,8 @@ void ClangASTImporter::Minion::ExecuteDeportWorkQueues() { m_decls_already_deported = nullptr; } -void ClangASTImporter::Minion::ImportDefinitionTo(clang::Decl *to, - clang::Decl *from) { +void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo( + clang::Decl *to, clang::Decl *from) { ASTImporter::Imported(from, to); /* @@ -886,11 +940,39 @@ void ClangASTImporter::Minion::ImportDefinitionTo(clang::Decl *to, to_cxx_record->startDefinition(); */ - ImportDefinition(from); + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + + if (llvm::Error err = ImportDefinition(from)) { + LLDB_LOG_ERROR(log, std::move(err), + "[ClangASTImporter] Error during importing definition: {0}"); + return; + } if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to)) { if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from)) { to_tag->setCompleteDefinition(from_tag->isCompleteDefinition()); + + if (Log *log_ast = + lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST)) { + std::string name_string; + if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) { + llvm::raw_string_ostream name_stream(name_string); + from_named_decl->printName(name_stream); + name_stream.flush(); + } + LLDB_LOG(log_ast, "==== [ClangASTImporter][TUDecl: {0}] Imported " + "({1}Decl*){2}, named {3} (from " + "(Decl*){4})", + static_cast<void *>(to->getTranslationUnitDecl()), + from->getDeclKindName(), static_cast<void *>(to), name_string, + static_cast<void *>(from)); + + // Log the AST of the TU. + std::string ast_string; + llvm::raw_string_ostream ast_stream(ast_string); + to->getTranslationUnitDecl()->dump(ast_stream); + LLDB_LOG(log_ast, "{0}", ast_string); + } } } @@ -916,13 +998,17 @@ void ClangASTImporter::Minion::ImportDefinitionTo(clang::Decl *to, if (!from_superclass) break; - Decl *imported_from_superclass_decl = Import(from_superclass); + llvm::Expected<Decl *> imported_from_superclass_decl = + Import(from_superclass); - if (!imported_from_superclass_decl) + if (!imported_from_superclass_decl) { + LLDB_LOG_ERROR(log, imported_from_superclass_decl.takeError(), + "Couldn't import decl: {0}"); break; + } ObjCInterfaceDecl *imported_from_superclass = - dyn_cast<ObjCInterfaceDecl>(imported_from_superclass_decl); + dyn_cast<ObjCInterfaceDecl>(*imported_from_superclass_decl); if (!imported_from_superclass) break; @@ -932,16 +1018,21 @@ void ClangASTImporter::Minion::ImportDefinitionTo(clang::Decl *to, to_objc_interface->setSuperClass(m_source_ctx->getTrivialTypeSourceInfo( m_source_ctx->getObjCInterfaceType(imported_from_superclass))); - } while (0); + } while (false); } } -clang::Decl *ClangASTImporter::Minion::Imported(clang::Decl *from, - clang::Decl *to) { +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 + // copying 'from' to 'to'. Just exit early for those. + if (m_decls_to_ignore.find(to) != m_decls_to_ignore.end()) + return clang::ASTImporter::Imported(from, to); + lldb::user_id_t user_id = LLDB_INVALID_UID; ClangASTMetadata *metadata = m_master.GetDeclMetadata(from); if (metadata) @@ -983,8 +1074,8 @@ clang::Decl *ClangASTImporter::Minion::Imported(clang::Decl *from, to_context_md->m_origins[to] = origin_iter->second; } - MinionSP direct_completer = - m_master.GetMinion(&to->getASTContext(), origin_iter->second.ctx); + ImporterDelegateSP direct_completer = + m_master.GetDelegate(&to->getASTContext(), origin_iter->second.ctx); if (direct_completer.get() != this) direct_completer->ASTImporter::Imported(origin_iter->second.decl, to); @@ -1095,11 +1186,10 @@ clang::Decl *ClangASTImporter::Minion::Imported(clang::Decl *from, } } } - - return clang::ASTImporter::Imported(from, to); } -clang::Decl *ClangASTImporter::Minion::GetOriginalDecl(clang::Decl *To) { +clang::Decl * +ClangASTImporter::ASTImporterDelegate::GetOriginalDecl(clang::Decl *To) { ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&To->getASTContext()); |