[Lldb-commits] [lldb] r193564 - <rdar://problem/15144376>
Enrico Granata
egranata at apple.com
Mon Oct 28 17:28:35 PDT 2013
Author: enrico
Date: Mon Oct 28 19:28:35 2013
New Revision: 193564
URL: http://llvm.org/viewvc/llvm-project?rev=193564&view=rev
Log:
<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
Added:
lldb/trunk/test/lang/objc/objc-dyn-sbtype/
lldb/trunk/test/lang/objc/objc-dyn-sbtype/.categories
lldb/trunk/test/lang/objc/objc-dyn-sbtype/Makefile
lldb/trunk/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py
lldb/trunk/test/lang/objc/objc-dyn-sbtype/main.m
Modified:
lldb/trunk/include/lldb/Core/ValueObject.h
lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h
lldb/trunk/include/lldb/DataFormatters/FormatClasses.h
lldb/trunk/include/lldb/Symbol/ClangASTType.h
lldb/trunk/include/lldb/Symbol/Type.h
lldb/trunk/include/lldb/lldb-forward.h
lldb/trunk/source/API/SBTarget.cpp
lldb/trunk/source/API/SBType.cpp
lldb/trunk/source/API/SBTypeNameSpecifier.cpp
lldb/trunk/source/API/SBValue.cpp
lldb/trunk/source/Core/ValueObject.cpp
lldb/trunk/source/Core/ValueObjectDynamicValue.cpp
lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
lldb/trunk/source/Symbol/ClangASTType.cpp
lldb/trunk/source/Symbol/Type.cpp
lldb/trunk/test/dotest.py
lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
lldb/trunk/test/lang/objc/blocks/TestObjCIvarsInBlocks.py
Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Mon Oct 28 19:28:35 2013
@@ -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.
Modified: lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h Mon Oct 28 19:28:35 2013
@@ -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;
Modified: lldb/trunk/include/lldb/DataFormatters/FormatClasses.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/FormatClasses.h?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/FormatClasses.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/FormatClasses.h Mon Oct 28 19:28:35 2013
@@ -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;
Modified: lldb/trunk/include/lldb/Symbol/ClangASTType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTType.h?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTType.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTType.h Mon Oct 28 19:28:35 2013
@@ -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;
Modified: lldb/trunk/include/lldb/Symbol/Type.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Type.h?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/Type.h (original)
+++ lldb/trunk/include/lldb/Symbol/Type.h Mon Oct 28 19:28:35 2013
@@ -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();
}
+};
+
+class TypeImpl
+{
+public:
+
+ TypeImpl();
- clang::ASTContext*
- GetASTContext();
+ ~TypeImpl () {}
- lldb::clang_type_t
- GetOpaqueQualType();
+ TypeImpl(const TypeImpl& rhs);
+
+ TypeImpl (lldb::TypeSP type_sp);
+
+ TypeImpl (ClangASTType clang_type);
+
+ 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_
Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Mon Oct 28 19:28:35 2013
@@ -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;
Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Mon Oct 28 19:28:35 2013
@@ -1891,7 +1891,7 @@ SBTarget::CreateValueFromAddress (const
{
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)));
Modified: lldb/trunk/source/API/SBType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBType.cpp?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/source/API/SBType.cpp (original)
+++ lldb/trunk/source/API/SBType.cpp Mon Oct 28 19:28:35 2013
@@ -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 (uint3
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 (uint
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_
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_
{
TemplateArgumentKind kind = eTemplateArgumentKindNull;
if (IsValid())
- m_opaque_sp->GetClangASTType().GetTemplateArgument (idx, kind);
+ m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
return kind;
}
Modified: lldb/trunk/source/API/SBTypeNameSpecifier.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTypeNameSpecifier.cpp?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTypeNameSpecifier.cpp (original)
+++ lldb/trunk/source/API/SBTypeNameSpecifier.cpp Mon Oct 28 19:28:35 2013
@@ -36,7 +36,7 @@ SBTypeNameSpecifier::SBTypeNameSpecifier
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) :
Modified: lldb/trunk/source/API/SBValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/source/API/SBValue.cpp (original)
+++ lldb/trunk/source/API/SBValue.cpp Mon Oct 28 19:28:35 2013
@@ -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
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 ch
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
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);
Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Mon Oct 28 19:28:35 2013
@@ -359,6 +359,12 @@ ValueObject::GetClangType ()
return MaybeCalculateCompleteType();
}
+TypeImpl
+ValueObject::GetTypeImpl ()
+{
+ return TypeImpl(GetClangType());
+}
+
DataExtractor &
ValueObject::GetDataExtractor ()
{
Modified: lldb/trunk/source/Core/ValueObjectDynamicValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectDynamicValue.cpp?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectDynamicValue.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectDynamicValue.cpp Mon Oct 28 19:28:35 2013
@@ -52,10 +52,15 @@ ValueObjectDynamicValue::~ValueObjectDyn
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()
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...
Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Mon Oct 28 19:28:35 2013
@@ -393,6 +393,17 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAdd
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));
+ }
+ }
}
}
}
Modified: lldb/trunk/source/Symbol/ClangASTType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTType.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTType.cpp Mon Oct 28 19:28:35 2013
@@ -385,6 +385,34 @@ ClangASTType::IsFunctionType (bool *is_v
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
Modified: lldb/trunk/source/Symbol/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Type.cpp?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Type.cpp (original)
+++ lldb/trunk/source/Symbol/Type.cpp Mon Oct 28 19:28:35 2013
@@ -798,12 +798,12 @@ Type::GetTypeScopeAndBasename (const cha
-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
{
}
-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 TypeAndO
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 TypeAndO
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 TypeAndO
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 TypeAndO
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
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_clang_ast_type.IsValid())
- return m_clang_ast_type.GetConstTypeName();
- return ConstString();
+ 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 (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;
}
Modified: lldb/trunk/test/dotest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/test/dotest.py (original)
+++ lldb/trunk/test/dotest.py Mon Oct 28 19:28:35 2013
@@ -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.
Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py Mon Oct 28 19:28:35 2013
@@ -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")
Modified: lldb/trunk/test/lang/objc/blocks/TestObjCIvarsInBlocks.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/blocks/TestObjCIvarsInBlocks.py?rev=193564&r1=193563&r2=193564&view=diff
==============================================================================
--- lldb/trunk/test/lang/objc/blocks/TestObjCIvarsInBlocks.py (original)
+++ lldb/trunk/test/lang/objc/blocks/TestObjCIvarsInBlocks.py Mon Oct 28 19:28:35 2013
@@ -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__':
Added: lldb/trunk/test/lang/objc/objc-dyn-sbtype/.categories
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/objc-dyn-sbtype/.categories?rev=193564&view=auto
==============================================================================
--- lldb/trunk/test/lang/objc/objc-dyn-sbtype/.categories (added)
+++ lldb/trunk/test/lang/objc/objc-dyn-sbtype/.categories Mon Oct 28 19:28:35 2013
@@ -0,0 +1 @@
+dyntype
Added: lldb/trunk/test/lang/objc/objc-dyn-sbtype/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/objc-dyn-sbtype/Makefile?rev=193564&view=auto
==============================================================================
--- lldb/trunk/test/lang/objc/objc-dyn-sbtype/Makefile (added)
+++ lldb/trunk/test/lang/objc/objc-dyn-sbtype/Makefile Mon Oct 28 19:28:35 2013
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation -framework Cocoa
Added: lldb/trunk/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py?rev=193564&view=auto
==============================================================================
--- lldb/trunk/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py (added)
+++ lldb/trunk/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py Mon Oct 28 19:28:35 2013
@@ -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
+
+ at 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()
Added: lldb/trunk/test/lang/objc/objc-dyn-sbtype/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/objc-dyn-sbtype/main.m?rev=193564&view=auto
==============================================================================
--- lldb/trunk/test/lang/objc/objc-dyn-sbtype/main.m (added)
+++ lldb/trunk/test/lang/objc/objc-dyn-sbtype/main.m Mon Oct 28 19:28:35 2013
@@ -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;
+}
+
More information about the lldb-commits
mailing list