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*a1e541bfSJim Ingham { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "If true, simple FixIt 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."}, 661deb7962SGreg Clayton }; 671deb7962SGreg Clayton 681deb7962SGreg Clayton uint32_t 691deb7962SGreg Clayton CommandObjectExpression::CommandOptions::GetNumDefinitions () 701deb7962SGreg Clayton { 7128606954SSaleem Abdulrasool return llvm::array_lengthof(g_option_table); 721deb7962SGreg Clayton } 731deb7962SGreg Clayton 7430fdc8d8SChris Lattner Error 751deb7962SGreg Clayton CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter, 761deb7962SGreg Clayton uint32_t option_idx, 771deb7962SGreg Clayton const char *option_arg) 7830fdc8d8SChris Lattner { 7930fdc8d8SChris Lattner Error error; 8030fdc8d8SChris Lattner 813bcdfc0eSGreg Clayton const int short_option = g_option_table[option_idx].short_option; 8230fdc8d8SChris Lattner 8330fdc8d8SChris Lattner switch (short_option) 8430fdc8d8SChris Lattner { 8515663c53SDawn Perchik case 'l': 860e0984eeSJim Ingham language = Language::GetLanguageTypeFromString (option_arg); 8715663c53SDawn Perchik if (language == eLanguageTypeUnknown) 8815663c53SDawn Perchik error.SetErrorStringWithFormat ("unknown language type: '%s' for expression", option_arg); 8915663c53SDawn Perchik break; 9030fdc8d8SChris Lattner 9135e1bda6SJim Ingham case 'a': 9235e1bda6SJim Ingham { 9335e1bda6SJim Ingham bool success; 9435e1bda6SJim Ingham bool result; 9535e1bda6SJim Ingham result = Args::StringToBoolean(option_arg, true, &success); 9635e1bda6SJim Ingham if (!success) 9735e1bda6SJim Ingham error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg); 9835e1bda6SJim Ingham else 9935e1bda6SJim Ingham try_all_threads = result; 10035e1bda6SJim Ingham } 1016c68fb45SJim Ingham break; 1026c68fb45SJim Ingham 103184e9811SJim Ingham case 'i': 104184e9811SJim Ingham { 105184e9811SJim Ingham bool success; 106184e9811SJim Ingham bool tmp_value = Args::StringToBoolean(option_arg, true, &success); 107184e9811SJim Ingham if (success) 108184e9811SJim Ingham ignore_breakpoints = tmp_value; 109184e9811SJim Ingham else 110184e9811SJim Ingham error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg); 111184e9811SJim Ingham break; 112184e9811SJim Ingham } 11335e1bda6SJim Ingham case 't': 11435e1bda6SJim Ingham { 11535e1bda6SJim Ingham bool success; 11635e1bda6SJim Ingham uint32_t result; 1175275aaa0SVince Harron result = StringConvert::ToUInt32(option_arg, 0, 0, &success); 11835e1bda6SJim Ingham if (success) 11935e1bda6SJim Ingham timeout = result; 12035e1bda6SJim Ingham else 12135e1bda6SJim Ingham error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg); 12235e1bda6SJim Ingham } 12335e1bda6SJim Ingham break; 12435e1bda6SJim Ingham 125399f1cafSJim Ingham case 'u': 1263bfdaa2aSSean Callanan { 127399f1cafSJim Ingham bool success; 128184e9811SJim Ingham bool tmp_value = Args::StringToBoolean(option_arg, true, &success); 129184e9811SJim Ingham if (success) 130184e9811SJim Ingham unwind_on_error = tmp_value; 131184e9811SJim Ingham else 13286edbf41SGreg Clayton error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg); 133399f1cafSJim Ingham break; 1343bfdaa2aSSean Callanan } 1354d93b8cdSEnrico Granata 1364d93b8cdSEnrico Granata case 'v': 1374d93b8cdSEnrico Granata if (!option_arg) 1384d93b8cdSEnrico Granata { 1394d93b8cdSEnrico Granata m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull; 1404d93b8cdSEnrico Granata break; 1414d93b8cdSEnrico Granata } 1424d93b8cdSEnrico Granata m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 1434d93b8cdSEnrico Granata if (!error.Success()) 1444d93b8cdSEnrico Granata error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg); 1454d93b8cdSEnrico Granata break; 1464d93b8cdSEnrico Granata 14762afb9f6SGreg Clayton case 'g': 14862afb9f6SGreg Clayton debug = true; 14962afb9f6SGreg Clayton unwind_on_error = false; 15062afb9f6SGreg Clayton ignore_breakpoints = false; 15162afb9f6SGreg Clayton break; 15262afb9f6SGreg Clayton 153*a1e541bfSJim Ingham case 'X': 154*a1e541bfSJim Ingham { 155*a1e541bfSJim Ingham bool success; 156*a1e541bfSJim Ingham bool tmp_value = Args::StringToBoolean(option_arg, true, &success); 157*a1e541bfSJim Ingham if (success) 158*a1e541bfSJim Ingham auto_apply_fixits = tmp_value ? eLazyBoolYes : eLazyBoolNo; 159*a1e541bfSJim Ingham else 160*a1e541bfSJim Ingham error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg); 161*a1e541bfSJim Ingham break; 162*a1e541bfSJim Ingham } 163*a1e541bfSJim Ingham 16430fdc8d8SChris Lattner default: 16586edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 16630fdc8d8SChris Lattner break; 16730fdc8d8SChris Lattner } 16830fdc8d8SChris Lattner 16930fdc8d8SChris Lattner return error; 17030fdc8d8SChris Lattner } 17130fdc8d8SChris Lattner 17230fdc8d8SChris Lattner void 1731deb7962SGreg Clayton CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter) 17430fdc8d8SChris Lattner { 175184e9811SJim Ingham Process *process = interpreter.GetExecutionContext().GetProcessPtr(); 176c8ecc2a9SEugene Zelenko if (process != nullptr) 177184e9811SJim Ingham { 178184e9811SJim Ingham ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions(); 179184e9811SJim Ingham unwind_on_error = process->GetUnwindOnErrorInExpressions(); 180184e9811SJim Ingham } 181184e9811SJim Ingham else 182184e9811SJim Ingham { 183fc03f8fcSGreg Clayton ignore_breakpoints = true; 184399f1cafSJim Ingham unwind_on_error = true; 185184e9811SJim Ingham } 186184e9811SJim Ingham 18730fdc8d8SChris Lattner show_summary = true; 18835e1bda6SJim Ingham try_all_threads = true; 18935e1bda6SJim Ingham timeout = 0; 19062afb9f6SGreg Clayton debug = false; 19115663c53SDawn Perchik language = eLanguageTypeUnknown; 1924d93b8cdSEnrico Granata m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact; 193*a1e541bfSJim Ingham auto_apply_fixits = eLazyBoolCalculate; 19430fdc8d8SChris Lattner } 19530fdc8d8SChris Lattner 196e0d378b3SGreg Clayton const OptionDefinition* 19730fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::GetDefinitions () 19830fdc8d8SChris Lattner { 19930fdc8d8SChris Lattner return g_option_table; 20030fdc8d8SChris Lattner } 20130fdc8d8SChris Lattner 202a7015092SGreg Clayton CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) : 2035a988416SJim Ingham CommandObjectRaw(interpreter, 20430fdc8d8SChris Lattner "expression", 20515663c53SDawn Perchik "Evaluate an expression in the current program context, using user defined variables and variables currently in scope.", 206c8ecc2a9SEugene Zelenko nullptr, 207e87764f2SEnrico Granata eCommandProcessMustBePaused | eCommandTryTargetAPILock), 20844d93782SGreg Clayton IOHandlerDelegate (IOHandlerDelegate::Completion::Expression), 2091deb7962SGreg Clayton m_option_group (interpreter), 2101deb7962SGreg Clayton m_format_options (eFormatDefault), 211f2bd5c3eSSean Callanan m_repl_option (LLDB_OPT_SET_1, false, "repl", 'r', "Drop into REPL", false, true), 2121deb7962SGreg Clayton m_command_options (), 21330fdc8d8SChris Lattner m_expr_line_count (0), 21430fdc8d8SChris Lattner m_expr_lines () 21530fdc8d8SChris Lattner { 21630fdc8d8SChris Lattner SetHelpLong( 217ea671fbdSKate Stone R"( 218ea671fbdSKate Stone Timeouts: 219ea671fbdSKate Stone 220ea671fbdSKate Stone )" " If the expression can be evaluated statically (without running code) then it will be. \ 221ea671fbdSKate Stone Otherwise, by default the expression will run on the current thread with a short timeout: \ 222ea671fbdSKate Stone currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted \ 223ea671fbdSKate Stone and resumed with all threads running. You can use the -a option to disable retrying on all \ 224ea671fbdSKate Stone threads. You can use the -t option to set a shorter timeout." R"( 225ea671fbdSKate Stone 226ea671fbdSKate Stone User defined variables: 227ea671fbdSKate Stone 228ea671fbdSKate Stone )" " You can define your own variables for convenience or to be used in subsequent expressions. \ 229ea671fbdSKate Stone You define them the same way you would define variables in C. If the first character of \ 230ea671fbdSKate Stone your user defined variable is a $, then the variable's value will be available in future \ 231ea671fbdSKate Stone expressions, otherwise it will just be available in the current expression." R"( 232ea671fbdSKate Stone 233ea671fbdSKate Stone Continuing evaluation after a breakpoint: 234ea671fbdSKate Stone 235ea671fbdSKate Stone )" " If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \ 236ea671fbdSKate Stone you are done with your investigation, you can either remove the expression execution frames \ 237ea671fbdSKate Stone from the stack with \"thread return -x\" or if you are still interested in the expression result \ 238ea671fbdSKate Stone you can issue the \"continue\" command and the expression evaluation will complete and the \ 239ea671fbdSKate Stone expression result will be available using the \"thread.completed-expression\" key in the thread \ 240ea671fbdSKate Stone format." R"( 241ea671fbdSKate Stone 242ea671fbdSKate Stone Examples: 243ea671fbdSKate Stone 244ea671fbdSKate Stone expr my_struct->a = my_array[3] 245ea671fbdSKate Stone expr -f bin -- (index * 8) + 5 246ea671fbdSKate Stone expr unsigned int $foo = 5 247ea671fbdSKate Stone expr char c[] = \"foo\"; c[0])" 248ea671fbdSKate Stone ); 249405fe67fSCaroline Tice 250405fe67fSCaroline Tice CommandArgumentEntry arg; 251405fe67fSCaroline Tice CommandArgumentData expression_arg; 252405fe67fSCaroline Tice 253405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 254405fe67fSCaroline Tice expression_arg.arg_type = eArgTypeExpression; 255405fe67fSCaroline Tice expression_arg.arg_repetition = eArgRepeatPlain; 256405fe67fSCaroline Tice 257405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 258405fe67fSCaroline Tice arg.push_back (expression_arg); 259405fe67fSCaroline Tice 260405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 261405fe67fSCaroline Tice m_arguments.push_back (arg); 2621deb7962SGreg Clayton 2635009f9d5SGreg Clayton // Add the "--format" and "--gdb-format" 2645009f9d5SGreg Clayton m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1); 2651deb7962SGreg Clayton m_option_group.Append (&m_command_options); 266b576bba2SEnrico Granata m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2); 267f2bd5c3eSSean Callanan m_option_group.Append (&m_repl_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3); 2681deb7962SGreg Clayton m_option_group.Finalize(); 26930fdc8d8SChris Lattner } 27030fdc8d8SChris Lattner 271c8ecc2a9SEugene Zelenko CommandObjectExpression::~CommandObjectExpression() = default; 27230fdc8d8SChris Lattner 27330fdc8d8SChris Lattner Options * 27430fdc8d8SChris Lattner CommandObjectExpression::GetOptions () 27530fdc8d8SChris Lattner { 2761deb7962SGreg Clayton return &m_option_group; 27730fdc8d8SChris Lattner } 27830fdc8d8SChris Lattner 27930fdc8d8SChris Lattner bool 280c8ecc2a9SEugene Zelenko CommandObjectExpression::EvaluateExpression(const char *expr, 2816e8dc334SCaroline Tice Stream *output_stream, 2826e8dc334SCaroline Tice Stream *error_stream, 283c8ecc2a9SEugene Zelenko CommandReturnObject *result) 28430fdc8d8SChris Lattner { 285ba7b8e2cSGreg Clayton // Don't use m_exe_ctx as this might be called asynchronously 286ba7b8e2cSGreg Clayton // after the command object DoExecute has finished when doing 287ba7b8e2cSGreg Clayton // multi-line expression that use an input reader... 288ba7b8e2cSGreg Clayton ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 289ba7b8e2cSGreg Clayton 290ba7b8e2cSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 291c0a6e061SSean Callanan 292c0a6e061SSean Callanan if (!target) 293893c932aSJim Ingham target = GetDummyTarget(); 294c0a6e061SSean Callanan 295c14ee32dSGreg Clayton if (target) 2966961e878SSean Callanan { 2978b2fe6dcSGreg Clayton lldb::ValueObjectSP result_valobj_sp; 29892adcac9SSean Callanan bool keep_in_memory = true; 299009d110dSDawn Perchik StackFrame *frame = exe_ctx.GetFramePtr(); 30092adcac9SSean Callanan 30135e1bda6SJim Ingham EvaluateExpressionOptions options; 3026fbc48bcSJim Ingham options.SetCoerceToId(m_varobj_options.use_objc); 3036fbc48bcSJim Ingham options.SetUnwindOnError(m_command_options.unwind_on_error); 3046fbc48bcSJim Ingham options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints); 3056fbc48bcSJim Ingham options.SetKeepInMemory(keep_in_memory); 3066fbc48bcSJim Ingham options.SetUseDynamic(m_varobj_options.use_dynamic); 3076fbc48bcSJim Ingham options.SetTryAllThreads(m_command_options.try_all_threads); 3086fbc48bcSJim Ingham options.SetDebug(m_command_options.debug); 30915663c53SDawn Perchik options.SetLanguage(m_command_options.language); 31015663c53SDawn Perchik 311*a1e541bfSJim Ingham bool auto_apply_fixits; 312*a1e541bfSJim Ingham if (m_command_options.auto_apply_fixits == eLazyBoolCalculate) 313*a1e541bfSJim Ingham auto_apply_fixits = target->GetEnableAutoApplyFixIts(); 314*a1e541bfSJim Ingham else 315*a1e541bfSJim Ingham auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes ? true : false; 316*a1e541bfSJim Ingham 317*a1e541bfSJim Ingham options.SetAutoApplyFixIts(auto_apply_fixits); 318*a1e541bfSJim Ingham 31923f8c95aSGreg Clayton // If there is any chance we are going to stop and want to see 32023f8c95aSGreg Clayton // what went wrong with our expression, we should generate debug info 32123f8c95aSGreg Clayton if (!m_command_options.ignore_breakpoints || 32223f8c95aSGreg Clayton !m_command_options.unwind_on_error) 32323f8c95aSGreg Clayton options.SetGenerateDebugInfo(true); 32423f8c95aSGreg Clayton 32562afb9f6SGreg Clayton if (m_command_options.timeout > 0) 32662afb9f6SGreg Clayton options.SetTimeoutUsec(m_command_options.timeout); 3276f78f386SJim Ingham else 3286f78f386SJim Ingham options.SetTimeoutUsec(0); 329d4439aa9SEnrico Granata 330009d110dSDawn Perchik target->EvaluateExpression(expr, frame, result_valobj_sp, options); 3318b2fe6dcSGreg Clayton 3328b2fe6dcSGreg Clayton if (result_valobj_sp) 3338b2fe6dcSGreg Clayton { 334bf154daeSSean Callanan Format format = m_format_options.GetFormat(); 335bf154daeSSean Callanan 336b71f3844SGreg Clayton if (result_valobj_sp->GetError().Success()) 33730fdc8d8SChris Lattner { 338bf154daeSSean Callanan if (format != eFormatVoid) 339bf154daeSSean Callanan { 3401deb7962SGreg Clayton if (format != eFormatDefault) 3411deb7962SGreg Clayton result_valobj_sp->SetFormat (format); 34232c4085bSGreg Clayton 3434d93b8cdSEnrico Granata DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format)); 34473e8c4d0SEnrico Granata options.SetVariableFormatDisplayLanguage(result_valobj_sp->GetPreferredDisplayLanguage()); 345770eb05aSEnrico Granata 3464d93b8cdSEnrico Granata result_valobj_sp->Dump(*output_stream,options); 3474d93b8cdSEnrico Granata 348fcd43b71SJohnny Chen if (result) 349fcd43b71SJohnny Chen result->SetStatus (eReturnStatusSuccessFinishResult); 35030fdc8d8SChris Lattner } 351bf154daeSSean Callanan } 35230fdc8d8SChris Lattner else 35330fdc8d8SChris Lattner { 354151c032cSJim Ingham if (result_valobj_sp->GetError().GetError() == UserExpression::kNoResult) 355bccce813SSean Callanan { 356bcf897faSSean Callanan if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid()) 357bf154daeSSean Callanan { 358bcf897faSSean Callanan error_stream->PutCString("(void)\n"); 359bcf897faSSean Callanan } 360bccce813SSean Callanan 361bccce813SSean Callanan if (result) 362bccce813SSean Callanan result->SetStatus (eReturnStatusSuccessFinishResult); 363bccce813SSean Callanan } 364bccce813SSean Callanan else 365bccce813SSean Callanan { 3665fd05903SGreg Clayton const char *error_cstr = result_valobj_sp->GetError().AsCString(); 3675fd05903SGreg Clayton if (error_cstr && error_cstr[0]) 3685fd05903SGreg Clayton { 369c7bece56SGreg Clayton const size_t error_cstr_len = strlen (error_cstr); 3705fd05903SGreg Clayton const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n'; 3715fd05903SGreg Clayton if (strstr(error_cstr, "error:") != error_cstr) 3725fd05903SGreg Clayton error_stream->PutCString ("error: "); 3735fd05903SGreg Clayton error_stream->Write(error_cstr, error_cstr_len); 3745fd05903SGreg Clayton if (!ends_with_newline) 3755fd05903SGreg Clayton error_stream->EOL(); 3765fd05903SGreg Clayton } 3775fd05903SGreg Clayton else 3785fd05903SGreg Clayton { 3795fd05903SGreg Clayton error_stream->PutCString ("error: unknown error\n"); 3805fd05903SGreg Clayton } 3815fd05903SGreg Clayton 382fcd43b71SJohnny Chen if (result) 383b71f3844SGreg Clayton result->SetStatus (eReturnStatusFailed); 38430fdc8d8SChris Lattner } 3858b2fe6dcSGreg Clayton } 3868b2fe6dcSGreg Clayton } 387bccce813SSean Callanan } 3888b2fe6dcSGreg Clayton else 3898b2fe6dcSGreg Clayton { 3906e8dc334SCaroline Tice error_stream->Printf ("error: invalid execution context for expression\n"); 3918b2fe6dcSGreg Clayton return false; 3928b2fe6dcSGreg Clayton } 39330fdc8d8SChris Lattner 39416ad5faeSSean Callanan return true; 39530fdc8d8SChris Lattner } 39630fdc8d8SChris Lattner 39744d93782SGreg Clayton void 39844d93782SGreg Clayton CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line) 39944d93782SGreg Clayton { 40044d93782SGreg Clayton io_handler.SetIsDone(true); 40144d93782SGreg Clayton // StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream(); 40244d93782SGreg Clayton // StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream(); 40344d93782SGreg Clayton StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 40444d93782SGreg Clayton StreamFileSP error_sp(io_handler.GetErrorStreamFile()); 40544d93782SGreg Clayton 40644d93782SGreg Clayton EvaluateExpression (line.c_str(), 40744d93782SGreg Clayton output_sp.get(), 40844d93782SGreg Clayton error_sp.get()); 40944d93782SGreg Clayton if (output_sp) 41044d93782SGreg Clayton output_sp->Flush(); 41144d93782SGreg Clayton if (error_sp) 41244d93782SGreg Clayton error_sp->Flush(); 41344d93782SGreg Clayton } 41444d93782SGreg Clayton 41544d93782SGreg Clayton LineStatus 41644d93782SGreg Clayton CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler, 41744d93782SGreg Clayton StringList &lines, 41844d93782SGreg Clayton uint32_t line_idx, 41944d93782SGreg Clayton Error &error) 42044d93782SGreg Clayton { 42144d93782SGreg Clayton if (line_idx == UINT32_MAX) 42244d93782SGreg Clayton { 42344d93782SGreg Clayton // Remove the last line from "lines" so it doesn't appear 42444d93782SGreg Clayton // in our final expression 42544d93782SGreg Clayton lines.PopBack(); 42644d93782SGreg Clayton error.Clear(); 42744d93782SGreg Clayton return LineStatus::Done; 42844d93782SGreg Clayton } 42944d93782SGreg Clayton else if (line_idx + 1 == lines.GetSize()) 43044d93782SGreg Clayton { 43144d93782SGreg Clayton // The last line was edited, if this line is empty, then we are done 43244d93782SGreg Clayton // getting our multiple lines. 43344d93782SGreg Clayton if (lines[line_idx].empty()) 43444d93782SGreg Clayton return LineStatus::Done; 43544d93782SGreg Clayton } 43644d93782SGreg Clayton return LineStatus::Success; 43744d93782SGreg Clayton } 43844d93782SGreg Clayton 439cf28a8b7SGreg Clayton void 440cf28a8b7SGreg Clayton CommandObjectExpression::GetMultilineExpression () 44130fdc8d8SChris Lattner { 44230fdc8d8SChris Lattner m_expr_lines.clear(); 44330fdc8d8SChris Lattner m_expr_line_count = 0; 44430fdc8d8SChris Lattner 44544d93782SGreg Clayton Debugger &debugger = GetCommandInterpreter().GetDebugger(); 446e30f11d9SKate Stone bool color_prompt = debugger.GetUseColor(); 44744d93782SGreg Clayton const bool multiple_lines = true; // Get multiple lines 44844d93782SGreg Clayton IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger, 449e30f11d9SKate Stone IOHandler::Type::Expression, 45044d93782SGreg Clayton "lldb-expr", // Name of input reader for history 451c8ecc2a9SEugene Zelenko nullptr, // No prompt 452c8ecc2a9SEugene Zelenko nullptr, // Continuation prompt 45344d93782SGreg Clayton multiple_lines, 454e30f11d9SKate Stone color_prompt, 455f6913cd7SGreg Clayton 1, // Show line numbers starting at 1 45644d93782SGreg Clayton *this)); 457b6892508SGreg Clayton 458b6892508SGreg Clayton StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile()); 459b6892508SGreg Clayton if (output_sp) 460b6892508SGreg Clayton { 461b6892508SGreg Clayton output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n"); 462b6892508SGreg Clayton output_sp->Flush(); 463b6892508SGreg Clayton } 46444d93782SGreg Clayton debugger.PushIOHandler(io_handler_sp); 465cf28a8b7SGreg Clayton } 466cf28a8b7SGreg Clayton 467cf28a8b7SGreg Clayton bool 468c8ecc2a9SEugene Zelenko CommandObjectExpression::DoExecute(const char *command, 469c8ecc2a9SEugene Zelenko CommandReturnObject &result) 470cf28a8b7SGreg Clayton { 471cf28a8b7SGreg Clayton m_option_group.NotifyOptionParsingStarting(); 472cf28a8b7SGreg Clayton 473c8ecc2a9SEugene Zelenko const char * expr = nullptr; 474cf28a8b7SGreg Clayton 475cf28a8b7SGreg Clayton if (command[0] == '\0') 476cf28a8b7SGreg Clayton { 477cf28a8b7SGreg Clayton GetMultilineExpression (); 47830fdc8d8SChris Lattner return result.Succeeded(); 47930fdc8d8SChris Lattner } 48030fdc8d8SChris Lattner 48130fdc8d8SChris Lattner if (command[0] == '-') 48230fdc8d8SChris Lattner { 48330fdc8d8SChris Lattner // We have some options and these options MUST end with --. 484c8ecc2a9SEugene Zelenko const char *end_options = nullptr; 48530fdc8d8SChris Lattner const char *s = command; 48630fdc8d8SChris Lattner while (s && s[0]) 48730fdc8d8SChris Lattner { 48830fdc8d8SChris Lattner end_options = ::strstr (s, "--"); 48930fdc8d8SChris Lattner if (end_options) 49030fdc8d8SChris Lattner { 49130fdc8d8SChris Lattner end_options += 2; // Get past the "--" 49230fdc8d8SChris Lattner if (::isspace (end_options[0])) 49330fdc8d8SChris Lattner { 49430fdc8d8SChris Lattner expr = end_options; 49530fdc8d8SChris Lattner while (::isspace (*expr)) 49630fdc8d8SChris Lattner ++expr; 49730fdc8d8SChris Lattner break; 49830fdc8d8SChris Lattner } 49930fdc8d8SChris Lattner } 50030fdc8d8SChris Lattner s = end_options; 50130fdc8d8SChris Lattner } 50230fdc8d8SChris Lattner 50330fdc8d8SChris Lattner if (end_options) 50430fdc8d8SChris Lattner { 50500b7f95bSPavel Labath Args args (llvm::StringRef(command, end_options - command)); 506a7015092SGreg Clayton if (!ParseOptions (args, result)) 50730fdc8d8SChris Lattner return false; 508f6b8b581SGreg Clayton 5091deb7962SGreg Clayton Error error (m_option_group.NotifyOptionParsingFinished()); 510f6b8b581SGreg Clayton if (error.Fail()) 511f6b8b581SGreg Clayton { 512f6b8b581SGreg Clayton result.AppendError (error.AsCString()); 513f6b8b581SGreg Clayton result.SetStatus (eReturnStatusFailed); 514f6b8b581SGreg Clayton return false; 515f6b8b581SGreg Clayton } 516cf28a8b7SGreg Clayton 517f2bd5c3eSSean Callanan if (m_repl_option.GetOptionValue().GetCurrentValue()) 518f2bd5c3eSSean Callanan { 519f2bd5c3eSSean Callanan Target *target = m_interpreter.GetExecutionContext().GetTargetPtr(); 520f2bd5c3eSSean Callanan if (target) 521f2bd5c3eSSean Callanan { 522f2bd5c3eSSean Callanan // Drop into REPL 523f2bd5c3eSSean Callanan m_expr_lines.clear(); 524f2bd5c3eSSean Callanan m_expr_line_count = 0; 525f2bd5c3eSSean Callanan 526f2bd5c3eSSean Callanan Debugger &debugger = target->GetDebugger(); 527f2bd5c3eSSean Callanan 528f2bd5c3eSSean Callanan // Check if the LLDB command interpreter is sitting on top of a REPL that 529f2bd5c3eSSean Callanan // launched it... 530f2bd5c3eSSean Callanan if (debugger.CheckTopIOHandlerTypes(IOHandler::Type::CommandInterpreter, IOHandler::Type::REPL)) 531f2bd5c3eSSean Callanan { 532f2bd5c3eSSean Callanan // the LLDB command interpreter is sitting on top of a REPL that launched it, 533f2bd5c3eSSean Callanan // so just say the command interpreter is done and fall back to the existing REPL 534f2bd5c3eSSean Callanan m_interpreter.GetIOHandler(false)->SetIsDone(true); 535f2bd5c3eSSean Callanan } 536f2bd5c3eSSean Callanan else 537f2bd5c3eSSean Callanan { 538f2bd5c3eSSean Callanan // We are launching the REPL on top of the current LLDB command interpreter, 539f2bd5c3eSSean Callanan // so just push one 540f2bd5c3eSSean Callanan bool initialize = false; 541f2bd5c3eSSean Callanan Error repl_error; 542f2bd5c3eSSean Callanan REPLSP repl_sp (target->GetREPL(repl_error, m_command_options.language, nullptr, false)); 543f2bd5c3eSSean Callanan 544f2bd5c3eSSean Callanan if (!repl_sp) 545f2bd5c3eSSean Callanan { 546f2bd5c3eSSean Callanan initialize = true; 547f2bd5c3eSSean Callanan repl_sp = target->GetREPL(repl_error, m_command_options.language, nullptr, true); 548f2bd5c3eSSean Callanan if (!repl_error.Success()) 549f2bd5c3eSSean Callanan { 550f2bd5c3eSSean Callanan result.SetError(repl_error); 551f2bd5c3eSSean Callanan return result.Succeeded(); 552f2bd5c3eSSean Callanan } 553f2bd5c3eSSean Callanan } 554f2bd5c3eSSean Callanan 555f2bd5c3eSSean Callanan if (repl_sp) 556f2bd5c3eSSean Callanan { 557f2bd5c3eSSean Callanan if (initialize) 558f2bd5c3eSSean Callanan { 559f2bd5c3eSSean Callanan repl_sp->SetCommandOptions(m_command_options); 560f2bd5c3eSSean Callanan repl_sp->SetFormatOptions(m_format_options); 561f2bd5c3eSSean Callanan repl_sp->SetValueObjectDisplayOptions(m_varobj_options); 562f2bd5c3eSSean Callanan } 563f2bd5c3eSSean Callanan 564f2bd5c3eSSean Callanan IOHandlerSP io_handler_sp (repl_sp->GetIOHandler()); 565f2bd5c3eSSean Callanan 566f2bd5c3eSSean Callanan io_handler_sp->SetIsDone(false); 567f2bd5c3eSSean Callanan 568f2bd5c3eSSean Callanan debugger.PushIOHandler(io_handler_sp); 569f2bd5c3eSSean Callanan } 570f2bd5c3eSSean Callanan else 571f2bd5c3eSSean Callanan { 572f2bd5c3eSSean Callanan repl_error.SetErrorStringWithFormat("Couldn't create a REPL for %s", Language::GetNameForLanguageType(m_command_options.language)); 573f2bd5c3eSSean Callanan result.SetError(repl_error); 574f2bd5c3eSSean Callanan return result.Succeeded(); 575f2bd5c3eSSean Callanan } 576f2bd5c3eSSean Callanan } 577f2bd5c3eSSean Callanan } 578f2bd5c3eSSean Callanan } 579cf28a8b7SGreg Clayton // No expression following options 580c8ecc2a9SEugene Zelenko else if (expr == nullptr || expr[0] == '\0') 581cf28a8b7SGreg Clayton { 582cf28a8b7SGreg Clayton GetMultilineExpression (); 583cf28a8b7SGreg Clayton return result.Succeeded(); 584cf28a8b7SGreg Clayton } 58530fdc8d8SChris Lattner } 58630fdc8d8SChris Lattner } 58730fdc8d8SChris Lattner 588c8ecc2a9SEugene Zelenko if (expr == nullptr) 58930fdc8d8SChris Lattner expr = command; 59030fdc8d8SChris Lattner 5916e8dc334SCaroline Tice if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result)) 592fcd43b71SJohnny Chen return true; 593fcd43b71SJohnny Chen 594fcd43b71SJohnny Chen result.SetStatus (eReturnStatusFailed); 595fcd43b71SJohnny Chen return false; 59630fdc8d8SChris Lattner } 597