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 9151c032cSJim Ingham #include <stdio.h> 10151c032cSJim Ingham #if HAVE_SYS_TYPES_H 11151c032cSJim Ingham #include <sys/types.h> 12151c032cSJim Ingham #endif 13151c032cSJim Ingham 14151c032cSJim Ingham #include <cstdlib> 15151c032cSJim Ingham #include <map> 16b9c1b51eSKate Stone #include <string> 17151c032cSJim Ingham 18579e70c9SSean Callanan #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" 19151c032cSJim Ingham #include "lldb/Core/Module.h" 20151c032cSJim Ingham #include "lldb/Core/StreamFile.h" 21151c032cSJim Ingham #include "lldb/Core/ValueObjectConstResult.h" 22579e70c9SSean Callanan #include "lldb/Expression/DiagnosticManager.h" 23151c032cSJim Ingham #include "lldb/Expression/IRExecutionUnit.h" 24151c032cSJim Ingham #include "lldb/Expression/IRInterpreter.h" 25151c032cSJim Ingham #include "lldb/Expression/Materializer.h" 26151c032cSJim Ingham #include "lldb/Expression/UserExpression.h" 27151c032cSJim Ingham #include "lldb/Host/HostInfo.h" 28151c032cSJim Ingham #include "lldb/Symbol/Block.h" 29151c032cSJim Ingham #include "lldb/Symbol/Function.h" 30151c032cSJim Ingham #include "lldb/Symbol/ObjectFile.h" 31151c032cSJim Ingham #include "lldb/Symbol/SymbolVendor.h" 32151c032cSJim Ingham #include "lldb/Symbol/Type.h" 338f1f9a1bSSean Callanan #include "lldb/Symbol/TypeSystem.h" 34151c032cSJim Ingham #include "lldb/Symbol/VariableList.h" 35151c032cSJim Ingham #include "lldb/Target/ExecutionContext.h" 36151c032cSJim Ingham #include "lldb/Target/Process.h" 37151c032cSJim Ingham #include "lldb/Target/StackFrame.h" 38151c032cSJim Ingham #include "lldb/Target/Target.h" 39151c032cSJim Ingham #include "lldb/Target/ThreadPlan.h" 40151c032cSJim Ingham #include "lldb/Target/ThreadPlanCallUserExpression.h" 41bf9a7730SZachary Turner #include "lldb/Utility/ConstString.h" 426f9e6901SZachary Turner #include "lldb/Utility/Log.h" 43bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h" 44151c032cSJim Ingham 45151c032cSJim Ingham using namespace lldb_private; 46151c032cSJim Ingham 4719a63fc6SJim Ingham UserExpression::UserExpression(ExecutionContextScope &exe_scope, 48c5d7df90SZachary Turner llvm::StringRef expr, llvm::StringRef prefix, 4919a63fc6SJim Ingham lldb::LanguageType language, 5019a63fc6SJim Ingham ResultType desired_type, 51*7e34d78dSAdrian Prantl const EvaluateExpressionOptions &options, 52*7e34d78dSAdrian Prantl ExpressionKind kind) 53*7e34d78dSAdrian Prantl : Expression(exe_scope, kind), m_expr_text(expr), m_expr_prefix(prefix), 54c5d7df90SZachary Turner m_language(language), m_desired_type(desired_type), m_options(options) {} 55151c032cSJim Ingham 56b9c1b51eSKate Stone UserExpression::~UserExpression() {} 57151c032cSJim Ingham 58b9c1b51eSKate Stone void UserExpression::InstallContext(ExecutionContext &exe_ctx) { 59151c032cSJim Ingham m_jit_process_wp = exe_ctx.GetProcessSP(); 60151c032cSJim Ingham 61151c032cSJim Ingham lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP(); 62151c032cSJim Ingham 63151c032cSJim Ingham if (frame_sp) 64151c032cSJim Ingham m_address = frame_sp->GetFrameCodeAddress(); 65151c032cSJim Ingham } 66151c032cSJim Ingham 67b9c1b51eSKate Stone bool UserExpression::LockAndCheckContext(ExecutionContext &exe_ctx, 68151c032cSJim Ingham lldb::TargetSP &target_sp, 69151c032cSJim Ingham lldb::ProcessSP &process_sp, 70b9c1b51eSKate Stone lldb::StackFrameSP &frame_sp) { 71151c032cSJim Ingham lldb::ProcessSP expected_process_sp = m_jit_process_wp.lock(); 72151c032cSJim Ingham process_sp = exe_ctx.GetProcessSP(); 73151c032cSJim Ingham 74151c032cSJim Ingham if (process_sp != expected_process_sp) 75151c032cSJim Ingham return false; 76151c032cSJim Ingham 77151c032cSJim Ingham process_sp = exe_ctx.GetProcessSP(); 78151c032cSJim Ingham target_sp = exe_ctx.GetTargetSP(); 79151c032cSJim Ingham frame_sp = exe_ctx.GetFrameSP(); 80151c032cSJim Ingham 81b9c1b51eSKate Stone if (m_address.IsValid()) { 82151c032cSJim Ingham if (!frame_sp) 83151c032cSJim Ingham return false; 84151c032cSJim Ingham else 85b9c1b51eSKate Stone return (0 == Address::CompareLoadAddress(m_address, 86b9c1b51eSKate Stone frame_sp->GetFrameCodeAddress(), 87b9c1b51eSKate Stone target_sp.get())); 88151c032cSJim Ingham } 89151c032cSJim Ingham 90151c032cSJim Ingham return true; 91151c032cSJim Ingham } 92151c032cSJim Ingham 93b9c1b51eSKate Stone bool UserExpression::MatchesContext(ExecutionContext &exe_ctx) { 94151c032cSJim Ingham lldb::TargetSP target_sp; 95151c032cSJim Ingham lldb::ProcessSP process_sp; 96151c032cSJim Ingham lldb::StackFrameSP frame_sp; 97151c032cSJim Ingham 98151c032cSJim Ingham return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp); 99151c032cSJim Ingham } 100151c032cSJim Ingham 101b9c1b51eSKate Stone lldb::addr_t UserExpression::GetObjectPointer(lldb::StackFrameSP frame_sp, 102151c032cSJim Ingham ConstString &object_name, 10397206d57SZachary Turner Status &err) { 104151c032cSJim Ingham err.Clear(); 105151c032cSJim Ingham 106b9c1b51eSKate Stone if (!frame_sp) { 107b9c1b51eSKate Stone err.SetErrorStringWithFormat( 108b9c1b51eSKate Stone "Couldn't load '%s' because the context is incomplete", 109b9c1b51eSKate Stone object_name.AsCString()); 110151c032cSJim Ingham return LLDB_INVALID_ADDRESS; 111151c032cSJim Ingham } 112151c032cSJim Ingham 113151c032cSJim Ingham lldb::VariableSP var_sp; 114151c032cSJim Ingham lldb::ValueObjectSP valobj_sp; 115151c032cSJim Ingham 116b9c1b51eSKate Stone valobj_sp = frame_sp->GetValueForVariableExpressionPath( 117b9c1b51eSKate Stone object_name.AsCString(), lldb::eNoDynamicValues, 118151c032cSJim Ingham StackFrame::eExpressionPathOptionCheckPtrVsMember | 119151c032cSJim Ingham StackFrame::eExpressionPathOptionsNoFragileObjcIvar | 120151c032cSJim Ingham StackFrame::eExpressionPathOptionsNoSyntheticChildren | 121151c032cSJim Ingham StackFrame::eExpressionPathOptionsNoSyntheticArrayRange, 122b9c1b51eSKate Stone var_sp, err); 123151c032cSJim Ingham 124151c032cSJim Ingham if (!err.Success() || !valobj_sp.get()) 125151c032cSJim Ingham return LLDB_INVALID_ADDRESS; 126151c032cSJim Ingham 127151c032cSJim Ingham lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 128151c032cSJim Ingham 129b9c1b51eSKate Stone if (ret == LLDB_INVALID_ADDRESS) { 130b9c1b51eSKate Stone err.SetErrorStringWithFormat( 131b9c1b51eSKate Stone "Couldn't load '%s' because its value couldn't be evaluated", 132b9c1b51eSKate Stone object_name.AsCString()); 133151c032cSJim Ingham return LLDB_INVALID_ADDRESS; 134151c032cSJim Ingham } 135151c032cSJim Ingham 136151c032cSJim Ingham return ret; 137151c032cSJim Ingham } 138151c032cSJim Ingham 139b9c1b51eSKate Stone lldb::ExpressionResults UserExpression::Evaluate( 140b9c1b51eSKate Stone ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, 141c5d7df90SZachary Turner llvm::StringRef expr, llvm::StringRef prefix, 14281dbc026SAlex Langford lldb::ValueObjectSP &result_valobj_sp, Status &error, 14340624a08SAleksandr Urakov std::string *fixed_expression, lldb::ModuleSP *jit_module_sp_ptr, 14440624a08SAleksandr Urakov ValueObject *ctx_obj) { 145b9c1b51eSKate Stone Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | 146b9c1b51eSKate Stone LIBLLDB_LOG_STEP)); 147151c032cSJim Ingham 14840624a08SAleksandr Urakov if (ctx_obj) { 14940624a08SAleksandr Urakov static unsigned const ctx_type_mask = 15040624a08SAleksandr Urakov lldb::TypeFlags::eTypeIsClass | lldb::TypeFlags::eTypeIsStructUnion; 15140624a08SAleksandr Urakov if (!(ctx_obj->GetTypeInfo() & ctx_type_mask)) { 15240624a08SAleksandr Urakov LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a context object of " 15340624a08SAleksandr Urakov "an invalid type, can't run expressions."); 15440624a08SAleksandr Urakov error.SetErrorString("a context object of an invalid type passed"); 15540624a08SAleksandr Urakov return lldb::eExpressionSetupError; 15640624a08SAleksandr Urakov } 15740624a08SAleksandr Urakov } 15840624a08SAleksandr Urakov 159151c032cSJim Ingham lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy(); 1601bbaede5SDawn Perchik lldb::LanguageType language = options.GetLanguage(); 161b9c1b51eSKate Stone const ResultType desired_type = options.DoesCoerceToId() 162b9c1b51eSKate Stone ? UserExpression::eResultTypeId 163b9c1b51eSKate Stone : UserExpression::eResultTypeAny; 164151c032cSJim Ingham lldb::ExpressionResults execution_results = lldb::eExpressionSetupError; 165151c032cSJim Ingham 166151c032cSJim Ingham Target *target = exe_ctx.GetTargetPtr(); 167b9c1b51eSKate Stone if (!target) { 168151c032cSJim Ingham if (log) 169b9c1b51eSKate Stone log->Printf("== [UserExpression::Evaluate] Passed a NULL target, can't " 170b9c1b51eSKate Stone "run expressions."); 17102980825SJim Ingham error.SetErrorString("expression passed a null target"); 172151c032cSJim Ingham return lldb::eExpressionSetupError; 173151c032cSJim Ingham } 174151c032cSJim Ingham 175151c032cSJim Ingham Process *process = exe_ctx.GetProcessPtr(); 176151c032cSJim Ingham 177b9c1b51eSKate Stone if (process == NULL || process->GetState() != lldb::eStateStopped) { 178b9c1b51eSKate Stone if (execution_policy == eExecutionPolicyAlways) { 179151c032cSJim Ingham if (log) 180b9c1b51eSKate Stone log->Printf("== [UserExpression::Evaluate] Expression may not run, but " 181b9c1b51eSKate Stone "is not constant =="); 182151c032cSJim Ingham 183151c032cSJim Ingham error.SetErrorString("expression needed to run but couldn't"); 184151c032cSJim Ingham 185151c032cSJim Ingham return execution_results; 186151c032cSJim Ingham } 187151c032cSJim Ingham } 188151c032cSJim Ingham 189151c032cSJim Ingham if (process == NULL || !process->CanJIT()) 190151c032cSJim Ingham execution_policy = eExecutionPolicyNever; 1916896b355SJim Ingham 192b9c1b51eSKate Stone // We need to set the expression execution thread here, turns out parse can 19305097246SAdrian Prantl // call functions in the process of looking up symbols, which will escape the 19405097246SAdrian Prantl // context set by exe_ctx passed to Execute. 1956896b355SJim Ingham lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP(); 196b9c1b51eSKate Stone ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher( 197b9c1b51eSKate Stone thread_sp); 198151c032cSJim Ingham 199c5d7df90SZachary Turner llvm::StringRef full_prefix; 200c5d7df90SZachary Turner llvm::StringRef option_prefix(options.GetPrefix()); 201151c032cSJim Ingham std::string full_prefix_storage; 202c5d7df90SZachary Turner if (!prefix.empty() && !option_prefix.empty()) { 203c5d7df90SZachary Turner full_prefix_storage = prefix; 204151c032cSJim Ingham full_prefix_storage.append(option_prefix); 205c5d7df90SZachary Turner full_prefix = full_prefix_storage; 206c5d7df90SZachary Turner } else if (!prefix.empty()) 207c5d7df90SZachary Turner full_prefix = prefix; 208151c032cSJim Ingham else 209151c032cSJim Ingham full_prefix = option_prefix; 210151c032cSJim Ingham 21105097246SAdrian Prantl // If the language was not specified in the expression command, set it to the 21205097246SAdrian Prantl // language in the target's properties if specified, else default to the 21305097246SAdrian Prantl // langage for the frame. 214b9c1b51eSKate Stone if (language == lldb::eLanguageTypeUnknown) { 2151bbaede5SDawn Perchik if (target->GetLanguage() != lldb::eLanguageTypeUnknown) 2161bbaede5SDawn Perchik language = target->GetLanguage(); 2171bbaede5SDawn Perchik else if (StackFrame *frame = exe_ctx.GetFramePtr()) 2181bbaede5SDawn Perchik language = frame->GetLanguage(); 2191bbaede5SDawn Perchik } 2201bbaede5SDawn Perchik 221b9c1b51eSKate Stone lldb::UserExpressionSP user_expression_sp( 222c5d7df90SZachary Turner target->GetUserExpressionForLanguage(expr, full_prefix, language, 22340624a08SAleksandr Urakov desired_type, options, ctx_obj, 22440624a08SAleksandr Urakov error)); 225b9c1b51eSKate Stone if (error.Fail()) { 226151c032cSJim Ingham if (log) 227b9c1b51eSKate Stone log->Printf("== [UserExpression::Evaluate] Getting expression: %s ==", 228b9c1b51eSKate Stone error.AsCString()); 229151c032cSJim Ingham return lldb::eExpressionSetupError; 230151c032cSJim Ingham } 231151c032cSJim Ingham 232151c032cSJim Ingham if (log) 233b9c1b51eSKate Stone log->Printf("== [UserExpression::Evaluate] Parsing expression %s ==", 234c5d7df90SZachary Turner expr.str().c_str()); 235151c032cSJim Ingham 236151c032cSJim Ingham const bool keep_expression_in_memory = true; 237151c032cSJim Ingham const bool generate_debug_info = options.GetGenerateDebugInfo(); 238151c032cSJim Ingham 239b9c1b51eSKate Stone if (options.InvokeCancelCallback(lldb::eExpressionEvaluationParse)) { 240151c032cSJim Ingham error.SetErrorString("expression interrupted by callback before parse"); 241b9c1b51eSKate Stone result_valobj_sp = ValueObjectConstResult::Create( 242b9c1b51eSKate Stone exe_ctx.GetBestExecutionContextScope(), error); 243151c032cSJim Ingham return lldb::eExpressionInterrupted; 244151c032cSJim Ingham } 245151c032cSJim Ingham 246579e70c9SSean Callanan DiagnosticManager diagnostic_manager; 247579e70c9SSean Callanan 248b9c1b51eSKate Stone bool parse_success = 249b9c1b51eSKate Stone user_expression_sp->Parse(diagnostic_manager, exe_ctx, execution_policy, 250b9c1b51eSKate Stone keep_expression_in_memory, generate_debug_info); 251e5ee6f04SJim Ingham 252e5ee6f04SJim Ingham // Calculate the fixed expression always, since we need it for errors. 253e5ee6f04SJim Ingham std::string tmp_fixed_expression; 254e5ee6f04SJim Ingham if (fixed_expression == nullptr) 255e5ee6f04SJim Ingham fixed_expression = &tmp_fixed_expression; 256e5ee6f04SJim Ingham 257e5ee6f04SJim Ingham const char *fixed_text = user_expression_sp->GetFixedText(); 258e5ee6f04SJim Ingham if (fixed_text != nullptr) 259e5ee6f04SJim Ingham fixed_expression->append(fixed_text); 260e5ee6f04SJim Ingham 261e5ee6f04SJim Ingham // If there is a fixed expression, try to parse it: 262b9c1b51eSKate Stone if (!parse_success) { 263151c032cSJim Ingham execution_results = lldb::eExpressionParseError; 264b9c1b51eSKate Stone if (fixed_expression && !fixed_expression->empty() && 265b9c1b51eSKate Stone options.GetAutoApplyFixIts()) { 266b9c1b51eSKate Stone lldb::UserExpressionSP fixed_expression_sp( 267b9c1b51eSKate Stone target->GetUserExpressionForLanguage(fixed_expression->c_str(), 268b9c1b51eSKate Stone full_prefix, language, 26940624a08SAleksandr Urakov desired_type, options, ctx_obj, 27040624a08SAleksandr Urakov error)); 271e5ee6f04SJim Ingham DiagnosticManager fixed_diagnostic_manager; 272b9c1b51eSKate Stone parse_success = fixed_expression_sp->Parse( 273b9c1b51eSKate Stone fixed_diagnostic_manager, exe_ctx, execution_policy, 274b9c1b51eSKate Stone keep_expression_in_memory, generate_debug_info); 275b9c1b51eSKate Stone if (parse_success) { 276e5ee6f04SJim Ingham diagnostic_manager.Clear(); 277e5ee6f04SJim Ingham user_expression_sp = fixed_expression_sp; 278b9c1b51eSKate Stone } else { 279b9c1b51eSKate Stone // If the fixed expression failed to parse, don't tell the user about, 280b9c1b51eSKate Stone // that won't help. 281b29c42f9SJim Ingham fixed_expression->clear(); 282b29c42f9SJim Ingham } 283e5ee6f04SJim Ingham } 284e5ee6f04SJim Ingham 285b9c1b51eSKate Stone if (!parse_success) { 286b9c1b51eSKate Stone if (!fixed_expression->empty() && target->GetEnableNotifyAboutFixIts()) { 287b9c1b51eSKate Stone error.SetExpressionErrorWithFormat( 288b9c1b51eSKate Stone execution_results, 289b9c1b51eSKate Stone "expression failed to parse, fixed expression suggested:\n %s", 290e5ee6f04SJim Ingham fixed_expression->c_str()); 291b9c1b51eSKate Stone } else { 292579e70c9SSean Callanan if (!diagnostic_manager.Diagnostics().size()) 293b9c1b51eSKate Stone error.SetExpressionError(execution_results, 294b9c1b51eSKate Stone "expression failed to parse, unknown error"); 295151c032cSJim Ingham else 296b9c1b51eSKate Stone error.SetExpressionError(execution_results, 297b9c1b51eSKate Stone diagnostic_manager.GetString().c_str()); 298151c032cSJim Ingham } 299e5ee6f04SJim Ingham } 300e5ee6f04SJim Ingham } 301e5ee6f04SJim Ingham 302b9c1b51eSKate Stone if (parse_success) { 303b9c1b51eSKate Stone // If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module 304b9c1b51eSKate Stone // if one was created 305998c8a1cSRyan Brown if (jit_module_sp_ptr) 306998c8a1cSRyan Brown *jit_module_sp_ptr = user_expression_sp->GetJITModule(); 3076681041dSSean Callanan 308151c032cSJim Ingham lldb::ExpressionVariableSP expr_result; 309151c032cSJim Ingham 310151c032cSJim Ingham if (execution_policy == eExecutionPolicyNever && 311b9c1b51eSKate Stone !user_expression_sp->CanInterpret()) { 312151c032cSJim Ingham if (log) 313b9c1b51eSKate Stone log->Printf("== [UserExpression::Evaluate] Expression may not run, but " 314b9c1b51eSKate Stone "is not constant =="); 315151c032cSJim Ingham 316579e70c9SSean Callanan if (!diagnostic_manager.Diagnostics().size()) 317b9c1b51eSKate Stone error.SetExpressionError(lldb::eExpressionSetupError, 318b9c1b51eSKate Stone "expression needed to run but couldn't"); 319b9c1b51eSKate Stone } else if (execution_policy == eExecutionPolicyTopLevel) { 320a35912daSKrasimir Georgiev error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); 3212ff00003SSean Callanan return lldb::eExpressionCompleted; 322b9c1b51eSKate Stone } else { 323b9c1b51eSKate Stone if (options.InvokeCancelCallback(lldb::eExpressionEvaluationExecution)) { 324b9c1b51eSKate Stone error.SetExpressionError( 325b9c1b51eSKate Stone lldb::eExpressionInterrupted, 326b9c1b51eSKate Stone "expression interrupted by callback before execution"); 327b9c1b51eSKate Stone result_valobj_sp = ValueObjectConstResult::Create( 328b9c1b51eSKate Stone exe_ctx.GetBestExecutionContextScope(), error); 329151c032cSJim Ingham return lldb::eExpressionInterrupted; 330151c032cSJim Ingham } 331151c032cSJim Ingham 332579e70c9SSean Callanan diagnostic_manager.Clear(); 333151c032cSJim Ingham 334151c032cSJim Ingham if (log) 335151c032cSJim Ingham log->Printf("== [UserExpression::Evaluate] Executing expression =="); 336151c032cSJim Ingham 337579e70c9SSean Callanan execution_results = 338b9c1b51eSKate Stone user_expression_sp->Execute(diagnostic_manager, exe_ctx, options, 339b9c1b51eSKate Stone user_expression_sp, expr_result); 340151c032cSJim Ingham 341b9c1b51eSKate Stone if (execution_results != lldb::eExpressionCompleted) { 342151c032cSJim Ingham if (log) 343b9c1b51eSKate Stone log->Printf("== [UserExpression::Evaluate] Execution completed " 344b9c1b51eSKate Stone "abnormally =="); 345151c032cSJim Ingham 346579e70c9SSean Callanan if (!diagnostic_manager.Diagnostics().size()) 347b9c1b51eSKate Stone error.SetExpressionError( 348b9c1b51eSKate Stone execution_results, "expression failed to execute, unknown error"); 349151c032cSJim Ingham else 350b9c1b51eSKate Stone error.SetExpressionError(execution_results, 351b9c1b51eSKate Stone diagnostic_manager.GetString().c_str()); 352b9c1b51eSKate Stone } else { 353b9c1b51eSKate Stone if (expr_result) { 354151c032cSJim Ingham result_valobj_sp = expr_result->GetValueObject(); 355151c032cSJim Ingham 356151c032cSJim Ingham if (log) 357b9c1b51eSKate Stone log->Printf("== [UserExpression::Evaluate] Execution completed " 358b9c1b51eSKate Stone "normally with result %s ==", 359151c032cSJim Ingham result_valobj_sp->GetValueAsCString()); 360b9c1b51eSKate Stone } else { 361151c032cSJim Ingham if (log) 362b9c1b51eSKate Stone log->Printf("== [UserExpression::Evaluate] Execution completed " 363b9c1b51eSKate Stone "normally with no result =="); 364151c032cSJim Ingham 365a35912daSKrasimir Georgiev error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric); 366151c032cSJim Ingham } 367151c032cSJim Ingham } 368151c032cSJim Ingham } 369151c032cSJim Ingham } 370151c032cSJim Ingham 371b9c1b51eSKate Stone if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete)) { 372b9c1b51eSKate Stone error.SetExpressionError( 373b9c1b51eSKate Stone lldb::eExpressionInterrupted, 374b9c1b51eSKate Stone "expression interrupted by callback after complete"); 375151c032cSJim Ingham return lldb::eExpressionInterrupted; 376151c032cSJim Ingham } 377151c032cSJim Ingham 378b9c1b51eSKate Stone if (result_valobj_sp.get() == NULL) { 379b9c1b51eSKate Stone result_valobj_sp = ValueObjectConstResult::Create( 380b9c1b51eSKate Stone exe_ctx.GetBestExecutionContextScope(), error); 381151c032cSJim Ingham } 382151c032cSJim Ingham 383151c032cSJim Ingham return execution_results; 384151c032cSJim Ingham } 385ff7ac6a7SJim Ingham 386ff7ac6a7SJim Ingham lldb::ExpressionResults 387ff7ac6a7SJim Ingham UserExpression::Execute(DiagnosticManager &diagnostic_manager, 388ff7ac6a7SJim Ingham ExecutionContext &exe_ctx, 389ff7ac6a7SJim Ingham const EvaluateExpressionOptions &options, 390ff7ac6a7SJim Ingham lldb::UserExpressionSP &shared_ptr_to_me, 391b9c1b51eSKate Stone lldb::ExpressionVariableSP &result_var) { 392b9c1b51eSKate Stone lldb::ExpressionResults expr_result = DoExecute( 393b9c1b51eSKate Stone diagnostic_manager, exe_ctx, options, shared_ptr_to_me, result_var); 394ff7ac6a7SJim Ingham Target *target = exe_ctx.GetTargetPtr(); 395b9c1b51eSKate Stone if (options.GetResultIsInternal() && result_var && target) { 396b9c1b51eSKate Stone target->GetPersistentExpressionStateForLanguage(m_language) 397b9c1b51eSKate Stone ->RemovePersistentVariable(result_var); 398ff7ac6a7SJim Ingham } 399ff7ac6a7SJim Ingham return expr_result; 400ff7ac6a7SJim Ingham } 401