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