[Lldb-commits] [lldb] 4aee81c - [lldb][NFC] Allow creating ClangExpressionDeclMap and ClangASTSource without a Target and add basic unit test

Raphael Isemann via lldb-commits lldb-commits at lists.llvm.org
Tue Dec 17 05:05:24 PST 2019


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());
+}


        


More information about the lldb-commits mailing list