diff options
Diffstat (limited to 'lldb/source/Core/ValueObject.cpp')
-rw-r--r-- | lldb/source/Core/ValueObject.cpp | 230 |
1 files changed, 162 insertions, 68 deletions
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index bd613ba7b2c..c8c5f3362fe 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -42,8 +42,9 @@ static lldb::user_id_t g_value_obj_uid = 0; //---------------------------------------------------------------------- // ValueObject constructor //---------------------------------------------------------------------- -ValueObject::ValueObject () : +ValueObject::ValueObject (ValueObject *parent) : UserID (++g_value_obj_uid), // Unique identifier for every value object + m_parent (parent), m_update_id (0), // Value object lists always start at 1, value objects start at zero m_name (), m_data (), @@ -354,6 +355,7 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3 int32_t child_byte_offset = 0; uint32_t child_bitfield_bit_size = 0; uint32_t child_bitfield_bit_offset = 0; + bool child_is_base_class = false; const bool transparent_pointers = synthetic_array_member == false; clang::ASTContext *clang_ast = GetClangAST(); void *clang_type = GetClangType(); @@ -368,7 +370,8 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3 child_byte_size, child_byte_offset, child_bitfield_bit_size, - child_bitfield_bit_offset); + child_bitfield_bit_offset, + child_is_base_class); if (child_clang_type) { if (synthetic_index) @@ -385,7 +388,8 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3 child_byte_size, child_byte_offset, child_bitfield_bit_size, - child_bitfield_bit_offset)); + child_bitfield_bit_offset, + child_is_base_class)); } return valobj_sp; } @@ -863,6 +867,46 @@ ValueObject::SetDynamicValue () void +ValueObject::GetExpressionPath (Stream &s) +{ + if (m_parent) + { + m_parent->GetExpressionPath (s); + clang_type_t parent_clang_type = m_parent->GetClangType(); + if (parent_clang_type) + { + if (ClangASTContext::IsPointerType(parent_clang_type)) + { + s.PutCString("->"); + } + else if (ClangASTContext::IsAggregateType (parent_clang_type)) + { + if (ClangASTContext::IsArrayType (parent_clang_type) == false && + m_parent->IsBaseClass() == false) + s.PutChar('.'); + } + } + } + + if (IsBaseClass()) + { + clang_type_t clang_type = GetClangType(); + std::string cxx_class_name; + if (ClangASTContext::GetCXXClassName (clang_type, cxx_class_name)) + { + s << cxx_class_name.c_str() << "::"; + } + } + else + { + const char *name = GetName().AsCString(); + if (name) + s.PutCString(name); + } +} + + +void ValueObject::DumpValueObject ( Stream &s, @@ -875,33 +919,59 @@ ValueObject::DumpValueObject bool show_types, bool show_location, bool use_objc, - bool scope_already_checked + bool scope_already_checked, + bool flat_output ) { if (valobj) { //const char *loc_cstr = valobj->GetLocationAsCString(); - if (show_location) + clang_type_t clang_type = valobj->GetClangType(); + + const Flags type_info_flags (ClangASTContext::GetTypeInfoMask (clang_type)); + const char *err_cstr = NULL; + const bool has_children = type_info_flags.IsSet (ClangASTContext::eTypeHasChildren); + const bool has_value = type_info_flags.IsSet (ClangASTContext::eTypeHasValue); + + const bool print_valobj = flat_output == false || has_value; + + if (print_valobj) { - s.Printf("%s: ", valobj->GetLocationAsCString(exe_scope)); - } + if (show_location) + { + s.Printf("%s: ", valobj->GetLocationAsCString(exe_scope)); + } - s.Indent(); + s.Indent(); - if (show_types) - s.Printf("(%s) ", valobj->GetTypeName().AsCString()); + if (show_types) + s.Printf("(%s) ", valobj->GetTypeName().AsCString()); - const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString(""); - s.Printf ("%s = ", name_cstr); - if (!scope_already_checked && !valobj->IsInScope(exe_scope->CalculateStackFrame())) - { - s.PutCString("error: out of scope"); - return; + if (flat_output) + { + valobj->GetExpressionPath(s); + s.PutCString(" ="); + } + else + { + const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString(""); + s.Printf ("%s =", name_cstr); + } + + if (!scope_already_checked && !valobj->IsInScope(exe_scope->CalculateStackFrame())) + { + err_cstr = "error: out of scope"; + } } - const char *val_cstr = valobj->GetValueAsCString(exe_scope); - const char *err_cstr = valobj->GetError().AsCString(); + const char *val_cstr = NULL; + + if (err_cstr == NULL) + { + val_cstr = valobj->GetValueAsCString(exe_scope); + err_cstr = valobj->GetError().AsCString(); + } if (err_cstr) { @@ -909,75 +979,99 @@ ValueObject::DumpValueObject } else { - const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope); - - const bool is_aggregate = ClangASTContext::IsAggregateType (valobj->GetClangType()); + if (print_valobj) + { + const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope); - if (val_cstr) - s.PutCString(val_cstr); + if (val_cstr) + s.Printf(" %s", val_cstr); - if (sum_cstr) - s.Printf(" %s", sum_cstr); - - if (use_objc) - { - const char *object_desc = valobj->GetObjectDescription(exe_scope); - if (object_desc) - s.Printf("\n%s\n", object_desc); - else - s.Printf ("No description available.\n"); - return; + if (sum_cstr) + s.Printf(" %s", sum_cstr); + + if (use_objc) + { + const char *object_desc = valobj->GetObjectDescription(exe_scope); + if (object_desc) + s.Printf(" %s\n", object_desc); + else + s.Printf ("No description available.\n"); + return; + } } - if (curr_depth < max_depth) { - if (is_aggregate) - s.PutChar('{'); - - bool is_ptr_or_ref = ClangASTContext::IsPointerOrReferenceType (valobj->GetClangType()); + bool is_ptr_or_ref = type_info_flags.IsSet (ClangASTContext::eTypeIsPointer | ClangASTContext::eTypeIsReference); - if (is_ptr_or_ref && ptr_depth == 0) - return; - - const uint32_t num_children = valobj->GetNumChildren(); - if (num_children) + if (!is_ptr_or_ref || ptr_depth > 0) { - s.IndentMore(); - for (uint32_t idx=0; idx<num_children; ++idx) + const uint32_t num_children = valobj->GetNumChildren(); + if (num_children) { - ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true)); - if (child_sp.get()) + if (flat_output) { - s.EOL(); - DumpValueObject (s, - exe_scope, - child_sp.get(), - NULL, - is_ptr_or_ref ? ptr_depth - 1 : ptr_depth, - curr_depth + 1, - max_depth, - show_types, - show_location, - false, - true); - if (idx + 1 < num_children) - s.PutChar(','); + if (print_valobj) + s.EOL(); + } + else + { + if (print_valobj) + s.PutCString(" {\n"); + s.IndentMore(); + } + + for (uint32_t idx=0; idx<num_children; ++idx) + { + ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true)); + if (child_sp.get()) + { + DumpValueObject (s, + exe_scope, + child_sp.get(), + NULL, + is_ptr_or_ref ? ptr_depth - 1 : ptr_depth, + curr_depth + 1, + max_depth, + show_types, + show_location, + false, + true, + flat_output); + } + } + + if (!flat_output) + { + s.IndentLess(); + s.Indent("}\n"); } } - s.IndentLess(); + else if (has_children) + { + // Aggregate, no children... + if (print_valobj) + s.PutCString("{}\n"); + } + else + { + if (print_valobj) + s.EOL(); + } + } - if (is_aggregate) - { + else + { + // We printed a pointer, but we are stopping and not printing + // and children of this pointer... s.EOL(); - s.Indent("}"); } } else { - if (is_aggregate) + if (has_children && print_valobj) { - s.PutCString("{...}"); + s.PutCString("{...}\n"); } } } |