Author: Raphael Isemann Date: 2019-12-17T14:04:12+01:00 New Revision: 4aee81c4f73359230e358108bc428e3b0cc59566
URL: https://github.com/llvm/llvm-project/commit/4aee81c4f73359230e358108bc428e3b0cc59566 DIFF: https://github.com/llvm/llvm-project/commit/4aee81c4f73359230e358108bc428e3b0cc59566.diff LOG: [lldb][NFC] Allow creating ClangExpressionDeclMap and ClangASTSource without a Target and add basic unit test The ClangExpressionDeclMap should be testable from a unit test. This is currently impossible as they have both dependencies on Target/ExecutionContext from their constructor. This patch allows constructing these classes without an active Target and adds the missing tests for running without a target that we can do at least a basic lookup test without crashing. Added: lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp Modified: lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp lldb/source/Symbol/ClangASTContext.cpp lldb/unittests/Expression/CMakeLists.txt Removed: ################################################################################ diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index 94a23c8069a1..f37fe21b5545 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -49,10 +49,11 @@ class ScopedLexicalDeclEraser { }; } -ClangASTSource::ClangASTSource(const lldb::TargetSP &target) +ClangASTSource::ClangASTSource(const lldb::TargetSP &target, + const lldb::ClangASTImporterSP &importer) : m_import_in_progress(false), m_lookups_enabled(false), m_target(target), m_ast_context(nullptr), m_active_lexical_decls(), m_active_lookups() { - m_ast_importer_sp = m_target->GetClangASTImporter(); + m_ast_importer_sp = importer; } void ClangASTSource::InstallASTContext(ClangASTContext &clang_ast_context, @@ -65,9 +66,13 @@ void ClangASTSource::InstallASTContext(ClangASTContext &clang_ast_context, } ClangASTSource::~ClangASTSource() { - if (m_ast_importer_sp) - m_ast_importer_sp->ForgetDestination(m_ast_context); + if (!m_ast_importer_sp) + return; + + m_ast_importer_sp->ForgetDestination(m_ast_context); + if (!m_target) + return; // We are in the process of destruction, don't create clang ast context on // demand by passing false to // Target::GetScratchClangASTContext(create_on_demand). @@ -683,6 +688,9 @@ void ClangASTSource::FindExternalVisibleDecls( if (IgnoreName(name, true)) return; + if (!m_target) + return; + if (module_sp && namespace_decl) { CompilerDeclContext found_namespace_decl; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h index 0ae65e526e7e..e0442aeca326 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h @@ -38,7 +38,11 @@ class ClangASTSource : public ClangExternalASTSourceCommon, /// /// \param[in] target /// A reference to the target containing debug information to use. - ClangASTSource(const lldb::TargetSP &target); + /// + /// \param[in] importer + /// The ClangASTImporter to use. + ClangASTSource(const lldb::TargetSP &target, + const lldb::ClangASTImporterSP &importer); /// Destructor ~ClangASTSource() override; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index 3a6b7018e48f..33867fb4d45a 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -65,9 +65,10 @@ const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars"; ClangExpressionDeclMap::ClangExpressionDeclMap( bool keep_result_in_memory, Materializer::PersistentVariableDelegate *result_delegate, - ExecutionContext &exe_ctx, ValueObject *ctx_obj) - : ClangASTSource(exe_ctx.GetTargetSP()), m_found_entities(), - m_struct_members(), m_keep_result_in_memory(keep_result_in_memory), + const lldb::TargetSP &target, const lldb::ClangASTImporterSP &importer, + ValueObject *ctx_obj) + : ClangASTSource(target, importer), m_found_entities(), m_struct_members(), + m_keep_result_in_memory(keep_result_in_memory), m_result_delegate(result_delegate), m_ctx_obj(ctx_obj), m_parser_vars(), m_struct_vars() { EnableStructVars(); @@ -737,6 +738,8 @@ void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context, const ConstString name, unsigned int current_id) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + if (!m_parser_vars) + return; Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); if (!target) return; @@ -1048,6 +1051,9 @@ void ClangExpressionDeclMap::LookupInModulesDeclVendor( NameSearchContext &context, ConstString name, unsigned current_id) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + if (!m_target) + return; + auto *modules_decl_vendor = m_target->GetClangModulesDeclVendor(); if (!modules_decl_vendor) return; @@ -1236,6 +1242,8 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context, ConstString name, CompilerDeclContext &namespace_decl, unsigned current_id) { + if (!m_parser_vars) + return; Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); @@ -1366,9 +1374,14 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( // Only look for functions by name out in our symbols if the function doesn't // start with our phony prefix of '$' - Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); - StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); + + Target *target = nullptr; + StackFrame *frame = nullptr; SymbolContext sym_ctx; + if (m_parser_vars) { + target = m_parser_vars->m_exe_ctx.GetTargetPtr(); + frame = m_parser_vars->m_exe_ctx.GetFramePtr(); + } if (frame != nullptr) sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock); diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h index 5cd16d5d1687..223fd3201097 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -67,8 +67,11 @@ class ClangExpressionDeclMap : public ClangASTSource { /// If non-NULL, use this delegate to report result values. This /// allows the client ClangUserExpression to report a result. /// - /// \param[in] exe_ctx - /// The execution context to use when parsing. + /// \param[in] target + /// The target to use when parsing. + /// + /// \param[in] importer + /// The ClangASTImporter to use when parsing. /// /// \param[in] ctx_obj /// If not empty, then expression is evaluated in context of this object. @@ -76,7 +79,7 @@ class ClangExpressionDeclMap : public ClangASTSource { ClangExpressionDeclMap( bool keep_result_in_memory, Materializer::PersistentVariableDelegate *result_delegate, - ExecutionContext &exe_ctx, + const lldb::TargetSP &target, const lldb::ClangASTImporterSP &importer, ValueObject *ctx_obj); /// Destructor diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index 6ef56ced21ce..9a1da40cd6d7 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -892,9 +892,9 @@ void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap( Materializer::PersistentVariableDelegate &delegate, bool keep_result_in_memory, ValueObject *ctx_obj) { - m_expr_decl_map_up.reset( - new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx, - ctx_obj)); + m_expr_decl_map_up.reset(new ClangExpressionDeclMap( + keep_result_in_memory, &delegate, exe_ctx.GetTargetSP(), + exe_ctx.GetTargetRef().GetClangASTImporter(), ctx_obj)); } clang::ASTConsumer * diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp index 1edf443d6970..199e4898e118 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp @@ -159,7 +159,7 @@ bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager, void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap( ExecutionContext &exe_ctx, bool keep_result_in_memory) { - m_expr_decl_map_up.reset( - new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx, - nullptr)); + m_expr_decl_map_up.reset(new ClangExpressionDeclMap( + keep_result_in_memory, nullptr, exe_ctx.GetTargetSP(), + exe_ctx.GetTargetRef().GetClangASTImporter(), nullptr)); } diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index efc7b4d780e7..da29750215aa 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -569,8 +569,8 @@ lldb::TypeSystemSP ClangASTContext::CreateInstance(lldb::LanguageType language, } else if (target && target->IsValid()) { std::shared_ptr<ClangASTContextForExpressions> ast_sp( new ClangASTContextForExpressions(*target, fixed_arch)); - ast_sp->m_scratch_ast_source_up.reset( - new ClangASTSource(target->shared_from_this())); + ast_sp->m_scratch_ast_source_up.reset(new ClangASTSource( + target->shared_from_this(), target->GetClangASTImporter())); lldbassert(ast_sp->getFileManager()); ast_sp->m_scratch_ast_source_up->InstallASTContext( *ast_sp, *ast_sp->getFileManager(), true); diff --git a/lldb/unittests/Expression/CMakeLists.txt b/lldb/unittests/Expression/CMakeLists.txt index 3408b278b0bf..25e94f4d88fd 100644 --- a/lldb/unittests/Expression/CMakeLists.txt +++ b/lldb/unittests/Expression/CMakeLists.txt @@ -1,5 +1,6 @@ add_lldb_unittest(ExpressionTests ClangParserTest.cpp + ClangExpressionDeclMapTest.cpp DiagnosticManagerTest.cpp DWARFExpressionTest.cpp CppModuleConfigurationTest.cpp diff --git a/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp b/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp new file mode 100644 index 000000000000..2d93a6120dbd --- /dev/null +++ b/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp @@ -0,0 +1,59 @@ +//===-- ClangExpressionDeclMapTest.cpp ------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/lldb-defines.h" +#include "gtest/gtest.h" + +using namespace lldb_private; +using namespace lldb; + +namespace { +struct ClangExpressionDeclMapTest : public testing::Test { + static void SetUpTestCase() { + FileSystem::Initialize(); + HostInfo::Initialize(); + } + static void TearDownTestCase() { + HostInfo::Terminate(); + FileSystem::Terminate(); + } + + std::unique_ptr<ClangASTContext> createAST() { + return std::make_unique<ClangASTContext>(HostInfo::GetTargetTriple()); + } + + clang::DeclarationName getDeclarationName(ClangASTContext &ast, + llvm::StringRef name) { + clang::IdentifierInfo &II = ast.getIdentifierTable()->get(name); + return ast.getASTContext()->DeclarationNames.getIdentifier(&II); + } +}; +} // namespace + +TEST_F(ClangExpressionDeclMapTest, TestIdentifierLookupInEmptyTU) { + ClangASTImporterSP importer = std::make_shared<ClangASTImporter>(); + ClangExpressionDeclMap map(false, nullptr, lldb::TargetSP(), importer, + nullptr); + + std::unique_ptr<ClangASTContext> ast = createAST(); + map.InstallASTContext(*ast, *ast->getFileManager()); + + llvm::SmallVector<clang::NamedDecl *, 16> decls; + clang::DeclarationName name = getDeclarationName(*ast, "does_no_exist"); + const clang::DeclContext *dc = ast->GetTranslationUnitDecl(); + + NameSearchContext search(map, decls, name, dc); + map.FindExternalVisibleDecls(search); + + EXPECT_EQ(0U, decls.size()); +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits