diff options
author | Enrico Granata <granata.enrico@gmail.com> | 2011-08-09 01:04:56 +0000 |
---|---|---|
committer | Enrico Granata <granata.enrico@gmail.com> | 2011-08-09 01:04:56 +0000 |
commit | 27b625e12f25cd9fb3c141a91cd7d40f5fcaf144 (patch) | |
tree | f3c42c5a673bb18f25905c7ee13a533c5ff160f3 /lldb/source/Target/StackFrame.cpp | |
parent | 6c1ed31b3b94f97723ef870c9e633268580b80f3 (diff) | |
download | llvm-27b625e12f25cd9fb3c141a91cd7d40f5fcaf144.zip llvm-27b625e12f25cd9fb3c141a91cd7d40f5fcaf144.tar.gz llvm-27b625e12f25cd9fb3c141a91cd7d40f5fcaf144.tar.bz2 |
Basic support for reading synthetic children by index:
if your datatype provides synthetic children, "frame variable object[index]" should now do the right thing
in cases where the above syntax would have been rejected before, i.e.
object is not a pointer nor an array (frame variable ignores potential overload of [])
object is a pointer to an Objective-C class (which cannot be dereferenced)
expression will still run operator[] if available and complain if it cannot do so
synthetic children by name do not work yet
llvm-svn: 137097
Diffstat (limited to 'lldb/source/Target/StackFrame.cpp')
-rw-r--r-- | lldb/source/Target/StackFrame.cpp | 90 |
1 files changed, 79 insertions, 11 deletions
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index 803e49b..9ce7590 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -525,6 +525,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, { const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0; const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0; + const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0; error.Clear(); bool deref = false; bool address_of = false; @@ -718,14 +719,55 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, if (valobj_sp->IsPointerType ()) { - child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true); - if (!child_valobj_sp) + if (no_synth_child == false + && + ClangASTType::GetMinimumLanguage(valobj_sp->GetClangAST(), + valobj_sp->GetClangType()) == lldb::eLanguageTypeObjC /* is ObjC pointer */ + && + ClangASTContext::IsPointerType(ClangASTType::GetPointeeType(valobj_sp->GetClangType())) == false /* is not double-ptr */) { - valobj_sp->GetExpressionPath (var_expr_path_strm, false); - 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()); + // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children + lldb::ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(lldb::eUseSyntheticFilter); + if (synthetic.get() == NULL /* no synthetic */ + || synthetic == valobj_sp) /* synthetic is the same as the original object */ + { + valobj_sp->GetExpressionPath (var_expr_path_strm, false); + error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", + valobj_sp->GetTypeName().AsCString("<invalid type>"), + var_expr_path_strm.GetString().c_str()); + } + else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */) + { + valobj_sp->GetExpressionPath (var_expr_path_strm, false); + 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 + { + child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); + if (!child_valobj_sp) + { + valobj_sp->GetExpressionPath (var_expr_path_strm, false); + 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 + { + child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true); + if (!child_valobj_sp) + { + valobj_sp->GetExpressionPath (var_expr_path_strm, false); + 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)) @@ -757,10 +799,36 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr, } else { - valobj_sp->GetExpressionPath (var_expr_path_strm, false); - error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", - valobj_sp->GetTypeName().AsCString("<invalid type>"), - var_expr_path_strm.GetString().c_str()); + lldb::ValueObjectSP synthetic = valobj_sp->GetSyntheticValue(lldb::eUseSyntheticFilter); + if (no_synth_child /* synthetic is forbidden */ || + synthetic.get() == NULL /* no synthetic */ + || synthetic == valobj_sp) /* synthetic is the same as the original object */ + { + valobj_sp->GetExpressionPath (var_expr_path_strm, false); + error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type", + valobj_sp->GetTypeName().AsCString("<invalid type>"), + var_expr_path_strm.GetString().c_str()); + } + else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */) + { + valobj_sp->GetExpressionPath (var_expr_path_strm, false); + 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 + { + child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); + if (!child_valobj_sp) + { + valobj_sp->GetExpressionPath (var_expr_path_strm, false); + 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()); + } + } } if (!child_valobj_sp) |