130fdc8d8SChris Lattner //===-- CommandObjectExpression.cpp -----------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner // C Includes 1130fdc8d8SChris Lattner // C++ Includes 1230fdc8d8SChris Lattner // Other libraries and framework includes 13c8ecc2a9SEugene Zelenko #include "llvm/ADT/STLExtras.h" 14c8ecc2a9SEugene Zelenko #include "llvm/ADT/StringRef.h" 15c8ecc2a9SEugene Zelenko 1630fdc8d8SChris Lattner // Project includes 17c8ecc2a9SEugene Zelenko #include "CommandObjectExpression.h" 1830fdc8d8SChris Lattner #include "lldb/Core/Value.h" 196c68fb45SJim Ingham #include "lldb/Core/ValueObjectVariable.h" 204d93b8cdSEnrico Granata #include "lldb/DataFormatters/ValueObjectPrinter.h" 2130e33974SSean Callanan #include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h" 22151c032cSJim Ingham #include "lldb/Expression/UserExpression.h" 2330fdc8d8SChris Lattner #include "lldb/Expression/DWARFExpression.h" 24f2bd5c3eSSean Callanan #include "lldb/Expression/REPL.h" 2530fdc8d8SChris Lattner #include "lldb/Host/Host.h" 265275aaa0SVince Harron #include "lldb/Host/StringConvert.h" 27ebf7707eSSean Callanan #include "lldb/Core/Debugger.h" 286611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 2930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 300e0984eeSJim Ingham #include "lldb/Target/Language.h" 3130fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h" 3230fdc8d8SChris Lattner #include "lldb/Symbol/Variable.h" 3330fdc8d8SChris Lattner #include "lldb/Target/Process.h" 34b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h" 3530fdc8d8SChris Lattner #include "lldb/Target/Target.h" 367260f620SGreg Clayton #include "lldb/Target/Thread.h" 3730fdc8d8SChris Lattner 3830fdc8d8SChris Lattner using namespace lldb; 3930fdc8d8SChris Lattner using namespace lldb_private; 4030fdc8d8SChris Lattner 411deb7962SGreg Clayton CommandObjectExpression::CommandOptions::CommandOptions () : 421deb7962SGreg Clayton OptionGroup() 4330fdc8d8SChris Lattner { 4430fdc8d8SChris Lattner } 4530fdc8d8SChris Lattner 46c8ecc2a9SEugene Zelenko CommandObjectExpression::CommandOptions::~CommandOptions() = default; 4730fdc8d8SChris Lattner 484d93b8cdSEnrico Granata static OptionEnumValueElement g_description_verbosity_type[] = 494d93b8cdSEnrico Granata { 504d93b8cdSEnrico Granata { eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact", "Only show the description string"}, 514d93b8cdSEnrico Granata { eLanguageRuntimeDescriptionDisplayVerbosityFull, "full", "Show the full output, including persistent variable's name and type"}, 52c8ecc2a9SEugene Zelenko { 0, nullptr, nullptr } 534d93b8cdSEnrico Granata }; 544d93b8cdSEnrico Granata 551deb7962SGreg Clayton OptionDefinition 561deb7962SGreg Clayton CommandObjectExpression::CommandOptions::g_option_table[] = 571deb7962SGreg Clayton { 58c8ecc2a9SEugene Zelenko { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."}, 59c8ecc2a9SEugene Zelenko { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"}, 60c8ecc2a9SEugene Zelenko { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."}, 61c8ecc2a9SEugene Zelenko { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."}, 62c8ecc2a9SEugene Zelenko { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."}, 63c8ecc2a9SEugene Zelenko { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specifies the Language to use when parsing the expression. If not set the target.language setting is used." }, 64*279b2e88SJim Ingham { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "If true, simple fix-it hints will be automatically applied to the expression." }, 65c8ecc2a9SEugene Zelenko { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, nullptr, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."}, 663fe71581SMarianne Mailhot-Sarrasin { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "top-level", 'p', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Interpret the expression as top-level definitions rather than code to be immediately executed."}, 673fe71581SMarianne Mailhot-Sarrasin { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "allow-jit", 'j', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Controls whether the expression can fall back to being JITted if it's not supported by the interpreter (defaults to true)."} 681deb7962SGreg Clayton }; 691deb7962SGreg Clayton 701deb7962SGreg Clayton uint32_t 711deb7962SGreg Clayton CommandObjectExpression::CommandOptions::GetNumDefinitions () 721deb7962SGreg Clayton { 7328606954SSaleem Abdulrasool return llvm::array_lengthof(g_option_table); 741deb7962SGreg Clayton } 751deb7962SGreg Clayton 7630fdc8d8SChris Lattner Error 771deb7962SGreg Clayton CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter, 781deb7962SGreg Clayton uint32_t option_idx, 791deb7962SGreg Clayton const char *option_arg) 8030fdc8d8SChris Lattner { 8130fdc8d8SChris Lattner Error error; 8230fdc8d8SChris Lattner 833bcdfc0eSGreg Clayton const int short_option = g_option_table[option_idx].short_option; 8430fdc8d8SChris Lattner 8530fdc8d8SChris Lattner switch (short_option) 8630fdc8d8SChris Lattner { 8715663c53SDawn Perchik case 'l': 880e0984eeSJim Ingham language = Language::GetLanguageTypeFromString (option_arg); 8915663c53SDawn Perchik if (language == eLanguageTypeUnknown) 9015663c53SDawn Perchik error.SetErrorStringWithFormat ("unknown language type: '%s' for expression", option_arg); 9115663c53SDawn Perchik break; 9230fdc8d8SChris Lattner 9335e1bda6SJim Ingham case 'a': 9435e1bda6SJim Ingham { 9535e1bda6SJim Ingham bool success; 9635e1bda6SJim Ingham bool result; 9735e1bda6SJim Ingham result = Args::StringToBoolean(option_arg, true, &success); 9835e1bda6SJim Ingham if (!success) 9935e1bda6SJim Ingham error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg); 10035e1bda6SJim Ingham else 10135e1bda6SJim Ingham try_all_threads = result; 10235e1bda6SJim Ingham } 1036c68fb45SJim Ingham break; 1046c68fb45SJim Ingham 105184e9811SJim Ingham case 'i': 106184e9811SJim Ingham { 107184e9811SJim Ingham bool success; 108184e9811SJim Ingham bool tmp_value = Args::StringToBoolean(option_arg, true, &success); 109184e9811SJim Ingham if (success) 110184e9811SJim Ingham ignore_breakpoints = tmp_value; 111184e9811SJim Ingham else 112184e9811SJim Ingham error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg); 113184e9811SJim Ingham break; 114184e9811SJim Ingham } 1153fe71581SMarianne Mailhot-Sarrasin 1163fe71581SMarianne Mailhot-Sarrasin case 'j': 1173fe71581SMarianne Mailhot-Sarrasin { 1183fe71581SMarianne Mailhot-Sarrasin bool success; 1193fe71581SMarianne Mailhot-Sarrasin bool tmp_value = Args::StringToBoolean(option_arg, true, &success); 1203fe71581SMarianne Mailhot-Sarrasin if (success) 1213fe71581SMarianne Mailhot-Sarrasin allow_jit = tmp_value; 1223fe71581SMarianne Mailhot-Sarrasin else 1233fe71581SMarianne Mailhot-Sarrasin error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg); 1243fe71581SMarianne Mailhot-Sarrasin break; 1253fe71581SMarianne Mailhot-Sarrasin } 1263fe71581SMarianne Mailhot-Sarrasin 12735e1bda6SJim Ingham case 't': 12835e1bda6SJim Ingham { 12935e1bda6SJim Ingham bool success; 13035e1bda6SJim Ingham uint32_t result; 1315275aaa0SVince Harron result = StringConvert::ToUInt32(option_arg, 0, 0, &success); 13235e1bda6SJim Ingham if (success) 13335e1bda6SJim Ingham timeout = result; 13435e1bda6SJim Ingham else 13535e1bda6SJim Ingham error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg); 13635e1bda6SJim Ingham } 13735e1bda6SJim Ingham break; 13835e1bda6SJim Ingham 139399f1cafSJim Ingham case 'u': 1403bfdaa2aSSean Callanan { 141399f1cafSJim Ingham bool success; 142184e9811SJim Ingham bool tmp_value = Args::StringToBoolean(option_arg, true, &success); 143184e9811SJim Ingham if (success) 144184e9811SJim Ingham unwind_on_error = tmp_value; 145184e9811SJim Ingham else 14686edbf41SGreg Clayton error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg); 147399f1cafSJim Ingham break; 1483bfdaa2aSSean Callanan } 1494d93b8cdSEnrico Granata 1504d93b8cdSEnrico Granata case 'v': 1514d93b8cdSEnrico Granata if (!option_arg) 1524d93b8cdSEnrico Granata { 1534d93b8cdSEnrico Granata m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull; 1544d93b8cdSEnrico Granata break; 1554d93b8cdSEnrico Granata } 1564d93b8cdSEnrico Granata m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 1574d93b8cdSEnrico Granata if (!error.Success()) 1584d93b8cdSEnrico Granata error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg); 1594d93b8cdSEnrico Granata break; 1604d93b8cdSEnrico Granata 16162afb9f6SGreg Clayton case 'g': 16262afb9f6SGreg Clayton debug = true; 16362afb9f6SGreg Clayton unwind_on_error = false; 16462afb9f6SGreg Clayton ignore_breakpoints = false; 16562afb9f6SGreg Clayton break; 16662afb9f6SGreg Clayton 167863fab69SSean Callanan case 'p': 168863fab69SSean Callanan top_level = true; 169863fab69SSean Callanan break; 170863fab69SSean Callanan 171a1e541bfSJim Ingham case 'X': 172a1e541bfSJim Ingham { 173a1e541bfSJim Ingham bool success; 174a1e541bfSJim Ingham bool tmp_value = Args::StringToBoolean(option_arg, true, &success); 175a1e541bfSJim Ingham if (success) 176a1e541bfSJim Ingham auto_apply_fixits = tmp_value ? eLazyBoolYes : eLazyBoolNo; 177a1e541bfSJim Ingham else 178a1e541bfSJim Ingham error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg); 179a1e541bfSJim Ingham break; 180a1e541bfSJim Ingham } 181a1e541bfSJim Ingham 18230fdc8d8SChris Lattner default: 18386edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 18430fdc8d8SChris Lattner break; 18530fdc8d8SChris Lattner } 18630fdc8d8SChris Lattner 18730fdc8d8SChris Lattner return error; 18830fdc8d8SChris Lattner } 18930fdc8d8SChris Lattner 19030fdc8d8SChris Lattner void 1911deb7962SGreg Clayton CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter) 19230fdc8d8SChris Lattner { 193184e9811SJim Ingham Process *process = interpreter.GetExecutionContext().GetProcessPtr(); 194c8ecc2a9SEugene Zelenko if (process != nullptr) 195184e9811SJim Ingham { 196184e9811SJim Ingham ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions(); 197184e9811SJim Ingham unwind_on_error = process->GetUnwindOnErrorInExpressions(); 198184e9811SJim Ingham } 199184e9811SJim Ingham else 200184e9811SJim Ingham { 201fc03f8fcSGreg Clayton ignore_breakpoints = true; 202399f1cafSJim Ingham unwind_on_error = true; 203184e9811SJim Ingham } 204184e9811SJim Ingham 20530fdc8d8SChris Lattner show_summary = true; 20635e1bda6SJim Ingham try_all_threads = true; 20735e1bda6SJim Ingham timeout = 0; 20862afb9f6SGreg Clayton debug = false; 20915663c53SDawn Perchik language = eLanguageTypeUnknown; 2104d93b8cdSEnrico Granata m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact; 211a1e541bfSJim Ingham auto_apply_fixits = eLazyBoolCalculate; 212863fab69SSean Callanan top_level = false; 2133fe71581SMarianne Mailhot-Sarrasin allow_jit = true; 21430fdc8d8SChris Lattner } 21530fdc8d8SChris Lattner 216e0d378b3SGreg Clayton const OptionDefinition* 21730fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::GetDefinitions () 21830fdc8d8SChris Lattner { 21930fdc8d8SChris Lattner return g_option_table; 22030fdc8d8SChris Lattner } 22130fdc8d8SChris Lattner 222a7015092SGreg Clayton CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) : 2235a988416SJim Ingham CommandObjectRaw(interpreter, 22430fdc8d8SChris Lattner "expression", 22515663c53SDawn Perchik "Evaluate an expression in the current program context, using user defined variables and variables currently in scope.", 226c8ecc2a9SEugene Zelenko nullptr, 227e87764f2SEnrico Granata eCommandProcessMustBePaused | eCommandTryTargetAPILock), 22844d93782SGreg Clayton IOHandlerDelegate (IOHandlerDelegate::Completion::Expression), 2291deb7962SGreg Clayton m_option_group (interpreter), 2301deb7962SGreg Clayton m_format_options (eFormatDefault), 231f2bd5c3eSSean Callanan m_repl_option (LLDB_OPT_SET_1, false, "repl", 'r', "Drop into REPL", false, true), 2321deb7962SGreg Clayton m_command_options (), 23330fdc8d8SChris Lattner m_expr_line_count (0), 23430fdc8d8SChris Lattner m_expr_lines () 23530fdc8d8SChris Lattner { 23630fdc8d8SChris Lattner SetHelpLong( 237ea671fbdSKate Stone R"( 238ea671fbdSKate Stone Timeouts: 239ea671fbdSKate Stone 240ea671fbdSKate Stone )" " If the expression can be evaluated statically (without running code) then it will be. \ 241ea671fbdSKate Stone Otherwise, by default the expression will run on the current thread with a short timeout: \ 242ea671fbdSKate Stone currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted \ 243ea671fbdSKate Stone and resumed with all threads running. You can use the -a option to disable retrying on all \ 244ea671fbdSKate Stone threads. You can use the -t option to set a shorter timeout." R"( 245ea671fbdSKate Stone 246ea671fbdSKate Stone User defined variables: 247ea671fbdSKate Stone 248ea671fbdSKate Stone )" " You can define your own variables for convenience or to be used in subsequent expressions. \ 249ea671fbdSKate Stone You define them the same way you would define variables in C. If the first character of \ 250ea671fbdSKate Stone your user defined variable is a $, then the variable's value will be available in future \ 251ea671fbdSKate Stone expressions, otherwise it will just be available in the current expression." R"( 252ea671fbdSKate Stone 253ea671fbdSKate Stone Continuing evaluation after a breakpoint: 254ea671fbdSKate Stone 255ea671fbdSKate Stone )" " If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \ 256ea671fbdSKate Stone you are done with your investigation, you can either remove the expression execution frames \ 257ea671fbdSKate Stone from the stack with \"thread return -x\" or if you are still interested in the expression result \ 258ea671fbdSKate Stone you can issue the \"continue\" command and the expression evaluation will complete and the \ 259ea671fbdSKate Stone expression result will be available using the \"thread.completed-expression\" key in the thread \ 260ea671fbdSKate Stone format." R"( 261ea671fbdSKate Stone 262ea671fbdSKate Stone Examples: 263ea671fbdSKate Stone 264ea671fbdSKate Stone expr my_struct->a = my_array[3] 265ea671fbdSKate Stone expr -f bin -- (index * 8) + 5 266ea671fbdSKate Stone expr unsigned int $foo = 5 267ea671fbdSKate Stone expr char c[] = \"foo\"; c[0])" 268ea671fbdSKate Stone ); 269405fe67fSCaroline Tice 270405fe67fSCaroline Tice CommandArgumentEntry arg; 271405fe67fSCaroline Tice CommandArgumentData expression_arg; 272405fe67fSCaroline Tice 273405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 274405fe67fSCaroline Tice expression_arg.arg_type = eArgTypeExpression; 275405fe67fSCaroline Tice expression_arg.arg_repetition = eArgRepeatPlain; 276405fe67fSCaroline Tice 277405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 278405fe67fSCaroline Tice arg.push_back (expression_arg); 279405fe67fSCaroline Tice 280405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 281405fe67fSCaroline Tice m_arguments.push_back (arg); 2821deb7962SGreg Clayton 2835009f9d5SGreg Clayton // Add the "--format" and "--gdb-format" 2845009f9d5SGreg Clayton m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1); 2851deb7962SGreg Clayton m_option_group.Append (&m_command_options); 286b576bba2SEnrico Granata m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2); 287f2bd5c3eSSean Callanan m_option_group.Append (&m_repl_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3); 2881deb7962SGreg Clayton m_option_group.Finalize(); 28930fdc8d8SChris Lattner } 29030fdc8d8SChris Lattner 291c8ecc2a9SEugene Zelenko CommandObjectExpression::~CommandObjectExpression() = default; 29230fdc8d8SChris Lattner 29330fdc8d8SChris Lattner Options * 29430fdc8d8SChris Lattner CommandObjectExpression::GetOptions () 29530fdc8d8SChris Lattner { 2961deb7962SGreg Clayton return &m_option_group; 29730fdc8d8SChris Lattner } 29830fdc8d8SChris Lattner 299520a422bSEnrico Granata static lldb_private::Error 300520a422bSEnrico Granata CanBeUsedForElementCountPrinting (ValueObject& valobj) 301520a422bSEnrico Granata { 302520a422bSEnrico Granata CompilerType type(valobj.GetCompilerType()); 303520a422bSEnrico Granata CompilerType pointee; 304520a422bSEnrico Granata if (!type.IsPointerType(&pointee)) 305520a422bSEnrico Granata return Error("as it does not refer to a pointer"); 306520a422bSEnrico Granata if (pointee.IsVoidType()) 307520a422bSEnrico Granata return Error("as it refers to a pointer to void"); 308520a422bSEnrico Granata return Error(); 309520a422bSEnrico Granata } 310520a422bSEnrico Granata 31130fdc8d8SChris Lattner bool 312c8ecc2a9SEugene Zelenko CommandObjectExpression::EvaluateExpression(const char *expr, 3136e8dc334SCaroline Tice Stream *output_stream, 3146e8dc334SCaroline Tice Stream *error_stream, 315c8ecc2a9SEugene Zelenko CommandReturnObject *result) 31630fdc8d8SChris Lattner { 317ba7b8e2cSGreg Clayton // Don't use m_exe_ctx as this might be called asynchronously 318ba7b8e2cSGreg Clayton // after the command object DoExecute has finished when doing 319ba7b8e2cSGreg Clayton // multi-line expression that use an input reader... 320ba7b8e2cSGreg Clayton ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 321ba7b8e2cSGreg Clayton 322ba7b8e2cSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 323c0a6e061SSean Callanan 324c0a6e061SSean Callanan if (!target) 325893c932aSJim Ingham target = GetDummyTarget(); 326c0a6e061SSean Callanan 327c14ee32dSGreg Clayton if (target) 3286961e878SSean Callanan { 3298b2fe6dcSGreg Clayton lldb::ValueObjectSP result_valobj_sp; 33092adcac9SSean Callanan bool keep_in_memory = true; 331009d110dSDawn Perchik StackFrame *frame = exe_ctx.GetFramePtr(); 33292adcac9SSean Callanan 33335e1bda6SJim Ingham EvaluateExpressionOptions options; 3346fbc48bcSJim Ingham options.SetCoerceToId(m_varobj_options.use_objc); 3356fbc48bcSJim Ingham options.SetUnwindOnError(m_command_options.unwind_on_error); 3366fbc48bcSJim Ingham options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints); 3376fbc48bcSJim Ingham options.SetKeepInMemory(keep_in_memory); 3386fbc48bcSJim Ingham options.SetUseDynamic(m_varobj_options.use_dynamic); 3396fbc48bcSJim Ingham options.SetTryAllThreads(m_command_options.try_all_threads); 3406fbc48bcSJim Ingham options.SetDebug(m_command_options.debug); 34115663c53SDawn Perchik options.SetLanguage(m_command_options.language); 3423fe71581SMarianne Mailhot-Sarrasin options.SetExecutionPolicy(m_command_options.allow_jit ? 3433fe71581SMarianne Mailhot-Sarrasin EvaluateExpressionOptions::default_execution_policy : 3443fe71581SMarianne Mailhot-Sarrasin lldb_private::eExecutionPolicyNever); 34515663c53SDawn Perchik 346a1e541bfSJim Ingham bool auto_apply_fixits; 347a1e541bfSJim Ingham if (m_command_options.auto_apply_fixits == eLazyBoolCalculate) 348a1e541bfSJim Ingham auto_apply_fixits = target->GetEnableAutoApplyFixIts(); 349a1e541bfSJim Ingham else 350a1e541bfSJim Ingham auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes ? true : false; 351a1e541bfSJim Ingham 352a1e541bfSJim Ingham options.SetAutoApplyFixIts(auto_apply_fixits); 353a1e541bfSJim Ingham 354863fab69SSean Callanan if (m_command_options.top_level) 355863fab69SSean Callanan options.SetExecutionPolicy(eExecutionPolicyTopLevel); 356863fab69SSean Callanan 35723f8c95aSGreg Clayton // If there is any chance we are going to stop and want to see 35823f8c95aSGreg Clayton // what went wrong with our expression, we should generate debug info 35923f8c95aSGreg Clayton if (!m_command_options.ignore_breakpoints || 36023f8c95aSGreg Clayton !m_command_options.unwind_on_error) 36123f8c95aSGreg Clayton options.SetGenerateDebugInfo(true); 36223f8c95aSGreg Clayton 36362afb9f6SGreg Clayton if (m_command_options.timeout > 0) 36462afb9f6SGreg Clayton options.SetTimeoutUsec(m_command_options.timeout); 3656f78f386SJim Ingham else 3666f78f386SJim Ingham options.SetTimeoutUsec(0); 367d4439aa9SEnrico Granata 368e5ee6f04SJim Ingham ExpressionResults success = target->EvaluateExpression(expr, frame, result_valobj_sp, options, &m_fixed_expression); 369e5ee6f04SJim Ingham 370e5ee6f04SJim Ingham // We only tell you about the FixIt if we applied it. The compiler errors will suggest the FixIt if it parsed. 371e5ee6f04SJim Ingham if (error_stream && !m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) 372e5ee6f04SJim Ingham { 373e5ee6f04SJim Ingham if (success == eExpressionCompleted) 374*279b2e88SJim Ingham error_stream->Printf (" Fix-it applied, fixed expression was: \n %s\n", m_fixed_expression.c_str()); 375e5ee6f04SJim Ingham } 3768b2fe6dcSGreg Clayton 3778b2fe6dcSGreg Clayton if (result_valobj_sp) 3788b2fe6dcSGreg Clayton { 379bf154daeSSean Callanan Format format = m_format_options.GetFormat(); 380bf154daeSSean Callanan 381b71f3844SGreg Clayton if (result_valobj_sp->GetError().Success()) 38230fdc8d8SChris Lattner { 383bf154daeSSean Callanan if (format != eFormatVoid) 384bf154daeSSean Callanan { 3851deb7962SGreg Clayton if (format != eFormatDefault) 3861deb7962SGreg Clayton result_valobj_sp->SetFormat (format); 38732c4085bSGreg Clayton 388520a422bSEnrico Granata if (m_varobj_options.elem_count > 0) 389520a422bSEnrico Granata { 390520a422bSEnrico Granata Error error(CanBeUsedForElementCountPrinting(*result_valobj_sp)); 391520a422bSEnrico Granata if (error.Fail()) 392520a422bSEnrico Granata { 393520a422bSEnrico Granata result->AppendErrorWithFormat("expression cannot be used with --element-count %s\n", error.AsCString("")); 394520a422bSEnrico Granata result->SetStatus(eReturnStatusFailed); 395520a422bSEnrico Granata return false; 396520a422bSEnrico Granata } 397520a422bSEnrico Granata } 398520a422bSEnrico Granata 3994d93b8cdSEnrico Granata DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format)); 40073e8c4d0SEnrico Granata options.SetVariableFormatDisplayLanguage(result_valobj_sp->GetPreferredDisplayLanguage()); 401770eb05aSEnrico Granata 4024d93b8cdSEnrico Granata result_valobj_sp->Dump(*output_stream,options); 4034d93b8cdSEnrico Granata 404fcd43b71SJohnny Chen if (result) 405fcd43b71SJohnny Chen result->SetStatus (eReturnStatusSuccessFinishResult); 40630fdc8d8SChris Lattner } 407bf154daeSSean Callanan } 40830fdc8d8SChris Lattner else 40930fdc8d8SChris Lattner { 410151c032cSJim Ingham if (result_valobj_sp->GetError().GetError() == UserExpression::kNoResult) 411bccce813SSean Callanan { 412bcf897faSSean Callanan if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid()) 413bf154daeSSean Callanan { 414bcf897faSSean Callanan error_stream->PutCString("(void)\n"); 415bcf897faSSean Callanan } 416bccce813SSean Callanan 417bccce813SSean Callanan if (result) 418bccce813SSean Callanan result->SetStatus (eReturnStatusSuccessFinishResult); 419bccce813SSean Callanan } 420bccce813SSean Callanan else 421bccce813SSean Callanan { 4225fd05903SGreg Clayton const char *error_cstr = result_valobj_sp->GetError().AsCString(); 4235fd05903SGreg Clayton if (error_cstr && error_cstr[0]) 4245fd05903SGreg Clayton { 425c7bece56SGreg Clayton const size_t error_cstr_len = strlen (error_cstr); 4265fd05903SGreg Clayton const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n'; 4275fd05903SGreg Clayton if (strstr(error_cstr, "error:") != error_cstr) 4285fd05903SGreg Clayton error_stream->PutCString ("error: "); 4295fd05903SGreg Clayton error_stream->Write(error_cstr, error_cstr_len); 4305fd05903SGreg Clayton if (!ends_with_newline) 4315fd05903SGreg Clayton error_stream->EOL(); 4325fd05903SGreg Clayton } 4335fd05903SGreg Clayton else 4345fd05903SGreg Clayton { 4355fd05903SGreg Clayton error_stream->PutCString ("error: unknown error\n"); 4365fd05903SGreg Clayton } 4375fd05903SGreg Clayton 438fcd43b71SJohnny Chen if (result) 439b71f3844SGreg Clayton result->SetStatus (eReturnStatusFailed); 44030fdc8d8SChris Lattner } 4418b2fe6dcSGreg Clayton } 4428b2fe6dcSGreg Clayton } 443bccce813SSean Callanan } 4448b2fe6dcSGreg Clayton else 4458b2fe6dcSGreg Clayton { 4466e8dc334SCaroline Tice error_stream->Printf ("error: invalid execution context for expression\n"); 4478b2fe6dcSGreg Clayton return false; 4488b2fe6dcSGreg Clayton } 44930fdc8d8SChris Lattner 45016ad5faeSSean Callanan return true; 45130fdc8d8SChris Lattner } 45230fdc8d8SChris Lattner 45344d93782SGreg Clayton void 45444d93782SGreg Clayton CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line) 45544d93782SGreg Clayton { 45644d93782SGreg Clayton io_handler.SetIsDone(true); 45744d93782SGreg Clayton // StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream(); 45844d93782SGreg Clayton // StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream(); 45944d93782SGreg Clayton StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 46044d93782SGreg Clayton StreamFileSP error_sp(io_handler.GetErrorStreamFile()); 46144d93782SGreg Clayton 46244d93782SGreg Clayton EvaluateExpression (line.c_str(), 46344d93782SGreg Clayton output_sp.get(), 46444d93782SGreg Clayton error_sp.get()); 46544d93782SGreg Clayton if (output_sp) 46644d93782SGreg Clayton output_sp->Flush(); 46744d93782SGreg Clayton if (error_sp) 46844d93782SGreg Clayton error_sp->Flush(); 46944d93782SGreg Clayton } 47044d93782SGreg Clayton 471f52c40c5SSean Callanan bool 472f52c40c5SSean Callanan CommandObjectExpression::IOHandlerIsInputComplete (IOHandler &io_handler, 473f52c40c5SSean Callanan StringList &lines) 47444d93782SGreg Clayton { 475f52c40c5SSean Callanan // An empty lines is used to indicate the end of input 476f52c40c5SSean Callanan const size_t num_lines = lines.GetSize(); 477f52c40c5SSean Callanan if (num_lines > 0 && lines[num_lines - 1].empty()) 47844d93782SGreg Clayton { 479f52c40c5SSean Callanan // Remove the last empty line from "lines" so it doesn't appear 480f52c40c5SSean Callanan // in our resulting input and return true to indicate we are done 481f52c40c5SSean Callanan // getting lines 48244d93782SGreg Clayton lines.PopBack(); 483f52c40c5SSean Callanan return true; 48444d93782SGreg Clayton } 485f52c40c5SSean Callanan return false; 48644d93782SGreg Clayton } 48744d93782SGreg Clayton 488cf28a8b7SGreg Clayton void 489cf28a8b7SGreg Clayton CommandObjectExpression::GetMultilineExpression () 49030fdc8d8SChris Lattner { 49130fdc8d8SChris Lattner m_expr_lines.clear(); 49230fdc8d8SChris Lattner m_expr_line_count = 0; 49330fdc8d8SChris Lattner 49444d93782SGreg Clayton Debugger &debugger = GetCommandInterpreter().GetDebugger(); 495e30f11d9SKate Stone bool color_prompt = debugger.GetUseColor(); 49644d93782SGreg Clayton const bool multiple_lines = true; // Get multiple lines 49744d93782SGreg Clayton IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger, 498e30f11d9SKate Stone IOHandler::Type::Expression, 49944d93782SGreg Clayton "lldb-expr", // Name of input reader for history 500c8ecc2a9SEugene Zelenko nullptr, // No prompt 501c8ecc2a9SEugene Zelenko nullptr, // Continuation prompt 50244d93782SGreg Clayton multiple_lines, 503e30f11d9SKate Stone color_prompt, 504f6913cd7SGreg Clayton 1, // Show line numbers starting at 1 50544d93782SGreg Clayton *this)); 506b6892508SGreg Clayton 507b6892508SGreg Clayton StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile()); 508b6892508SGreg Clayton if (output_sp) 509b6892508SGreg Clayton { 510b6892508SGreg Clayton output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n"); 511b6892508SGreg Clayton output_sp->Flush(); 512b6892508SGreg Clayton } 51344d93782SGreg Clayton debugger.PushIOHandler(io_handler_sp); 514cf28a8b7SGreg Clayton } 515cf28a8b7SGreg Clayton 516cf28a8b7SGreg Clayton bool 517c8ecc2a9SEugene Zelenko CommandObjectExpression::DoExecute(const char *command, 518c8ecc2a9SEugene Zelenko CommandReturnObject &result) 519cf28a8b7SGreg Clayton { 520e5ee6f04SJim Ingham m_fixed_expression.clear(); 521cf28a8b7SGreg Clayton m_option_group.NotifyOptionParsingStarting(); 522cf28a8b7SGreg Clayton 523c8ecc2a9SEugene Zelenko const char * expr = nullptr; 524cf28a8b7SGreg Clayton 525cf28a8b7SGreg Clayton if (command[0] == '\0') 526cf28a8b7SGreg Clayton { 527cf28a8b7SGreg Clayton GetMultilineExpression (); 52830fdc8d8SChris Lattner return result.Succeeded(); 52930fdc8d8SChris Lattner } 53030fdc8d8SChris Lattner 53130fdc8d8SChris Lattner if (command[0] == '-') 53230fdc8d8SChris Lattner { 53330fdc8d8SChris Lattner // We have some options and these options MUST end with --. 534c8ecc2a9SEugene Zelenko const char *end_options = nullptr; 53530fdc8d8SChris Lattner const char *s = command; 53630fdc8d8SChris Lattner while (s && s[0]) 53730fdc8d8SChris Lattner { 53830fdc8d8SChris Lattner end_options = ::strstr (s, "--"); 53930fdc8d8SChris Lattner if (end_options) 54030fdc8d8SChris Lattner { 54130fdc8d8SChris Lattner end_options += 2; // Get past the "--" 54230fdc8d8SChris Lattner if (::isspace (end_options[0])) 54330fdc8d8SChris Lattner { 54430fdc8d8SChris Lattner expr = end_options; 54530fdc8d8SChris Lattner while (::isspace (*expr)) 54630fdc8d8SChris Lattner ++expr; 54730fdc8d8SChris Lattner break; 54830fdc8d8SChris Lattner } 54930fdc8d8SChris Lattner } 55030fdc8d8SChris Lattner s = end_options; 55130fdc8d8SChris Lattner } 55230fdc8d8SChris Lattner 55330fdc8d8SChris Lattner if (end_options) 55430fdc8d8SChris Lattner { 55500b7f95bSPavel Labath Args args (llvm::StringRef(command, end_options - command)); 556a7015092SGreg Clayton if (!ParseOptions (args, result)) 55730fdc8d8SChris Lattner return false; 558f6b8b581SGreg Clayton 5591deb7962SGreg Clayton Error error (m_option_group.NotifyOptionParsingFinished()); 560f6b8b581SGreg Clayton if (error.Fail()) 561f6b8b581SGreg Clayton { 562f6b8b581SGreg Clayton result.AppendError (error.AsCString()); 563f6b8b581SGreg Clayton result.SetStatus (eReturnStatusFailed); 564f6b8b581SGreg Clayton return false; 565f6b8b581SGreg Clayton } 566cf28a8b7SGreg Clayton 567f2bd5c3eSSean Callanan if (m_repl_option.GetOptionValue().GetCurrentValue()) 568f2bd5c3eSSean Callanan { 569f2bd5c3eSSean Callanan Target *target = m_interpreter.GetExecutionContext().GetTargetPtr(); 570f2bd5c3eSSean Callanan if (target) 571f2bd5c3eSSean Callanan { 572f2bd5c3eSSean Callanan // Drop into REPL 573f2bd5c3eSSean Callanan m_expr_lines.clear(); 574f2bd5c3eSSean Callanan m_expr_line_count = 0; 575f2bd5c3eSSean Callanan 576f2bd5c3eSSean Callanan Debugger &debugger = target->GetDebugger(); 577f2bd5c3eSSean Callanan 578f2bd5c3eSSean Callanan // Check if the LLDB command interpreter is sitting on top of a REPL that 579f2bd5c3eSSean Callanan // launched it... 580f2bd5c3eSSean Callanan if (debugger.CheckTopIOHandlerTypes(IOHandler::Type::CommandInterpreter, IOHandler::Type::REPL)) 581f2bd5c3eSSean Callanan { 582f2bd5c3eSSean Callanan // the LLDB command interpreter is sitting on top of a REPL that launched it, 583f2bd5c3eSSean Callanan // so just say the command interpreter is done and fall back to the existing REPL 584f2bd5c3eSSean Callanan m_interpreter.GetIOHandler(false)->SetIsDone(true); 585f2bd5c3eSSean Callanan } 586f2bd5c3eSSean Callanan else 587f2bd5c3eSSean Callanan { 588f2bd5c3eSSean Callanan // We are launching the REPL on top of the current LLDB command interpreter, 589f2bd5c3eSSean Callanan // so just push one 590f2bd5c3eSSean Callanan bool initialize = false; 591f2bd5c3eSSean Callanan Error repl_error; 592f2bd5c3eSSean Callanan REPLSP repl_sp (target->GetREPL(repl_error, m_command_options.language, nullptr, false)); 593f2bd5c3eSSean Callanan 594f2bd5c3eSSean Callanan if (!repl_sp) 595f2bd5c3eSSean Callanan { 596f2bd5c3eSSean Callanan initialize = true; 597f2bd5c3eSSean Callanan repl_sp = target->GetREPL(repl_error, m_command_options.language, nullptr, true); 598f2bd5c3eSSean Callanan if (!repl_error.Success()) 599f2bd5c3eSSean Callanan { 600f2bd5c3eSSean Callanan result.SetError(repl_error); 601f2bd5c3eSSean Callanan return result.Succeeded(); 602f2bd5c3eSSean Callanan } 603f2bd5c3eSSean Callanan } 604f2bd5c3eSSean Callanan 605f2bd5c3eSSean Callanan if (repl_sp) 606f2bd5c3eSSean Callanan { 607f2bd5c3eSSean Callanan if (initialize) 608f2bd5c3eSSean Callanan { 609f2bd5c3eSSean Callanan repl_sp->SetCommandOptions(m_command_options); 610f2bd5c3eSSean Callanan repl_sp->SetFormatOptions(m_format_options); 611f2bd5c3eSSean Callanan repl_sp->SetValueObjectDisplayOptions(m_varobj_options); 612f2bd5c3eSSean Callanan } 613f2bd5c3eSSean Callanan 614f2bd5c3eSSean Callanan IOHandlerSP io_handler_sp (repl_sp->GetIOHandler()); 615f2bd5c3eSSean Callanan 616f2bd5c3eSSean Callanan io_handler_sp->SetIsDone(false); 617f2bd5c3eSSean Callanan 618f2bd5c3eSSean Callanan debugger.PushIOHandler(io_handler_sp); 619f2bd5c3eSSean Callanan } 620f2bd5c3eSSean Callanan else 621f2bd5c3eSSean Callanan { 622f2bd5c3eSSean Callanan repl_error.SetErrorStringWithFormat("Couldn't create a REPL for %s", Language::GetNameForLanguageType(m_command_options.language)); 623f2bd5c3eSSean Callanan result.SetError(repl_error); 624f2bd5c3eSSean Callanan return result.Succeeded(); 625f2bd5c3eSSean Callanan } 626f2bd5c3eSSean Callanan } 627f2bd5c3eSSean Callanan } 628f2bd5c3eSSean Callanan } 629cf28a8b7SGreg Clayton // No expression following options 630c8ecc2a9SEugene Zelenko else if (expr == nullptr || expr[0] == '\0') 631cf28a8b7SGreg Clayton { 632cf28a8b7SGreg Clayton GetMultilineExpression (); 633cf28a8b7SGreg Clayton return result.Succeeded(); 634cf28a8b7SGreg Clayton } 63530fdc8d8SChris Lattner } 63630fdc8d8SChris Lattner } 63730fdc8d8SChris Lattner 638c8ecc2a9SEugene Zelenko if (expr == nullptr) 63930fdc8d8SChris Lattner expr = command; 64030fdc8d8SChris Lattner 6416e8dc334SCaroline Tice if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result)) 642e5ee6f04SJim Ingham { 643e5ee6f04SJim Ingham Target *target = m_interpreter.GetExecutionContext().GetTargetPtr(); 644e5ee6f04SJim Ingham if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) 645e5ee6f04SJim Ingham { 646e5ee6f04SJim Ingham CommandHistory &history = m_interpreter.GetCommandHistory(); 647e5ee6f04SJim Ingham // FIXME: Can we figure out what the user actually typed (e.g. some alias for expr???) 648e5ee6f04SJim Ingham // If we can it would be nice to show that. 649e5ee6f04SJim Ingham std::string fixed_command("expression "); 650e5ee6f04SJim Ingham if (expr == command) 651e5ee6f04SJim Ingham fixed_command.append(m_fixed_expression); 652e5ee6f04SJim Ingham else 653e5ee6f04SJim Ingham { 654e5ee6f04SJim Ingham // Add in any options that might have been in the original command: 655e5ee6f04SJim Ingham fixed_command.append(command, expr - command); 656e5ee6f04SJim Ingham fixed_command.append(m_fixed_expression); 657e5ee6f04SJim Ingham } 658e5ee6f04SJim Ingham history.AppendString(fixed_command); 659e5ee6f04SJim Ingham } 660fcd43b71SJohnny Chen return true; 661e5ee6f04SJim Ingham } 662fcd43b71SJohnny Chen 663fcd43b71SJohnny Chen result.SetStatus (eReturnStatusFailed); 664fcd43b71SJohnny Chen return false; 66530fdc8d8SChris Lattner } 666