summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/ValueObjectDynamicValue.h6
-rw-r--r--lldb/include/lldb/Symbol/Type.h21
-rw-r--r--lldb/include/lldb/Target/LanguageRuntime.h1
-rw-r--r--lldb/source/Core/ValueObject.cpp33
-rw-r--r--lldb/source/Core/ValueObjectDynamicValue.cpp94
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp4
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp7
-rw-r--r--lldb/source/Symbol/Type.cpp39
-rw-r--r--lldb/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py4
9 files changed, 139 insertions, 70 deletions
diff --git a/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/lldb/include/lldb/Core/ValueObjectDynamicValue.h
index a76ca10d637..fd174e1d11d 100644
--- a/lldb/include/lldb/Core/ValueObjectDynamicValue.h
+++ b/lldb/include/lldb/Core/ValueObjectDynamicValue.h
@@ -15,6 +15,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/Type.h"
namespace lldb_private {
@@ -34,6 +35,9 @@ public:
virtual ConstString
GetTypeName();
+ virtual ConstString
+ GetQualifiedTypeName();
+
virtual uint32_t
CalculateNumChildren();
@@ -97,7 +101,7 @@ protected:
GetClangTypeImpl ();
Address m_address; ///< The variable that this value object is based upon
- lldb::TypeSP m_type_sp;
+ TypeAndOrName m_dynamic_type_info; // We can have a type_sp or just a name
lldb::ValueObjectSP m_owning_valobj_sp;
lldb::DynamicValueType m_use_dynamic;
diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h
index 40bbd10b83a..f3b381efd39 100644
--- a/lldb/include/lldb/Symbol/Type.h
+++ b/lldb/include/lldb/Symbol/Type.h
@@ -340,6 +340,12 @@ public:
TypeAndOrName &
operator= (const TypeAndOrName &rhs);
+ bool
+ operator==(const TypeAndOrName &other) const;
+
+ bool
+ operator!=(const TypeAndOrName &other) const;
+
ConstString GetName () const;
lldb::TypeSP
@@ -360,6 +366,21 @@ public:
bool
IsEmpty ();
+ bool
+ HasName ();
+
+ bool
+ HasTypeSP ();
+
+ void
+ Clear ();
+
+ operator
+ bool ()
+ {
+ return !IsEmpty();
+ }
+
private:
lldb::TypeSP m_type_sp;
ConstString m_type_name;
diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h
index 5a4dc7ae7f6..cafbff03a03 100644
--- a/lldb/include/lldb/Target/LanguageRuntime.h
+++ b/lldb/include/lldb/Target/LanguageRuntime.h
@@ -44,6 +44,7 @@ public:
virtual bool
GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope) = 0;
+ // this call should return true if it could set the name and/or the type
virtual bool
GetDynamicTypeAndAddress (ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 449e49c0720..92d2c36415e 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -3336,38 +3336,7 @@ DumpValueObject_Impl (Stream &s,
show_type = options.m_show_types || (curr_depth == 0 && !options.m_flat_output);
if (show_type)
- {
- const char* typeName = valobj->GetQualifiedTypeName().AsCString("<invalid type>");
- //const char* typeName = valobj->GetTypeName().AsCString("<invalid type>");
- s.Printf("(%s", typeName);
- // only show dynamic types if the user really wants to see types
- if (options.m_show_types && options.m_use_dynamic != eNoDynamicValues &&
- (/*strstr(typeName, "id") == typeName ||*/
- ClangASTType::GetMinimumLanguage(valobj->GetClangAST(), valobj->GetClangType()) == eLanguageTypeObjC))
- {
- ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
- Process *process = exe_ctx.GetProcessPtr();
- if (process == NULL)
- s.Printf(", dynamic type: unknown) ");
- else
- {
- ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
- if (runtime == NULL)
- s.Printf(", dynamic type: unknown) ");
- else
- {
- ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (runtime->GetNonKVOClassDescriptor(*valobj));
- if (objc_class_sp)
- s.Printf(", dynamic type: %s) ", objc_class_sp->GetClassName().GetCString());
- else
- s.Printf(", dynamic type: unknown) ");
- }
- }
- }
- else
- s.Printf(") ");
- }
-
+ s.Printf("(%s) ", valobj->GetQualifiedTypeName().AsCString("<invalid type>"));
if (options.m_flat_output)
{
diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp
index 9eb63b83a48..8cd1d1f547b 100644
--- a/lldb/source/Core/ValueObjectDynamicValue.cpp
+++ b/lldb/source/Core/ValueObjectDynamicValue.cpp
@@ -38,7 +38,7 @@ using namespace lldb_private;
ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
ValueObject(parent),
m_address (),
- m_type_sp(),
+ m_dynamic_type_info(),
m_use_dynamic (use_dynamic)
{
m_last_format_mgr_dynamic = use_dynamic;
@@ -53,7 +53,7 @@ ValueObjectDynamicValue::~ValueObjectDynamicValue()
lldb::clang_type_t
ValueObjectDynamicValue::GetClangTypeImpl ()
{
- if (m_type_sp)
+ if (m_dynamic_type_info.HasTypeSP())
return m_value.GetClangType();
else
return m_parent->GetClangType();
@@ -63,17 +63,35 @@ ConstString
ValueObjectDynamicValue::GetTypeName()
{
const bool success = UpdateValueIfNeeded(false);
- if (success && m_type_sp)
- return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
- else
- return m_parent->GetTypeName();
+ if (success)
+ {
+ if (m_dynamic_type_info.HasTypeSP())
+ return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
+ if (m_dynamic_type_info.HasName())
+ return m_dynamic_type_info.GetName();
+ }
+ return m_parent->GetTypeName();
+}
+
+ConstString
+ValueObjectDynamicValue::GetQualifiedTypeName()
+{
+ const bool success = UpdateValueIfNeeded(false);
+ if (success)
+ {
+ if (m_dynamic_type_info.HasTypeSP())
+ return ClangASTType::GetConstQualifiedTypeName (GetClangAST(), GetClangType());
+ if (m_dynamic_type_info.HasName())
+ return m_dynamic_type_info.GetName();
+ }
+ return m_parent->GetTypeName();
}
uint32_t
ValueObjectDynamicValue::CalculateNumChildren()
{
const bool success = UpdateValueIfNeeded(false);
- if (success && m_type_sp)
+ if (success && m_dynamic_type_info.HasTypeSP())
return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
else
return m_parent->GetNumChildren();
@@ -83,8 +101,8 @@ clang::ASTContext *
ValueObjectDynamicValue::GetClangASTImpl ()
{
const bool success = UpdateValueIfNeeded(false);
- if (success && m_type_sp)
- return m_type_sp->GetClangAST();
+ if (success && m_dynamic_type_info.HasTypeSP())
+ return m_dynamic_type_info.GetTypeSP()->GetClangAST();
else
return m_parent->GetClangAST ();
}
@@ -93,7 +111,7 @@ size_t
ValueObjectDynamicValue::GetByteSize()
{
const bool success = UpdateValueIfNeeded(false);
- if (success && m_type_sp)
+ if (success && m_dynamic_type_info.HasTypeSP())
return m_value.GetValueByteSize(GetClangAST(), NULL);
else
return m_parent->GetByteSize();
@@ -123,7 +141,7 @@ ValueObjectDynamicValue::UpdateValue ()
// parent which is equivalent to not using dynamic values.
if (m_use_dynamic == lldb::eNoDynamicValues)
{
- m_type_sp.reset();
+ m_dynamic_type_info.Clear();
return true;
}
@@ -165,8 +183,6 @@ ValueObjectDynamicValue::UpdateValue ()
}
}
- lldb::TypeSP dynamic_type_sp = class_type_or_name.GetTypeSP();
-
// Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
// don't...
@@ -176,10 +192,10 @@ ValueObjectDynamicValue::UpdateValue ()
// Or we could return false, and make ourselves an echo of our parent?
if (!found_dynamic_type)
{
- if (m_type_sp)
+ if (m_dynamic_type_info)
SetValueDidChange(true);
ClearDynamicTypeInformation();
- m_type_sp.reset();
+ m_dynamic_type_info.Clear();
m_value = m_parent->GetValue();
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
return m_error.Success();
@@ -191,15 +207,15 @@ ValueObjectDynamicValue::UpdateValue ()
bool has_changed_type = false;
- if (!m_type_sp)
+ if (!m_dynamic_type_info)
{
- m_type_sp = dynamic_type_sp;
+ m_dynamic_type_info = class_type_or_name;
has_changed_type = true;
}
- else if (dynamic_type_sp != m_type_sp)
+ else if (class_type_or_name != m_dynamic_type_info)
{
// We are another type, we need to tear down our children...
- m_type_sp = dynamic_type_sp;
+ m_dynamic_type_info = class_type_or_name;
SetValueDidChange (true);
has_changed_type = true;
}
@@ -219,16 +235,34 @@ ValueObjectDynamicValue::UpdateValue ()
m_value.GetScalar() = load_address;
}
- // 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...
- lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType();
- lldb::clang_type_t corrected_type = orig_type;
- if (m_parent->IsPointerType())
- corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type);
- else if (m_parent->IsPointerOrReferenceType())
- corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type);
-
+ lldb::clang_type_t 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...
+ lldb::clang_type_t orig_type;
+ clang::ASTContext* ast;
+ orig_type = m_dynamic_type_info.GetTypeSP()->GetClangForwardType();
+ ast = m_dynamic_type_info.GetTypeSP()->GetClangAST();
+ corrected_type = orig_type;
+ if (m_parent->IsPointerType())
+ corrected_type = ClangASTContext::CreatePointerType (ast, orig_type);
+ else if (m_parent->IsPointerOrReferenceType())
+ corrected_type = ClangASTContext::CreateLValueReferenceType (ast, orig_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 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_value.SetContext (Value::eContextTypeClangType, corrected_type);
// Our address is the location of the dynamic type stored in memory. It isn't a load address,
@@ -241,7 +275,7 @@ ValueObjectDynamicValue::UpdateValue ()
this,
GetTypeName().GetCString());
- if (m_address.IsValid() && m_type_sp)
+ if (m_address.IsValid() && m_dynamic_type_info)
{
// The variable value is in the Scalar value inside the m_value.
// We can point our m_data right to it.
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 44b8468428c..2cd340980c1 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -59,6 +59,8 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
// start of the value object which holds the dynamic type.
//
+ class_type_or_name.Clear();
+
// Only a pointer or reference type can have a different dynamic and static type:
if (CouldHaveDynamicValue (in_value))
{
@@ -271,7 +273,7 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
}
}
- return false;
+ return class_type_or_name.IsEmpty() == false;
}
bool
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index f194ac3d2d9..cfe7d13c697 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -329,6 +329,8 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value,
// The Runtime is attached to a particular process, you shouldn't pass in a value from another process.
assert (in_value.GetProcessSP().get() == m_process);
assert (m_process != NULL);
+
+ class_type_or_name.Clear();
// Make sure we can have a dynamic value before starting...
if (CouldHaveDynamicValue (in_value))
@@ -354,12 +356,9 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value,
class_type_or_name.SetTypeSP (type_sp);
}
}
-
- if (type_sp)
- return true;
}
}
- return false;
+ return class_type_or_name.IsEmpty() == false;
}
//------------------------------------------------------------------
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index c2d1cddcc36..03fc429bb45 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -828,6 +828,26 @@ TypeAndOrName::operator= (const TypeAndOrName &rhs)
return *this;
}
+bool
+TypeAndOrName::operator==(const TypeAndOrName &other) const
+{
+ if (m_type_sp != other.m_type_sp)
+ return false;
+ if (m_type_name != other.m_type_name)
+ return false;
+ return true;
+}
+
+bool
+TypeAndOrName::operator!=(const TypeAndOrName &other) const
+{
+ if (m_type_sp != other.m_type_sp)
+ return true;
+ if (m_type_name != other.m_type_name)
+ return true;
+ return false;
+}
+
ConstString
TypeAndOrName::GetName () const
{
@@ -866,6 +886,25 @@ TypeAndOrName::IsEmpty()
return true;
}
+void
+TypeAndOrName::Clear ()
+{
+ m_type_name.Clear();
+ m_type_sp.reset();
+}
+
+bool
+TypeAndOrName::HasName ()
+{
+ return (bool)m_type_name;
+}
+
+bool
+TypeAndOrName::HasTypeSP ()
+{
+ return m_type_sp.get() != NULL;
+}
+
TypeImpl::TypeImpl(const lldb_private::ClangASTType& clang_ast_type) :
m_clang_ast_type(clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType()),
m_type_sp()
diff --git a/lldb/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py b/lldb/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py
index 40a1281a8af..2fb73fba6b6 100644
--- a/lldb/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py
+++ b/lldb/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py
@@ -116,10 +116,10 @@ class ObjCDynamicValueTestCase(TestBase):
# check that our ObjC GetISA() does a good job at hiding KVO swizzled classes
self.expect('frame var -d run-target myObserver->_source -T', 'the KVO-ed class is hidden',
- substrs = ['dynamic type: SourceDerived'])
+ substrs = ['SourceDerived'])
self.expect('frame var -d run-target myObserver->_source -T', 'the KVO-ed class is hidden', matching = False,
- substrs = ['dynamic type: NSKVONotify'])
+ substrs = ['NSKVONotify'])
# This test is not entirely related to the main thrust of this test case, but since we're here,
# try stepping into setProperty, and make sure we get into the version in Source:
OpenPOWER on IntegriCloud