summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/StackFrame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target/StackFrame.cpp')
-rw-r--r--lldb/source/Target/StackFrame.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 7281ba427e4..20946532188 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -478,6 +478,159 @@ StackFrame::GetVariableList (bool get_file_globals)
return m_variable_list_sp.get();
}
+ValueObjectSP
+StackFrame::GetValueForVariableExpressionPath (const char *var_expr)
+{
+ bool deref = false;
+ bool address_of = false;
+ ValueObjectSP valobj_sp;
+ const bool get_file_globals = true;
+ VariableList *variable_list = GetVariableList (get_file_globals);
+
+ if (variable_list)
+ {
+ // If first character is a '*', then show pointer contents
+ if (var_expr[0] == '*')
+ {
+ deref = true;
+ var_expr++; // Skip the '*'
+ }
+ else if (var_expr[0] == '&')
+ {
+ address_of = true;
+ var_expr++; // Skip the '&'
+ }
+
+ std::string var_path (var_expr);
+ size_t separator_idx = var_path.find_first_of(".-[");
+
+ ConstString name_const_string;
+ if (separator_idx == std::string::npos)
+ name_const_string.SetCString (var_path.c_str());
+ else
+ name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
+
+ VariableSP var_sp (variable_list->FindVariable(name_const_string));
+ if (var_sp)
+ {
+ valobj_sp = GetValueObjectForFrameVariable (var_sp);
+
+ var_path.erase (0, name_const_string.GetLength ());
+ // We are dumping at least one child
+ while (separator_idx != std::string::npos)
+ {
+ // Calculate the next separator index ahead of time
+ ValueObjectSP child_valobj_sp;
+ const char separator_type = var_path[0];
+ switch (separator_type)
+ {
+
+ case '-':
+ if (var_path.size() >= 2 && var_path[1] != '>')
+ return ValueObjectSP();
+
+ var_path.erase (0, 1); // Remove the '-'
+ // Fall through
+ case '.':
+ {
+ // We either have a pointer type and need to verify
+ // valobj_sp is a pointer, or we have a member of a
+ // class/union/struct being accessed with the . syntax
+ // and need to verify we don't have a pointer.
+ const bool is_ptr = var_path[0] == '>';
+
+ if (valobj_sp->IsPointerType () != is_ptr)
+ {
+ // Incorrect use of "." with a pointer, or "->" with
+ // a class/union/struct instance or reference.
+ return ValueObjectSP();
+ }
+
+ var_path.erase (0, 1); // Remove the '.' or '>'
+ separator_idx = var_path.find_first_of(".-[");
+ ConstString child_name;
+ if (separator_idx == std::string::npos)
+ child_name.SetCString (var_path.c_str());
+ else
+ child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
+
+ child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
+ if (!child_valobj_sp)
+ {
+ // No child member with name "child_name"
+ return ValueObjectSP();
+ }
+ // Remove the child name from the path
+ var_path.erase(0, child_name.GetLength());
+ }
+ break;
+
+ case '[':
+ // Array member access, or treating pointer as an array
+ if (var_path.size() > 2) // Need at least two brackets and a number
+ {
+ char *end = NULL;
+ int32_t child_index = ::strtol (&var_path[1], &end, 0);
+ if (end && *end == ']')
+ {
+
+ if (valobj_sp->IsPointerType ())
+ {
+ child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
+ }
+ else
+ {
+ child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
+ }
+
+ if (!child_valobj_sp)
+ {
+ // Invalid array index...
+ return ValueObjectSP();
+ }
+
+ // Erase the array member specification '[%i]' where
+ // %i is the array index
+ var_path.erase(0, (end - var_path.c_str()) + 1);
+ separator_idx = var_path.find_first_of(".-[");
+
+ // Break out early from the switch since we were
+ // able to find the child member
+ break;
+ }
+ }
+ return ValueObjectSP();
+
+ default:
+ // Failure...
+ return ValueObjectSP();
+ }
+
+ if (child_valobj_sp)
+ valobj_sp = child_valobj_sp;
+
+ if (var_path.empty())
+ break;
+
+ }
+ if (valobj_sp)
+ {
+ if (deref)
+ {
+ ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(this, NULL));
+ valobj_sp = deref_valobj_sp;
+ }
+ else if (address_of)
+ {
+ ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf());
+ valobj_sp = address_of_valobj_sp;
+ }
+ }
+ return valobj_sp;
+ }
+ }
+ return ValueObjectSP();
+}
bool
StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
OpenPOWER on IntegriCloud