[Lldb-commits] [lldb] [lldb][ExpressionParser][NFCI] Add new DoPrepareForExecution interface to be implemented by language plugins (PR #96290)

Michael Buch via lldb-commits lldb-commits at lists.llvm.org
Fri Jun 21 02:50:56 PDT 2024


https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/96290

This patch adds a new `DoPrepareForExecution` API, which can be implemented by the Clang and Swift language plugins. This also moves `RunStaticInitializers` into `ExpressionParser::PrepareForExecution`, so we call it consistently between language plugins.

This *should* be mostly NFC (the static initializers will still only run after we finished parsing). We've been living on this patch downstream for sometime now.

>From 67d8bab2d2d42ca3ec5d07efd3be94e614dde2e9 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Thu, 20 Jun 2024 18:29:15 +0100
Subject: [PATCH] [lldb][ExpressionParser] Add DoPrepareForExecution API

---
 .../lldb/Expression/ExpressionParser.h        | 25 ++++++-
 lldb/source/Expression/CMakeLists.txt         |  1 +
 lldb/source/Expression/ExpressionParser.cpp   | 73 +++++++++++++++++++
 .../Clang/ClangExpressionParser.cpp           | 46 +-----------
 .../Clang/ClangExpressionParser.h             | 23 ++----
 .../Clang/ClangUserExpression.cpp             | 15 ----
 6 files changed, 103 insertions(+), 80 deletions(-)
 create mode 100644 lldb/source/Expression/ExpressionParser.cpp

diff --git a/lldb/include/lldb/Expression/ExpressionParser.h b/lldb/include/lldb/Expression/ExpressionParser.h
index ab5223c915530..2ef7e036909c7 100644
--- a/lldb/include/lldb/Expression/ExpressionParser.h
+++ b/lldb/include/lldb/Expression/ExpressionParser.h
@@ -119,14 +119,35 @@ class ExpressionParser {
   /// \return
   ///     An error code indicating the success or failure of the operation.
   ///     Test with Success().
-  virtual Status
+  Status
   PrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end,
                       std::shared_ptr<IRExecutionUnit> &execution_unit_sp,
                       ExecutionContext &exe_ctx, bool &can_interpret,
-                      lldb_private::ExecutionPolicy execution_policy) = 0;
+                      lldb_private::ExecutionPolicy execution_policy);
 
   bool GetGenerateDebugInfo() const { return m_generate_debug_info; }
 
+protected:
+  virtual Status
+  DoPrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end,
+                        std::shared_ptr<IRExecutionUnit> &execution_unit_sp,
+                        ExecutionContext &exe_ctx, bool &can_interpret,
+                        lldb_private::ExecutionPolicy execution_policy) = 0;
+
+private:
+  /// Run all static initializers for an execution unit.
+  ///
+  /// \param[in] execution_unit_sp
+  ///     The execution unit.
+  ///
+  /// \param[in] exe_ctx
+  ///     The execution context to use when running them.  Thread can't be null.
+  ///
+  /// \return
+  ///     The error code indicating the
+  Status RunStaticInitializers(lldb::IRExecutionUnitSP &execution_unit_sp,
+                               ExecutionContext &exe_ctx);
+
 protected:
   Expression &m_expr; ///< The expression to be parsed
   bool m_generate_debug_info;
