blob: 9afc8c0a1a3d2c0943a1be87ed0c7987ca771921 [file] [log] [blame]
Chris Lattner24943d22010-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
10#include "CommandObjectExpression.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Args.h"
17#include "lldb/Core/Value.h"
18#include "lldb/Core/InputReader.h"
19#include "lldb/Expression/ClangExpression.h"
20#include "lldb/Expression/ClangExpressionDeclMap.h"
21#include "lldb/Expression/ClangExpressionVariable.h"
22#include "lldb/Expression/DWARFExpression.h"
23#include "lldb/Host/Host.h"
24#include "lldb/Interpreter/CommandContext.h"
25#include "lldb/Interpreter/CommandReturnObject.h"
26#include "lldb/Symbol/ObjectFile.h"
27#include "lldb/Symbol/Variable.h"
28#include "lldb/Target/Process.h"
29#include "lldb/Target/StackFrame.h"
30#include "lldb/Target/Target.h"
31#include "llvm/ADT/StringRef.h"
32
33using namespace lldb;
34using namespace lldb_private;
35
36CommandObjectExpression::CommandOptions::CommandOptions () :
37 Options()
38{
39 // Keep only one place to reset the values to their defaults
40 ResetOptionValues();
41}
42
43
44CommandObjectExpression::CommandOptions::~CommandOptions ()
45{
46}
47
48Error
49CommandObjectExpression::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
50{
51 Error error;
52
53 char short_option = (char) m_getopt_table[option_idx].val;
54
55 switch (short_option)
56 {
57 case 'l':
58 if (language.SetLanguageFromCString (option_arg) == false)
59 {
60 error.SetErrorStringWithFormat("Invalid language option argument '%s'.\n", option_arg);
61 }
62 break;
63
64 case 'g':
65 debug = true;
66 break;
67
68 case 'f':
69 error = Args::StringToFormat(option_arg, format);
70 break;
71
72 default:
73 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
74 break;
75 }
76
77 return error;
78}
79
80void
81CommandObjectExpression::CommandOptions::ResetOptionValues ()
82{
83 Options::ResetOptionValues();
84 language.Clear();
85 debug = false;
86 format = eFormatDefault;
87 show_types = true;
88 show_summary = true;
89}
90
91const lldb::OptionDefinition*
92CommandObjectExpression::CommandOptions::GetDefinitions ()
93{
94 return g_option_table;
95}
96
97CommandObjectExpression::CommandObjectExpression () :
98 CommandObject (
99 "expression",
100 "Evaluate a C expression in the current program context, using variables currently in scope.",
101 "expression [<cmd-options>] <expr>"),
102 m_expr_line_count (0),
103 m_expr_lines ()
104{
105 SetHelpLong(
106"Examples: \n\
107\n\
108 expr my_struct->a = my_array[3] \n\
109 expr -f bin -- (index * 8) + 5 \n\
110 expr char c[] = \"foo\"; c[0]\n");
111}
112
113CommandObjectExpression::~CommandObjectExpression ()
114{
115}
116
117Options *
118CommandObjectExpression::GetOptions ()
119{
120 return &m_options;
121}
122
123
124bool
125CommandObjectExpression::Execute
126(
127 Args& command,
128 CommandContext *context,
129 CommandInterpreter *interpreter,
130 CommandReturnObject &result
131)
132{
133 return false;
134}
135
136
137size_t
138CommandObjectExpression::MultiLineExpressionCallback
139(
140 void *baton,
141 InputReader *reader,
142 lldb::InputReaderAction notification,
143 const char *bytes,
144 size_t bytes_len
145)
146{
147 FILE *out_fh = Debugger::GetSharedInstance().GetOutputFileHandle();
148 CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
149
150 switch (notification)
151 {
152 case eInputReaderActivate:
153 if (out_fh)
154 ::fprintf (out_fh, "%s\n", "Enter expressions, then terminate with an empty line to evaluate:");
155 // Fall through
156 case eInputReaderReactivate:
157 //if (out_fh)
158 // ::fprintf (out_fh, "%3u: ", cmd_object_expr->m_expr_line_count);
159 break;
160
161 case eInputReaderDeactivate:
162 break;
163
164 case eInputReaderGotToken:
165 ++cmd_object_expr->m_expr_line_count;
166 if (bytes && bytes_len)
167 {
168 cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
169 }
170
171 if (bytes_len == 0)
172 reader->SetIsDone(true);
173 //else if (out_fh && !reader->IsDone())
174 // ::fprintf (out_fh, "%3u: ", cmd_object_expr->m_expr_line_count);
175 break;
176
177 case eInputReaderDone:
178 {
179 StreamFile out_stream(Debugger::GetSharedInstance().GetOutputFileHandle());
180 StreamFile err_stream(Debugger::GetSharedInstance().GetErrorFileHandle());
181 bool bare = false;
182 cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
183 bare,
184 out_stream,
185 err_stream);
186 }
187 break;
188 }
189
190 return bytes_len;
191}
192
193bool
194CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream &output_stream, Stream &error_stream)
195{
196 bool success = false;
197 ConstString target_triple;
198 Target *target = m_exe_ctx.target;
199 if (target)
200 target->GetTargetTriple(target_triple);
201
202 if (!target_triple)
203 target_triple = Host::GetTargetTriple ();
204
205
206 if (target_triple)
207 {
208 const bool show_types = m_options.show_types;
209 const bool show_summary = m_options.show_summary;
210 const bool debug = m_options.debug;
211
212 ClangExpressionDeclMap expr_decl_map(&m_exe_ctx);
213 ClangExpression clang_expr(target_triple.AsCString(), &expr_decl_map);
214
215 unsigned num_errors = 0;
216
217 if (bare)
218 num_errors = clang_expr.ParseBareExpression (llvm::StringRef(expr), error_stream);
219 else
220 num_errors = clang_expr.ParseExpression (expr, error_stream);
221
222 if (num_errors == 0)
223 {
224 StreamString dwarf_opcodes;
225 dwarf_opcodes.SetByteOrder(eByteOrderHost);
226 dwarf_opcodes.GetFlags().Set(Stream::eBinary);
227 ClangExpressionVariableList expr_local_vars;
228 clang_expr.ConvertExpressionToDWARF (expr_local_vars, dwarf_opcodes);
229
230 success = true;
231
232 DataExtractor dwarf_opcodes_data(dwarf_opcodes.GetData(), dwarf_opcodes.GetSize(), eByteOrderHost, 8);
233 DWARFExpression expr(dwarf_opcodes_data, 0, dwarf_opcodes_data.GetByteSize(), NULL);
234 expr.SetExpressionLocalVariableList(&expr_local_vars);
235 if (debug)
236 {
237 output_stream << "Expression parsed ok, dwarf opcodes:";
238 output_stream.IndentMore();
239 expr.GetDescription(&output_stream, lldb::eDescriptionLevelVerbose);
240 output_stream.IndentLess();
241 output_stream.EOL();
242 }
243
244 clang::ASTContext *ast_context = clang_expr.GetASTContext();
245 Value expr_result;
246 Error expr_error;
247 bool expr_success = expr.Evaluate (&m_exe_ctx, ast_context, NULL, expr_result, &expr_error);
248 if (expr_success)
249 {
250 lldb::Format format = m_options.format;
251
252 // Resolve any values that are possible
253 expr_result.ResolveValue(&m_exe_ctx, ast_context);
254
255 if (expr_result.GetContextType() == Value::eContextTypeInvalid &&
256 expr_result.GetValueType() == Value::eValueTypeScalar &&
257 format == eFormatDefault)
258 {
259 // The expression result is just a scalar with no special formatting
260 expr_result.GetScalar().GetValue (&output_stream, show_types);
261 output_stream.EOL();
262 }
263 else
264 {
265 DataExtractor data;
266 expr_error = expr_result.GetValueAsData (&m_exe_ctx, ast_context, data, 0);
267 if (expr_error.Success())
268 {
269 if (format == eFormatDefault)
270 format = expr_result.GetValueDefaultFormat ();
271
272 void *clang_type = expr_result.GetValueOpaqueClangQualType();
273 if (clang_type)
274 {
275 if (show_types)
276 Type::DumpClangTypeName(&output_stream, clang_type);
277
278 Type::DumpValue (
279 &m_exe_ctx, // The execution context for memory and variable access
280 ast_context, // The ASTContext that the clang type belongs to
281 clang_type, // The opaque clang type we want to dump that value of
282 &output_stream, // Stream to dump to
283 format, // Format to use when dumping
284 data, // A buffer containing the bytes for the clang type
285 0, // Byte offset within "data" where value is
286 data.GetByteSize(), // Size in bytes of the value we are dumping
287 0, // Bitfield bit size
288 0, // Bitfield bit offset
289 show_types, // Show types?
290 show_summary, // Show summary?
291 debug, // Debug logging output?
292 UINT32_MAX); // Depth to dump in case this is an aggregate type
293 }
294 else
295 {
296 data.Dump(&output_stream, // Stream to dump to
297 0, // Byte offset within "data"
298 format, // Format to use when dumping
299 data.GetByteSize(), // Size in bytes of each item we are dumping
300 1, // Number of items to dump
301 UINT32_MAX, // Number of items per line
302 LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context
303 0, // Bitfield bit size
304 0); // Bitfield bit offset
305 }
306 output_stream.EOL();
307 }
308 else
309 {
310 error_stream.Printf ("error: %s\n", expr_error.AsCString());
311 success = false;
312 }
313 }
314 }
315 else
316 {
317 error_stream.Printf ("error: %s\n", expr_error.AsCString());
318 }
319 }
320 }
321 else
322 {
323 error_stream.PutCString ("error: invalid target triple\n");
324 }
325
326 return success;
327}
328
329bool
330CommandObjectExpression::ExecuteRawCommandString
331(
332 const char *command,
333 CommandContext *context,
334 CommandInterpreter *interpreter,
335 CommandReturnObject &result
336)
337{
338 ConstString target_triple;
339 Target *target = context->GetTarget ();
340 if (target)
341 target->GetTargetTriple(target_triple);
342
343 if (!target_triple)
344 target_triple = Host::GetTargetTriple ();
345
346 ExecutionContext exe_ctx(context->GetExecutionContext());
347
348 Stream &output_stream = result.GetOutputStream();
349
350 m_options.ResetOptionValues();
351
352 const char * expr = NULL;
353
354 if (command[0] == '\0')
355 {
356 m_expr_lines.clear();
357 m_expr_line_count = 0;
358
359 InputReaderSP reader_sp (new InputReader());
360 if (reader_sp)
361 {
362 Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
363 this, // baton
364 eInputReaderGranularityLine, // token size, to pass to callback function
365 NULL, // end token
366 NULL, // prompt
367 true)); // echo input
368 if (err.Success())
369 {
370 Debugger::GetSharedInstance().PushInputReader (reader_sp);
371 result.SetStatus (eReturnStatusSuccessFinishNoResult);
372 }
373 else
374 {
375 result.AppendError (err.AsCString());
376 result.SetStatus (eReturnStatusFailed);
377 }
378 }
379 else
380 {
381 result.AppendError("out of memory");
382 result.SetStatus (eReturnStatusFailed);
383 }
384 return result.Succeeded();
385 }
386
387 if (command[0] == '-')
388 {
389 // We have some options and these options MUST end with --.
390 const char *end_options = NULL;
391 const char *s = command;
392 while (s && s[0])
393 {
394 end_options = ::strstr (s, "--");
395 if (end_options)
396 {
397 end_options += 2; // Get past the "--"
398 if (::isspace (end_options[0]))
399 {
400 expr = end_options;
401 while (::isspace (*expr))
402 ++expr;
403 break;
404 }
405 }
406 s = end_options;
407 }
408
409 if (end_options)
410 {
411 Args args(command, end_options - command);
412 if (!ParseOptions(args, interpreter, result))
413 return false;
414 }
415 }
416
417 const bool show_types = m_options.show_types;
418 const bool show_summary = m_options.show_summary;
419 const bool debug = m_options.debug;
420
421
422 if (expr == NULL)
423 expr = command;
424
425 if (target_triple)
426 {
427 ClangExpressionDeclMap expr_decl_map(&exe_ctx);
428
429 ClangExpression clang_expr(target_triple.AsCString(), &expr_decl_map);
430
431 unsigned num_errors = clang_expr.ParseExpression (expr, result.GetErrorStream());
432
433 if (num_errors == 0)
434 {
435 StreamString dwarf_opcodes;
436 dwarf_opcodes.SetByteOrder(eByteOrderHost);
437 dwarf_opcodes.GetFlags().Set(Stream::eBinary);
438 ClangExpressionVariableList expr_local_vars;
439 clang_expr.ConvertExpressionToDWARF (expr_local_vars, dwarf_opcodes);
440
441 result.SetStatus (eReturnStatusSuccessFinishResult);
442
443 DataExtractor dwarf_opcodes_data(dwarf_opcodes.GetData(), dwarf_opcodes.GetSize(), eByteOrderHost, 8);
444 DWARFExpression expr(dwarf_opcodes_data, 0, dwarf_opcodes_data.GetByteSize(), NULL);
445 expr.SetExpressionLocalVariableList(&expr_local_vars);
446 expr.SetExpressionDeclMap(&expr_decl_map);
447 if (debug)
448 {
449 output_stream << "Expression parsed ok, dwarf opcodes:";
450 output_stream.IndentMore();
451 expr.GetDescription(&output_stream, lldb::eDescriptionLevelVerbose);
452 output_stream.IndentLess();
453 output_stream.EOL();
454 }
455
456 clang::ASTContext *ast_context = clang_expr.GetASTContext();
457 Value expr_result;
458 Error expr_error;
459 bool expr_success = expr.Evaluate (&exe_ctx, ast_context, NULL, expr_result, &expr_error);
460 if (expr_success)
461 {
462 lldb::Format format = m_options.format;
463
464 // Resolve any values that are possible
465 expr_result.ResolveValue(&exe_ctx, ast_context);
466
467 if (expr_result.GetContextType() == Value::eContextTypeInvalid &&
468 expr_result.GetValueType() == Value::eValueTypeScalar &&
469 format == eFormatDefault)
470 {
471 // The expression result is just a scalar with no special formatting
472 expr_result.GetScalar().GetValue (&output_stream, show_types);
473 output_stream.EOL();
474 }
475 else
476 {
477 DataExtractor data;
478 expr_error = expr_result.GetValueAsData (&exe_ctx, ast_context, data, 0);
479 if (expr_error.Success())
480 {
481 if (format == eFormatDefault)
482 format = expr_result.GetValueDefaultFormat ();
483
484 void *clang_type = expr_result.GetValueOpaqueClangQualType();
485 if (clang_type)
486 {
487 if (show_types)
488 Type::DumpClangTypeName(&output_stream, clang_type);
489
490 Type::DumpValue (
491 &exe_ctx, // The execution context for memory and variable access
492 ast_context, // The ASTContext that the clang type belongs to
493 clang_type, // The opaque clang type we want to dump that value of
494 &output_stream, // Stream to dump to
495 format, // Format to use when dumping
496 data, // A buffer containing the bytes for the clang type
497 0, // Byte offset within "data" where value is
498 data.GetByteSize(), // Size in bytes of the value we are dumping
499 0, // Bitfield bit size
500 0, // Bitfield bit offset
501 show_types, // Show types?
502 show_summary, // Show summary?
503 debug, // Debug logging output?
504 UINT32_MAX); // Depth to dump in case this is an aggregate type
505 }
506 else
507 {
508 data.Dump(&output_stream, // Stream to dump to
509 0, // Byte offset within "data"
510 format, // Format to use when dumping
511 data.GetByteSize(), // Size in bytes of each item we are dumping
512 1, // Number of items to dump
513 UINT32_MAX, // Number of items per line
514 LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context
515 0, // Bitfield bit size
516 0); // Bitfield bit offset
517 }
518 output_stream.EOL();
519 }
520 else
521 {
522 result.AppendError(expr_error.AsCString());
523 result.SetStatus (eReturnStatusFailed);
524 }
525 }
526 }
527 else
528 {
529 result.AppendError (expr_error.AsCString());
530 result.SetStatus (eReturnStatusFailed);
531 }
532 }
533 else
534 {
535 result.SetStatus (eReturnStatusFailed);
536 }
537 }
538 else
539 {
540 result.AppendError ("invalid target triple");
541 result.SetStatus (eReturnStatusFailed);
542 }
543 return result.Succeeded();
544}
545
546lldb::OptionDefinition
547CommandObjectExpression::CommandOptions::g_option_table[] =
548{
549{ 0, true, "language", 'l', required_argument, NULL, 0, "[c|c++|objc|objc++]", "Sets the language to use when parsing the expression."},
550{ 0, false, "format", 'f', required_argument, NULL, 0, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]", "Specify the format that the expression output should use."},
551{ 0, false, "debug", 'g', no_argument, NULL, 0, NULL, "Enable verbose debug logging of the expression parsing and evaluation."},
552{ 0, false, NULL, 0, 0, NULL, NULL, NULL, NULL }
553};
554