summaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp161
1 files changed, 161 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
new file mode 100644
index 000000000000..5eec224477fc
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -0,0 +1,161 @@
+//===-- ClangUtilityFunction.cpp ---------------------------------*- C++-*-===//
+//
+// 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 "ClangUtilityFunction.h"
+#include "ClangExpressionDeclMap.h"
+#include "ClangExpressionParser.h"
+#include "ClangExpressionSourceCode.h"
+
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Expression/IRExecutionUnit.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Stream.h"
+
+using namespace lldb_private;
+
+/// Constructor
+///
+/// \param[in] text
+/// The text of the function. Must be a full translation unit.
+///
+/// \param[in] name
+/// The name of the function, as used in the text.
+ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope,
+ const char *text, const char *name)
+ : UtilityFunction(exe_scope, text, name, eKindClangUtilityFunction) {
+ m_function_text.assign(ClangExpressionSourceCode::g_expression_prefix);
+ if (text && text[0])
+ m_function_text.append(text);
+}
+
+ClangUtilityFunction::~ClangUtilityFunction() {}
+
+/// Install the utility function into a process
+///
+/// \param[in] diagnostic_manager
+/// A diagnostic manager to report errors and warnings to.
+///
+/// \param[in] exe_ctx
+/// The execution context to install the utility function to.
+///
+/// \return
+/// True on success (no errors); false otherwise.
+bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx) {
+ if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
+ diagnostic_manager.PutString(eDiagnosticSeverityWarning,
+ "already installed");
+ return false;
+ }
+
+ ////////////////////////////////////
+ // Set up the target and compiler
+ //
+
+ Target *target = exe_ctx.GetTargetPtr();
+
+ if (!target) {
+ diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target");
+ return false;
+ }
+
+ Process *process = exe_ctx.GetProcessPtr();
+
+ if (!process) {
+ diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid process");
+ return false;
+ }
+
+ //////////////////////////
+ // Parse the expression
+ //
+
+ bool keep_result_in_memory = false;
+
+ ResetDeclMap(exe_ctx, keep_result_in_memory);
+
+ if (!DeclMap()->WillParse(exe_ctx, nullptr)) {
+ diagnostic_manager.PutString(
+ eDiagnosticSeverityError,
+ "current process state is unsuitable for expression parsing");
+ return false;
+ }
+
+ const bool generate_debug_info = true;
+ ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this,
+ generate_debug_info);
+
+ unsigned num_errors = parser.Parse(diagnostic_manager);
+
+ if (num_errors) {
+ ResetDeclMap();
+
+ return false;
+ }
+
+ //////////////////////////////////
+ // JIT the output of the parser
+ //
+
+ bool can_interpret = false; // should stay that way
+
+ Status jit_error = parser.PrepareForExecution(
+ m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
+ can_interpret, eExecutionPolicyAlways);
+
+ if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
+ m_jit_process_wp = process->shared_from_this();
+ if (parser.GetGenerateDebugInfo()) {
+ lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
+
+ if (jit_module_sp) {
+ ConstString const_func_name(FunctionName());
+ FileSpec jit_file;
+ jit_file.GetFilename() = const_func_name;
+ jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
+ m_jit_module_wp = jit_module_sp;
+ target->GetImages().Append(jit_module_sp);
+ }
+ }
+ }
+
+ DeclMap()->DidParse();
+
+ ResetDeclMap();
+
+ if (jit_error.Success()) {
+ return true;
+ } else {
+ const char *error_cstr = jit_error.AsCString();
+ if (error_cstr && error_cstr[0]) {
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
+ } else {
+ diagnostic_manager.PutString(eDiagnosticSeverityError,
+ "expression can't be interpreted or run");
+ }
+ return false;
+ }
+}
+
+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));
+}