diff options
Diffstat (limited to 'lldb/source')
| -rw-r--r-- | lldb/source/API/SBTarget.cpp | 3 | ||||
| -rw-r--r-- | lldb/source/Commands/CommandObjectFrame.cpp | 187 | ||||
| -rw-r--r-- | lldb/source/Core/ValueObject.cpp | 101 | ||||
| -rw-r--r-- | lldb/source/Symbol/ClangASTContext.cpp | 68 | ||||
| -rw-r--r-- | lldb/source/Target/StackFrame.cpp | 310 | ||||
| -rw-r--r-- | lldb/source/Target/Target.cpp | 4 |
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) { |

