diff options
| author | Jim Ingham <jingham@apple.com> | 2011-04-16 00:01:13 +0000 |
|---|---|---|
| committer | Jim Ingham <jingham@apple.com> | 2011-04-16 00:01:13 +0000 |
| commit | 78a685aa2d8bbf48f25f2f93d4c0a74652eb0e9b (patch) | |
| tree | bccc15a9b0e04bef29c0d2ceeb85a3c355dc9586 /lldb/source/Target | |
| parent | f46b33852c0294f1dba3303c6810902212fe749d (diff) | |
| download | bcm5719-llvm-78a685aa2d8bbf48f25f2f93d4c0a74652eb0e9b.tar.gz bcm5719-llvm-78a685aa2d8bbf48f25f2f93d4c0a74652eb0e9b.zip | |
Add support for "dynamic values" for C++ classes. This currently only works for "frame var" and for the
expressions that are simple enough to get passed to the "frame var" underpinnings. The parser code will
have to be changed to also query for the dynamic types & offsets as it is looking up variables.
The behavior of "frame var" is controlled in two ways. You can pass "-d {true/false} to the frame var
command to get the dynamic or static value of the variables you are printing.
There's also a general setting:
target.prefer-dynamic-value (boolean) = 'true'
which is consulted if you call "frame var" without supplying a value for the -d option.
llvm-svn: 129623
Diffstat (limited to 'lldb/source/Target')
| -rw-r--r-- | lldb/source/Target/Process.cpp | 8 | ||||
| -rw-r--r-- | lldb/source/Target/StackFrame.cpp | 37 | ||||
| -rw-r--r-- | lldb/source/Target/Target.cpp | 73 | ||||
| -rw-r--r-- | lldb/source/Target/ThreadPlanTestCondition.cpp | 4 |
4 files changed, 105 insertions, 17 deletions
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 26d84b968dc..a492e47642d 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -1902,6 +1902,12 @@ Process::WriteMemory (addr_t addr, const void *buf, size_t size, Error &error) if (buf == NULL || size == 0) return 0; + + // Need to bump the stop ID after writing so that ValueObjects will know to re-read themselves. + // FUTURE: Doing this should be okay, but if anybody else gets upset about the stop_id changing when + // the target hasn't run, then we will need to add a "memory generation" as well as a stop_id... + m_stop_id++; + // We need to write any data that would go where any current software traps // (enabled software breakpoints) any software traps (breakpoints) that we // may have placed in our tasks memory. @@ -1962,7 +1968,7 @@ Process::WriteMemory (addr_t addr, const void *buf, size_t size, Error &error) ubuf + bytes_written, size - bytes_written, error); - + return bytes_written; } diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index 0d0c0e8ec61..a5df9284b55 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -493,6 +493,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, uint32 { const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0; const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0; + const bool dynamic_value = (options & eExpressionPathOptionsDynamicValue) != 0; error.Clear(); bool deref = false; bool address_of = false; @@ -528,8 +529,10 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, uint32 VariableSP var_sp (variable_list->FindVariable(name_const_string)); if (var_sp) { - valobj_sp = GetValueObjectForFrameVariable (var_sp); - + valobj_sp = GetValueObjectForFrameVariable (var_sp, dynamic_value); + if (!valobj_sp) + return valobj_sp; + var_path.erase (0, name_const_string.GetLength ()); // We are dumping at least one child while (separator_idx != std::string::npos) @@ -600,7 +603,6 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, uint32 return ValueObjectSP(); } } - child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); if (!child_valobj_sp) { @@ -624,6 +626,12 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, uint32 } // Remove the child name from the path var_path.erase(0, child_name.GetLength()); + if (dynamic_value) + { + ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(true, child_valobj_sp)); + if (dynamic_value_sp) + child_valobj_sp = dynamic_value_sp; + } } break; @@ -650,6 +658,8 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, uint32 } else if (ClangASTContext::IsArrayType (valobj_sp->GetClangType(), NULL, NULL)) { + // Pass false to dynamic_value here so we can tell the difference between + // no dynamic value and no member of this type... child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); if (!child_valobj_sp) { @@ -678,7 +688,12 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, uint32 // %i is the array index var_path.erase(0, (end - var_path.c_str()) + 1); separator_idx = var_path.find_first_of(".-["); - + if (dynamic_value) + { + ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(true, child_valobj_sp)); + if (dynamic_value_sp) + child_valobj_sp = dynamic_value_sp; + } // Break out early from the switch since we were // able to find the child member break; @@ -794,7 +809,7 @@ StackFrame::HasDebugInformation () ValueObjectSP -StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp) +StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, bool use_dynamic) { ValueObjectSP valobj_sp; VariableList *var_list = GetVariableList (true); @@ -815,14 +830,20 @@ StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp) } } } + if (use_dynamic && valobj_sp) + { + ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (true, valobj_sp); + if (dynamic_sp) + return dynamic_sp; + } return valobj_sp; } ValueObjectSP -StackFrame::TrackGlobalVariable (const VariableSP &variable_sp) +StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, bool use_dynamic) { // Check to make sure we aren't already tracking this variable? - ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp)); + ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic)); if (!valobj_sp) { // We aren't already tracking this global @@ -835,7 +856,7 @@ StackFrame::TrackGlobalVariable (const VariableSP &variable_sp) m_variable_list_sp->AddVariable (variable_sp); // Now make a value object for it so we can track its changes - valobj_sp = GetValueObjectForFrameVariable (variable_sp); + valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic); } return valobj_sp; } diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 2ade9e66142..d08a0fe2bd1 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -887,6 +887,7 @@ Target::EvaluateExpression StackFrame *frame, bool unwind_on_error, bool keep_in_memory, + bool fetch_dynamic_value, lldb::ValueObjectSP &result_valobj_sp ) { @@ -927,7 +928,16 @@ Target::EvaluateExpression const_valobj_sp->SetName (persistent_variable_name); } else + { + if (fetch_dynamic_value) + { + ValueObjectSP dynamic_sp = result_valobj_sp->GetDynamicValue(true, result_valobj_sp); + if (dynamic_sp) + result_valobj_sp = dynamic_sp; + } + const_valobj_sp = result_valobj_sp->CreateConstantValue (persistent_variable_name); + } lldb::ValueObjectSP live_valobj_sp = result_valobj_sp; @@ -1277,11 +1287,12 @@ Target::SettingsController::CreateInstanceSettings (const char *instance_name) } -#define TSC_DEFAULT_ARCH "default-arch" -#define TSC_EXPR_PREFIX "expr-prefix" -#define TSC_EXEC_LEVEL "execution-level" -#define TSC_EXEC_MODE "execution-mode" -#define TSC_EXEC_OS_TYPE "execution-os-type" +#define TSC_DEFAULT_ARCH "default-arch" +#define TSC_EXPR_PREFIX "expr-prefix" +#define TSC_EXEC_LEVEL "execution-level" +#define TSC_EXEC_MODE "execution-mode" +#define TSC_EXEC_OS_TYPE "execution-os-type" +#define TSC_PREFER_DYNAMIC "prefer-dynamic-value" static const ConstString & @@ -1320,6 +1331,13 @@ GetSettingNameForExecutionOSType () return g_const_string; } +static const ConstString & +GetSettingNameForPreferDynamicValue () +{ + static ConstString g_const_string (TSC_PREFER_DYNAMIC); + return g_const_string; +} + bool Target::SettingsController::SetGlobalVariable (const ConstString &var_name, @@ -1369,7 +1387,8 @@ TargetInstanceSettings::TargetInstanceSettings ) : InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance), m_expr_prefix_path (), - m_expr_prefix_contents () + m_expr_prefix_contents (), + m_prefer_dynamic_value (true) { // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called // until the vtables for TargetInstanceSettings are properly set up, i.e. AFTER all the initializers. @@ -1467,6 +1486,39 @@ TargetInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_n return; } } + else if (var_name == GetSettingNameForPreferDynamicValue()) + { + switch (op) + { + default: + err.SetErrorToGenericError (); + err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); + return; + case eVarSetOperationAssign: + { + bool success; + bool result = Args::StringToBoolean(value, false, &success); + + if (success) + { + m_prefer_dynamic_value = result; + } + else + { + err.SetErrorStringWithFormat ("Bad value \"%s\" for %s, should be Boolean.", + value, + GetSettingNameForPreferDynamicValue().AsCString()); + } + return; + } + case eVarSetOperationClear: + m_prefer_dynamic_value = true; + case eVarSetOperationAppend: + err.SetErrorToGenericError (); + err.SetErrorString ("Cannot append to a bool.\n"); + return; + } + } } void @@ -1479,6 +1531,7 @@ TargetInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &ne m_expr_prefix_path = new_settings_ptr->m_expr_prefix_path; m_expr_prefix_contents = new_settings_ptr->m_expr_prefix_contents; + m_prefer_dynamic_value = new_settings_ptr->m_prefer_dynamic_value; } bool @@ -1491,6 +1544,13 @@ TargetInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, { value.AppendString (m_expr_prefix_path.c_str(), m_expr_prefix_path.size()); } + else if (var_name == GetSettingNameForPreferDynamicValue()) + { + if (m_prefer_dynamic_value) + value.AppendString ("true"); + else + value.AppendString ("false"); + } else { if (err) @@ -1533,5 +1593,6 @@ Target::SettingsController::instance_settings_table[] = // var-name var-type default enum init'd hidden help-text // ================= ================== =========== ==== ====== ====== ========================================================================= { TSC_EXPR_PREFIX , eSetVarTypeString , NULL , NULL, false, false, "Path to a file containing expressions to be prepended to all expressions." }, + { TSC_PREFER_DYNAMIC, eSetVarTypeBoolean ,"true" , NULL, false, false, "Should printed values be shown as their dynamic value." }, { NULL , eSetVarTypeNone , NULL , NULL, false, false, NULL } }; diff --git a/lldb/source/Target/ThreadPlanTestCondition.cpp b/lldb/source/Target/ThreadPlanTestCondition.cpp index 9facfdcb95c..1349e9eb649 100644 --- a/lldb/source/Target/ThreadPlanTestCondition.cpp +++ b/lldb/source/Target/ThreadPlanTestCondition.cpp @@ -84,8 +84,8 @@ ThreadPlanTestCondition::ShouldStop (Event *event_ptr) if (result_sp) { // FIXME: This is not the right answer, we should have a "GetValueAsBoolean..." - Scalar scalar_value = result_sp->GetValue().ResolveValue (&m_exe_ctx, result_sp->GetClangAST()); - if (scalar_value.IsValid()) + Scalar scalar_value; + if (result_sp->ResolveValue (scalar_value)) { if (scalar_value.ULongLong(1) == 0) m_did_stop = false; |

