Implementing an Options class for EvaluateExpression() in order to make the signature more compact and make it easy to 'just run an expression'

llvm-svn: 163239
This commit is contained in:
Enrico Granata 2012-09-05 20:41:26 +00:00
parent d0855e180d
commit d4439aa9ed
8 changed files with 161 additions and 73 deletions

View File

@ -760,6 +760,105 @@ public:
ClangASTImporter * ClangASTImporter *
GetClangASTImporter(); GetClangASTImporter();
class EvaluateExpressionOptions
{
public:
EvaluateExpressionOptions() :
m_execution_policy(eExecutionPolicyOnlyWhenNeeded),
m_coerce_to_id(false),
m_unwind_on_error(true),
m_keep_in_memory(false),
m_use_dynamic(lldb::eNoDynamicValues),
m_single_thread_timeout_usec(500000)
{}
ExecutionPolicy
GetExecutionPolicy () const
{
return m_execution_policy;
}
EvaluateExpressionOptions&
SetExecutionPolicy (ExecutionPolicy policy = eExecutionPolicyAlways)
{
m_execution_policy = policy;
return *this;
}
bool
DoesCoerceToId () const
{
return m_coerce_to_id;
}
EvaluateExpressionOptions&
SetCoerceToId (bool coerce = true)
{
m_coerce_to_id = coerce;
return *this;
}
bool
DoesUnwindOnError () const
{
return m_unwind_on_error;
}
EvaluateExpressionOptions&
SetUnwindOnError (bool unwind = false)
{
m_unwind_on_error = unwind;
return *this;
}
bool
DoesKeepInMemory () const
{
return m_keep_in_memory;
}
EvaluateExpressionOptions&
SetKeepInMemory (bool keep = true)
{
m_keep_in_memory = keep;
return *this;
}
lldb::DynamicValueType
GetUseDynamic () const
{
return m_use_dynamic;
}
EvaluateExpressionOptions&
SetUseDynamic (lldb::DynamicValueType dynamic = lldb::eDynamicCanRunTarget)
{
m_use_dynamic = dynamic;
return *this;
}
uint32_t
GetSingleThreadTimeoutUsec () const
{
return m_single_thread_timeout_usec;
}
EvaluateExpressionOptions&
SetSingleThreadTimeoutUsec (uint32_t timeout = 0)
{
m_single_thread_timeout_usec = timeout;
return *this;
}
private:
ExecutionPolicy m_execution_policy;
bool m_coerce_to_id;
bool m_unwind_on_error;
bool m_keep_in_memory;
lldb::DynamicValueType m_use_dynamic;
uint32_t m_single_thread_timeout_usec;
};
// Since expressions results can persist beyond the lifetime of a process, // Since expressions results can persist beyond the lifetime of a process,
// and the const expression results are available after a process is gone, // and the const expression results are available after a process is gone,
// we provide a way for expressions to be evaluated from the Target itself. // we provide a way for expressions to be evaluated from the Target itself.
@ -768,13 +867,8 @@ public:
ExecutionResults ExecutionResults
EvaluateExpression (const char *expression, EvaluateExpression (const char *expression,
StackFrame *frame, StackFrame *frame,
lldb_private::ExecutionPolicy execution_policy,
bool coerce_to_id,
bool unwind_on_error,
bool keep_in_memory,
lldb::DynamicValueType use_dynamic,
lldb::ValueObjectSP &result_valobj_sp, lldb::ValueObjectSP &result_valobj_sp,
uint32_t single_thread_timeout_usec = 500000); const EvaluateExpressionOptions& options = EvaluateExpressionOptions());
ClangPersistentVariables & ClangPersistentVariables &
GetPersistentVariables() GetPersistentVariables()

View File

@ -1082,17 +1082,14 @@ SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dyna
Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s", Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
expr, fetch_dynamic_value, frame_description.GetString().c_str()); expr, fetch_dynamic_value, frame_description.GetString().c_str());
#endif #endif
const bool coerce_to_id = false; Target::EvaluateExpressionOptions options;
const bool keep_in_memory = false; options.SetUnwindOnError(unwind_on_error)
.SetUseDynamic(fetch_dynamic_value);
exe_results = target->EvaluateExpression (expr, exe_results = target->EvaluateExpression (expr,
frame, frame,
eExecutionPolicyOnlyWhenNeeded, expr_value_sp,
coerce_to_id, options);
unwind_on_error,
keep_in_memory,
fetch_dynamic_value,
expr_value_sp);
expr_result.SetSP(expr_value_sp); expr_result.SetSP(expr_value_sp);
#ifdef LLDB_CONFIGURATION_DEBUG #ifdef LLDB_CONFIGURATION_DEBUG
Host::SetCrashDescription (NULL); Host::SetCrashDescription (NULL);

