summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/ValueObject.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2010-10-27 03:32:59 +0000
committerGreg Clayton <gclayton@apple.com>2010-10-27 03:32:59 +0000
commit73b472d42a4c2d1dafa165694456a06b05cb408a (patch)
tree08048a8c2adc8eba74148f0ea5966e19f2fdaebc /lldb/source/Core/ValueObject.cpp
parentd95ccd58a9fd96880c94ca995b334501738df5e8 (diff)
downloadbcm5719-llvm-73b472d42a4c2d1dafa165694456a06b05cb408a.tar.gz
bcm5719-llvm-73b472d42a4c2d1dafa165694456a06b05cb408a.zip
Updated the lldb_private::Flags class to have better method names and made
all of the calls inlined in the header file for better performance. Fixed the summary for C string types (array of chars (with any combo if modifiers), and pointers to chars) work in all cases. Fixed an issue where a forward declaration to a clang type could cause itself to resolve itself more than once if, during the resolving of the type itself it caused something to try and resolve itself again. We now remove the clang type from the forward declaration map in the DWARF parser when we start to resolve it and avoid this additional call. This should stop any duplicate members from appearing and throwing all the alignment of structs, unions and classes. llvm-svn: 117437
Diffstat (limited to 'lldb/source/Core/ValueObject.cpp')
-rw-r--r--lldb/source/Core/ValueObject.cpp117
1 files changed, 94 insertions, 23 deletions
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 4345eecea18..d10bf064c08 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -358,8 +358,8 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3
bool child_is_base_class = false;
const bool transparent_pointers = synthetic_array_member == false;
clang::ASTContext *clang_ast = GetClangAST();
- void *clang_type = GetClangType();
- void *child_clang_type;
+ clang_type_t clang_type = GetClangType();
+ clang_type_t child_clang_type;
child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (clang_ast,
GetName().AsCString(),
clang_type,
@@ -401,22 +401,38 @@ ValueObject::GetSummaryAsCString (ExecutionContextScope *exe_scope)
{
if (m_summary_str.empty())
{
- void *clang_type = GetClangType();
+ clang_type_t clang_type = GetClangType();
// See if this is a pointer to a C string?
- uint32_t fixed_length = 0;
if (clang_type)
{
StreamString sstr;
+ clang_type_t elem_or_pointee_clang_type;
+ const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
+ GetClangAST(),
+ &elem_or_pointee_clang_type));
- if (ClangASTContext::IsCStringType (clang_type, fixed_length))
+ if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
+ ClangASTContext::IsCharType (elem_or_pointee_clang_type))
{
Process *process = exe_scope->CalculateProcess();
if (process != NULL)
{
+ lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
lldb::AddressType cstr_address_type = eAddressTypeInvalid;
- lldb::addr_t cstr_address = GetPointerValue (cstr_address_type, true);
+ size_t cstr_len = 0;
+ if (type_flags.Test (ClangASTContext::eTypeIsArray))
+ {
+ // We have an array
+ cstr_len = ClangASTContext::GetArraySize (clang_type);
+ cstr_address = GetAddressOf (cstr_address_type, true);
+ }
+ else
+ {
+ // We have a pointer
+ cstr_address = GetPointerValue (cstr_address_type, true);
+ }
if (cstr_address != LLDB_INVALID_ADDRESS)
{
DataExtractor data;
@@ -425,14 +441,14 @@ ValueObject::GetSummaryAsCString (ExecutionContextScope *exe_scope)
std::vector<char> cstr_buffer;
size_t cstr_length;
Error error;
- if (fixed_length > 0)
+ if (cstr_len > 0)
{
- data_buffer.resize(fixed_length);
+ data_buffer.resize(cstr_len);
// Resize the formatted buffer in case every character
// uses the "\xXX" format and one extra byte for a NULL
cstr_buffer.resize(data_buffer.size() * 4 + 1);
data.SetData (&data_buffer.front(), data_buffer.size(), eByteOrderHost);
- bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), fixed_length, error);
+ bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), cstr_len, error);
if (bytes_read > 0)
{
sstr << '"';
@@ -590,7 +606,7 @@ ValueObject::GetValueAsCString (ExecutionContextScope *exe_scope)
case Value::eContextTypeDCType:
case Value::eContextTypeDCVariable:
{
- void *clang_type = GetClangType ();
+ clang_type_t clang_type = GetClangType ();
if (clang_type)
{
StreamString sstr;
@@ -644,11 +660,37 @@ ValueObject::GetValueAsCString (ExecutionContextScope *exe_scope)
}
addr_t
+ValueObject::GetAddressOf (lldb::AddressType &address_type, bool scalar_is_load_address)
+{
+ switch (m_value.GetValueType())
+ {
+ case Value::eValueTypeScalar:
+ if (scalar_is_load_address)
+ {
+ address_type = eAddressTypeLoad;
+ return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ }
+ break;
+
+ case Value::eValueTypeLoadAddress:
+ case Value::eValueTypeFileAddress:
+ case Value::eValueTypeHostAddress:
+ {
+ address_type = m_value.GetValueAddressType ();
+ return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ }
+ break;
+ }
+ address_type = eAddressTypeInvalid;
+ return LLDB_INVALID_ADDRESS;
+}
+
+addr_t
ValueObject::GetPointerValue (lldb::AddressType &address_type, bool scalar_is_load_address)
{
lldb::addr_t address = LLDB_INVALID_ADDRESS;
address_type = eAddressTypeInvalid;
- switch (GetValue().GetValueType())
+ switch (m_value.GetValueType())
{
case Value::eValueTypeScalar:
if (scalar_is_load_address)
@@ -773,7 +815,7 @@ ValueObject::Write ()
lldb::LanguageType
ValueObject::GetObjectRuntimeLanguage ()
{
- void *opaque_qual_type = GetClangType();
+ clang_type_t opaque_qual_type = GetClangType();
if (opaque_qual_type == NULL)
return lldb::eLanguageTypeC;
@@ -825,6 +867,8 @@ ValueObject::IsPointerType ()
return ClangASTContext::IsPointerType (GetClangType());
}
+
+
bool
ValueObject::IsPointerOrReferenceType ()
{
@@ -909,7 +953,6 @@ ValueObject::GetExpressionPath (Stream &s)
}
}
-
void
ValueObject::DumpValueObject
(
@@ -929,13 +972,12 @@ ValueObject::DumpValueObject
{
if (valobj)
{
- //const char *loc_cstr = valobj->GetLocationAsCString();
clang_type_t clang_type = valobj->GetClangType();
- const Flags type_info_flags (ClangASTContext::GetTypeInfoMask (clang_type));
+ const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
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 has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
+ const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
const bool print_valobj = flat_output == false || has_value;
@@ -983,6 +1025,7 @@ ValueObject::DumpValueObject
}
else
{
+ const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
if (print_valobj)
{
const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope);
@@ -1006,9 +1049,39 @@ ValueObject::DumpValueObject
if (curr_depth < max_depth)
{
- bool is_ptr_or_ref = type_info_flags.IsSet (ClangASTContext::eTypeIsPointer | ClangASTContext::eTypeIsReference);
+ // We will show children for all concrete types. We won't show
+ // pointer contents unless a pointer depth has been specified.
+ // We won't reference contents unless the reference is the
+ // root object (depth of zero).
+ bool print_children = true;
+
+ // Use a new temporary pointer depth in case we override the
+ // current pointer depth below...
+ uint32_t curr_ptr_depth = ptr_depth;
+
+ const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
+ if (is_ptr || is_ref)
+ {
+ // We have a pointer or reference whose value is an address.
+ // Make sure that address is not NULL
+ lldb::AddressType ptr_address_type;
+ if (valobj->GetPointerValue (ptr_address_type, true) == 0)
+ print_children = false;
+
+ else if (is_ref && curr_depth == 0)
+ {
+ // If this is the root object (depth is zero) that we are showing
+ // and it is a reference, and no pointer depth has been supplied
+ // print out what it references. Don't do this at deeper depths
+ // otherwise we can end up with infinite recursion...
+ curr_ptr_depth = 1;
+ }
+
+ if (curr_ptr_depth == 0)
+ print_children = false;
+ }
- if (!is_ptr_or_ref || ptr_depth > 0)
+ if (print_children)
{
const uint32_t num_children = valobj->GetNumChildren();
if (num_children)
@@ -1034,7 +1107,7 @@ ValueObject::DumpValueObject
exe_scope,
child_sp.get(),
NULL,
- is_ptr_or_ref ? ptr_depth - 1 : ptr_depth,
+ (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
curr_depth + 1,
max_depth,
show_types,
@@ -1055,7 +1128,7 @@ ValueObject::DumpValueObject
{
// Aggregate, no children...
if (print_valobj)
- s.PutCString("{}\n");
+ s.PutCString(" {}\n");
}
else
{
@@ -1066,8 +1139,6 @@ ValueObject::DumpValueObject
}
else
{
- // We printed a pointer, but we are stopping and not printing
- // and children of this pointer...
s.EOL();
}
}
OpenPOWER on IntegriCloud