[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