]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Commands/CommandObjectExpression.cpp
Merge llvm 3.6.0rc1 from ^/vendor/llvm/dist, merge clang 3.6.0rc1 from
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Commands / CommandObjectExpression.cpp
1 //===-- 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
10 #include "lldb/lldb-python.h"
11
12 #include "CommandObjectExpression.h"
13
14 // C Includes
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/Interpreter/Args.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Core/ValueObjectVariable.h"
21 #include "lldb/DataFormatters/ValueObjectPrinter.h"
22 #include "lldb/Expression/ClangExpressionVariable.h"
23 #include "lldb/Expression/ClangUserExpression.h"
24 #include "lldb/Expression/ClangFunction.h"
25 #include "lldb/Expression/DWARFExpression.h"
26 #include "lldb/Host/Host.h"
27 #include "lldb/Core/Debugger.h"
28 #include "lldb/Interpreter/CommandInterpreter.h"
29 #include "lldb/Interpreter/CommandReturnObject.h"
30 #include "lldb/Target/ObjCLanguageRuntime.h"
31 #include "lldb/Symbol/ObjectFile.h"
32 #include "lldb/Symbol/Variable.h"
33 #include "lldb/Target/Process.h"
34 #include "lldb/Target/StackFrame.h"
35 #include "lldb/Target/Target.h"
36 #include "lldb/Target/Thread.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/ADT/StringRef.h"
39
40 using namespace lldb;
41 using namespace lldb_private;
42
43 CommandObjectExpression::CommandOptions::CommandOptions () :
44     OptionGroup()
45 {
46 }
47
48
49 CommandObjectExpression::CommandOptions::~CommandOptions ()
50 {
51 }
52
53 static OptionEnumValueElement g_description_verbosity_type[] =
54 {
55     { eLanguageRuntimeDescriptionDisplayVerbosityCompact,      "compact",       "Only show the description string"},
56     { eLanguageRuntimeDescriptionDisplayVerbosityFull,         "full",          "Show the full output, including persistent variable's name and type"},
57     { 0, NULL, NULL }
58 };
59
60 OptionDefinition
61 CommandObjectExpression::CommandOptions::g_option_table[] =
62 {
63     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads",        'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "Should we run all threads if the execution doesn't complete on one thread."},
64     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "Ignore breakpoint hits while running expressions"},
65     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout",            't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger,  "Timeout value (in microseconds) for running the expression."},
66     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error",    'u', OptionParser::eRequiredArgument, NULL, NULL, 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)."},
67     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug",              'g', OptionParser::eNoArgument      , NULL, NULL, 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)."},
68     { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, NULL, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity,        "How verbose should the output of this expression be, if the object description is asked for."},
69 };
70
71
72 uint32_t
73 CommandObjectExpression::CommandOptions::GetNumDefinitions ()
74 {
75     return llvm::array_lengthof(g_option_table);
76 }
77
78 Error
79 CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
80                                                          uint32_t option_idx,
81                                                          const char *option_arg)
82 {
83     Error error;
84
85     const int short_option = g_option_table[option_idx].short_option;
86
87     switch (short_option)
88     {
89       //case 'l':
90       //if (language.SetLanguageFromCString (option_arg) == false)
91       //{
92       //    error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
93       //}
94       //break;
95
96     case 'a':
97         {
98             bool success;
99             bool result;
100             result = Args::StringToBoolean(option_arg, true, &success);
101             if (!success)
102                 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
103             else
104                 try_all_threads = result;
105         }
106         break;
107         
108     case 'i':
109         {
110             bool success;
111             bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
112             if (success)
113                 ignore_breakpoints = tmp_value;
114             else
115                 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
116             break;
117         }
118     case 't':
119         {
120             bool success;
121             uint32_t result;
122             result = Args::StringToUInt32(option_arg, 0, 0, &success);
123             if (success)
124                 timeout = result;
125             else
126                 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
127         }
128         break;
129         
130     case 'u':
131         {
132             bool success;
133             bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
134             if (success)
135                 unwind_on_error = tmp_value;
136             else
137                 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
138             break;
139         }
140             
141     case 'v':
142         if (!option_arg)
143         {
144             m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
145             break;
146         }
147         m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
148         if (!error.Success())
149             error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg);
150         break;
151     
152     case 'g':
153         debug = true;
154         unwind_on_error = false;
155         ignore_breakpoints = false;
156         break;
157
158     default:
159         error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
160         break;
161     }
162
163     return error;
164 }
165
166 void
167 CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
168 {
169     Process *process = interpreter.GetExecutionContext().GetProcessPtr();
170     if (process != NULL)
171     {
172         ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
173         unwind_on_error    = process->GetUnwindOnErrorInExpressions();
174     }
175     else
176     {
177         ignore_breakpoints = true;
178         unwind_on_error = true;
179     }
180     
181     show_summary = true;
182     try_all_threads = true;
183     timeout = 0;
184     debug = false;
185     m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
186 }
187
188 const OptionDefinition*
189 CommandObjectExpression::CommandOptions::GetDefinitions ()
190 {
191     return g_option_table;
192 }
193
194 CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
195     CommandObjectRaw (interpreter,
196                       "expression",
197                       "Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.",
198                       NULL,
199                       eFlagProcessMustBePaused | eFlagTryTargetAPILock),
200     IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
201     m_option_group (interpreter),
202     m_format_options (eFormatDefault),
203     m_command_options (),
204     m_expr_line_count (0),
205     m_expr_lines ()
206 {
207   SetHelpLong(
208 "Timeouts:\n\
209     If the expression can be evaluated statically (without running code) then it will be.\n\
210     Otherwise, by default the expression will run on the current thread with a short timeout:\n\
211     currently .25 seconds.  If it doesn't return in that time, the evaluation will be interrupted\n\
212     and resumed with all threads running.  You can use the -a option to disable retrying on all\n\
213     threads.  You can use the -t option to set a shorter timeout.\n\
214 \n\
215 User defined variables:\n\
216     You can define your own variables for convenience or to be used in subsequent expressions.\n\
217     You define them the same way you would define variables in C.  If the first character of \n\
218     your user defined variable is a $, then the variable's value will be available in future\n\
219     expressions, otherwise it will just be available in the current expression.\n\
220 \n\
221 \n\
222 Continuing evaluation after a breakpoint:\n\
223     If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once\n\
224     you are done with your investigation, you can either remove the expression execution frames\n\
225     from the stack with \"thread return -x\" or if you are still interested in the expression result\n\
226     you can issue the \"continue\" command and the expression evaluation will complete and the\n\
227     expression result will be available using the \"thread.completed-expression\" key in the thread\n\
228     format.\n\
229 \n\
230 Examples: \n\
231 \n\
232    expr my_struct->a = my_array[3] \n\
233    expr -f bin -- (index * 8) + 5 \n\
234    expr unsigned int $foo = 5\n\
235    expr char c[] = \"foo\"; c[0]\n");
236
237     CommandArgumentEntry arg;
238     CommandArgumentData expression_arg;
239
240     // Define the first (and only) variant of this arg.
241     expression_arg.arg_type = eArgTypeExpression;
242     expression_arg.arg_repetition = eArgRepeatPlain;
243
244     // There is only one variant this argument could be; put it into the argument entry.
245     arg.push_back (expression_arg);
246
247     // Push the data for the first argument into the m_arguments vector.
248     m_arguments.push_back (arg);
249     
250     // Add the "--format" and "--gdb-format"
251     m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
252     m_option_group.Append (&m_command_options);
253     m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
254     m_option_group.Finalize();
255 }
256
257 CommandObjectExpression::~CommandObjectExpression ()
258 {
259 }
260
261 Options *
262 CommandObjectExpression::GetOptions ()
263 {
264     return &m_option_group;
265 }
266
267 bool
268 CommandObjectExpression::EvaluateExpression 
269 (
270     const char *expr, 
271     Stream *output_stream, 
272     Stream *error_stream,
273     CommandReturnObject *result
274 )
275 {
276     // Don't use m_exe_ctx as this might be called asynchronously
277     // after the command object DoExecute has finished when doing
278     // multi-line expression that use an input reader...
279     ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
280
281     Target *target = exe_ctx.GetTargetPtr();
282     
283     if (!target)
284         target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
285     
286     if (target)
287     {
288         lldb::ValueObjectSP result_valobj_sp;
289
290         bool keep_in_memory = true;
291
292         EvaluateExpressionOptions options;
293         options.SetCoerceToId(m_varobj_options.use_objc);
294         options.SetUnwindOnError(m_command_options.unwind_on_error);
295         options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
296         options.SetKeepInMemory(keep_in_memory);
297         options.SetUseDynamic(m_varobj_options.use_dynamic);
298         options.SetTryAllThreads(m_command_options.try_all_threads);
299         options.SetDebug(m_command_options.debug);
300         
301         // If there is any chance we are going to stop and want to see
302         // what went wrong with our expression, we should generate debug info
303         if (!m_command_options.ignore_breakpoints ||
304             !m_command_options.unwind_on_error)
305             options.SetGenerateDebugInfo(true);
306         
307         if (m_command_options.timeout > 0)
308             options.SetTimeoutUsec(m_command_options.timeout);
309         else
310             options.SetTimeoutUsec(0);
311
312         target->EvaluateExpression(expr, exe_ctx.GetFramePtr(),
313                                    result_valobj_sp, options);
314
315         if (result_valobj_sp)
316         {
317             Format format = m_format_options.GetFormat();
318
319             if (result_valobj_sp->GetError().Success())
320             {
321                 if (format != eFormatVoid)
322                 {
323                     if (format != eFormatDefault)
324                         result_valobj_sp->SetFormat (format);
325
326                     DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
327
328                     result_valobj_sp->Dump(*output_stream,options);
329                     
330                     if (result)
331                         result->SetStatus (eReturnStatusSuccessFinishResult);
332                 }
333             }
334             else
335             {
336                 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
337                 {
338                     if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
339                     {
340                         error_stream->PutCString("(void)\n");
341                     }
342                     
343                     if (result)
344                         result->SetStatus (eReturnStatusSuccessFinishResult);
345                 }
346                 else
347                 {
348                     const char *error_cstr = result_valobj_sp->GetError().AsCString();
349                     if (error_cstr && error_cstr[0])
350                     {
351                         const size_t error_cstr_len = strlen (error_cstr);
352                         const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
353                         if (strstr(error_cstr, "error:") != error_cstr)
354                             error_stream->PutCString ("error: ");
355                         error_stream->Write(error_cstr, error_cstr_len);
356                         if (!ends_with_newline)
357                             error_stream->EOL();
358                     }
359                     else
360                     {
361                         error_stream->PutCString ("error: unknown error\n");
362                     }
363                     
364                     if (result)
365                         result->SetStatus (eReturnStatusFailed);
366                 }
367             }
368         }
369     }
370     else
371     {
372         error_stream->Printf ("error: invalid execution context for expression\n");
373         return false;
374     }
375         
376     return true;
377 }
378
379 void
380 CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
381 {
382     io_handler.SetIsDone(true);
383 //    StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
384 //    StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
385     StreamFileSP output_sp(io_handler.GetOutputStreamFile());
386     StreamFileSP error_sp(io_handler.GetErrorStreamFile());
387
388     EvaluateExpression (line.c_str(),
389                         output_sp.get(),
390                         error_sp.get());
391     if (output_sp)
392         output_sp->Flush();
393     if (error_sp)
394         error_sp->Flush();
395 }
396
397 LineStatus
398 CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
399                                                 StringList &lines,
400                                                 uint32_t line_idx,
401                                                 Error &error)
402 {
403     if (line_idx == UINT32_MAX)
404     {
405         // Remove the last line from "lines" so it doesn't appear
406         // in our final expression
407         lines.PopBack();
408         error.Clear();
409         return LineStatus::Done;
410     }
411     else if (line_idx + 1 == lines.GetSize())
412     {
413         // The last line was edited, if this line is empty, then we are done
414         // getting our multiple lines.
415         if (lines[line_idx].empty())
416             return LineStatus::Done;
417     }
418     return LineStatus::Success;
419 }
420
421 void
422 CommandObjectExpression::GetMultilineExpression ()
423 {
424     m_expr_lines.clear();
425     m_expr_line_count = 0;
426     
427     Debugger &debugger = GetCommandInterpreter().GetDebugger();
428     const bool multiple_lines = true; // Get multiple lines
429     IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
430                                                       "lldb-expr",      // Name of input reader for history
431                                                       NULL,             // No prompt
432                                                       multiple_lines,
433                                                       1,                // Show line numbers starting at 1
434                                                       *this));
435     
436     StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
437     if (output_sp)
438     {
439         output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
440         output_sp->Flush();
441     }
442     debugger.PushIOHandler(io_handler_sp);
443 }
444
445 bool
446 CommandObjectExpression::DoExecute
447 (
448     const char *command,
449     CommandReturnObject &result
450 )
451 {
452     m_option_group.NotifyOptionParsingStarting();
453
454     const char * expr = NULL;
455
456     if (command[0] == '\0')
457     {
458         GetMultilineExpression ();
459         return result.Succeeded();
460     }
461
462     if (command[0] == '-')
463     {
464         // We have some options and these options MUST end with --.
465         const char *end_options = NULL;
466         const char *s = command;
467         while (s && s[0])
468         {
469             end_options = ::strstr (s, "--");
470             if (end_options)
471             {
472                 end_options += 2; // Get past the "--"
473                 if (::isspace (end_options[0]))
474                 {
475                     expr = end_options;
476                     while (::isspace (*expr))
477                         ++expr;
478                     break;
479                 }
480             }
481             s = end_options;
482         }
483
484         if (end_options)
485         {
486             Args args (command, end_options - command);
487             if (!ParseOptions (args, result))
488                 return false;
489             
490             Error error (m_option_group.NotifyOptionParsingFinished());
491             if (error.Fail())
492             {
493                 result.AppendError (error.AsCString());
494                 result.SetStatus (eReturnStatusFailed);
495                 return false;
496             }
497             
498             // No expression following options
499             if (expr == NULL || expr[0] == '\0')
500             {
501                 GetMultilineExpression ();
502                 return result.Succeeded();
503             }
504         }
505     }
506
507     if (expr == NULL)
508         expr = command;
509     
510     if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
511         return true;
512
513     result.SetStatus (eReturnStatusFailed);
514     return false;
515 }
516