View File

@ -732,14 +732,12 @@ SBValue::CreateValueFromExpression (const char *name, const char* expression)
Target* target = exe_ctx.GetTargetPtr(); Target* target = exe_ctx.GetTargetPtr();
if (target) if (target)
{ {
Target::EvaluateExpressionOptions options;
options.SetKeepInMemory(true);
target->EvaluateExpression (expression, target->EvaluateExpression (expression,
exe_ctx.GetFramePtr(), exe_ctx.GetFramePtr(),
eExecutionPolicyOnlyWhenNeeded, new_value_sp,
false, // coerce to id options);
true, // unwind on error
true, // keep in memory
eNoDynamicValues,
new_value_sp);
if (new_value_sp) if (new_value_sp)
{ {
new_value_sp->SetName(ConstString(name)); new_value_sp->SetName(ConstString(name));

View File

@ -298,15 +298,17 @@ CommandObjectExpression::EvaluateExpression
break; break;
} }
Target::EvaluateExpressionOptions options;
options.SetCoerceToId(m_command_options.print_object)
.SetUnwindOnError(m_command_options.unwind_on_error)
.SetKeepInMemory(keep_in_memory)
.SetUseDynamic(use_dynamic)
.SetSingleThreadTimeoutUsec(0);
exe_results = target->EvaluateExpression (expr, exe_results = target->EvaluateExpression (expr,
m_interpreter.GetExecutionContext().GetFramePtr(), m_interpreter.GetExecutionContext().GetFramePtr(),
eExecutionPolicyOnlyWhenNeeded,
m_command_options.print_object,
m_command_options.unwind_on_error,
keep_in_memory,
use_dynamic,
result_valobj_sp, result_valobj_sp,
0 /* no timeout */); options);
if (exe_results == eExecutionInterrupted && !m_command_options.unwind_on_error) if (exe_results == eExecutionInterrupted && !m_command_options.unwind_on_error)
{ {

View File

@ -1201,18 +1201,16 @@ protected:
} }
// Use expression evaluation to arrive at the address to watch. // Use expression evaluation to arrive at the address to watch.
const bool coerce_to_id = true; Target::EvaluateExpressionOptions options;
const bool unwind_on_error = true; options.SetCoerceToId(false)
const bool keep_in_memory = false; .SetUnwindOnError(true)
.SetKeepInMemory(false)
.SetSingleThreadTimeoutUsec(0);
ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(), ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
frame, frame,
eExecutionPolicyOnlyWhenNeeded,
coerce_to_id,
unwind_on_error,
keep_in_memory,
eNoDynamicValues,
valobj_sp, valobj_sp,
0 /* no timeout */); options);
if (expr_result != eExecutionCompleted) { if (expr_result != eExecutionCompleted) {
result.GetErrorStream().Printf("error: expression evaluation of address to watch failed\n"); result.GetErrorStream().Printf("error: expression evaluation of address to watch failed\n");
result.GetErrorStream().Printf("expression evaluated: %s\n", expr_str.c_str()); result.GetErrorStream().Printf("expression evaluated: %s\n", expr_str.c_str());

View File

@ -42,14 +42,17 @@ lldb_private::formatters::CodeRunning_Fetcher (ValueObject &valobj,
StackFrame* stack_frame = exe_ctx.GetFramePtr(); StackFrame* stack_frame = exe_ctx.GetFramePtr();
if (!target || !stack_frame) if (!target || !stack_frame)
return false; return false;
Target::EvaluateExpressionOptions options;
options.SetCoerceToId(false)
.SetUnwindOnError(true)
.SetKeepInMemory(true)
.SetUseDynamic(lldb::eDynamicCanRunTarget);
target->EvaluateExpression(expr.GetData(), target->EvaluateExpression(expr.GetData(),
stack_frame, stack_frame,
eExecutionPolicyOnlyWhenNeeded, result_sp,
false, options);
true,
true,
lldb::eDynamicCanRunTarget,
result_sp);
if (!result_sp) if (!result_sp)
return false; return false;
value = result_sp->GetValueAsUnsigned(0); value = result_sp->GetValueAsUnsigned(0);
@ -364,14 +367,17 @@ lldb_private::formatters::NSNumber_SummaryProvider (ValueObject& valobj, Stream&
StackFrame* stack_frame = exe_ctx.GetFramePtr(); StackFrame* stack_frame = exe_ctx.GetFramePtr();
if (!target || !stack_frame) if (!target || !stack_frame)
return false; return false;
Target::EvaluateExpressionOptions options;
options.SetCoerceToId(false)
.SetUnwindOnError(true)
.SetKeepInMemory(true)
.SetUseDynamic(lldb::eDynamicCanRunTarget);
target->EvaluateExpression(expr.GetData(), target->EvaluateExpression(expr.GetData(),
stack_frame, stack_frame,
eExecutionPolicyOnlyWhenNeeded, result_sp,
false, options);
true,
true,
lldb::eDynamicCanRunTarget,
result_sp);
if (!result_sp) if (!result_sp)
return false; return false;
stream.Printf("%s",result_sp->GetSummaryAsCString()); stream.Printf("%s",result_sp->GetSummaryAsCString());

View File

@ -1193,19 +1193,19 @@ CommandInterpreter::PreprocessCommand (std::string &command)
target = Host::GetDummyTarget(GetDebugger()).get(); target = Host::GetDummyTarget(GetDebugger()).get();
if (target) if (target)
{ {
const bool coerce_to_id = false;
const bool unwind_on_error = true;
const bool keep_in_memory = false;
ValueObjectSP expr_result_valobj_sp; ValueObjectSP expr_result_valobj_sp;
Target::EvaluateExpressionOptions options;
options.SetCoerceToId(false)
.SetUnwindOnError(true)
.SetKeepInMemory(false)
.SetSingleThreadTimeoutUsec(0);
ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(), ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
exe_ctx.GetFramePtr(), exe_ctx.GetFramePtr(),
eExecutionPolicyOnlyWhenNeeded,
coerce_to_id,
unwind_on_error,
keep_in_memory,
eNoDynamicValues,
expr_result_valobj_sp, expr_result_valobj_sp,
0 /* no timeout */); options);
if (expr_result == eExecutionCompleted) if (expr_result == eExecutionCompleted)
{ {
Scalar scalar; Scalar scalar;

View File

@ -1606,19 +1606,12 @@ Target::EvaluateExpression
( (
const char *expr_cstr, const char *expr_cstr,
StackFrame *frame, StackFrame *frame,
lldb_private::ExecutionPolicy execution_policy,
bool coerce_to_id,
bool unwind_on_error,
bool keep_in_memory,
lldb::DynamicValueType use_dynamic,
lldb::ValueObjectSP &result_valobj_sp, lldb::ValueObjectSP &result_valobj_sp,
uint32_t single_thread_timeout_usec const EvaluateExpressionOptions& options
) )
{ {
ExecutionResults execution_results = eExecutionSetupError; ExecutionResults execution_results = eExecutionSetupError;
result_valobj_sp.reset();
if (expr_cstr == NULL || expr_cstr[0] == '\0') if (expr_cstr == NULL || expr_cstr[0] == '\0')
return execution_results; return execution_results;
@ -1645,7 +1638,7 @@ Target::EvaluateExpression
if (::strcspn (expr_cstr, "()+*&|!~<=/^%,?") == expr_cstr_len) if (::strcspn (expr_cstr, "()+*&|!~<=/^%,?") == expr_cstr_len)
{ {
result_valobj_sp = frame->GetValueForVariableExpressionPath (expr_cstr, result_valobj_sp = frame->GetValueForVariableExpressionPath (expr_cstr,
use_dynamic, options.GetUseDynamic(),
expr_path_options, expr_path_options,
var_sp, var_sp,
error); error);
@ -1679,9 +1672,9 @@ Target::EvaluateExpression
} }
else else
{ {
if (use_dynamic != lldb::eNoDynamicValues) if (options.GetUseDynamic() != lldb::eNoDynamicValues)
{ {
ValueObjectSP dynamic_sp = result_valobj_sp->GetDynamicValue(use_dynamic); ValueObjectSP dynamic_sp = result_valobj_sp->GetDynamicValue(options.GetUseDynamic());
if (dynamic_sp) if (dynamic_sp)
result_valobj_sp = dynamic_sp; result_valobj_sp = dynamic_sp;
} }
@ -1735,14 +1728,14 @@ Target::EvaluateExpression
const char *prefix = GetExpressionPrefixContentsAsCString(); const char *prefix = GetExpressionPrefixContentsAsCString();
execution_results = ClangUserExpression::Evaluate (exe_ctx, execution_results = ClangUserExpression::Evaluate (exe_ctx,
execution_policy, options.GetExecutionPolicy(),
lldb::eLanguageTypeUnknown, lldb::eLanguageTypeUnknown,
coerce_to_id ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny, options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny,
unwind_on_error, options.DoesUnwindOnError(),
expr_cstr, expr_cstr,
prefix, prefix,
result_valobj_sp, result_valobj_sp,
single_thread_timeout_usec); options.GetSingleThreadTimeoutUsec());
} }
} }