summaryrefslogtreecommitdiff
path: root/source/Symbol/ClangASTImporter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Symbol/ClangASTImporter.cpp')
-rw-r--r--source/Symbol/ClangASTImporter.cpp250
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());