diff --git a/lldb/source/Expression/CMakeLists.txt b/lldb/source/Expression/CMakeLists.txt
index 9ba5fefc09b6a..be1e132f7aaad 100644
--- a/lldb/source/Expression/CMakeLists.txt
+++ b/lldb/source/Expression/CMakeLists.txt
@@ -3,6 +3,7 @@ add_lldb_library(lldbExpression NO_PLUGIN_DEPENDENCIES
   DWARFExpression.cpp
   DWARFExpressionList.cpp
   Expression.cpp
+  ExpressionParser.cpp
   ExpressionTypeSystemHelper.cpp
   ExpressionVariable.cpp
   FunctionCaller.cpp
diff --git a/lldb/source/Expression/ExpressionParser.cpp b/lldb/source/Expression/ExpressionParser.cpp
new file mode 100644
index 0000000000000..ac727be78e8d3
--- /dev/null
+++ b/lldb/source/Expression/ExpressionParser.cpp
@@ -0,0 +1,73 @@
+//===-- ExpressionParser.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 "lldb/Expression/ExpressionParser.h"
+#include "lldb/Expression/DiagnosticManager.h"
+#include "lldb/Expression/IRExecutionUnit.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/ThreadPlanCallFunction.h"
+
+using namespace lldb_private;
+
+Status ExpressionParser::PrepareForExecution(
+    lldb::addr_t &func_addr, lldb::addr_t &func_end,
+    std::shared_ptr<IRExecutionUnit> &execution_unit_sp,
+    ExecutionContext &exe_ctx, bool &can_interpret,
+    lldb_private::ExecutionPolicy execution_policy) {
+  Status status =
+      DoPrepareForExecution(func_addr, func_end, execution_unit_sp, exe_ctx,
+                            can_interpret, execution_policy);
+  if (status.Success() && exe_ctx.GetProcessPtr() && exe_ctx.HasThreadScope()) {
+    status = RunStaticInitializers(execution_unit_sp, exe_ctx);
+  }
+  return status;
+}
+
+Status ExpressionParser::RunStaticInitializers(
+    lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx) {
+  lldb_private::Status err;
+
+  lldbassert(execution_unit_sp.get());
+  lldbassert(exe_ctx.HasThreadScope());
+
+  if (!execution_unit_sp.get()) {
+    err.SetErrorString(
+        "can't run static initializers for a NULL execution unit");
+    return err;
+  }
+
+  if (!exe_ctx.HasThreadScope()) {
+    err.SetErrorString("can't run static initializers without a thread");
+    return err;
+  }
+
+  std::vector<lldb::addr_t> static_initializers;
+
+  execution_unit_sp->GetStaticInitializers(static_initializers);
+
+  for (lldb::addr_t static_initializer : static_initializers) {
+    EvaluateExpressionOptions options;
+
+    lldb::ThreadPlanSP call_static_initializer(new ThreadPlanCallFunction(
+        exe_ctx.GetThreadRef(), Address(static_initializer), CompilerType(),
+        llvm::ArrayRef<lldb::addr_t>(), options));
+
+    DiagnosticManager execution_errors;
+    lldb::ExpressionResults results =
+        exe_ctx.GetThreadRef().GetProcess()->RunThreadPlan(
+            exe_ctx, call_static_initializer, options, execution_errors);
+
+    if (results != lldb::eExpressionCompleted) {
+      err.SetErrorStringWithFormat("couldn't run static initializer: %s",
+                                   execution_errors.GetString().c_str());
+      return err;
+    }
+  }
+
+  return err;
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 1dd98567f8d69..303e88feea20b 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -1296,7 +1296,7 @@ static bool FindFunctionInModule(ConstString &mangled_name,
   return false;
 }
 
-lldb_private::Status ClangExpressionParser::PrepareForExecution(
+lldb_private::Status ClangExpressionParser::DoPrepareForExecution(
     lldb::addr_t &func_addr, lldb::addr_t &func_end,
     lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx,
     bool &can_interpret, ExecutionPolicy execution_policy) {
@@ -1472,47 +1472,3 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
 
   return err;
 }
-
-lldb_private::Status ClangExpressionParser::RunStaticInitializers(
-    lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx) {
-  lldb_private::Status err;
-
-  lldbassert(execution_unit_sp.get());
-  lldbassert(exe_ctx.HasThreadScope());
-
-  if (!execution_unit_sp.get()) {
-    err.SetErrorString(
-        "can't run static initializers for a NULL execution unit");
-    return err;
-  }
-
-  if (!exe_ctx.HasThreadScope()) {
-    err.SetErrorString("can't run static initializers without a thread");
-    return err;
-  }
-
-  std::vector<lldb::addr_t> static_initializers;
-
-  execution_unit_sp->GetStaticInitializers(static_initializers);
-
-  for (lldb::addr_t static_initializer : static_initializers) {
-    EvaluateExpressionOptions options;
-
-    lldb::ThreadPlanSP call_static_initializer(new ThreadPlanCallFunction(
-        exe_ctx.GetThreadRef(), Address(static_initializer), CompilerType(),
-        llvm::ArrayRef<lldb::addr_t>(), options));
-
-    DiagnosticManager execution_errors;
-    lldb::ExpressionResults results =
-        exe_ctx.GetThreadRef().GetProcess()->RunThreadPlan(
-            exe_ctx, call_static_initializer, options, execution_errors);
-
-    if (results != lldb::eExpressionCompleted) {
-      err.SetErrorStringWithFormat("couldn't run static initializer: %s",
-                                   execution_errors.GetString().c_str());
-      return err;
-    }
-  }
-
-  return err;
-}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index 185a5a381f23c..0852e928a9d42 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -113,24 +113,11 @@ class ClangExpressionParser : public ExpressionParser {
   /// \return
   ///     An error code indicating the success or failure of the operation.
   ///     Test with Success().
-  Status
-  PrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end,
-                      lldb::IRExecutionUnitSP &execution_unit_sp,
-                      ExecutionContext &exe_ctx, bool &can_interpret,
-                      lldb_private::ExecutionPolicy execution_policy) override;
-
-  /// Run all static initializers for an execution unit.
-  ///
-  /// \param[in] execution_unit_sp
-  ///     The execution unit.
-  ///
-  /// \param[in] exe_ctx
-  ///     The execution context to use when running them.  Thread can't be null.
-  ///
-  /// \return
-  ///     The error code indicating the
-  Status RunStaticInitializers(lldb::IRExecutionUnitSP &execution_unit_sp,
-                               ExecutionContext &exe_ctx);
+  Status DoPrepareForExecution(
+      lldb::addr_t &func_addr, lldb::addr_t &func_end,
+      lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx,
+      bool &can_interpret,
+      lldb_private::ExecutionPolicy execution_policy) override;
 
   /// Returns a string representing current ABI.
   ///
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index c7e98d12590d9..35038a56440d5 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -698,21 +698,6 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
   if (!parse_success)
     return false;
 
-  if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel) {
-    Status static_init_error =
-        m_parser->RunStaticInitializers(m_execution_unit_sp, exe_ctx);
-
-    if (!static_init_error.Success()) {
-      const char *error_cstr = static_init_error.AsCString();
-      if (error_cstr && error_cstr[0])
-        diagnostic_manager.Printf(lldb::eSeverityError, "%s\n", error_cstr);
-      else
-        diagnostic_manager.PutString(lldb::eSeverityError,
-                                     "couldn't run static initializers\n");
-      return false;
-    }
-  }
-
   if (m_execution_unit_sp) {
     bool register_execution_unit = false;
 



More information about the lldb-commits mailing list