[Lldb-commits] [lldb] r314458 - [Expression parser] Setting to enable use of ExternalASTMerger
Sean Callanan via lldb-commits
lldb-commits at lists.llvm.org
Thu Sep 28 13:20:25 PDT 2017
Author: spyffe
Date: Thu Sep 28 13:20:25 2017
New Revision: 314458
URL: http://llvm.org/viewvc/llvm-project?rev=314458&view=rev
Log:
[Expression parser] Setting to enable use of ExternalASTMerger
This setting can be enabled like this at the target level:
(lldb) settings set target.experimental.use-modern-type-lookup true
This causes several new behaviors in the Clang expression parser:
- It completely disables use of ClangASTImporter. None are created
at all, and all users of it are now conditionalized on its
presence.
- It instead constructs a per-expression ExternalASTMerger, which
exists inside Clang and contains much of the type completion
logic that hitherto lived in ExternalASTSource,
ClangExpressionDeclMap, and ClangASTImporter.
- The expression parser uses this Merger as a backend for copying
and completing types.
- It also constructs a persistent ExternalASTMerger which is
connected to the Target's persistent AST context.
This is a major chunk of LLDB functionality moved into Clang. It
can be tested in two ways:
1. For an individual debug session, enable the setting before
running a target.
2. For the testsuite, change the option to be default-true. This
is done in Target.cpp's g_experimental_properties. The
testsuite is not yet clean with this, so I have not committed
that switch.
I have filed a Bugzilla for extending the testsuite to allow
custom settings for all tests:
https://bugs.llvm.org/show_bug.cgi?id=34771
I have also filed a Bugzilla for fixing the remaining testsuite
failures with this setting enabled:
https://bugs.llvm.org/show_bug.cgi?id=34772
Modified:
lldb/trunk/include/lldb/Symbol/ClangASTContext.h
lldb/trunk/include/lldb/Symbol/DeclVendor.h
lldb/trunk/include/lldb/Target/Target.h
lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
lldb/trunk/source/Symbol/ClangASTContext.cpp
lldb/trunk/source/Target/Target.cpp
Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Thu Sep 28 13:20:25 2017
@@ -25,6 +25,7 @@
// Other libraries and framework includes
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ExternalASTMerger.h"
#include "clang/AST/TemplateBase.h"
#include "llvm/ADT/SmallVector.h"
@@ -964,7 +965,10 @@ public:
clang::DeclarationName
GetDeclarationName(const char *name, const CompilerType &function_clang_type);
-
+
+ virtual const clang::ExternalASTMerger::OriginMap &GetOriginMap() {
+ return m_origins;
+ }
protected:
//------------------------------------------------------------------
// Classes that inherit from ClangASTContext can see and modify these
@@ -990,6 +994,7 @@ protected:
CompleteTagDeclCallback m_callback_tag_decl;
CompleteObjCInterfaceDeclCallback m_callback_objc_decl;
void * m_callback_baton;
+ clang::ExternalASTMerger::OriginMap m_origins;
uint32_t m_pointer_byte_size;
bool m_ast_owned;
bool m_can_evaluate_expressions;
@@ -1023,7 +1028,12 @@ public:
const char *name) override;
PersistentExpressionState *GetPersistentExpressionState() override;
-
+
+ clang::ExternalASTMerger &GetMergerUnchecked();
+
+ const clang::ExternalASTMerger::OriginMap &GetOriginMap() override {
+ return GetMergerUnchecked().GetOrigins();
+ }
private:
lldb::TargetWP m_target_wp;
lldb::ClangPersistentVariablesUP m_persistent_variables; ///< These are the
Modified: lldb/trunk/include/lldb/Symbol/DeclVendor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/DeclVendor.h?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/DeclVendor.h (original)
+++ lldb/trunk/include/lldb/Symbol/DeclVendor.h Thu Sep 28 13:20:25 2017
@@ -13,6 +13,8 @@
#include "lldb/Core/ClangForward.h"
#include "lldb/lldb-defines.h"
+#include "clang/AST/ExternalASTMerger.h"
+
#include <vector>
namespace lldb_private {
@@ -53,6 +55,15 @@ public:
uint32_t max_matches,
std::vector<clang::NamedDecl *> &decls) = 0;
+ //------------------------------------------------------------------
+ /// Interface for ExternalASTMerger. Returns an ImporterSource
+ /// allowing type completion.
+ ///
+ /// @return
+ /// An ImporterSource for this DeclVendor.
+ //------------------------------------------------------------------
+ virtual clang::ExternalASTMerger::ImporterSource GetImporterSource() = 0;
+
private:
//------------------------------------------------------------------
// For DeclVendor only
Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Thu Sep 28 13:20:25 2017
@@ -196,6 +196,8 @@ public:
void SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b);
+ bool GetUseModernTypeLookup() const;
+
private:
//------------------------------------------------------------------
// Callbacks for m_launch_info.
Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp Thu Sep 28 13:20:25 2017
@@ -51,8 +51,94 @@ private:
};
}
+ClangASTSource::ClangASTSource(const lldb::TargetSP &target)
+ : m_import_in_progress(false), m_lookups_enabled(false), m_target(target),
+ m_ast_context(NULL), m_active_lexical_decls(), m_active_lookups() {
+ if (!target->GetUseModernTypeLookup()) {
+ m_ast_importer_sp = m_target->GetClangASTImporter();
+ }
+}
+
+void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context,
+ clang::FileManager &file_manager,
+ bool is_shared_context) {
+ m_ast_context = &ast_context;
+ m_file_manager = &file_manager;
+ if (m_target->GetUseModernTypeLookup()) {
+ // Configure the ExternalASTMerger. The merger needs to be able to import
+ // types from any source that we would do lookups in, which includes the
+ // persistent AST context as well as the modules and Objective-C runtime
+ // AST contexts.
+
+ lldbassert(!m_merger_up);
+ clang::ExternalASTMerger::ImporterTarget target = {ast_context,
+ file_manager};
+ std::vector<clang::ExternalASTMerger::ImporterSource> sources;
+ for (lldb::ModuleSP module_sp : m_target->GetImages().Modules()) {
+ if (auto *module_ast_ctx = llvm::cast_or_null<ClangASTContext>(
+ module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC))) {
+ lldbassert(module_ast_ctx->getASTContext());
+ lldbassert(module_ast_ctx->getFileManager());
+ sources.push_back({*module_ast_ctx->getASTContext(),
+ *module_ast_ctx->getFileManager(),
+ module_ast_ctx->GetOriginMap()
+ });
+ }
+ }
+
+ do {
+ lldb::ProcessSP process(m_target->GetProcessSP());
+
+ if (!process)
+ break;
+
+ ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+
+ if (!language_runtime)
+ break;
+
+ DeclVendor *runtime_decl_vendor = language_runtime->GetDeclVendor();
+
+ if (!runtime_decl_vendor)
+ break;
+
+ sources.push_back(runtime_decl_vendor->GetImporterSource());
+ } while (0);
+
+ do {
+ DeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor();
+
+ if (!modules_decl_vendor)
+ break;
+
+ sources.push_back(modules_decl_vendor->GetImporterSource());
+ } while (0);
+
+ if (!is_shared_context) {
+ // Update the scratch AST context's merger to reflect any new sources we
+ // might have come across since the last time an expression was parsed.
+
+ auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>(
+ m_target->GetScratchClangASTContext());
+
+ scratch_ast_context->GetMergerUnchecked().AddSources(sources);
+
+ sources.push_back({*scratch_ast_context->getASTContext(),
+ *scratch_ast_context->getFileManager(),
+ scratch_ast_context->GetOriginMap()});
+ } while (0);
+
+ m_merger_up =
+ llvm::make_unique<clang::ExternalASTMerger>(target, sources);
+ } else {
+ m_ast_importer_sp->InstallMapCompleter(&ast_context, *this);
+ }
+}
+
ClangASTSource::~ClangASTSource() {
- m_ast_importer_sp->ForgetDestination(m_ast_context);
+ if (m_ast_importer_sp)
+ m_ast_importer_sp->ForgetDestination(m_ast_context);
// We are in the process of destruction, don't create clang ast context on
// demand
@@ -69,7 +155,7 @@ ClangASTSource::~ClangASTSource() {
if (!scratch_ast_context)
return;
- if (m_ast_context != scratch_ast_context)
+ if (m_ast_context != scratch_ast_context && m_ast_importer_sp)
m_ast_importer_sp->ForgetSource(scratch_ast_context, m_ast_context);
}
@@ -203,6 +289,13 @@ void ClangASTSource::CompleteType(TagDec
m_active_lexical_decls.insert(tag_decl);
ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
+ if (!m_ast_importer_sp) {
+ if (HasMerger()) {
+ GetMergerUnchecked().CompleteType(tag_decl);
+ }
+ return;
+ }
+
if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) {
// We couldn't complete the type. Maybe there's a definition
// somewhere else that can be completed.
@@ -336,6 +429,22 @@ void ClangASTSource::CompleteType(clang:
ASTDumper dumper((Decl *)interface_decl);
dumper.ToLog(log, " [COID] ");
}
+
+ if (!m_ast_importer_sp) {
+ if (HasMerger()) {
+ ObjCInterfaceDecl *complete_iface_decl =
+ GetCompleteObjCInterface(interface_decl);
+
+ if (complete_iface_decl && (complete_iface_decl != interface_decl)) {
+ m_merger_up->ForceRecordOrigin(interface_decl, {complete_iface_decl, &complete_iface_decl->getASTContext()});
+ }
+
+ GetMergerUnchecked().CompleteType(interface_decl);
+ } else {
+ lldbassert(!"No mechanism for completing a type!");
+ }
+ return;
+ }
Decl *original_decl = NULL;
ASTContext *original_ctx = NULL;
@@ -367,7 +476,7 @@ void ClangASTSource::CompleteType(clang:
}
clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface(
- clang::ObjCInterfaceDecl *interface_decl) {
+ const clang::ObjCInterfaceDecl *interface_decl) {
lldb::ProcessSP process(m_target->GetProcessSP());
if (!process)
@@ -411,6 +520,22 @@ void ClangASTSource::FindExternalLexical
const DeclContext *decl_context,
llvm::function_ref<bool(Decl::Kind)> predicate,
llvm::SmallVectorImpl<Decl *> &decls) {
+
+ if (HasMerger()) {
+ if (auto *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_context)) {
+ ObjCInterfaceDecl *complete_iface_decl =
+ GetCompleteObjCInterface(interface_decl);
+
+ if (complete_iface_decl && (complete_iface_decl != interface_decl)) {
+ m_merger_up->ForceRecordOrigin(interface_decl, {complete_iface_decl, &complete_iface_decl->getASTContext()});
+ }
+ }
+ return GetMergerUnchecked().FindExternalLexicalDecls(decl_context,
+ predicate,
+ decls);
+ } else if (!m_ast_importer_sp)
+ return;
+
ClangASTMetrics::RegisterLexicalQuery();
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -507,8 +632,7 @@ void ClangASTSource::FindExternalLexical
decl->getDeclKindName(), ast_dumper.GetCString());
}
- Decl *copied_decl =
- m_ast_importer_sp->CopyDecl(m_ast_context, original_ctx, decl);
+ Decl *copied_decl = CopyDecl(decl);
if (!copied_decl)
continue;
@@ -568,12 +692,31 @@ void ClangASTSource::FindExternalVisible
name.GetCString(), context.m_decl_context->getDeclKindName());
}
+ if (HasMerger() && !isa<TranslationUnitDecl>(context.m_decl_context)
+ /* possibly handle NamespaceDecls here? */) {
+ if (auto *interface_decl =
+ dyn_cast<ObjCInterfaceDecl>(context.m_decl_context)) {
+ ObjCInterfaceDecl *complete_iface_decl =
+ GetCompleteObjCInterface(interface_decl);
+
+ if (complete_iface_decl && (complete_iface_decl != interface_decl)) {
+ GetMergerUnchecked().ForceRecordOrigin(
+ interface_decl,
+ {complete_iface_decl, &complete_iface_decl->getASTContext()});
+ }
+ }
+
+ GetMergerUnchecked().FindExternalVisibleDeclsByName(context.m_decl_context,
+ context.m_decl_name);
+ return; // otherwise we may need to fall back
+ }
+
context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap);
if (const NamespaceDecl *namespace_context =
dyn_cast<NamespaceDecl>(context.m_decl_context)) {
- ClangASTImporter::NamespaceMapSP namespace_map =
- m_ast_importer_sp->GetNamespaceMap(namespace_context);
+ ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp ?
+ m_ast_importer_sp->GetNamespaceMap(namespace_context) : nullptr;
if (log && log->GetVerbose())
log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
@@ -593,7 +736,7 @@ void ClangASTSource::FindExternalVisible
FindExternalVisibleDecls(context, i->first, i->second, current_id);
}
- } else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) {
+ } else if (isa<ObjCInterfaceDecl>(context.m_decl_context) && !HasMerger()) {
FindObjCPropertyAndIvarDecls(context);
} else if (!isa<TranslationUnitDecl>(context.m_decl_context)) {
// we shouldn't be getting FindExternalVisibleDecls calls for these
@@ -677,7 +820,7 @@ void ClangASTSource::FindExternalVisible
module_sp->GetFileSpec().GetFilename().GetCString());
}
}
- } else {
+ } else if (!HasMerger()) {
const ModuleList &target_images = m_target->GetImages();
std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
@@ -780,9 +923,7 @@ void ClangASTSource::FindExternalVisible
if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) {
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, &decl_from_modules->getASTContext(),
- decl_from_modules);
+ clang::Decl *copied_decl = CopyDecl(decl_from_modules);
clang::NamedDecl *copied_named_decl =
copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
@@ -837,8 +978,7 @@ void ClangASTSource::FindExternalVisible
current_id, name.GetCString());
}
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, &decls[0]->getASTContext(), decls[0]);
+ clang::Decl *copied_decl = CopyDecl(decls[0]);
clang::NamedDecl *copied_named_decl =
copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
@@ -881,7 +1021,7 @@ public:
DeclFromParser() : TaggedASTDecl<D>() {}
DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) {}
- DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
+ DeclFromUser<D> GetOrigin(ClangASTSource &source);
};
template <class D> class DeclFromUser : public TaggedASTDecl<D> {
@@ -889,32 +1029,29 @@ public:
DeclFromUser() : TaggedASTDecl<D>() {}
DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) {}
- DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
+ DeclFromParser<D> Import(ClangASTSource &source);
};
template <class D>
-DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTImporter *importer) {
+DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTSource &source) {
DeclFromUser<> origin_decl;
- importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
+ source.ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
if (origin_decl.IsInvalid())
return DeclFromUser<D>();
return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl));
}
template <class D>
-DeclFromParser<D> DeclFromUser<D>::Import(ClangASTImporter *importer,
- ASTContext &dest_ctx) {
- DeclFromParser<> parser_generic_decl(
- importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl));
+DeclFromParser<D> DeclFromUser<D>::Import(ClangASTSource &source) {
+ DeclFromParser<> parser_generic_decl(source.CopyDecl(this->decl));
if (parser_generic_decl.IsInvalid())
return DeclFromParser<D>();
return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
}
-static bool FindObjCMethodDeclsWithOrigin(
+bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
unsigned int current_id, NameSearchContext &context,
- ObjCInterfaceDecl *original_interface_decl, clang::ASTContext *ast_context,
- ClangASTImporter *ast_importer, const char *log_info) {
+ ObjCInterfaceDecl *original_interface_decl, const char *log_info) {
const DeclarationName &decl_name(context.m_decl_name);
clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
@@ -973,8 +1110,7 @@ static bool FindObjCMethodDeclsWithOrigi
if (!result_method)
continue;
- Decl *copied_decl = ast_importer->CopyDecl(
- ast_context, &result_method->getASTContext(), result_method);
+ Decl *copied_decl = CopyDecl(result_method);
if (!copied_decl)
continue;
@@ -1001,6 +1137,21 @@ static bool FindObjCMethodDeclsWithOrigi
void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ if (HasMerger()) {
+ if (auto *interface_decl = dyn_cast<ObjCInterfaceDecl>(context.m_decl_context)) {
+ ObjCInterfaceDecl *complete_iface_decl =
+ GetCompleteObjCInterface(interface_decl);
+
+ if (complete_iface_decl && (complete_iface_decl != context.m_decl_context)) {
+ m_merger_up->ForceRecordOrigin(interface_decl, {complete_iface_decl, &complete_iface_decl->getASTContext()});
+ }
+ }
+
+ GetMergerUnchecked().FindExternalVisibleDeclsByName(context.m_decl_context,
+ context.m_decl_name);
+ return;
+ }
+
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
@@ -1027,8 +1178,7 @@ void ClangASTSource::FindObjCMethodDecls
dyn_cast<ObjCInterfaceDecl>(original_decl);
if (FindObjCMethodDeclsWithOrigin(current_id, context,
- original_interface_decl, m_ast_context,
- m_ast_importer_sp.get(), "at origin"))
+ original_interface_decl, "at origin"))
return; // found it, no need to look any further
} while (0);
@@ -1166,8 +1316,7 @@ void ClangASTSource::FindObjCMethodDecls
continue;
if (found_interface_decl->getName() == interface_decl->getName()) {
- Decl *copied_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, &method_decl->getASTContext(), method_decl);
+ Decl *copied_decl = CopyDecl(method_decl);
if (!copied_decl)
continue;
@@ -1216,7 +1365,6 @@ void ClangASTSource::FindObjCMethodDecls
static_cast<void *>(&complete_iface_decl->getASTContext()));
FindObjCMethodDeclsWithOrigin(current_id, context, complete_interface_decl,
- m_ast_context, m_ast_importer_sp.get(),
"in debug info");
return;
@@ -1244,8 +1392,7 @@ void ClangASTSource::FindObjCMethodDecls
break;
if (FindObjCMethodDeclsWithOrigin(
- current_id, context, interface_decl_from_modules, m_ast_context,
- m_ast_importer_sp.get(), "in modules"))
+ current_id, context, interface_decl_from_modules, "in modules"))
return;
}
} while (0);
@@ -1284,14 +1431,12 @@ void ClangASTSource::FindObjCMethodDecls
break;
FindObjCMethodDeclsWithOrigin(current_id, context, runtime_interface_decl,
- m_ast_context, m_ast_importer_sp.get(),
"in runtime");
} while (0);
}
static bool FindObjCPropertyAndIvarDeclsWithOrigin(
- unsigned int current_id, NameSearchContext &context,
- clang::ASTContext &ast_context, ClangASTImporter *ast_importer,
+ unsigned int current_id, NameSearchContext &context, ClangASTSource &source,
DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1311,7 +1456,7 @@ static bool FindObjCPropertyAndIvarDecls
if (origin_property_decl.IsValid()) {
DeclFromParser<ObjCPropertyDecl> parser_property_decl(
- origin_property_decl.Import(ast_importer, ast_context));
+ origin_property_decl.Import(source));
if (parser_property_decl.IsValid()) {
if (log) {
ASTDumper dumper((Decl *)parser_property_decl.decl);
@@ -1329,7 +1474,7 @@ static bool FindObjCPropertyAndIvarDecls
if (origin_ivar_decl.IsValid()) {
DeclFromParser<ObjCIvarDecl> parser_ivar_decl(
- origin_ivar_decl.Import(ast_importer, ast_context));
+ origin_ivar_decl.Import(source));
if (parser_ivar_decl.IsValid()) {
if (log) {
ASTDumper dumper((Decl *)parser_ivar_decl.decl);
@@ -1354,7 +1499,7 @@ void ClangASTSource::FindObjCPropertyAnd
DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(
cast<ObjCInterfaceDecl>(context.m_decl_context));
DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(
- parser_iface_decl.GetOrigin(m_ast_importer_sp.get()));
+ parser_iface_decl.GetOrigin(*this));
ConstString class_name(parser_iface_decl->getNameAsString().c_str());
@@ -1366,8 +1511,7 @@ void ClangASTSource::FindObjCPropertyAnd
context.m_decl_name.getAsString().c_str());
if (FindObjCPropertyAndIvarDeclsWithOrigin(
- current_id, context, *m_ast_context, m_ast_importer_sp.get(),
- origin_iface_decl))
+ current_id, context, *this, origin_iface_decl))
return;
if (log)
@@ -1403,8 +1547,7 @@ void ClangASTSource::FindObjCPropertyAnd
static_cast<const void *>(complete_iface_decl.decl),
static_cast<void *>(&complete_iface_decl->getASTContext()));
- FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *m_ast_context,
- m_ast_importer_sp.get(),
+ FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
complete_iface_decl);
return;
@@ -1441,9 +1584,8 @@ void ClangASTSource::FindObjCPropertyAnd
static_cast<const void *>(interface_decl_from_modules.decl),
static_cast<void *>(&interface_decl_from_modules->getASTContext()));
- if (FindObjCPropertyAndIvarDeclsWithOrigin(
- current_id, context, *m_ast_context, m_ast_importer_sp.get(),
- interface_decl_from_modules))
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
+ interface_decl_from_modules))
return;
} while (0);
@@ -1489,8 +1631,7 @@ void ClangASTSource::FindObjCPropertyAnd
static_cast<void *>(&interface_decl_from_runtime->getASTContext()));
if (FindObjCPropertyAndIvarDeclsWithOrigin(
- current_id, context, *m_ast_context, m_ast_importer_sp.get(),
- interface_decl_from_runtime))
+ current_id, context, *this, interface_decl_from_runtime))
return;
} while (0);
}
@@ -1501,7 +1642,7 @@ typedef llvm::DenseMap<const CXXRecordDe
template <class D, class O>
static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map,
llvm::DenseMap<const D *, O> &source_map,
- ClangASTImporter *importer, ASTContext &dest_ctx) {
+ ClangASTSource &source) {
// When importing fields into a new record, clang has a hard requirement that
// fields be imported in field offset order. Since they are stored in a
// DenseMap
@@ -1522,7 +1663,7 @@ static bool ImportOffsetMap(llvm::DenseM
for (const auto &item : sorted_items) {
DeclFromUser<D> user_decl(const_cast<D *>(item.first));
- DeclFromParser<D> parser_decl(user_decl.Import(importer, dest_ctx));
+ DeclFromParser<D> parser_decl(user_decl.Import(source));
if (parser_decl.IsInvalid())
return false;
destination_map.insert(
@@ -1599,7 +1740,7 @@ bool ClangASTSource::layoutRecordType(co
DeclFromParser<const RecordDecl> parser_record(record);
DeclFromUser<const RecordDecl> origin_record(
- parser_record.GetOrigin(m_ast_importer_sp.get()));
+ parser_record.GetOrigin(*this));
if (origin_record.IsInvalid())
return false;
@@ -1635,7 +1776,7 @@ bool ClangASTSource::layoutRecordType(co
field_idx++;
}
- ASTContext &parser_ast_context(record->getASTContext());
+ lldbassert(&record->getASTContext() == m_ast_context);
DeclFromUser<const CXXRecordDecl> origin_cxx_record(
DynCast<const CXXRecordDecl>(origin_record));
@@ -1648,12 +1789,10 @@ bool ClangASTSource::layoutRecordType(co
return false;
}
- if (!ImportOffsetMap(field_offsets, origin_field_offsets,
- m_ast_importer_sp.get(), parser_ast_context) ||
- !ImportOffsetMap(base_offsets, origin_base_offsets,
- m_ast_importer_sp.get(), parser_ast_context) ||
+ if (!ImportOffsetMap(field_offsets, origin_field_offsets, *this) ||
+ !ImportOffsetMap(base_offsets, origin_base_offsets, *this) ||
!ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets,
- m_ast_importer_sp.get(), parser_ast_context))
+ *this))
return false;
size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
@@ -1817,8 +1956,7 @@ NamespaceDecl *ClangASTSource::AddNamesp
if (!src_namespace_decl)
return nullptr;
- Decl *copied_decl =
- m_ast_importer_sp->CopyDecl(m_ast_context, src_ast, src_namespace_decl);
+ Decl *copied_decl = CopyDecl(src_namespace_decl);
if (!copied_decl)
return nullptr;
@@ -1836,6 +1974,54 @@ NamespaceDecl *ClangASTSource::AddNamesp
return dyn_cast<NamespaceDecl>(copied_decl);
}
+clang::QualType ClangASTSource::CopyTypeWithMerger(
+ clang::ASTContext &from_context,
+ clang::ExternalASTMerger &merger,
+ clang::QualType type) {
+ if (!merger.HasImporterForOrigin(from_context)) {
+ lldbassert(!"Couldn't find the importer for a source context!");
+ return QualType();
+ }
+
+ return merger.ImporterForOrigin(from_context).Import(type);
+}
+
+clang::Decl *ClangASTSource::CopyDecl(Decl *src_decl) {
+ clang::ASTContext &from_context = src_decl->getASTContext();
+ if (m_ast_importer_sp) {
+ return m_ast_importer_sp->CopyDecl(m_ast_context, &from_context, src_decl);
+ } else if (m_merger_up) {
+ if (!m_merger_up->HasImporterForOrigin(from_context)) {
+ lldbassert(!"Couldn't find the importer for a source context!");
+ return nullptr;
+ }
+
+ return m_merger_up->ImporterForOrigin(from_context).Import(src_decl);
+ } else {
+ lldbassert("No mechanism for copying a decl!");
+ return nullptr;
+ }
+}
+
+bool ClangASTSource::ResolveDeclOrigin(const clang::Decl *decl,
+ clang::Decl **original_decl,
+ clang::ASTContext **original_ctx) {
+ if (m_ast_importer_sp) {
+ return m_ast_importer_sp->ResolveDeclOrigin(decl, original_decl,
+ original_ctx);
+ } else if (m_merger_up) {
+ return false; // Implement this correctly in ExternalASTMerger
+ } else {
+ // this can happen early enough that no ExternalASTSource is installed.
+ return false;
+ }
+}
+
+clang::ExternalASTMerger &ClangASTSource::GetMergerUnchecked() {
+ lldbassert(m_merger_up);
+ return *m_merger_up;
+}
+
CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
ClangASTContext *src_ast =
llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
@@ -1846,9 +2032,20 @@ CompilerType ClangASTSource::GuardedCopy
SetImportInProgress(true);
- QualType copied_qual_type =
- m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(),
- ClangUtil::GetQualType(src_type));
+ QualType copied_qual_type;
+
+ if (m_ast_importer_sp) {
+ copied_qual_type =
+ m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(),
+ ClangUtil::GetQualType(src_type));
+ } else if (m_merger_up) {
+ copied_qual_type =
+ CopyTypeWithMerger(*src_ast->getASTContext(), *m_merger_up,
+ ClangUtil::GetQualType(src_type));
+ } else {
+ lldbassert("No mechanism for copying a type!");
+ return CompilerType();
+ }
SetImportInProgress(false);
Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h Thu Sep 28 13:20:25 2017
@@ -16,6 +16,7 @@
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Target.h"
+#include "clang/AST/ExternalASTMerger.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/SmallSet.h"
@@ -41,14 +42,10 @@ public:
///
/// Initializes class variables.
///
- /// @param[in] declMap
- /// A reference to the LLDB object that handles entity lookup.
+ /// @param[in] target
+ /// A reference to the target containing debug information to use.
//------------------------------------------------------------------
- ClangASTSource(const lldb::TargetSP &target)
- : m_import_in_progress(false), m_lookups_enabled(false), m_target(target),
- m_ast_context(NULL), m_active_lexical_decls(), m_active_lookups() {
- m_ast_importer_sp = m_target->GetClangASTImporter();
- }
+ ClangASTSource(const lldb::TargetSP &target);
//------------------------------------------------------------------
/// Destructor
@@ -70,10 +67,9 @@ public:
}
void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; }
- void InstallASTContext(clang::ASTContext *ast_context) {
- m_ast_context = ast_context;
- m_ast_importer_sp->InstallMapCompleter(ast_context, *this);
- }
+ void InstallASTContext(clang::ASTContext &ast_context,
+ clang::FileManager &file_manager,
+ bool is_shared_context = false);
//
// APIs for ExternalASTSource
@@ -313,7 +309,7 @@ protected:
/// the complete interface otherwise.
//------------------------------------------------------------------
clang::ObjCInterfaceDecl *
- GetCompleteObjCInterface(clang::ObjCInterfaceDecl *interface_decl);
+ GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl);
//------------------------------------------------------------------
/// Find all entities matching a given name in a given module,
@@ -376,7 +372,7 @@ protected:
//------------------------------------------------------------------
CompilerType GuardedCopyType(const CompilerType &src_type);
-
+public:
//------------------------------------------------------------------
/// Returns true if a name should be ignored by name lookup.
///
@@ -392,6 +388,73 @@ protected:
//------------------------------------------------------------------
bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);
+public:
+ //------------------------------------------------------------------
+ /// Copies a single Decl into the parser's AST context.
+ ///
+ /// @param[in] src_decl
+ /// The Decl to copy.
+ ///
+ /// @return
+ /// A copy of the Decl in m_ast_context, or NULL if the copy failed.
+ //------------------------------------------------------------------
+ clang::Decl *CopyDecl(clang::Decl *src_decl);
+
+ //------------------------------------------------------------------
+ /// Copies a single Type to the target of the given ExternalASTMerger.
+ ///
+ /// @param[in] src_context
+ /// The ASTContext containing the type.
+ ///
+ /// @param[in] merger
+ /// The merger to use. This isn't just *m_merger_up because it might be
+ /// the persistent AST context's merger.
+ ///
+ /// @param[in] type
+ /// The type to copy.
+ ///
+ /// @return
+ /// A copy of the Type in the merger's target context.
+ //------------------------------------------------------------------
+ clang::QualType CopyTypeWithMerger(clang::ASTContext &src_context,
+ clang::ExternalASTMerger &merger,
+ clang::QualType type);
+
+ //------------------------------------------------------------------
+ /// Determined the origin of a single Decl, if it can be found.
+ ///
+ /// @param[in] decl
+ /// The Decl whose origin is to be found.
+ ///
+ /// @param[out] original_decl
+ /// A pointer whose target is filled in with the original Decl.
+ ///
+ /// @param[in] original_ctx
+ /// A pointer whose target is filled in with the original's ASTContext.
+ ///
+ /// @return
+ /// True if lookup succeeded; false otherwise.
+ //------------------------------------------------------------------
+ bool ResolveDeclOrigin(const clang::Decl *decl, clang::Decl **original_decl,
+ clang::ASTContext **original_ctx);
+
+ //------------------------------------------------------------------
+ /// Returns m_merger_up. Only call this if the target is configured to use
+ /// modern lookup,
+ //------------------------------------------------------------------
+ clang::ExternalASTMerger &GetMergerUnchecked();
+
+ //------------------------------------------------------------------
+ /// Returns true if there is a merger. This only occurs if the target is
+ /// using modern lookup.
+ //------------------------------------------------------------------
+ bool HasMerger() { return (bool)m_merger_up; }
+
+protected:
+ bool FindObjCMethodDeclsWithOrigin(
+ unsigned int current_id, NameSearchContext &context,
+ clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);
+
friend struct NameSearchContext;
bool m_import_in_progress;
@@ -401,7 +464,11 @@ protected:
m_target; ///< The target to use in finding variables and types.
clang::ASTContext
*m_ast_context; ///< The AST context requests are coming in for.
+ clang::FileManager
+ *m_file_manager; ///< The file manager paired with the AST context.
lldb::ClangASTImporterSP m_ast_importer_sp; ///< The target's AST importer.
+ std::unique_ptr<clang::ExternalASTMerger> m_merger_up;
+ ///< The ExternalASTMerger for this parse.
std::set<const clang::Decl *> m_active_lexical_decls;
std::set<const char *> m_active_lookups;
};
Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp Thu Sep 28 13:20:25 2017
@@ -48,8 +48,10 @@
#include "lldb/lldb-private.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTImporter.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/RecursiveASTVisitor.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
@@ -178,6 +180,134 @@ ClangExpressionDeclMap::TargetInfo Clang
return ret;
}
+namespace {
+/// This class walks an AST and ensures that all DeclContexts defined inside the
+/// current source file are properly complete.
+///
+/// This is used to ensure that persistent types defined in the current source
+/// file migrate completely to the persistent AST context before they are
+/// reused. If that didn't happen, it would be impoossible to complete them
+/// because their origin would be gone.
+///
+/// The stragtegy used by this class is to check the SourceLocation (to be
+/// specific, the FileID) and see if it's the FileID for the current expression.
+/// Alternate strategies could include checking whether an ExternalASTMerger,
+/// set up to not have the current context as a source, can find an original for
+/// the type.
+class Completer : public clang::RecursiveASTVisitor<Completer> {
+private:
+ clang::ASTImporter &m_exporter; /// Used to import Decl contents
+ clang::FileID m_file; /// The file that's going away
+ llvm::DenseSet<clang::Decl *> m_completed; /// Visited Decls, to avoid cycles
+
+ bool ImportAndCheckCompletable(clang::Decl *decl) {
+ (void)m_exporter.Import(decl);
+ if (m_completed.count(decl))
+ return false;
+ if (!llvm::isa<DeclContext>(decl))
+ return false;
+ const clang::SourceLocation loc = decl->getLocation();
+ if (!loc.isValid())
+ return false;
+ const clang::FileID file =
+ m_exporter.getFromContext().getSourceManager().getFileID(loc);
+ if (file != m_file)
+ return false;
+ // We are assuming the Decl was parsed in this very expression, so it should
+ // not have external storage.
+ lldbassert(!llvm::cast<DeclContext>(decl)->hasExternalLexicalStorage());
+ return true;
+ }
+
+ void Complete(clang::Decl *decl) {
+ m_completed.insert(decl);
+ auto *decl_context = llvm::cast<DeclContext>(decl);
+ (void)m_exporter.Import(decl);
+ m_exporter.CompleteDecl(decl);
+ for (Decl *child : decl_context->decls())
+ if (ImportAndCheckCompletable(child))
+ Complete(child);
+ }
+
+ void MaybeComplete(clang::Decl *decl) {
+ if (ImportAndCheckCompletable(decl))
+ Complete(decl);
+ }
+
+public:
+ Completer(clang::ASTImporter &exporter, clang::FileID file)
+ : m_exporter(exporter), m_file(file) {}
+
+ // Implements the RecursiveASTVisitor's core API. It is called on each Decl
+ // that the RecursiveASTVisitor encounters, and returns true if the traversal
+ // should continue.
+ bool VisitDecl(clang::Decl *decl) {
+ MaybeComplete(decl);
+ return true;
+ }
+};
+}
+
+static void CompleteAllDeclContexts(clang::ASTImporter &exporter,
+ clang::FileID file,
+ clang::QualType root) {
+ clang::QualType canonical_type = root.getCanonicalType();
+ if (clang::TagDecl *tag_decl = canonical_type->getAsTagDecl()) {
+ Completer(exporter, file).TraverseDecl(tag_decl);
+ } else if (auto interface_type = llvm::dyn_cast<ObjCInterfaceType>(
+ canonical_type.getTypePtr())) {
+ Completer(exporter, file).TraverseDecl(interface_type->getDecl());
+ } else {
+ Completer(exporter, file).TraverseType(canonical_type);
+ }
+}
+
+static clang::QualType ExportAllDeclaredTypes(
+ clang::ExternalASTMerger &merger,
+ clang::ASTContext &source, clang::FileManager &source_file_manager,
+ const clang::ExternalASTMerger::OriginMap &source_origin_map,
+ clang::FileID file, clang::QualType root) {
+ clang::ExternalASTMerger::ImporterSource importer_source =
+ { source, source_file_manager, source_origin_map };
+ merger.AddSources(importer_source);
+ clang::ASTImporter &exporter = merger.ImporterForOrigin(source);
+ CompleteAllDeclContexts(exporter, file, root);
+ clang::QualType ret = exporter.Import(root);
+ merger.RemoveSources(importer_source);
+ return ret;
+}
+
+TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target,
+ ClangASTContext &source,
+ TypeFromParser parser_type) {
+ assert (&target == m_target->GetScratchClangASTContext());
+ assert ((TypeSystem*)&source == parser_type.GetTypeSystem());
+ assert (source.getASTContext() == m_ast_context);
+
+ if (m_ast_importer_sp) {
+ return TypeFromUser(m_ast_importer_sp->DeportType(
+ target.getASTContext(), source.getASTContext(),
+ parser_type.GetOpaqueQualType()),
+ &target);
+ } else if (m_merger_up) {
+ clang::FileID source_file =
+ source.getASTContext()->getSourceManager().getFileID(
+ source.getASTContext()->getTranslationUnitDecl()->getLocation());
+ auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>(
+ m_target->GetScratchClangASTContext());
+ clang::QualType exported_type = ExportAllDeclaredTypes(
+ scratch_ast_context->GetMergerUnchecked(),
+ *source.getASTContext(), *source.getFileManager(),
+ m_merger_up->GetOrigins(),
+ source_file,
+ clang::QualType::getFromOpaquePtr(parser_type.GetOpaqueQualType()));
+ return TypeFromUser(exported_type.getAsOpaquePtr(), &target);
+ } else {
+ lldbassert(!"No mechanism for deporting a type!");
+ return TypeFromUser();
+ }
+}
+
bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
const ConstString &name,
TypeFromParser parser_type,
@@ -198,12 +328,8 @@ bool ClangExpressionDeclMap::AddPersiste
if (target == nullptr)
return false;
- ClangASTContext *context(target->GetScratchClangASTContext());
-
- TypeFromUser user_type(m_ast_importer_sp->DeportType(
- context->getASTContext(), ast->getASTContext(),
- parser_type.GetOpaqueQualType()),
- context);
+ TypeFromUser user_type =
+ DeportType(*target->GetScratchClangASTContext(), *ast, parser_type);
uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(
user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err);
@@ -240,10 +366,7 @@ bool ClangExpressionDeclMap::AddPersiste
ClangASTContext *context(target->GetScratchClangASTContext());
- TypeFromUser user_type(m_ast_importer_sp->DeportType(
- context->getASTContext(), ast->getASTContext(),
- parser_type.GetOpaqueQualType()),
- context);
+ TypeFromUser user_type = DeportType(*context, *ast, parser_type);
if (!user_type.GetOpaqueQualType()) {
if (log)
@@ -688,16 +811,18 @@ void ClangExpressionDeclMap::FindExterna
}
ClangASTImporter::NamespaceMapSP namespace_map =
- m_ast_importer_sp->GetNamespaceMap(namespace_context);
+ m_ast_importer_sp
+ ? m_ast_importer_sp->GetNamespaceMap(namespace_context)
+ : ClangASTImporter::NamespaceMapSP();
+
+ if (!namespace_map)
+ return;
if (log && log->GetVerbose())
log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
current_id, static_cast<void *>(namespace_map.get()),
(int)namespace_map->size());
-
- if (!namespace_map)
- return;
-
+
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
e = namespace_map->end();
i != e; ++i) {
@@ -775,8 +900,7 @@ void ClangExpressionDeclMap::FindExterna
if (!persistent_decl)
break;
- Decl *parser_persistent_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, scratch_ast_context, persistent_decl);
+ Decl *parser_persistent_decl = CopyDecl(persistent_decl);
if (!parser_persistent_decl)
break;
@@ -1320,8 +1444,7 @@ void ClangExpressionDeclMap::FindExterna
for (clang::NamedDecl *decl : decls_from_modules) {
if (llvm::isa<clang::FunctionDecl>(decl)) {
clang::NamedDecl *copied_decl =
- llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(
- m_ast_context, &decl->getASTContext(), decl));
+ llvm::cast_or_null<FunctionDecl>(CopyDecl(decl));
if (copied_decl) {
context.AddNamedDecl(copied_decl);
context.m_found.function_with_type_info = true;
@@ -1363,9 +1486,7 @@ void ClangExpressionDeclMap::FindExterna
current_id, name.GetCString());
}
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, &decl_from_modules->getASTContext(),
- decl_from_modules);
+ clang::Decl *copied_decl = CopyDecl(decl_from_modules);
clang::FunctionDecl *copied_function_decl =
copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl)
: nullptr;
@@ -1392,9 +1513,7 @@ void ClangExpressionDeclMap::FindExterna
current_id, name.GetCString());
}
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, &decl_from_modules->getASTContext(),
- decl_from_modules);
+ clang::Decl *copied_decl = CopyDecl(decl_from_modules);
clang::VarDecl *copied_var_decl =
copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl)
: nullptr;
@@ -1753,7 +1872,9 @@ bool ClangExpressionDeclMap::ResolveUnkn
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- ClangASTContext *scratch_ast_context = target->GetScratchClangASTContext();
+ ClangASTContextForExpressions *scratch_ast_context =
+ static_cast<ClangASTContextForExpressions*>(
+ target->GetScratchClangASTContext());
for (size_t index = 0, num_entities = m_found_entities.GetSize();
index < num_entities; ++index) {
@@ -1784,9 +1905,20 @@ bool ClangExpressionDeclMap::ResolveUnkn
var_type.getAsOpaquePtr(),
ClangASTContext::GetASTContext(&var_decl->getASTContext()));
- lldb::opaque_compiler_type_t copied_type = m_ast_importer_sp->CopyType(
- scratch_ast_context->getASTContext(), &var_decl->getASTContext(),
- var_type.getAsOpaquePtr());
+ lldb::opaque_compiler_type_t copied_type = 0;
+ if (m_ast_importer_sp) {
+ copied_type = m_ast_importer_sp->CopyType(
+ scratch_ast_context->getASTContext(), &var_decl->getASTContext(),
+ var_type.getAsOpaquePtr());
+ } else if (HasMerger()) {
+ copied_type = CopyTypeWithMerger(
+ var_decl->getASTContext(),
+ scratch_ast_context->GetMergerUnchecked(),
+ var_type).getAsOpaquePtr();
+ } else {
+ lldbassert(!"No mechanism to copy a resolved unknown type!");
+ return false;
+ }
if (!copied_type) {
if (log)
@@ -1896,9 +2028,7 @@ void ClangExpressionDeclMap::AddOneFunct
src_function_decl->getTemplateSpecializationInfo()->getTemplate();
clang::FunctionTemplateDecl *copied_function_template =
llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(
- m_ast_importer_sp->CopyDecl(m_ast_context,
- src_ast->getASTContext(),
- function_template));
+ CopyDecl(function_template));
if (copied_function_template) {
if (log) {
ASTDumper ast_dumper((clang::Decl *)copied_function_template);
@@ -1919,9 +2049,7 @@ void ClangExpressionDeclMap::AddOneFunct
} else if (src_function_decl) {
if (clang::FunctionDecl *copied_function_decl =
llvm::dyn_cast_or_null<clang::FunctionDecl>(
- m_ast_importer_sp->CopyDecl(m_ast_context,
- src_ast->getASTContext(),
- src_function_decl))) {
+ CopyDecl(src_function_decl))) {
if (log) {
ASTDumper ast_dumper((clang::Decl *)copied_function_decl);
Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h Thu Sep 28 13:20:25 2017
@@ -613,6 +613,23 @@ private:
void AddThisType(NameSearchContext &context, TypeFromUser &type,
unsigned int current_id);
+ //------------------------------------------------------------------
+ /// Move a type out of the current ASTContext into another, but make sure to
+ /// export all components of the type also.
+ ///
+ /// @param[in] target
+ /// The ClangASTContext to move to.
+ /// @param[in] source
+ /// The ClangASTContext to move from. This is assumed to be going away.
+ /// @param[in] parser_type
+ /// The type as it appears in the source context.
+ ///
+ /// @return
+ /// Returns the moved type, or an empty type if there was a problem.
+ //------------------------------------------------------------------
+ TypeFromUser DeportType(ClangASTContext &target, ClangASTContext &source,
+ TypeFromParser parser_type);
+
ClangASTContext *GetClangASTContext();
};
Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp Thu Sep 28 13:20:25 2017
@@ -526,7 +526,7 @@ ClangExpressionParser::ClangExpressionPa
if (decl_map) {
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source(
decl_map->CreateProxy());
- decl_map->InstallASTContext(ast_context.get());
+ decl_map->InstallASTContext(*ast_context, m_compiler->getFileManager());
ast_context->setExternalSource(ast_source);
}
Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp Thu Sep 28 13:20:25 2017
@@ -85,6 +85,7 @@ public:
void ForEachMacro(const ModuleVector &modules,
std::function<bool(const std::string &)> handler) override;
+ clang::ExternalASTMerger::ImporterSource GetImporterSource() override;
private:
void
ReportModuleExportsHelper(std::set<ClangModulesDeclVendor::ModuleID> &exports,
@@ -109,6 +110,7 @@ private:
typedef std::set<ModuleID> ImportedModuleSet;
ImportedModuleMap m_imported_modules;
ImportedModuleSet m_user_imported_modules;
+ const clang::ExternalASTMerger::OriginMap m_origin_map;
};
} // anonymous namespace
@@ -548,6 +550,12 @@ ClangModulesDeclVendorImpl::DoGetModule(
is_inclusion_directive);
}
+clang::ExternalASTMerger::ImporterSource
+ClangModulesDeclVendorImpl::GetImporterSource() {
+ return {m_compiler_instance->getASTContext(),
+ m_compiler_instance->getFileManager(), m_origin_map};
+}
+
static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer";
lldb_private::ClangModulesDeclVendor *
Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp Thu Sep 28 13:20:25 2017
@@ -653,3 +653,11 @@ AppleObjCDeclVendor::FindDecls(const Con
return ret;
}
+
+clang::ExternalASTMerger::ImporterSource
+AppleObjCDeclVendor::GetImporterSource() {
+ return {*m_ast_ctx.getASTContext(),
+ *m_ast_ctx.getFileManager(),
+ m_ast_ctx.GetOriginMap()
+ };
+}
Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h Thu Sep 28 13:20:25 2017
@@ -30,6 +30,8 @@ public:
uint32_t FindDecls(const ConstString &name, bool append, uint32_t max_matches,
std::vector<clang::NamedDecl *> &decls) override;
+ clang::ExternalASTMerger::ImporterSource GetImporterSource() override;
+
friend class AppleObjCExternalASTSource;
private:
Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Thu Sep 28 13:20:25 2017
@@ -596,8 +596,9 @@ lldb::TypeSystemSP ClangASTContext::Crea
ast_sp->SetArchitecture(fixed_arch);
ast_sp->m_scratch_ast_source_ap.reset(
new ClangASTSource(target->shared_from_this()));
+ lldbassert(ast_sp->getFileManager());
ast_sp->m_scratch_ast_source_ap->InstallASTContext(
- ast_sp->getASTContext());
+ *ast_sp->getASTContext(), *ast_sp->getFileManager(), true);
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
ast_sp->m_scratch_ast_source_ap->CreateProxy());
ast_sp->SetExternalSource(proxy_ast_source);
@@ -10122,3 +10123,10 @@ PersistentExpressionState *
ClangASTContextForExpressions::GetPersistentExpressionState() {
return m_persistent_variables.get();
}
+
+clang::ExternalASTMerger &
+ClangASTContextForExpressions::GetMergerUnchecked() {
+ lldbassert(m_scratch_ast_source_ap);
+ return m_scratch_ast_source_ap->GetMergerUnchecked();
+}
+
Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Thu Sep 28 13:20:25 2017
@@ -3645,9 +3645,11 @@ static PropertyDefinition g_experimental
"This will fix symbol resolution when there are name collisions between "
"ivars and local variables. "
"But it can make expressions run much more slowly."},
+ {"use-modern-type-lookup", OptionValue::eTypeBoolean, true, false, nullptr,
+ nullptr, "If true, use Clang's modern type lookup infrastructure."},
{nullptr, OptionValue::eTypeInvalid, true, 0, nullptr, nullptr, nullptr}};
-enum { ePropertyInjectLocalVars = 0 };
+enum { ePropertyInjectLocalVars = 0, ePropertyUseModernTypeLookup };
class TargetExperimentalOptionValueProperties : public OptionValueProperties {
public:
@@ -3758,6 +3760,18 @@ void TargetProperties::SetInjectLocalVar
true);
}
+bool TargetProperties::GetUseModernTypeLookup() const {
+ const Property *exp_property = m_collection_sp->GetPropertyAtIndex(
+ nullptr, false, ePropertyExperimental);
+ OptionValueProperties *exp_values =
+ exp_property->GetValue()->GetAsProperties();
+ if (exp_values)
+ return exp_values->GetPropertyAtIndexAsBoolean(
+ nullptr, ePropertyUseModernTypeLookup, true);
+ else
+ return true;
+}
+
ArchSpec TargetProperties::GetDefaultArchitecture() const {
OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch(
nullptr, ePropertyDefaultArch);
More information about the lldb-commits
mailing list