130fdc8d8SChris Lattner //===-- CommandObjectExpression.cpp -----------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "CommandObjectExpression.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
16ebf7707eSSean Callanan #include "lldb/Interpreter/Args.h"
1730fdc8d8SChris Lattner #include "lldb/Core/Value.h"
1830fdc8d8SChris Lattner #include "lldb/Core/InputReader.h"
1930fdc8d8SChris Lattner #include "lldb/Expression/ClangExpression.h"
2030fdc8d8SChris Lattner #include "lldb/Expression/ClangExpressionDeclMap.h"
2130fdc8d8SChris Lattner #include "lldb/Expression/ClangExpressionVariable.h"
222235f32bSSean Callanan #include "lldb/Expression/ClangPersistentVariables.h"
23ebb84b24SStephen Wilson #include "lldb/Expression/ClangFunction.h"
2430fdc8d8SChris Lattner #include "lldb/Expression/DWARFExpression.h"
2530fdc8d8SChris Lattner #include "lldb/Host/Host.h"
26ebf7707eSSean Callanan #include "lldb/Core/Debugger.h"
276611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2830fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
2930fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
3030fdc8d8SChris Lattner #include "lldb/Symbol/Variable.h"
3130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
3230fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h"
3330fdc8d8SChris Lattner #include "lldb/Target/Target.h"
34ebf7707eSSean Callanan #include "llvm/ADT/StringRef.h"
3530fdc8d8SChris Lattner 
3630fdc8d8SChris Lattner using namespace lldb;
3730fdc8d8SChris Lattner using namespace lldb_private;
3830fdc8d8SChris Lattner 
3930fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::CommandOptions () :
4030fdc8d8SChris Lattner     Options()
4130fdc8d8SChris Lattner {
4230fdc8d8SChris Lattner     // Keep only one place to reset the values to their defaults
4330fdc8d8SChris Lattner     ResetOptionValues();
4430fdc8d8SChris Lattner }
4530fdc8d8SChris Lattner 
4630fdc8d8SChris Lattner 
4730fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::~CommandOptions ()
4830fdc8d8SChris Lattner {
4930fdc8d8SChris Lattner }
5030fdc8d8SChris Lattner 
5130fdc8d8SChris Lattner Error
5230fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
5330fdc8d8SChris Lattner {
5430fdc8d8SChris Lattner     Error error;
5530fdc8d8SChris Lattner 
5630fdc8d8SChris Lattner     char short_option = (char) m_getopt_table[option_idx].val;
5730fdc8d8SChris Lattner 
5830fdc8d8SChris Lattner     switch (short_option)
5930fdc8d8SChris Lattner     {
6030fdc8d8SChris Lattner     case 'l':
6130fdc8d8SChris Lattner         if (language.SetLanguageFromCString (option_arg) == false)
6230fdc8d8SChris Lattner         {
6330fdc8d8SChris Lattner             error.SetErrorStringWithFormat("Invalid language option argument '%s'.\n", option_arg);
6430fdc8d8SChris Lattner         }
6530fdc8d8SChris Lattner         break;
6630fdc8d8SChris Lattner 
6730fdc8d8SChris Lattner     case 'g':
6830fdc8d8SChris Lattner         debug = true;
6930fdc8d8SChris Lattner         break;
7030fdc8d8SChris Lattner 
7130fdc8d8SChris Lattner     case 'f':
7230fdc8d8SChris Lattner         error = Args::StringToFormat(option_arg, format);
7330fdc8d8SChris Lattner         break;
7430fdc8d8SChris Lattner 
7530fdc8d8SChris Lattner     default:
7630fdc8d8SChris Lattner         error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
7730fdc8d8SChris Lattner         break;
7830fdc8d8SChris Lattner     }
7930fdc8d8SChris Lattner 
8030fdc8d8SChris Lattner     return error;
8130fdc8d8SChris Lattner }
8230fdc8d8SChris Lattner 
8330fdc8d8SChris Lattner void
8430fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::ResetOptionValues ()
8530fdc8d8SChris Lattner {
8630fdc8d8SChris Lattner     Options::ResetOptionValues();
8730fdc8d8SChris Lattner     language.Clear();
8830fdc8d8SChris Lattner     debug = false;
8930fdc8d8SChris Lattner     format = eFormatDefault;
9030fdc8d8SChris Lattner     show_types = true;
9130fdc8d8SChris Lattner     show_summary = true;
9230fdc8d8SChris Lattner }
9330fdc8d8SChris Lattner 
9430fdc8d8SChris Lattner const lldb::OptionDefinition*
9530fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::GetDefinitions ()
9630fdc8d8SChris Lattner {
9730fdc8d8SChris Lattner     return g_option_table;
9830fdc8d8SChris Lattner }
9930fdc8d8SChris Lattner 
10030fdc8d8SChris Lattner CommandObjectExpression::CommandObjectExpression () :
10130fdc8d8SChris Lattner     CommandObject (
10230fdc8d8SChris Lattner             "expression",
10330fdc8d8SChris Lattner             "Evaluate a C expression in the current program context, using variables currently in scope.",
10430fdc8d8SChris Lattner             "expression [<cmd-options>] <expr>"),
10530fdc8d8SChris Lattner     m_expr_line_count (0),
10630fdc8d8SChris Lattner     m_expr_lines ()
10730fdc8d8SChris Lattner {
10830fdc8d8SChris Lattner   SetHelpLong(
10930fdc8d8SChris Lattner "Examples: \n\
11030fdc8d8SChris Lattner \n\
11130fdc8d8SChris Lattner    expr my_struct->a = my_array[3] \n\
11230fdc8d8SChris Lattner    expr -f bin -- (index * 8) + 5 \n\
11330fdc8d8SChris Lattner    expr char c[] = \"foo\"; c[0]\n");
11430fdc8d8SChris Lattner }
11530fdc8d8SChris Lattner 
11630fdc8d8SChris Lattner CommandObjectExpression::~CommandObjectExpression ()
11730fdc8d8SChris Lattner {
11830fdc8d8SChris Lattner }
11930fdc8d8SChris Lattner 
12030fdc8d8SChris Lattner Options *
12130fdc8d8SChris Lattner CommandObjectExpression::GetOptions ()
12230fdc8d8SChris Lattner {
12330fdc8d8SChris Lattner     return &m_options;
12430fdc8d8SChris Lattner }
12530fdc8d8SChris Lattner 
12630fdc8d8SChris Lattner 
12730fdc8d8SChris Lattner bool
12830fdc8d8SChris Lattner CommandObjectExpression::Execute
12930fdc8d8SChris Lattner (
1306611103cSGreg Clayton     CommandInterpreter &interpreter,
13130fdc8d8SChris Lattner     Args& command,
13230fdc8d8SChris Lattner     CommandReturnObject &result
13330fdc8d8SChris Lattner )
13430fdc8d8SChris Lattner {
13530fdc8d8SChris Lattner     return false;
13630fdc8d8SChris Lattner }
13730fdc8d8SChris Lattner 
13830fdc8d8SChris Lattner 
13930fdc8d8SChris Lattner size_t
14030fdc8d8SChris Lattner CommandObjectExpression::MultiLineExpressionCallback
14130fdc8d8SChris Lattner (
14230fdc8d8SChris Lattner     void *baton,
1436611103cSGreg Clayton     InputReader &reader,
14430fdc8d8SChris Lattner     lldb::InputReaderAction notification,
14530fdc8d8SChris Lattner     const char *bytes,
14630fdc8d8SChris Lattner     size_t bytes_len
14730fdc8d8SChris Lattner )
14830fdc8d8SChris Lattner {
14930fdc8d8SChris Lattner     CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
15030fdc8d8SChris Lattner 
15130fdc8d8SChris Lattner     switch (notification)
15230fdc8d8SChris Lattner     {
15330fdc8d8SChris Lattner     case eInputReaderActivate:
1546611103cSGreg Clayton         reader.GetDebugger().GetOutputStream().Printf("%s\n", "Enter expressions, then terminate with an empty line to evaluate:");
15530fdc8d8SChris Lattner         // Fall through
15630fdc8d8SChris Lattner     case eInputReaderReactivate:
15730fdc8d8SChris Lattner         //if (out_fh)
1586611103cSGreg Clayton         //    reader.GetDebugger().GetOutputStream().Printf ("%3u: ", cmd_object_expr->m_expr_line_count);
15930fdc8d8SChris Lattner         break;
16030fdc8d8SChris Lattner 
16130fdc8d8SChris Lattner     case eInputReaderDeactivate:
16230fdc8d8SChris Lattner         break;
16330fdc8d8SChris Lattner 
16430fdc8d8SChris Lattner     case eInputReaderGotToken:
16530fdc8d8SChris Lattner         ++cmd_object_expr->m_expr_line_count;
16630fdc8d8SChris Lattner         if (bytes && bytes_len)
16730fdc8d8SChris Lattner         {
16830fdc8d8SChris Lattner             cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
16930fdc8d8SChris Lattner         }
17030fdc8d8SChris Lattner 
17130fdc8d8SChris Lattner         if (bytes_len == 0)
1726611103cSGreg Clayton             reader.SetIsDone(true);
17330fdc8d8SChris Lattner         //else if (out_fh && !reader->IsDone())
17430fdc8d8SChris Lattner         //    ::fprintf (out_fh, "%3u: ", cmd_object_expr->m_expr_line_count);
17530fdc8d8SChris Lattner         break;
17630fdc8d8SChris Lattner 
17730fdc8d8SChris Lattner     case eInputReaderDone:
17830fdc8d8SChris Lattner         {
17930fdc8d8SChris Lattner             bool bare = false;
18030fdc8d8SChris Lattner             cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
18130fdc8d8SChris Lattner                                                  bare,
1826611103cSGreg Clayton                                                  reader.GetDebugger().GetOutputStream(),
1836611103cSGreg Clayton                                                  reader.GetDebugger().GetErrorStream());
18430fdc8d8SChris Lattner         }
18530fdc8d8SChris Lattner         break;
18630fdc8d8SChris Lattner     }
18730fdc8d8SChris Lattner 
18830fdc8d8SChris Lattner     return bytes_len;
18930fdc8d8SChris Lattner }
19030fdc8d8SChris Lattner 
19130fdc8d8SChris Lattner bool
19230fdc8d8SChris Lattner CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream &output_stream, Stream &error_stream)
19330fdc8d8SChris Lattner {
19416ad5faeSSean Callanan     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
19516ad5faeSSean Callanan 
19616ad5faeSSean Callanan     ////////////////////////////////////
19716ad5faeSSean Callanan     // Set up the target and compiler
19816ad5faeSSean Callanan     //
19916ad5faeSSean Callanan 
20030fdc8d8SChris Lattner     Target *target = m_exe_ctx.target;
20116ad5faeSSean Callanan 
20216ad5faeSSean Callanan     if (!target)
20316ad5faeSSean Callanan     {
20416ad5faeSSean Callanan         error_stream.PutCString ("error: invalid target\n");
20516ad5faeSSean Callanan         return false;
20616ad5faeSSean Callanan     }
20716ad5faeSSean Callanan 
20816ad5faeSSean Callanan     ConstString target_triple;
20916ad5faeSSean Callanan 
21030fdc8d8SChris Lattner     target->GetTargetTriple (target_triple);
21130fdc8d8SChris Lattner 
21230fdc8d8SChris Lattner     if (!target_triple)
21330fdc8d8SChris Lattner         target_triple = Host::GetTargetTriple ();
21430fdc8d8SChris Lattner 
21516ad5faeSSean Callanan     if (!target_triple)
21630fdc8d8SChris Lattner     {
21716ad5faeSSean Callanan         error_stream.PutCString ("error: invalid target triple\n");
21816ad5faeSSean Callanan         return false;
21916ad5faeSSean Callanan     }
22030fdc8d8SChris Lattner 
2212235f32bSSean Callanan     ClangExpressionDeclMap expr_decl_map (&m_exe_ctx);
22230fdc8d8SChris Lattner     ClangExpression clang_expr (target_triple.AsCString (), &expr_decl_map);
22330fdc8d8SChris Lattner 
22416ad5faeSSean Callanan     //////////////////////////
22516ad5faeSSean Callanan     // Parse the expression
22616ad5faeSSean Callanan     //
22716ad5faeSSean Callanan 
22816ad5faeSSean Callanan     unsigned num_errors;
22930fdc8d8SChris Lattner 
23030fdc8d8SChris Lattner     if (bare)
23130fdc8d8SChris Lattner         num_errors = clang_expr.ParseBareExpression (llvm::StringRef (expr), error_stream);
23230fdc8d8SChris Lattner     else
233fc16cc0aSSean Callanan         num_errors = clang_expr.ParseExpression (expr, error_stream, true);
23430fdc8d8SChris Lattner 
23516ad5faeSSean Callanan     if (num_errors)
23630fdc8d8SChris Lattner     {
23716ad5faeSSean Callanan         error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
23816ad5faeSSean Callanan         return false;
23916ad5faeSSean Callanan     }
24016ad5faeSSean Callanan 
24116ad5faeSSean Callanan     ///////////////////////////////////////////////
24216ad5faeSSean Callanan     // Convert the output of the parser to DWARF
24316ad5faeSSean Callanan     //
24416ad5faeSSean Callanan 
24530fdc8d8SChris Lattner     StreamString dwarf_opcodes;
24630fdc8d8SChris Lattner     dwarf_opcodes.SetByteOrder (eByteOrderHost);
24730fdc8d8SChris Lattner     dwarf_opcodes.GetFlags ().Set (Stream::eBinary);
24816ad5faeSSean Callanan 
24930fdc8d8SChris Lattner     ClangExpressionVariableList expr_local_vars;
25030fdc8d8SChris Lattner 
2511d389c4bSSean Callanan     bool success;
2522ab712f2SSean Callanan     bool canInterpret = false;
2531d389c4bSSean Callanan 
254ebf7707eSSean Callanan     clang::ASTContext *ast_context = clang_expr.GetASTContext ();
255d1e5b439SSean Callanan     ClangPersistentVariable *expr_result = 0;
256ebf7707eSSean Callanan     Error expr_error;
257ebf7707eSSean Callanan 
2582ab712f2SSean Callanan     canInterpret = clang_expr.ConvertIRToDWARF (expr_local_vars, dwarf_opcodes);
2592ab712f2SSean Callanan 
2602ab712f2SSean Callanan     if (canInterpret)
2612ab712f2SSean Callanan     {
2622ab712f2SSean Callanan         if (log)
2632ab712f2SSean Callanan             log->Printf("Code can be interpreted.");
2642ab712f2SSean Callanan         success = true;
2652ab712f2SSean Callanan     }
2661d389c4bSSean Callanan     else
2672ab712f2SSean Callanan     {
2682ab712f2SSean Callanan         if (log)
2692ab712f2SSean Callanan             log->Printf("Code cannot be interpreted and must be run in the target.");
270*b269b6eaSSean Callanan         success = clang_expr.PrepareIRForTarget ();
2712ab712f2SSean Callanan     }
2727618f4ebSSean Callanan 
2737618f4ebSSean Callanan     if (!success)
2747618f4ebSSean Callanan     {
2757618f4ebSSean Callanan         error_stream.PutCString ("error: expression couldn't be converted to IR\n");
2767618f4ebSSean Callanan         return false;
2777618f4ebSSean Callanan     }
2787618f4ebSSean Callanan 
2797618f4ebSSean Callanan     if (canInterpret)
2807618f4ebSSean Callanan     {
2817618f4ebSSean Callanan         // TODO interpret IR
2827618f4ebSSean Callanan         return false;
2837618f4ebSSean Callanan     }
2847618f4ebSSean Callanan     else
2857618f4ebSSean Callanan     {
286*b269b6eaSSean Callanan         if (!clang_expr.JITFunction ())
2877618f4ebSSean Callanan         {
2887618f4ebSSean Callanan             error_stream.PutCString ("error: IR could not be JIT compiled\n");
2897618f4ebSSean Callanan             return false;
2907618f4ebSSean Callanan         }
2917618f4ebSSean Callanan 
2927618f4ebSSean Callanan         if (!clang_expr.WriteJITCode (m_exe_ctx))
2937618f4ebSSean Callanan         {
2947618f4ebSSean Callanan             error_stream.PutCString ("error: JIT code could not be written to the target\n");
2957618f4ebSSean Callanan             return false;
2967618f4ebSSean Callanan         }
2977618f4ebSSean Callanan 
298*b269b6eaSSean Callanan         lldb::addr_t function_address(clang_expr.GetFunctionAddress ());
2997618f4ebSSean Callanan 
3007618f4ebSSean Callanan         if (function_address == LLDB_INVALID_ADDRESS)
3017618f4ebSSean Callanan         {
3027618f4ebSSean Callanan             error_stream.PutCString ("JIT compiled code's address couldn't be found\n");
3037618f4ebSSean Callanan             return false;
3047618f4ebSSean Callanan         }
3057618f4ebSSean Callanan 
3061d180664SSean Callanan         lldb::addr_t struct_address;
307ea22d428SSean Callanan 
308ebf7707eSSean Callanan         if (!expr_decl_map.Materialize(&m_exe_ctx, struct_address, expr_error))
309ea22d428SSean Callanan         {
310ebf7707eSSean Callanan             error_stream.Printf ("Couldn't materialize struct: %s\n", expr_error.AsCString("unknown error"));
311ea22d428SSean Callanan             return false;
3127618f4ebSSean Callanan         }
313ea22d428SSean Callanan 
314ebf7707eSSean Callanan         if (log)
315ebf7707eSSean Callanan         {
316ea22d428SSean Callanan             log->Printf("Function address  : 0x%llx", (uint64_t)function_address);
317ea22d428SSean Callanan             log->Printf("Structure address : 0x%llx", (uint64_t)struct_address);
3186dde30e9SSean Callanan 
3196dde30e9SSean Callanan             StreamString insns;
3206dde30e9SSean Callanan 
321*b269b6eaSSean Callanan             Error err = clang_expr.DisassembleFunction(insns, m_exe_ctx);
3226dde30e9SSean Callanan 
3236dde30e9SSean Callanan             if (!err.Success())
3246dde30e9SSean Callanan             {
3256dde30e9SSean Callanan                 log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
3266dde30e9SSean Callanan             }
3276dde30e9SSean Callanan             else
3286dde30e9SSean Callanan             {
3296dde30e9SSean Callanan                 log->Printf("Function disassembly:\n%s", insns.GetData());
3306dde30e9SSean Callanan             }
331289e07b9SSean Callanan 
332289e07b9SSean Callanan             StreamString args;
333289e07b9SSean Callanan 
334289e07b9SSean Callanan             if (!expr_decl_map.DumpMaterializedStruct(&m_exe_ctx, args, err))
335289e07b9SSean Callanan             {
336289e07b9SSean Callanan                 log->Printf("Couldn't extract variable values : %s", err.AsCString("unknown error"));
337289e07b9SSean Callanan             }
338289e07b9SSean Callanan             else
339289e07b9SSean Callanan             {
340289e07b9SSean Callanan                 log->Printf("Structure contents:\n%s", args.GetData());
341289e07b9SSean Callanan             }
342ea22d428SSean Callanan         }
343ea22d428SSean Callanan 
344ebf7707eSSean Callanan         ClangFunction::ExecutionResults execution_result =
345ebf7707eSSean Callanan             ClangFunction::ExecuteFunction (m_exe_ctx, function_address, struct_address, true, true, 10000, error_stream);
346ea22d428SSean Callanan 
347ebf7707eSSean Callanan         if (execution_result != ClangFunction::eExecutionCompleted)
348ebf7707eSSean Callanan         {
349ebf7707eSSean Callanan             const char *result_name;
350ebf7707eSSean Callanan 
351ebf7707eSSean Callanan             switch (execution_result)
352ebf7707eSSean Callanan             {
353ebf7707eSSean Callanan             case ClangFunction::eExecutionCompleted:
354ebf7707eSSean Callanan                 result_name = "eExecutionCompleted";
355ebf7707eSSean Callanan                 break;
356ebf7707eSSean Callanan             case ClangFunction::eExecutionDiscarded:
357ebf7707eSSean Callanan                 result_name = "eExecutionDiscarded";
358ebf7707eSSean Callanan                 break;
359ebf7707eSSean Callanan             case ClangFunction::eExecutionInterrupted:
360ebf7707eSSean Callanan                 result_name = "eExecutionInterrupted";
361ebf7707eSSean Callanan                 break;
362ebf7707eSSean Callanan             case ClangFunction::eExecutionSetupError:
363ebf7707eSSean Callanan                 result_name = "eExecutionSetupError";
364ebf7707eSSean Callanan                 break;
365ebf7707eSSean Callanan             case ClangFunction::eExecutionTimedOut:
366ebf7707eSSean Callanan                 result_name = "eExecutionTimedOut";
367ebf7707eSSean Callanan                 break;
368ebf7707eSSean Callanan             }
369ebf7707eSSean Callanan 
370ebf7707eSSean Callanan             error_stream.Printf ("Couldn't execute function; result was %s\n", result_name);
371ebf7707eSSean Callanan             return false;
372ebf7707eSSean Callanan         }
373ebf7707eSSean Callanan 
374ebf7707eSSean Callanan         if (!expr_decl_map.Dematerialize(&m_exe_ctx, expr_result, expr_error))
375ebf7707eSSean Callanan         {
376ebf7707eSSean Callanan             error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error"));
377ebf7707eSSean Callanan             return false;
378ebf7707eSSean Callanan         }
379ebf7707eSSean Callanan     }
38016ad5faeSSean Callanan 
381d1e5b439SSean Callanan     if (expr_result)
38230fdc8d8SChris Lattner     {
383d1e5b439SSean Callanan         StreamString ss;
38416ad5faeSSean Callanan 
385d1e5b439SSean Callanan         Error err = expr_result->Print (ss,
386d1e5b439SSean Callanan                                         m_exe_ctx,
387d1e5b439SSean Callanan                                         m_options.format,
388d1e5b439SSean Callanan                                         m_options.show_types,
389d1e5b439SSean Callanan                                         m_options.show_summary,
390d1e5b439SSean Callanan                                         m_options.debug);
39116ad5faeSSean Callanan 
392d1e5b439SSean Callanan         if (err.Success())
393d1e5b439SSean Callanan             output_stream.PutCString(ss.GetString().c_str());
394d1e5b439SSean Callanan         else
395d1e5b439SSean Callanan             error_stream.Printf ("Couldn't print result : %s\n", err.AsCString("unknown error"));
39630fdc8d8SChris Lattner     }
39730fdc8d8SChris Lattner     else
39830fdc8d8SChris Lattner     {
399d1e5b439SSean Callanan         error_stream.Printf ("Expression produced no result\n");
40030fdc8d8SChris Lattner     }
40130fdc8d8SChris Lattner 
40216ad5faeSSean Callanan     return true;
40330fdc8d8SChris Lattner }
40430fdc8d8SChris Lattner 
40530fdc8d8SChris Lattner bool
40630fdc8d8SChris Lattner CommandObjectExpression::ExecuteRawCommandString
40730fdc8d8SChris Lattner (
4086611103cSGreg Clayton     CommandInterpreter &interpreter,
40930fdc8d8SChris Lattner     const char *command,
41030fdc8d8SChris Lattner     CommandReturnObject &result
41130fdc8d8SChris Lattner )
41230fdc8d8SChris Lattner {
41316ad5faeSSean Callanan     m_exe_ctx = interpreter.GetDebugger().GetExecutionContext();
41430fdc8d8SChris Lattner 
41530fdc8d8SChris Lattner     m_options.ResetOptionValues();
41630fdc8d8SChris Lattner 
41730fdc8d8SChris Lattner     const char * expr = NULL;
41830fdc8d8SChris Lattner 
41930fdc8d8SChris Lattner     if (command[0] == '\0')
42030fdc8d8SChris Lattner     {
42130fdc8d8SChris Lattner         m_expr_lines.clear();
42230fdc8d8SChris Lattner         m_expr_line_count = 0;
42330fdc8d8SChris Lattner 
4246611103cSGreg Clayton         InputReaderSP reader_sp (new InputReader(interpreter.GetDebugger()));
42530fdc8d8SChris Lattner         if (reader_sp)
42630fdc8d8SChris Lattner         {
42730fdc8d8SChris Lattner             Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
42830fdc8d8SChris Lattner                                               this,                         // baton
42930fdc8d8SChris Lattner                                               eInputReaderGranularityLine,  // token size, to pass to callback function
43030fdc8d8SChris Lattner                                               NULL,                         // end token
43130fdc8d8SChris Lattner                                               NULL,                         // prompt
43230fdc8d8SChris Lattner                                               true));                       // echo input
43330fdc8d8SChris Lattner             if (err.Success())
43430fdc8d8SChris Lattner             {
4356611103cSGreg Clayton                 interpreter.GetDebugger().PushInputReader (reader_sp);
43630fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
43730fdc8d8SChris Lattner             }
43830fdc8d8SChris Lattner             else
43930fdc8d8SChris Lattner             {
44030fdc8d8SChris Lattner                 result.AppendError (err.AsCString());
44130fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
44230fdc8d8SChris Lattner             }
44330fdc8d8SChris Lattner         }
44430fdc8d8SChris Lattner         else
44530fdc8d8SChris Lattner         {
44630fdc8d8SChris Lattner             result.AppendError("out of memory");
44730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
44830fdc8d8SChris Lattner         }
44930fdc8d8SChris Lattner         return result.Succeeded();
45030fdc8d8SChris Lattner     }
45130fdc8d8SChris Lattner 
45230fdc8d8SChris Lattner     if (command[0] == '-')
45330fdc8d8SChris Lattner     {
45430fdc8d8SChris Lattner         // We have some options and these options MUST end with --.
45530fdc8d8SChris Lattner         const char *end_options = NULL;
45630fdc8d8SChris Lattner         const char *s = command;
45730fdc8d8SChris Lattner         while (s && s[0])
45830fdc8d8SChris Lattner         {
45930fdc8d8SChris Lattner             end_options = ::strstr (s, "--");
46030fdc8d8SChris Lattner             if (end_options)
46130fdc8d8SChris Lattner             {
46230fdc8d8SChris Lattner                 end_options += 2; // Get past the "--"
46330fdc8d8SChris Lattner                 if (::isspace (end_options[0]))
46430fdc8d8SChris Lattner                 {
46530fdc8d8SChris Lattner                     expr = end_options;
46630fdc8d8SChris Lattner                     while (::isspace (*expr))
46730fdc8d8SChris Lattner                         ++expr;
46830fdc8d8SChris Lattner                     break;
46930fdc8d8SChris Lattner                 }
47030fdc8d8SChris Lattner             }
47130fdc8d8SChris Lattner             s = end_options;
47230fdc8d8SChris Lattner         }
47330fdc8d8SChris Lattner 
47430fdc8d8SChris Lattner         if (end_options)
47530fdc8d8SChris Lattner         {
47630fdc8d8SChris Lattner             Args args (command, end_options - command);
4776611103cSGreg Clayton             if (!ParseOptions (interpreter, args, result))
47830fdc8d8SChris Lattner                 return false;
47930fdc8d8SChris Lattner         }
48030fdc8d8SChris Lattner     }
48130fdc8d8SChris Lattner 
48230fdc8d8SChris Lattner     if (expr == NULL)
48330fdc8d8SChris Lattner         expr = command;
48430fdc8d8SChris Lattner 
48516ad5faeSSean Callanan     return EvaluateExpression (expr, false, result.GetOutputStream(), result.GetErrorStream());
48630fdc8d8SChris Lattner }
48730fdc8d8SChris Lattner 
48830fdc8d8SChris Lattner lldb::OptionDefinition
48930fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::g_option_table[] =
49030fdc8d8SChris Lattner {
4910c5cd90dSGreg Clayton { LLDB_OPT_SET_ALL, false, "language",   'l', required_argument, NULL, 0, "[c|c++|objc|objc++]",          "Sets the language to use when parsing the expression."},
4921d389c4bSSean Callanan { LLDB_OPT_SET_ALL, 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."},
4931d389c4bSSean Callanan { LLDB_OPT_SET_ALL, false, "debug",      'g', no_argument,       NULL, 0, NULL,                           "Enable verbose debug logging of the expression parsing and evaluation."},
4941d389c4bSSean Callanan { LLDB_OPT_SET_ALL, false, "use-ir",     'i', no_argument,       NULL, 0, NULL,                           "[Temporary] Instructs the expression evaluator to use IR instead of ASTs."},
49530fdc8d8SChris Lattner { 0, false, NULL, 0, 0, NULL, NULL, NULL, NULL }
49630fdc8d8SChris Lattner };
49730fdc8d8SChris Lattner 
498