summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBTarget.cpp3
-rw-r--r--lldb/source/Commands/CommandObjectFrame.cpp187
-rw-r--r--lldb/source/Core/ValueObject.cpp101
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp68
-rw-r--r--lldb/source/Target/StackFrame.cpp310
-rw-r--r--lldb/source/Target/Target.cpp4
6 files changed, 313 insertions, 360 deletions
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index cae72479c7b..039c0ecdd51 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -50,7 +50,8 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// SBTarget constructor
//----------------------------------------------------------------------
-SBTarget::SBTarget ()
+SBTarget::SBTarget () :
+ m_opaque_sp ()
{
}
diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index 1fecc88947e..2960362df4a 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -586,175 +586,36 @@ public:
}
else
{
- bool address_of = false;
- // If first character is a '*', then show pointer contents
- if (name_cstr[0] == '*')
+ Error error;
+ const bool check_ptr_vs_member = true;
+ valobj_sp = exe_ctx.frame->GetValueForVariableExpressionPath (name_cstr, check_ptr_vs_member, error);
+ if (valobj_sp)
{
- ++ptr_depth;
- name_cstr++; // Skip the '*'
- }
- else if (name_cstr[0] == '&')
- {
- address_of = true;
- name_cstr++; // Skip the '&'
- }
-
- std::string var_path (name_cstr);
- 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);
-
- var_sp = variable_list->FindVariable(name_const_string);
- if (var_sp)
- {
- valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp);
-
- var_path.erase (0, name_const_string.GetLength ());
- // We are dumping at least one child
- while (separator_idx != std::string::npos)
+ if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
{
- // 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] != '>')
- {
- result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n",
- var_path.c_str());
- var_path.clear();
- valobj_sp.reset();
- break;
- }
- var_path.erase (0, 1); // Remove the '-'
- // Fall through
- case '.':
- {
- 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)
- {
- result.GetErrorStream().Printf ("error: can't find child of '%s' named '%s'\n",
- valobj_sp->GetName().AsCString(),
- child_name.GetCString());
- var_path.clear();
- valobj_sp.reset();
- break;
- }
- // 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)
- {
- result.GetErrorStream().Printf ("error: invalid array index %u in '%s'\n",
- child_index,
- valobj_sp->GetName().AsCString());
- var_path.clear();
- valobj_sp.reset();
- break;
- }
-
- // 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;
- }
- }
- result.GetErrorStream().Printf ("error: invalid array member specification for '%s' starting at '%s'\n",
- valobj_sp->GetName().AsCString(),
- var_path.c_str());
- var_path.clear();
- valobj_sp.reset();
- break;
-
- break;
-
- default:
- result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n",
- var_path.c_str());
- var_path.clear();
- valobj_sp.reset();
- separator_idx = std::string::npos;
- break;
- }
-
- if (child_valobj_sp)
- valobj_sp = child_valobj_sp;
-
- if (var_path.empty())
- break;
-
- }
-
- if (valobj_sp)
- {
- if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
- {
- var_sp->GetDeclaration ().DumpStopContext (&s, false);
- s.PutCString (": ");
- }
-
-
- if (address_of)
- {
- s.Printf("&%s = %s\n", name_cstr, valobj_sp->GetLocationAsCString (exe_ctx.frame));
- }
- else
- {
- ValueObject::DumpValueObject (result.GetOutputStream(),
- exe_ctx.frame,
- valobj_sp.get(),
- valobj_sp->GetParent() ? name_cstr : NULL,
- ptr_depth,
- 0,
- m_options.max_depth,
- m_options.show_types,
- m_options.show_location,
- m_options.use_objc,
- false,
- m_options.flat_output);
- }
+ var_sp->GetDeclaration ().DumpStopContext (&s, false);
+ s.PutCString (": ");
}
+ ValueObject::DumpValueObject (result.GetOutputStream(),
+ exe_ctx.frame,
+ valobj_sp.get(),
+ valobj_sp->GetParent() ? name_cstr : NULL,
+ ptr_depth,
+ 0,
+ m_options.max_depth,
+ m_options.show_types,
+ m_options.show_location,
+ m_options.use_objc,
+ false,
+ m_options.flat_output);
}
else
{
- result.GetErrorStream().Printf ("error: unable to find any variables named '%s'\n", name_cstr);
- var_path.clear();
+ const char *error_cstr = error.AsCString(NULL);
+ if (error_cstr)
+ result.GetErrorStream().Printf("error: %s\n", error_cstr);
+ else
+ result.GetErrorStream().Printf ("error: unable to find any variable expression path that matches '%s'\n", name_cstr);
}
}
}
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 60b1009ad7a..2f82d49bd0b 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -1203,10 +1203,11 @@ ValueObject::CreateConstantValue (ExecutionContextScope *exe_scope, const ConstS
}
lldb::ValueObjectSP
-ValueObject::Dereference (ExecutionContextScope *exe_scope, Error *error_ptr)
+ValueObject::Dereference (ExecutionContextScope *exe_scope, Error &error)
{
lldb::ValueObjectSP valobj_sp;
- if (IsPointerType())
+ const bool is_pointer_type = IsPointerType();
+ if (is_pointer_type)
{
bool omit_empty_base_classes = true;
@@ -1249,98 +1250,46 @@ ValueObject::Dereference (ExecutionContextScope *exe_scope, Error *error_ptr)
child_is_base_class));
}
}
+
+ if (valobj_sp)
+ {
+ error.Clear();
+ }
else
{
- if (error_ptr)
- error_ptr->SetErrorString("can't dereference a non-pointer value");
+ StreamString strm;
+ GetExpressionPath(strm);
+
+ if (is_pointer_type)
+ error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
+ else
+ error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
}
return valobj_sp;
}
-
-
-//lldb::ValueObjectSP
-//ValueObject::Dereference (ExecutionContextScope *exe_scope, Error *error_ptr)
-//{
-// lldb::ValueObjectSP valobj_sp;
-// if (IsPointerType())
-// {
-// UpdateValueIfNeeded(exe_scope);
-// if (m_error.Success())
-// {
-// lldb::AddressType address_type = eAddressTypeInvalid;
-// const bool scalar_is_load_address = true;
-// lldb::addr_t addr = GetPointerValue (address_type, scalar_is_load_address);
-// if (addr != LLDB_INVALID_ADDRESS)
-// {
-// switch (address_type)
-// {
-// case eAddressTypeInvalid:
-// if (error_ptr)
-// error_ptr->SetErrorString("value is not in memory");
-// break;
-// case eAddressTypeFile:
-// case eAddressTypeLoad:
-// case eAddressTypeHost:
-// {
-// clang::ASTContext *ast = GetClangAST();
-// clang_type_t clang_type = ClangASTType::GetPointeeType (GetClangType());
-// if (ast && clang_type)
-// {
-// std::string name (1, '*');
-// name.append (m_name.AsCString(""));
-// valobj_sp.reset (new ValueObjectConstResult (ast,
-// ClangASTContext::CreatePointerType (ast, clang_type),
-// ConstString (name.c_str()),
-// addr,
-// address_type,
-// m_data.GetAddressByteSize()));
-// }
-// else
-// {
-// if (error_ptr)
-// error_ptr->SetErrorString("invalid clang type info");
-// }
-// }
-// break;
-// }
-// }
-// else
-// {
-// if (error_ptr)
-// error_ptr->SetErrorString("failed to extract pointer value");
-// }
-// }
-// else
-// {
-// if (error_ptr)
-// *error_ptr = m_error;
-// }
-// }
-// else
-// {
-// if (error_ptr)
-// error_ptr->SetErrorString("can't dereference a non-pointer value");
-// }
-//
-// return valobj_sp;
-//}
-
-lldb::ValueObjectSP
-ValueObject::AddressOf ()
+ lldb::ValueObjectSP
+ValueObject::AddressOf (Error &error)
{
lldb::ValueObjectSP valobj_sp;
-
lldb::AddressType address_type = eAddressTypeInvalid;
const bool scalar_is_load_address = false;
lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address);
+ error.Clear();
if (addr != LLDB_INVALID_ADDRESS)
{
switch (address_type)
{
+ default:
case eAddressTypeInvalid:
+ {
+ StreamString expr_path_strm;
+ GetExpressionPath(expr_path_strm);
+ error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
+ }
break;
+
case eAddressTypeFile:
case eAddressTypeLoad:
case eAddressTypeHost:
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index cd725cac8aa..05643e63fc5 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -1901,7 +1901,10 @@ ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_b
break;
}
break;
-
+
+ case clang::Type::Complex:
+ return 2;
+
case clang::Type::Record:
if (ClangASTType::IsDefined (clang_qual_type))
{
@@ -1995,12 +1998,15 @@ ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_b
case clang::Type::Pointer:
{
PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
- QualType pointee_type = pointer_type->getPointeeType();
+ QualType pointee_type (pointer_type->getPointeeType());
uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
omit_empty_base_classes);
- // If this type points to a simple type, then it has 1 child
if (num_pointee_children == 0)
- num_children = 1;
+ {
+ // We have a pointer to a pointee type that claims it has no children.
+ // We will want to look at
+ num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
+ }
else
num_children = num_pointee_children;
}
@@ -2032,6 +2038,60 @@ ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_b
return num_children;
}
+// If a pointer to a pointee type (the clang_type arg) says that it has no
+// children, then we either need to trust it, or override it and return a
+// different result. For example, an "int *" has one child that is an integer,
+// but a function pointer doesn't have any children. Likewise if a Record type
+// claims it has no children, then there really is nothing to show.
+uint32_t
+ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
+{
+ if (clang_type == NULL)
+ return 0;
+
+ QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Builtin: return 1;
+ case clang::Type::Complex: return 2;
+ case clang::Type::Pointer: return 1;
+ case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
+ case clang::Type::LValueReference: return 1;
+ case clang::Type::RValueReference: return 1;
+ case clang::Type::MemberPointer: return 0;
+ case clang::Type::ConstantArray: return 0;
+ case clang::Type::IncompleteArray: return 0;
+ case clang::Type::VariableArray: return 0;
+ case clang::Type::DependentSizedArray: return 0;
+ case clang::Type::DependentSizedExtVector: return 0;
+ case clang::Type::Vector: return 0;
+ case clang::Type::ExtVector: return 0;
+ case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
+ case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
+ case clang::Type::UnresolvedUsing: return 0;
+ case clang::Type::Paren: return 0;
+ case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+ case clang::Type::TypeOfExpr: return 0;
+ case clang::Type::TypeOf: return 0;
+ case clang::Type::Decltype: return 0;
+ case clang::Type::Record: return 0;
+ case clang::Type::Enum: return 1;
+ case clang::Type::Elaborated: return 1;
+ case clang::Type::TemplateTypeParm: return 1;
+ case clang::Type::SubstTemplateTypeParm: return 1;
+ case clang::Type::TemplateSpecialization: return 1;
+ case clang::Type::InjectedClassName: return 0;
+ case clang::Type::DependentName: return 1;
+ case clang::Type::DependentTemplateSpecialization: return 1;
+ case clang::Type::ObjCObject: return 0;
+ case clang::Type::ObjCInterface: return 0;
+ case clang::Type::ObjCObjectPointer: return 1;
+ default:
+ break;
+ }
+ return 0;
+}
clang_type_t
ClangASTContext::GetChildClangTypeAtIndex
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 20946532188..341954f2a11 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -18,6 +18,7 @@
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
@@ -479,156 +480,235 @@ StackFrame::GetVariableList (bool get_file_globals)
}
ValueObjectSP
-StackFrame::GetValueForVariableExpressionPath (const char *var_expr)
+StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, bool check_ptr_vs_member, Error &error)
{
- 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 (var_expr_cstr && var_expr_cstr[0])
{
- // If first character is a '*', then show pointer contents
- if (var_expr[0] == '*')
- {
- deref = true;
- var_expr++; // Skip the '*'
- }
- else if (var_expr[0] == '&')
+ error.Clear();
+ 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)
{
- address_of = true;
- var_expr++; // Skip the '&'
- }
-
- std::string var_path (var_expr);
- size_t separator_idx = var_path.find_first_of(".-[");
+ // If first character is a '*', then show pointer contents
+ const char *var_expr = var_expr_cstr;
+ if (var_expr[0] == '*')
+ {
+ deref = true;
+ var_expr++; // Skip the '*'
+ }
+ else if (var_expr[0] == '&')
+ {
+ address_of = true;
+ var_expr++; // Skip the '&'
+ }
- 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);
+ std::string var_path (var_expr);
+ size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}");
+ StreamString var_expr_path_strm;
- VariableSP var_sp (variable_list->FindVariable(name_const_string));
- if (var_sp)
- {
- valobj_sp = GetValueObjectForFrameVariable (var_sp);
+ 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);
- var_path.erase (0, name_const_string.GetLength ());
- // We are dumping at least one child
- while (separator_idx != std::string::npos)
+ VariableSP var_sp (variable_list->FindVariable(name_const_string));
+ if (var_sp)
{
- // 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();
+ valobj_sp = GetValueObjectForFrameVariable (var_sp);
- var_path.erase (0, 1); // Remove the '-'
- // Fall through
- case '.':
+ 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)
{
- // 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"
+ case '-':
+ if (var_path.size() >= 2 && var_path[1] != '>')
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 == ']')
+ var_path.erase (0, 1); // Remove the '-'
+ // Fall through
+ case '.':
{
+ const bool expr_is_ptr = var_path[0] == '>';
- if (valobj_sp->IsPointerType ())
- {
- child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
- }
+ 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);
+
+ if (check_ptr_vs_member)
{
- child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
+ // 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 actual_is_ptr = valobj_sp->IsPointerType ();
+
+ if (actual_is_ptr != expr_is_ptr)
+ {
+ // Incorrect use of "." with a pointer, or "->" with
+ // a class/union/struct instance or reference.
+ valobj_sp->GetExpressionPath (var_expr_path_strm);
+ if (actual_is_ptr)
+ error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?",
+ var_expr_path_strm.GetString().c_str(),
+ child_name.GetCString(),
+ var_expr_path_strm.GetString().c_str(),
+ var_path.c_str());
+ else
+ error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?",
+ var_expr_path_strm.GetString().c_str(),
+ child_name.GetCString(),
+ var_expr_path_strm.GetString().c_str(),
+ var_path.c_str());
+ return ValueObjectSP();
+ }
}
+ child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
if (!child_valobj_sp)
{
- // Invalid array index...
+ // No child member with name "child_name"
+ valobj_sp->GetExpressionPath (var_expr_path_strm);
+ if (child_name)
+ {
+ error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"",
+ child_name.GetCString(),
+ valobj_sp->GetTypeName().AsCString("<invalid type>"),
+ var_expr_path_strm.GetString().c_str());
+ }
+ else
+ {
+ error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"",
+ var_expr_path_strm.GetString().c_str(),
+ var_expr_cstr);
+ }
+
return ValueObjectSP();
}
+ // Remove the child name from the path
+ var_path.erase(0, child_name.GetLength());
+ }
+ break;
- // 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(".-[");
+ 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 == ']')
+ {
- // Break out early from the switch since we were
- // able to find the child member
- break;
+ if (valobj_sp->IsPointerType ())
+ {
+ child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
+ if (!child_valobj_sp)
+ {
+ valobj_sp->GetExpressionPath (var_expr_path_strm);
+ error.SetErrorStringWithFormat ("failed to use pointer as array for index %i for \"(%s) %s\"",
+ child_index,
+ valobj_sp->GetTypeName().AsCString("<invalid type>"),
+ var_expr_path_strm.GetString().c_str());
+ }
+ }
+ else if (ClangASTContext::IsArrayType (valobj_sp->GetClangType(), NULL, NULL))
+ {
+ child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
+ if (!child_valobj_sp)
+ {
+ valobj_sp->GetExpressionPath (var_expr_path_strm);
+ error.SetErrorStringWithFormat ("array index %i is not valid for \"(%s) %s\"",
+ child_index,
+ valobj_sp->GetTypeName().AsCString("<invalid type>"),
+ var_expr_path_strm.GetString().c_str());
+ }
+ }
+ else
+ {
+ valobj_sp->GetExpressionPath (var_expr_path_strm);
+ error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
+ valobj_sp->GetTypeName().AsCString("<invalid type>"),
+ var_expr_path_strm.GetString().c_str());
+ }
+
+ 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();
+ return ValueObjectSP();
- default:
- // Failure...
- return ValueObjectSP();
- }
+ default:
+ // Failure...
+ {
+ valobj_sp->GetExpressionPath (var_expr_path_strm);
+ error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"",
+ separator_type,
+ var_expr_path_strm.GetString().c_str(),
+ var_path.c_str());
- if (child_valobj_sp)
- valobj_sp = child_valobj_sp;
+ return ValueObjectSP();
+ }
+ }
- if (var_path.empty())
- break;
+ 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)
+ if (valobj_sp)
{
- ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf());
- valobj_sp = address_of_valobj_sp;
+ if (deref)
+ {
+ ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(this, error));
+ valobj_sp = deref_valobj_sp;
+ }
+ else if (address_of)
+ {
+ ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error));
+ valobj_sp = address_of_valobj_sp;
+ }
}
+ return valobj_sp;
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("no variable named '%s' found in this frame", name_const_string.GetCString());
}
- return valobj_sp;
}
}
+ else
+ {
+ error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr);
+ }
return ValueObjectSP();
}
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 8546537b9a1..7990111aa43 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -886,7 +886,9 @@ Target::EvaluateExpression
if (frame)
{
frame->CalculateExecutionContext(exe_ctx);
- result_valobj_sp = frame->GetValueForVariableExpressionPath (expr_cstr);
+ Error error;
+ const bool check_ptr_vs_member = true;
+ result_valobj_sp = frame->GetValueForVariableExpressionPath (expr_cstr, check_ptr_vs_member, error);
}
else if (m_process_sp)
{
OpenPOWER on IntegriCloud