blob: f2bd3ed367caf64c0558c8e089aa5a133090b375 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectExpression.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Chris Lattner30fdc8d2010-06-08 16:52:24 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +000013#include "llvm/ADT/STLExtras.h"
14#include "llvm/ADT/StringRef.h"
15
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016// Project includes
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +000017#include "CommandObjectExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Core/Value.h"
Jim Ingham6c68fb42010-09-30 00:54:27 +000019#include "lldb/Core/ValueObjectVariable.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000020#include "lldb/DataFormatters/ValueObjectPrinter.h"
Sean Callanan30e33972015-09-03 00:48:23 +000021#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
Jim Ingham151c0322015-09-15 21:13:50 +000022#include "lldb/Expression/UserExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Expression/DWARFExpression.h"
Sean Callananf2bd5c32015-10-20 00:55:21 +000024#include "lldb/Expression/REPL.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Host/Host.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000026#include "lldb/Host/StringConvert.h"
Sean Callananebf77072010-07-23 00:16:21 +000027#include "lldb/Core/Debugger.h"
Greg Clayton66111032010-06-23 01:19:29 +000028#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Interpreter/CommandReturnObject.h"
Jim Ingham0e0984e2015-09-02 01:06:46 +000030#include "lldb/Target/Language.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Symbol/ObjectFile.h"
32#include "lldb/Symbol/Variable.h"
33#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000034#include "lldb/Target/StackFrame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "lldb/Target/Target.h"
Greg Clayton7260f622011-04-18 08:33:37 +000036#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037
38using namespace lldb;
39using namespace lldb_private;
40
Greg Clayton1deb7962011-10-25 06:44:01 +000041CommandObjectExpression::CommandOptions::CommandOptions () :
42 OptionGroup()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043{
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044}
45
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +000046CommandObjectExpression::CommandOptions::~CommandOptions() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047
Enrico Granata4d93b8c2013-09-30 19:11:51 +000048static OptionEnumValueElement g_description_verbosity_type[] =
49{
50 { eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact", "Only show the description string"},
51 { eLanguageRuntimeDescriptionDisplayVerbosityFull, "full", "Show the full output, including persistent variable's name and type"},
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +000052 { 0, nullptr, nullptr }
Enrico Granata4d93b8c2013-09-30 19:11:51 +000053};
54
Greg Clayton1deb7962011-10-25 06:44:01 +000055OptionDefinition
56CommandObjectExpression::CommandOptions::g_option_table[] =
57{
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +000058 { 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."},
59 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
60 { 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."},
61 { 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)."},
62 { 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)."},
63 { 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." },
Jim Ingham279b2e82016-06-28 01:33:03 +000064 { 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." },
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +000065 { 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."},
Marianne Mailhot-Sarrasin3fe71582016-05-12 20:00:53 +000066 { 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."},
67 { 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)."}
Greg Clayton1deb7962011-10-25 06:44:01 +000068};
69
Greg Clayton1deb7962011-10-25 06:44:01 +000070uint32_t
71CommandObjectExpression::CommandOptions::GetNumDefinitions ()
72{
Saleem Abdulrasool28606952014-06-27 05:17:41 +000073 return llvm::array_lengthof(g_option_table);
Greg Clayton1deb7962011-10-25 06:44:01 +000074}
75
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076Error
Greg Clayton1deb7962011-10-25 06:44:01 +000077CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
78 uint32_t option_idx,
79 const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080{
81 Error error;
82
Greg Clayton3bcdfc02012-12-04 00:32:51 +000083 const int short_option = g_option_table[option_idx].short_option;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084
85 switch (short_option)
86 {
Dawn Perchik15663c52015-07-25 00:19:39 +000087 case 'l':
Jim Ingham0e0984e2015-09-02 01:06:46 +000088 language = Language::GetLanguageTypeFromString (option_arg);
Dawn Perchik15663c52015-07-25 00:19:39 +000089 if (language == eLanguageTypeUnknown)
90 error.SetErrorStringWithFormat ("unknown language type: '%s' for expression", option_arg);
91 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000092
Jim Ingham35e1bda2012-10-16 21:41:58 +000093 case 'a':
94 {
95 bool success;
96 bool result;
97 result = Args::StringToBoolean(option_arg, true, &success);
98 if (!success)
99 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
100 else
101 try_all_threads = result;
102 }
Jim Ingham6c68fb42010-09-30 00:54:27 +0000103 break;
Jim Ingham399f1ca2010-11-05 19:25:48 +0000104
Jim Ingham184e9812013-01-15 02:47:48 +0000105 case 'i':
106 {
107 bool success;
108 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
109 if (success)
110 ignore_breakpoints = tmp_value;
111 else
112 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
113 break;
114 }
Marianne Mailhot-Sarrasin3fe71582016-05-12 20:00:53 +0000115
116 case 'j':
117 {
118 bool success;
119 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
120 if (success)
121 allow_jit = tmp_value;
122 else
123 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
124 break;
125 }
126
Jim Ingham35e1bda2012-10-16 21:41:58 +0000127 case 't':
128 {
129 bool success;
130 uint32_t result;
Vince Harron5275aaa2015-01-15 20:08:35 +0000131 result = StringConvert::ToUInt32(option_arg, 0, 0, &success);
Jim Ingham35e1bda2012-10-16 21:41:58 +0000132 if (success)
133 timeout = result;
134 else
135 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
136 }
137 break;
138
Jim Ingham399f1ca2010-11-05 19:25:48 +0000139 case 'u':
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000140 {
141 bool success;
Jim Ingham184e9812013-01-15 02:47:48 +0000142 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
143 if (success)
144 unwind_on_error = tmp_value;
145 else
Greg Clayton86edbf42011-10-26 00:56:27 +0000146 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000147 break;
148 }
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000149
150 case 'v':
151 if (!option_arg)
152 {
153 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
154 break;
155 }
156 m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
157 if (!error.Success())
158 error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg);
159 break;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000160
161 case 'g':
162 debug = true;
163 unwind_on_error = false;
164 ignore_breakpoints = false;
165 break;
Sean Callanan863fab62016-03-28 21:20:05 +0000166
167 case 'p':
168 top_level = true;
169 break;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000170
Jim Inghama1e541b2016-03-25 01:57:14 +0000171 case 'X':
172 {
173 bool success;
174 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
175 if (success)
176 auto_apply_fixits = tmp_value ? eLazyBoolYes : eLazyBoolNo;
177 else
178 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
179 break;
180 }
181
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000183 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184 break;
185 }
186
187 return error;
188}
189
190void
Greg Clayton1deb7962011-10-25 06:44:01 +0000191CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000192{
Jim Ingham184e9812013-01-15 02:47:48 +0000193 Process *process = interpreter.GetExecutionContext().GetProcessPtr();
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000194 if (process != nullptr)
Jim Ingham184e9812013-01-15 02:47:48 +0000195 {
196 ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
197 unwind_on_error = process->GetUnwindOnErrorInExpressions();
198 }
199 else
200 {
Greg Claytonfc03f8f2014-03-25 18:47:07 +0000201 ignore_breakpoints = true;
Jim Ingham184e9812013-01-15 02:47:48 +0000202 unwind_on_error = true;
203 }
204
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205 show_summary = true;
Jim Ingham35e1bda2012-10-16 21:41:58 +0000206 try_all_threads = true;
207 timeout = 0;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000208 debug = false;
Dawn Perchik15663c52015-07-25 00:19:39 +0000209 language = eLanguageTypeUnknown;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000210 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
Jim Inghama1e541b2016-03-25 01:57:14 +0000211 auto_apply_fixits = eLazyBoolCalculate;
Sean Callanan863fab62016-03-28 21:20:05 +0000212 top_level = false;
Marianne Mailhot-Sarrasin3fe71582016-05-12 20:00:53 +0000213 allow_jit = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000214}
215
Greg Claytone0d378b2011-03-24 21:19:54 +0000216const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000217CommandObjectExpression::CommandOptions::GetDefinitions ()
218{
219 return g_option_table;
220}
221
Kate Stone7428a182016-07-14 22:03:10 +0000222CommandObjectExpression::CommandObjectExpression(CommandInterpreter &interpreter)
223 : CommandObjectRaw(
224 interpreter, "expression",
225 "Evaluate an expression on the current thread. Displays any returned value with LLDB's default formatting.",
226 nullptr, eCommandProcessMustBePaused | eCommandTryTargetAPILock),
227 IOHandlerDelegate(IOHandlerDelegate::Completion::Expression),
228 m_option_group(interpreter),
229 m_format_options(eFormatDefault),
230 m_repl_option(LLDB_OPT_SET_1, false, "repl", 'r', "Drop into REPL", false, true),
231 m_command_options(),
232 m_expr_line_count(0),
233 m_expr_lines()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000234{
Kate Stoneea671fb2015-07-14 05:48:36 +0000235 SetHelpLong(
236R"(
237Timeouts:
238
239)" " If the expression can be evaluated statically (without running code) then it will be. \
240Otherwise, by default the expression will run on the current thread with a short timeout: \
241currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted \
242and resumed with all threads running. You can use the -a option to disable retrying on all \
243threads. You can use the -t option to set a shorter timeout." R"(
244
245User defined variables:
246
247)" " You can define your own variables for convenience or to be used in subsequent expressions. \
248You define them the same way you would define variables in C. If the first character of \
249your user defined variable is a $, then the variable's value will be available in future \
250expressions, otherwise it will just be available in the current expression." R"(
251
252Continuing evaluation after a breakpoint:
253
254)" " If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \
255you are done with your investigation, you can either remove the expression execution frames \
256from the stack with \"thread return -x\" or if you are still interested in the expression result \
257you can issue the \"continue\" command and the expression evaluation will complete and the \
258expression result will be available using the \"thread.completed-expression\" key in the thread \
259format." R"(
260
261Examples:
262
263 expr my_struct->a = my_array[3]
264 expr -f bin -- (index * 8) + 5
265 expr unsigned int $foo = 5
266 expr char c[] = \"foo\"; c[0])"
267 );
Caroline Tice405fe672010-10-04 22:28:36 +0000268
269 CommandArgumentEntry arg;
270 CommandArgumentData expression_arg;
271
272 // Define the first (and only) variant of this arg.
273 expression_arg.arg_type = eArgTypeExpression;
274 expression_arg.arg_repetition = eArgRepeatPlain;
275
276 // There is only one variant this argument could be; put it into the argument entry.
277 arg.push_back (expression_arg);
278
279 // Push the data for the first argument into the m_arguments vector.
280 m_arguments.push_back (arg);
Greg Clayton1deb7962011-10-25 06:44:01 +0000281
Greg Clayton5009f9d2011-10-27 17:55:14 +0000282 // Add the "--format" and "--gdb-format"
283 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
Greg Clayton1deb7962011-10-25 06:44:01 +0000284 m_option_group.Append (&m_command_options);
Enrico Granatab576bba2013-01-09 20:12:53 +0000285 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
Sean Callananf2bd5c32015-10-20 00:55:21 +0000286 m_option_group.Append (&m_repl_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
Greg Clayton1deb7962011-10-25 06:44:01 +0000287 m_option_group.Finalize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000288}
289
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000290CommandObjectExpression::~CommandObjectExpression() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291
292Options *
293CommandObjectExpression::GetOptions ()
294{
Greg Clayton1deb7962011-10-25 06:44:01 +0000295 return &m_option_group;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296}
297
Enrico Granata520a4222016-04-25 00:52:47 +0000298static lldb_private::Error
299CanBeUsedForElementCountPrinting (ValueObject& valobj)
300{
301 CompilerType type(valobj.GetCompilerType());
302 CompilerType pointee;
303 if (!type.IsPointerType(&pointee))
304 return Error("as it does not refer to a pointer");
305 if (pointee.IsVoidType())
306 return Error("as it refers to a pointer to void");
307 return Error();
308}
309
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310bool
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000311CommandObjectExpression::EvaluateExpression(const char *expr,
312 Stream *output_stream,
313 Stream *error_stream,
314 CommandReturnObject *result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315{
Greg Claytonba7b8e22013-01-26 23:54:29 +0000316 // Don't use m_exe_ctx as this might be called asynchronously
317 // after the command object DoExecute has finished when doing
318 // multi-line expression that use an input reader...
319 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
320
321 Target *target = exe_ctx.GetTargetPtr();
Sean Callananc0a6e062011-10-27 21:22:25 +0000322
323 if (!target)
Jim Ingham893c9322014-11-22 01:42:44 +0000324 target = GetDummyTarget();
Sean Callananc0a6e062011-10-27 21:22:25 +0000325
Greg Claytonc14ee322011-09-22 04:58:26 +0000326 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000328 lldb::ValueObjectSP result_valobj_sp;
Sean Callanan92adcac2011-01-13 08:53:35 +0000329 bool keep_in_memory = true;
Dawn Perchik009d1102015-09-04 01:02:30 +0000330 StackFrame *frame = exe_ctx.GetFramePtr();
Enrico Granatab576bba2013-01-09 20:12:53 +0000331
Jim Ingham35e1bda2012-10-16 21:41:58 +0000332 EvaluateExpressionOptions options;
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000333 options.SetCoerceToId(m_varobj_options.use_objc);
334 options.SetUnwindOnError(m_command_options.unwind_on_error);
335 options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
336 options.SetKeepInMemory(keep_in_memory);
337 options.SetUseDynamic(m_varobj_options.use_dynamic);
338 options.SetTryAllThreads(m_command_options.try_all_threads);
339 options.SetDebug(m_command_options.debug);
Dawn Perchik1bbaede2015-10-07 22:01:12 +0000340 options.SetLanguage(m_command_options.language);
Marianne Mailhot-Sarrasin3fe71582016-05-12 20:00:53 +0000341 options.SetExecutionPolicy(m_command_options.allow_jit ?
342 EvaluateExpressionOptions::default_execution_policy :
343 lldb_private::eExecutionPolicyNever);
Jim Inghama1e541b2016-03-25 01:57:14 +0000344
345 bool auto_apply_fixits;
346 if (m_command_options.auto_apply_fixits == eLazyBoolCalculate)
347 auto_apply_fixits = target->GetEnableAutoApplyFixIts();
348 else
349 auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes ? true : false;
350
351 options.SetAutoApplyFixIts(auto_apply_fixits);
Sean Callanan863fab62016-03-28 21:20:05 +0000352
353 if (m_command_options.top_level)
354 options.SetExecutionPolicy(eExecutionPolicyTopLevel);
Dawn Perchik15663c52015-07-25 00:19:39 +0000355
Greg Clayton23f8c952014-03-24 23:10:19 +0000356 // If there is any chance we are going to stop and want to see
357 // what went wrong with our expression, we should generate debug info
358 if (!m_command_options.ignore_breakpoints ||
359 !m_command_options.unwind_on_error)
360 options.SetGenerateDebugInfo(true);
361
Greg Clayton62afb9f2013-11-04 19:35:17 +0000362 if (m_command_options.timeout > 0)
363 options.SetTimeoutUsec(m_command_options.timeout);
Jim Ingham6f78f382014-01-17 20:09:23 +0000364 else
365 options.SetTimeoutUsec(0);
Arnaud A. de Grandmaison62e5f4d2014-03-22 20:23:26 +0000366
Jim Inghame5ee6f02016-03-29 22:00:08 +0000367 ExpressionResults success = target->EvaluateExpression(expr, frame, result_valobj_sp, options, &m_fixed_expression);
368
369 // We only tell you about the FixIt if we applied it. The compiler errors will suggest the FixIt if it parsed.
370 if (error_stream && !m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts())
371 {
372 if (success == eExpressionCompleted)
Jim Ingham279b2e82016-06-28 01:33:03 +0000373 error_stream->Printf (" Fix-it applied, fixed expression was: \n %s\n", m_fixed_expression.c_str());
Jim Inghame5ee6f02016-03-29 22:00:08 +0000374 }
Sean Callanan4b388c92013-07-30 19:54:09 +0000375
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000376 if (result_valobj_sp)
377 {
Sean Callananbf154da2012-08-08 17:35:10 +0000378 Format format = m_format_options.GetFormat();
379
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000380 if (result_valobj_sp->GetError().Success())
381 {
Sean Callananbf154da2012-08-08 17:35:10 +0000382 if (format != eFormatVoid)
383 {
384 if (format != eFormatDefault)
385 result_valobj_sp->SetFormat (format);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000386
Enrico Granata520a4222016-04-25 00:52:47 +0000387 if (m_varobj_options.elem_count > 0)
388 {
389 Error error(CanBeUsedForElementCountPrinting(*result_valobj_sp));
390 if (error.Fail())
391 {
392 result->AppendErrorWithFormat("expression cannot be used with --element-count %s\n", error.AsCString(""));
393 result->SetStatus(eReturnStatusFailed);
394 return false;
395 }
396 }
397
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000398 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
Enrico Granata73e8c4d2015-10-07 02:36:35 +0000399 options.SetVariableFormatDisplayLanguage(result_valobj_sp->GetPreferredDisplayLanguage());
Enrico Granatab576bba2013-01-09 20:12:53 +0000400
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000401 result_valobj_sp->Dump(*output_stream,options);
402
Sean Callananbf154da2012-08-08 17:35:10 +0000403 if (result)
404 result->SetStatus (eReturnStatusSuccessFinishResult);
405 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000406 }
407 else
408 {
Jim Ingham151c0322015-09-15 21:13:50 +0000409 if (result_valobj_sp->GetError().GetError() == UserExpression::kNoResult)
Greg Clayton5fd05902011-06-24 22:31:10 +0000410 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000411 if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
Sean Callananbf154da2012-08-08 17:35:10 +0000412 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000413 error_stream->PutCString("(void)\n");
Sean Callananbf154da2012-08-08 17:35:10 +0000414 }
Sean Callananbcf897f2012-08-09 18:18:47 +0000415
416 if (result)
417 result->SetStatus (eReturnStatusSuccessFinishResult);
Greg Clayton5fd05902011-06-24 22:31:10 +0000418 }
419 else
420 {
Sean Callananbccce812011-08-23 21:20:51 +0000421 const char *error_cstr = result_valobj_sp->GetError().AsCString();
422 if (error_cstr && error_cstr[0])
423 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000424 const size_t error_cstr_len = strlen (error_cstr);
Sean Callananbccce812011-08-23 21:20:51 +0000425 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
426 if (strstr(error_cstr, "error:") != error_cstr)
427 error_stream->PutCString ("error: ");
428 error_stream->Write(error_cstr, error_cstr_len);
429 if (!ends_with_newline)
430 error_stream->EOL();
431 }
432 else
433 {
434 error_stream->PutCString ("error: unknown error\n");
435 }
436
437 if (result)
438 result->SetStatus (eReturnStatusFailed);
Greg Clayton5fd05902011-06-24 22:31:10 +0000439 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000440 }
441 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000442 }
443 else
444 {
Caroline Tice6e8dc332011-06-13 20:20:29 +0000445 error_stream->Printf ("error: invalid execution context for expression\n");
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000446 return false;
Sean Callananebf77072010-07-23 00:16:21 +0000447 }
Sean Callanand1e5b432010-08-12 01:56:52 +0000448
Sean Callananebf77072010-07-23 00:16:21 +0000449 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450}
451
Greg Clayton44d93782014-01-27 23:43:24 +0000452void
Greg Clayton44d93782014-01-27 23:43:24 +0000453CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
454{
455 io_handler.SetIsDone(true);
456// StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
457// StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
458 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
459 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
460
461 EvaluateExpression (line.c_str(),
462 output_sp.get(),
463 error_sp.get());
464 if (output_sp)
465 output_sp->Flush();
466 if (error_sp)
467 error_sp->Flush();
468}
469
Sean Callananf52c40c2016-05-09 21:13:27 +0000470bool
471CommandObjectExpression::IOHandlerIsInputComplete (IOHandler &io_handler,
472 StringList &lines)
Greg Clayton44d93782014-01-27 23:43:24 +0000473{
Sean Callananf52c40c2016-05-09 21:13:27 +0000474 // An empty lines is used to indicate the end of input
475 const size_t num_lines = lines.GetSize();
476 if (num_lines > 0 && lines[num_lines - 1].empty())
Greg Clayton44d93782014-01-27 23:43:24 +0000477 {
Sean Callananf52c40c2016-05-09 21:13:27 +0000478 // Remove the last empty line from "lines" so it doesn't appear
479 // in our resulting input and return true to indicate we are done
480 // getting lines
Greg Clayton44d93782014-01-27 23:43:24 +0000481 lines.PopBack();
Sean Callananf52c40c2016-05-09 21:13:27 +0000482 return true;
Greg Clayton44d93782014-01-27 23:43:24 +0000483 }
Sean Callananf52c40c2016-05-09 21:13:27 +0000484 return false;
Greg Clayton44d93782014-01-27 23:43:24 +0000485}
486
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000487void
488CommandObjectExpression::GetMultilineExpression ()
489{
490 m_expr_lines.clear();
491 m_expr_line_count = 0;
492
493 Debugger &debugger = GetCommandInterpreter().GetDebugger();
Kate Stonee30f11d2014-11-17 19:06:59 +0000494 bool color_prompt = debugger.GetUseColor();
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000495 const bool multiple_lines = true; // Get multiple lines
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000496 IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger,
497 IOHandler::Type::Expression,
498 "lldb-expr", // Name of input reader for history
499 nullptr, // No prompt
500 nullptr, // Continuation prompt
501 multiple_lines,
502 color_prompt,
503 1, // Show line numbers starting at 1
504 *this));
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000505
506 StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
507 if (output_sp)
508 {
509 output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
510 output_sp->Flush();
511 }
512 debugger.PushIOHandler(io_handler_sp);
513}
514
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000515bool
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000516CommandObjectExpression::DoExecute(const char *command,
517 CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000518{
Jim Inghame5ee6f02016-03-29 22:00:08 +0000519 m_fixed_expression.clear();
Greg Clayton1deb7962011-10-25 06:44:01 +0000520 m_option_group.NotifyOptionParsingStarting();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000521
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000522 const char * expr = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523
524 if (command[0] == '\0')
525 {
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000526 GetMultilineExpression ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000527 return result.Succeeded();
528 }
529
530 if (command[0] == '-')
531 {
532 // We have some options and these options MUST end with --.
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000533 const char *end_options = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000534 const char *s = command;
535 while (s && s[0])
536 {
537 end_options = ::strstr (s, "--");
538 if (end_options)
539 {
540 end_options += 2; // Get past the "--"
541 if (::isspace (end_options[0]))
542 {
543 expr = end_options;
544 while (::isspace (*expr))
545 ++expr;
546 break;
547 }
548 }
549 s = end_options;
550 }
551
552 if (end_options)
553 {
Pavel Labath00b7f952015-03-02 12:46:22 +0000554 Args args (llvm::StringRef(command, end_options - command));
Greg Claytona7015092010-09-18 01:14:36 +0000555 if (!ParseOptions (args, result))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556 return false;
Greg Claytonf6b8b582011-04-13 00:18:08 +0000557
Greg Clayton1deb7962011-10-25 06:44:01 +0000558 Error error (m_option_group.NotifyOptionParsingFinished());
Greg Claytonf6b8b582011-04-13 00:18:08 +0000559 if (error.Fail())
560 {
561 result.AppendError (error.AsCString());
562 result.SetStatus (eReturnStatusFailed);
563 return false;
564 }
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000565
Sean Callananf2bd5c32015-10-20 00:55:21 +0000566 if (m_repl_option.GetOptionValue().GetCurrentValue())
567 {
568 Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
569 if (target)
570 {
571 // Drop into REPL
572 m_expr_lines.clear();
573 m_expr_line_count = 0;
574
575 Debugger &debugger = target->GetDebugger();
576
577 // Check if the LLDB command interpreter is sitting on top of a REPL that
578 // launched it...
579 if (debugger.CheckTopIOHandlerTypes(IOHandler::Type::CommandInterpreter, IOHandler::Type::REPL))
580 {
581 // the LLDB command interpreter is sitting on top of a REPL that launched it,
582 // so just say the command interpreter is done and fall back to the existing REPL
583 m_interpreter.GetIOHandler(false)->SetIsDone(true);
584 }
585 else
586 {
587 // We are launching the REPL on top of the current LLDB command interpreter,
588 // so just push one
589 bool initialize = false;
590 Error repl_error;
591 REPLSP repl_sp (target->GetREPL(repl_error, m_command_options.language, nullptr, false));
592
593 if (!repl_sp)
594 {
595 initialize = true;
596 repl_sp = target->GetREPL(repl_error, m_command_options.language, nullptr, true);
597 if (!repl_error.Success())
598 {
599 result.SetError(repl_error);
600 return result.Succeeded();
601 }
602 }
603
604 if (repl_sp)
605 {
606 if (initialize)
607 {
608 repl_sp->SetCommandOptions(m_command_options);
609 repl_sp->SetFormatOptions(m_format_options);
610 repl_sp->SetValueObjectDisplayOptions(m_varobj_options);
611 }
612
613 IOHandlerSP io_handler_sp (repl_sp->GetIOHandler());
614
615 io_handler_sp->SetIsDone(false);
616
617 debugger.PushIOHandler(io_handler_sp);
618 }
619 else
620 {
621 repl_error.SetErrorStringWithFormat("Couldn't create a REPL for %s", Language::GetNameForLanguageType(m_command_options.language));
622 result.SetError(repl_error);
623 return result.Succeeded();
624 }
625 }
626 }
627 }
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000628 // No expression following options
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000629 else if (expr == nullptr || expr[0] == '\0')
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000630 {
631 GetMultilineExpression ();
632 return result.Succeeded();
633 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634 }
635 }
636
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000637 if (expr == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000638 expr = command;
Sean Callanan16ad5fa2010-06-24 00:16:27 +0000639
Caroline Tice6e8dc332011-06-13 20:20:29 +0000640 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
Jim Inghame5ee6f02016-03-29 22:00:08 +0000641 {
642 Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
643 if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts())
644 {
645 CommandHistory &history = m_interpreter.GetCommandHistory();
646 // FIXME: Can we figure out what the user actually typed (e.g. some alias for expr???)
647 // If we can it would be nice to show that.
648 std::string fixed_command("expression ");
649 if (expr == command)
650 fixed_command.append(m_fixed_expression);
651 else
652 {
653 // Add in any options that might have been in the original command:
654 fixed_command.append(command, expr - command);
655 fixed_command.append(m_fixed_expression);
656 }
657 history.AppendString(fixed_command);
658 }
Johnny Chenfcd43b72010-08-13 00:42:30 +0000659 return true;
Jim Inghame5ee6f02016-03-29 22:00:08 +0000660 }
Johnny Chenfcd43b72010-08-13 00:42:30 +0000661
662 result.SetStatus (eReturnStatusFailed);
663 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000664}