summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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