summaryrefslogtreecommitdiffstats
path: root/lldb
diff options
context:
space:
mode:
authorEnrico Granata <egranata@apple.com>2013-10-29 00:28:35 +0000
committerEnrico Granata <egranata@apple.com>2013-10-29 00:28:35 +0000
commitdc4db5a6ebcdee39e0816e9ac7ae7ac480ab14fc (patch)
treebf1cf0f68b3941a46161204fd06a009a9bbc0ebc /lldb
parent330b8939bb6f4a37753974504ad24e1587761225 (diff)
downloadbcm5719-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')
-rw-r--r--lldb/include/lldb/Core/ValueObject.h4
-rw-r--r--lldb/include/lldb/Core/ValueObjectDynamicValue.h4
-rw-r--r--lldb/include/lldb/DataFormatters/FormatClasses.h17
-rw-r--r--lldb/include/lldb/Symbol/ClangASTType.h6
-rw-r--r--lldb/include/lldb/Symbol/Type.h356
-rw-r--r--lldb/include/lldb/lldb-forward.h3
-rw-r--r--lldb/source/API/SBTarget.cpp2
-rw-r--r--lldb/source/API/SBType.cpp78
-rw-r--r--lldb/source/API/SBTypeNameSpecifier.cpp2
-rw-r--r--lldb/source/API/SBValue.cpp10
-rw-r--r--lldb/source/Core/ValueObject.cpp6
-rw-r--r--lldb/source/Core/ValueObjectDynamicValue.cpp99
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp11
-rw-r--r--lldb/source/Symbol/ClangASTType.cpp28
-rw-r--r--lldb/source/Symbol/Type.cpp281
-rwxr-xr-xlldb/test/dotest.py3
-rw-r--r--lldb/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py2
-rw-r--r--lldb/test/lang/objc/blocks/TestObjCIvarsInBlocks.py2
-rw-r--r--lldb/test/lang/objc/objc-dyn-sbtype/.categories1
-rw-r--r--lldb/test/lang/objc/objc-dyn-sbtype/Makefile7
-rw-r--r--lldb/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py65
-rw-r--r--lldb/test/lang/objc/objc-dyn-sbtype/main.m13
22 files changed, 757 insertions, 243 deletions
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h
index b304563221e..c27490144eb 100644
--- a/lldb/include/lldb/Core/ValueObject.h
+++ b/lldb/include/lldb/Core/ValueObject.h
@@ -374,6 +374,10 @@ public:
ClangASTType
GetClangType ();
+
+ // this vends a TypeImpl that is useful at the SB API layer
+ virtual TypeImpl
+ GetTypeImpl ();
//------------------------------------------------------------------
// Sublasses must implement the functions below.
diff --git a/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/lldb/include/lldb/Core/ValueObjectDynamicValue.h
index c0f6baade3f..68f88c96e54 100644
--- a/lldb/include/lldb/Core/ValueObjectDynamicValue.h
+++ b/lldb/include/lldb/Core/ValueObjectDynamicValue.h
@@ -93,6 +93,9 @@ public:
virtual bool
SetData (DataExtractor &data, Error &error);
+ virtual TypeImpl
+ GetTypeImpl ();
+
protected:
virtual bool
UpdateValue ();
@@ -116,6 +119,7 @@ protected:
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;
+ TypeImpl m_type_impl;
private:
friend class ValueObject;
diff --git a/lldb/include/lldb/DataFormatters/FormatClasses.h b/lldb/include/lldb/DataFormatters/FormatClasses.h
index 9e11471546e..6d9a50e8f2c 100644
--- a/lldb/include/lldb/DataFormatters/FormatClasses.h
+++ b/lldb/include/lldb/DataFormatters/FormatClasses.h
@@ -60,7 +60,7 @@ public:
if (type)
{
m_type.m_type_name.assign(type->GetName().GetCString());
- m_type.m_typeimpl_sp = lldb::TypeImplSP(new TypeImpl(type));
+ m_type.m_type_pair.SetType(type);
}
}
@@ -71,7 +71,7 @@ public:
if (type.IsValid())
{
m_type.m_type_name.assign(type.GetConstTypeName().GetCString());
- m_type.m_typeimpl_sp = lldb::TypeImplSP(new TypeImpl(type));
+ m_type.m_type_pair.SetType(type);
}
}
@@ -86,16 +86,16 @@ public:
lldb::TypeSP
GetTypeSP ()
{
- if (m_type.m_typeimpl_sp && m_type.m_typeimpl_sp->IsValid())
- return m_type.m_typeimpl_sp->GetTypeSP();
+ if (m_type.m_type_pair.IsValid())
+ return m_type.m_type_pair.GetTypeSP();
return lldb::TypeSP();
}
ClangASTType
GetClangASTType ()
{
- if (m_type.m_typeimpl_sp && m_type.m_typeimpl_sp->IsValid())
- return m_type.m_typeimpl_sp->GetClangASTType();
+ if (m_type.m_type_pair.IsValid())
+ return m_type.m_type_pair.GetClangASTType();
return ClangASTType();
}
@@ -108,12 +108,11 @@ public:
private:
bool m_is_regex;
// this works better than TypeAndOrName because the latter only wraps a TypeSP
- // whereas TypeImplSP can also be backed by a ClangASTType which is more commonly
- // used in LLDB. moreover, TypeImplSP is also what is currently backing SBType
+ // whereas TypePair can also be backed by a ClangASTType
struct TypeOrName
{
std::string m_type_name;
- lldb::TypeImplSP m_typeimpl_sp;
+ TypePair m_type_pair;
};
TypeOrName m_type;
diff --git a/lldb/include/lldb/Symbol/ClangASTType.h b/lldb/include/lldb/Symbol/ClangASTType.h
index f0dffe38e19..e5cced34020 100644
--- a/lldb/include/lldb/Symbol/ClangASTType.h
+++ b/lldb/include/lldb/Symbol/ClangASTType.h
@@ -155,6 +155,12 @@ public:
bool
IsFunctionType (bool *is_variadic_ptr = NULL) const;
+ size_t
+ GetNumberOfFunctionArguments () const;
+
+ ClangASTType
+ GetFunctionArgumentAtIndex (const size_t index);
+
bool
IsVariadicFunctionType () const;
diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h
index 50b22fe96b9..920f571fa1e 100644
--- a/lldb/include/lldb/Symbol/Type.h
+++ b/lldb/include/lldb/Symbol/Type.h
@@ -304,147 +304,236 @@ protected:
ResolveClangType (ResolveState clang_type_resolve_state);
};
+// these classes are used to back the SBType* objects
-///
-/// Sometimes you can find the name of the type corresponding to an object, but we don't have debug
-/// information for it. If that is the case, you can return one of these objects, and then if it
-/// has a full type, you can use that, but if not at least you can print the name for informational
-/// purposes.
-///
-
-class TypeAndOrName
-{
-public:
- TypeAndOrName ();
- TypeAndOrName (lldb::TypeSP &type_sp);
- TypeAndOrName (const char *type_str);
- TypeAndOrName (const TypeAndOrName &rhs);
- TypeAndOrName (ConstString &type_const_string);
+class TypePair {
+private:
+ ClangASTType clang_type;
+ lldb::TypeSP type_sp;
- TypeAndOrName &
- operator= (const TypeAndOrName &rhs);
+public:
+ TypePair () : clang_type(), type_sp() {}
+ TypePair (ClangASTType type) :
+ clang_type(type),
+ type_sp()
+ {
+ }
- bool
- operator==(const TypeAndOrName &other) const;
+ TypePair (lldb::TypeSP type) :
+ clang_type(),
+ type_sp(type)
+ {
+ clang_type = type_sp->GetClangForwardType();
+ }
bool
- operator!=(const TypeAndOrName &other) const;
-
- ConstString GetName () const;
-
- lldb::TypeSP
- GetTypeSP () const
+ IsValid () const
{
- return m_type_sp;
+ return clang_type.IsValid() || (type_sp.get() != nullptr);
}
- void
- SetName (const ConstString &type_name);
-
- void
- SetName (const char *type_name_cstr);
-
- void
- SetTypeSP (lldb::TypeSP type_sp);
-
- bool
- IsEmpty ();
+ explicit operator bool () const
+ {
+ return IsValid();
+ }
bool
- HasName ();
+ operator == (const TypePair& rhs) const
+ {
+ return clang_type == rhs.clang_type &&
+ type_sp.get() == rhs.type_sp.get();
+ }
bool
- HasTypeSP ();
+ operator != (const TypePair& rhs) const
+ {
+ return clang_type != rhs.clang_type ||
+ type_sp.get() != rhs.type_sp.get();
+ }
void
- Clear ();
+ Clear ()
+ {
+ clang_type.Clear();
+ type_sp.reset();
+ }
- operator
- bool ()
+ ConstString
+ GetName () const
{
- return !IsEmpty();
+ if (type_sp)
+ return type_sp->GetName();
+ if (clang_type)
+ return clang_type.GetTypeName();
+ return ConstString ();
}
-private:
- lldb::TypeSP m_type_sp;
- ConstString m_type_name;
-};
-
-// the two classes here are used by the public API as a backend to
-// the SBType and SBTypeList classes
+ void
+ SetType (ClangASTType type)
+ {
+ type_sp.reset();
+ clang_type = type;
+ }
-class TypeImpl
-{
-public:
+ void
+ SetType (lldb::TypeSP type)
+ {
+ type_sp = type;
+ clang_type = type_sp->GetClangForwardType();
+ }
- TypeImpl() :
- m_clang_ast_type(),
- m_type_sp()
+ lldb::TypeSP
+ GetTypeSP () const
{
+ return type_sp;
}
- TypeImpl(const TypeImpl& rhs) :
- m_clang_ast_type(rhs.m_clang_ast_type),
- m_type_sp(rhs.m_type_sp)
+ ClangASTType
+ GetClangASTType () const
{
+ return clang_type;
}
- TypeImpl(const lldb_private::ClangASTType& type);
+ ClangASTType
+ GetPointerType () const
+ {
+ if (type_sp)
+ return type_sp->GetClangLayoutType().GetPointerType();
+ return clang_type.GetPointerType();
+ }
- TypeImpl(const lldb::TypeSP& type);
+ ClangASTType
+ GetPointeeType () const
+ {
+ if (type_sp)
+ return type_sp->GetClangFullType().GetPointeeType();
+ return clang_type.GetPointeeType();
+ }
- TypeImpl&
- operator = (const TypeImpl& rhs);
+ ClangASTType
+ GetReferenceType () const
+ {
+ if (type_sp)
+ return type_sp->GetClangLayoutType().GetLValueReferenceType();
+ return clang_type.GetLValueReferenceType();
+ }
- bool
- operator == (const TypeImpl& rhs)
+ ClangASTType
+ GetDereferencedType () const
{
- return m_clang_ast_type == rhs.m_clang_ast_type && m_type_sp.get() == rhs.m_type_sp.get();
+ if (type_sp)
+ return type_sp->GetClangFullType().GetNonReferenceType();
+ return clang_type.GetNonReferenceType();
}
-
- bool
- operator != (const TypeImpl& rhs)
+
+ ClangASTType
+ GetUnqualifiedType () const
{
- return m_clang_ast_type != rhs.m_clang_ast_type || m_type_sp.get() != rhs.m_type_sp.get();
+ if (type_sp)
+ return type_sp->GetClangLayoutType().GetFullyUnqualifiedType();
+ return clang_type.GetFullyUnqualifiedType();
}
- bool
- IsValid()
+ ClangASTType
+ GetCanonicalType () const
{
- return m_type_sp.get() != NULL || m_clang_ast_type.IsValid();
+ if (type_sp)
+ return type_sp->GetClangFullType().GetCanonicalType();
+ return clang_type.GetCanonicalType();
}
- const lldb_private::ClangASTType &
- GetClangASTType() const
+ clang::ASTContext *
+ GetClangASTContext () const
{
- return m_clang_ast_type;
+ return clang_type.GetASTContext();
}
+};
- clang::ASTContext*
- GetASTContext();
+class TypeImpl
+{
+public:
+
+ TypeImpl();
+
+ ~TypeImpl () {}
+
+ TypeImpl(const TypeImpl& rhs);
+
+ TypeImpl (lldb::TypeSP type_sp);
+
+ TypeImpl (ClangASTType clang_type);
- lldb::clang_type_t
- GetOpaqueQualType();
+ TypeImpl (lldb::TypeSP type_sp, ClangASTType dynamic);
+
+ TypeImpl (ClangASTType clang_type, ClangASTType dynamic);
+
+ TypeImpl (TypePair pair, ClangASTType dynamic);
- lldb::TypeSP
- GetTypeSP ()
- {
- return m_type_sp;
- }
+ void
+ SetType (lldb::TypeSP type_sp);
+
+ void
+ SetType (ClangASTType clang_type);
+
+ void
+ SetType (lldb::TypeSP type_sp, ClangASTType dynamic);
+
+ void
+ SetType (ClangASTType clang_type, ClangASTType dynamic);
+
+ void
+ SetType (TypePair pair, ClangASTType dynamic);
+
+ TypeImpl&
+ operator = (const TypeImpl& rhs);
+
+ bool
+ operator == (const TypeImpl& rhs) const;
+
+ bool
+ operator != (const TypeImpl& rhs) const;
+
+ bool
+ IsValid() const;
+
+ explicit operator bool () const;
+
+ void Clear();
ConstString
- GetName ();
-
+ GetName () const;
+
+ TypeImpl
+ GetPointerType () const;
+
+ TypeImpl
+ GetPointeeType () const;
+
+ TypeImpl
+ GetReferenceType () const;
+
+ TypeImpl
+ GetDereferencedType () const;
+
+ TypeImpl
+ GetUnqualifiedType() const;
+
+ TypeImpl
+ GetCanonicalType() const;
+
+ ClangASTType
+ GetClangASTType (bool prefer_dynamic);
+
+ clang::ASTContext *
+ GetClangASTContext (bool prefer_dynamic);
+
bool
GetDescription (lldb_private::Stream &strm,
lldb::DescriptionLevel description_level);
- void
- SetType (const lldb::TypeSP &type_sp);
-
private:
- ClangASTType m_clang_ast_type;
- lldb::TypeSP m_type_sp;
+ TypePair m_static_type;
+ ClangASTType m_dynamic_type;
};
class TypeListImpl
@@ -590,6 +679,89 @@ protected:
};
+///
+/// Sometimes you can find the name of the type corresponding to an object, but we don't have debug
+/// information for it. If that is the case, you can return one of these objects, and then if it
+/// has a full type, you can use that, but if not at least you can print the name for informational
+/// purposes.
+///
+
+class TypeAndOrName
+{
+public:
+ TypeAndOrName ();
+ TypeAndOrName (lldb::TypeSP &type_sp);
+ TypeAndOrName (const ClangASTType &clang_type);
+ TypeAndOrName (const char *type_str);
+ TypeAndOrName (const TypeAndOrName &rhs);
+ TypeAndOrName (ConstString &type_const_string);
+
+ TypeAndOrName &
+ operator= (const TypeAndOrName &rhs);
+
+ bool
+ operator==(const TypeAndOrName &other) const;
+
+ bool
+ operator!=(const TypeAndOrName &other) const;
+
+ ConstString GetName () const;
+
+ lldb::TypeSP
+ GetTypeSP () const
+ {
+ return m_type_pair.GetTypeSP();
+ }
+
+ ClangASTType
+ GetClangASTType () const
+ {
+ return m_type_pair.GetClangASTType();
+ }
+
+ void
+ SetName (const ConstString &type_name);
+
+ void
+ SetName (const char *type_name_cstr);
+
+ void
+ SetTypeSP (lldb::TypeSP type_sp);
+
+ void
+ SetClangASTType (ClangASTType clang_type);
+
+ bool
+ IsEmpty () const;
+
+ bool
+ HasName () const;
+
+ bool
+ HasTypeSP () const;
+
+ bool
+ HasClangASTType () const;
+
+ bool
+ HasType () const
+ {
+ return HasTypeSP() || HasClangASTType();
+ }
+
+ void
+ Clear ();
+
+ explicit operator bool ()
+ {
+ return !IsEmpty();
+ }
+
+private:
+ TypePair m_type_pair;
+ ConstString m_type_name;
+};
+
} // namespace lldb_private
#endif // liblldb_Type_h_
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index e06044b09c9..ee59e0e2892 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -227,13 +227,14 @@ class ThreadPlanTracer;
class ThreadSpec;
class TimeValue;
class Type;
+class TypeAndOrName;
class TypeCategoryMap;
class TypeImpl;
-class TypeAndOrName;
class TypeList;
class TypeListImpl;
class TypeMemberImpl;
class TypeNameSpecifierImpl;
+class TypePair;
class UUID;
class Unwind;
class UnwindAssembly;
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index b1f11666590..cff6e4e2de3 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -1891,7 +1891,7 @@ SBTarget::CreateValueFromAddress (const char *name, SBAddress addr, SBType type)
{
lldb::addr_t address(addr.GetLoadAddress(*this));
lldb::TypeImplSP type_impl_sp (type.GetSP());
- ClangASTType pointer_ast_type(type_impl_sp->GetClangASTType().GetPointerType ());
+ ClangASTType pointer_ast_type(type_impl_sp->GetClangASTType(true).GetPointerType ());
if (pointer_ast_type)
{
lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp
index 9e254779ba1..3055c275208 100644
--- a/lldb/source/API/SBType.cpp
+++ b/lldb/source/API/SBType.cpp
@@ -63,8 +63,10 @@ SBType::operator == (SBType &rhs)
if (IsValid() == false)
return !rhs.IsValid();
- return (rhs.m_opaque_sp->GetASTContext() == m_opaque_sp->GetASTContext()) &&
- (rhs.m_opaque_sp->GetOpaqueQualType() == m_opaque_sp->GetOpaqueQualType());
+ if (rhs.IsValid() == false)
+ return false;
+
+ return *m_opaque_sp.get() == *rhs.m_opaque_sp.get();
}
bool
@@ -72,9 +74,11 @@ SBType::operator != (SBType &rhs)
{
if (IsValid() == false)
return rhs.IsValid();
-
- return (rhs.m_opaque_sp->GetASTContext() != m_opaque_sp->GetASTContext()) ||
- (rhs.m_opaque_sp->GetOpaqueQualType() != m_opaque_sp->GetOpaqueQualType());
+
+ if (rhs.IsValid() == false)
+ return true;
+
+ return *m_opaque_sp.get() != *rhs.m_opaque_sp.get();
}
lldb::TypeImplSP
@@ -136,7 +140,7 @@ SBType::GetByteSize()
if (!IsValid())
return 0;
- return m_opaque_sp->GetClangASTType().GetByteSize();
+ return m_opaque_sp->GetClangASTType(false).GetByteSize();
}
@@ -145,7 +149,7 @@ SBType::IsPointerType()
{
if (!IsValid())
return false;
- return m_opaque_sp->GetClangASTType().IsPointerType();
+ return m_opaque_sp->GetClangASTType(true).IsPointerType();
}
bool
@@ -153,7 +157,7 @@ SBType::IsReferenceType()
{
if (!IsValid())
return false;
- return m_opaque_sp->GetClangASTType().IsReferenceType();
+ return m_opaque_sp->GetClangASTType(true).IsReferenceType();
}
SBType
@@ -162,7 +166,7 @@ SBType::GetPointerType()
if (!IsValid())
return SBType();
- return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetPointerType()));
+ return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointerType())));
}
SBType
@@ -170,7 +174,7 @@ SBType::GetPointeeType()
{
if (!IsValid())
return SBType();
- return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetPointeeType()));
+ return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointeeType())));
}
SBType
@@ -178,7 +182,7 @@ SBType::GetReferenceType()
{
if (!IsValid())
return SBType();
- return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetLValueReferenceType()));
+ return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetReferenceType())));
}
SBType
@@ -186,7 +190,7 @@ SBType::GetDereferencedType()
{
if (!IsValid())
return SBType();
- return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetNonReferenceType()));
+ return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetDereferencedType())));
}
bool
@@ -194,7 +198,7 @@ SBType::IsFunctionType ()
{
if (!IsValid())
return false;
- return m_opaque_sp->GetClangASTType().IsFunctionType();
+ return m_opaque_sp->GetClangASTType(true).IsFunctionType();
}
bool
@@ -202,7 +206,7 @@ SBType::IsPolymorphicClass ()
{
if (!IsValid())
return false;
- return m_opaque_sp->GetClangASTType().IsPolymorphicClass();
+ return m_opaque_sp->GetClangASTType(true).IsPolymorphicClass();
}
@@ -212,7 +216,7 @@ SBType::GetFunctionReturnType ()
{
if (IsValid())
{
- ClangASTType return_clang_type (m_opaque_sp->GetClangASTType().GetFunctionReturnType());
+ ClangASTType return_clang_type (m_opaque_sp->GetClangASTType(true).GetFunctionReturnType());
if (return_clang_type.IsValid())
return SBType(return_clang_type);
}
@@ -225,13 +229,13 @@ SBType::GetFunctionArgumentTypes ()
SBTypeList sb_type_list;
if (IsValid())
{
- QualType qual_type(QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()));
- const FunctionProtoType* func = dyn_cast<FunctionProtoType>(qual_type.getTypePtr());
- if (func)
+ ClangASTType func_type(m_opaque_sp->GetClangASTType(true));
+ size_t count = func_type.GetNumberOfFunctionArguments();
+ for (size_t i = 0;
+ i < count;
+ i++)
{
- const uint32_t num_args = func->getNumArgs();
- for (uint32_t i=0; i<num_args; ++i)
- sb_type_list.Append (SBType(ClangASTType(m_opaque_sp->GetASTContext(), func->getArgType(i).getAsOpaquePtr())));
+ sb_type_list.Append(SBType(func_type.GetFunctionArgumentAtIndex(i)));
}
}
return sb_type_list;
@@ -242,14 +246,14 @@ SBType::GetUnqualifiedType()
{
if (!IsValid())
return SBType();
- return SBType(m_opaque_sp->GetClangASTType().GetFullyUnqualifiedType());
+ return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetUnqualifiedType())));
}
lldb::SBType
SBType::GetCanonicalType()
{
if (IsValid())
- return SBType(m_opaque_sp->GetClangASTType().GetCanonicalType());
+ return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetCanonicalType())));
return SBType();
}
@@ -258,7 +262,7 @@ lldb::BasicType
SBType::GetBasicType()
{
if (IsValid())
- return m_opaque_sp->GetClangASTType().GetBasicTypeEnumeration ();
+ return m_opaque_sp->GetClangASTType(false).GetBasicTypeEnumeration ();
return eBasicTypeInvalid;
}
@@ -266,7 +270,7 @@ SBType
SBType::GetBasicType(lldb::BasicType basic_type)
{
if (IsValid())
- return SBType (ClangASTContext::GetBasicType (m_opaque_sp->GetASTContext(), basic_type));
+ return SBType (ClangASTContext::GetBasicType (m_opaque_sp->GetClangASTContext(false), basic_type));
return SBType();
}
@@ -274,7 +278,7 @@ uint32_t
SBType::GetNumberOfDirectBaseClasses ()
{
if (IsValid())
- return m_opaque_sp->GetClangASTType().GetNumDirectBaseClasses();
+ return m_opaque_sp->GetClangASTType(true).GetNumDirectBaseClasses();
return 0;
}
@@ -282,7 +286,7 @@ uint32_t
SBType::GetNumberOfVirtualBaseClasses ()
{
if (IsValid())
- return m_opaque_sp->GetClangASTType().GetNumVirtualBaseClasses();
+ return m_opaque_sp->GetClangASTType(true).GetNumVirtualBaseClasses();
return 0;
}
@@ -290,7 +294,7 @@ uint32_t
SBType::GetNumberOfFields ()
{
if (IsValid())
- return m_opaque_sp->GetClangASTType().GetNumFields();
+ return m_opaque_sp->GetClangASTType(false).GetNumFields();
return 0;
}
@@ -317,7 +321,7 @@ SBType::GetDirectBaseClassAtIndex (uint32_t idx)
SBTypeMember sb_type_member;
if (IsValid())
{
- ClangASTType this_type (m_opaque_sp->GetClangASTType ());
+ ClangASTType this_type (m_opaque_sp->GetClangASTType (true));
if (this_type.IsValid())
{
uint32_t bit_offset = 0;
@@ -338,7 +342,7 @@ SBType::GetVirtualBaseClassAtIndex (uint32_t idx)
SBTypeMember sb_type_member;
if (IsValid())
{
- ClangASTType this_type (m_opaque_sp->GetClangASTType ());
+ ClangASTType this_type (m_opaque_sp->GetClangASTType (true));
if (this_type.IsValid())
{
uint32_t bit_offset = 0;
@@ -358,7 +362,7 @@ SBType::GetFieldAtIndex (uint32_t idx)
SBTypeMember sb_type_member;
if (IsValid())
{
- ClangASTType this_type (m_opaque_sp->GetClangASTType ());
+ ClangASTType this_type (m_opaque_sp->GetClangASTType (false));
if (this_type.IsValid())
{
uint64_t bit_offset = 0;
@@ -391,7 +395,7 @@ SBType::IsTypeComplete()
{
if (!IsValid())
return false;
- return m_opaque_sp->GetClangASTType().IsCompleteType();
+ return m_opaque_sp->GetClangASTType(false).IsCompleteType();
}
const char*
@@ -399,14 +403,14 @@ SBType::GetName()
{
if (!IsValid())
return "";
- return m_opaque_sp->GetClangASTType().GetConstTypeName().GetCString();
+ return m_opaque_sp->GetName().GetCString();
}
lldb::TypeClass
SBType::GetTypeClass ()
{
if (IsValid())
- return m_opaque_sp->GetClangASTType().GetTypeClass();
+ return m_opaque_sp->GetClangASTType(false).GetTypeClass();
return lldb::eTypeClassInvalid;
}
@@ -414,7 +418,7 @@ uint32_t
SBType::GetNumberOfTemplateArguments ()
{
if (IsValid())
- return m_opaque_sp->GetClangASTType().GetNumTemplateArguments();
+ return m_opaque_sp->GetClangASTType(false).GetNumTemplateArguments();
return 0;
}
@@ -424,7 +428,7 @@ SBType::GetTemplateArgumentType (uint32_t idx)
if (IsValid())
{
TemplateArgumentKind kind = eTemplateArgumentKindNull;
- ClangASTType template_arg_type = m_opaque_sp->GetClangASTType().GetTemplateArgument (idx, kind);
+ ClangASTType template_arg_type = m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
if (template_arg_type.IsValid())
return SBType(template_arg_type);
}
@@ -437,7 +441,7 @@ SBType::GetTemplateArgumentKind (uint32_t idx)
{
TemplateArgumentKind kind = eTemplateArgumentKindNull;
if (IsValid())
- m_opaque_sp->GetClangASTType().GetTemplateArgument (idx, kind);
+ m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
return kind;
}
diff --git a/lldb/source/API/SBTypeNameSpecifier.cpp b/lldb/source/API/SBTypeNameSpecifier.cpp
index d417499ecbd..3d03c6a0c53 100644
--- a/lldb/source/API/SBTypeNameSpecifier.cpp
+++ b/lldb/source/API/SBTypeNameSpecifier.cpp
@@ -36,7 +36,7 @@ SBTypeNameSpecifier::SBTypeNameSpecifier (SBType type) :
m_opaque_sp()
{
if (type.IsValid())
- m_opaque_sp = TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(type.m_opaque_sp->GetClangASTType()));
+ m_opaque_sp = TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(type.m_opaque_sp->GetClangASTType(true)));
}
SBTypeNameSpecifier::SBTypeNameSpecifier (const lldb::SBTypeNameSpecifier &rhs) :
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 408d51cc54b..68cd56f2998 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -473,7 +473,7 @@ SBValue::GetType()
TypeImplSP type_sp;
if (value_sp)
{
- type_sp.reset (new TypeImpl(value_sp->GetClangType()));
+ type_sp.reset (new TypeImpl(value_sp->GetTypeImpl()));
sb_type.SetSP(type_sp);
}
if (log)
@@ -671,7 +671,7 @@ SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type)
TypeImplSP type_sp (type.GetSP());
if (type.IsValid())
{
- sb_value.SetSP(value_sp->GetSyntheticChildAtOffset(offset, type_sp->GetClangASTType(), true),GetPreferDynamicValue(),GetPreferSyntheticValue(), name);
+ sb_value.SetSP(value_sp->GetSyntheticChildAtOffset(offset, type_sp->GetClangASTType(false), true),GetPreferDynamicValue(),GetPreferSyntheticValue(), name);
}
}
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -696,7 +696,7 @@ SBValue::Cast (SBType type)
lldb::ValueObjectSP value_sp(GetSP(locker));
TypeImplSP type_sp (type.GetSP());
if (value_sp && type_sp)
- sb_value.SetSP(value_sp->Cast(type_sp->GetClangASTType()),GetPreferDynamicValue(),GetPreferSyntheticValue());
+ sb_value.SetSP(value_sp->Cast(type_sp->GetClangASTType(false)),GetPreferDynamicValue(),GetPreferSyntheticValue());
return sb_value;
}
@@ -761,7 +761,7 @@ SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType s
lldb::TypeImplSP type_impl_sp (sb_type.GetSP());
if (value_sp && type_impl_sp)
{
- ClangASTType pointer_ast_type(type_impl_sp->GetClangASTType().GetPointerType ());
+ ClangASTType pointer_ast_type(type_impl_sp->GetClangASTType(false).GetPointerType ());
if (pointer_ast_type)
{
lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
@@ -808,7 +808,7 @@ SBValue::CreateValueFromData (const char* name, SBData data, SBType type)
ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
- type.m_opaque_sp->GetClangASTType(),
+ type.m_opaque_sp->GetClangASTType(false),
ConstString(name),
*data.m_opaque_sp,
LLDB_INVALID_ADDRESS);
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index c84bdf60062..e1f3b8a6470 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -359,6 +359,12 @@ ValueObject::GetClangType ()
return MaybeCalculateCompleteType();
}
+TypeImpl
+ValueObject::GetTypeImpl ()
+{
+ return TypeImpl(GetClangType());
+}
+
DataExtractor &
ValueObject::GetDataExtractor ()
{
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...
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 9012dd67281..e16c530329c 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -393,6 +393,17 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value,
objc_class_sp->SetType (type_sp);
class_type_or_name.SetTypeSP (type_sp);
}
+ else
+ {
+ // try to go for a ClangASTType at least
+ TypeVendor* vendor = GetTypeVendor();
+ if (vendor)
+ {
+ std::vector<ClangASTType> types;
+ if (vendor->FindTypes(class_name, false, 1, types) && types.size() && types.at(0).IsValid())
+ class_type_or_name.SetClangASTType(types.at(0));
+ }
+ }
}
}
}
diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp
index da445d83e79..b0413edffdd 100644
--- a/lldb/source/Symbol/ClangASTType.cpp
+++ b/lldb/source/Symbol/ClangASTType.cpp
@@ -385,6 +385,34 @@ ClangASTType::IsFunctionType (bool *is_variadic_ptr) const
return false;
}
+size_t
+ClangASTType::GetNumberOfFunctionArguments () const
+{
+ if (IsValid())
+ {
+ QualType qual_type (GetCanonicalQualType());
+ const FunctionProtoType* func = dyn_cast<FunctionProtoType>(qual_type.getTypePtr());
+ if (func)
+ return func->getNumArgs();
+ }
+ return 0;
+}
+
+ClangASTType
+ClangASTType::GetFunctionArgumentAtIndex (const size_t index)
+{
+ if (IsValid())
+ {
+ QualType qual_type (GetCanonicalQualType());
+ const FunctionProtoType* func = dyn_cast<FunctionProtoType>(qual_type.getTypePtr());
+ if (func)
+ {
+ if (index < func->getNumArgs())
+ return ClangASTType(m_ast, func->getArgType(index).getAsOpaquePtr());
+ }
+ }
+ return ClangASTType();
+}
bool
ClangASTType::IsFunctionPointerType () const
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 0af2359e1da..81aa44fc987 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -798,12 +798,12 @@ Type::GetTypeScopeAndBasename (const char* &name_cstr,
-TypeAndOrName::TypeAndOrName () : m_type_sp(), m_type_name()
+TypeAndOrName::TypeAndOrName () : m_type_pair(), m_type_name()
{
}
-TypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_sp(in_type_sp)
+TypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_pair(in_type_sp)
{
if (in_type_sp)
m_type_name = in_type_sp->GetName();
@@ -813,7 +813,7 @@ TypeAndOrName::TypeAndOrName (const char *in_type_str) : m_type_name(in_type_str
{
}
-TypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_sp (rhs.m_type_sp), m_type_name (rhs.m_type_name)
+TypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_pair (rhs.m_type_pair), m_type_name (rhs.m_type_name)
{
}
@@ -828,7 +828,7 @@ TypeAndOrName::operator= (const TypeAndOrName &rhs)
if (this != &rhs)
{
m_type_name = rhs.m_type_name;
- m_type_sp = rhs.m_type_sp;
+ m_type_pair = rhs.m_type_pair;
}
return *this;
}
@@ -836,7 +836,7 @@ TypeAndOrName::operator= (const TypeAndOrName &rhs)
bool
TypeAndOrName::operator==(const TypeAndOrName &other) const
{
- if (m_type_sp != other.m_type_sp)
+ if (m_type_pair != other.m_type_pair)
return false;
if (m_type_name != other.m_type_name)
return false;
@@ -846,7 +846,7 @@ TypeAndOrName::operator==(const TypeAndOrName &other) const
bool
TypeAndOrName::operator!=(const TypeAndOrName &other) const
{
- if (m_type_sp != other.m_type_sp)
+ if (m_type_pair != other.m_type_pair)
return true;
if (m_type_name != other.m_type_name)
return true;
@@ -856,8 +856,8 @@ TypeAndOrName::operator!=(const TypeAndOrName &other) const
ConstString
TypeAndOrName::GetName () const
{
- if (m_type_sp)
- return m_type_sp->GetName();
+ if (m_type_pair)
+ return m_type_pair.GetName();
else
return m_type_name;
}
@@ -877,15 +877,23 @@ TypeAndOrName::SetName (const char *type_name_cstr)
void
TypeAndOrName::SetTypeSP (lldb::TypeSP type_sp)
{
- m_type_sp = type_sp;
- if (type_sp)
- m_type_name = type_sp->GetName();
+ m_type_pair.SetType(type_sp);
+ if (m_type_pair)
+ m_type_name = m_type_pair.GetName();
+}
+
+void
+TypeAndOrName::SetClangASTType (ClangASTType clang_type)
+{
+ m_type_pair.SetType(clang_type);
+ if (m_type_pair)
+ m_type_name = m_type_pair.GetName();
}
bool
-TypeAndOrName::IsEmpty()
+TypeAndOrName::IsEmpty() const
{
- if (m_type_name || m_type_sp)
+ if ((bool)m_type_name || (bool)m_type_pair)
return false;
else
return true;
@@ -895,96 +903,247 @@ void
TypeAndOrName::Clear ()
{
m_type_name.Clear();
- m_type_sp.reset();
+ m_type_pair.Clear();
}
bool
-TypeAndOrName::HasName ()
+TypeAndOrName::HasName () const
{
return (bool)m_type_name;
}
bool
-TypeAndOrName::HasTypeSP ()
+TypeAndOrName::HasTypeSP () const
+{
+ return m_type_pair.GetTypeSP().get() != nullptr;
+}
+
+bool
+TypeAndOrName::HasClangASTType () const
+{
+ return m_type_pair.GetClangASTType().IsValid();
+}
+
+
+TypeImpl::TypeImpl() :
+m_static_type(),
+m_dynamic_type()
+{
+}
+
+TypeImpl::TypeImpl(const TypeImpl& rhs) :
+m_static_type(rhs.m_static_type),
+m_dynamic_type(rhs.m_dynamic_type)
{
- return m_type_sp.get() != NULL;
}
-TypeImpl::TypeImpl(const lldb_private::ClangASTType& clang_ast_type) :
- m_clang_ast_type(clang_ast_type),
- m_type_sp()
+TypeImpl::TypeImpl (lldb::TypeSP type_sp) :
+m_static_type(type_sp),
+m_dynamic_type()
{
}
-TypeImpl::TypeImpl(const lldb::TypeSP& type) :
- m_clang_ast_type(type->GetClangForwardType()),
- m_type_sp(type)
+TypeImpl::TypeImpl (ClangASTType clang_type) :
+m_static_type(clang_type),
+m_dynamic_type()
+{
+}
+
+TypeImpl::TypeImpl (lldb::TypeSP type_sp, ClangASTType dynamic) :
+m_static_type (type_sp),
+m_dynamic_type(dynamic)
+{
+}
+
+TypeImpl::TypeImpl (ClangASTType clang_type, ClangASTType dynamic) :
+m_static_type (clang_type),
+m_dynamic_type(dynamic)
+{
+}
+
+TypeImpl::TypeImpl (TypePair pair, ClangASTType dynamic) :
+m_static_type (pair),
+m_dynamic_type(dynamic)
{
}
void
-TypeImpl::SetType (const lldb::TypeSP &type_sp)
+TypeImpl::SetType (lldb::TypeSP type_sp)
{
- if (type_sp)
- {
- m_clang_ast_type = type_sp->GetClangForwardType();
- m_type_sp = type_sp;
- }
- else
- {
- m_clang_ast_type.Clear();
- m_type_sp.reset();
- }
+ m_static_type.SetType(type_sp);
+}
+
+void
+TypeImpl::SetType (ClangASTType clang_type)
+{
+ m_static_type.SetType (clang_type);
+}
+
+void
+TypeImpl::SetType (lldb::TypeSP type_sp, ClangASTType dynamic)
+{
+ m_static_type.SetType (type_sp);
+ m_dynamic_type = dynamic;
+}
+
+void
+TypeImpl::SetType (ClangASTType clang_type, ClangASTType dynamic)
+{
+ m_static_type.SetType (clang_type);
+ m_dynamic_type = dynamic;
+}
+
+void
+TypeImpl::SetType (TypePair pair, ClangASTType dynamic)
+{
+ m_static_type = pair;
+ m_dynamic_type = dynamic;
}
TypeImpl&
TypeImpl::operator = (const TypeImpl& rhs)
{
- if (*this != rhs)
+ if (rhs != *this)
{
- m_clang_ast_type = rhs.m_clang_ast_type;
- m_type_sp = rhs.m_type_sp;
+ m_static_type = rhs.m_static_type;
+ m_dynamic_type = rhs.m_dynamic_type;
}
return *this;
}
-clang::ASTContext*
-TypeImpl::GetASTContext()
+bool
+TypeImpl::operator == (const TypeImpl& rhs) const
{
- if (!IsValid())
- return NULL;
-
- return m_clang_ast_type.GetASTContext();
+ return m_static_type == rhs.m_static_type &&
+ m_dynamic_type == rhs.m_dynamic_type;
}
-lldb::clang_type_t
-TypeImpl::GetOpaqueQualType()
+bool
+TypeImpl::operator != (const TypeImpl& rhs) const
{
- if (!IsValid())
- return NULL;
-
- return m_clang_ast_type.GetOpaqueQualType();
+ return m_static_type != rhs.m_static_type ||
+ m_dynamic_type != rhs.m_dynamic_type;
}
bool
-TypeImpl::GetDescription (lldb_private::Stream &strm,
- lldb::DescriptionLevel description_level)
+TypeImpl::IsValid() const
+{
+ // just a name is not valid
+ return m_static_type.IsValid() || m_dynamic_type.IsValid();
+}
+
+TypeImpl::operator bool () const
{
- if (m_clang_ast_type.IsValid())
+ return IsValid();
+}
+
+void
+TypeImpl::Clear()
+{
+ m_static_type.Clear();
+ m_dynamic_type.Clear();
+}
+
+ConstString
+TypeImpl::GetName () const
+{
+ if (m_dynamic_type)
+ return m_dynamic_type.GetTypeName();
+ return m_static_type.GetName ();
+}
+
+TypeImpl
+TypeImpl::GetPointerType () const
+{
+ if (m_dynamic_type.IsValid())
{
- m_clang_ast_type.DumpTypeDescription (&strm);
+ return TypeImpl(m_static_type, m_dynamic_type.GetPointerType());
}
- else
+ return TypeImpl(m_static_type.GetPointerType());
+}
+
+TypeImpl
+TypeImpl::GetPointeeType () const
+{
+ if (m_dynamic_type.IsValid())
{
- strm.PutCString ("No value");
+ return TypeImpl(m_static_type, m_dynamic_type.GetPointeeType());
}
- return true;
+ return TypeImpl(m_static_type.GetPointeeType());
}
-ConstString
-TypeImpl::GetName ()
+TypeImpl
+TypeImpl::GetReferenceType () const
+{
+ if (m_dynamic_type.IsValid())
+ {
+ return TypeImpl(m_static_type, m_dynamic_type.GetLValueReferenceType());
+ }
+ return TypeImpl(m_static_type.GetReferenceType());
+}
+
+TypeImpl
+TypeImpl::GetDereferencedType () const
+{
+ if (m_dynamic_type.IsValid())
+ {
+ return TypeImpl(m_static_type, m_dynamic_type.GetNonReferenceType());
+ }
+ return TypeImpl(m_static_type.GetDereferencedType());
+}
+
+TypeImpl
+TypeImpl::GetUnqualifiedType() const
+{
+ if (m_dynamic_type.IsValid())
+ {
+ return TypeImpl(m_static_type, m_dynamic_type.GetFullyUnqualifiedType());
+ }
+ return TypeImpl(m_static_type.GetUnqualifiedType());
+}
+
+TypeImpl
+TypeImpl::GetCanonicalType() const
+{
+ if (m_dynamic_type.IsValid())
+ {
+ return TypeImpl(m_static_type, m_dynamic_type.GetCanonicalType());
+ }
+ return TypeImpl(m_static_type.GetCanonicalType());
+}
+
+ClangASTType
+TypeImpl::GetClangASTType (bool prefer_dynamic)
+{
+ if (prefer_dynamic)
+ {
+ if (m_dynamic_type.IsValid())
+ return m_dynamic_type;
+ }
+ return m_static_type.GetClangASTType();
+}
+
+clang::ASTContext *
+TypeImpl::GetClangASTContext (bool prefer_dynamic)
{
- if (m_clang_ast_type.IsValid())
- return m_clang_ast_type.GetConstTypeName();
- return ConstString();
+ if (prefer_dynamic)
+ {
+ if (m_dynamic_type.IsValid())
+ return m_dynamic_type.GetASTContext();
+ }
+ return m_static_type.GetClangASTContext();
+}
+
+bool
+TypeImpl::GetDescription (lldb_private::Stream &strm,
+ lldb::DescriptionLevel description_level)
+{
+ if (m_dynamic_type.IsValid())
+ {
+ strm.Printf("Dynamic:\n");
+ m_dynamic_type.DumpTypeDescription(&strm);
+ strm.Printf("\nStatic:\n");
+ }
+ m_static_type.GetClangASTType().DumpTypeDescription(&strm);
+ return true;
}
diff --git a/lldb/test/dotest.py b/lldb/test/dotest.py
index 96a35b9f135..bc2b068d5c8 100755
--- a/lldb/test/dotest.py
+++ b/lldb/test/dotest.py
@@ -97,7 +97,8 @@ validCategories = {
'objc':'Tests related to the Objective-C programming language support',
'pyapi':'Tests related to the Python API',
'basic_process': 'Basic process execution sniff tests.',
-'cmdline' : 'Tests related to the LLDB command-line interface'
+'cmdline' : 'Tests related to the LLDB command-line interface',
+'dyntype' : 'Tests related to dynamic type support'
}
# The test suite.
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py b/lldb/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
index 935673cb7ad..30a76928ea8 100644
--- a/lldb/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
+++ b/lldb/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
@@ -178,7 +178,7 @@ class AdvDataFormatterTestCase(TestBase):
# if the summary has an error, we still display the value
self.expect("frame variable couple --summary-string \"${*var.sp.foo[0-2]\"",
- substrs = ['(Couple) couple = (sp = SimpleWithPointers @ 0x', 's = 0x',')'])
+ substrs = ['(Couple) couple = {','x = 0x','y = 0x','z = 0x','s = 0x'])
self.runCmd("type summary add --summary-string \"${*var.sp.x[0-2]} are low bits of integer ${*var.sp.x}. If I pretend it is an array I get ${var.sp.x[0-5]}\" Couple")
diff --git a/lldb/test/lang/objc/blocks/TestObjCIvarsInBlocks.py b/lldb/test/lang/objc/blocks/TestObjCIvarsInBlocks.py
index 955bd6dd902..0213c46b435 100644
--- a/lldb/test/lang/objc/blocks/TestObjCIvarsInBlocks.py
+++ b/lldb/test/lang/objc/blocks/TestObjCIvarsInBlocks.py
@@ -112,7 +112,7 @@ class TestObjCIvarsInBlocks(TestBase):
self.assertTrue (expr, "Successfully got a local variable in a block in a class method.")
ret_value_signed = expr.GetValueAsSigned (error)
- print 'ret_value_signed = %i' % (ret_value_signed)
+ # print 'ret_value_signed = %i' % (ret_value_signed)
self.assertTrue (ret_value_signed == 5, "The local variable in the block was what we expected.")
if __name__ == '__main__':
diff --git a/lldb/test/lang/objc/objc-dyn-sbtype/.categories b/lldb/test/lang/objc/objc-dyn-sbtype/.categories
new file mode 100644
index 00000000000..9526bab96fb
--- /dev/null
+++ b/lldb/test/lang/objc/objc-dyn-sbtype/.categories
@@ -0,0 +1 @@
+dyntype
diff --git a/lldb/test/lang/objc/objc-dyn-sbtype/Makefile b/lldb/test/lang/objc/objc-dyn-sbtype/Makefile
new file mode 100644
index 00000000000..72b89bd59db
--- /dev/null
+++ b/lldb/test/lang/objc/objc-dyn-sbtype/Makefile
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation -framework Cocoa
diff --git a/lldb/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py b/lldb/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py
new file mode 100644
index 00000000000..9dae1e45688
--- /dev/null
+++ b/lldb/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py
@@ -0,0 +1,65 @@
+"""
+Test that we are able to properly report a usable dynamic type for NSImage
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+class ObjCDynamicSBTypeTestCase(TestBase):
+
+ mydir = os.path.join("lang", "objc", "objc-dyn-sbtype")
+
+ @dsym_test
+ @skipIfi386
+ def test_nsimage_dyn_with_dsym(self):
+ """Test that we are able to properly report a usable dynamic type for NSImage."""
+ d = {'EXE': self.exe_name}
+ self.buildDsym(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ self.nsimage_dyn(self.exe_name)
+
+ @dwarf_test
+ @skipIfi386
+ def test_nsimage_dyn_with_dwarf(self):
+ """Test that we are able to properly report a usable dynamic type for NSImage."""
+ d = {'EXE': self.exe_name}
+ self.buildDwarf(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ self.nsimage_dyn(self.exe_name)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # We'll use the test method name as the exe_name.
+ self.exe_name = self.testMethodName
+ # Find the line number to break inside main().
+ self.main_source = "main.m"
+ self.line = line_number(self.main_source, '// Set breakpoint here.')
+
+ def nsimage_dyn(self, exe_name):
+ """Test that we are able to properly report a usable dynamic type for NSImage."""
+ exe = os.path.join(os.getcwd(), exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, self.main_source, self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ image = self.frame().EvaluateExpression("(id)image",lldb.eDynamicCanRunTarget)
+ self.assertTrue(image.GetTypeName() == "NSImage *", "The SBValue is properly type-named")
+ image_type = image.GetType()
+ self.assertTrue(image_type.GetName() == "NSImage *", "The dynamic SBType is for the correct type")
+ image_pointee_type = image_type.GetPointeeType()
+ self.assertTrue(image_pointee_type.GetName() == "NSImage", "The dynamic type figures out its pointee type just fine")
+ self.assertTrue(image_pointee_type.GetDirectBaseClassAtIndex(0).GetName() == "NSObject", "The dynamic type can go back to its base class")
+
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
diff --git a/lldb/test/lang/objc/objc-dyn-sbtype/main.m b/lldb/test/lang/objc/objc-dyn-sbtype/main.m
new file mode 100644
index 00000000000..de757bc40e5
--- /dev/null
+++ b/lldb/test/lang/objc/objc-dyn-sbtype/main.m
@@ -0,0 +1,13 @@
+#import <Foundation/Foundation.h>
+#import <Cocoa/Cocoa.h>
+
+int main (int argc, char const *argv[])
+{
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ NSSize size = {10,10};
+ NSImage *image = [[NSImage alloc] initWithSize:size];
+ [pool release]; // Set breakpoint here.
+ return 0;
+}
+
OpenPOWER on IntegriCloud