diff options
author | Enrico Granata <egranata@apple.com> | 2013-10-29 00:28:35 +0000 |
---|---|---|
committer | Enrico Granata <egranata@apple.com> | 2013-10-29 00:28:35 +0000 |
commit | dc4db5a6ebcdee39e0816e9ac7ae7ac480ab14fc (patch) | |
tree | bf1cf0f68b3941a46161204fd06a009a9bbc0ebc /lldb/source/Core/ValueObjectDynamicValue.cpp | |
parent | 330b8939bb6f4a37753974504ad24e1587761225 (diff) | |
download | bcm5719-llvm-dc4db5a6ebcdee39e0816e9ac7ae7ac480ab14fc.tar.gz bcm5719-llvm-dc4db5a6ebcdee39e0816e9ac7ae7ac480ab14fc.zip |
<rdar://problem/15144376>
This commit reimplements the TypeImpl class (the class that backs SBType) in terms of a static,dynamic type pair
This is useful for those cases when the dynamic type of an ObjC variable can only be obtained in terms of an "hollow" type with no ivars
In that case, we could either go with the static type (+iVar information) or with the dynamic type (+inheritance chain)
With the new TypeImpl implementation, we try to combine these two sources of information in order to extract as much information as possible
This should improve the functionality of tools that are using the SBType API to do extensive dynamic type inspection
llvm-svn: 193564
Diffstat (limited to 'lldb/source/Core/ValueObjectDynamicValue.cpp')
-rw-r--r-- | lldb/source/Core/ValueObjectDynamicValue.cpp | 99 |
1 files changed, 66 insertions, 33 deletions
diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp index 977cc4cd313..64f9750434d 100644 --- a/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -52,10 +52,15 @@ ValueObjectDynamicValue::~ValueObjectDynamicValue() ClangASTType ValueObjectDynamicValue::GetClangTypeImpl () { - if (m_dynamic_type_info.HasTypeSP()) - return m_value.GetClangType(); - else - return m_parent->GetClangType(); + const bool success = UpdateValueIfNeeded(false); + if (success) + { + if (m_dynamic_type_info.HasType()) + return m_value.GetClangType(); + else + return m_parent->GetClangType(); + } + return m_parent->GetClangType(); } ConstString @@ -64,7 +69,7 @@ ValueObjectDynamicValue::GetTypeName() const bool success = UpdateValueIfNeeded(false); if (success) { - if (m_dynamic_type_info.HasTypeSP()) + if (m_dynamic_type_info.HasType()) return GetClangType().GetConstTypeName(); if (m_dynamic_type_info.HasName()) return m_dynamic_type_info.GetName(); @@ -72,13 +77,24 @@ ValueObjectDynamicValue::GetTypeName() return m_parent->GetTypeName(); } +TypeImpl +ValueObjectDynamicValue::GetTypeImpl () +{ + const bool success = UpdateValueIfNeeded(false); + if (success) + { + return m_type_impl; + } + return m_parent->GetTypeImpl(); +} + ConstString ValueObjectDynamicValue::GetQualifiedTypeName() { const bool success = UpdateValueIfNeeded(false); if (success) { - if (m_dynamic_type_info.HasTypeSP()) + if (m_dynamic_type_info.HasType()) return GetClangType().GetConstQualifiedTypeName (); if (m_dynamic_type_info.HasName()) return m_dynamic_type_info.GetName(); @@ -90,7 +106,7 @@ size_t ValueObjectDynamicValue::CalculateNumChildren() { const bool success = UpdateValueIfNeeded(false); - if (success && m_dynamic_type_info.HasTypeSP()) + if (success && m_dynamic_type_info.HasType()) return GetClangType().GetNumChildren (true); else return m_parent->GetNumChildren(); @@ -100,7 +116,7 @@ uint64_t ValueObjectDynamicValue::GetByteSize() { const bool success = UpdateValueIfNeeded(false); - if (success && m_dynamic_type_info.HasTypeSP()) + if (success && m_dynamic_type_info.HasType()) return m_value.GetValueByteSize(NULL); else return m_parent->GetByteSize(); @@ -112,6 +128,38 @@ ValueObjectDynamicValue::GetValueType() const return m_parent->GetValueType(); } + +static TypeAndOrName +FixupTypeAndOrName (const TypeAndOrName& type_andor_name, + ValueObject& parent) +{ + TypeAndOrName ret(type_andor_name); + if (type_andor_name.HasType()) + { + // The type will always be the type of the dynamic object. If our parent's type was a pointer, + // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type + // should be okay... + ClangASTType orig_type = type_andor_name.GetClangASTType(); + ClangASTType corrected_type = orig_type; + if (parent.IsPointerType()) + corrected_type = orig_type.GetPointerType (); + else if (parent.IsPointerOrReferenceType()) + corrected_type = orig_type.GetLValueReferenceType (); + ret.SetClangASTType(corrected_type); + } + else /*if (m_dynamic_type_info.HasName())*/ + { + // If we are here we need to adjust our dynamic type name to include the correct & or * symbol + std::string corrected_name (type_andor_name.GetName().GetCString()); + if (parent.IsPointerType()) + corrected_name.append(" *"); + else if (parent.IsPointerOrReferenceType()) + corrected_name.append(" &"); + ret.SetName(corrected_name.c_str()); + } + return ret; +} + bool ValueObjectDynamicValue::UpdateValue () { @@ -176,6 +224,14 @@ ValueObjectDynamicValue::UpdateValue () // don't... m_update_point.SetUpdated(); + + // if the runtime only vended a ClangASTType, then we have an hollow type that we don't want to use + // but we save it for the TypeImpl, which can still use an hollow type for some questions + if (found_dynamic_type && class_type_or_name.HasType() && !class_type_or_name.HasTypeSP()) + { + m_type_impl = TypeImpl(m_parent->GetClangType(),FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType()); + class_type_or_name.SetClangASTType(ClangASTType()); + } // If we don't have a dynamic type, then make ourselves just a echo of our parent. // Or we could return false, and make ourselves an echo of our parent? @@ -224,33 +280,10 @@ ValueObjectDynamicValue::UpdateValue () m_value.GetScalar() = load_address; } - ClangASTType corrected_type; - if (m_dynamic_type_info.HasTypeSP()) - { - // The type will always be the type of the dynamic object. If our parent's type was a pointer, - // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type - // should be okay... - ClangASTType orig_type = m_dynamic_type_info.GetTypeSP()->GetClangForwardType(); - corrected_type = orig_type; - if (m_parent->IsPointerType()) - corrected_type = orig_type.GetPointerType (); - else if (m_parent->IsPointerOrReferenceType()) - corrected_type = orig_type.GetLValueReferenceType (); - } - else /*if (m_dynamic_type_info.HasName())*/ - { - // If we are here we need to adjust our dynamic type name to include the correct & or * symbol - std::string type_name_buf (m_dynamic_type_info.GetName().GetCString()); - if (m_parent->IsPointerType()) - type_name_buf.append(" *"); - else if (m_parent->IsPointerOrReferenceType()) - type_name_buf.append(" &"); - corrected_type = m_parent->GetClangType(); - m_dynamic_type_info.SetName(type_name_buf.c_str()); - } + m_dynamic_type_info = FixupTypeAndOrName(m_dynamic_type_info, *m_parent); //m_value.SetContext (Value::eContextTypeClangType, corrected_type); - m_value.SetClangType (corrected_type); + m_value.SetClangType (m_dynamic_type_info.GetClangASTType()); // Our address is the location of the dynamic type stored in memory. It isn't a load address, // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us... |