1151c032cSJim Ingham //===-- UserExpression.cpp ---------------------------------*- C++ -*-===// 2151c032cSJim Ingham // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6151c032cSJim Ingham // 7151c032cSJim Ingham //===----------------------------------------------------------------------===// 8151c032cSJim Ingham 9c6551bf0SHaibo Huang #include "lldb/Host/Config.h" 10c6551bf0SHaibo Huang 11151c032cSJim Ingham #include <stdio.h> 12151c032cSJim Ingham #if HAVE_SYS_TYPES_H 13151c032cSJim Ingham #include <sys/types.h> 14151c032cSJim Ingham #endif 15151c032cSJim Ingham 16151c032cSJim Ingham #include <cstdlib> 17151c032cSJim Ingham #include <map> 18b9c1b51eSKate Stone #include <string> 19151c032cSJim Ingham 20151c032cSJim Ingham #include "lldb/Core/Module.h" 21151c032cSJim Ingham #include "lldb/Core/StreamFile.h" 22151c032cSJim Ingham #include "lldb/Core/ValueObjectConstResult.h" 23579e70c9SSean Callanan #include "lldb/Expression/DiagnosticManager.h" 248b6071f5SAlex Langford #include "lldb/Expression/ExpressionVariable.h" 25151c032cSJim Ingham #include "lldb/Expression/IRExecutionUnit.h" 26151c032cSJim Ingham #include "lldb/Expression/IRInterpreter.h" 27151c032cSJim Ingham #include "lldb/Expression/Materializer.h" 28151c032cSJim Ingham #include "lldb/Expression/UserExpression.h" 29151c032cSJim Ingham #include "lldb/Host/HostInfo.h" 30151c032cSJim Ingham #include "lldb/Symbol/Block.h" 31151c032cSJim Ingham #include "lldb/Symbol/Function.h" 32151c032cSJim Ingham #include "lldb/Symbol/ObjectFile.h" 33151c032cSJim Ingham #include "lldb/Symbol/SymbolVendor.h" 34151c032cSJim Ingham #include "lldb/Symbol/Type.h" 358f1f9a1bSSean Callanan #include "lldb/Symbol/TypeSystem.h" 36151c032cSJim Ingham #include "lldb/Symbol/VariableList.h" 37151c032cSJim Ingham #include "lldb/Target/ExecutionContext.h" 38151c032cSJim Ingham #include "lldb/Target/Process.h" 39151c032cSJim Ingham #include "lldb/Target/StackFrame.h" 40151c032cSJim Ingham #include "lldb/Target/Target.h" 41151c032cSJim Ingham #include "lldb/Target/ThreadPlan.h" 42151c032cSJim Ingham #include "lldb/Target/ThreadPlanCallUserExpression.h" 43bf9a7730SZachary Turner #include "lldb/Utility/ConstString.h" 446f9e6901SZachary Turner #include "lldb/Utility/Log.h" 45bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h" 46151c032cSJim Ingham 47151c032cSJim Ingham using namespace lldb_private; 48151c032cSJim Ingham 49*52f3a2faSRaphael Isemann char UserExpression::ID; 50*52f3a2faSRaphael Isemann 5119a63fc6SJim Ingham UserExpression::UserExpression(ExecutionContextScope &exe_scope, 52c5d7df90SZachary Turner llvm::StringRef expr, llvm::StringRef prefix, 5319a63fc6SJim Ingham lldb::LanguageType language, 5419a63fc6SJim Ingham ResultType desired_type, 55*52f3a2faSRaphael Isemann const EvaluateExpressionOptions &options) 56*52f3a2faSRaphael Isemann : Expression(exe_scope), m_expr_text(expr), m_expr_prefix(prefix), 57c5d7df90SZachary Turner m_language(language), m_desired_type(desired_type), m_options(options) {} 58151c032cSJim Ingham 59b9c1b51eSKate Stone UserExpression::~UserExpression() {} 60151c032cSJim Ingham 61b9c1b51eSKate Stone void UserExpression::InstallContext(ExecutionContext &exe_ctx) { 62151c032cSJim Ingham m_jit_process_wp = exe_ctx.GetProcessSP(); 63151c032cSJim Ingham 64151c032cSJim Ingham lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP(); 65151c032cSJim Ingham 66151c032cSJim Ingham if (frame_sp) 67151c032cSJim Ingham m_address = frame_sp->GetFrameCodeAddress(); 68151c032cSJim Ingham } 69151c032cSJim Ingham 70b9c1b51eSKate Stone bool UserExpression::LockAndCheckContext(ExecutionContext &exe_ctx, 71151c032cSJim Ingham lldb::TargetSP &target_sp, 72151c032cSJim Ingham lldb::ProcessSP &process_sp, 73b9c1b51eSKate Stone lldb::StackFrameSP &frame_sp) { 74151c032cSJim Ingham lldb::ProcessSP expected_process_sp = m_jit_process_wp.lock(); 75151c032cSJim Ingham process_sp = exe_ctx.GetProcessSP(); 76151c032cSJim Ingham 77151c032cSJim Ingham if (process_sp != expected_process_sp) 78151c032cSJim Ingham return false; 79151c032cSJim Ingham 80151c032cSJim Ingham process_sp = exe_ctx.GetProcessSP(); 81151c032cSJim Ingham target_sp = exe_ctx.GetTargetSP(); 82151c032cSJim Ingham frame_sp = exe_ctx.GetFrameSP(); 83151c032cSJim Ingham 84b9c1b51eSKate Stone if (m_address.IsValid()) { 85151c032cSJim Ingham if (!frame_sp) 86151c032cSJim Ingham return false; 87151c032cSJim Ingham else 88b9c1b51eSKate Stone return (0 == Address::CompareLoadAddress(m_address, 89b9c1b51eSKate Stone frame_sp->GetFrameCodeAddress(), 90b9c1b51eSKate Stone target_sp.get())); 91151c032cSJim Ingham } 92151c032cSJim Ingham 93151c032cSJim Ingham return true; 94151c032cSJim Ingham } 95151c032cSJim Ingham 96b9c1b51eSKate Stone bool UserExpression::MatchesContext(ExecutionContext &exe_ctx) { 97151c032cSJim Ingham lldb::TargetSP target_sp; 98151c032cSJim Ingham lldb::ProcessSP process_sp; 99151c032cSJim Ingham lldb::StackFrameSP frame_sp; 100151c032cSJim Ingham 101151c032cSJim Ingham return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp); 102151c032cSJim Ingham } 103151c032cSJim Ingham 104b9c1b51eSKate Stone lldb::addr_t UserExpression::GetObjectPointer(lldb::StackFrameSP frame_sp, 105151c032cSJim Ingham ConstString &object_name, 10697206d57SZachary Turner Status &err) { 107151c032cSJim Ingham err.Clear(); 108151c032cSJim Ingham 109b9c1b51eSKate Stone if (!frame_sp) { 110b9c1b51eSKate Stone err.SetErrorStringWithFormat( 111b9c1b51eSKate Stone "Couldn't load '%s' because the context is incomplete", 112b9c1b51eSKate Stone object_name.AsCString()); 113151c032cSJim Ingham return LLDB_INVALID_ADDRESS; 114151c032cSJim Ingham } 115151c032cSJim Ingham 116151c032cSJim Ingham lldb::VariableSP var_sp; 117151c032cSJim Ingham lldb::ValueObjectSP valobj_sp; 118151c032cSJim Ingham 119b9c1b51eSKate Stone valobj_sp = frame_sp->GetValueForVariableExpressionPath( 120b9c1b51eSKate Stone object_name.AsCString(), lldb::eNoDynamicValues, 121151c032cSJim Ingham StackFrame::eExpressionPathOptionCheckPtrVsMember | 122151c032cSJim Ingham StackFrame::eExpressionPathOptionsNoFragileObjcIvar | 123151c032cSJim Ingham StackFrame::eExpressionPathOptionsNoSyntheticChildren | 124151c032cSJim Ingham StackFrame::eExpressionPathOptionsNoSyntheticArrayRange, 125b9c1b51eSKate Stone var_sp, err); 126151c032cSJim Ingham 127151c032cSJim Ingham if (!err.Success() || !valobj_sp.get()) 128151c032cSJim Ingham return LLDB_INVALID_ADDRESS; 129151c032cSJim Ingham 130151c032cSJim Ingham lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 131151c032cSJim Ingham 132b9c1b51eSKate Stone if (ret == LLDB_INVALID_ADDRESS) { 133b9c1b51eSKate Stone err.SetErrorStringWithFormat( 134b9c1b51eSKate Stone "Couldn't load '%s' because its value couldn't be evaluated", 135b9c1b51eSKate Stone object_name.AsCString()); 136151c032cSJim Ingham return LLDB_INVALID_ADDRESS; 137151c032cSJim Ingham } 138151c032cSJim Ingham 139151c032cSJim Ingham return ret; 140151c032cSJim Ingham } 141151c032cSJim Ingham 142b9c1b51eSKate Stone lldb::ExpressionResults UserExpression::Evaluate( 143b9c1b51eSKate Stone ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, 144c5d7df90SZachary Turner llvm::StringRef expr, llvm::StringRef prefix, 14581dbc026SAlex Langford lldb::ValueObjectSP &result_valobj_sp, Status &error, 14640624a08SAleksandr Urakov std::string *fixed_expression, lldb::ModuleSP *jit_module_sp_ptr, 14740624a08SAleksandr Urakov ValueObject *ctx_obj) { 148b9c1b51eSKate Stone Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | 149b9c1b51eSKate Stone LIBLLDB_LOG_STEP)); 150151c032cSJim Ingham 15140624a08SAleksandr Urakov if (ctx_obj) { 15240624a08SAleksandr Urakov static unsigned const ctx_type_mask = 15340624a08SAleksandr Urakov lldb::TypeFlags::eTypeIsClass | lldb::TypeFlags::eTypeIsStructUnion; 15440624a08SAleksandr Urakov if (!(ctx_obj->GetTypeInfo() & ctx_type_mask)) { 15540624a08SAleksandr Urakov LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a context object of " 15640624a08SAleksandr Urakov "an invalid type, can't run expressions."); 15740624a08SAleksandr Urakov error.SetErrorString("a context object of an invalid type passed"); 15840624a08SAleksandr Urakov return lldb::eExpressionSetupError; 15940624a08SAleksandr Urakov } 16040624a08SAleksandr Urakov } 16140624a08SAleksandr Urakov 162151c032cSJim Ingham lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy(); 1631bbaede5SDawn Perchik lldb::LanguageType language = options.GetLanguage(); 164b9c1b51eSKate Stone const ResultType desired_type = options.DoesCoerceToId() 165b9c1b51eSKate Stone ? UserExpression::eResultTypeId 166b9c1b51eSKate Stone : UserExpression::eResultTypeAny; 167151c032cSJim Ingham lldb::ExpressionResults execution_results = lldb::eExpressionSetupError; 168151c032cSJim Ingham 169151c032cSJim Ingham Target *target = exe_ctx.GetTargetPtr(); 170b9c1b51eSKate Stone if (!target) { 17163e5fb76SJonas Devlieghere LLDB_LOGF(log, "== [UserExpression::Evaluate] Passed a NULL target, can't " 172b9c1b51eSKate Stone "run expressions."); 17302980825SJim Ingham error.SetErrorString("expression passed a null target"); 174151c032cSJim Ingham return lldb::eExpressionSetupError; 175151c032cSJim Ingham } 176151c032cSJim Ingham 177151c032cSJim Ingham Process *process = exe_ctx.GetProcessPtr(); 178151c032cSJim Ingham 179248a1305SKonrad Kleine if (process == nullptr || process->GetState() != lldb::eStateStopped) { 180b9c1b51eSKate Stone if (execution_policy == eExecutionPolicyAlways) { 18163e5fb76SJonas Devlieghere LLDB_LOGF(log, 18263e5fb76SJonas Devlieghere "== [UserExpression::Evaluate] Expression may not run, but " 183b9c1b51eSKate Stone "is not constant =="); 184151c032cSJim Ingham 185151c032cSJim Ingham error.SetErrorString("expression needed to run but couldn't"); 186151c032cSJim Ingham 187151c032cSJim Ingham return execution_results; 188151c032cSJim Ingham } 189151c032cSJim Ingham } 190151c032cSJim Ingham 191248a1305SKonrad Kleine if (process == nullptr || !process->CanJIT()) 192151c032cSJim Ingham execution_policy = eExecutionPolicyNever; 1936896b355SJim Ingham 194b9c1b51eSKate Stone // We need to set the expression execution thread here, turns out parse can 19505097246SAdrian Prantl // call functions in the process of looking up symbols, which will escape the 19605097246SAdrian Prantl // context set by exe_ctx passed to Execute. 1976896b355SJim Ingham lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP(); 198b9c1b51eSKate Stone ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher( 199b9c1b51eSKate Stone thread_sp); 200151c032cSJim Ingham 201c5d7df90SZachary Turner llvm::StringRef full_prefix; 202c5d7df90SZachary Turner llvm::StringRef option_prefix(options.GetPrefix()); 203151c032cSJim Ingham std::string full_prefix_storage; 204c5d7df90SZachary Turner if (!prefix.empty() && !option_prefix.empty()) { 205c5d7df90SZachary Turner full_prefix_storage = prefix; 206151c032cSJim Ingham full_prefix_storage.append(option_prefix); 207c5d7df90SZachary Turner full_prefix = full_prefix_storage; 208c5d7df90SZachary Turner } else if (!prefix.empty()) 209c5d7df90SZachary Turner full_prefix = prefix; 210151c032cSJim Ingham else 211151c032cSJim Ingham full_prefix = option_prefix; 212151c032cSJim Ingham 21305097246SAdrian Prantl // If the language was not specified in the expression command, set it to the 21405097246SAdrian Prantl // language in the target's properties if specified, else default to the 21505097246SAdrian Prantl // langage for the frame. 216b9c1b51eSKate Stone if (language == lldb::eLanguageTypeUnknown) { 2171bbaede5SDawn Perchik if (target->GetLanguage() != lldb::eLanguageTypeUnknown) 2181bbaede5SDawn Perchik language = target->GetLanguage(); 2191bbaede5SDawn Perchik else if (StackFrame *frame = exe_ctx.GetFramePtr()) 2201bbaede5SDawn Perchik language = frame->GetLanguage(); 2211bbaede5SDawn Perchik } 2221bbaede5SDawn Perchik 223b9c1b51eSKate Stone lldb::UserExpressionSP user_expression_sp( 224c5d7df90SZachary Turner target->GetUserExpressionForLanguage(expr, full_prefix, language, 22540624a08SAleksandr Urakov desired_type, options, ctx_obj, 22640624a08SAleksandr Urakov error)); 227b9c1b51eSKate Stone if (error.Fail()) { 228151c032cSJim Ingham if (log) 22963e5fb76SJonas Devlieghere LLDB_LOGF(log, "== [UserExpression::Evaluate] Getting expression: %s ==", 230b9c1b51eSKate Stone error.AsCString()); 231151c032cSJim Ingham return lldb::eExpressionSetupError; 232151c032cSJim Ingham } 233151c032cSJim Ingham 234151c032cSJim Ingham if (log) 23563e5fb76SJonas Devlieghere LLDB_LOGF(log, "== [UserExpression::Evaluate] Parsing expression %s ==", 236c5d7df90SZachary Turner expr.str().c_str()); 237151c032cSJim Ingham 238151c032cSJim Ingham const bool keep_expression_in_memory = true; 239151c032cSJim Ingham const bool generate_debug_info = options.GetGenerateDebugInfo(); 240151c032cSJim Ingham 241b9c1b51eSKate Stone if (options.InvokeCancelCallback(lldb::eExpressionEvaluationParse)) { 242151c032cSJim Ingham error.SetErrorString("expression interrupted by callback before parse"); 243b9c1b51eSKate Stone result_valobj_sp = ValueObjectConstResult::Create( 244b9c1b51eSKate Stone exe_ctx.GetBestExecutionContextScope(), error); 245151c032cSJim Ingham return lldb::eExpressionInterrupted; 246151c032cSJim Ingham } 247151c032cSJim Ingham 248579e70c9SSean Callanan DiagnosticManager diagnostic_manager; 249579e70c9SSean Callanan 250b9c1b51eSKate Stone bool parse_success = 251b9c1b51eSKate Stone user_expression_sp->Parse(diagnostic_manager, exe_ctx, execution_policy, 252b9c1b51eSKate Stone keep_expression_in_memory, generate_debug_info); 253e5ee6f04SJim Ingham 254e5ee6f04SJim Ingham // Calculate the fixed expression always, since we need it for errors. 255e5ee6f04SJim Ingham std::string tmp_fixed_expression; 256e5ee6f04SJim Ingham if (fixed_expression == nullptr) 257e5ee6f04SJim Ingham fixed_expression = &tmp_fixed_expression; 258e5ee6f04SJim Ingham 259e5ee6f04SJim Ingham const char *fixed_text = user_expression_sp->GetFixedText(); 260e5ee6f04SJim Ingham if (fixed_text != nullptr) 261e5ee6f04SJim Ingham fixed_expression->append(fixed_text); 262e5ee6f04SJim Ingham 263e5ee6f04SJim Ingham // If there is a fixed expression, try to parse it: 264b9c1b51eSKate Stone if (!parse_success) { 265151c032cSJim Ingham execution_results = lldb::eExpressionParseError; 266b9c1b51eSKate Stone if (fixed_expression && !fixed_expression->empty() && 267b9c1b51eSKate Stone options.GetAutoApplyFixIts()) { 268b9c1b51eSKate Stone lldb::UserExpressionSP fixed_expression_sp( 269b9c1b51eSKate Stone target->GetUserExpressionForLanguage(fixed_expression->c_str(), 270b9c1b51eSKate Stone full_prefix, language, 27140624a08SAleksandr Urakov desired_type, options, ctx_obj, 27240624a08SAleksandr Urakov error)); 273e5ee6f04SJim Ingham DiagnosticManager fixed_diagnostic_manager; 274b9c1b51eSKate Stone parse_success = fixed_expression_sp->Parse( 275b9c1b51eSKate Stone fixed_diagnostic_manager, exe_ctx, execution_policy, 276b9c1b51eSKate Stone keep_expression_in_memory, generate_debug_info); 277b9c1b51eSKate Stone if (parse_success) { 278e5ee6f04SJim Ingham diagnostic_manager.Clear(); 279e5ee6f04SJim Ingham user_expression_sp = fixed_expression_sp; 280b9c1b51eSKate Stone } else { 281b9c1b51eSKate Stone // If the fixed expression failed to parse, don't tell the user about, 282b9c1b51eSKate Stone // that won't help. 283b29c42f9SJim Ingham fixed_expression->clear(); 284b29c42f9SJim Ingham } 285e5ee6f04SJim Ingham } 286e5ee6f04SJim Ingham 287b9c1b51eSKate Stone if (!parse_success) { 288b9c1b51eSKate Stone if (!fixed_expression->empty() && target->GetEnableNotifyAboutFixIts()) { 289b9c1b51eSKate Stone error.SetExpressionErrorWithFormat( 290b9c1b51eSKate Stone execution_results, 291b9c1b51eSKate Stone "expression failed to parse, fixed expression suggested:\n %s", 292e5ee6f04SJim Ingham fixed_expression->c_str()); 293b9c1b51eSKate Stone } else { 294579e70c9SSean Callanan if (!diagnostic_manager.Diagnostics().size()) 295b9c1b51eSKate Stone error.SetExpressionError(execution_results, 296b9c1b51eSKate Stone "expression failed to parse, unknown error"); 297151c032cSJim Ingham else 298b9c1b51eSKate Stone error.SetExpressionError(execution_results, 299b9c1b51eSKate Stone diagnostic_manager.GetString().c_str()); 300151c032cSJim Ingham } 301e5ee6f04SJim Ingham } 302e5ee6f04SJim Ingham } 303e5ee6f04SJim Ingham 304b9c1b51eSKate Stone if (parse_success) { 305b9c1b51eSKate Stone // If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module 306b9c1b51eSKate Stone // if one was created 307998c8a1cSRyan Brown if (jit_module_sp_ptr) 308998c8a1cSRyan Brown *jit_module_sp_ptr = user_expression_sp->GetJITModule(); 3096681041dSSean Callanan 310151c032cSJim Ingham lldb::ExpressionVariableSP expr_result; 311151c032cSJim Ingham 312151c032cSJim Ingham if (execution_policy == eExecutionPolicyNever && 313b9c1b51eSKate Stone !user_expression_sp->CanInterpret()) { 314151c032cSJim Ingham if (log) 31563e5fb76SJonas Devlieghere LLDB_LOGF(log, 31663e5fb76SJonas Devlieghere "== [UserExpression::Evaluate] Expression may not run, but " 317b9c1b51eSKate Stone "is not constant =="); 318151c032cSJim Ingham 319579e70c9SSean Callanan if (!diagnostic_manager.Diagnostics().size()) 320b9c1b51eSKate Stone error.SetExpressionError(lldb::eExpressionSetupError, 321b9c1b51eSKate Stone "expression needed to run but couldn't"); 322b9c1b51eSKate Stone } else if (execution_policy == eExecutionPolicyTopLevel) { 323a35912daSKrasimir Georgiev error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); 3242ff00003SSean Callanan return lldb::eExpressionCompleted; 325b9c1b51eSKate Stone } else { 326b9c1b51eSKate Stone if (options.InvokeCancelCallback(lldb::eExpressionEvaluationExecution)) { 327b9c1b51eSKate Stone error.SetExpressionError( 328b9c1b51eSKate Stone lldb::eExpressionInterrupted, 329b9c1b51eSKate Stone "expression interrupted by callback before execution"); 330b9c1b51eSKate Stone result_valobj_sp = ValueObjectConstResult::Create( 331b9c1b51eSKate Stone exe_ctx.GetBestExecutionContextScope(), error); 332151c032cSJim Ingham return lldb::eExpressionInterrupted; 333151c032cSJim Ingham } 334151c032cSJim Ingham 335579e70c9SSean Callanan diagnostic_manager.Clear(); 336151c032cSJim Ingham 337151c032cSJim Ingham if (log) 33863e5fb76SJonas Devlieghere LLDB_LOGF(log, "== [UserExpression::Evaluate] Executing expression =="); 339151c032cSJim Ingham 340579e70c9SSean Callanan execution_results = 341b9c1b51eSKate Stone user_expression_sp->Execute(diagnostic_manager, exe_ctx, options, 342b9c1b51eSKate Stone user_expression_sp, expr_result); 343151c032cSJim Ingham 344b9c1b51eSKate Stone if (execution_results != lldb::eExpressionCompleted) { 345151c032cSJim Ingham if (log) 34663e5fb76SJonas Devlieghere LLDB_LOGF(log, "== [UserExpression::Evaluate] Execution completed " 347b9c1b51eSKate Stone "abnormally =="); 348151c032cSJim Ingham 349579e70c9SSean Callanan if (!diagnostic_manager.Diagnostics().size()) 350b9c1b51eSKate Stone error.SetExpressionError( 351b9c1b51eSKate Stone execution_results, "expression failed to execute, unknown error"); 352151c032cSJim Ingham else 353b9c1b51eSKate Stone error.SetExpressionError(execution_results, 354b9c1b51eSKate Stone diagnostic_manager.GetString().c_str()); 355b9c1b51eSKate Stone } else { 356b9c1b51eSKate Stone if (expr_result) { 357151c032cSJim Ingham result_valobj_sp = expr_result->GetValueObject(); 358151c032cSJim Ingham 359151c032cSJim Ingham if (log) 36063e5fb76SJonas Devlieghere LLDB_LOGF(log, 36163e5fb76SJonas Devlieghere "== [UserExpression::Evaluate] Execution completed " 362b9c1b51eSKate Stone "normally with result %s ==", 363151c032cSJim Ingham result_valobj_sp->GetValueAsCString()); 364b9c1b51eSKate Stone } else { 365151c032cSJim Ingham if (log) 36663e5fb76SJonas Devlieghere LLDB_LOGF(log, "== [UserExpression::Evaluate] Execution completed " 367b9c1b51eSKate Stone "normally with no result =="); 368151c032cSJim Ingham 369a35912daSKrasimir Georgiev error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); 370151c032cSJim Ingham } 371151c032cSJim Ingham } 372151c032cSJim Ingham } 373151c032cSJim Ingham } 374151c032cSJim Ingham 375b9c1b51eSKate Stone if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete)) { 376b9c1b51eSKate Stone error.SetExpressionError( 377b9c1b51eSKate Stone lldb::eExpressionInterrupted, 378b9c1b51eSKate Stone "expression interrupted by callback after complete"); 379151c032cSJim Ingham return lldb::eExpressionInterrupted; 380151c032cSJim Ingham } 381151c032cSJim Ingham 382248a1305SKonrad Kleine if (result_valobj_sp.get() == nullptr) { 383b9c1b51eSKate Stone result_valobj_sp = ValueObjectConstResult::Create( 384b9c1b51eSKate Stone exe_ctx.GetBestExecutionContextScope(), error); 385151c032cSJim Ingham } 386151c032cSJim Ingham 387151c032cSJim Ingham return execution_results; 388151c032cSJim Ingham } 389ff7ac6a7SJim Ingham 390ff7ac6a7SJim Ingham lldb::ExpressionResults 391ff7ac6a7SJim Ingham UserExpression::Execute(DiagnosticManager &diagnostic_manager, 392ff7ac6a7SJim Ingham ExecutionContext &exe_ctx, 393ff7ac6a7SJim Ingham const EvaluateExpressionOptions &options, 394ff7ac6a7SJim Ingham lldb::UserExpressionSP &shared_ptr_to_me, 395b9c1b51eSKate Stone lldb::ExpressionVariableSP &result_var) { 396b9c1b51eSKate Stone lldb::ExpressionResults expr_result = DoExecute( 397b9c1b51eSKate Stone diagnostic_manager, exe_ctx, options, shared_ptr_to_me, result_var); 398ff7ac6a7SJim Ingham Target *target = exe_ctx.GetTargetPtr(); 399b9c1b51eSKate Stone if (options.GetResultIsInternal() && result_var && target) { 400b9c1b51eSKate Stone target->GetPersistentExpressionStateForLanguage(m_language) 401b9c1b51eSKate Stone ->RemovePersistentVariable(result_var); 402ff7ac6a7SJim Ingham } 403ff7ac6a7SJim Ingham return expr_result; 404ff7ac6a7SJim Ingham } 405