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 9*c6551bf0SHaibo Huang #include "lldb/Host/Config.h" 10*c6551bf0SHaibo 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 4919a63fc6SJim Ingham UserExpression::UserExpression(ExecutionContextScope &exe_scope, 50c5d7df90SZachary Turner llvm::StringRef expr, llvm::StringRef prefix, 5119a63fc6SJim Ingham lldb::LanguageType language, 5219a63fc6SJim Ingham ResultType desired_type, 537e34d78dSAdrian Prantl const EvaluateExpressionOptions &options, 547e34d78dSAdrian Prantl ExpressionKind kind) 557e34d78dSAdrian Prantl : Expression(exe_scope, kind), m_expr_text(expr), m_expr_prefix(prefix), 56c5d7df90SZachary Turner m_language(language), m_desired_type(desired_type), m_options(options) {} 57151c032cSJim Ingham 58b9c1b51eSKate Stone UserExpression::~UserExpression() {} 59151c032cSJim Ingham 60b9c1b51eSKate Stone void UserExpression::InstallContext(ExecutionContext &exe_ctx) { 61151c032cSJim Ingham m_jit_process_wp = exe_ctx.GetProcessSP(); 62151c032cSJim Ingham 63151c032cSJim Ingham lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP(); 64151c032cSJim Ingham 65151c032cSJim Ingham if (frame_sp) 66151c032cSJim Ingham m_address = frame_sp->GetFrameCodeAddress(); 67151c032cSJim Ingham } 68151c032cSJim Ingham 69b9c1b51eSKate Stone bool UserExpression::LockAndCheckContext(ExecutionContext &exe_ctx, 70151c032cSJim Ingham lldb::TargetSP &target_sp, 71151c032cSJim Ingham lldb::ProcessSP &process_sp, 72b9c1b51eSKate Stone lldb::StackFrameSP &frame_sp) { 73151c032cSJim Ingham lldb::ProcessSP expected_process_sp = m_jit_process_wp.lock(); 74151c032cSJim Ingham process_sp = exe_ctx.GetProcessSP(); 75151c032cSJim Ingham 76151c032cSJim Ingham if (process_sp != expected_process_sp) 77151c032cSJim Ingham return false; 78151c032cSJim Ingham 79151c032cSJim Ingham process_sp = exe_ctx.GetProcessSP(); 80151c032cSJim Ingham target_sp = exe_ctx.GetTargetSP(); 81151c032cSJim Ingham frame_sp = exe_ctx.GetFrameSP(); 82151c032cSJim Ingham 83b9c1b51eSKate Stone if (m_address.IsValid()) { 84151c032cSJim Ingham if (!frame_sp) 85151c032cSJim Ingham return false; 86151c032cSJim Ingham else 87b9c1b51eSKate Stone return (0 == Address::CompareLoadAddress(m_address, 88b9c1b51eSKate Stone frame_sp->GetFrameCodeAddress(), 89b9c1b51eSKate Stone target_sp.get())); 90151c032cSJim Ingham } 91151c032cSJim Ingham 92151c032cSJim Ingham return true; 93151c032cSJim Ingham } 94151c032cSJim Ingham 95b9c1b51eSKate Stone bool UserExpression::MatchesContext(ExecutionContext &exe_ctx) { 96151c032cSJim Ingham lldb::TargetSP target_sp; 97151c032cSJim Ingham lldb::ProcessSP process_sp; 98151c032cSJim Ingham lldb::StackFrameSP frame_sp; 99151c032cSJim Ingham 100151c032cSJim Ingham return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp); 101151c032cSJim Ingham } 102151c032cSJim Ingham 103b9c1b51eSKate Stone lldb::addr_t UserExpression::GetObjectPointer(lldb::StackFrameSP frame_sp, 104151c032cSJim Ingham ConstString &object_name, 10597206d57SZachary Turner Status &err) { 106151c032cSJim Ingham err.Clear(); 107151c032cSJim Ingham 108b9c1b51eSKate Stone if (!frame_sp) { 109b9c1b51eSKate Stone err.SetErrorStringWithFormat( 110b9c1b51eSKate Stone "Couldn't load '%s' because the context is incomplete", 111b9c1b51eSKate Stone object_name.AsCString()); 112151c032cSJim Ingham return LLDB_INVALID_ADDRESS; 113151c032cSJim Ingham } 114151c032cSJim Ingham 115151c032cSJim Ingham lldb::VariableSP var_sp; 116151c032cSJim Ingham lldb::ValueObjectSP valobj_sp; 117151c032cSJim Ingham 118b9c1b51eSKate Stone valobj_sp = frame_sp->GetValueForVariableExpressionPath( 119b9c1b51eSKate Stone object_name.AsCString(), lldb::eNoDynamicValues, 120151c032cSJim Ingham StackFrame::eExpressionPathOptionCheckPtrVsMember | 121151c032cSJim Ingham StackFrame::eExpressionPathOptionsNoFragileObjcIvar | 122151c032cSJim Ingham StackFrame::eExpressionPathOptionsNoSyntheticChildren | 123151c032cSJim Ingham StackFrame::eExpressionPathOptionsNoSyntheticArrayRange, 124b9c1b51eSKate Stone var_sp, err); 125151c032cSJim Ingham 126151c032cSJim Ingham if (!err.Success() || !valobj_sp.get()) 127151c032cSJim Ingham return LLDB_INVALID_ADDRESS; 128151c032cSJim Ingham 129151c032cSJim Ingham lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 130151c032cSJim Ingham 131b9c1b51eSKate Stone if (ret == LLDB_INVALID_ADDRESS) { 132b9c1b51eSKate Stone err.SetErrorStringWithFormat( 133b9c1b51eSKate Stone "Couldn't load '%s' because its value couldn't be evaluated", 134b9c1b51eSKate Stone object_name.AsCString()); 135151c032cSJim Ingham return LLDB_INVALID_ADDRESS; 136151c032cSJim Ingham } 137151c032cSJim Ingham 138151c032cSJim Ingham return ret; 139151c032cSJim Ingham } 140151c032cSJim Ingham 141b9c1b51eSKate Stone lldb::ExpressionResults UserExpression::Evaluate( 142b9c1b51eSKate Stone ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, 143c5d7df90SZachary Turner llvm::StringRef expr, llvm::StringRef prefix, 14481dbc026SAlex Langford lldb::ValueObjectSP &result_valobj_sp, Status &error, 14540624a08SAleksandr Urakov std::string *fixed_expression, lldb::ModuleSP *jit_module_sp_ptr, 14640624a08SAleksandr Urakov ValueObject *ctx_obj) { 147b9c1b51eSKate Stone Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | 148b9c1b51eSKate Stone LIBLLDB_LOG_STEP)); 149151c032cSJim Ingham 15040624a08SAleksandr Urakov if (ctx_obj) { 15140624a08SAleksandr Urakov static unsigned const ctx_type_mask = 15240624a08SAleksandr Urakov lldb::TypeFlags::eTypeIsClass | lldb::TypeFlags::eTypeIsStructUnion; 15340624a08SAleksandr Urakov if (!(ctx_obj->GetTypeInfo() & ctx_type_mask)) { 15440624a08SAleksandr Urakov LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a context object of " 15540624a08SAleksandr Urakov "an invalid type, can't run expressions."); 15640624a08SAleksandr Urakov error.SetErrorString("a context object of an invalid type passed"); 15740624a08SAleksandr Urakov return lldb::eExpressionSetupError; 15840624a08SAleksandr Urakov } 15940624a08SAleksandr Urakov } 16040624a08SAleksandr Urakov 161151c032cSJim Ingham lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy(); 1621bbaede5SDawn Perchik lldb::LanguageType language = options.GetLanguage(); 163b9c1b51eSKate Stone const ResultType desired_type = options.DoesCoerceToId() 164b9c1b51eSKate Stone ? UserExpression::eResultTypeId 165b9c1b51eSKate Stone : UserExpression::eResultTypeAny; 166151c032cSJim Ingham lldb::ExpressionResults execution_results = lldb::eExpressionSetupError; 167151c032cSJim Ingham 168151c032cSJim Ingham Target *target = exe_ctx.GetTargetPtr(); 169b9c1b51eSKate Stone if (!target) { 17063e5fb76SJonas Devlieghere LLDB_LOGF(log, "== [UserExpression::Evaluate] Passed a NULL target, can't " 171b9c1b51eSKate Stone "run expressions."); 17202980825SJim Ingham error.SetErrorString("expression passed a null target"); 173151c032cSJim Ingham return lldb::eExpressionSetupError; 174151c032cSJim Ingham } 175151c032cSJim Ingham 176151c032cSJim Ingham Process *process = exe_ctx.GetProcessPtr(); 177151c032cSJim Ingham 178248a1305SKonrad Kleine if (process == nullptr || process->GetState() != lldb::eStateStopped) { 179b9c1b51eSKate Stone if (execution_policy == eExecutionPolicyAlways) { 18063e5fb76SJonas Devlieghere LLDB_LOGF(log, 18163e5fb76SJonas Devlieghere "== [UserExpression::Evaluate] Expression may not run, but " 182b9c1b51eSKate Stone "is not constant =="); 183151c032cSJim Ingham 184151c032cSJim Ingham error.SetErrorString("expression needed to run but couldn't"); 185151c032cSJim Ingham 186151c032cSJim Ingham return execution_results; 187151c032cSJim Ingham } 188151c032cSJim Ingham } 189151c032cSJim Ingham 190248a1305SKonrad Kleine if (process == nullptr || !process->CanJIT()) 191151c032cSJim Ingham execution_policy = eExecutionPolicyNever; 1926896b355SJim Ingham 193b9c1b51eSKate Stone // We need to set the expression execution thread here, turns out parse can 19405097246SAdrian Prantl // call functions in the process of looking up symbols, which will escape the 19505097246SAdrian Prantl // context set by exe_ctx passed to Execute. 1966896b355SJim Ingham lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP(); 197b9c1b51eSKate Stone ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher( 198b9c1b51eSKate Stone thread_sp); 199151c032cSJim Ingham 200c5d7df90SZachary Turner llvm::StringRef full_prefix; 201c5d7df90SZachary Turner llvm::StringRef option_prefix(options.GetPrefix()); 202151c032cSJim Ingham std::string full_prefix_storage; 203c5d7df90SZachary Turner if (!prefix.empty() && !option_prefix.empty()) { 204c5d7df90SZachary Turner full_prefix_storage = prefix; 205151c032cSJim Ingham full_prefix_storage.append(option_prefix); 206c5d7df90SZachary Turner full_prefix = full_prefix_storage; 207c5d7df90SZachary Turner } else if (!prefix.empty()) 208c5d7df90SZachary Turner full_prefix = prefix; 209151c032cSJim Ingham else 210151c032cSJim Ingham full_prefix = option_prefix; 211151c032cSJim Ingham 21205097246SAdrian Prantl // If the language was not specified in the expression command, set it to the 21305097246SAdrian Prantl // language in the target's properties if specified, else default to the 21405097246SAdrian Prantl // langage for the frame. 215b9c1b51eSKate Stone if (language == lldb::eLanguageTypeUnknown) { 2161bbaede5SDawn Perchik if (target->GetLanguage() != lldb::eLanguageTypeUnknown) 2171bbaede5SDawn Perchik language = target->GetLanguage(); 2181bbaede5SDawn Perchik else if (StackFrame *frame = exe_ctx.GetFramePtr()) 2191bbaede5SDawn Perchik language = frame->GetLanguage(); 2201bbaede5SDawn Perchik } 2211bbaede5SDawn Perchik 222b9c1b51eSKate Stone lldb::UserExpressionSP user_expression_sp( 223c5d7df90SZachary Turner target->GetUserExpressionForLanguage(expr, full_prefix, language, 22440624a08SAleksandr Urakov desired_type, options, ctx_obj, 22540624a08SAleksandr Urakov error)); 226b9c1b51eSKate Stone if (error.Fail()) { 227151c032cSJim Ingham if (log) 22863e5fb76SJonas Devlieghere LLDB_LOGF(log, "== [UserExpression::Evaluate] Getting expression: %s ==", 229b9c1b51eSKate Stone error.AsCString()); 230151c032cSJim Ingham return lldb::eExpressionSetupError; 231151c032cSJim Ingham } 232151c032cSJim Ingham 233151c032cSJim Ingham if (log) 23463e5fb76SJonas Devlieghere LLDB_LOGF(log, "== [UserExpression::Evaluate] Parsing expression %s ==", 235c5d7df90SZachary Turner expr.str().c_str()); 236151c032cSJim Ingham 237151c032cSJim Ingham const bool keep_expression_in_memory = true; 238151c032cSJim Ingham const bool generate_debug_info = options.GetGenerateDebugInfo(); 239151c032cSJim Ingham 240b9c1b51eSKate Stone if (options.InvokeCancelCallback(lldb::eExpressionEvaluationParse)) { 241151c032cSJim Ingham error.SetErrorString("expression interrupted by callback before parse"); 242b9c1b51eSKate Stone result_valobj_sp = ValueObjectConstResult::Create( 243b9c1b51eSKate Stone exe_ctx.GetBestExecutionContextScope(), error); 244151c032cSJim Ingham return lldb::eExpressionInterrupted; 245151c032cSJim Ingham } 246151c032cSJim Ingham 247579e70c9SSean Callanan DiagnosticManager diagnostic_manager; 248579e70c9SSean Callanan 249b9c1b51eSKate Stone bool parse_success = 250b9c1b51eSKate Stone user_expression_sp->Parse(diagnostic_manager, exe_ctx, execution_policy, 251b9c1b51eSKate Stone keep_expression_in_memory, generate_debug_info); 252e5ee6f04SJim Ingham 253e5ee6f04SJim Ingham // Calculate the fixed expression always, since we need it for errors. 254e5ee6f04SJim Ingham std::string tmp_fixed_expression; 255e5ee6f04SJim Ingham if (fixed_expression == nullptr) 256e5ee6f04SJim Ingham fixed_expression = &tmp_fixed_expression; 257e5ee6f04SJim Ingham 258e5ee6f04SJim Ingham const char *fixed_text = user_expression_sp->GetFixedText(); 259e5ee6f04SJim Ingham if (fixed_text != nullptr) 260e5ee6f04SJim Ingham fixed_expression->append(fixed_text); 261e5ee6f04SJim Ingham 262e5ee6f04SJim Ingham // If there is a fixed expression, try to parse it: 263b9c1b51eSKate Stone if (!parse_success) { 264151c032cSJim Ingham execution_results = lldb::eExpressionParseError; 265b9c1b51eSKate Stone if (fixed_expression && !fixed_expression->empty() && 266b9c1b51eSKate Stone options.GetAutoApplyFixIts()) { 267b9c1b51eSKate Stone lldb::UserExpressionSP fixed_expression_sp( 268b9c1b51eSKate Stone target->GetUserExpressionForLanguage(fixed_expression->c_str(), 269b9c1b51eSKate Stone full_prefix, language, 27040624a08SAleksandr Urakov desired_type, options, ctx_obj, 27140624a08SAleksandr Urakov error)); 272e5ee6f04SJim Ingham DiagnosticManager fixed_diagnostic_manager; 273b9c1b51eSKate Stone parse_success = fixed_expression_sp->Parse( 274b9c1b51eSKate Stone fixed_diagnostic_manager, exe_ctx, execution_policy, 275b9c1b51eSKate Stone keep_expression_in_memory, generate_debug_info); 276b9c1b51eSKate Stone if (parse_success) { 277e5ee6f04SJim Ingham diagnostic_manager.Clear(); 278e5ee6f04SJim Ingham user_expression_sp = fixed_expression_sp; 279b9c1b51eSKate Stone } else { 280b9c1b51eSKate Stone // If the fixed expression failed to parse, don't tell the user about, 281b9c1b51eSKate Stone // that won't help. 282b29c42f9SJim Ingham fixed_expression->clear(); 283b29c42f9SJim Ingham } 284e5ee6f04SJim Ingham } 285e5ee6f04SJim Ingham 286b9c1b51eSKate Stone if (!parse_success) { 287b9c1b51eSKate Stone if (!fixed_expression->empty() && target->GetEnableNotifyAboutFixIts()) { 288b9c1b51eSKate Stone error.SetExpressionErrorWithFormat( 289b9c1b51eSKate Stone execution_results, 290b9c1b51eSKate Stone "expression failed to parse, fixed expression suggested:\n %s", 291e5ee6f04SJim Ingham fixed_expression->c_str()); 292b9c1b51eSKate Stone } else { 293579e70c9SSean Callanan if (!diagnostic_manager.Diagnostics().size()) 294b9c1b51eSKate Stone error.SetExpressionError(execution_results, 295b9c1b51eSKate Stone "expression failed to parse, unknown error"); 296151c032cSJim Ingham else 297b9c1b51eSKate Stone error.SetExpressionError(execution_results, 298b9c1b51eSKate Stone diagnostic_manager.GetString().c_str()); 299151c032cSJim Ingham } 300e5ee6f04SJim Ingham } 301e5ee6f04SJim Ingham } 302e5ee6f04SJim Ingham 303b9c1b51eSKate Stone if (parse_success) { 304b9c1b51eSKate Stone // If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module 305b9c1b51eSKate Stone // if one was created 306998c8a1cSRyan Brown if (jit_module_sp_ptr) 307998c8a1cSRyan Brown *jit_module_sp_ptr = user_expression_sp->GetJITModule(); 3086681041dSSean Callanan 309151c032cSJim Ingham lldb::ExpressionVariableSP expr_result; 310151c032cSJim Ingham 311151c032cSJim Ingham if (execution_policy == eExecutionPolicyNever && 312b9c1b51eSKate Stone !user_expression_sp->CanInterpret()) { 313151c032cSJim Ingham if (log) 31463e5fb76SJonas Devlieghere LLDB_LOGF(log, 31563e5fb76SJonas Devlieghere "== [UserExpression::Evaluate] Expression may not run, but " 316b9c1b51eSKate Stone "is not constant =="); 317151c032cSJim Ingham 318579e70c9SSean Callanan if (!diagnostic_manager.Diagnostics().size()) 319b9c1b51eSKate Stone error.SetExpressionError(lldb::eExpressionSetupError, 320b9c1b51eSKate Stone "expression needed to run but couldn't"); 321b9c1b51eSKate Stone } else if (execution_policy == eExecutionPolicyTopLevel) { 322a35912daSKrasimir Georgiev error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); 3232ff00003SSean Callanan return lldb::eExpressionCompleted; 324b9c1b51eSKate Stone } else { 325b9c1b51eSKate Stone if (options.InvokeCancelCallback(lldb::eExpressionEvaluationExecution)) { 326b9c1b51eSKate Stone error.SetExpressionError( 327b9c1b51eSKate Stone lldb::eExpressionInterrupted, 328b9c1b51eSKate Stone "expression interrupted by callback before execution"); 329b9c1b51eSKate Stone result_valobj_sp = ValueObjectConstResult::Create( 330b9c1b51eSKate Stone exe_ctx.GetBestExecutionContextScope(), error); 331151c032cSJim Ingham return lldb::eExpressionInterrupted; 332151c032cSJim Ingham } 333151c032cSJim Ingham 334579e70c9SSean Callanan diagnostic_manager.Clear(); 335151c032cSJim Ingham 336151c032cSJim Ingham if (log) 33763e5fb76SJonas Devlieghere LLDB_LOGF(log, "== [UserExpression::Evaluate] Executing expression =="); 338151c032cSJim Ingham 339579e70c9SSean Callanan execution_results = 340b9c1b51eSKate Stone user_expression_sp->Execute(diagnostic_manager, exe_ctx, options, 341b9c1b51eSKate Stone user_expression_sp, expr_result); 342151c032cSJim Ingham 343b9c1b51eSKate Stone if (execution_results != lldb::eExpressionCompleted) { 344151c032cSJim Ingham if (log) 34563e5fb76SJonas Devlieghere LLDB_LOGF(log, "== [UserExpression::Evaluate] Execution completed " 346b9c1b51eSKate Stone "abnormally =="); 347151c032cSJim Ingham 348579e70c9SSean Callanan if (!diagnostic_manager.Diagnostics().size()) 349b9c1b51eSKate Stone error.SetExpressionError( 350b9c1b51eSKate Stone execution_results, "expression failed to execute, unknown error"); 351151c032cSJim Ingham else 352b9c1b51eSKate Stone error.SetExpressionError(execution_results, 353b9c1b51eSKate Stone diagnostic_manager.GetString().c_str()); 354b9c1b51eSKate Stone } else { 355b9c1b51eSKate Stone if (expr_result) { 356151c032cSJim Ingham result_valobj_sp = expr_result->GetValueObject(); 357151c032cSJim Ingham 358151c032cSJim Ingham if (log) 35963e5fb76SJonas Devlieghere LLDB_LOGF(log, 36063e5fb76SJonas Devlieghere "== [UserExpression::Evaluate] Execution completed " 361b9c1b51eSKate Stone "normally with result %s ==", 362151c032cSJim Ingham result_valobj_sp->GetValueAsCString()); 363b9c1b51eSKate Stone } else { 364151c032cSJim Ingham if (log) 36563e5fb76SJonas Devlieghere LLDB_LOGF(log, "== [UserExpression::Evaluate] Execution completed " 366b9c1b51eSKate Stone "normally with no result =="); 367151c032cSJim Ingham 368a35912daSKrasimir Georgiev error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); 369151c032cSJim Ingham } 370151c032cSJim Ingham } 371151c032cSJim Ingham } 372151c032cSJim Ingham } 373151c032cSJim Ingham 374b9c1b51eSKate Stone if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete)) { 375b9c1b51eSKate Stone error.SetExpressionError( 376b9c1b51eSKate Stone lldb::eExpressionInterrupted, 377b9c1b51eSKate Stone "expression interrupted by callback after complete"); 378151c032cSJim Ingham return lldb::eExpressionInterrupted; 379151c032cSJim Ingham } 380151c032cSJim Ingham 381248a1305SKonrad Kleine if (result_valobj_sp.get() == nullptr) { 382b9c1b51eSKate Stone result_valobj_sp = ValueObjectConstResult::Create( 383b9c1b51eSKate Stone exe_ctx.GetBestExecutionContextScope(), error); 384151c032cSJim Ingham } 385151c032cSJim Ingham 386151c032cSJim Ingham return execution_results; 387151c032cSJim Ingham } 388ff7ac6a7SJim Ingham 389ff7ac6a7SJim Ingham lldb::ExpressionResults 390ff7ac6a7SJim Ingham UserExpression::Execute(DiagnosticManager &diagnostic_manager, 391ff7ac6a7SJim Ingham ExecutionContext &exe_ctx, 392ff7ac6a7SJim Ingham const EvaluateExpressionOptions &options, 393ff7ac6a7SJim Ingham lldb::UserExpressionSP &shared_ptr_to_me, 394b9c1b51eSKate Stone lldb::ExpressionVariableSP &result_var) { 395b9c1b51eSKate Stone lldb::ExpressionResults expr_result = DoExecute( 396b9c1b51eSKate Stone diagnostic_manager, exe_ctx, options, shared_ptr_to_me, result_var); 397ff7ac6a7SJim Ingham Target *target = exe_ctx.GetTargetPtr(); 398b9c1b51eSKate Stone if (options.GetResultIsInternal() && result_var && target) { 399b9c1b51eSKate Stone target->GetPersistentExpressionStateForLanguage(m_language) 400b9c1b51eSKate Stone ->RemovePersistentVariable(result_var); 401ff7ac6a7SJim Ingham } 402ff7ac6a7SJim Ingham return expr_result; 403ff7ac6a7SJim Ingham } 404