2010-06-08 16:52:24 +00:00
//===-- CommandObjectExpression.cpp -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
# include "CommandObjectExpression.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
2010-07-23 00:16:21 +00:00
# include "lldb/Interpreter/Args.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Core/Value.h"
# include "lldb/Core/InputReader.h"
# include "lldb/Expression/ClangExpressionVariable.h"
2010-08-27 01:01:44 +00:00
# include "lldb/Expression/ClangUserExpression.h"
2010-07-23 21:47:22 +00:00
# include "lldb/Expression/ClangFunction.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Expression/DWARFExpression.h"
# include "lldb/Host/Host.h"
2010-07-23 00:16:21 +00:00
# include "lldb/Core/Debugger.h"
2010-06-23 01:19:29 +00:00
# include "lldb/Interpreter/CommandInterpreter.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Interpreter/CommandReturnObject.h"
# include "lldb/Symbol/ObjectFile.h"
# include "lldb/Symbol/Variable.h"
# include "lldb/Target/Process.h"
# include "lldb/Target/StackFrame.h"
# include "lldb/Target/Target.h"
2010-07-23 00:16:21 +00:00
# include "llvm/ADT/StringRef.h"
2010-06-08 16:52:24 +00:00
using namespace lldb ;
using namespace lldb_private ;
CommandObjectExpression : : CommandOptions : : CommandOptions ( ) :
Options ( )
{
// Keep only one place to reset the values to their defaults
ResetOptionValues ( ) ;
}
CommandObjectExpression : : CommandOptions : : ~ CommandOptions ( )
{
}
Error
CommandObjectExpression : : CommandOptions : : SetOptionValue ( int option_idx , const char * option_arg )
{
Error error ;
char short_option = ( char ) m_getopt_table [ option_idx ] . val ;
switch ( short_option )
{
2010-09-07 22:38:08 +00:00
//case 'l':
//if (language.SetLanguageFromCString (option_arg) == false)
//{
// error.SetErrorStringWithFormat("Invalid language option argument '%s'.\n", option_arg);
//}
//break;
2010-06-08 16:52:24 +00:00
case ' g ' :
debug = true ;
break ;
case ' f ' :
error = Args : : StringToFormat ( option_arg , format ) ;
break ;
default :
error . SetErrorStringWithFormat ( " Invalid short option character '%c'. \n " , short_option ) ;
break ;
}
return error ;
}
void
CommandObjectExpression : : CommandOptions : : ResetOptionValues ( )
{
Options : : ResetOptionValues ( ) ;
2010-09-07 22:38:08 +00:00
//language.Clear();
2010-06-08 16:52:24 +00:00
debug = false ;
format = eFormatDefault ;
show_types = true ;
show_summary = true ;
}
const lldb : : OptionDefinition *
CommandObjectExpression : : CommandOptions : : GetDefinitions ( )
{
return g_option_table ;
}
CommandObjectExpression : : CommandObjectExpression ( ) :
CommandObject (
" expression " ,
2010-09-07 22:38:08 +00:00
" Evaluate an Objective-C++ expression in the current program context, using variables currently in scope. " ,
2010-06-08 16:52:24 +00:00
" expression [<cmd-options>] <expr> " ) ,
m_expr_line_count ( 0 ) ,
m_expr_lines ( )
{
SetHelpLong (
" Examples: \n \
\n \
expr my_struct->a = my_array[3] \n \
expr -f bin -- (index * 8) + 5 \n \
expr char c[] = \" foo \" ; c[0] \n " ) ;
}
CommandObjectExpression : : ~ CommandObjectExpression ( )
{
}
Options *
CommandObjectExpression : : GetOptions ( )
{
return & m_options ;
}
bool
CommandObjectExpression : : Execute
(
2010-06-23 01:19:29 +00:00
CommandInterpreter & interpreter ,
2010-06-08 16:52:24 +00:00
Args & command ,
CommandReturnObject & result
)
{
return false ;
}
size_t
CommandObjectExpression : : MultiLineExpressionCallback
(
void * baton ,
2010-06-23 01:19:29 +00:00
InputReader & reader ,
2010-06-08 16:52:24 +00:00
lldb : : InputReaderAction notification ,
const char * bytes ,
size_t bytes_len
)
{
CommandObjectExpression * cmd_object_expr = ( CommandObjectExpression * ) baton ;
switch ( notification )
{
case eInputReaderActivate :
2010-06-23 01:19:29 +00:00
reader . GetDebugger ( ) . GetOutputStream ( ) . Printf ( " %s \n " , " Enter expressions, then terminate with an empty line to evaluate: " ) ;
2010-06-08 16:52:24 +00:00
// Fall through
case eInputReaderReactivate :
//if (out_fh)
2010-06-23 01:19:29 +00:00
// reader.GetDebugger().GetOutputStream().Printf ("%3u: ", cmd_object_expr->m_expr_line_count);
2010-06-08 16:52:24 +00:00
break ;
case eInputReaderDeactivate :
break ;
case eInputReaderGotToken :
+ + cmd_object_expr - > m_expr_line_count ;
if ( bytes & & bytes_len )
{
cmd_object_expr - > m_expr_lines . append ( bytes , bytes_len + 1 ) ;
}
if ( bytes_len = = 0 )
2010-06-23 01:19:29 +00:00
reader . SetIsDone ( true ) ;
2010-06-08 16:52:24 +00:00
//else if (out_fh && !reader->IsDone())
// ::fprintf (out_fh, "%3u: ", cmd_object_expr->m_expr_line_count);
break ;
case eInputReaderDone :
{
bool bare = false ;
cmd_object_expr - > EvaluateExpression ( cmd_object_expr - > m_expr_lines . c_str ( ) ,
bare ,
2010-06-23 01:19:29 +00:00
reader . GetDebugger ( ) . GetOutputStream ( ) ,
reader . GetDebugger ( ) . GetErrorStream ( ) ) ;
2010-06-08 16:52:24 +00:00
}
break ;
}
return bytes_len ;
}
bool
2010-08-13 00:42:30 +00:00
CommandObjectExpression : : EvaluateExpression ( const char * expr , bool bare , Stream & output_stream , Stream & error_stream ,
CommandReturnObject * result )
2010-06-08 16:52:24 +00:00
{
2010-09-01 00:58:00 +00:00
if ( ! m_exe_ctx . process )
{
2010-09-01 19:53:33 +00:00
error_stream . Printf ( " Execution context doesn't contain a process \n " ) ;
2010-09-01 00:58:00 +00:00
return false ;
}
if ( ! m_exe_ctx . process - > GetDynamicCheckers ( ) )
{
DynamicCheckerFunctions * dynamic_checkers = new DynamicCheckerFunctions ( ) ;
StreamString install_errors ;
if ( ! dynamic_checkers - > Install ( install_errors , m_exe_ctx ) )
{
2010-09-01 19:53:33 +00:00
error_stream . Printf ( " Couldn't install dynamic checkers into the execution context: %s \n " , install_errors . GetData ( ) ) ;
2010-09-01 00:58:00 +00:00
return false ;
}
m_exe_ctx . process - > SetDynamicCheckers ( dynamic_checkers ) ;
}
2010-08-27 01:01:44 +00:00
ClangUserExpression user_expression ( expr ) ;
2010-06-24 00:16:27 +00:00
2010-08-27 01:01:44 +00:00
if ( ! user_expression . Parse ( error_stream , m_exe_ctx ) )
2010-06-24 00:16:27 +00:00
{
2010-09-01 19:53:33 +00:00
error_stream . Printf ( " Couldn't parse the expresssion \n " ) ;
2010-06-24 00:16:27 +00:00
return false ;
}
2010-08-27 01:01:44 +00:00
ClangExpressionVariable * expr_result ;
2010-06-24 00:16:27 +00:00
2010-08-27 01:01:44 +00:00
if ( ! user_expression . Execute ( error_stream , m_exe_ctx , expr_result ) )
2010-06-08 16:52:24 +00:00
{
2010-09-01 19:53:33 +00:00
error_stream . Printf ( " Couldn't execute the expresssion \n " ) ;
2010-06-24 00:16:27 +00:00
return false ;
}
2010-06-08 16:52:24 +00:00
2010-08-12 01:56:52 +00:00
if ( expr_result )
2010-07-23 00:16:21 +00:00
{
2010-08-12 01:56:52 +00:00
StreamString ss ;
2010-07-23 00:16:21 +00:00
2010-08-13 00:42:30 +00:00
Error rc = expr_result - > Print ( ss ,
m_exe_ctx ,
m_options . format ,
m_options . show_types ,
m_options . show_summary ,
m_options . debug ) ;
2010-08-12 01:56:52 +00:00
2010-08-13 00:42:30 +00:00
if ( rc . Fail ( ) ) {
error_stream . Printf ( " Couldn't print result : %s \n " , rc . AsCString ( ) ) ;
return false ;
}
output_stream . PutCString ( ss . GetString ( ) . c_str ( ) ) ;
if ( result )
result - > SetStatus ( eReturnStatusSuccessFinishResult ) ;
2010-07-23 00:16:21 +00:00
}
else
{
2010-08-12 01:56:52 +00:00
error_stream . Printf ( " Expression produced no result \n " ) ;
2010-08-13 00:42:30 +00:00
if ( result )
result - > SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
2010-07-23 00:16:21 +00:00
}
2010-08-12 01:56:52 +00:00
2010-07-23 00:16:21 +00:00
return true ;
2010-06-08 16:52:24 +00:00
}
bool
CommandObjectExpression : : ExecuteRawCommandString
(
2010-06-23 01:19:29 +00:00
CommandInterpreter & interpreter ,
2010-06-08 16:52:24 +00:00
const char * command ,
CommandReturnObject & result
)
{
2010-06-24 00:16:27 +00:00
m_exe_ctx = interpreter . GetDebugger ( ) . GetExecutionContext ( ) ;
2010-06-08 16:52:24 +00:00
m_options . ResetOptionValues ( ) ;
const char * expr = NULL ;
if ( command [ 0 ] = = ' \0 ' )
{
m_expr_lines . clear ( ) ;
m_expr_line_count = 0 ;
2010-06-23 01:19:29 +00:00
InputReaderSP reader_sp ( new InputReader ( interpreter . GetDebugger ( ) ) ) ;
2010-06-08 16:52:24 +00:00
if ( reader_sp )
{
Error err ( reader_sp - > Initialize ( CommandObjectExpression : : MultiLineExpressionCallback ,
this , // baton
eInputReaderGranularityLine , // token size, to pass to callback function
2010-06-23 01:19:29 +00:00
NULL , // end token
2010-06-08 16:52:24 +00:00
NULL , // prompt
true ) ) ; // echo input
if ( err . Success ( ) )
{
2010-06-23 01:19:29 +00:00
interpreter . GetDebugger ( ) . PushInputReader ( reader_sp ) ;
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . AppendError ( err . AsCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
}
else
{
result . AppendError ( " out of memory " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
}
return result . Succeeded ( ) ;
}
if ( command [ 0 ] = = ' - ' )
{
// We have some options and these options MUST end with --.
const char * end_options = NULL ;
const char * s = command ;
while ( s & & s [ 0 ] )
{
end_options = : : strstr ( s , " -- " ) ;
if ( end_options )
{
end_options + = 2 ; // Get past the "--"
if ( : : isspace ( end_options [ 0 ] ) )
{
expr = end_options ;
while ( : : isspace ( * expr ) )
+ + expr ;
break ;
}
}
s = end_options ;
}
if ( end_options )
{
2010-06-23 01:19:29 +00:00
Args args ( command , end_options - command ) ;
if ( ! ParseOptions ( interpreter , args , result ) )
2010-06-08 16:52:24 +00:00
return false ;
}
}
if ( expr = = NULL )
expr = command ;
2010-06-24 00:16:27 +00:00
2010-08-13 00:42:30 +00:00
if ( EvaluateExpression ( expr , false , result . GetOutputStream ( ) , result . GetErrorStream ( ) , & result ) )
return true ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2010-06-08 16:52:24 +00:00
}
lldb : : OptionDefinition
CommandObjectExpression : : CommandOptions : : g_option_table [ ] =
{
2010-09-07 22:38:08 +00:00
//{ LLDB_OPT_SET_ALL, false, "language", 'l', required_argument, NULL, 0, "[c|c++|objc|objc++]", "Sets the language to use when parsing the expression."},
2010-06-23 23:18:04 +00:00
{ 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. " } ,
{ LLDB_OPT_SET_ALL , false , " debug " , ' g ' , no_argument , NULL , 0 , NULL , " Enable verbose debug logging of the expression parsing and evaluation. " } ,
{ LLDB_OPT_SET_ALL , false , " use-ir " , ' i ' , no_argument , NULL , 0 , NULL , " [Temporary] Instructs the expression evaluator to use IR instead of ASTs. " } ,
2010-06-08 16:52:24 +00:00
{ 0 , false , NULL , 0 , 0 , NULL , NULL , NULL , NULL }
} ;