summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2011-04-16 00:01:13 +0000
committerJim Ingham <jingham@apple.com>2011-04-16 00:01:13 +0000
commit78a685aa2d8bbf48f25f2f93d4c0a74652eb0e9b (patch)
treebccc15a9b0e04bef29c0d2ceeb85a3c355dc9586 /lldb/source/Target
parentf46b33852c0294f1dba3303c6810902212fe749d (diff)
downloadbcm5719-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.cpp8
-rw-r--r--lldb/source/Target/StackFrame.cpp37
-rw-r--r--lldb/source/Target/Target.cpp73
-rw-r--r--lldb/source/Target/ThreadPlanTestCondition.cpp4
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;
OpenPOWER on IntegriCloud