Huge change to clean up types.

A long time ago we start with clang types that were created by the symbol files and there were many functions in lldb_private::ClangASTContext that helped. Later we create ClangASTType which contains a clang::ASTContext and an opauque QualType, but we didn't switch over to fully using it. There were a lot of places where we would pass around a raw clang_type_t and also pass along a clang::ASTContext separately. This left room for error.

This checkin change all type code over to use ClangASTType everywhere and I cleaned up the interfaces quite a bit. Any code that was in ClangASTContext that was type related, was moved over into ClangASTType. All code that used these types was switched over to use all of the new goodness.



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@186130 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/lldb/API/SBType.h b/include/lldb/API/SBType.h
index e08c1ae..3729b2f 100644
--- a/include/lldb/API/SBType.h
+++ b/include/lldb/API/SBType.h
@@ -164,10 +164,6 @@
     bool
     IsTypeComplete ();
 
-    // DEPRECATED: but needed for Xcode right now
-    static bool
-    IsPointerType (void * clang_type);
-        
     bool
     GetDescription (lldb::SBStream &description, 
                     lldb::DescriptionLevel description_level);
diff --git a/include/lldb/Core/DataBufferHeap.h b/include/lldb/Core/DataBufferHeap.h
index dfd5d7e..dac9a28 100644
--- a/include/lldb/Core/DataBufferHeap.h
+++ b/include/lldb/Core/DataBufferHeap.h
@@ -121,6 +121,9 @@
     void
     CopyData (const void *src, lldb::offset_t src_len);
 
+    void
+    Clear();
+
 private:
     //------------------------------------------------------------------
     // This object uses a std::vector<uint8_t> to store its data. This
diff --git a/include/lldb/Core/Value.h b/include/lldb/Core/Value.h
index 3ca7301..5461ca7 100644
--- a/include/lldb/Core/Value.h
+++ b/include/lldb/Core/Value.h
@@ -21,6 +21,7 @@
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Scalar.h"
+#include "lldb/Symbol/ClangASTType.h"
 
 namespace lldb_private {
 
@@ -46,7 +47,6 @@
                                         // m_context contains...
                                         // ====================
         eContextTypeInvalid,            // undefined
-        eContextTypeClangType,          // void * (an opaque clang::QualType * that can be fed to "static QualType QualType::getFromOpaquePtr(void *)")
         eContextTypeRegisterInfo,       // RegisterInfo * (can be a scalar or a vector register)
         eContextTypeLLDBType,           // lldb_private::Type *
         eContextTypeVariable            // lldb_private::Variable *
@@ -77,7 +77,13 @@
             return *this;
         }
 
-        bool 
+        void
+        Clear ()
+        {
+			length = 0;
+        }
+
+        bool
 		SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
 		{
             this->length = length;
@@ -124,8 +130,11 @@
     Value &
     operator=(const Value &rhs);
 
-    lldb::clang_type_t
+    const ClangASTType &
     GetClangType();
+    
+    void
+    SetClangType (const ClangASTType &clang_type);
 
     ValueType
     GetValueType() const;
@@ -173,7 +182,7 @@
     GetType();
 
     Scalar &
-    ResolveValue (ExecutionContext *exe_ctx, clang::ASTContext *ast_context);
+    ResolveValue (ExecutionContext *exe_ctx);
 
     const Scalar &
     GetScalar() const
@@ -227,7 +236,7 @@
     ResizeData(size_t len);
 
     bool
-    ValueOf(ExecutionContext *exe_ctx, clang::ASTContext *ast_context);
+    ValueOf(ExecutionContext *exe_ctx);
 
     Variable *
     GetVariable();
@@ -239,11 +248,10 @@
     GetValueDefaultFormat ();
 
     uint64_t
-    GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr);
+    GetValueByteSize (Error *error_ptr);
 
     Error
     GetValueAsData (ExecutionContext *exe_ctx, 
-                    clang::ASTContext *ast_context, 
                     DataExtractor &data, 
                     uint32_t data_offset,
                     Module *module);     // Can be NULL
@@ -257,11 +265,15 @@
     bool
     GetData (DataExtractor &data);
 
+    void
+    Clear();
+
 protected:
     Scalar          m_value;
     Vector          m_vector;
-    ValueType       m_value_type;
+    ClangASTType    m_clang_type;
     void *          m_context;
+    ValueType       m_value_type;
     ContextType     m_context_type;
     DataBufferHeap  m_data_buffer;
 };
diff --git a/include/lldb/Core/ValueObject.h b/include/lldb/Core/ValueObject.h
index 26fa3aa..0d965d6 100644
--- a/include/lldb/Core/ValueObject.h
+++ b/include/lldb/Core/ValueObject.h
@@ -596,10 +596,7 @@
     
     virtual ~ValueObject();
     
-    clang::ASTContext *
-    GetClangAST ();
-    
-    lldb::clang_type_t
+    ClangASTType
     GetClangType ();
 
     //------------------------------------------------------------------
@@ -624,7 +621,7 @@
     GetObjectRuntimeLanguage();
 
     virtual uint32_t
-    GetTypeInfo (lldb::clang_type_t *pointee_or_element_clang_type = NULL);
+    GetTypeInfo (ClangASTType *pointee_or_element_clang_type = NULL);
 
     virtual bool
     IsPointerType ();
@@ -718,12 +715,6 @@
         return m_is_array_item_for_pointer;
     }
     
-    virtual bool
-    SetClangAST (clang::ASTContext *ast)
-    {
-        return false;
-    }
-
     virtual const char *
     GetValueAsCString ();
     
@@ -1337,10 +1328,7 @@
     // Sublasses must implement the functions below.
     //------------------------------------------------------------------
     
-    virtual clang::ASTContext *
-    GetClangASTImpl () = 0;
-    
-    virtual lldb::clang_type_t
+    virtual ClangASTType
     GetClangTypeImpl () = 0;
     
     const char *
diff --git a/include/lldb/Core/ValueObjectCast.h b/include/lldb/Core/ValueObjectCast.h
index 2ddee7a..1538d7a 100644
--- a/include/lldb/Core/ValueObjectCast.h
+++ b/include/lldb/Core/ValueObjectCast.h
@@ -66,10 +66,7 @@
     virtual bool
     UpdateValue ();
     
-    virtual clang::ASTContext *
-    GetClangASTImpl ();
-    
-    virtual lldb::clang_type_t
+    virtual ClangASTType
     GetClangTypeImpl ();
     
     ClangASTType m_cast_type;
diff --git a/include/lldb/Core/ValueObjectChild.h b/include/lldb/Core/ValueObjectChild.h
index b071a0f..780529a 100644
--- a/include/lldb/Core/ValueObjectChild.h
+++ b/include/lldb/Core/ValueObjectChild.h
@@ -81,20 +81,13 @@
     virtual bool
     UpdateValue ();
 
-    virtual clang::ASTContext *
-    GetClangASTImpl ()
-    {
-        return m_clang_ast;
-    }
-    
-    virtual lldb::clang_type_t
+    virtual ClangASTType
     GetClangTypeImpl ()
     {
         return m_clang_type;
     }
     
-    clang::ASTContext *m_clang_ast; // The clang AST that the clang type comes from
-    void *m_clang_type; // The type of the child in question within the parent (m_parent_sp)
+    ClangASTType m_clang_type;
     ConstString m_type_name;
     uint64_t m_byte_size;
     int32_t m_byte_offset;
@@ -111,8 +104,7 @@
     friend class ValueObject;
     friend class ValueObjectConstResult;
     ValueObjectChild (ValueObject &parent,
-                      clang::ASTContext *clang_ast,
-                      void *clang_type,
+                      const ClangASTType &clang_type,
                       const ConstString &name,
                       uint64_t byte_size,
                       int32_t byte_offset,
diff --git a/include/lldb/Core/ValueObjectConstResult.h b/include/lldb/Core/ValueObjectConstResult.h
index bce25e5..4964d05 100644
--- a/include/lldb/Core/ValueObjectConstResult.h
+++ b/include/lldb/Core/ValueObjectConstResult.h
@@ -34,16 +34,14 @@
 
     static lldb::ValueObjectSP
     Create (ExecutionContextScope *exe_scope,
-            clang::ASTContext *clang_ast,
-            void *clang_type,
+            const ClangASTType &clang_type,
             const ConstString &name,
             const DataExtractor &data,
             lldb::addr_t address = LLDB_INVALID_ADDRESS);
 
     static lldb::ValueObjectSP
     Create (ExecutionContextScope *exe_scope,
-            clang::ASTContext *clang_ast,
-            void *clang_type,
+            const ClangASTType &clang_type,
             const ConstString &name,
             const lldb::DataBufferSP &result_data_sp,
             lldb::ByteOrder byte_order, 
@@ -52,8 +50,7 @@
 
     static lldb::ValueObjectSP
     Create (ExecutionContextScope *exe_scope,
-            clang::ASTContext *clang_ast,
-            void *clang_type,
+            const ClangASTType &clang_type,
             const ConstString &name,
             lldb::addr_t address,
             AddressType address_type,
@@ -61,7 +58,6 @@
 
     static lldb::ValueObjectSP
     Create (ExecutionContextScope *exe_scope,
-            clang::ASTContext *clang_ast,
             Value &value,
             const ConstString &name);
 
@@ -87,13 +83,6 @@
     virtual bool
     IsInScope ();
 
-    virtual bool
-    SetClangAST (clang::ASTContext *ast)
-    {
-        m_clang_ast = ast;
-        return true;
-    }
-
     void
     SetByteSize (size_t size);
     
@@ -139,13 +128,9 @@
     virtual bool
     UpdateValue ();
     
-    virtual clang::ASTContext *
-    GetClangASTImpl ();
-    
-    virtual lldb::clang_type_t
+    virtual ClangASTType
     GetClangTypeImpl ();
 
-    clang::ASTContext *m_clang_ast; // The clang AST that the clang type comes from
     ConstString m_type_name;
     uint64_t m_byte_size;
     
@@ -159,15 +144,13 @@
                             lldb::addr_t address);
 
     ValueObjectConstResult (ExecutionContextScope *exe_scope,
-                            clang::ASTContext *clang_ast,
-                            void *clang_type,
+                            const ClangASTType &clang_type,
                             const ConstString &name,
                             const DataExtractor &data,
                             lldb::addr_t address);
 
     ValueObjectConstResult (ExecutionContextScope *exe_scope,
-                            clang::ASTContext *clang_ast,
-                            void *clang_type,
+                            const ClangASTType &clang_type,
                             const ConstString &name,
                             const lldb::DataBufferSP &result_data_sp,
                             lldb::ByteOrder byte_order, 
@@ -175,15 +158,13 @@
                             lldb::addr_t address);
 
     ValueObjectConstResult (ExecutionContextScope *exe_scope,
-                            clang::ASTContext *clang_ast,
-                            void *clang_type,
+                            const ClangASTType &clang_type,
                             const ConstString &name,
                             lldb::addr_t address,
                             AddressType address_type,
                             uint32_t addr_byte_size);
 
     ValueObjectConstResult (ExecutionContextScope *exe_scope,
-                            clang::ASTContext *clang_ast,
                             const Value &value,
                             const ConstString &name);
 
diff --git a/include/lldb/Core/ValueObjectConstResultChild.h b/include/lldb/Core/ValueObjectConstResultChild.h
index fbc3e7c..9063276 100644
--- a/include/lldb/Core/ValueObjectConstResultChild.h
+++ b/include/lldb/Core/ValueObjectConstResultChild.h
@@ -27,8 +27,7 @@
 public:
     
     ValueObjectConstResultChild (ValueObject &parent,
-                                 clang::ASTContext *clang_ast,
-                                 void *clang_type,
+                                 const ClangASTType &clang_type,
                                  const ConstString &name,
                                  uint32_t byte_size,
                                  int32_t byte_offset,
@@ -45,7 +44,7 @@
     virtual ValueObject *
     CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
 
-    virtual lldb::clang_type_t
+    virtual ClangASTType
     GetClangType ()
     {
         return ValueObjectChild::GetClangType();
diff --git a/include/lldb/Core/ValueObjectDynamicValue.h b/include/lldb/Core/ValueObjectDynamicValue.h
index 12f75bd..c0f6baa 100644
--- a/include/lldb/Core/ValueObjectDynamicValue.h
+++ b/include/lldb/Core/ValueObjectDynamicValue.h
@@ -109,10 +109,7 @@
         return true;
     }
     
-    virtual clang::ASTContext *
-    GetClangASTImpl ();
-    
-    virtual lldb::clang_type_t
+    virtual ClangASTType
     GetClangTypeImpl ();
 
     Address  m_address;  ///< The variable that this value object is based upon
diff --git a/include/lldb/Core/ValueObjectMemory.h b/include/lldb/Core/ValueObjectMemory.h
index 21bd75a..627d73e 100644
--- a/include/lldb/Core/ValueObjectMemory.h
+++ b/include/lldb/Core/ValueObjectMemory.h
@@ -63,10 +63,7 @@
     virtual bool
     UpdateValue ();
     
-    virtual clang::ASTContext *
-    GetClangASTImpl ();
-    
-    virtual lldb::clang_type_t
+    virtual ClangASTType
     GetClangTypeImpl ();
 
     Address  m_address;  ///< The variable that this value object is based upon
diff --git a/include/lldb/Core/ValueObjectRegister.h b/include/lldb/Core/ValueObjectRegister.h
index 73f6e58..6820629 100644
--- a/include/lldb/Core/ValueObjectRegister.h
+++ b/include/lldb/Core/ValueObjectRegister.h
@@ -56,10 +56,7 @@
     virtual bool
     UpdateValue ();
     
-    virtual clang::ASTContext *
-    GetClangASTImpl ();
-    
-    virtual lldb::clang_type_t
+    virtual ClangASTType
     GetClangTypeImpl ();
 
     lldb::RegisterContextSP m_reg_ctx_sp;
@@ -113,10 +110,7 @@
     virtual bool
     UpdateValue ();
     
-    virtual clang::ASTContext *
-    GetClangASTImpl ();
-    
-    virtual lldb::clang_type_t
+    virtual ClangASTType
     GetClangTypeImpl ();
 
     lldb::RegisterContextSP m_reg_ctx_sp;
@@ -173,17 +167,14 @@
     virtual bool
     UpdateValue ();
     
-    virtual clang::ASTContext *
-    GetClangASTImpl ();
-    
-    virtual lldb::clang_type_t
+    virtual ClangASTType
     GetClangTypeImpl ();
 
     lldb::RegisterContextSP m_reg_ctx_sp;
     RegisterInfo m_reg_info;
     RegisterValue m_reg_value;
     ConstString m_type_name;
-    void *m_clang_type;
+    ClangASTType m_clang_type;
 
 private:
     void
diff --git a/include/lldb/Core/ValueObjectSyntheticFilter.h b/include/lldb/Core/ValueObjectSyntheticFilter.h
index 75c57c1..f1d8c88 100644
--- a/include/lldb/Core/ValueObjectSyntheticFilter.h
+++ b/include/lldb/Core/ValueObjectSyntheticFilter.h
@@ -140,10 +140,7 @@
     virtual bool
     UpdateValue ();
     
-    virtual clang::ASTContext *
-    GetClangASTImpl ();
-    
-    virtual lldb::clang_type_t
+    virtual ClangASTType
     GetClangTypeImpl ();
     
     virtual void
diff --git a/include/lldb/Core/ValueObjectVariable.h b/include/lldb/Core/ValueObjectVariable.h
index 897ce82..8a30b00 100644
--- a/include/lldb/Core/ValueObjectVariable.h
+++ b/include/lldb/Core/ValueObjectVariable.h
@@ -71,10 +71,7 @@
     virtual bool
     UpdateValue ();
     
-    virtual clang::ASTContext *
-    GetClangASTImpl ();
-    
-    virtual lldb::clang_type_t
+    virtual ClangASTType
     GetClangTypeImpl ();
 
     lldb::VariableSP  m_variable_sp;  ///< The variable that this value object is based upon
diff --git a/include/lldb/DataFormatters/FormatNavigator.h b/include/lldb/DataFormatters/FormatNavigator.h
index 0d3a833..a738cfd 100644
--- a/include/lldb/DataFormatters/FormatNavigator.h
+++ b/include/lldb/DataFormatters/FormatNavigator.h
@@ -288,8 +288,8 @@
         uint32_t* why = NULL)
     {
         uint32_t value = lldb_private::eFormatterChoiceCriterionDirectChoice;
-        clang::QualType type = clang::QualType::getFromOpaquePtr(valobj.GetClangType());
-        bool ret = Get(valobj, type, entry, use_dynamic, value);
+        ClangASTType ast_type(valobj.GetClangType());
+        bool ret = Get(valobj, ast_type, entry, use_dynamic, value);
         if (ret)
             entry = MapValueType(entry);
         else
@@ -523,29 +523,23 @@
     
     bool
     Get_Impl (ValueObject& valobj,
-              clang::QualType type,
+              ClangASTType clang_type,
               MapValueType& entry,
               lldb::DynamicValueType use_dynamic,
               uint32_t& reason)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
 
-        if (type.isNull())
+        if (!clang_type.IsValid())
         {
             if (log)
-                log->Printf("[Get_Impl] type is NULL, returning");
+                log->Printf("[Get_Impl] type is invalid, returning");
             return false;
         }
         
-        type.removeLocalConst(); type.removeLocalVolatile(); type.removeLocalRestrict();
-        const clang::Type* typePtr = type.getTypePtrOrNull();
-        if (!typePtr)
-        {
-            if (log)
-                log->Printf("[Get_Impl] type is NULL, returning");
-            return false;
-        }
-        ConstString typeName(ClangASTType::GetTypeNameForQualType(valobj.GetClangAST(), type).c_str());
+        clang_type = clang_type.RemoveFastQualifiers();
+
+        ConstString typeName(clang_type.GetConstTypeName());
         
         if (valobj.GetBitfieldBitSize() > 0)
         {
@@ -569,33 +563,30 @@
             log->Printf("[Get_Impl] no direct match");
         
         // strip pointers and references and see if that helps
-        if (typePtr->isReferenceType())
+        if (clang_type.IsReferenceType())
         {
             if (log)
                 log->Printf("[Get_Impl] stripping reference");
-            if (Get_Impl(valobj,type.getNonReferenceType(),entry, use_dynamic, reason) && !entry->SkipsReferences())
+            if (Get_Impl(valobj, clang_type.GetNonReferenceType(), entry, use_dynamic, reason) && !entry->SkipsReferences())
             {
                 reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
                 return true;
             }
         }
-        else if (typePtr->isPointerType())
+        else if (clang_type.IsPointerType())
         {
             if (log)
                 log->Printf("[Get_Impl] stripping pointer");
-            clang::QualType pointee = typePtr->getPointeeType();
-            if (Get_Impl(valobj, pointee, entry, use_dynamic, reason) && !entry->SkipsPointers())
+            if (Get_Impl(valobj, clang_type.GetPointeeType(), entry, use_dynamic, reason) && !entry->SkipsPointers())
             {
                 reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
                 return true;
             }
         }
         
-        bool canBeObjCDynamic = ClangASTContext::IsPossibleDynamicType (valobj.GetClangAST(),
-                                                                        type.getAsOpaquePtr(),
-                                                                        NULL,
-                                                                        false, // no C++
-                                                                        true); // yes ObjC
+        bool canBeObjCDynamic = valobj.GetClangType().IsPossibleDynamicType (NULL,
+                                                                             false, // no C++
+                                                                             true); // yes ObjC
         
         if (canBeObjCDynamic)
         {
@@ -611,8 +602,7 @@
             }
             if (log)
                 log->Printf("[Get_Impl] dynamic disabled or failed - stripping ObjC pointer");
-            clang::QualType pointee = typePtr->getPointeeType();
-            if (Get_Impl(valobj, pointee, entry, use_dynamic, reason) && !entry->SkipsPointers())
+            if (Get_Impl(valobj, clang_type.GetPointeeType(), entry, use_dynamic, reason) && !entry->SkipsPointers())
             {
                 reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
                 return true;
@@ -620,12 +610,11 @@
         }
         
         // try to strip typedef chains
-        const clang::TypedefType* type_tdef = type->getAs<clang::TypedefType>();
-        if (type_tdef)
+        if (clang_type.IsTypedefType())
         {
             if (log)
                 log->Printf("[Get_Impl] stripping typedef");
-            if ((Get_Impl(valobj, type_tdef->getDecl()->getUnderlyingType(), entry, use_dynamic, reason)) && entry->Cascades())
+            if ((Get_Impl(valobj, clang_type.GetTypedefedType(), entry, use_dynamic, reason)) && entry->Cascades())
             {
                 reason |= lldb_private::eFormatterChoiceCriterionNavigatedTypedefs;
                 return true;
@@ -639,40 +628,35 @@
     // we are separately passing in valobj and type because the valobj is fixed (and is used for ObjC discovery and bitfield size)
     // but the type can change (e.g. stripping pointers, ...)
     bool Get (ValueObject& valobj,
-              clang::QualType type,
+              ClangASTType clang_type,
               MapValueType& entry,
               lldb::DynamicValueType use_dynamic,
               uint32_t& reason)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
         
-        if (Get_Impl (valobj,type,entry,use_dynamic,reason))
+        if (Get_Impl (valobj, clang_type, entry, use_dynamic, reason))
             return true;
         
         // try going to the unqualified type
         do {
             if (log)
                 log->Printf("[Get] trying the unqualified type");
-            lldb::clang_type_t opaque_type = type.getAsOpaquePtr();
-            if (!opaque_type)
-            {
-                if (log)
-                    log->Printf("[Get] could not get the opaque_type");
+            if (!clang_type.IsValid())
                 break;
-            }
-            ClangASTType unqual_clang_ast_type = ClangASTType::GetFullyUnqualifiedType(valobj.GetClangAST(),opaque_type);
+
+            ClangASTType unqual_clang_ast_type = clang_type.GetFullyUnqualifiedType();
             if (!unqual_clang_ast_type.IsValid())
             {
                 if (log)
                     log->Printf("[Get] could not get the unqual_clang_ast_type");
                 break;
             }
-            clang::QualType unqualified_qual_type = clang::QualType::getFromOpaquePtr(unqual_clang_ast_type.GetOpaqueQualType());
-            if (unqualified_qual_type.getTypePtrOrNull() != type.getTypePtrOrNull())
+            if (unqual_clang_ast_type.GetOpaqueQualType() != clang_type.GetOpaqueQualType())
             {
                 if (log)
                     log->Printf("[Get] unqualified type is there and is not the same, let's try");
-                if (Get_Impl (valobj,unqualified_qual_type,entry,use_dynamic,reason))
+                if (Get_Impl (valobj, unqual_clang_ast_type,entry, use_dynamic, reason))
                     return true;
             }
             else if (log)
@@ -689,7 +673,7 @@
             {
                 if (log)
                     log->Printf("[Get] has a static value - actually use it");
-                if (Get(*static_value_sp.get(), clang::QualType::getFromOpaquePtr(static_value_sp->GetClangType()) , entry, use_dynamic, reason))
+                if (Get(*static_value_sp.get(), static_value_sp->GetClangType(), entry, use_dynamic, reason))
                 {
                     reason |= lldb_private::eFormatterChoiceCriterionWentToStaticValue;
                     return true;
diff --git a/include/lldb/Expression/ASTDumper.h b/include/lldb/Expression/ASTDumper.h
index 5118eb3..47f7ea4 100644
--- a/include/lldb/Expression/ASTDumper.h
+++ b/include/lldb/Expression/ASTDumper.h
@@ -28,6 +28,7 @@
     ASTDumper (const clang::Type *type);
     ASTDumper (clang::QualType type);
     ASTDumper (lldb::clang_type_t type);
+    ASTDumper (const ClangASTType &clang_type);
     
     const char *GetCString();
     void ToSTDERR();
diff --git a/include/lldb/Expression/ClangASTSource.h b/include/lldb/Expression/ClangASTSource.h
index 020a815..3e41a9e 100644
--- a/include/lldb/Expression/ClangASTSource.h
+++ b/include/lldb/Expression/ClangASTSource.h
@@ -404,10 +404,8 @@
     /// @return
     ///     The imported type.
     //------------------------------------------------------------------
-    void *
-    GuardedCopyType (clang::ASTContext *dest_context, 
-                     clang::ASTContext *source_context,
-                     void *clang_type);
+    ClangASTType
+    GuardedCopyType (const ClangASTType &src_type);
     
     friend struct NameSearchContext;
     
@@ -434,7 +432,7 @@
     ClangASTImporter::NamespaceMapSP m_namespace_map;           ///< The mapping of all namespaces found for this request back to their modules
     const clang::DeclarationName &m_decl_name;                  ///< The name being looked for
     const clang::DeclContext *m_decl_context;                   ///< The DeclContext to put declarations into
-    llvm::SmallSet <lldb::clang_type_t, 5> m_function_types;    ///< All the types of functions that have been reported, so we don't report conflicts
+    llvm::SmallSet <ClangASTType, 5> m_function_types;    ///< All the types of functions that have been reported, so we don't report conflicts
     
     struct {
         bool variable                   : 1;
@@ -479,7 +477,7 @@
     /// @param[in] type
     ///     The opaque QualType for the VarDecl being registered.
     //------------------------------------------------------------------
-    clang::NamedDecl *AddVarDecl(void *type);
+    clang::NamedDecl *AddVarDecl(const ClangASTType &type);
     
     //------------------------------------------------------------------
     /// Create a FunDecl with the name being searched for and the provided
@@ -488,7 +486,7 @@
     /// @param[in] type
     ///     The opaque QualType for the FunDecl being registered.
     //------------------------------------------------------------------
-    clang::NamedDecl *AddFunDecl(void *type);
+    clang::NamedDecl *AddFunDecl(const ClangASTType &type);
     
     //------------------------------------------------------------------
     /// Create a FunDecl with the name being searched for and generic
@@ -504,7 +502,7 @@
     /// @param[in] type
     ///     The opaque QualType for the TypeDecl being registered.
     //------------------------------------------------------------------
-    clang::NamedDecl *AddTypeDecl(void *type);
+    clang::NamedDecl *AddTypeDecl(const ClangASTType &clang_type);
     
     
     //------------------------------------------------------------------
diff --git a/include/lldb/Expression/ClangExpressionDeclMap.h b/include/lldb/Expression/ClangExpressionDeclMap.h
index b8be7f0..b2a43e0 100644
--- a/include/lldb/Expression/ClangExpressionDeclMap.h
+++ b/include/lldb/Expression/ClangExpressionDeclMap.h
@@ -549,8 +549,8 @@
     /// @param[in] var
     ///     The variable to evaluate.
     ///
-    /// @param[in] parser_ast_context
-    ///     The AST context of the parser, to store the found type in.
+    /// @param[out] var_location
+    ///     The variable location value to fill in
     ///
     /// @param[out] found_type
     ///     The type of the found value, as it was found in the user process.
@@ -566,11 +566,11 @@
     ///     The Decl to be looked up.
     ///
     /// @return
-    ///     The LLDB Value for the variable.
+    ///     Return true if the value was successfully filled in.
     //------------------------------------------------------------------
-    Value *
+    bool
     GetVariableValue (lldb::VariableSP &var,
-                      clang::ASTContext *parser_ast_context,
+                      lldb_private::Value &var_location,
                       TypeFromUser *found_type = NULL,
                       TypeFromParser *parser_type = NULL);
     
diff --git a/include/lldb/Expression/ClangExpressionVariable.h b/include/lldb/Expression/ClangExpressionVariable.h
index 4f0ba67..620e604 100644
--- a/include/lldb/Expression/ClangExpressionVariable.h
+++ b/include/lldb/Expression/ClangExpressionVariable.h
@@ -25,6 +25,7 @@
 #include "lldb/lldb-public.h"
 #include "lldb/Core/ClangForward.h"
 #include "lldb/Core/ConstString.h"
+#include "lldb/Core/Value.h"
 #include "lldb/Symbol/TaggedASTType.h"
 
 namespace llvm {
@@ -98,7 +99,7 @@
             m_parser_type(),
             m_named_decl (NULL),
             m_llvm_value (NULL),
-            m_lldb_value (NULL),
+            m_lldb_value (),
             m_lldb_var   (),
             m_lldb_sym   (NULL)
         {
@@ -107,7 +108,7 @@
         TypeFromParser          m_parser_type;  ///< The type of the variable according to the parser
         const clang::NamedDecl *m_named_decl;   ///< The Decl corresponding to this variable
         llvm::Value            *m_llvm_value;   ///< The IR value corresponding to this variable; usually a GlobalValue
-        lldb_private::Value    *m_lldb_value;   ///< The value found in LLDB for this variable
+        lldb_private::Value     m_lldb_value;   ///< The value found in LLDB for this variable
         lldb::VariableSP        m_lldb_var;     ///< The original variable for this variable
         const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol
     };
@@ -215,17 +216,11 @@
     void
     SetRegisterInfo (const RegisterInfo *reg_info);
 
-    lldb::clang_type_t
+    ClangASTType
     GetClangType ();
     
     void
-    SetClangType (lldb::clang_type_t);
-
-    clang::ASTContext *
-    GetClangAST ();
-    
-    void
-    SetClangAST (clang::ASTContext *ast);
+    SetClangType (const ClangASTType &clang_type);
 
     TypeFromUser
     GetTypeFromUser ();
@@ -420,8 +415,7 @@
     {
         lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
         var_sp->SetName (name);
-        var_sp->SetClangType (user_type.GetOpaqueQualType());
-        var_sp->SetClangAST (user_type.GetASTContext());
+        var_sp->SetClangType (user_type);
         m_variables.push_back(var_sp);
         return var_sp;
     }
diff --git a/include/lldb/Expression/ClangFunction.h b/include/lldb/Expression/ClangFunction.h
index ca7619f..3f96f7b 100644
--- a/include/lldb/Expression/ClangFunction.h
+++ b/include/lldb/Expression/ClangFunction.h
@@ -112,8 +112,7 @@
     ///     be overridden using WriteFunctionArguments().
 	//------------------------------------------------------------------
 	ClangFunction (ExecutionContextScope &exe_scope,
-                   ClangASTContext *ast_context, 
-                   void *return_qualtype, 
+                   const ClangASTType &return_type,
                    const Address& function_address, 
                    const ValueList &arg_value_list);
     
@@ -624,7 +623,7 @@
     
     Function                       *m_function_ptr;                 ///< The function we're going to call.  May be NULL if we don't have debug info for the function.
     Address                         m_function_addr;                ///< If we don't have the FunctionSP, we at least need the address & return type.
-    lldb::clang_type_t              m_function_return_qual_type;    ///< The opaque clang qual type for the function return type.
+    ClangASTType                    m_function_return_type;         ///< The opaque clang qual type for the function return type.
     ClangASTContext                *m_clang_ast_context;            ///< This is the clang_ast_context that we're getting types from the and value, and the function return the function pointer is NULL.
 
     std::string                     m_wrapper_function_name;        ///< The name of the wrapper function.
diff --git a/include/lldb/Expression/DWARFExpression.h b/include/lldb/Expression/DWARFExpression.h
index 35fa0a9..2692831 100644
--- a/include/lldb/Expression/DWARFExpression.h
+++ b/include/lldb/Expression/DWARFExpression.h
@@ -250,7 +250,6 @@
     //------------------------------------------------------------------
     bool
     Evaluate (ExecutionContextScope *exe_scope,
-              clang::ASTContext *ast_context,
               ClangExpressionVariableList *expr_locals,
               ClangExpressionDeclMap *decl_map,
               lldb::addr_t loclist_base_load_addr,
@@ -264,7 +263,6 @@
     //------------------------------------------------------------------
     bool
     Evaluate (ExecutionContext *exe_ctx,
-              clang::ASTContext *ast_context,
               ClangExpressionVariableList *expr_locals,
               ClangExpressionDeclMap *decl_map,
               RegisterContext *reg_ctx,
@@ -281,9 +279,6 @@
     ///     expression.  The location expression may access the target's
     ///     memory, especially if it comes from the expression parser.
     ///
-    /// @param[in] ast_context
-    ///     The context in which to interpret types.
-    ///
     /// @param[in] opcodes
     ///     This is a static method so the opcodes need to be provided
     ///     explicitly.
@@ -334,7 +329,6 @@
     //------------------------------------------------------------------
     static bool
     Evaluate (ExecutionContext *exe_ctx,
-              clang::ASTContext *ast_context,
               ClangExpressionVariableList *expr_locals,
               ClangExpressionDeclMap *decl_map,
               RegisterContext *reg_ctx,
diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h
index b3da283..75fc07b 100644
--- a/include/lldb/Symbol/ClangASTContext.h
+++ b/include/lldb/Symbol/ClangASTContext.h
@@ -35,31 +35,6 @@
 class ClangASTContext
 {
 public:
-    enum {
-        eTypeHasChildren        = (1u <<  0),
-        eTypeHasValue           = (1u <<  1),
-        eTypeIsArray            = (1u <<  2),
-        eTypeIsBlock            = (1u <<  3),
-        eTypeIsBuiltIn          = (1u <<  4),
-        eTypeIsClass            = (1u <<  5),
-        eTypeIsCPlusPlus        = (1u <<  6),
-        eTypeIsEnumeration      = (1u <<  7),
-        eTypeIsFuncPrototype    = (1u <<  8),
-        eTypeIsMember           = (1u <<  9),
-        eTypeIsObjC             = (1u << 10),
-        eTypeIsPointer          = (1u << 11),
-        eTypeIsReference        = (1u << 12),
-        eTypeIsStructUnion      = (1u << 13),
-        eTypeIsTemplate         = (1u << 14),
-        eTypeIsTypedef          = (1u << 15),
-        eTypeIsVector           = (1u << 16),
-        eTypeIsScalar           = (1u << 17),
-        eTypeIsInteger          = (1u << 18),
-        eTypeIsFloat            = (1u << 19),
-        eTypeIsComplex          = (1u << 20),
-        eTypeIsSigned           = (1u << 21)
-    };
-
     typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *);
     typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, clang::ObjCInterfaceDecl *);
     
@@ -123,20 +98,6 @@
 
     void
     RemoveExternalSource ();
-
-    bool
-    GetCompleteType (lldb::clang_type_t clang_type);
-    
-    static bool
-    GetCompleteType (clang::ASTContext *ast,
-                     lldb::clang_type_t clang_type);
-
-    bool
-    IsCompleteType (lldb::clang_type_t clang_type);
-    
-    static bool
-    IsCompleteType (clang::ASTContext *ast,
-                    lldb::clang_type_t clang_type);
     
     bool
     GetCompleteDecl (clang::Decl *decl)
@@ -175,70 +136,48 @@
     //------------------------------------------------------------------
     // Basic Types
     //------------------------------------------------------------------
-
-    lldb::clang_type_t
+    ClangASTType
     GetBuiltinTypeForEncodingAndBitSize (lldb::Encoding encoding,
                                           uint32_t bit_size);
-    
-    static lldb::clang_type_t
+
+    static ClangASTType
     GetBuiltinTypeForEncodingAndBitSize (clang::ASTContext *ast,
                                          lldb::Encoding encoding,
                                          uint32_t bit_size);
 
-    lldb::clang_type_t
+    ClangASTType
+    GetBasicType (lldb::BasicType type);
+
+    static ClangASTType
+    GetBasicType (clang::ASTContext *ast, lldb::BasicType type);
+    
+    static ClangASTType
+    GetBasicType (clang::ASTContext *ast, const ConstString &name);
+    
+    static lldb::BasicType
+    GetBasicTypeEnumeration (const ConstString &name);
+
+    ClangASTType
     GetBuiltinTypeForDWARFEncodingAndBitSize (
         const char *type_name,
         uint32_t dw_ate,
         uint32_t bit_size);
 
-    static lldb::clang_type_t
-    GetBuiltInType_void(clang::ASTContext *ast);
+    ClangASTType
+    GetCStringType(bool is_const);
     
-    lldb::clang_type_t
-    GetBuiltInType_void()
-    {
-        return GetBuiltInType_void(getASTContext());
-    }
-    
-    lldb::clang_type_t
-    GetBuiltInType_bool();
-
-    lldb::clang_type_t
-    GetBuiltInType_objc_id();
-    
-    static lldb::clang_type_t
-    GetBuiltInType_objc_id(clang::ASTContext *ast);
-
-    lldb::clang_type_t
-    GetBuiltInType_objc_Class();
-    
-    static lldb::clang_type_t
+    static ClangASTType
     GetUnknownAnyType(clang::ASTContext *ast);
     
-    lldb::clang_type_t
+    ClangASTType
     GetUnknownAnyType()
     {
         return ClangASTContext::GetUnknownAnyType(getASTContext());
     }
+    
+    uint32_t
+    GetPointerByteSize ();
 
-    lldb::clang_type_t
-    GetBuiltInType_objc_selector();
-
-    lldb::clang_type_t
-    GetCStringType(bool is_const);
-    
-    lldb::clang_type_t
-    GetVoidType();
-    
-    lldb::clang_type_t
-    GetVoidType(clang::ASTContext *ast);
-
-    lldb::clang_type_t
-    GetVoidPtrType(bool is_const);
-    
-    static lldb::clang_type_t
-    GetVoidPtrType(clang::ASTContext *ast, bool is_const);
-    
     static clang::DeclContext *
     GetTranslationUnitDecl (clang::ASTContext *ast);
     
@@ -254,10 +193,9 @@
                                       bool &is_instance_method,
                                       ConstString &language_object_name);
     
-    static lldb::clang_type_t
+    static ClangASTType
     CopyType(clang::ASTContext *dest_context, 
-             clang::ASTContext *source_context,
-             lldb::clang_type_t clang_type);
+             ClangASTType source_type);
     
     static clang::Decl *
     CopyDecl (clang::ASTContext *dest_context, 
@@ -265,146 +203,42 @@
               clang::Decl *source_decl);
 
     static bool
-    AreTypesSame(clang::ASTContext *ast,
-                 lldb::clang_type_t type1,
-                 lldb::clang_type_t type2,
+    AreTypesSame(ClangASTType type1,
+                 ClangASTType type2,
                  bool ignore_qualifiers = false);
     
-    bool
-    AreTypesSame(lldb::clang_type_t type1,
-                 lldb::clang_type_t type2,
-                 bool ignore_qualifiers = false)
-    {
-        return ClangASTContext::AreTypesSame(getASTContext(), type1, type2, ignore_qualifiers);
-    }
-    
-    
-    lldb::clang_type_t
+    ClangASTType
     GetTypeForDecl (clang::TagDecl *decl);
     
-    lldb::clang_type_t
+    ClangASTType
     GetTypeForDecl (clang::ObjCInterfaceDecl *objc_decl);
 
-    static lldb::BasicType
-    GetLLDBBasicTypeEnumeration (lldb::clang_type_t clang_type);
-
-    //------------------------------------------------------------------
-    // CVR modifiers
-    //------------------------------------------------------------------
-
-    static lldb::clang_type_t
-    AddConstModifier (lldb::clang_type_t clang_type);
-
-    static lldb::clang_type_t
-    AddRestrictModifier (lldb::clang_type_t clang_type);
-
-    static lldb::clang_type_t
-    AddVolatileModifier (lldb::clang_type_t clang_type);
-
     //------------------------------------------------------------------
     // Structure, Unions, Classes
     //------------------------------------------------------------------
 
-    lldb::clang_type_t
+    static clang::AccessSpecifier
+    ConvertAccessTypeToAccessSpecifier (lldb::AccessType access);
+
+    static clang::AccessSpecifier
+    UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs);
+
+    static uint32_t
+    GetNumBaseClasses (const clang::CXXRecordDecl *cxx_record_decl,
+                       bool omit_empty_base_classes);
+
+    static uint32_t
+    GetIndexForRecordBase (const clang::RecordDecl *record_decl,
+                           const clang::CXXBaseSpecifier *base_spec,
+                           bool omit_empty_base_classes);
+
+    ClangASTType
     CreateRecordType (clang::DeclContext *decl_ctx,
                       lldb::AccessType access_type,
                       const char *name,
                       int kind,
                       lldb::LanguageType language,
                       ClangASTMetadata *metadata = NULL);
-
-    static clang::FieldDecl *
-    AddFieldToRecordType (clang::ASTContext *ast,
-                          lldb::clang_type_t record_qual_type,
-                          const char *name,
-                          lldb::clang_type_t field_type,
-                          lldb::AccessType access,
-                          uint32_t bitfield_bit_size);
-    
-    clang::FieldDecl *
-    AddFieldToRecordType (lldb::clang_type_t record_qual_type,
-                          const char *name,
-                          lldb::clang_type_t field_type,
-                          lldb::AccessType access,
-                          uint32_t bitfield_bit_size)
-    {
-        return ClangASTContext::AddFieldToRecordType (getASTContext(),
-                                                      record_qual_type,
-                                                      name,
-                                                      field_type,
-                                                      access,
-                                                      bitfield_bit_size);
-    }
-    
-    clang::VarDecl *
-    AddVariableToRecordType (lldb::clang_type_t record_opaque_type,
-                             const char *name,
-                             lldb::clang_type_t var_opaque_type,
-                             lldb::AccessType access)
-    {
-        return ClangASTContext::AddVariableToRecordType (getASTContext(),
-                                                         record_opaque_type,
-                                                         name,
-                                                         var_opaque_type,
-                                                         access);
-    }
-
-    static clang::VarDecl *
-    AddVariableToRecordType (clang::ASTContext *ast,
-                             lldb::clang_type_t record_opaque_type,
-                             const char *name,
-                             lldb::clang_type_t var_opaque_type,
-                             lldb::AccessType access);
-
-    static void
-    BuildIndirectFields (clang::ASTContext *ast,
-                         lldb::clang_type_t record_qual_type);
-    
-    void
-    BuildIndirectFields (lldb::clang_type_t record_qual_type)
-    {
-        ClangASTContext::BuildIndirectFields(getASTContext(),
-                                             record_qual_type);
-    }
-    
-    static clang::CXXMethodDecl *
-    AddMethodToCXXRecordType (clang::ASTContext *ast,
-                              lldb::clang_type_t record_opaque_type,
-                              const char *name,
-                              lldb::clang_type_t method_type,
-                              lldb::AccessType access,
-                              bool is_virtual,
-                              bool is_static,
-                              bool is_inline,
-                              bool is_explicit,
-                              bool is_attr_used,
-                              bool is_artificial);
-    
-    clang::CXXMethodDecl *
-    AddMethodToCXXRecordType (lldb::clang_type_t record_opaque_type,
-                              const char *name,
-                              lldb::clang_type_t method_type,
-                              lldb::AccessType access,
-                              bool is_virtual,
-                              bool is_static,
-                              bool is_inline,
-                              bool is_explicit,
-                              bool is_attr_used,
-                              bool is_artificial)
-    
-    {
-        return ClangASTContext::AddMethodToCXXRecordType (getASTContext(),
-                                                          record_opaque_type,
-                                                          name,
-                                                          method_type,
-                                                          access,
-                                                          is_virtual,
-                                                          is_static,
-                                                          is_inline,
-                                                          is_explicit,
-                                                          is_attr_used,
-                                                          is_artificial);
-    }
     
     class TemplateParameterInfos
     {
@@ -453,7 +287,7 @@
                                            int kind,
                                            const TemplateParameterInfos &infos);
 
-    lldb::clang_type_t
+    ClangASTType
     CreateClassTemplateSpecializationType (clang::ClassTemplateSpecializationDecl *class_template_specialization_decl);
 
     static clang::DeclContext *
@@ -479,292 +313,16 @@
     static bool
     RecordHasFields (const clang::RecordDecl *record_decl);
 
-    void
-    SetDefaultAccessForRecordFields (lldb::clang_type_t clang_type,
-                                     int default_accessibility,
-                                     int *assigned_accessibilities,
-                                     size_t num_assigned_accessibilities);
 
-    lldb::clang_type_t
+    ClangASTType
     CreateObjCClass (const char *name, 
                      clang::DeclContext *decl_ctx, 
                      bool isForwardDecl, 
                      bool isInternal,
                      ClangASTMetadata *metadata = NULL);
-    
-    static clang::FieldDecl *
-    AddObjCClassIVar (clang::ASTContext *ast,
-                      lldb::clang_type_t class_opaque_type, 
-                      const char *name, 
-                      lldb::clang_type_t ivar_opaque_type, 
-                      lldb::AccessType access, 
-                      uint32_t bitfield_bit_size, 
-                      bool isSynthesized);
-    
-    clang::FieldDecl *
-    AddObjCClassIVar (lldb::clang_type_t class_opaque_type, 
-                      const char *name, 
-                      lldb::clang_type_t ivar_opaque_type, 
-                      lldb::AccessType access, 
-                      uint32_t bitfield_bit_size, 
-                      bool isSynthesized)
-    {
-        return ClangASTContext::AddObjCClassIVar (getASTContext(),
-                                                  class_opaque_type,
-                                                  name,
-                                                  ivar_opaque_type,
-                                                  access,
-                                                  bitfield_bit_size,
-                                                  isSynthesized);
-    }
-
-    static bool
-    AddObjCClassProperty 
-    (
-        clang::ASTContext *ast,
-        lldb::clang_type_t class_opaque_type, 
-        const char *property_name,
-        lldb::clang_type_t property_opaque_type,  // The property type is only required if you don't have an ivar decl
-        clang::ObjCIvarDecl *ivar_decl,   
-        const char *property_setter_name,
-        const char *property_getter_name,
-        uint32_t property_attributes,
-        ClangASTMetadata *metadata = NULL
-    );
-
-    bool
-    AddObjCClassProperty 
-    (
-        lldb::clang_type_t class_opaque_type, 
-        const char *property_name,
-        lldb::clang_type_t property_opaque_type,  
-        clang::ObjCIvarDecl *ivar_decl,   
-        const char *property_setter_name,
-        const char *property_getter_name,
-        uint32_t property_attributes,
-        ClangASTMetadata *metadata = NULL
-    )
-    {
-        return ClangASTContext::AddObjCClassProperty (getASTContext(),
-                                                      class_opaque_type, 
-                                                      property_name,
-                                                      property_opaque_type,
-                                                      ivar_decl,
-                                                      property_setter_name,
-                                                      property_getter_name,
-                                                      property_attributes,
-                                                      metadata);
-    }
-    
-    bool
-    SetObjCSuperClass (lldb::clang_type_t class_clang_type,
-                       lldb::clang_type_t superclass_clang_type);
-
-    static bool
-    ObjCTypeHasIVars (lldb::clang_type_t class_clang_type, bool check_superclass);
-
-    static bool
-    ObjCDeclHasIVars (clang::ObjCInterfaceDecl *class_interface_decl, 
-                      bool check_superclass);
-
-
-    static clang::ObjCMethodDecl *
-    AddMethodToObjCObjectType (clang::ASTContext *ast,
-                               lldb::clang_type_t class_opaque_type, 
-                               const char *name,  // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
-                               lldb::clang_type_t method_opaque_type,
-                               lldb::AccessType access,
-                               bool is_artificial);
-
-    clang::ObjCMethodDecl *
-    AddMethodToObjCObjectType (lldb::clang_type_t class_opaque_type, 
-                               const char *name,  // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
-                               lldb::clang_type_t method_opaque_type,
-                               lldb::AccessType access,
-                               bool is_artificial)
-    {
-        return AddMethodToObjCObjectType (getASTContext(),
-                                          class_opaque_type,
-                                          name,
-                                          method_opaque_type,
-                                          access, is_artificial);
-    }
-
-    static bool
-    SetHasExternalStorage (lldb::clang_type_t clang_type, bool has_extern);
-
-    //------------------------------------------------------------------
-    // Aggregate Types
-    //------------------------------------------------------------------
-    static bool
-    IsAggregateType (lldb::clang_type_t clang_type);
 
     // Returns a mask containing bits from the ClangASTContext::eTypeXXX enumerations
-    static uint32_t
-    GetTypeInfo (lldb::clang_type_t clang_type, 
-                 clang::ASTContext *ast,                // The AST for clang_type (can be NULL)
-                 lldb::clang_type_t *pointee_or_element_type);  // (can be NULL)
 
-    static uint32_t
-    GetNumChildren (clang::ASTContext *ast,
-                    lldb::clang_type_t clang_type,
-                    bool omit_empty_base_classes);
-
-    static uint32_t 
-    GetNumDirectBaseClasses (clang::ASTContext *ast, 
-                             lldb::clang_type_t clang_type);
-
-    static uint32_t 
-    GetNumVirtualBaseClasses (clang::ASTContext *ast, 
-                              lldb::clang_type_t clang_type);
-
-    static uint32_t 
-    GetNumFields (clang::ASTContext *ast, 
-                  lldb::clang_type_t clang_type);
-    
-    static lldb::clang_type_t
-    GetDirectBaseClassAtIndex (clang::ASTContext *ast, 
-                               lldb::clang_type_t clang_type,
-                               size_t idx, 
-                               uint32_t *bit_offset_ptr);
-
-    static lldb::clang_type_t
-    GetVirtualBaseClassAtIndex (clang::ASTContext *ast, 
-                                lldb::clang_type_t clang_type,
-                                size_t idx, 
-                                uint32_t *bit_offset_ptr);
-
-    static lldb::clang_type_t
-    GetFieldAtIndex (clang::ASTContext *ast, 
-                     lldb::clang_type_t clang_type,
-                     size_t idx, 
-                     std::string& name,
-                     uint64_t *bit_offset_ptr,
-                     uint32_t *bitfield_bit_size_ptr,
-                     bool *is_bitfield_ptr);
-    
-    static size_t
-    GetIndexOfFieldWithName (clang::ASTContext *ast,
-                             lldb::clang_type_t clang_type,
-                             const char* name,
-                             lldb::clang_type_t* field_clang_type = NULL,
-                             uint64_t *bit_offset_ptr = NULL,
-                             uint32_t *bitfield_bit_size_ptr = NULL,
-                             bool *is_bitfield_ptr = NULL);
-
-    static uint32_t
-    GetNumPointeeChildren (lldb::clang_type_t clang_type);
-
-    lldb::clang_type_t
-    GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
-                              const char *parent_name,
-                              lldb::clang_type_t  parent_clang_type,
-                              size_t idx,
-                              bool transparent_pointers,
-                              bool omit_empty_base_classes,
-                              bool ignore_array_bounds,
-                              std::string& child_name,
-                              uint32_t &child_byte_size,
-                              int32_t &child_byte_offset,
-                              uint32_t &child_bitfield_bit_size,
-                              uint32_t &child_bitfield_bit_offset,
-                              bool &child_is_base_class,
-                              bool &child_is_deref_of_parent);
- 
-    static lldb::clang_type_t
-    GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
-                              clang::ASTContext *ast,
-                              const char *parent_name,
-                              lldb::clang_type_t  parent_clang_type,
-                              size_t idx,
-                              bool transparent_pointers,
-                              bool omit_empty_base_classes,
-                              bool ignore_array_bounds,
-                              std::string& child_name,
-                              uint32_t &child_byte_size,
-                              int32_t &child_byte_offset,
-                              uint32_t &child_bitfield_bit_size,
-                              uint32_t &child_bitfield_bit_offset,
-                              bool &child_is_base_class,
-                              bool &child_is_deref_of_parent);
-    
-    // Lookup a child given a name. This function will match base class names
-    // and member member names in "clang_type" only, not descendants.
-    static uint32_t
-    GetIndexOfChildWithName (clang::ASTContext *ast,
-                             lldb::clang_type_t clang_type,
-                             const char *name,
-                             bool omit_empty_base_classes);
-
-    // Lookup a child member given a name. This function will match member names
-    // only and will descend into "clang_type" children in search for the first
-    // member in this class, or any base class that matches "name".
-    // TODO: Return all matches for a given name by returning a vector<vector<uint32_t>>
-    // so we catch all names that match a given child name, not just the first.
-    static size_t
-    GetIndexOfChildMemberWithName (clang::ASTContext *ast,
-                                   lldb::clang_type_t clang_type,
-                                   const char *name,
-                                   bool omit_empty_base_classes,
-                                   std::vector<uint32_t>& child_indexes);
-
-    size_t
-    GetNumTemplateArguments (lldb::clang_type_t clang_type)
-    {
-        return GetNumTemplateArguments(getASTContext(), clang_type);
-    }
-
-    lldb::clang_type_t
-    GetTemplateArgument (lldb::clang_type_t clang_type, 
-                         size_t idx, 
-                         lldb::TemplateArgumentKind &kind)
-    {
-        return GetTemplateArgument(getASTContext(), clang_type, idx, kind);
-    }
-
-    static size_t
-    GetNumTemplateArguments (clang::ASTContext *ast, 
-                             lldb::clang_type_t clang_type);
-    
-    static lldb::clang_type_t
-    GetTemplateArgument (clang::ASTContext *ast, 
-                         lldb::clang_type_t clang_type, 
-                         size_t idx, 
-                         lldb::TemplateArgumentKind &kind);
-
-    //------------------------------------------------------------------
-    // clang::TagType
-    //------------------------------------------------------------------
-
-    bool
-    SetTagTypeKind (lldb::clang_type_t  tag_qual_type,
-                    int kind);
-
-    //------------------------------------------------------------------
-    // C++ Base Classes
-    //------------------------------------------------------------------
-
-    clang::CXXBaseSpecifier *
-    CreateBaseClassSpecifier (lldb::clang_type_t  base_class_type,
-                              lldb::AccessType access,
-                              bool is_virtual,
-                              bool base_of_class);
-    
-    static void
-    DeleteBaseClassSpecifiers (clang::CXXBaseSpecifier **base_classes, 
-                               unsigned num_base_classes);
-
-    bool
-    SetBaseClassesForClassType (lldb::clang_type_t  class_clang_type,
-                                clang::CXXBaseSpecifier const * const *base_classes,
-                                unsigned num_base_classes);
-
-    //------------------------------------------------------------------
-    // DeclContext Functions
-    //------------------------------------------------------------------
-
-    static clang::DeclContext *
-    GetDeclContextForType (lldb::clang_type_t  qual_type);
 
     //------------------------------------------------------------------
     // Namespace Declarations
@@ -781,21 +339,21 @@
     clang::FunctionDecl *
     CreateFunctionDeclaration (clang::DeclContext *decl_ctx,
                                const char *name,
-                               lldb::clang_type_t  function_Type,
+                               const ClangASTType &function_Type,
                                int storage,
                                bool is_inline);
     
-    static lldb::clang_type_t
+    static ClangASTType
     CreateFunctionType (clang::ASTContext *ast,
-                        lldb::clang_type_t result_type,
-                        lldb::clang_type_t *args,
+                        const ClangASTType &result_type,
+                        const ClangASTType *args,
                         unsigned num_args,
                         bool is_variadic,
                         unsigned type_quals);
     
-    lldb::clang_type_t
-    CreateFunctionType (lldb::clang_type_t result_type,
-                        lldb::clang_type_t *args,
+    ClangASTType
+    CreateFunctionType (const ClangASTType &result_type,
+                        const ClangASTType *args,
                         unsigned num_args,
                         bool is_variadic,
                         unsigned type_quals)
@@ -810,8 +368,8 @@
     
     clang::ParmVarDecl *
     CreateParameterDeclaration (const char *name,
-                               lldb::clang_type_t param_type,
-                               int storage);
+                                const ClangASTType &param_type,
+                                int storage);
 
     void
     SetFunctionParameters (clang::FunctionDecl *function_decl,
@@ -822,222 +380,54 @@
     // Array Types
     //------------------------------------------------------------------
 
-    lldb::clang_type_t
-    CreateArrayType (lldb::clang_type_t element_type,
+    ClangASTType
+    CreateArrayType (const ClangASTType &element_type,
                      size_t element_count,
                      bool is_vector);
 
     //------------------------------------------------------------------
-    // Tag Declarations
-    //------------------------------------------------------------------
-    bool
-    StartTagDeclarationDefinition (lldb::clang_type_t  qual_type);
-
-    bool
-    CompleteTagDeclarationDefinition (lldb::clang_type_t  qual_type);
-
-    //------------------------------------------------------------------
     // Enumeration Types
     //------------------------------------------------------------------
-    lldb::clang_type_t
+    ClangASTType
     CreateEnumerationType (const char *name, 
                            clang::DeclContext *decl_ctx, 
                            const Declaration &decl, 
-                           lldb::clang_type_t integer_qual_type);
-
-    static lldb::clang_type_t
-    GetEnumerationIntegerType (lldb::clang_type_t enum_clang_type);
-    
-    bool
-    AddEnumerationValueToEnumerationType (lldb::clang_type_t  enum_qual_type,
-                                          lldb::clang_type_t  enumerator_qual_type,
-                                          const Declaration &decl,
-                                          const char *name,
-                                          int64_t enum_value,
-                                          uint32_t enum_value_bit_size);
+                           const ClangASTType &integer_qual_type);
     
     //------------------------------------------------------------------
-    // Pointers & References
+    // Floating point functions
     //------------------------------------------------------------------
-    lldb::clang_type_t
-    CreatePointerType (lldb::clang_type_t clang_type);
-
-    static lldb::clang_type_t
-    CreatePointerType (clang::ASTContext *ast, 
-                       lldb::clang_type_t clang_type);
-
-    static lldb::clang_type_t
-    CreateLValueReferenceType (clang::ASTContext *ast_context,
-                               lldb::clang_type_t clang_type);
     
-    static lldb::clang_type_t
-    CreateRValueReferenceType (clang::ASTContext *ast_context,
-                               lldb::clang_type_t clang_type);
-    
-    lldb::clang_type_t
-    CreateLValueReferenceType (lldb::clang_type_t clang_type)
-    {
-        return ClangASTContext::CreateLValueReferenceType(getASTContext(), clang_type);
-    }
-
-    lldb::clang_type_t
-    CreateRValueReferenceType (lldb::clang_type_t clang_type)
-    {
-        return ClangASTContext::CreateRValueReferenceType(getASTContext(), clang_type);
-    }
-
-    lldb::clang_type_t
-    CreateMemberPointerType (lldb::clang_type_t  clang_pointee_type,
-                             lldb::clang_type_t  clang_class_type);
-
-    uint64_t
-    GetPointerBitSize ();
-
-    static bool
-    IsIntegerType (lldb::clang_type_t clang_type, bool &is_signed);
-    
-    static bool
-    IsPointerType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type = NULL);
-
-    static bool
-    IsReferenceType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type = NULL);
-    
-    static bool
-    IsPointerOrReferenceType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type = NULL);
-    
-    static bool
-    IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast,
-                                    lldb::clang_type_t clang_type, 
-                                    lldb::clang_type_t *target_type = NULL);
-
-    static bool
-    IsPossibleDynamicType (clang::ASTContext *ast, 
-                           lldb::clang_type_t clang_type, 
-                           lldb::clang_type_t *dynamic_pointee_type, // Can pass NULL
-                           bool check_cplusplus,
-                           bool check_objc);
-
-    static bool
-    IsCStringType (lldb::clang_type_t clang_type, uint32_t &length);
-
-    static bool
-    IsFunctionPointerType (lldb::clang_type_t clang_type);
-    
-    static lldb::clang_type_t
-    GetAsArrayType (lldb::clang_type_t clang_type, 
-                    lldb::clang_type_t *member_type,
-                    uint64_t *size,
-                    bool *is_incomplete);
-    
-    static bool
-    IsArrayType (lldb::clang_type_t clang_type,
-                 lldb::clang_type_t *member_type,
-                 uint64_t *size,
-                 bool *is_incomplete)
-    {
-        return GetAsArrayType(clang_type, member_type, size, is_incomplete) != 0;
-    }
-
-    //------------------------------------------------------------------
-    // Typedefs
-    //------------------------------------------------------------------
-    lldb::clang_type_t
-    CreateTypedefType (const char *name,
-                       lldb::clang_type_t clang_type,
-                       clang::DeclContext *decl_ctx);
-
-    //------------------------------------------------------------------
-    // Type names
-    //------------------------------------------------------------------
-    static bool
-    IsFloatingPointType (lldb::clang_type_t clang_type, uint32_t &count, bool &is_complex);
-    
-    // true iff this is one of the types that can "fit"
-    // in a Scalar object
-    static bool
-    IsScalarType (lldb::clang_type_t clang_type);
-    
-    static bool
-    IsPointerToScalarType (lldb::clang_type_t clang_type);
-
-    static bool
-    IsArrayOfScalarType (lldb::clang_type_t clang_type);
-    
-    static bool
-    GetCXXClassName (lldb::clang_type_t clang_type, 
-                     std::string &class_name);
-
-    static bool
-    IsCXXClassType (lldb::clang_type_t clang_type);
-    
-    static bool
-    IsBeingDefined (lldb::clang_type_t clang_type);
-    
-    static bool
-    IsObjCClassType (lldb::clang_type_t clang_type);
-    
-    static bool
-    IsObjCObjectPointerType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type);
-    
-    static bool
-    GetObjCClassName (lldb::clang_type_t clang_type,
-                      std::string &class_name);
-
-    static bool
-    IsCharType (lldb::clang_type_t clang_type);
-
-    static size_t
-    GetArraySize (lldb::clang_type_t clang_type);
-
-    //static bool
-    //ConvertFloatValueToString (clang::ASTContext *ast, 
-    //                           lldb::clang_type_t clang_type, 
-    //                           const uint8_t* bytes, 
-    //                           size_t byte_size, 
-    //                           int apint_byte_order, 
-    //                           std::string &float_str);
-    
-    static size_t
-    ConvertStringToFloatValue (clang::ASTContext *ast, 
-                               lldb::clang_type_t clang_type, 
-                               const char *s, 
-                               uint8_t *dst, 
-                               size_t dst_size);
-
-    lldb::clang_type_t
+    ClangASTType
     GetFloatTypeFromBitSize (size_t bit_size)
     {
         return GetFloatTypeFromBitSize (getASTContext(), bit_size);
     }
 
-    static lldb::clang_type_t
+    static ClangASTType
     GetFloatTypeFromBitSize (clang::ASTContext *ast,
                              size_t bit_size);
-    //------------------------------------------------------------------
-    // Qualifiers
-    //------------------------------------------------------------------
-    static unsigned
-    GetTypeQualifiers(lldb::clang_type_t clang_type);
 protected:
     //------------------------------------------------------------------
     // Classes that inherit from ClangASTContext can see and modify these
     //------------------------------------------------------------------
     std::string                                     m_target_triple;
-    std::unique_ptr<clang::ASTContext>               m_ast_ap;
-    std::unique_ptr<clang::LangOptions>              m_language_options_ap;
-    std::unique_ptr<clang::FileManager>              m_file_manager_ap;
-    std::unique_ptr<clang::FileSystemOptions>        m_file_system_options_ap;
-    std::unique_ptr<clang::SourceManager>            m_source_manager_ap;
-    std::unique_ptr<clang::DiagnosticsEngine>        m_diagnostics_engine_ap;
-    std::unique_ptr<clang::DiagnosticConsumer>       m_diagnostic_consumer_ap;
+    std::unique_ptr<clang::ASTContext>              m_ast_ap;
+    std::unique_ptr<clang::LangOptions>             m_language_options_ap;
+    std::unique_ptr<clang::FileManager>             m_file_manager_ap;
+    std::unique_ptr<clang::FileSystemOptions>       m_file_system_options_ap;
+    std::unique_ptr<clang::SourceManager>           m_source_manager_ap;
+    std::unique_ptr<clang::DiagnosticsEngine>       m_diagnostics_engine_ap;
+    std::unique_ptr<clang::DiagnosticConsumer>      m_diagnostic_consumer_ap;
     llvm::IntrusiveRefCntPtr<clang::TargetOptions>  m_target_options_rp;
-    std::unique_ptr<clang::TargetInfo>               m_target_info_ap;
-    std::unique_ptr<clang::IdentifierTable>          m_identifier_table_ap;
-    std::unique_ptr<clang::SelectorTable>            m_selector_table_ap;
-    std::unique_ptr<clang::Builtin::Context>         m_builtins_ap;
+    std::unique_ptr<clang::TargetInfo>              m_target_info_ap;
+    std::unique_ptr<clang::IdentifierTable>         m_identifier_table_ap;
+    std::unique_ptr<clang::SelectorTable>           m_selector_table_ap;
+    std::unique_ptr<clang::Builtin::Context>        m_builtins_ap;
     CompleteTagDeclCallback                         m_callback_tag_decl;
     CompleteObjCInterfaceDeclCallback               m_callback_objc_decl;
     void *                                          m_callback_baton;
+    uint32_t                                        m_pointer_byte_size;
 private:
     //------------------------------------------------------------------
     // For ClangASTContext only
diff --git a/include/lldb/Symbol/ClangASTImporter.h b/include/lldb/Symbol/ClangASTImporter.h
index bc23230..10df7da 100644
--- a/include/lldb/Symbol/ClangASTImporter.h
+++ b/include/lldb/Symbol/ClangASTImporter.h
@@ -14,7 +14,6 @@
 #include <set>
 
 #include "lldb/lldb-types.h"
-
 #include "clang/AST/ASTImporter.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
diff --git a/include/lldb/Symbol/ClangASTType.h b/include/lldb/Symbol/ClangASTType.h
index 63a2e1e..d9e754e 100644
--- a/include/lldb/Symbol/ClangASTType.h
+++ b/include/lldb/Symbol/ClangASTType.h
@@ -13,6 +13,7 @@
 #include <string>
 #include "lldb/lldb-private.h"
 #include "lldb/Core/ClangForward.h"
+#include "clang/AST/Type.h"
 
 namespace lldb_private {
 
@@ -29,16 +30,46 @@
 class ClangASTType
 {
 public:
+    enum {
+        eTypeHasChildren        = (1u <<  0),
+        eTypeHasValue           = (1u <<  1),
+        eTypeIsArray            = (1u <<  2),
+        eTypeIsBlock            = (1u <<  3),
+        eTypeIsBuiltIn          = (1u <<  4),
+        eTypeIsClass            = (1u <<  5),
+        eTypeIsCPlusPlus        = (1u <<  6),
+        eTypeIsEnumeration      = (1u <<  7),
+        eTypeIsFuncPrototype    = (1u <<  8),
+        eTypeIsMember           = (1u <<  9),
+        eTypeIsObjC             = (1u << 10),
+        eTypeIsPointer          = (1u << 11),
+        eTypeIsReference        = (1u << 12),
+        eTypeIsStructUnion      = (1u << 13),
+        eTypeIsTemplate         = (1u << 14),
+        eTypeIsTypedef          = (1u << 15),
+        eTypeIsVector           = (1u << 16),
+        eTypeIsScalar           = (1u << 17),
+        eTypeIsInteger          = (1u << 18),
+        eTypeIsFloat            = (1u << 19),
+        eTypeIsComplex          = (1u << 20),
+        eTypeIsSigned           = (1u << 21)
+    };
     
+
+    //----------------------------------------------------------------------
+    // Constructors and Destructors
+    //----------------------------------------------------------------------
     ClangASTType (clang::ASTContext *ast_context, lldb::clang_type_t type) :
         m_type (type),
         m_ast  (ast_context) 
     {
     }
-    
-    ClangASTType (const ClangASTType &tw) :
-        m_type (tw.m_type),
-        m_ast  (tw.m_ast)
+
+    ClangASTType (clang::ASTContext *ast_context, clang::QualType qual_type);
+
+    ClangASTType (const ClangASTType &rhs) :
+        m_type (rhs.m_type),
+        m_ast  (rhs.m_ast)
     {
     }
     
@@ -48,143 +79,502 @@
     {
     }
     
-    virtual ~ClangASTType();
+    ~ClangASTType();
     
+    //----------------------------------------------------------------------
+    // Operators
+    //----------------------------------------------------------------------
+
     const ClangASTType &
-    operator= (const ClangASTType &atb)
+    operator= (const ClangASTType &rhs)
     {
-        m_type = atb.m_type;
-        m_ast = atb.m_ast;
+        m_type = rhs.m_type;
+        m_ast = rhs.m_ast;
         return *this;
     }
     
+
+    //----------------------------------------------------------------------
+    // Tests
+    //----------------------------------------------------------------------
+
+    operator bool () const
+    {
+        return m_type != NULL && m_ast != NULL;
+    }
+    
+    bool
+    operator < (const ClangASTType &rhs) const
+    {
+        if (m_ast == rhs.m_ast)
+            return m_type < rhs.m_type;
+        return m_ast < rhs.m_ast;
+    }
+
     bool
     IsValid () const
     {
         return m_type != NULL && m_ast != NULL;
     }
+    
+    bool
+    IsArrayType (ClangASTType *element_type,
+                 uint64_t *size,
+                 bool *is_incomplete) const;
 
-    lldb::clang_type_t
-    GetOpaqueQualType() const
-    { 
-        return m_type; 
+    bool
+    IsArrayOfScalarType () const;
+
+    bool
+    IsAggregateType () const;
+    
+    bool
+    IsBeingDefined () const;
+
+    bool
+    IsCharType () const;
+
+    bool
+    IsCompleteType () const;
+    
+    bool
+    IsConst() const;
+    
+    bool
+    IsCStringType (uint32_t &length) const;
+
+    bool
+    IsCXXClassType () const;
+    
+    bool
+    IsDefined() const;
+    
+    bool
+    IsFloatingPointType (uint32_t &count, bool &is_complex) const;
+
+    bool
+    IsFunctionType (bool *is_variadic_ptr = NULL) const;
+
+    bool
+    IsVariadicFunctionType () const;
+
+    bool
+    IsFunctionPointerType () const;
+    
+    bool
+    IsIntegerType (bool &is_signed) const;
+
+    bool
+    IsObjCClassType () const;
+    
+    bool
+    IsObjCClassTypeAndHasIVars (bool check_superclass) const;
+    
+    bool
+    IsObjCObjectOrInterfaceType () const;
+
+    bool
+    IsObjCObjectPointerType (ClangASTType *target_type = NULL);
+    
+    bool
+    IsPolymorphicClass () const;
+
+    bool
+    IsPossibleCPlusPlusDynamicType (ClangASTType *target_type = NULL) const
+    {
+        return IsPossibleDynamicType (target_type, true, false);
     }
     
+    bool
+    IsPossibleDynamicType (ClangASTType *target_type, // Can pass NULL
+                           bool check_cplusplus,
+                           bool check_objc) const;
+
+
+    bool
+    IsPointerToScalarType () const;
+    
+    bool
+    IsPointerType (ClangASTType *pointee_type = NULL) const;
+    
+    bool
+    IsPointerOrReferenceType (ClangASTType *pointee_type = NULL) const;
+    
+    bool
+    IsReferenceType (ClangASTType *pointee_type = NULL) const;
+    
+    bool
+    IsScalarType () const;
+    
+    bool
+    IsTypedefType () const;
+
+    bool
+    IsVoidType () const;
+
+    bool
+    GetCXXClassName (std::string &class_name) const;
+    
+    bool
+    GetObjCClassName (std::string &class_name);
+    
+
+    //----------------------------------------------------------------------
+    // Type Completion
+    //----------------------------------------------------------------------
+    
+    bool
+    GetCompleteType () const;
+
+    //----------------------------------------------------------------------
+    // AST related queries
+    //----------------------------------------------------------------------
+
+    size_t
+    GetPointerByteSize () const;
+    
+    //----------------------------------------------------------------------
+    // Accessors
+    //----------------------------------------------------------------------
+    
     clang::ASTContext *
     GetASTContext() const
-    { 
-        return m_ast; 
-    }
-
-    static ClangASTType
-    GetCanonicalType (clang::ASTContext *ast, lldb::clang_type_t clang_type);
-
-    ClangASTType
-    GetCanonicalType ()
     {
-        return GetCanonicalType (GetASTContext(), GetOpaqueQualType());
+        return m_ast;
     }
-
-    ConstString
-    GetConstTypeName ();
     
     ConstString
-    GetConstQualifiedTypeName ();
+    GetConstQualifiedTypeName () const;
+
+    ConstString
+    GetConstTypeName () const;
+    
+    std::string
+    GetTypeName () const;
+
+    uint32_t
+    GetTypeInfo (ClangASTType *pointee_or_element_clang_type = NULL) const;
+    
+    lldb::LanguageType
+    GetMinimumLanguage ();
+
+    lldb::clang_type_t
+    GetOpaqueQualType() const
+    {
+        return m_type;
+    }
+
+    lldb::TypeClass
+    GetTypeClass () const;
+    
+    void
+    SetClangType (clang::ASTContext *ast, lldb::clang_type_t type)
+    {
+        m_ast = ast;
+        m_type = type;
+    }
+
+    void
+    SetClangType (clang::ASTContext *ast, clang::QualType qual_type);
+
+    unsigned
+    GetTypeQualifiers() const;
+    
+    //----------------------------------------------------------------------
+    // Creating related types
+    //----------------------------------------------------------------------
+
+    ClangASTType
+    AddConstModifier () const;
+
+    ClangASTType
+    AddRestrictModifier () const;
+
+    ClangASTType
+    AddVolatileModifier () const;
+    
+    // Using the current type, create a new typedef to that type using "typedef_name"
+    // as the name and "decl_ctx" as the decl context.
+    ClangASTType
+    CreateTypedefType (const char *typedef_name,
+                       clang::DeclContext *decl_ctx) const;
+    
+    ClangASTType
+    GetArrayElementType (uint64_t& stride) const;
+    
+    ClangASTType
+    GetCanonicalType () const;
+    
+    ClangASTType
+    GetFullyUnqualifiedType () const;
+    
+    // Returns -1 if this isn't a function of if the fucntion doesn't have a prototype
+    // Returns a value >= 0 if there is a prototype.
+    int
+    GetFunctionArgumentCount () const;
+
+    ClangASTType
+    GetFunctionArgumentTypeAtIndex (size_t idx);
+
+    ClangASTType
+    GetFunctionReturnType () const;
+    
+    ClangASTType
+    GetLValueReferenceType () const;
+    
+    ClangASTType
+    GetNonReferenceType () const;
+
+    ClangASTType
+    GetPointeeType () const;
+    
+    ClangASTType
+    GetPointerType () const;
+    
+    ClangASTType
+    GetRValueReferenceType () const;
+
+    // If the current object represents a typedef type, get the underlying type
+    ClangASTType
+    GetTypedefedType () const;
+
+    ClangASTType
+    RemoveFastQualifiers () const;
+    
+    //----------------------------------------------------------------------
+    // Create related types using the current type's AST
+    //----------------------------------------------------------------------
+    ClangASTType
+    GetBasicTypeFromAST (lldb::BasicType basic_type) const;
+
+    //----------------------------------------------------------------------
+    // Exploring the type
+    //----------------------------------------------------------------------
+
+    uint64_t
+    GetByteSize () const;
+
+    uint64_t
+    GetBitSize () const;
+
+    lldb::Encoding
+    GetEncoding (uint64_t &count) const;
+    
+    lldb::Format
+    GetFormat () const;
+    
+    size_t
+    GetTypeBitAlign () const;
+
+    uint32_t
+    GetNumChildren (bool omit_empty_base_classes) const;
+
+    lldb::BasicType
+    GetBasicTypeEnumeration () const;
 
     static lldb::BasicType
     GetBasicTypeEnumeration (const ConstString &name);
 
-    static ClangASTType
-    GetBasicType (clang::ASTContext *ast, lldb::BasicType type);
-
-    static ClangASTType
-    GetBasicType (clang::ASTContext *ast, const ConstString &name);
-
-    static ConstString
-    GetConstTypeName (clang::ASTContext *ast,
-                      lldb::clang_type_t clang_type);
+    uint32_t
+    GetNumDirectBaseClasses () const;
     
-    static ConstString
-    GetConstQualifiedTypeName (clang::ASTContext *ast,
-                               lldb::clang_type_t clang_type);
-
-    static std::string
-    GetTypeNameForQualType (clang::ASTContext *ast,
-                            clang::QualType qual_type);
-
-    static std::string
-    GetTypeNameForOpaqueQualType (clang::ASTContext *ast,
-                                  lldb::clang_type_t opaque_qual_type);
-
-    uint64_t
-    GetClangTypeByteSize ();
-
-    static uint64_t
-    GetClangTypeByteSize (clang::ASTContext *ast_context,
-                          lldb::clang_type_t clang_type);
+    uint32_t
+    GetNumVirtualBaseClasses () const;
     
-    uint64_t
-    GetClangTypeBitWidth ();
-
-    static uint64_t
-    GetClangTypeBitWidth (clang::ASTContext *ast_context, lldb::clang_type_t opaque_clang_qual_type);
-
-    size_t
-    GetTypeBitAlign ();
-    
-    static size_t
-    GetTypeBitAlign (clang::ASTContext *ast_context, lldb::clang_type_t clang_type);
-
-    lldb::LanguageType
-    GetMinimumLanguage ();
-
-    static lldb::LanguageType
-    GetMinimumLanguage (clang::ASTContext *ctx,
-                        lldb::clang_type_t clang_type);
-
-    static lldb::TypeClass
-    GetTypeClass (clang::ASTContext *ast_context, 
-                  lldb::clang_type_t clang_type);
-
-    lldb::TypeClass
-    GetTypeClass () const
-    {
-        return GetTypeClass (GetASTContext(), GetOpaqueQualType());
-    }
-    
-    bool
-    IsPolymorphicClass ()
-    {
-        return IsPolymorphicClass(GetASTContext(), GetOpaqueQualType());
-    }
-    
-    static bool
-    IsPolymorphicClass (clang::ASTContext *ast_context, lldb::clang_type_t clang_type);
+    uint32_t
+    GetNumFields () const;
     
     ClangASTType
-    GetFullyUnqualifiedType ();
+    GetDirectBaseClassAtIndex (size_t idx,
+                               uint32_t *bit_offset_ptr) const;
     
-    static ClangASTType
-    GetFullyUnqualifiedType (clang::ASTContext *ast_context, lldb::clang_type_t clang_type);
+    ClangASTType
+    GetVirtualBaseClassAtIndex (size_t idx,
+                                uint32_t *bit_offset_ptr) const;
+    
+    ClangASTType
+    GetFieldAtIndex (size_t idx,
+                     std::string& name,
+                     uint64_t *bit_offset_ptr,
+                     uint32_t *bitfield_bit_size_ptr,
+                     bool *is_bitfield_ptr) const;
+    
+    uint32_t
+    GetIndexOfFieldWithName (const char* name,
+                             ClangASTType* field_clang_type = NULL,
+                             uint64_t *bit_offset_ptr = NULL,
+                             uint32_t *bitfield_bit_size_ptr = NULL,
+                             bool *is_bitfield_ptr = NULL) const;
+    
+    uint32_t
+    GetNumPointeeChildren () const;
+    
+    ClangASTType
+    GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
+                              const char *parent_name,
+                              size_t idx,
+                              bool transparent_pointers,
+                              bool omit_empty_base_classes,
+                              bool ignore_array_bounds,
+                              std::string& child_name,
+                              uint32_t &child_byte_size,
+                              int32_t &child_byte_offset,
+                              uint32_t &child_bitfield_bit_size,
+                              uint32_t &child_bitfield_bit_offset,
+                              bool &child_is_base_class,
+                              bool &child_is_deref_of_parent) const;
+    
+    // Lookup a child given a name. This function will match base class names
+    // and member member names in "clang_type" only, not descendants.
+    uint32_t
+    GetIndexOfChildWithName (const char *name,
+                             bool omit_empty_base_classes) const;
+    
+    // Lookup a child member given a name. This function will match member names
+    // only and will descend into "clang_type" children in search for the first
+    // member in this class, or any base class that matches "name".
+    // TODO: Return all matches for a given name by returning a vector<vector<uint32_t>>
+    // so we catch all names that match a given child name, not just the first.
+    size_t
+    GetIndexOfChildMemberWithName (const char *name,
+                                   bool omit_empty_base_classes,
+                                   std::vector<uint32_t>& child_indexes) const;
+    
+    size_t
+    GetNumTemplateArguments () const;
+    
+    ClangASTType
+    GetTemplateArgument (size_t idx,
+                         lldb::TemplateArgumentKind &kind) const;
+
+
+    //----------------------------------------------------------------------
+    // Modifying RecordType
+    //----------------------------------------------------------------------
+    clang::FieldDecl *
+    AddFieldToRecordType (const char *name,
+                          const ClangASTType &field_type,
+                          lldb::AccessType access,
+                          uint32_t bitfield_bit_size);
     
     void
-    DumpValue (ExecutionContext *exe_ctx,
-               Stream *s,
-               lldb::Format format,
-               const DataExtractor &data,
-               lldb::offset_t data_offset,
-               size_t data_byte_size,
-               uint32_t bitfield_bit_size,
-               uint32_t bitfield_bit_offset,
-               bool show_types,
-               bool show_summary,
-               bool verbose,
-               uint32_t depth);
+    BuildIndirectFields ();
+    
+    clang::VarDecl *
+    AddVariableToRecordType (const char *name,
+                             const ClangASTType &var_type,
+                             lldb::AccessType access);
 
+    clang::CXXMethodDecl *
+    AddMethodToCXXRecordType (const char *name,
+                              const ClangASTType &method_type,
+                              lldb::AccessType access,
+                              bool is_virtual,
+                              bool is_static,
+                              bool is_inline,
+                              bool is_explicit,
+                              bool is_attr_used,
+                              bool is_artificial);
+    
+    // C++ Base Classes
+    clang::CXXBaseSpecifier *
+    CreateBaseClassSpecifier (lldb::AccessType access,
+                              bool is_virtual,
+                              bool base_of_class);
+    
     static void
-    DumpValue (clang::ASTContext *ast_context,
-               lldb::clang_type_t opaque_clang_qual_type,
-               ExecutionContext *exe_ctx,
+    DeleteBaseClassSpecifiers (clang::CXXBaseSpecifier **base_classes,
+                               unsigned num_base_classes);
+    
+    bool
+    SetBaseClassesForClassType (clang::CXXBaseSpecifier const * const *base_classes,
+                                unsigned num_base_classes);
+    
+
+    bool
+    SetObjCSuperClass (const ClangASTType &superclass_clang_type);
+    
+    bool
+    AddObjCClassProperty (const char *property_name,
+                          const ClangASTType &property_clang_type,
+                          clang::ObjCIvarDecl *ivar_decl,
+                          const char *property_setter_name,
+                          const char *property_getter_name,
+                          uint32_t property_attributes,
+                          ClangASTMetadata *metadata);
+
+    clang::ObjCMethodDecl *
+    AddMethodToObjCObjectType (const char *name,  // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
+                               const ClangASTType &method_clang_type,
+                               lldb::AccessType access,
+                               bool is_artificial);
+
+    clang::DeclContext *
+    GetDeclContextForType () const;
+
+    
+    bool
+    SetDefaultAccessForRecordFields (int default_accessibility,
+                                     int *assigned_accessibilities,
+                                     size_t num_assigned_accessibilities);
+    
+    bool
+    SetHasExternalStorage (bool has_extern);
+    
+    
+    //------------------------------------------------------------------
+    // clang::TagType
+    //------------------------------------------------------------------
+    
+    bool
+    SetTagTypeKind (int kind) const;
+    
+    //------------------------------------------------------------------
+    // Tag Declarations
+    //------------------------------------------------------------------
+    bool
+    StartTagDeclarationDefinition ();
+    
+    bool
+    CompleteTagDeclarationDefinition ();
+    
+    //----------------------------------------------------------------------
+    // Modifying Enumeration types
+    //----------------------------------------------------------------------
+    bool
+    AddEnumerationValueToEnumerationType (const ClangASTType &enumerator_qual_type,
+                                          const Declaration &decl,
+                                          const char *name,
+                                          int64_t enum_value,
+                                          uint32_t enum_value_bit_size);
+    
+
+    
+    ClangASTType
+    GetEnumerationIntegerType () const;
+
+    
+    //------------------------------------------------------------------
+    // Pointers & References
+    //------------------------------------------------------------------
+
+    // Call this function using the class type when you want to make a
+    // member pointer type to pointee_type.
+    ClangASTType
+    CreateMemberPointerType (const ClangASTType &pointee_type) const;
+    
+    
+    // Converts "s" to a floating point value and place resulting floating
+    // point bytes in the "dst" buffer.
+    size_t
+    ConvertStringToFloatValue (const char *s,
+                               uint8_t *dst,
+                               size_t dst_size) const;
+    //----------------------------------------------------------------------
+    // Dumping types
+    //----------------------------------------------------------------------
+    void
+    DumpValue (ExecutionContext *exe_ctx,
                Stream *s,
                lldb::Format format,
                const DataExtractor &data,
@@ -207,164 +597,50 @@
                    uint32_t bitfield_bit_offset,
                    ExecutionContextScope *exe_scope);
     
-    
-    static bool
-    DumpTypeValue (clang::ASTContext *ast_context,
-                   lldb::clang_type_t opaque_clang_qual_type,
-                   Stream *s,
-                   lldb::Format format,
-                   const DataExtractor &data,
-                   lldb::offset_t data_offset,
-                   size_t data_byte_size,
-                   uint32_t bitfield_bit_size,
-                   uint32_t bitfield_bit_offset,
-                   ExecutionContextScope *exe_scope);
-
     void
     DumpSummary (ExecutionContext *exe_ctx,
                  Stream *s,
                  const DataExtractor &data,
                  lldb::offset_t data_offset,
                  size_t data_byte_size);
-                 
-    
-    static void
-    DumpSummary (clang::ASTContext *ast_context,
-                 lldb::clang_type_t opaque_clang_qual_type,
-                 ExecutionContext *exe_ctx,
-                 Stream *s,
-                 const DataExtractor &data,
-                 lldb::offset_t data_offset,
-                 size_t data_byte_size);
-    
-    void
-    DumpTypeDescription (); // Dump to stdout
 
     void
-    DumpTypeDescription (Stream *s);
-    
-    static void
-    DumpTypeDescription (clang::ASTContext *ast_context,
-                         lldb::clang_type_t opaque_clang_qual_type,
-                         Stream *s);
-    
-    lldb::Encoding
-    GetEncoding (uint64_t &count);
+    DumpTypeDescription () const; // Dump to stdout
 
-    static lldb::Encoding
-    GetEncoding (lldb::clang_type_t opaque_clang_qual_type, uint64_t &count);
-
-    lldb::Format
-    GetFormat ();
-                 
-    static lldb::Format
-    GetFormat (lldb::clang_type_t opaque_clang_qual_type);
+    void
+    DumpTypeDescription (Stream *s) const;
     
-    uint64_t
-    GetTypeByteSize() const;
-    
-    static uint64_t
-    GetTypeByteSize(clang::ASTContext *ast_context,
-                    lldb::clang_type_t opaque_clang_qual_type);
-
     bool
     GetValueAsScalar (const DataExtractor &data,
                       lldb::offset_t data_offset,
                       size_t data_byte_size,
-                      Scalar &value);
+                      Scalar &value) const;
 
-    static bool
-    GetValueAsScalar (clang::ASTContext *ast_context,
-                      lldb::clang_type_t opaque_clang_qual_type,
-                      const DataExtractor &data,
-                      lldb::offset_t data_offset,
-                      size_t data_byte_size,
-                      Scalar &value);
-
-
-    bool
-    IsDefined();
-
-    static bool
-    IsDefined (lldb::clang_type_t opaque_clang_qual_type);
-
-    bool
-    IsConst();
-    
-    static bool
-    IsConst (lldb::clang_type_t opaque_clang_qual_type);
-    
     bool
     SetValueFromScalar (const Scalar &value,
                         Stream &strm);
 
-    static bool
-    SetValueFromScalar (clang::ASTContext *ast_context,
-                        lldb::clang_type_t opaque_clang_qual_type,
-                        const Scalar &value,
-                        Stream &strm);
-
-    void
-    SetClangType (clang::ASTContext *ast, lldb::clang_type_t type)
-    {
-        m_type = type;
-        m_ast = ast;
-    }
-
     bool
     ReadFromMemory (ExecutionContext *exe_ctx,
                     lldb::addr_t addr,
                     AddressType address_type,
                     DataExtractor &data);
 
-    static bool
-    ReadFromMemory (clang::ASTContext *ast_context,
-                    lldb::clang_type_t opaque_clang_qual_type,
-                    ExecutionContext *exe_ctx,
-                    lldb::addr_t addr,
-                    AddressType address_type,
-                    DataExtractor &data);
-
     bool
     WriteToMemory (ExecutionContext *exe_ctx,
                    lldb::addr_t addr,
                    AddressType address_type,
                    StreamString &new_value);
 
-    static bool
-    WriteToMemory (clang::ASTContext *ast_context,
-                   lldb::clang_type_t opaque_clang_qual_type,
-                   ExecutionContext *exe_ctx,
-                   lldb::addr_t addr,
-                   AddressType address_type,
-                   StreamString &new_value);
-
-    lldb::clang_type_t
-    GetPointeeType () const;
-
-    static lldb::clang_type_t
-    GetPointeeType (lldb::clang_type_t opaque_clang_qual_type);
     
-    lldb::clang_type_t
-    GetArrayElementType (uint64_t& stride);
+    clang::RecordDecl *
+    GetAsRecordDecl () const;
     
-    static lldb::clang_type_t
-    GetArrayElementType (clang::ASTContext* ast,
-                         lldb::clang_type_t opaque_clang_qual_type,
-						 uint64_t& stride);
+    clang::CXXRecordDecl *
+    GetAsCXXRecordDecl () const;
     
-    lldb::clang_type_t
-    GetPointerType () const;
-    
-    static lldb::clang_type_t
-    GetPointerType (clang::ASTContext *ast_context,
-                    lldb::clang_type_t opaque_clang_qual_type);
-
-    static lldb::clang_type_t
-    RemoveFastQualifiers (lldb::clang_type_t);
-
-    static clang::CXXRecordDecl *
-    GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type);
+    clang::ObjCInterfaceDecl *
+    GetAsObjCInterfaceDecl () const;
 
     void
     Clear()
@@ -373,9 +649,25 @@
         m_ast = NULL;
     }
 
+    clang::QualType
+    GetQualType () const
+    {
+        if (m_type)
+            return clang::QualType::getFromOpaquePtr(m_type);
+        return clang::QualType();
+    }
+    clang::QualType
+    GetCanonicalQualType () const
+    {
+        if (m_type)
+            return clang::QualType::getFromOpaquePtr(m_type).getCanonicalType();
+        return clang::QualType();
+    }
+
 private:
     lldb::clang_type_t m_type;
     clang::ASTContext *m_ast;
+    
 };
     
 bool operator == (const ClangASTType &lhs, const ClangASTType &rhs);
diff --git a/include/lldb/Symbol/Function.h b/include/lldb/Symbol/Function.h
index 55cc819..787f81c 100644
--- a/include/lldb/Symbol/Function.h
+++ b/include/lldb/Symbol/Function.h
@@ -564,19 +564,9 @@
     //------------------------------------------------------------------
     const Type*
     GetType() const;
-
-    lldb::clang_type_t
-    GetReturnClangType ();
-
-    // The Number of arguments, or -1 for an unprototyped function.
-    int
-    GetArgumentCount ();
-
-    lldb::clang_type_t
-    GetArgumentTypeAtIndex (size_t idx);
-
-    bool
-    IsVariadic ();
+    
+    ClangASTType
+    GetClangType ();
 
     uint32_t
     GetPrologueByteSize ();
diff --git a/include/lldb/Symbol/SymbolFile.h b/include/lldb/Symbol/SymbolFile.h
index ef433d3..5b774e3 100644
--- a/include/lldb/Symbol/SymbolFile.h
+++ b/include/lldb/Symbol/SymbolFile.h
@@ -128,7 +128,7 @@
     virtual size_t          ParseTypes (const SymbolContext& sc) = 0;
     virtual size_t          ParseVariablesForContext (const SymbolContext& sc) = 0;
     virtual Type*           ResolveTypeUID (lldb::user_id_t type_uid) = 0;
-    virtual lldb::clang_type_t ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type) = 0;
+    virtual bool            ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type) = 0;
     virtual clang::DeclContext* GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) { return NULL; }
     virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) { return NULL; }
     virtual uint32_t        ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) = 0;
diff --git a/include/lldb/Symbol/TaggedASTType.h b/include/lldb/Symbol/TaggedASTType.h
index fbd1897..c44a535 100644
--- a/include/lldb/Symbol/TaggedASTType.h
+++ b/include/lldb/Symbol/TaggedASTType.h
@@ -20,16 +20,30 @@
 template <unsigned int C> class TaggedASTType : public ClangASTType
 {
 public:
+    TaggedASTType (const ClangASTType &clang_type) :
+        ClangASTType(clang_type)
+    {
+    }
+
     TaggedASTType (lldb::clang_type_t type, clang::ASTContext *ast_context) :
-        ClangASTType(ast_context, type) { }
+        ClangASTType(ast_context, type)
+    {
+    }
     
     TaggedASTType (const TaggedASTType<C> &tw) :
-        ClangASTType(tw) { }
+        ClangASTType(tw)
+    {
+    }
     
     TaggedASTType () :
-        ClangASTType() { }
+        ClangASTType()
+    {
+    }
     
-    virtual ~TaggedASTType() { }
+    virtual
+    ~TaggedASTType()
+    {
+    }
     
     TaggedASTType<C> &operator= (const TaggedASTType<C> &tw)
     {
diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h
index e95441b..50b22fe 100644
--- a/include/lldb/Symbol/Type.h
+++ b/include/lldb/Symbol/Type.h
@@ -16,6 +16,7 @@
 #include "lldb/Core/UserID.h"
 #include "lldb/Symbol/ClangASTType.h"
 #include "lldb/Symbol/Declaration.h"
+
 #include <set>
 
 namespace lldb_private {
@@ -84,7 +85,7 @@
           lldb::user_id_t encoding_uid,
           EncodingDataType encoding_uid_type,
           const Declaration& decl,
-          lldb::clang_type_t clang_qual_type,
+          const ClangASTType &clang_qual_type,
           ResolveState clang_type_resolve_state);
     
     // This makes an invalid type.  Used for functions that return a Type when they
@@ -226,23 +227,20 @@
 
     // Get the clang type, and resolve definitions for any 
     // class/struct/union/enum types completely.
-    lldb::clang_type_t 
+    ClangASTType
     GetClangFullType ();
 
     // Get the clang type, and resolve definitions enough so that the type could
     // have layout performed. This allows ptrs and refs to class/struct/union/enum 
     // types remain forward declarations.
-    lldb::clang_type_t 
+    ClangASTType
     GetClangLayoutType ();
 
     // Get the clang type and leave class/struct/union/enum types as forward
     // declarations if they haven't already been fully defined.
-    lldb::clang_type_t 
+    ClangASTType 
     GetClangForwardType ();
 
-    clang::ASTContext *
-    GetClangAST ();
-
     ClangASTContext &
     GetClangASTContext ();
 
@@ -264,21 +262,10 @@
 
     uint32_t
     GetEncodingMask ();
-
-    void *
-    CreateClangPointerType (Type *type);
-
-    void *
+    
+    ClangASTType
     CreateClangTypedefType (Type *typedef_type, Type *base_type);
 
-    // For C++98 references (&)
-    void *
-    CreateClangLValueReferenceType (Type *type);
-
-    // For C++0x references (&&)
-    void *
-    CreateClangRValueReferenceType (Type *type);
-    
     bool
     IsRealObjCClass();
     
@@ -303,7 +290,7 @@
     EncodingDataType m_encoding_uid_type;
     uint64_t m_byte_size;
     Declaration m_decl;
-    lldb::clang_type_t m_clang_type;
+    ClangASTType m_clang_type;
     
     struct Flags {
         ResolveState    clang_type_resolve_state : 2;
diff --git a/include/lldb/Symbol/TypeHierarchyNavigator.h b/include/lldb/Symbol/TypeHierarchyNavigator.h
deleted file mode 100644
index d1657c0..0000000
--- a/include/lldb/Symbol/TypeHierarchyNavigator.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===-- TypeHierarchyNavigator.h ------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_TypeHierarchyNavigator_h_
-#define lldb_TypeHierarchyNavigator_h_
-
-// C Includes
-// C++ Includes
-
-// Other libraries and framework includes
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/DeclObjC.h"
-
-// Project includes
-#include "lldb/lldb-public.h"
-#include "lldb/lldb-enumerations.h"
-
-namespace lldb_private {
-
-class TypeHierarchyNavigator {
-
-public:
-    
-    enum RelationshipToCurrentType
-    {
-        eRootType,
-        eCXXBaseClass,
-        eCXXVBaseClass,
-        eObjCBaseClass,
-        eStrippedPointer,
-        eStrippedReference,
-        eStrippedTypedef
-    };
-    
-    typedef bool (*TypeHierarchyNavigatorCallback)(const clang::QualType& qual_type,
-                                                   RelationshipToCurrentType reason_why_here,
-                                                   void* callback_baton);
-    
-    TypeHierarchyNavigator(const clang::QualType& qual_type,
-                           ValueObject& val_obj,
-                           void* callback_baton = NULL) : 
-        m_root_type(qual_type),
-        m_value_object(val_obj),
-        m_default_callback_baton(callback_baton)
-    {
-    }
-        
-    bool
-    LoopThrough(TypeHierarchyNavigatorCallback callback,
-                void* callback_baton = NULL);
-    
-private:
-    
-    bool
-    LoopThrough(const clang::QualType& qual_type,
-                TypeHierarchyNavigatorCallback callback,
-                RelationshipToCurrentType reason_why_here,
-                void* callback_baton);
-    
-    const clang::QualType& m_root_type;
-    ValueObject& m_value_object;
-    void* m_default_callback_baton;
-    
-};
-    
-} // namespace lldb_private
-
-#endif  // lldb_TypeHierarchyNavigator_h_
diff --git a/include/lldb/Target/ThreadPlanStepOut.h b/include/lldb/Target/ThreadPlanStepOut.h
index 9097eff..918c023 100644
--- a/include/lldb/Target/ThreadPlanStepOut.h
+++ b/include/lldb/Target/ThreadPlanStepOut.h
@@ -63,7 +63,7 @@
     bool m_stop_others;
     lldb::ThreadPlanSP m_step_through_inline_plan_sp;
     lldb::ThreadPlanSP m_step_out_plan_sp;
-    Function          *m_immediate_step_from_function;
+    Function *m_immediate_step_from_function;
     lldb::ValueObjectSP m_return_valobj_sp;
 
     friend ThreadPlan *
diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj
index e7c5938..96162c7 100644
--- a/lldb.xcodeproj/project.pbxproj
+++ b/lldb.xcodeproj/project.pbxproj
@@ -539,7 +539,6 @@
 		9461569C14E358A6003A195C /* SBTypeSummary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9461568C14E35621003A195C /* SBTypeSummary.cpp */; };
 		9461569D14E358A6003A195C /* SBTypeSynthetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9461568D14E35621003A195C /* SBTypeSynthetic.cpp */; };
 		9463D4CD13B1798800C230D4 /* CommandObjectType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */; };
-		9467E65213C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */; };
 		9475C18814E5E9FA001BFC6D /* SBTypeCategory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9475C18714E5E9FA001BFC6D /* SBTypeCategory.cpp */; };
 		9475C18914E5EA08001BFC6D /* SBTypeCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 9475C18514E5E9C5001BFC6D /* SBTypeCategory.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		9475C18E14E5F834001BFC6D /* SBTypeNameSpecifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9475C18D14E5F834001BFC6D /* SBTypeNameSpecifier.cpp */; };
@@ -1584,8 +1583,6 @@
 		9461569514E3567F003A195C /* SBTypeSynthetic.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBTypeSynthetic.i; sourceTree = "<group>"; };
 		9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = CommandObjectType.cpp; path = source/Commands/CommandObjectType.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
 		9463D4CE13B179A500C230D4 /* CommandObjectType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CommandObjectType.h; path = source/Commands/CommandObjectType.h; sourceTree = "<group>"; };
-		9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeHierarchyNavigator.cpp; path = source/Symbol/TypeHierarchyNavigator.cpp; sourceTree = "<group>"; };
-		9467E65413C3D98900B3B6F3 /* TypeHierarchyNavigator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeHierarchyNavigator.h; path = include/lldb/Symbol/TypeHierarchyNavigator.h; sourceTree = "<group>"; };
 		9475C18514E5E9C5001BFC6D /* SBTypeCategory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBTypeCategory.h; path = include/lldb/API/SBTypeCategory.h; sourceTree = "<group>"; };
 		9475C18714E5E9FA001BFC6D /* SBTypeCategory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBTypeCategory.cpp; path = source/API/SBTypeCategory.cpp; sourceTree = "<group>"; };
 		9475C18A14E5EA1C001BFC6D /* SBTypeCategory.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBTypeCategory.i; sourceTree = "<group>"; };
@@ -2753,8 +2750,6 @@
 				49BB309511F79450001A4197 /* TaggedASTType.h */,
 				26BC7C6510F1B6E900F91463 /* Type.h */,
 				26BC7F2010F1B8EC00F91463 /* Type.cpp */,
-				9467E65413C3D98900B3B6F3 /* TypeHierarchyNavigator.h */,
-				9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */,
 				26BC7C6610F1B6E900F91463 /* TypeList.h */,
 				26BC7F2110F1B8EC00F91463 /* TypeList.cpp */,
 				49B01A2D15F67B1700666829 /* TypeVendor.h */,
@@ -3536,6 +3531,7 @@
 				26FFC19E14FC072100087D58 /* DynamicLoaderPOSIXDYLD.h in Headers */,
 				AF254E32170CCC33007AE5C9 /* PlatformDarwinKernel.h in Headers */,
 				2694E99E14FC0BB30076DE67 /* PlatformFreeBSD.h in Headers */,
+				2635878C17822E20004C30BA /* SymbolVendorELF.h in Headers */,
 				2694E9A514FC0BBD0076DE67 /* PlatformLinux.h in Headers */,
 				2663E379152BD1890091EC22 /* ReadWriteLock.h in Headers */,
 				26B1EFAF154638AF00E2DAC7 /* DWARFDeclContext.h in Headers */,
@@ -4228,7 +4224,6 @@
 				4CCA645813B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */,
 				9463D4CD13B1798800C230D4 /* CommandObjectType.cpp in Sources */,
 				49D8FB3913B5598F00411094 /* ClangASTImporter.cpp in Sources */,
-				9467E65213C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp in Sources */,
 				26ED3D6D13C563810017D45E /* OptionGroupVariable.cpp in Sources */,
 				94611EB213CCA4A4003A22AF /* RefCounter.cpp in Sources */,
 				94031A9E13CF486700DCFF3C /* InputReaderEZ.cpp in Sources */,
diff --git a/lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme b/lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme
index 4bc97ec..494df2d 100644
--- a/lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme
+++ b/lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme
@@ -79,15 +79,16 @@
             isEnabled = "YES">
          </CommandLineArgument>
          <CommandLineArgument
-            argument = "-f"
-            isEnabled = "YES">
-         </CommandLineArgument>
-         <CommandLineArgument
-            argument = "ConditionalBreakTestCase.test_with_dwarf_command"
+            argument = "functionalities/breakpoint/breakpoint_conditions"
             isEnabled = "YES">
          </CommandLineArgument>
       </CommandLineArguments>
       <AdditionalOptions>
+         <AdditionalOption
+            key = "DYLD_INSERT_LIBRARIES"
+            value = "/usr/lib/libgmalloc.dylib"
+            isEnabled = "YES">
+         </AdditionalOption>
       </AdditionalOptions>
    </LaunchAction>
    <ProfileAction
diff --git a/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme b/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme
index bd7c34c..39343d6 100644
--- a/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme
+++ b/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme
@@ -100,6 +100,12 @@
             ReferencedContainer = "container:lldb.xcodeproj">
          </BuildableReference>
       </BuildableProductRunnable>
+      <CommandLineArguments>
+         <CommandLineArgument
+            argument = "/private/tmp/a.out"
+            isEnabled = "YES">
+         </CommandLineArgument>
+      </CommandLineArguments>
       <EnvironmentVariables>
          <EnvironmentVariable
             key = "LLDB_LAUNCH_FLAG_DISABLE_ASLR"
diff --git a/source/API/SBModule.cpp b/source/API/SBModule.cpp
index 390ca64..5f5fc92 100644
--- a/source/API/SBModule.cpp
+++ b/source/API/SBModule.cpp
@@ -506,7 +506,7 @@
         sb_type = SBType (module_sp->FindFirstType(sc, name, exact_match));
         
         if (!sb_type.IsValid())
-            sb_type = SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
+            sb_type = SBType (ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
     }
     return sb_type;
 }
@@ -516,7 +516,7 @@
 {
     ModuleSP module_sp (GetSP ());
     if (module_sp)
-        return SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type));
+        return SBType (ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type));
     return SBType();
 }
 
@@ -549,7 +549,7 @@
         }
         else
         {
-            SBType sb_type(ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
+            SBType sb_type(ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
             if (sb_type.IsValid())
                 retval.Append(sb_type);
         }
diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp
index 7e47fbf..f37c8f8 100644
--- a/source/API/SBTarget.cpp
+++ b/source/API/SBTarget.cpp
@@ -2153,7 +2153,7 @@
         // No matches, search for basic typename matches
         ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
         if (clang_ast)
-            return SBType (ClangASTType::GetBasicType (clang_ast->getASTContext(), const_typename));
+            return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename));
     }
     return SBType();
 }
@@ -2166,7 +2166,7 @@
     {
         ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
         if (clang_ast)
-            return SBType (ClangASTType::GetBasicType (clang_ast->getASTContext(), type));
+            return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), type));
     }
     return SBType();
 }
@@ -2233,7 +2233,7 @@
             // No matches, search for basic typename matches
             ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
             if (clang_ast)
-                sb_type_list.Append (SBType (ClangASTType::GetBasicType (clang_ast->getASTContext(), const_typename)));
+                sb_type_list.Append (SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename)));
         }
     }
     return sb_type_list;
diff --git a/source/API/SBType.cpp b/source/API/SBType.cpp
index f6d2fc5..372d073 100644
--- a/source/API/SBType.cpp
+++ b/source/API/SBType.cpp
@@ -142,7 +142,7 @@
     if (!IsValid())
         return 0;
     
-    return ClangASTType::GetTypeByteSize(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
+    return m_opaque_sp->GetClangASTType().GetByteSize();
     
 }
 
@@ -151,13 +151,7 @@
 {
     if (!IsValid())
         return false;
-    
-    QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
-    const clang::Type* typePtr = qt.getTypePtrOrNull();
-    
-    if (typePtr)
-        return typePtr->isAnyPointerType();
-    return false;
+    return m_opaque_sp->GetClangASTType().IsPointerType();
 }
 
 bool
@@ -165,13 +159,7 @@
 {
     if (!IsValid())
         return false;
-
-    QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
-    const clang::Type* typePtr = qt.getTypePtrOrNull();
-    
-    if (typePtr)
-        return typePtr->isReferenceType();
-    return false;
+    return m_opaque_sp->GetClangASTType().IsReferenceType();
 }
 
 SBType
@@ -180,8 +168,7 @@
     if (!IsValid())
         return SBType();
 
-    return SBType(ClangASTType(m_opaque_sp->GetASTContext(),
-                               ClangASTContext::CreatePointerType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType())));
+    return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetPointerType()));
 }
 
 SBType
@@ -189,13 +176,7 @@
 {
     if (!IsValid())
         return SBType();
-
-    QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
-    const clang::Type* typePtr = qt.getTypePtrOrNull();
-    
-    if (typePtr)
-        return SBType(ClangASTType(m_opaque_sp->GetASTContext(),typePtr->getPointeeType().getAsOpaquePtr()));
-    return SBType();
+    return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetPointeeType()));
 }
 
 SBType
@@ -203,9 +184,7 @@
 {
     if (!IsValid())
         return SBType();
-    
-    return SBType(ClangASTType(m_opaque_sp->GetASTContext(),
-                               ClangASTContext::CreateLValueReferenceType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType())));
+    return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetLValueReferenceType()));
 }
 
 SBType
@@ -213,32 +192,23 @@
 {
     if (!IsValid())
         return SBType();
-
-    QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
-    
-    return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getNonReferenceType().getAsOpaquePtr()));
+    return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetNonReferenceType()));
 }
 
 bool 
 SBType::IsFunctionType ()
 {
-    if (IsValid())
-    {
-        QualType qual_type(QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()));
-        const FunctionProtoType* func = dyn_cast<FunctionProtoType>(qual_type.getTypePtr());
-        return func != NULL;
-    }
-    return false;
+    if (!IsValid())
+        return false;
+    return m_opaque_sp->GetClangASTType().IsFunctionType();
 }
 
 bool
 SBType::IsPolymorphicClass ()
 {
-    if (IsValid())
-    {
-        return ClangASTType::IsPolymorphicClass (m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
-    }
-    return false;
+    if (!IsValid())
+        return false;
+    return m_opaque_sp->GetClangASTType().IsPolymorphicClass();
 }
 
 
@@ -248,12 +218,9 @@
 {
     if (IsValid())
     {
-        QualType qual_type(QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()));
-        const FunctionProtoType* func = dyn_cast<FunctionProtoType>(qual_type.getTypePtr());
-        
-        if (func)
-            return SBType(ClangASTType(m_opaque_sp->GetASTContext(),
-                                       func->getResultType().getAsOpaquePtr()));
+        ClangASTType return_clang_type (m_opaque_sp->GetClangASTType().GetFunctionReturnType());
+        if (return_clang_type.IsValid())
+            return SBType(return_clang_type);
     }
     return lldb::SBType();
 }
@@ -281,19 +248,14 @@
 {
     if (!IsValid())
         return SBType();
-        
-    QualType qt (QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()));
-    return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getUnqualifiedType().getAsOpaquePtr()));
+    return SBType(m_opaque_sp->GetClangASTType().GetFullyUnqualifiedType());
 }
 
 lldb::SBType
 SBType::GetCanonicalType()
 {
     if (IsValid())
-    {
-        QualType qt (QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()));
-        return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getCanonicalType().getAsOpaquePtr()));
-    }
+        return SBType(m_opaque_sp->GetClangASTType().GetCanonicalType());
     return SBType();
 }
 
@@ -302,15 +264,15 @@
 SBType::GetBasicType()
 {
     if (IsValid())
-        return ClangASTContext::GetLLDBBasicTypeEnumeration (m_opaque_sp->GetOpaqueQualType());
+        return m_opaque_sp->GetClangASTType().GetBasicTypeEnumeration ();
     return eBasicTypeInvalid;
 }
 
 SBType
-SBType::GetBasicType(lldb::BasicType type)
+SBType::GetBasicType(lldb::BasicType basic_type)
 {
     if (IsValid())
-        return SBType (ClangASTType::GetBasicType (m_opaque_sp->GetASTContext(), type));
+        return SBType (ClangASTContext::GetBasicType (m_opaque_sp->GetASTContext(), basic_type));
     return SBType();
 }
 
@@ -318,7 +280,7 @@
 SBType::GetNumberOfDirectBaseClasses ()
 {
     if (IsValid())
-        return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
+        return m_opaque_sp->GetClangASTType().GetNumDirectBaseClasses();
     return 0;
 }
 
@@ -326,7 +288,7 @@
 SBType::GetNumberOfVirtualBaseClasses ()
 {
     if (IsValid())
-        return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
+        return m_opaque_sp->GetClangASTType().GetNumVirtualBaseClasses();
     return 0;
 }
 
@@ -334,7 +296,7 @@
 SBType::GetNumberOfFields ()
 {
     if (IsValid())
-        return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
+        return m_opaque_sp->GetClangASTType().GetNumFields();
     return 0;
 }
 
@@ -361,13 +323,15 @@
     SBTypeMember sb_type_member;
     if (IsValid())
     {
-        clang::ASTContext* ast = m_opaque_sp->GetASTContext();
-        uint32_t bit_offset = 0;
-        clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset);
-        if (clang_type)
+        ClangASTType this_type (m_opaque_sp->GetClangASTType ());
+        if (this_type.IsValid())
         {
-            TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
-            sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset));
+            uint32_t bit_offset = 0;
+            ClangASTType base_class_type (this_type.GetDirectBaseClassAtIndex(idx, &bit_offset));
+            if (base_class_type.IsValid())
+            {
+                sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
+            }
         }
     }
     return sb_type_member;
@@ -380,14 +344,16 @@
     SBTypeMember sb_type_member;
     if (IsValid())
     {
-        uint32_t bit_offset = 0;
-        clang::ASTContext* ast = m_opaque_sp->GetASTContext();
-        clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset);
-        if (clang_type)
+        ClangASTType this_type (m_opaque_sp->GetClangASTType ());
+        if (this_type.IsValid())
         {
-            TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
-            sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset));
-        }        
+            uint32_t bit_offset = 0;
+            ClangASTType base_class_type (this_type.GetVirtualBaseClassAtIndex(idx, &bit_offset));
+            if (base_class_type.IsValid())
+            {
+                sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
+            }
+        }
     }
     return sb_type_member;
 }
@@ -398,20 +364,30 @@
     SBTypeMember sb_type_member;
     if (IsValid())
     {
-        uint64_t bit_offset = 0;
-        uint32_t bitfield_bit_size = 0;
-        bool is_bitfield = false;
-        clang::ASTContext* ast = m_opaque_sp->GetASTContext();
-        std::string name_sstr;
-        clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &bit_offset, &bitfield_bit_size, &is_bitfield);
-        if (clang_type)
+        ClangASTType this_type (m_opaque_sp->GetClangASTType ());
+        if (this_type.IsValid())
         {
-            ConstString name;
-            if (!name_sstr.empty())
-                name.SetCString(name_sstr.c_str());
-            TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
-            sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset, name, bitfield_bit_size, is_bitfield));
-        }        
+            uint64_t bit_offset = 0;
+            uint32_t bitfield_bit_size = 0;
+            bool is_bitfield = false;
+            std::string name_sstr;
+            ClangASTType field_type (this_type.GetFieldAtIndex (idx,
+                                                                name_sstr,
+                                                                &bit_offset,
+                                                                &bitfield_bit_size,
+                                                                &is_bitfield));
+            if (field_type.IsValid())
+            {
+                ConstString name;
+                if (!name_sstr.empty())
+                    name.SetCString(name_sstr.c_str());
+                sb_type_member.reset (new TypeMemberImpl (TypeImplSP (new TypeImpl(field_type)),
+                                                          bit_offset,
+                                                          name,
+                                                          bitfield_bit_size,
+                                                          is_bitfield));
+            }
+        }
     }
     return sb_type_member;
 }
@@ -420,9 +396,8 @@
 SBType::IsTypeComplete()
 {
     if (!IsValid())
-        return false;
-    
-    return ClangASTContext::IsCompleteType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
+        return false;    
+    return m_opaque_sp->GetClangASTType().IsCompleteType();
 }
 
 const char*
@@ -430,17 +405,14 @@
 {
     if (!IsValid())
         return "";
-
-    return ClangASTType::GetConstTypeName(m_opaque_sp->GetASTContext(),
-                                          m_opaque_sp->GetOpaqueQualType()).GetCString();
+    return m_opaque_sp->GetClangASTType().GetConstTypeName().GetCString();
 }
 
 lldb::TypeClass
 SBType::GetTypeClass ()
 {
     if (IsValid())
-        return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(),
-                                           m_opaque_sp->GetOpaqueQualType());
+        return m_opaque_sp->GetClangASTType().GetTypeClass();
     return lldb::eTypeClassInvalid;
 }
 
@@ -448,10 +420,7 @@
 SBType::GetNumberOfTemplateArguments ()
 {
     if (IsValid())
-    {
-        return ClangASTContext::GetNumTemplateArguments (m_opaque_sp->GetASTContext(),
-                                                         m_opaque_sp->GetOpaqueQualType());
-    }
+        return m_opaque_sp->GetClangASTType().GetNumTemplateArguments();
     return 0;
 }
 
@@ -461,11 +430,9 @@
     if (IsValid())
     {
         TemplateArgumentKind kind = eTemplateArgumentKindNull;
-        return SBType(ClangASTType(m_opaque_sp->GetASTContext(),
-                                   ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(),
-                                                                        m_opaque_sp->GetOpaqueQualType(), 
-                                                                        idx, 
-                                                                        kind)));
+        ClangASTType template_arg_type = m_opaque_sp->GetClangASTType().GetTemplateArgument (idx, kind);
+        if (template_arg_type.IsValid())
+            return SBType(template_arg_type);
     }
     return SBType();
 }
@@ -476,18 +443,11 @@
 {
     TemplateArgumentKind kind = eTemplateArgumentKindNull;
     if (IsValid())
-    {
-        ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(),
-                                             m_opaque_sp->GetOpaqueQualType(), 
-                                             idx, 
-                                             kind);
-    }
+        m_opaque_sp->GetClangASTType().GetTemplateArgument (idx, kind);
     return kind;
 }
 
 
-
-
 SBTypeList::SBTypeList() :
     m_opaque_ap(new TypeListImpl())
 {
@@ -543,20 +503,6 @@
 {
 }
 
-bool
-SBType::IsPointerType (void *opaque_type)
-{
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-    
-    bool ret_value = ClangASTContext::IsPointerType (opaque_type);
-    
-    if (log)
-        log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false"));
-    
-    return ret_value;
-}
-
-
 SBTypeMember::SBTypeMember() :
     m_opaque_ap()
 {
diff --git a/source/API/SBValue.cpp b/source/API/SBValue.cpp
index 33608f3..aa9b23a 100644
--- a/source/API/SBValue.cpp
+++ b/source/API/SBValue.cpp
@@ -473,7 +473,7 @@
     TypeImplSP type_sp;
     if (value_sp)
     {
-        type_sp.reset (new TypeImpl(ClangASTType (value_sp->GetClangAST(), value_sp->GetClangType())));
+        type_sp.reset (new TypeImpl(value_sp->GetClangType()));
         sb_type.SetSP(type_sp);
     }
     if (log)
@@ -761,17 +761,14 @@
     lldb::TypeImplSP type_impl_sp (sb_type.GetSP());
     if (value_sp && type_impl_sp)
     {
-        ClangASTType pointee_ast_type(type_impl_sp->GetASTContext(), type_impl_sp->GetClangASTType().GetPointerType ());
-        lldb::TypeImplSP pointee_type_impl_sp (new TypeImpl(pointee_ast_type));
-        if (pointee_type_impl_sp)
+        ClangASTType pointee_ast_type(type_impl_sp->GetClangASTType().GetPointerType ());
+        if (pointee_ast_type)
         {
-        
             lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
         
             ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
             ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
-                                                                               pointee_type_impl_sp->GetASTContext(),
-                                                                               pointee_type_impl_sp->GetOpaqueQualType(),
+                                                                               pointee_ast_type,
                                                                                ConstString(name),
                                                                                buffer,
                                                                                lldb::endian::InlHostByteOrder(), 
@@ -811,8 +808,7 @@
         ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
 
         new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
-                                                       type.m_opaque_sp->GetASTContext() ,
-                                                       type.m_opaque_sp->GetOpaqueQualType(),
+                                                       type.m_opaque_sp->GetClangASTType(),
                                                        ConstString(name),
                                                        *data.m_opaque_sp,
                                                        LLDB_INVALID_ADDRESS);
@@ -1187,7 +1183,7 @@
     ValueLocker locker;
     lldb::ValueObjectSP value_sp(GetSP(locker));
     if (value_sp)
-        return value_sp->GetClangType();
+        return value_sp->GetClangType().GetOpaqueQualType();
     return NULL;
 }
 
@@ -1665,7 +1661,7 @@
             watch_type |= LLDB_WATCH_TYPE_WRITE;
         
         Error rc;
-        ClangASTType type (value_sp->GetClangAST(), value_sp->GetClangType());
+        ClangASTType type (value_sp->GetClangType());
         WatchpointSP watchpoint_sp = target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc);
         error.SetError(rc);
                 
diff --git a/source/Breakpoint/Watchpoint.cpp b/source/Breakpoint/Watchpoint.cpp
index f18722a..45559b1 100644
--- a/source/Breakpoint/Watchpoint.cpp
+++ b/source/Breakpoint/Watchpoint.cpp
@@ -54,8 +54,7 @@
     {
         // If we don't have a known type, then we force it to unsigned int of the right size.
         ClangASTContext *ast_context = target.GetScratchClangASTContext();
-        clang_type_t clang_type = ast_context->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8 * size);
-        m_type.SetClangType(ast_context->getASTContext(), clang_type);
+        m_type = ast_context->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8 * size);
     }
     
     // Set the initial value of the watched variable:
diff --git a/source/Commands/CommandObjectArgs.cpp b/source/Commands/CommandObjectArgs.cpp
index b2b4cdf..05fd53b 100644
--- a/source/Commands/CommandObjectArgs.cpp
+++ b/source/Commands/CommandObjectArgs.cpp
@@ -164,7 +164,7 @@
         const char *arg_type_cstr = args.GetArgumentAtIndex(arg_index);
         Value value;
         value.SetValueType(Value::eValueTypeScalar);
-        void *type;
+        ClangASTType clang_type;
         
         char *int_pos;
         if ((int_pos = strstr (const_cast<char*>(arg_type_cstr), "int")))
@@ -207,9 +207,9 @@
                 return false;
             }
             
-            type = ast_context.GetBuiltinTypeForEncodingAndBitSize(encoding, width);
+            clang_type = ast_context.GetBuiltinTypeForEncodingAndBitSize(encoding, width);
             
-            if (!type)
+            if (!clang_type.IsValid())
             {
                 result.AppendErrorWithFormat ("Couldn't get Clang type for format %s (%s integer, width %d).\n",
                                              arg_type_cstr,
@@ -223,9 +223,9 @@
         else if (strchr (arg_type_cstr, '*'))
         {
             if (!strcmp (arg_type_cstr, "void*"))
-                type = ast_context.CreatePointerType (ast_context.GetBuiltInType_void ());
+                clang_type = ast_context.GetBasicType(eBasicTypeVoid).GetPointerType();
             else if (!strcmp (arg_type_cstr, "char*"))
-                type = ast_context.GetCStringType (false);
+                clang_type = ast_context.GetCStringType (false);
             else
             {
                 result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
@@ -240,8 +240,7 @@
             return false;
         }
                      
-        value.SetContext (Value::eContextTypeClangType, type);
-        
+        value.SetClangType (clang_type);
         value_list.PushValue(value);
     }
     
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index 97ab957..eea0cf5 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -543,15 +543,15 @@
                 else
                 {
                     TypeSP type_sp (type_list.GetTypeAtIndex(0));
-                    clang_ast_type.SetClangType (type_sp->GetClangAST(), type_sp->GetClangFullType());
+                    clang_ast_type = type_sp->GetClangFullType();
                 }
             }
             
             while (pointer_count > 0)
             {
-                clang_type_t pointer_type = ClangASTContext::CreatePointerType (clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType());
-                if (pointer_type)
-                    clang_ast_type.SetClangType (clang_ast_type.GetASTContext(), pointer_type);
+                ClangASTType pointer_type = clang_ast_type.GetPointerType();
+                if (pointer_type.IsValid())
+                    clang_ast_type = pointer_type;
                 else
                 {
                     result.AppendError ("unable make a pointer type\n");
@@ -561,7 +561,7 @@
                 --pointer_count;
             }
 
-            m_format_options.GetByteSizeValue() = clang_ast_type.GetClangTypeByteSize();
+            m_format_options.GetByteSizeValue() = clang_ast_type.GetByteSize();
             
             if (m_format_options.GetByteSizeValue() == 0)
             {
@@ -675,7 +675,7 @@
             if (m_format_options.GetFormatValue().OptionWasSet() == false)
                 m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
 
-            bytes_read = clang_ast_type.GetTypeByteSize() * m_format_options.GetCountValue().GetCurrentValue();
+            bytes_read = clang_ast_type.GetByteSize() * m_format_options.GetCountValue().GetCurrentValue();
         }
         else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString)
         {
diff --git a/source/Commands/CommandObjectVersion.cpp b/source/Commands/CommandObjectVersion.cpp
index ea1930e..2d950a8 100644
--- a/source/Commands/CommandObjectVersion.cpp
+++ b/source/Commands/CommandObjectVersion.cpp
@@ -38,8 +38,16 @@
 bool
 CommandObjectVersion::DoExecute (Args& args, CommandReturnObject &result)
 {
-    result.AppendMessageWithFormat ("%s\n", lldb_private::GetVersion());
-    result.SetStatus (eReturnStatusSuccessFinishResult);
+    if (args.GetArgumentCount() == 0)
+    {
+        result.AppendMessageWithFormat ("%s\n", lldb_private::GetVersion());
+        result.SetStatus (eReturnStatusSuccessFinishResult);
+    }
+    else
+    {
+        result.AppendError("the version command takes no arguments.");
+        result.SetStatus (eReturnStatusFailed);
+    }
     return true;
 }
 
diff --git a/source/Commands/CommandObjectVersion.h b/source/Commands/CommandObjectVersion.h
index 035c65e..1fdbed6 100644
--- a/source/Commands/CommandObjectVersion.h
+++ b/source/Commands/CommandObjectVersion.h
@@ -34,7 +34,7 @@
 protected:
     virtual bool
     DoExecute (Args& args,
-             CommandReturnObject &result);
+               CommandReturnObject &result);
 
 };
 
diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp
index 7a6a47e..c1f0c41 100644
--- a/source/Commands/CommandObjectWatchpoint.cpp
+++ b/source/Commands/CommandObjectWatchpoint.cpp
@@ -1050,7 +1050,7 @@
                 valobj_sp = valobj_list.GetValueObjectAtIndex(0);
         }
         
-        ClangASTType type;
+        ClangASTType clang_type;
         
         if (valobj_sp)
         {
@@ -1063,7 +1063,7 @@
                 size = m_option_watchpoint.watch_size == 0 ? valobj_sp->GetByteSize()
                                                            : m_option_watchpoint.watch_size;
             }
-            type.SetClangType(valobj_sp->GetClangAST(), valobj_sp->GetClangType());
+            clang_type = valobj_sp->GetClangType();
         }
         else
         {
@@ -1080,7 +1080,7 @@
         uint32_t watch_type = m_option_watchpoint.watch_type;
         
         error.Clear();
-        Watchpoint *wp = target->CreateWatchpoint(addr, size, &type, watch_type, error).get();
+        Watchpoint *wp = target->CreateWatchpoint(addr, size, &clang_type, watch_type, error).get();
         if (wp)
         {
             wp->SetWatchSpec(command.GetArgumentAtIndex(0));
@@ -1292,12 +1292,10 @@
         
         // Fetch the type from the value object, the type of the watched object is the pointee type
         /// of the expression, so convert to that if we  found a valid type.
-        ClangASTType type(valobj_sp->GetClangAST(), valobj_sp->GetClangType());
-        if (type.IsValid())
-            type.SetClangType(type.GetASTContext(), type.GetPointeeType());
+        ClangASTType clang_type(valobj_sp->GetClangType());
         
         Error error;
-        Watchpoint *wp = target->CreateWatchpoint(addr, size, &type, watch_type, error).get();
+        Watchpoint *wp = target->CreateWatchpoint(addr, size, &clang_type, watch_type, error).get();
         if (wp)
         {
             Stream &output_stream = result.GetOutputStream();
diff --git a/source/Core/DataBufferHeap.cpp b/source/Core/DataBufferHeap.cpp
index 3692aa9..7489376 100644
--- a/source/Core/DataBufferHeap.cpp
+++ b/source/Core/DataBufferHeap.cpp
@@ -101,5 +101,9 @@
         m_data.clear();
 }
 
-
-
+void
+DataBufferHeap::Clear()
+{
+    buffer_t empty;
+    m_data.swap(empty);
+}
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index 4a6477f..01e5ae3 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -1632,9 +1632,10 @@
                                 }
                                 
                                 // TODO use flags for these
-                                bool is_array = ClangASTContext::IsArrayType(target->GetClangType(), NULL, NULL, NULL);
-                                bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
-                                bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType());
+                                const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
+                                bool is_array = (type_info_flags & ClangASTType::eTypeIsArray) != 0;
+                                bool is_pointer = (type_info_flags & ClangASTType::eTypeIsPointer) != 0;
+                                bool is_aggregate = target->GetClangType().IsAggregateType();
                                 
                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
                                 {
diff --git a/source/Core/Value.cpp b/source/Core/Value.cpp
index 9c69608..3fe75d3 100644
--- a/source/Core/Value.cpp
+++ b/source/Core/Value.cpp
@@ -33,8 +33,10 @@
 
 Value::Value() :
     m_value (),
-    m_value_type (eValueTypeScalar),
+    m_vector (),
+    m_clang_type (),
     m_context (NULL),
+    m_value_type (eValueTypeScalar),
     m_context_type (eContextTypeInvalid),
     m_data_buffer ()
 {
@@ -42,8 +44,10 @@
 
 Value::Value(const Scalar& scalar) :
     m_value (scalar),
-    m_value_type (eValueTypeScalar),
+    m_vector (),
+    m_clang_type (),
     m_context (NULL),
+    m_value_type (eValueTypeScalar),
     m_context_type (eContextTypeInvalid),
     m_data_buffer ()
 {
@@ -52,8 +56,10 @@
 
 Value::Value(const uint8_t *bytes, int len) :
     m_value (),
-    m_value_type (eValueTypeHostAddress),
+    m_vector (),
+    m_clang_type (),
     m_context (NULL),
+    m_value_type (eValueTypeHostAddress),
     m_context_type (eContextTypeInvalid),
     m_data_buffer ()
 {
@@ -62,10 +68,13 @@
 }
 
 Value::Value(const Value &v) :
-    m_value(v.m_value),
-    m_value_type(v.m_value_type),
-    m_context(v.m_context),
-    m_context_type(v.m_context_type)
+    m_value (v.m_value),
+    m_vector (v.m_vector),
+    m_clang_type (v.m_clang_type),
+    m_context (v.m_context),
+    m_value_type (v.m_value_type),
+    m_context_type (v.m_context_type),
+    m_data_buffer ()
 {
     if ((uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS) == (uintptr_t)v.m_data_buffer.GetBytes())
     {
@@ -82,8 +91,10 @@
     if (this != &rhs)
     {
         m_value = rhs.m_value;
-        m_value_type = rhs.m_value_type;
+        m_vector = rhs.m_vector;
+        m_clang_type = rhs.m_clang_type;
         m_context = rhs.m_context;
+        m_value_type = rhs.m_value_type;
         m_context_type = rhs.m_context_type;
         if ((uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS) == (uintptr_t)rhs.m_data_buffer.GetBytes())
         {
@@ -152,72 +163,42 @@
 }
 
 bool
-Value::ValueOf(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
+Value::ValueOf(ExecutionContext *exe_ctx)
 {
     switch (m_context_type)
     {
     case eContextTypeInvalid:
-    case eContextTypeClangType:         // clang::Type *
     case eContextTypeRegisterInfo:      // RegisterInfo *
     case eContextTypeLLDBType:          // Type *
         break;
 
     case eContextTypeVariable:          // Variable *
-        ResolveValue(exe_ctx, ast_context);
+        ResolveValue(exe_ctx);
         return true;
     }
     return false;
 }
 
 uint64_t
-Value::GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr)
+Value::GetValueByteSize (Error *error_ptr)
 {
     uint64_t byte_size = 0;
 
     switch (m_context_type)
     {
-    case eContextTypeInvalid:
-        // If we have no context, there is no way to know how much memory to read
-        if (error_ptr)
-            error_ptr->SetErrorString ("Invalid context type, there is no way to know how much memory to read.");
-        break;
-
-    case eContextTypeClangType:
-        if (ast_context == NULL)
-        {
-            if (error_ptr)
-                error_ptr->SetErrorString ("Can't determine size of opaque clang type with NULL ASTContext *.");
-        }
-        else
-        {
-            byte_size = ClangASTType(ast_context, m_context).GetClangTypeByteSize();
-        }
-        break;
-
     case eContextTypeRegisterInfo:     // RegisterInfo *
         if (GetRegisterInfo())
             byte_size = GetRegisterInfo()->byte_size;
-        else if (error_ptr)
-            error_ptr->SetErrorString ("Can't determine byte size with NULL RegisterInfo *.");
         break;
 
-    case eContextTypeLLDBType:             // Type *
-        if (GetType())
-            byte_size = GetType()->GetByteSize();
-        else if (error_ptr)
-            error_ptr->SetErrorString ("Can't determine byte size with NULL Type *.");
-        break;
-
+    case eContextTypeInvalid:
+    case eContextTypeLLDBType:         // Type *
     case eContextTypeVariable:         // Variable *
-        if (GetVariable())
-        {   
-            if (GetVariable()->GetType())
-                byte_size = GetVariable()->GetType()->GetByteSize();
-            else if (error_ptr)
-                error_ptr->SetErrorString ("Can't determine byte size with NULL Type *.");
+        {
+            const ClangASTType &ast_type = GetClangType();
+            if (ast_type.IsValid())
+                byte_size = ast_type.GetByteSize();
         }
-        else if (error_ptr)
-            error_ptr->SetErrorString ("Can't determine byte size with NULL Variable *.");
         break;
     }
 
@@ -236,32 +217,48 @@
     return byte_size;
 }
 
-clang_type_t
+const ClangASTType &
 Value::GetClangType ()
 {
-    switch (m_context_type)
+    if (!m_clang_type.IsValid())
     {
-    case eContextTypeInvalid:
-        break;
+        switch (m_context_type)
+        {
+        case eContextTypeInvalid:
+            break;
 
-    case eContextTypeClangType:
-        return m_context;
+        case eContextTypeRegisterInfo:
+            break;    // TODO: Eventually convert into a clang type?
 
-    case eContextTypeRegisterInfo:
-        break;    // TODO: Eventually convert into a clang type?
+        case eContextTypeLLDBType:
+            {
+                Type *lldb_type = GetType();
+                if (lldb_type)
+                    m_clang_type = lldb_type->GetClangForwardType();
+            }
+            break;
 
-    case eContextTypeLLDBType:
-        if (GetType())
-            return GetType()->GetClangForwardType();
-        break;
-
-    case eContextTypeVariable:
-        if (GetVariable())
-            return GetVariable()->GetType()->GetClangForwardType();
-        break;
+        case eContextTypeVariable:
+            {
+                Variable *variable = GetVariable();
+                if (variable)
+                {
+                    Type *variable_type = variable->GetType();
+                    if (variable_type)
+                        m_clang_type = variable_type->GetClangForwardType();
+                }
+            }
+            break;
+        }
     }
 
-    return NULL;
+    return m_clang_type;
+}
+
+void
+Value::SetClangType (const ClangASTType &clang_type)
+{
+    m_clang_type = clang_type;
 }
 
 lldb::Format
@@ -269,25 +266,19 @@
 {
     switch (m_context_type)
     {
-    case eContextTypeInvalid:
-        break;
-
-    case eContextTypeClangType:
-        return ClangASTType::GetFormat (m_context);
-
     case eContextTypeRegisterInfo:
         if (GetRegisterInfo())
             return GetRegisterInfo()->format;
         break;
 
+    case eContextTypeInvalid:
     case eContextTypeLLDBType:
-        if (GetType())
-            return GetType()->GetFormat();
-        break;
-
     case eContextTypeVariable:
-        if (GetVariable())
-            return GetVariable()->GetType()->GetFormat();
+        {
+            const ClangASTType &ast_type = GetClangType();
+            if (ast_type.IsValid())
+                return ast_type.GetFormat();
+        }
         break;
 
     }
@@ -326,8 +317,7 @@
 
 Error
 Value::GetValueAsData (ExecutionContext *exe_ctx,
-                       clang::ASTContext *ast_context, 
-                       DataExtractor &data, 
+                       DataExtractor &data,
                        uint32_t data_offset,
                        Module *module)
 {
@@ -337,15 +327,12 @@
     lldb::addr_t address = LLDB_INVALID_ADDRESS;
     AddressType address_type = eAddressTypeFile;
     Address file_so_addr;
+    const ClangASTType &ast_type = GetClangType();
     switch (m_value_type)
     {
     case eValueTypeVector:
-        if (m_context_type == eContextTypeClangType && ast_context)
-        {
-            ClangASTType ptr_type (ast_context, ClangASTContext::GetVoidPtrType(ast_context, false));
-            uint64_t ptr_byte_size = ptr_type.GetClangTypeByteSize();
-            data.SetAddressByteSize (ptr_byte_size);
-        }
+        if (ast_type.IsValid())
+            data.SetAddressByteSize (ast_type.GetPointerByteSize());
         else
             data.SetAddressByteSize(sizeof(void *));
         data.SetData(m_vector.bytes, m_vector.length, m_vector.byte_order);
@@ -353,12 +340,8 @@
 
     case eValueTypeScalar:
         data.SetByteOrder (lldb::endian::InlHostByteOrder());
-        if (m_context_type == eContextTypeClangType && ast_context)
-        {
-            ClangASTType ptr_type (ast_context, ClangASTContext::GetVoidPtrType(ast_context, false));
-            uint64_t ptr_byte_size = ptr_type.GetClangTypeByteSize();
-            data.SetAddressByteSize (ptr_byte_size);
-        }
+        if (ast_type.IsValid())
+            data.SetAddressByteSize (ast_type.GetPointerByteSize());
         else
             data.SetAddressByteSize(sizeof(void *));
         if (m_value.GetData (data))
@@ -562,7 +545,7 @@
     }
 
     // If we got here, we need to read the value from memory
-    size_t byte_size = GetValueByteSize (ast_context, &error);
+    size_t byte_size = GetValueByteSize (&error);
 
     // Bail if we encountered any errors getting the byte size
     if (error.Fail())
@@ -637,10 +620,10 @@
 }
 
 Scalar &
-Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
-{    
-    void *opaque_clang_qual_type = GetClangType();
-    if (opaque_clang_qual_type)
+Value::ResolveValue(ExecutionContext *exe_ctx)
+{
+    const ClangASTType &clang_type = GetClangType();
+    if (clang_type.IsValid())
     {
         switch (m_value_type)
         {
@@ -654,11 +637,11 @@
             {
                 DataExtractor data;
                 lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
-                Error error (GetValueAsData (exe_ctx, ast_context, data, 0, NULL));
+                Error error (GetValueAsData (exe_ctx, data, 0, NULL));
                 if (error.Success())
                 {
                     Scalar scalar;
-                    if (ClangASTType::GetValueAsScalar (ast_context, opaque_clang_qual_type, data, 0, data.GetByteSize(), scalar))
+                    if (clang_type.GetValueAsScalar (data, 0, data.GetByteSize(), scalar))
                     {
                         m_value = scalar;
                         m_value_type = eValueTypeScalar;
@@ -695,6 +678,19 @@
     return NULL;
 }
 
+void
+Value::Clear()
+{
+    m_value.Clear();
+    m_vector.Clear();
+    m_clang_type.Clear();
+    m_value_type = eValueTypeScalar;
+    m_context = NULL;
+    m_context_type = eContextTypeInvalid;
+    m_data_buffer.Clear();
+}
+
+
 const char *
 Value::GetValueTypeAsCString (ValueType value_type)
 {    
@@ -715,7 +711,6 @@
     switch (context_type)
     {
     case eContextTypeInvalid:       return "invalid";
-    case eContextTypeClangType:     return "clang::Type *";
     case eContextTypeRegisterInfo:  return "RegisterInfo *";
     case eContextTypeLLDBType:      return "Type *";
     case eContextTypeVariable:      return "Variable *";
@@ -763,3 +758,4 @@
 {
     m_values.clear();
 }
+
diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp
index e2a87d4..a30cc13 100644
--- a/source/Core/ValueObject.cpp
+++ b/source/Core/ValueObject.cpp
@@ -283,101 +283,80 @@
 ClangASTType
 ValueObject::MaybeCalculateCompleteType ()
 {
-    ClangASTType ret(GetClangASTImpl(), GetClangTypeImpl());
+    ClangASTType clang_type(GetClangTypeImpl());
         
     if (m_did_calculate_complete_objc_class_type)
     {
         if (m_override_type.IsValid())
             return m_override_type;
         else
-            return ret;
+            return clang_type;
     }
     
-    clang_type_t ast_type(GetClangTypeImpl());
-    clang_type_t class_type;
-    bool is_pointer_type;
+    ClangASTType class_type;
+    bool is_pointer_type = false;
     
-    if (ClangASTContext::IsObjCObjectPointerType(ast_type, &class_type))
+    if (clang_type.IsObjCObjectPointerType(&class_type))
     {
         is_pointer_type = true;
     }
-    else if (ClangASTContext::IsObjCClassType(ast_type))
+    else if (clang_type.IsObjCObjectOrInterfaceType())
     {
-        is_pointer_type = false;
-        class_type = ast_type;
+        class_type = clang_type;
     }
     else
     {
-        return ret;
+        return clang_type;
     }
     
     m_did_calculate_complete_objc_class_type = true;
     
-    if (!class_type)
-        return ret;
-    
-    std::string class_name;
-    
-    if (!ClangASTContext::GetObjCClassName(class_type, class_name))
-        return ret;
-    
-    ProcessSP process_sp(GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
-    
-    if (!process_sp)
-        return ret;
-    
-    ObjCLanguageRuntime *objc_language_runtime(process_sp->GetObjCLanguageRuntime());
-    
-    if (!objc_language_runtime)
-        return ret;
-    
-    ConstString class_name_cs(class_name.c_str());
-    
-    TypeSP complete_objc_class_type_sp = objc_language_runtime->LookupInCompleteClassCache(class_name_cs);
-    
-    if (!complete_objc_class_type_sp)
-        return ret;
-    
-    ClangASTType complete_class(complete_objc_class_type_sp->GetClangAST(),
-                                complete_objc_class_type_sp->GetClangFullType());
-    
-    if (!ClangASTContext::GetCompleteType(complete_class.GetASTContext(), 
-                                          complete_class.GetOpaqueQualType()))
-        return ret;
-    
-    if (is_pointer_type)
+    if (class_type)
     {
-        clang_type_t pointer_type = ClangASTContext::CreatePointerType(complete_class.GetASTContext(),
-                                                                       complete_class.GetOpaqueQualType());
+        ConstString class_name (class_type.GetConstTypeName());
         
-        m_override_type = ClangASTType(complete_class.GetASTContext(),
-                                       pointer_type);
+        if (class_name)
+        {
+            ProcessSP process_sp(GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
+            
+            if (process_sp)
+            {
+                ObjCLanguageRuntime *objc_language_runtime(process_sp->GetObjCLanguageRuntime());
+                
+                if (objc_language_runtime)
+                {
+                    TypeSP complete_objc_class_type_sp = objc_language_runtime->LookupInCompleteClassCache(class_name);
+                    
+                    if (complete_objc_class_type_sp)
+                    {
+                        ClangASTType complete_class(complete_objc_class_type_sp->GetClangFullType());
+                        
+                        if (complete_class.GetCompleteType())
+                        {
+                            if (is_pointer_type)
+                            {
+                                m_override_type = complete_class.GetPointerType();
+                            }
+                            else
+                            {
+                                m_override_type = complete_class;
+                            }
+                            
+                            if (m_override_type.IsValid())
+                                return m_override_type;
+                        }
+                    }
+                }
+            }
+        }
     }
-    else
-    {
-        m_override_type = complete_class;
-    }
-    
-    if (m_override_type.IsValid())
-        return m_override_type;
-    else
-        return ret;
+    return clang_type;
 }
 
-clang::ASTContext *
-ValueObject::GetClangAST ()
-{
-    ClangASTType type = MaybeCalculateCompleteType();
-    
-    return type.GetASTContext();
-}
-
-lldb::clang_type_t
+ClangASTType
 ValueObject::GetClangType ()
 {
-    ClangASTType type = MaybeCalculateCompleteType();
-    
-    return type.GetOpaqueQualType();
+    return MaybeCalculateCompleteType();
 }
 
 DataExtractor &
@@ -474,7 +453,7 @@
     {
         ExecutionContext exe_ctx (GetExecutionContextRef());
         Value tmp_value(m_value);
-        scalar = tmp_value.ResolveValue(&exe_ctx, GetClangAST ());
+        scalar = tmp_value.ResolveValue(&exe_ctx);
         if (scalar.IsValid())
         {
             const uint32_t bitfield_bit_size = GetBitfieldBitSize();
@@ -620,10 +599,7 @@
 ValueObject::GetIndexOfChildWithName (const ConstString &name)
 {
     bool omit_empty_base_classes = true;
-    return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
-                                                     GetClangType(),
-                                                     name.GetCString(),
-                                                     omit_empty_base_classes);
+    return GetClangType().GetIndexOfChildWithName (name.GetCString(), omit_empty_base_classes);
 }
 
 ValueObjectSP
@@ -639,14 +615,10 @@
         UpdateValueIfNeeded(false);
 
     std::vector<uint32_t> child_indexes;
-    clang::ASTContext *clang_ast = GetClangAST();
-    void *clang_type = GetClangType();
     bool omit_empty_base_classes = true;
-    const size_t num_child_indexes =  ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
-                                                                                      clang_type,
-                                                                                      name.GetCString(),
-                                                                                      omit_empty_base_classes,
-                                                                                      child_indexes);
+    const size_t num_child_indexes =  GetClangType().GetIndexOfChildMemberWithName (name.GetCString(),
+                                                                                    omit_empty_base_classes,
+                                                                                    child_indexes);
     if (num_child_indexes > 0)
     {
         std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
@@ -689,9 +661,9 @@
     const uint32_t type_info = GetTypeInfo();
     if (type_info)
     {
-        if (type_info & (ClangASTContext::eTypeHasChildren |
-                         ClangASTContext::eTypeIsPointer |
-                         ClangASTContext::eTypeIsReference))
+        if (type_info & (ClangASTType::eTypeHasChildren |
+                         ClangASTType::eTypeIsPointer |
+                         ClangASTType::eTypeIsReference))
             has_children = true;
     }
     else
@@ -731,27 +703,23 @@
     bool child_is_deref_of_parent = false;
 
     const bool transparent_pointers = synthetic_array_member == false;
-    clang::ASTContext *clang_ast = GetClangAST();
-    clang_type_t clang_type = GetClangType();
-    clang_type_t child_clang_type;
+    ClangASTType child_clang_type;
     
     ExecutionContext exe_ctx (GetExecutionContextRef());
     
-    child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
-                                                                  clang_ast,
-                                                                  GetName().GetCString(),
-                                                                  clang_type,
-                                                                  idx,
-                                                                  transparent_pointers,
-                                                                  omit_empty_base_classes,
-                                                                  ignore_array_bounds,
-                                                                  child_name_str,
-                                                                  child_byte_size,
-                                                                  child_byte_offset,
-                                                                  child_bitfield_bit_size,
-                                                                  child_bitfield_bit_offset,
-                                                                  child_is_base_class,
-                                                                  child_is_deref_of_parent);
+    child_clang_type = GetClangType().GetChildClangTypeAtIndex (&exe_ctx,
+                                                                GetName().GetCString(),
+                                                                idx,
+                                                                transparent_pointers,
+                                                                omit_empty_base_classes,
+                                                                ignore_array_bounds,
+                                                                child_name_str,
+                                                                child_byte_size,
+                                                                child_byte_offset,
+                                                                child_bitfield_bit_size,
+                                                                child_bitfield_bit_offset,
+                                                                child_is_base_class,
+                                                                child_is_deref_of_parent);
     if (child_clang_type)
     {
         if (synthetic_index)
@@ -762,7 +730,6 @@
             child_name.SetCString (child_name_str.c_str());
 
         valobj = new ValueObjectChild (*this,
-                                       clang_ast,
                                        child_clang_type,
                                        child_name,
                                        child_byte_size,
@@ -809,19 +776,14 @@
         }
         else
         {
-            clang_type_t clang_type = GetClangType();
+            ClangASTType clang_type = GetClangType();
             
             // Do some default printout for function pointers
             if (clang_type)
             {
-                StreamString sstr;
-                clang_type_t elem_or_pointee_clang_type;
-                const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, 
-                                                                      GetClangAST(), 
-                                                                      &elem_or_pointee_clang_type));
-                
-                if (ClangASTContext::IsFunctionPointerType (clang_type))
+                if (clang_type.IsFunctionPointerType ())
                 {
+                    StreamString sstr;
                     AddressType func_ptr_address_type = eAddressTypeInvalid;
                     addr_t func_ptr_address = GetPointerValue (&func_ptr_address_type);
                     if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
@@ -885,15 +847,15 @@
 bool
 ValueObject::IsCStringContainer(bool check_pointer)
 {
-    clang_type_t elem_or_pointee_clang_type;
-    const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type));
-    bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
-                          ClangASTContext::IsCharType (elem_or_pointee_clang_type));
+    ClangASTType pointee_or_element_clang_type;
+    const Flags type_flags (GetTypeInfo (&pointee_or_element_clang_type));
+    bool is_char_arr_ptr (type_flags.AnySet (ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) &&
+                          pointee_or_element_clang_type.IsCharType ());
     if (!is_char_arr_ptr)
         return false;
     if (!check_pointer)
         return true;
-    if (type_flags.Test(ClangASTContext::eTypeIsArray))
+    if (type_flags.Test(ClangASTType::eTypeIsArray))
         return true;
     addr_t cstr_address = LLDB_INVALID_ADDRESS;
     AddressType cstr_address_type = eAddressTypeInvalid;
@@ -906,23 +868,18 @@
                              uint32_t item_idx,
                              uint32_t item_count)
 {
-    clang_type_t pointee_or_element_clang_type;
+    ClangASTType pointee_or_element_clang_type;
     const uint32_t type_info = GetTypeInfo (&pointee_or_element_clang_type);
-    const bool is_pointer_type = type_info & ClangASTContext::eTypeIsPointer;
-    const bool is_array_type = type_info & ClangASTContext::eTypeIsArray;
+    const bool is_pointer_type = type_info & ClangASTType::eTypeIsPointer;
+    const bool is_array_type = type_info & ClangASTType::eTypeIsArray;
     if (!(is_pointer_type || is_array_type))
         return 0;
     
     if (item_count == 0)
         return 0;
     
-    clang::ASTContext *ast = GetClangAST();
-    ClangASTType pointee_or_element_type(ast, pointee_or_element_clang_type);
-    
-    const uint64_t item_type_size = pointee_or_element_type.GetClangTypeByteSize();
-    
+    const uint64_t item_type_size = pointee_or_element_clang_type.GetByteSize();
     const uint64_t bytes = item_count * item_type_size;
-    
     const uint64_t offset = item_idx * item_type_size;
     
     if (item_idx == 0 && item_count == 1) // simply a deref
@@ -996,8 +953,7 @@
                 break;
             case eAddressTypeHost:
                 {
-                    ClangASTType valobj_type(ast, GetClangType());
-                    uint64_t max_bytes = valobj_type.GetClangTypeByteSize();
+                    const uint64_t max_bytes = GetClangType().GetByteSize();
                     if (max_bytes > offset)
                     {
                         size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes);
@@ -1019,7 +975,7 @@
 {
     UpdateValueIfNeeded(false);
     ExecutionContext exe_ctx (GetExecutionContextRef());
-    Error error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), data, 0, GetModule().get());
+    Error error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
     if (error.Fail())
     {
         if (m_data.GetByteSize())
@@ -1050,7 +1006,7 @@
     }
     
     uint64_t count = 0;
-    Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
+    const Encoding encoding = GetClangType().GetEncoding(count);
     
     const size_t byte_size = GetByteSize();
     
@@ -1163,25 +1119,29 @@
     size_t bytes_read = 0;
     size_t total_bytes_read = 0;
     
-    clang_type_t clang_type = GetClangType();
-    clang_type_t elem_or_pointee_clang_type;
+    ClangASTType clang_type = GetClangType();
+    ClangASTType elem_or_pointee_clang_type;
     const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type));
-    if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
-        ClangASTContext::IsCharType (elem_or_pointee_clang_type))
+    if (type_flags.AnySet (ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) &&
+        elem_or_pointee_clang_type.IsCharType ())
     {
         addr_t cstr_address = LLDB_INVALID_ADDRESS;
         AddressType cstr_address_type = eAddressTypeInvalid;
         
         size_t cstr_len = 0;
         bool capped_data = false;
-        if (type_flags.Test (ClangASTContext::eTypeIsArray))
+        if (type_flags.Test (ClangASTType::eTypeIsArray))
         {
             // We have an array
-            cstr_len = ClangASTContext::GetArraySize (clang_type);
-            if (cstr_len > max_length)
+            uint64_t array_size = 0;
+            if (clang_type.IsArrayType(NULL, &array_size, NULL))
             {
-                capped_data = true;
-                cstr_len = max_length;
+                cstr_len = array_size;
+                if (cstr_len > max_length)
+                {
+                    capped_data = true;
+                    cstr_len = max_length;
+                }
             }
             cstr_address = GetAddressOf (true, &cstr_address_type);
         }
@@ -1318,12 +1278,11 @@
     if (runtime == NULL)
     {
         // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
-        clang_type_t opaque_qual_type = GetClangType();
-        if (opaque_qual_type != NULL)
+        ClangASTType clang_type = GetClangType();
+        if (clang_type)
         {
             bool is_signed;
-            if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed) 
-                || ClangASTContext::IsPointerType (opaque_qual_type))
+            if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType ())
             {
                 runtime = process->GetLanguageRuntime(eLanguageTypeObjC);
             }
@@ -1345,94 +1304,79 @@
 ValueObject::GetValueAsCString (lldb::Format format,
                                 std::string& destination)
 {
-    if (ClangASTContext::IsAggregateType (GetClangType()) == false &&
-        UpdateValueIfNeeded(false))
+    if (GetClangType().IsAggregateType () == false && UpdateValueIfNeeded(false))
     {
         const Value::ContextType context_type = m_value.GetContextType();
         
-        switch (context_type)
+        if (context_type == Value::eContextTypeRegisterInfo)
         {
-            case Value::eContextTypeClangType:
-            case Value::eContextTypeLLDBType:
-            case Value::eContextTypeVariable:
+            const RegisterInfo *reg_info = m_value.GetRegisterInfo();
+            if (reg_info)
             {
-                clang_type_t clang_type = GetClangType ();
-                if (clang_type)
+                ExecutionContext exe_ctx (GetExecutionContextRef());
+                
+                StreamString reg_sstr;
+                m_data.Dump (&reg_sstr,
+                             0,
+                             format,
+                             reg_info->byte_size,
+                             1,
+                             UINT32_MAX,
+                             LLDB_INVALID_ADDRESS,
+                             0,
+                             0,
+                             exe_ctx.GetBestExecutionContextScope());
+                destination.swap(reg_sstr.GetString());
+            }
+        }
+        else
+        {
+            ClangASTType clang_type = GetClangType ();
+            if (clang_type)
+            {
+                 // put custom bytes to display in this DataExtractor to override the default value logic
+                lldb_private::DataExtractor special_format_data;
+                if (format == eFormatCString)
                 {
-                     // put custom bytes to display in this DataExtractor to override the default value logic
-                    lldb_private::DataExtractor special_format_data;
-                    clang::ASTContext* ast = GetClangAST();
-                    if (format == eFormatCString)
+                    Flags type_flags(clang_type.GetTypeInfo(NULL));
+                    if (type_flags.Test(ClangASTType::eTypeIsPointer) && !type_flags.Test(ClangASTType::eTypeIsObjC))
                     {
-                        Flags type_flags(ClangASTContext::GetTypeInfo(clang_type, ast, NULL));
-                        if (type_flags.Test(ClangASTContext::eTypeIsPointer) && !type_flags.Test(ClangASTContext::eTypeIsObjC))
+                        // if we are dumping a pointer as a c-string, get the pointee data as a string
+                        TargetSP target_sp(GetTargetSP());
+                        if (target_sp)
                         {
-                            // if we are dumping a pointer as a c-string, get the pointee data as a string
-                            TargetSP target_sp(GetTargetSP());
-                            if (target_sp)
-                            {
-                                size_t max_len = target_sp->GetMaximumSizeOfStringSummary();
-                                Error error;
-                                DataBufferSP buffer_sp(new DataBufferHeap(max_len+1,0));
-                                Address address(GetPointerValue());
-                                if (target_sp->ReadCStringFromMemory(address, (char*)buffer_sp->GetBytes(), max_len, error) && error.Success())
-                                    special_format_data.SetData(buffer_sp);
-                            }
+                            size_t max_len = target_sp->GetMaximumSizeOfStringSummary();
+                            Error error;
+                            DataBufferSP buffer_sp(new DataBufferHeap(max_len+1,0));
+                            Address address(GetPointerValue());
+                            if (target_sp->ReadCStringFromMemory(address, (char*)buffer_sp->GetBytes(), max_len, error) && error.Success())
+                                special_format_data.SetData(buffer_sp);
                         }
                     }
-                    
-                    StreamString sstr;
-                    ExecutionContext exe_ctx (GetExecutionContextRef());
-                    ClangASTType::DumpTypeValue (ast,                           // The clang AST
-                                                 clang_type,                    // The clang type to display
-                                                 &sstr,                         // The stream to use for display
-                                                 format,                        // Format to display this type with
-                                                 special_format_data.GetByteSize() ?
-                                                 special_format_data: m_data,   // Data to extract from
-                                                 0,                             // Byte offset into "m_data"
-                                                 GetByteSize(),                 // Byte size of item in "m_data"
-                                                 GetBitfieldBitSize(),          // Bitfield bit size
-                                                 GetBitfieldBitOffset(),        // Bitfield bit offset
-                                                 exe_ctx.GetBestExecutionContextScope()); 
-                    // Don't set the m_error to anything here otherwise
-                    // we won't be able to re-format as anything else. The
-                    // code for ClangASTType::DumpTypeValue() should always
-                    // return something, even if that something contains
-                    // an error messsage. "m_error" is used to detect errors
-                    // when reading the valid object, not for formatting errors.
-                    if (sstr.GetString().empty())
-                        destination.clear();
-                    else
-                        destination.swap(sstr.GetString());
                 }
-            }
-                break;
                 
-            case Value::eContextTypeRegisterInfo:
-            {
-                const RegisterInfo *reg_info = m_value.GetRegisterInfo();
-                if (reg_info)
-                {
-                    ExecutionContext exe_ctx (GetExecutionContextRef());
-                    
-                    StreamString reg_sstr;
-                    m_data.Dump (&reg_sstr, 
-                                 0, 
-                                 format, 
-                                 reg_info->byte_size, 
-                                 1, 
-                                 UINT32_MAX, 
-                                 LLDB_INVALID_ADDRESS, 
-                                 0, 
-                                 0, 
-                                 exe_ctx.GetBestExecutionContextScope());
-                    destination.swap(reg_sstr.GetString());
-                }
+                StreamString sstr;
+                ExecutionContext exe_ctx (GetExecutionContextRef());
+                clang_type.DumpTypeValue (&sstr,                         // The stream to use for display
+                                          format,                        // Format to display this type with
+                                          special_format_data.GetByteSize() ?
+                                          special_format_data: m_data,   // Data to extract from
+                                          0,                             // Byte offset into "m_data"
+                                          GetByteSize(),                 // Byte size of item in "m_data"
+                                          GetBitfieldBitSize(),          // Bitfield bit size
+                                          GetBitfieldBitOffset(),        // Bitfield bit offset
+                                          exe_ctx.GetBestExecutionContextScope());
+                // Don't set the m_error to anything here otherwise
+                // we won't be able to re-format as anything else. The
+                // code for ClangASTType::DumpTypeValue() should always
+                // return something, even if that something contains
+                // an error messsage. "m_error" is used to detect errors
+                // when reading the valid object, not for formatting errors.
+                if (sstr.GetString().empty())
+                    destination.clear();
+                else
+                    destination.swap(sstr.GetString());
             }
-                break;
-                
-            default:
-                break;
         }
         return !destination.empty();
     }
@@ -1464,8 +1408,7 @@
                     }
                     else
                     {
-                        clang_type_t clang_type = GetClangType ();
-                        my_format = ClangASTType::GetFormat(clang_type);
+                        my_format = GetClangType().GetFormat();
                     }
                 }
             }
@@ -1495,7 +1438,7 @@
 ValueObject::GetValueAsUnsigned (uint64_t fail_value, bool *success)
 {
     // If our byte size is zero this is an aggregate type that has children
-    if (ClangASTContext::IsAggregateType (GetClangType()) == false)
+    if (!GetClangType().IsAggregateType())
     {
         Scalar scalar;
         if (ResolveValue (scalar))
@@ -1519,10 +1462,8 @@
 ValueObject::HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
                                                Format custom_format)
 {
-    clang_type_t elem_or_pointee_type;
-    Flags flags(GetTypeInfo(&elem_or_pointee_type));
-    
-    if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
+    Flags flags(GetTypeInfo());
+    if (flags.AnySet(ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer)
         && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
     {        
         if (IsCStringContainer(true) && 
@@ -1532,7 +1473,7 @@
              custom_format == eFormatVectorOfChar))
             return true;
 
-        if (flags.Test(ClangASTContext::eTypeIsArray))
+        if (flags.Test(ClangASTType::eTypeIsArray))
         {
             if ((custom_format == eFormatBytes) ||
                 (custom_format == eFormatBytesWithASCII))
@@ -1563,15 +1504,14 @@
                                          PrintableRepresentationSpecialCases special)
 {
 
-    clang_type_t elem_or_pointee_type;
-    Flags flags(GetTypeInfo(&elem_or_pointee_type));
+    Flags flags(GetTypeInfo());
     
     bool allow_special = ((special & ePrintableRepresentationSpecialCasesAllow) == ePrintableRepresentationSpecialCasesAllow);
     bool only_special = ((special & ePrintableRepresentationSpecialCasesOnly) == ePrintableRepresentationSpecialCasesOnly);
     
     if (allow_special)
     {
-        if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
+        if (flags.AnySet(ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer)
              && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
         {
             // when being asked to get a printable display an array or pointer type directly, 
@@ -1597,7 +1537,7 @@
             
             // this only works for arrays, because I have no way to know when
             // the pointed memory ends, and no special \0 end of data marker
-            if (flags.Test(ClangASTContext::eTypeIsArray))
+            if (flags.Test(ClangASTType::eTypeIsArray))
             {
                 if ((custom_format == eFormatBytes) ||
                     (custom_format == eFormatBytesWithASCII))
@@ -1745,7 +1685,7 @@
                 cstr = GetSummaryAsCString();
             else if (val_obj_display == eValueObjectRepresentationStyleSummary)
             {
-                if (ClangASTContext::IsAggregateType (GetClangType()) == true)
+                if (GetClangType().IsAggregateType())
                 {
                     strm.Printf("%s @ %s", GetTypeName().AsCString(), GetLocationAsCString());
                     cstr = strm.GetString().c_str();
@@ -1862,7 +1802,7 @@
     }
 
     uint64_t count = 0;
-    Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
+    const Encoding encoding = GetClangType().GetEncoding (count);
 
     const size_t byte_size = GetByteSize();
 
@@ -1960,21 +1900,20 @@
 ConstString
 ValueObject::GetTypeName()
 {
-    return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
+    return GetClangType().GetConstTypeName();
 }
 
 ConstString
 ValueObject::GetQualifiedTypeName()
 {
-    return ClangASTType::GetConstQualifiedTypeName (GetClangAST(), GetClangType());
+    return GetClangType().GetConstQualifiedTypeName();
 }
 
 
 LanguageType
 ValueObject::GetObjectRuntimeLanguage ()
 {
-    return ClangASTType::GetMinimumLanguage (GetClangAST(),
-                                             GetClangType());
+    return GetClangType().GetMinimumLanguage ();
 }
 
 void
@@ -1994,39 +1933,39 @@
 }
 
 uint32_t
-ValueObject::GetTypeInfo (clang_type_t *pointee_or_element_clang_type)
+ValueObject::GetTypeInfo (ClangASTType *pointee_or_element_clang_type)
 {
-    return ClangASTContext::GetTypeInfo (GetClangType(), GetClangAST(), pointee_or_element_clang_type);
+    return GetClangType().GetTypeInfo (pointee_or_element_clang_type);
 }
 
 bool
 ValueObject::IsPointerType ()
 {
-    return ClangASTContext::IsPointerType (GetClangType());
+    return GetClangType().IsPointerType();
 }
 
 bool
 ValueObject::IsArrayType ()
 {
-    return ClangASTContext::IsArrayType (GetClangType(), NULL, NULL, NULL);
+    return GetClangType().IsArrayType (NULL, NULL, NULL);
 }
 
 bool
 ValueObject::IsScalarType ()
 {
-    return ClangASTContext::IsScalarType (GetClangType());
+    return GetClangType().IsScalarType ();
 }
 
 bool
 ValueObject::IsIntegerType (bool &is_signed)
 {
-    return ClangASTContext::IsIntegerType (GetClangType(), is_signed);
+    return GetClangType().IsIntegerType (is_signed);
 }
 
 bool
 ValueObject::IsPointerOrReferenceType ()
 {
-    return ClangASTContext::IsPointerOrReferenceType (GetClangType());
+    return GetClangType().IsPointerOrReferenceType ();
 }
 
 bool
@@ -2037,14 +1976,14 @@
     if (process)
         return process->IsPossibleDynamicValue(*this);
     else
-        return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType(), NULL, true, true);
+        return GetClangType().IsPossibleDynamicType (NULL, true, true);
 }
 
 bool
 ValueObject::IsObjCNil ()
 {
-    const uint32_t mask = ClangASTContext::eTypeIsObjC | ClangASTContext::eTypeIsPointer;
-    bool isObjCpointer = ( ((ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), NULL)) & mask) == mask);
+    const uint32_t mask = ClangASTType::eTypeIsObjC | ClangASTType::eTypeIsPointer;
+    bool isObjCpointer = (((GetClangType().GetTypeInfo(NULL)) & mask) == mask);
     if (!isObjCpointer)
         return false;
     bool canReadValue = true;
@@ -2056,10 +1995,10 @@
 ValueObject::GetSyntheticArrayMember (size_t index, bool can_create)
 {
     const uint32_t type_info = GetTypeInfo ();
-    if (type_info & ClangASTContext::eTypeIsArray)
+    if (type_info & ClangASTType::eTypeIsArray)
         return GetSyntheticArrayMemberFromArray(index, can_create);
 
-    if (type_info & ClangASTContext::eTypeIsPointer)
+    if (type_info & ClangASTType::eTypeIsPointer)
         return GetSyntheticArrayMemberFromPointer(index, can_create);
     
     return ValueObjectSP();
@@ -2155,20 +2094,18 @@
         synthetic_child_sp = GetSyntheticChild (index_const_str);
         if (!synthetic_child_sp)
         {
-            ValueObjectChild *synthetic_child;
             // We haven't made a synthetic array member for INDEX yet, so
             // lets make one and cache it for any future reference.
-            synthetic_child = new ValueObjectChild(*this,
-                                                      GetClangAST(),
-                                                      GetClangType(),
-                                                      index_const_str,
-                                                      GetByteSize(),
-                                                      0,
-                                                      to-from+1,
-                                                      from,
-                                                      false,
-                                                      false,
-                                                      eAddressTypeInvalid);
+            ValueObjectChild *synthetic_child = new ValueObjectChild (*this,
+                                                                      GetClangType(),
+                                                                      index_const_str,
+                                                                      GetByteSize(),
+                                                                      0,
+                                                                      to-from+1,
+                                                                      from,
+                                                                      false,
+                                                                      false,
+                                                                      eAddressTypeInvalid);
             
             // Cache the value if we got one back...
             if (synthetic_child)
@@ -2204,10 +2141,9 @@
         return ValueObjectSP();
     
     ValueObjectChild *synthetic_child = new ValueObjectChild(*this,
-                                                             type.GetASTContext(),
-                                                             type.GetOpaqueQualType(),
+                                                             type,
                                                              name_const_str,
-                                                             type.GetTypeByteSize(),
+                                                             type.GetByteSize(),
                                                              offset,
                                                              0,
                                                              0,
@@ -2377,9 +2313,9 @@
     if (IsBaseClass())
     {
         bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
-        clang_type_t clang_type = GetClangType();
+        ClangASTType clang_type = GetClangType();
         std::string cxx_class_name;
-        bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
+        bool this_had_base_class = clang_type.GetCXXClassName (cxx_class_name);
         if (this_had_base_class)
         {
             if (parent_had_base_class)
@@ -2436,23 +2372,23 @@
             ValueObject *non_base_class_parent = GetNonBaseClassParent();
             if (non_base_class_parent)
             {
-                clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
+                ClangASTType non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
                 if (non_base_class_parent_clang_type)
                 {
-                    const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
-                    
                     if (parent && parent->IsDereferenceOfParent() && epformat == eGetExpressionPathFormatHonorPointers)
                     {
                         s.PutCString("->");
                     }
                     else
                     {                    
-                        if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer)
+                        const uint32_t non_base_class_parent_type_info = non_base_class_parent_clang_type.GetTypeInfo();
+                        
+                        if (non_base_class_parent_type_info & ClangASTType::eTypeIsPointer)
                         {
                             s.PutCString("->");
                         }
-                        else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) &&
-                                 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray))
+                        else if ((non_base_class_parent_type_info & ClangASTType::eTypeHasChildren) &&
+                                 !(non_base_class_parent_type_info & ClangASTType::eTypeIsArray))
                         {
                             s.PutChar('.');
                         }
@@ -2657,13 +2593,13 @@
         
         const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
         
-        clang_type_t root_clang_type = root->GetClangType();
-        clang_type_t pointee_clang_type;
-        Flags root_clang_type_info,pointee_clang_type_info;
+        ClangASTType root_clang_type = root->GetClangType();
+        ClangASTType pointee_clang_type;
+        Flags pointee_clang_type_info;
         
-        root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
+        Flags root_clang_type_info(root_clang_type.GetTypeInfo(&pointee_clang_type));
         if (pointee_clang_type)
-            pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
+            pointee_clang_type_info.Reset(pointee_clang_type.GetTypeInfo());
         
         if (!expression_cstr || *expression_cstr == '\0')
         {
@@ -2676,15 +2612,15 @@
             case '-':
             {
                 if (options.m_check_dot_vs_arrow_syntax &&
-                    root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error
+                    root_clang_type_info.Test(ClangASTType::eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error
                 {
                     *first_unparsed = expression_cstr;
                     *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
                     *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
                     return ValueObjectSP();
                 }
-                if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) &&  // if yo are trying to extract an ObjC IVar when this is forbidden
-                    root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) &&
+                if (root_clang_type_info.Test(ClangASTType::eTypeIsObjC) &&  // if yo are trying to extract an ObjC IVar when this is forbidden
+                    root_clang_type_info.Test(ClangASTType::eTypeIsPointer) &&
                     options.m_no_fragile_ivar)
                 {
                     *first_unparsed = expression_cstr;
@@ -2704,7 +2640,7 @@
             case '.': // or fallthrough from ->
             {
                 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
-                    root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error
+                    root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error
                 {
                     *first_unparsed = expression_cstr;
                     *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
@@ -2805,9 +2741,9 @@
             }
             case '[':
             {
-                if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && !root_clang_type_info.Test(ClangASTContext::eTypeIsVector)) // if this is not a T[] nor a T*
+                if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray) && !root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && !root_clang_type_info.Test(ClangASTType::eTypeIsVector)) // if this is not a T[] nor a T*
                 {
-                    if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar...
+                    if (!root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // if this is not even a scalar...
                     {
                         if (options.m_no_synthetic_children) // ...only chance left is synthetic
                         {
@@ -2827,7 +2763,7 @@
                 }
                 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
                 {
-                    if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
+                    if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray))
                     {
                         *first_unparsed = expression_cstr;
                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
@@ -2864,7 +2800,7 @@
                     }
                     if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
                     {
-                        if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
+                        if (root_clang_type_info.Test(ClangASTType::eTypeIsArray))
                         {
                             *first_unparsed = expression_cstr+2;
                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
@@ -2880,7 +2816,7 @@
                         }
                     }
                     // from here on we do have a valid index
-                    if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
+                    if (root_clang_type_info.Test(ClangASTType::eTypeIsArray))
                     {
                         ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
                         if (!child_valobj_sp)
@@ -2903,10 +2839,10 @@
                             return ValueObjectSP();
                         }
                     }
-                    else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
+                    else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer))
                     {
                         if (*what_next == ValueObject::eExpressionPathAftermathDereference &&  // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
-                            pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
+                            pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar))
                         {
                             Error error;
                             root = root->Dereference(error);
@@ -2925,9 +2861,8 @@
                         }
                         else
                         {
-                            if (ClangASTType::GetMinimumLanguage(root->GetClangAST(),
-                                                                 root->GetClangType()) == eLanguageTypeObjC
-                                && pointee_clang_type_info.AllClear(ClangASTContext::eTypeIsPointer)
+                            if (root->GetClangType().GetMinimumLanguage() == eLanguageTypeObjC
+                                && pointee_clang_type_info.AllClear(ClangASTType::eTypeIsPointer)
                                 && root->HasSyntheticValue()
                                 && options.m_no_synthetic_children == false)
                             {
@@ -2950,7 +2885,7 @@
                             }
                         }
                     }
-                    else if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
+                    else if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar))
                     {
                         root = root->GetSyntheticBitFieldChild(index, index, true);
                         if (!root.get())
@@ -2968,7 +2903,7 @@
                             return root;
                         }
                     }
-                    else if (root_clang_type_info.Test(ClangASTContext::eTypeIsVector))
+                    else if (root_clang_type_info.Test(ClangASTType::eTypeIsVector))
                     {
                         root = root->GetChildAtIndex(index, true);
                         if (!root.get())
@@ -3053,7 +2988,7 @@
                         index_lower = index_higher;
                         index_higher = temp;
                     }
-                    if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
+                    if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // expansion only works for scalars
                     {
                         root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
                         if (!root.get())
@@ -3071,9 +3006,9 @@
                             return root;
                         }
                     }
-                    else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
+                    else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
                              *what_next == ValueObject::eExpressionPathAftermathDereference &&
-                             pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
+                             pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar))
                     {
                         Error error;
                         root = root->Dereference(error);
@@ -3132,13 +3067,12 @@
         
         const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
         
-        clang_type_t root_clang_type = root->GetClangType();
-        clang_type_t pointee_clang_type;
-        Flags root_clang_type_info,pointee_clang_type_info;
-        
-        root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type));
+        ClangASTType root_clang_type = root->GetClangType();
+        ClangASTType pointee_clang_type;
+        Flags pointee_clang_type_info;
+        Flags root_clang_type_info(root_clang_type.GetTypeInfo(&pointee_clang_type));
         if (pointee_clang_type)
-            pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL));
+            pointee_clang_type_info.Reset(pointee_clang_type.GetTypeInfo());
         
         if (!expression_cstr || *expression_cstr == '\0')
         {
@@ -3151,9 +3085,9 @@
         {
             case '[':
             {
-                if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T*
+                if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray) && !root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) // if this is not a T[] nor a T*
                 {
-                    if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
+                    if (!root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
                     {
                         *first_unparsed = expression_cstr;
                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
@@ -3170,7 +3104,7 @@
                 }
                 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
                 {
-                    if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
+                    if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray))
                     {
                         *first_unparsed = expression_cstr;
                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
@@ -3214,7 +3148,7 @@
                     }
                     if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
                     {
-                        if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
+                        if (root_clang_type_info.Test(ClangASTType::eTypeIsArray))
                         {
                             const size_t max_index = root->GetNumChildren() - 1;
                             for (size_t index = 0; index < max_index; index++)
@@ -3237,7 +3171,7 @@
                         }
                     }
                     // from here on we do have a valid index
-                    if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
+                    if (root_clang_type_info.Test(ClangASTType::eTypeIsArray))
                     {
                         root = root->GetChildAtIndex(index, true);
                         if (!root.get())
@@ -3256,10 +3190,10 @@
                             return 1;
                         }
                     }
-                    else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer))
+                    else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer))
                     {
                         if (*what_next == ValueObject::eExpressionPathAftermathDereference &&  // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
-                            pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
+                            pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar))
                         {
                             Error error;
                             root = root->Dereference(error);
@@ -3341,7 +3275,7 @@
                         index_lower = index_higher;
                         index_higher = temp;
                     }
-                    if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars
+                    if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // expansion only works for scalars
                     {
                         root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
                         if (!root.get())
@@ -3360,9 +3294,9 @@
                             return 1;
                         }
                     }
-                    else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
+                    else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
                              *what_next == ValueObject::eExpressionPathAftermathDereference &&
-                             pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar))
+                             pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar))
                     {
                         Error error;
                         root = root->Dereference(error);
@@ -3431,12 +3365,11 @@
                 valobj = dynamic_value;
         }
         
-        clang_type_t clang_type = valobj->GetClangType();
-
-        const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL));
+        ClangASTType clang_type = valobj->GetClangType();
+        const Flags type_flags (clang_type.GetTypeInfo ());
         const char *err_cstr = NULL;
-        const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
-        const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
+        const bool has_children = type_flags.Test (ClangASTType::eTypeHasChildren);
+        const bool has_value = type_flags.Test (ClangASTType::eTypeHasValue);
         
         const bool print_valobj = options.m_flat_output == false || has_value;
         
@@ -3521,7 +3454,7 @@
         }
         else
         {
-            const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
+            const bool is_ref = type_flags.Test (ClangASTType::eTypeIsReference);
             if (print_valobj)
             {
                 if (is_nil)
@@ -3573,7 +3506,7 @@
                 // current pointer depth below...
                 uint32_t curr_ptr_depth = ptr_depth;
 
-                const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer);
+                const bool is_ptr = type_flags.Test (ClangASTType::eTypeIsPointer);
                 if (is_ptr || is_ref)
                 {
                     // We have a pointer or reference whose value is an address.
@@ -3742,7 +3675,6 @@
     if (UpdateValueIfNeeded(false) && m_error.Success())
     {
         ExecutionContext exe_ctx (GetExecutionContextRef());
-        clang::ASTContext *ast = GetClangAST ();
         
         DataExtractor data;
         data.SetByteOrder (m_data.GetByteOrder());
@@ -3751,13 +3683,12 @@
         if (IsBitfield())
         {
             Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
-            m_error = v.GetValueAsData (&exe_ctx, ast, data, 0, GetModule().get());
+            m_error = v.GetValueAsData (&exe_ctx, data, 0, GetModule().get());
         }
         else
-            m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule().get());
+            m_error = m_value.GetValueAsData (&exe_ctx, data, 0, GetModule().get());
         
         valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), 
-                                                    ast,
                                                     GetClangType(),
                                                     name,
                                                     data,
@@ -3791,27 +3722,24 @@
         bool child_is_base_class = false;
         bool child_is_deref_of_parent = false;
         const bool transparent_pointers = false;
-        clang::ASTContext *clang_ast = GetClangAST();
-        clang_type_t clang_type = GetClangType();
-        clang_type_t child_clang_type;
+        ClangASTType clang_type = GetClangType();
+        ClangASTType child_clang_type;
 
         ExecutionContext exe_ctx (GetExecutionContextRef());
         
-        child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
-                                                                      clang_ast,
-                                                                      GetName().GetCString(),
-                                                                      clang_type,
-                                                                      0,
-                                                                      transparent_pointers,
-                                                                      omit_empty_base_classes,
-                                                                      ignore_array_bounds,
-                                                                      child_name_str,
-                                                                      child_byte_size,
-                                                                      child_byte_offset,
-                                                                      child_bitfield_bit_size,
-                                                                      child_bitfield_bit_offset,
-                                                                      child_is_base_class,
-                                                                      child_is_deref_of_parent);
+        child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx,
+                                                                GetName().GetCString(),
+                                                                0,
+                                                                transparent_pointers,
+                                                                omit_empty_base_classes,
+                                                                ignore_array_bounds,
+                                                                child_name_str,
+                                                                child_byte_size,
+                                                                child_byte_offset,
+                                                                child_bitfield_bit_size,
+                                                                child_bitfield_bit_offset,
+                                                                child_is_base_class,
+                                                                child_is_deref_of_parent);
         if (child_clang_type && child_byte_size)
         {
             ConstString child_name;
@@ -3819,7 +3747,6 @@
                 child_name.SetCString (child_name_str.c_str());
 
             m_deref_valobj = new ValueObjectChild (*this,
-                                                   clang_ast,
                                                    child_clang_type,
                                                    child_name,
                                                    child_byte_size,
@@ -3876,16 +3803,14 @@
         case eAddressTypeLoad:
         case eAddressTypeHost:
             {
-                clang::ASTContext *ast = GetClangAST();
-                clang_type_t clang_type = GetClangType();
-                if (ast && clang_type)
+                ClangASTType clang_type = GetClangType();
+                if (clang_type)
                 {
                     std::string name (1, '&');
                     name.append (m_name.AsCString(""));
                     ExecutionContext exe_ctx (GetExecutionContextRef());
                     m_addr_of_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
-                                                                          ast, 
-                                                                          ClangASTContext::CreatePointerType (ast, clang_type),
+                                                                          clang_type.GetPointerType(),
                                                                           ConstString (name.c_str()),
                                                                           addr, 
                                                                           eAddressTypeInvalid,
@@ -4104,103 +4029,6 @@
 }
         
 
-//bool
-//ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
-//{
-//    if (!IsValid())
-//        return false;
-//    
-//    bool needs_update = false;
-//    
-//    // The target has to be non-null, and the 
-//    Target *target = exe_scope->CalculateTarget();
-//    if (target != NULL)
-//    {
-//        Target *old_target = m_target_sp.get();
-//        assert (target == old_target);
-//        Process *process = exe_scope->CalculateProcess();
-//        if (process != NULL)
-//        {
-//            // FOR NOW - assume you can't update variable objects across process boundaries.
-//            Process *old_process = m_process_sp.get();
-//            assert (process == old_process);
-//            ProcessModID current_mod_id = process->GetModID();
-//            if (m_mod_id != current_mod_id)
-//            {
-//                needs_update = true;
-//                m_mod_id = current_mod_id;
-//            }
-//            // See if we're switching the thread or stack context.  If no thread is given, this is
-//            // being evaluated in a global context.            
-//            Thread *thread = exe_scope->CalculateThread();
-//            if (thread != NULL)
-//            {
-//                user_id_t new_thread_index = thread->GetIndexID();
-//                if (new_thread_index != m_thread_id)
-//                {
-//                    needs_update = true;
-//                    m_thread_id = new_thread_index;
-//                    m_stack_id.Clear();
-//                }
-//                
-//                StackFrame *new_frame = exe_scope->CalculateStackFrame();
-//                if (new_frame != NULL)
-//                {
-//                    if (new_frame->GetStackID() != m_stack_id)
-//                    {
-//                        needs_update = true;
-//                        m_stack_id = new_frame->GetStackID();
-//                    }
-//                }
-//                else
-//                {
-//                    m_stack_id.Clear();
-//                    needs_update = true;
-//                }
-//            }
-//            else
-//            {
-//                // If this had been given a thread, and now there is none, we should update.
-//                // Otherwise we don't have to do anything.
-//                if (m_thread_id != LLDB_INVALID_UID)
-//                {
-//                    m_thread_id = LLDB_INVALID_UID;
-//                    m_stack_id.Clear();
-//                    needs_update = true;
-//                }
-//            }
-//        }
-//        else
-//        {
-//            // If there is no process, then we don't need to update anything.
-//            // But if we're switching from having a process to not, we should try to update.
-//            if (m_process_sp.get() != NULL)
-//            {
-//                needs_update = true;
-//                m_process_sp.reset();
-//                m_thread_id = LLDB_INVALID_UID;
-//                m_stack_id.Clear();
-//            }
-//        }
-//    }
-//    else
-//    {
-//        // If there's no target, nothing can change so we don't need to update anything.
-//        // But if we're switching from having a target to not, we should try to update.
-//        if (m_target_sp.get() != NULL)
-//        {
-//            needs_update = true;
-//            m_target_sp.reset();
-//            m_process_sp.reset();
-//            m_thread_id = LLDB_INVALID_UID;
-//            m_stack_id.Clear();
-//        }
-//    }
-//    if (!m_needs_update)
-//        m_needs_update = needs_update;
-//        
-//    return needs_update;
-//}
 
 void
 ValueObject::ClearUserVisibleData(uint32_t clear_mask)
@@ -4262,24 +4090,30 @@
                                            const ExecutionContext& exe_ctx,
                                            ClangASTType type)
 {
-    ClangASTType pointer_type(type.GetASTContext(),type.GetPointerType());
-    lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
-    lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
-                                                                             pointer_type.GetASTContext(),
-                                                                             pointer_type.GetOpaqueQualType(),
-                                                                             ConstString(name),
-                                                                             buffer,
-                                                                             lldb::endian::InlHostByteOrder(),
-                                                                             exe_ctx.GetAddressByteSize()));
-    if (ptr_result_valobj_sp)
+    if (type)
     {
-        ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
-        Error err;
-        ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
-        if (ptr_result_valobj_sp && name && *name)
-            ptr_result_valobj_sp->SetName(ConstString(name));
+        ClangASTType pointer_type(type.GetPointerType());
+        if (pointer_type)
+        {
+            lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
+            lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
+                                                                                     pointer_type,
+                                                                                     ConstString(name),
+                                                                                     buffer,
+                                                                                     lldb::endian::InlHostByteOrder(),
+                                                                                     exe_ctx.GetAddressByteSize()));
+            if (ptr_result_valobj_sp)
+            {
+                ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
+                Error err;
+                ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
+                if (ptr_result_valobj_sp && name && *name)
+                    ptr_result_valobj_sp->SetName(ConstString(name));
+            }
+            return ptr_result_valobj_sp;
+        }
     }
-    return ptr_result_valobj_sp;
+    return lldb::ValueObjectSP();
 }
 
 lldb::ValueObjectSP
@@ -4290,8 +4124,7 @@
 {
     lldb::ValueObjectSP new_value_sp;
     new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
-                                                   type.GetASTContext() ,
-                                                   type.GetOpaqueQualType(),
+                                                   type,
                                                    ConstString(name),
                                                    data,
                                                    LLDB_INVALID_ADDRESS);
diff --git a/source/Core/ValueObjectCast.cpp b/source/Core/ValueObjectCast.cpp
index e1c94cc..4f4f8cc 100644
--- a/source/Core/ValueObjectCast.cpp
+++ b/source/Core/ValueObjectCast.cpp
@@ -54,35 +54,30 @@
     m_cast_type (cast_type)
 {
     SetName (name);
-    m_value.SetContext (Value::eContextTypeClangType, cast_type.GetOpaqueQualType());
+    //m_value.SetContext (Value::eContextTypeClangType, cast_type.GetOpaqueQualType());
+    m_value.SetClangType (cast_type);
 }
 
 ValueObjectCast::~ValueObjectCast()
 {
 }
 
-lldb::clang_type_t
+ClangASTType
 ValueObjectCast::GetClangTypeImpl ()
 {
-    return m_cast_type.GetOpaqueQualType();
+    return m_cast_type;
 }
 
 size_t
 ValueObjectCast::CalculateNumChildren()
 {
-    return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
-}
-
-clang::ASTContext *
-ValueObjectCast::GetClangASTImpl ()
-{
-    return m_cast_type.GetASTContext();
+    return GetClangType().GetNumChildren (true);
 }
 
 uint64_t
 ValueObjectCast::GetByteSize()
 {
-    return m_value.GetValueByteSize(GetClangAST(), NULL);
+    return m_value.GetValueByteSize(NULL);
 }
 
 lldb::ValueType
@@ -103,9 +98,11 @@
         Value old_value(m_value);
         m_update_point.SetUpdated();
         m_value = m_parent->GetValue();
-        m_value.SetContext (Value::eContextTypeClangType, GetClangType());
+        ClangASTType clang_type (GetClangType());
+        //m_value.SetContext (Value::eContextTypeClangType, clang_type);
+        m_value.SetClangType (clang_type);
         SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren());
-        if (ClangASTContext::IsAggregateType (GetClangType()))
+        if (clang_type.IsAggregateType ())
         {
             // this value object represents an aggregate type whose
             // children have values, but this object does not. So we
@@ -113,7 +110,7 @@
             SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
         } 
         ExecutionContext exe_ctx (GetExecutionContextRef());
-        m_error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
+        m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
         SetValueDidChange (m_parent->GetValueDidChange());
         return true;
     }
diff --git a/source/Core/ValueObjectChild.cpp b/source/Core/ValueObjectChild.cpp
index cf69ea5..23add1c 100644
--- a/source/Core/ValueObjectChild.cpp
+++ b/source/Core/ValueObjectChild.cpp
@@ -27,8 +27,7 @@
 ValueObjectChild::ValueObjectChild
 (
     ValueObject &parent,
-    clang::ASTContext *clang_ast,
-    void *clang_type,
+    const ClangASTType &clang_type,
     const ConstString &name,
     uint64_t byte_size,
     int32_t byte_offset,
@@ -39,7 +38,6 @@
     AddressType child_ptr_or_ref_addr_type
 ) :
     ValueObject (parent),
-    m_clang_ast (clang_ast),
     m_clang_type (clang_type),
     m_byte_size (byte_size),
     m_byte_offset (byte_offset),
@@ -65,7 +63,7 @@
 size_t
 ValueObjectChild::CalculateNumChildren()
 {
-    return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
+    return GetClangType().GetNumChildren (true);
 }
 
 ConstString
@@ -73,7 +71,7 @@
 {
     if (m_type_name.IsEmpty())
     {
-        m_type_name = ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
+        m_type_name = GetClangType().GetConstTypeName ();
         if (m_type_name)
         {
             if (m_bitfield_bit_size > 0)
@@ -94,7 +92,7 @@
 ConstString
 ValueObjectChild::GetQualifiedTypeName()
 {
-    ConstString qualified_name = ClangASTType::GetConstQualifiedTypeName (GetClangAST(), GetClangType());
+    ConstString qualified_name = GetClangType().GetConstTypeName();
     if (qualified_name)
     {
         if (m_bitfield_bit_size > 0)
@@ -121,14 +119,14 @@
     {
         if (parent->UpdateValueIfNeeded(false))
         {
-            m_value.SetContext(Value::eContextTypeClangType, GetClangType());
+            m_value.SetClangType(GetClangType());
 
             // Copy the parent scalar value and the scalar value type
             m_value.GetScalar() = parent->GetValue().GetScalar();
             Value::ValueType value_type = parent->GetValue().GetValueType();
             m_value.SetValueType (value_type);
 
-            if (ClangASTContext::IsPointerOrReferenceType (parent->GetClangType()))
+            if (parent->GetClangType().IsPointerOrReferenceType ())
             {
                 lldb::addr_t addr = parent->GetPointerValue ();
                 m_value.GetScalar() = addr;
@@ -209,7 +207,7 @@
             if (m_error.Success())
             {
                 ExecutionContext exe_ctx (GetExecutionContextRef().Lock());
-                m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0, GetModule().get());
+                m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
             }
         }
         else
diff --git a/source/Core/ValueObjectConstResult.cpp b/source/Core/ValueObjectConstResult.cpp
index b78e4ec..d6d8638 100644
--- a/source/Core/ValueObjectConstResult.cpp
+++ b/source/Core/ValueObjectConstResult.cpp
@@ -30,13 +30,10 @@
 using namespace lldb_private;
 
 ValueObjectSP
-ValueObjectConstResult::Create
-(
-    ExecutionContextScope *exe_scope,
-    ByteOrder byte_order, 
-     uint32_t addr_byte_size,
-     lldb::addr_t address
-)
+ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
+                                ByteOrder byte_order,
+                                uint32_t addr_byte_size,
+                                lldb::addr_t address)
 {
     return (new ValueObjectConstResult (exe_scope,
                                         byte_order,
@@ -44,15 +41,11 @@
                                         address))->GetSP();
 }
 
-ValueObjectConstResult::ValueObjectConstResult
-(
-    ExecutionContextScope *exe_scope,
-    ByteOrder byte_order, 
-    uint32_t addr_byte_size,
-    lldb::addr_t address
-) :
+ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
+                                                ByteOrder byte_order,
+                                                uint32_t addr_byte_size,
+                                                lldb::addr_t address) :
     ValueObject (exe_scope),
-    m_clang_ast (NULL),
     m_type_name (),
     m_byte_size (0),
     m_impl(this, address)
@@ -68,32 +61,25 @@
 ValueObjectConstResult::Create
 (
     ExecutionContextScope *exe_scope,
-    clang::ASTContext *clang_ast,
-    void *clang_type,
+    const ClangASTType &clang_type,
     const ConstString &name,
     const DataExtractor &data,
     lldb::addr_t address
 )
 {
     return (new ValueObjectConstResult (exe_scope,
-                                        clang_ast,
                                         clang_type,
                                         name,
                                         data,
                                         address))->GetSP();
 }
 
-ValueObjectConstResult::ValueObjectConstResult
-(
-    ExecutionContextScope *exe_scope,
-    clang::ASTContext *clang_ast,
-    void *clang_type,
-    const ConstString &name,
-    const DataExtractor &data,
-    lldb::addr_t address
-) :
+ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
+                                                const ClangASTType &clang_type,
+                                                const ConstString &name,
+                                                const DataExtractor &data,
+                                                lldb::addr_t address) :
     ValueObject (exe_scope),
-    m_clang_ast (clang_ast),
     m_type_name (),
     m_byte_size (0),
     m_impl(this, address)
@@ -108,7 +94,7 @@
     
     m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
     m_value.SetValueType(Value::eValueTypeHostAddress);
-    m_value.SetContext(Value::eContextTypeClangType, clang_type);
+    m_value.SetClangType(clang_type);
     m_name = name;
     SetIsConstant ();
     SetValueIsValid(true);
@@ -116,20 +102,15 @@
 }
 
 ValueObjectSP
-ValueObjectConstResult::Create
-(
-    ExecutionContextScope *exe_scope,
-    clang::ASTContext *clang_ast,
-    void *clang_type,
-    const ConstString &name,
-    const lldb::DataBufferSP &data_sp,
-    lldb::ByteOrder data_byte_order, 
-    uint32_t data_addr_size,
-    lldb::addr_t address
-)
+ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
+                                const ClangASTType &clang_type,
+                                const ConstString &name,
+                                const lldb::DataBufferSP &data_sp,
+                                lldb::ByteOrder data_byte_order,
+                                uint32_t data_addr_size,
+                                lldb::addr_t address)
 {
     return (new ValueObjectConstResult (exe_scope,
-                                        clang_ast,
                                         clang_type,
                                         name,
                                         data_sp,
@@ -140,26 +121,20 @@
 
 ValueObjectSP
 ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
-        clang::ASTContext *clang_ast,
-        Value &value,
-        const ConstString &name)
+                                Value &value,
+                                const ConstString &name)
 {
-    return (new ValueObjectConstResult (exe_scope, clang_ast, value, name))->GetSP();
+    return (new ValueObjectConstResult (exe_scope, value, name))->GetSP();
 }
 
-ValueObjectConstResult::ValueObjectConstResult
-(
-    ExecutionContextScope *exe_scope,
-    clang::ASTContext *clang_ast,
-    void *clang_type,
-    const ConstString &name,
-    const lldb::DataBufferSP &data_sp,
-    lldb::ByteOrder data_byte_order, 
-    uint32_t data_addr_size,
-    lldb::addr_t address
-) :
+ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
+                                                const ClangASTType &clang_type,
+                                                const ConstString &name,
+                                                const lldb::DataBufferSP &data_sp,
+                                                lldb::ByteOrder data_byte_order, 
+                                                uint32_t data_addr_size,
+                                                lldb::addr_t address) :
     ValueObject (exe_scope),
-    m_clang_ast (clang_ast),
     m_type_name (),
     m_byte_size (0),
     m_impl(this, address)
@@ -169,7 +144,8 @@
     m_data.SetData(data_sp);
     m_value.GetScalar() = (uintptr_t)data_sp->GetBytes();
     m_value.SetValueType(Value::eValueTypeHostAddress);
-    m_value.SetContext(Value::eContextTypeClangType, clang_type);
+    //m_value.SetContext(Value::eContextTypeClangType, clang_type);
+    m_value.SetClangType (clang_type);
     m_name = name;
     SetIsConstant ();
     SetValueIsValid(true);
@@ -177,19 +153,14 @@
 }
 
 ValueObjectSP
-ValueObjectConstResult::Create
-(
-    ExecutionContextScope *exe_scope,
-    clang::ASTContext *clang_ast,
-    void *clang_type,
-    const ConstString &name,
-    lldb::addr_t address,
-    AddressType address_type,
-    uint32_t addr_byte_size
-)
+ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
+                                const ClangASTType &clang_type,
+                                const ConstString &name,
+                                lldb::addr_t address,
+                                AddressType address_type,
+                                uint32_t addr_byte_size)
 {
     return (new ValueObjectConstResult (exe_scope,
-                                        clang_ast,
                                         clang_type,
                                         name,
                                         address,
@@ -197,18 +168,13 @@
                                         addr_byte_size))->GetSP();
 }
 
-ValueObjectConstResult::ValueObjectConstResult 
-(
-    ExecutionContextScope *exe_scope,
-    clang::ASTContext *clang_ast,
-    void *clang_type,
-    const ConstString &name,
-    lldb::addr_t address,
-    AddressType address_type,
-    uint32_t addr_byte_size
-) :
+ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
+                                                const ClangASTType &clang_type,
+                                                const ConstString &name,
+                                                lldb::addr_t address,
+                                                AddressType address_type,
+                                                uint32_t addr_byte_size) :
     ValueObject (exe_scope),
-    m_clang_ast (clang_ast),
     m_type_name (),
     m_byte_size (0),
     m_impl(this, address)
@@ -224,7 +190,8 @@
     case eAddressTypeLoad:      m_value.SetValueType(Value::eValueTypeLoadAddress); break;    
     case eAddressTypeHost:      m_value.SetValueType(Value::eValueTypeHostAddress); break;
     }
-    m_value.SetContext(Value::eContextTypeClangType, clang_type);
+//    m_value.SetContext(Value::eContextTypeClangType, clang_type);
+    m_value.SetClangType (clang_type);
     m_name = name;
     SetIsConstant ();
     SetValueIsValid(true);
@@ -242,11 +209,9 @@
                                         error))->GetSP();
 }
 
-ValueObjectConstResult::ValueObjectConstResult (
-    ExecutionContextScope *exe_scope,
-    const Error& error) :
+ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
+                                                const Error& error) :
     ValueObject (exe_scope),
-    m_clang_ast (NULL),
     m_type_name (),
     m_byte_size (0),
     m_impl(this)
@@ -255,13 +220,10 @@
     SetIsConstant ();
 }
 
-ValueObjectConstResult::ValueObjectConstResult (
-    ExecutionContextScope *exe_scope,
-    clang::ASTContext *clang_ast,
-    const Value &value,
-    const ConstString &name) :
+ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
+                                                const Value &value,
+                                                const ConstString &name) :
     ValueObject (exe_scope),
-    m_clang_ast (clang_ast),
     m_type_name (),
     m_byte_size (0),
     m_impl(this)
@@ -274,7 +236,7 @@
 {
 }
 
-lldb::clang_type_t
+ClangASTType
 ValueObjectConstResult::GetClangTypeImpl()
 {
     return m_value.GetClangType();
@@ -290,7 +252,7 @@
 ValueObjectConstResult::GetByteSize()
 {
     if (m_byte_size == 0)
-        m_byte_size = ClangASTType::GetTypeByteSize(GetClangAST(), GetClangType());
+        m_byte_size = GetClangType().GetByteSize();
     return m_byte_size;
 }
 
@@ -303,20 +265,14 @@
 size_t
 ValueObjectConstResult::CalculateNumChildren()
 {
-    return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
-}
-
-clang::ASTContext *
-ValueObjectConstResult::GetClangASTImpl ()
-{
-    return m_clang_ast;
+    return GetClangType().GetNumChildren (true);
 }
 
 ConstString
 ValueObjectConstResult::GetTypeName()
 {
     if (m_type_name.IsEmpty())
-        m_type_name = ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
+        m_type_name = GetClangType().GetConstTypeName ();
     return m_type_name;
 }
 
diff --git a/source/Core/ValueObjectConstResultChild.cpp b/source/Core/ValueObjectConstResultChild.cpp
index 4f40381..64425ea 100644
--- a/source/Core/ValueObjectConstResultChild.cpp
+++ b/source/Core/ValueObjectConstResultChild.cpp
@@ -19,8 +19,7 @@
 ValueObjectConstResultChild::ValueObjectConstResultChild
 (
     ValueObject &parent,
-    clang::ASTContext *clang_ast,
-    void *clang_type,
+    const ClangASTType &clang_type,
     const ConstString &name,
     uint32_t byte_size,
     int32_t byte_offset,
@@ -30,7 +29,6 @@
     bool is_deref_of_parent
 ) :
     ValueObjectChild (parent,
-                      clang_ast,
                       clang_type,
                       name,
                       byte_size,
diff --git a/source/Core/ValueObjectConstResultImpl.cpp b/source/Core/ValueObjectConstResultImpl.cpp
index 3d86b91..e0757f6 100644
--- a/source/Core/ValueObjectConstResultImpl.cpp
+++ b/source/Core/ValueObjectConstResultImpl.cpp
@@ -55,7 +55,6 @@
         lldb::addr_t tgt_address = m_impl_backend->GetPointerValue();
         ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
         m_load_addr_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
-                                                              m_impl_backend->GetClangAST(),
                                                               m_impl_backend->GetClangType(),
                                                               m_impl_backend->GetName(),
                                                               tgt_address,
@@ -104,27 +103,24 @@
     bool child_is_deref_of_parent = false;
     
     const bool transparent_pointers = synthetic_array_member == false;
-    clang::ASTContext *clang_ast = m_impl_backend->GetClangAST();
-    lldb::clang_type_t clang_type = m_impl_backend->GetClangType();
-    lldb::clang_type_t child_clang_type;
+    ClangASTType clang_type = m_impl_backend->GetClangType();
+    ClangASTType child_clang_type;
     
     ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
     
-    child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx,
-                                                                  clang_ast,
-                                                                  m_impl_backend->GetName().GetCString(),
-                                                                  clang_type,
-                                                                  idx,
-                                                                  transparent_pointers,
-                                                                  omit_empty_base_classes,
-                                                                  ignore_array_bounds,
-                                                                  child_name_str,
-                                                                  child_byte_size,
-                                                                  child_byte_offset,
-                                                                  child_bitfield_bit_size,
-                                                                  child_bitfield_bit_offset,
-                                                                  child_is_base_class,
-                                                                  child_is_deref_of_parent);
+    child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx,
+                                                            m_impl_backend->GetName().GetCString(),
+                                                            idx,
+                                                            transparent_pointers,
+                                                            omit_empty_base_classes,
+                                                            ignore_array_bounds,
+                                                            child_name_str,
+                                                            child_byte_size,
+                                                            child_byte_offset,
+                                                            child_bitfield_bit_size,
+                                                            child_bitfield_bit_offset,
+                                                            child_is_base_class,
+                                                            child_is_deref_of_parent);
     if (child_clang_type && child_byte_size)
     {
         if (synthetic_index)
@@ -135,7 +131,6 @@
             child_name.SetCString (child_name_str.c_str());
         
         valobj = new ValueObjectConstResultChild (*m_impl_backend,
-                                                  clang_ast,
                                                   child_clang_type,
                                                   child_name,
                                                   child_byte_size,
@@ -178,7 +173,7 @@
         return lldb::ValueObjectSP();
     if (m_live_address != LLDB_INVALID_ADDRESS)
     {
-        ClangASTType type(m_impl_backend->GetClangAST(), m_impl_backend->GetClangType());
+        ClangASTType clang_type(m_impl_backend->GetClangType());
         
         lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t)));
         
@@ -186,8 +181,7 @@
         new_name.append(m_impl_backend->GetName().AsCString(""));
         ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
         m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
-                                                               type.GetASTContext(),
-                                                               type.GetPointerType(),
+                                                               clang_type.GetPointerType(),
                                                                ConstString(new_name.c_str()),
                                                                buffer,
                                                                lldb::endian::InlHostByteOrder(), 
diff --git a/source/Core/ValueObjectDynamicValue.cpp b/source/Core/ValueObjectDynamicValue.cpp
index 95108f3..977cc4c 100644
--- a/source/Core/ValueObjectDynamicValue.cpp
+++ b/source/Core/ValueObjectDynamicValue.cpp
@@ -49,7 +49,7 @@
     m_owning_valobj_sp.reset();
 }
 
-lldb::clang_type_t
+ClangASTType
 ValueObjectDynamicValue::GetClangTypeImpl ()
 {
     if (m_dynamic_type_info.HasTypeSP())
@@ -65,7 +65,7 @@
     if (success)
     {
         if (m_dynamic_type_info.HasTypeSP())
-            return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
+            return GetClangType().GetConstTypeName();
         if (m_dynamic_type_info.HasName())
             return m_dynamic_type_info.GetName();
     }
@@ -79,7 +79,7 @@
     if (success)
     {
         if (m_dynamic_type_info.HasTypeSP())
-            return ClangASTType::GetConstQualifiedTypeName (GetClangAST(), GetClangType());
+            return GetClangType().GetConstQualifiedTypeName ();
         if (m_dynamic_type_info.HasName())
             return m_dynamic_type_info.GetName();
     }
@@ -91,27 +91,17 @@
 {
     const bool success = UpdateValueIfNeeded(false);
     if (success && m_dynamic_type_info.HasTypeSP())
-        return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
+        return GetClangType().GetNumChildren (true);
     else
         return m_parent->GetNumChildren();
 }
 
-clang::ASTContext *
-ValueObjectDynamicValue::GetClangASTImpl ()
-{
-    const bool success = UpdateValueIfNeeded(false);
-    if (success && m_dynamic_type_info.HasTypeSP())
-        return m_dynamic_type_info.GetTypeSP()->GetClangAST();
-    else
-        return m_parent->GetClangAST ();
-}
-
 uint64_t
 ValueObjectDynamicValue::GetByteSize()
 {
     const bool success = UpdateValueIfNeeded(false);
     if (success && m_dynamic_type_info.HasTypeSP())
-        return m_value.GetValueByteSize(GetClangAST(), NULL);
+        return m_value.GetValueByteSize(NULL);
     else
         return m_parent->GetByteSize();
 }
@@ -196,7 +186,7 @@
         ClearDynamicTypeInformation();
         m_dynamic_type_info.Clear();
         m_value = m_parent->GetValue();
-        m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
+        m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
         return m_error.Success();
     }
     
@@ -234,21 +224,18 @@
         m_value.GetScalar() = load_address;
     }
     
-    lldb::clang_type_t corrected_type;
+    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...
-        lldb::clang_type_t orig_type;
-        clang::ASTContext* ast;
-        orig_type = m_dynamic_type_info.GetTypeSP()->GetClangForwardType();
-        ast = m_dynamic_type_info.GetTypeSP()->GetClangAST();
+        ClangASTType orig_type = m_dynamic_type_info.GetTypeSP()->GetClangForwardType();
         corrected_type = orig_type;
         if (m_parent->IsPointerType())
-            corrected_type = ClangASTContext::CreatePointerType (ast, orig_type);
+            corrected_type = orig_type.GetPointerType ();
         else if (m_parent->IsPointerOrReferenceType())
-            corrected_type = ClangASTContext::CreateLValueReferenceType (ast, orig_type);
+            corrected_type = orig_type.GetLValueReferenceType ();
     }
     else /*if (m_dynamic_type_info.HasName())*/
     {
@@ -262,7 +249,8 @@
         m_dynamic_type_info.SetName(type_name_buf.c_str());
     }
     
-    m_value.SetContext (Value::eContextTypeClangType, corrected_type);
+    //m_value.SetContext (Value::eContextTypeClangType, corrected_type);
+    m_value.SetClangType (corrected_type);
     
     // 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...
@@ -278,10 +266,10 @@
     {
         // The variable value is in the Scalar value inside the m_value.
         // We can point our m_data right to it.
-        m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
+        m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
         if (m_error.Success())
         {
-            if (ClangASTContext::IsAggregateType (GetClangType()))
+            if (GetClangType().IsAggregateType ())
             {
                 // this value object represents an aggregate type whose
                 // children have values, but this object does not. So we
diff --git a/source/Core/ValueObjectMemory.cpp b/source/Core/ValueObjectMemory.cpp
index 2bdf44f..42fd0e8 100644
--- a/source/Core/ValueObjectMemory.cpp
+++ b/source/Core/ValueObjectMemory.cpp
@@ -103,7 +103,8 @@
     TargetSP target_sp (GetTargetSP());
 
     SetName (ConstString(name));
-    m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType());
+//    m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType());
+    m_value.SetClangType(m_clang_type);
     lldb::addr_t load_address = m_address.GetLoadAddress (target_sp.get());
     if (load_address != LLDB_INVALID_ADDRESS)
     {
@@ -130,12 +131,12 @@
 {
 }
 
-lldb::clang_type_t
+ClangASTType
 ValueObjectMemory::GetClangTypeImpl ()
 {
     if (m_type_sp)
         return m_type_sp->GetClangForwardType();
-    return m_clang_type.GetOpaqueQualType();
+    return m_clang_type;
 }
 
 ConstString
@@ -143,7 +144,7 @@
 {
     if (m_type_sp)
         return m_type_sp->GetName();
-    return ClangASTType::GetConstTypeName (GetClangAST(), m_clang_type.GetOpaqueQualType());
+    return m_clang_type.GetConstTypeName();
 }
 
 size_t
@@ -152,17 +153,7 @@
     if (m_type_sp)
         return m_type_sp->GetNumChildren(true);
     const bool omit_empty_base_classes = true;
-    return ClangASTContext::GetNumChildren (m_clang_type.GetASTContext(),
-                                            m_clang_type.GetOpaqueQualType(), 
-                                            omit_empty_base_classes);
-}
-
-clang::ASTContext *
-ValueObjectMemory::GetClangASTImpl ()
-{
-    if (m_type_sp)
-        return m_type_sp->GetClangAST();
-    return m_clang_type.GetASTContext();
+    return m_clang_type.GetNumChildren (omit_empty_base_classes);
 }
 
 uint64_t
@@ -170,7 +161,7 @@
 {
     if (m_type_sp)
         return m_type_sp->GetByteSize();
-    return m_clang_type.GetClangTypeByteSize ();
+    return m_clang_type.GetByteSize ();
 }
 
 lldb::ValueType
@@ -209,7 +200,7 @@
         case Value::eValueTypeScalar:
             // The variable value is in the Scalar value inside the m_value.
             // We can point our m_data right to it.
-            m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
+            m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
             break;
 
         case Value::eValueTypeFileAddress:
@@ -234,7 +225,7 @@
                 }
             }
 
-            if (ClangASTContext::IsAggregateType (GetClangType()))
+            if (GetClangType().IsAggregateType())
             {
                 // this value object represents an aggregate type whose
                 // children have values, but this object does not. So we
@@ -249,9 +240,12 @@
                 if (m_type_sp)
                     value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
                 else
-                    value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType());
+                {
+                    //value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType());
+                    value.SetClangType(m_clang_type);
+                }
 
-                m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
+                m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
             }
             break;
         }
diff --git a/source/Core/ValueObjectRegister.cpp b/source/Core/ValueObjectRegister.cpp
index 8b02713..4f21457 100644
--- a/source/Core/ValueObjectRegister.cpp
+++ b/source/Core/ValueObjectRegister.cpp
@@ -42,10 +42,10 @@
 {
 }
 
-lldb::clang_type_t
+ClangASTType
 ValueObjectRegisterContext::GetClangTypeImpl ()
 {
-    return NULL;
+    return ClangASTType();
 }
 
 ConstString
@@ -66,12 +66,6 @@
     return m_reg_ctx_sp->GetRegisterSetCount();
 }
 
-clang::ASTContext *
-ValueObjectRegisterContext::GetClangASTImpl ()
-{
-    return NULL;
-}
-
 uint64_t
 ValueObjectRegisterContext::GetByteSize()
 {
@@ -144,10 +138,10 @@
 {
 }
 
-lldb::clang_type_t
+ClangASTType
 ValueObjectRegisterSet::GetClangTypeImpl ()
 {
-    return NULL;
+    return ClangASTType();
 }
 
 ConstString
@@ -171,12 +165,6 @@
     return 0;
 }
 
-clang::ASTContext *
-ValueObjectRegisterSet::GetClangASTImpl ()
-{
-    return NULL;
-}
-
 uint64_t
 ValueObjectRegisterSet::GetByteSize()
 {
@@ -285,7 +273,7 @@
     m_reg_info (),
     m_reg_value (),
     m_type_name (),
-    m_clang_type (NULL)
+    m_clang_type ()
 {
     assert (reg_ctx_sp.get());
     ConstructObject(reg_num);
@@ -303,7 +291,7 @@
     m_reg_info (),
     m_reg_value (),
     m_type_name (),
-    m_clang_type (NULL)
+    m_clang_type ()
 {
     assert (reg_ctx);
     ConstructObject(reg_num);
@@ -313,10 +301,10 @@
 {
 }
 
-lldb::clang_type_t
+ClangASTType
 ValueObjectRegister::GetClangTypeImpl ()
 {
-    if (m_clang_type == NULL)
+    if (!m_clang_type.IsValid())
     {
         ExecutionContext exe_ctx (GetExecutionContextRef());
         Target *target = exe_ctx.GetTargetPtr();
@@ -337,28 +325,14 @@
 ValueObjectRegister::GetTypeName()
 {
     if (m_type_name.IsEmpty())
-        m_type_name = ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
+        m_type_name = GetClangType().GetConstTypeName ();
     return m_type_name;
 }
 
 size_t
 ValueObjectRegister::CalculateNumChildren()
 {
-    return ClangASTContext::GetNumChildren(GetClangAST(), GetClangType(), true);
-}
-
-clang::ASTContext *
-ValueObjectRegister::GetClangASTImpl ()
-{
-    ExecutionContext exe_ctx (GetExecutionContextRef());
-    Target *target = exe_ctx.GetTargetPtr();
-    if (target)
-    {
-        Module *exe_module = target->GetExecutableModulePointer();
-        if (exe_module)
-            return exe_module->GetClangASTContext().getASTContext();
-    }
-    return NULL;
+    return GetClangType().GetNumChildren(true);
 }
 
 uint64_t
diff --git a/source/Core/ValueObjectSyntheticFilter.cpp b/source/Core/ValueObjectSyntheticFilter.cpp
index ab5d1f5..522ca08 100644
--- a/source/Core/ValueObjectSyntheticFilter.cpp
+++ b/source/Core/ValueObjectSyntheticFilter.cpp
@@ -83,7 +83,7 @@
 {
 }
 
-lldb::clang_type_t
+ClangASTType
 ValueObjectSynthetic::GetClangTypeImpl ()
 {
     return m_parent->GetClangType();
@@ -128,13 +128,6 @@
     return (m_might_have_children == eLazyBoolNo ? false : true);
 }
 
-
-clang::ASTContext *
-ValueObjectSynthetic::GetClangASTImpl ()
-{
-    return m_parent->GetClangAST ();
-}
-
 uint64_t
 ValueObjectSynthetic::GetByteSize()
 {
@@ -273,5 +266,5 @@
 {
     m_value = m_parent->GetValue();
     ExecutionContext exe_ctx (GetExecutionContextRef());
-    m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
+    m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
 }
diff --git a/source/Core/ValueObjectVariable.cpp b/source/Core/ValueObjectVariable.cpp
index 09e2f1f..38c0d91 100644
--- a/source/Core/ValueObjectVariable.cpp
+++ b/source/Core/ValueObjectVariable.cpp
@@ -54,13 +54,13 @@
 {
 }
 
-lldb::clang_type_t
+ClangASTType
 ValueObjectVariable::GetClangTypeImpl ()
 {
     Type *var_type = m_variable_sp->GetType();
     if (var_type)
         return var_type->GetClangForwardType();
-    return NULL;
+    return ClangASTType();
 }
 
 ConstString
@@ -84,34 +84,24 @@
 size_t
 ValueObjectVariable::CalculateNumChildren()
 {    
-    ClangASTType type(GetClangAST(),
-                      GetClangType());
+    ClangASTType type(GetClangType());
     
     if (!type.IsValid())
         return 0;
     
     const bool omit_empty_base_classes = true;
-    return ClangASTContext::GetNumChildren(type.GetASTContext(), type.GetOpaqueQualType(), omit_empty_base_classes);
-}
-
-clang::ASTContext *
-ValueObjectVariable::GetClangASTImpl ()
-{
-    Type *var_type = m_variable_sp->GetType();
-    if (var_type)
-        return var_type->GetClangAST();
-    return 0;
+    return type.GetNumChildren(omit_empty_base_classes);
 }
 
 uint64_t
 ValueObjectVariable::GetByteSize()
 {
-    ClangASTType type(GetClangAST(), GetClangType());
+    ClangASTType type(GetClangType());
     
     if (!type.IsValid())
         return 0;
     
-    return type.GetClangTypeByteSize();
+    return type.GetByteSize();
 }
 
 lldb::ValueType
@@ -162,7 +152,7 @@
                 loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
         }
         Value old_value(m_value);
-        if (expr.Evaluate (&exe_ctx, GetClangAST(), NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error))
+        if (expr.Evaluate (&exe_ctx, NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error))
         {
             m_resolved_value = m_value;
             m_value.SetContext(Value::eContextTypeVariable, variable);
@@ -191,7 +181,7 @@
             case Value::eValueTypeScalar:
                 // The variable value is in the Scalar value inside the m_value.
                 // We can point our m_data right to it.
-                m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
+                m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
                 break;
 
             case Value::eValueTypeFileAddress:
@@ -231,7 +221,7 @@
                     }
                 }
 
-                if (ClangASTContext::IsAggregateType (GetClangType()))
+                if (GetClangType().IsAggregateType())
                 {
                     // this value object represents an aggregate type whose
                     // children have values, but this object does not. So we
@@ -244,7 +234,7 @@
                     // so it can extract read its value into m_data appropriately
                     Value value(m_value);
                     value.SetContext(Value::eContextTypeVariable, variable);
-                    m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
+                    m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
                 }
                 break;
             }
diff --git a/source/DataFormatters/CXXFormatterFunctions.cpp b/source/DataFormatters/CXXFormatterFunctions.cpp
index 3432700..fba9217 100644
--- a/source/DataFormatters/CXXFormatterFunctions.cpp
+++ b/source/DataFormatters/CXXFormatterFunctions.cpp
@@ -518,12 +518,13 @@
     if (data_addr == 0 || data_addr == LLDB_INVALID_ADDRESS)
         return false;
 
-    clang::ASTContext* ast = valobj.GetClangAST();
-
+    clang::ASTContext* ast = valobj.GetClangType().GetASTContext();
+    
     if (!ast)
         return false;
 
-    uint32_t wchar_size = ClangASTType::GetClangTypeBitWidth(ast, ClangASTType::GetBasicType(ast, lldb::eBasicTypeWChar).GetOpaqueQualType());
+    ClangASTType wchar_clang_type = ClangASTContext::GetBasicType(ast, lldb::eBasicTypeWChar);
+    const uint32_t wchar_size = wchar_clang_type.GetBitSize();
 
     switch (wchar_size)
     {
@@ -605,15 +606,15 @@
     DataExtractor data;
     valobj.GetData(data);
     
-    clang::ASTContext* ast = valobj.GetClangAST();
+    clang::ASTContext* ast = valobj.GetClangType().GetASTContext();
     
     if (!ast)
         return false;
     
+    ClangASTType wchar_clang_type = ClangASTContext::GetBasicType(ast, lldb::eBasicTypeWChar);
+    const uint32_t wchar_size = wchar_clang_type.GetBitSize();
     std::string value;
     
-    uint32_t wchar_size = ClangASTType::GetClangTypeBitWidth(ast, ClangASTType::GetBasicType(ast, lldb::eBasicTypeWChar).GetOpaqueQualType());
-    
     switch (wchar_size)
     {
         case 8:
@@ -1133,13 +1134,13 @@
     if (!target_sp)
         return false;
     uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize();
-    uint64_t pointee = valobj.GetValueAsUnsigned(0);
-    if (!pointee)
+    uint64_t pointer_value = valobj.GetValueAsUnsigned(0);
+    if (!pointer_value)
         return false;
-    pointee += addr_size;
-    ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
+    pointer_value += addr_size;
+    ClangASTType type(valobj.GetClangType());
     ExecutionContext exe_ctx(target_sp,false);
-    ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress("string_ptr", pointee, exe_ctx, type));
+    ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress("string_ptr", pointer_value, exe_ctx, type));
     if (!child_ptr_sp)
         return false;
     DataExtractor data;
@@ -1167,20 +1168,18 @@
 bool
 lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream)
 {
-    const uint32_t type_info = ClangASTContext::GetTypeInfo(valobj.GetClangType(),
-                                                            valobj.GetClangAST(),
-                                                            NULL);
+    const uint32_t type_info = valobj.GetClangType().GetTypeInfo();
     
     ValueObjectSP real_guy_sp = valobj.GetSP();
     
-    if (type_info & ClangASTContext::eTypeIsPointer)
+    if (type_info & ClangASTType::eTypeIsPointer)
     {
         Error err;
         real_guy_sp = valobj.Dereference(err);
         if (err.Fail() || !real_guy_sp)
             return false;
     }
-    else if (type_info & ClangASTContext::eTypeIsReference)
+    else if (type_info & ClangASTType::eTypeIsReference)
     {
         real_guy_sp =  valobj.GetChildAtIndex(0, true);
         if (!real_guy_sp)
@@ -1202,12 +1201,10 @@
 {
     lldb::ValueObjectSP valobj_sp;
 
-    if (!valobj.GetClangAST())
+    ClangASTType charstar (valobj.GetClangType().GetBasicTypeFromAST(eBasicTypeChar).GetPointerType());
+    
+    if (!charstar)
         return false;
-    void* char_opaque_type = valobj.GetClangAST()->CharTy.getAsOpaquePtr();
-    if (!char_opaque_type)
-        return false;
-    ClangASTType charstar(valobj.GetClangAST(),ClangASTType::GetPointerType(valobj.GetClangAST(), char_opaque_type));
 
     ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
     
@@ -1303,7 +1300,7 @@
         return false;
     Error err;
     m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
-    m_item_sp = ValueObject::CreateValueObjectFromAddress("item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref, ClangASTType(item_ptr->GetClangAST(),ClangASTType::GetPointeeType(item_ptr->GetClangType())));
+    m_item_sp = ValueObject::CreateValueObjectFromAddress("item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref, item_ptr->GetClangType().GetPointeeType());
     if (err.Fail())
         m_item_sp.reset();
     return false;
diff --git a/source/DataFormatters/Cocoa.cpp b/source/DataFormatters/Cocoa.cpp
index 2a1e909..555954d 100644
--- a/source/DataFormatters/Cocoa.cpp
+++ b/source/DataFormatters/Cocoa.cpp
@@ -57,8 +57,7 @@
     if (!strcmp(class_name,"NSBundle"))
     {
         uint64_t offset = 5 * ptr_size;
-        ClangASTType type(valobj.GetClangAST(),ClangASTContext::GetBuiltInType_objc_id(valobj.GetClangAST()));
-        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
+        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetClangType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID), true));
 
         StreamString summary_stream;
         bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
@@ -105,8 +104,7 @@
     if (!strcmp(class_name,"__NSTimeZone"))
     {
         uint64_t offset = ptr_size;
-        ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
-        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
+        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetClangType(), true));
         StreamString summary_stream;
         bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
         if (was_nsstring_ok && summary_stream.GetSize() > 0)
@@ -150,8 +148,7 @@
     if (!strcmp(class_name,"NSConcreteNotification"))
     {
         uint64_t offset = ptr_size;
-        ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
-        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
+        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetClangType(), true));
         StreamString summary_stream;
         bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
         if (was_nsstring_ok && summary_stream.GetSize() > 0)
@@ -450,7 +447,7 @@
     {
         uint64_t offset_text = ptr_size + ptr_size + 8; // ISA + pointer + 8 bytes of data (even on 32bit)
         uint64_t offset_base = offset_text + ptr_size;
-        ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
+        ClangASTType type(valobj.GetClangType());
         ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset_text, type, true));
         ValueObjectSP base(valobj.GetSyntheticChildAtOffset(offset_base, type, true));
         if (!text)
diff --git a/source/DataFormatters/LibCxx.cpp b/source/DataFormatters/LibCxx.cpp
index f7c2589..cdc57f6 100644
--- a/source/DataFormatters/LibCxx.cpp
+++ b/source/DataFormatters/LibCxx.cpp
@@ -330,7 +330,7 @@
                 return lldb::ValueObjectSP();
             uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0);
             DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
-            m_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), ClangASTType(shared_owners_sp->GetClangAST(), shared_owners_sp->GetClangType()));
+            m_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), shared_owners_sp->GetClangType());
         }
         return m_count_sp;
     }
@@ -343,7 +343,7 @@
                 return lldb::ValueObjectSP();
             uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0);
             DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
-            m_weak_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), ClangASTType(shared_weak_owners_sp->GetClangAST(), shared_weak_owners_sp->GetClangType()));
+            m_weak_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), shared_weak_owners_sp->GetClangType());
         }
         return m_weak_count_sp;
     }
@@ -464,9 +464,8 @@
     data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true);
     if (!data_type_finder_sp)
         return false;
-    m_element_type = ClangASTType(data_type_finder_sp->GetClangAST(),data_type_finder_sp->GetClangType());
-    m_element_type.SetClangType(m_element_type.GetASTContext(), m_element_type.GetPointeeType());
-    m_element_size = m_element_type.GetTypeByteSize();
+    m_element_type = data_type_finder_sp->GetClangType().GetPointeeType();
+    m_element_size = m_element_type.GetByteSize();
     
     if (m_element_size > 0)
     {
diff --git a/source/DataFormatters/LibCxxList.cpp b/source/DataFormatters/LibCxxList.cpp
index d2669ea..de2ca1b 100644
--- a/source/DataFormatters/LibCxxList.cpp
+++ b/source/DataFormatters/LibCxxList.cpp
@@ -272,16 +272,14 @@
     ValueObjectSP impl_sp(m_backend.GetChildMemberWithName(ConstString("__end_"),true));
     if (!impl_sp)
         return false;
-    auto list_type = m_backend.GetClangType();
-    if (ClangASTContext::IsReferenceType(list_type))
-    {
-        clang::QualType qt = clang::QualType::getFromOpaquePtr(list_type);
-        list_type = qt.getNonReferenceType().getAsOpaquePtr();
-    }
-    if (ClangASTContext::GetNumTemplateArguments(m_backend.GetClangAST(), list_type) == 0)
+    ClangASTType list_type = m_backend.GetClangType();
+    if (list_type.IsReferenceType())
+        list_type = list_type.GetNonReferenceType();
+
+    if (list_type.GetNumTemplateArguments() == 0)
         return false;
     lldb::TemplateArgumentKind kind;
-    m_element_type = ClangASTType(m_backend.GetClangAST(), ClangASTContext::GetTemplateArgument(m_backend.GetClangAST(), list_type, 0, kind));
+    m_element_type = list_type.GetTemplateArgument(0, kind);
     m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
     m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get();
     return false;
diff --git a/source/DataFormatters/LibCxxMap.cpp b/source/DataFormatters/LibCxxMap.cpp
index 0b0b8f7..5daa40f 100644
--- a/source/DataFormatters/LibCxxMap.cpp
+++ b/source/DataFormatters/LibCxxMap.cpp
@@ -281,7 +281,7 @@
     deref = deref->GetChildMemberWithName(ConstString("__value_"), true);
     if (!deref)
         return false;
-    m_element_type.SetClangType(deref->GetClangAST(), deref->GetClangType());
+    m_element_type = deref->GetClangType();
     return true;
 }
 
@@ -292,9 +292,9 @@
         return;
     if (!node)
         return;
-    ClangASTType node_type(node->GetClangAST(),node->GetClangType());
+    ClangASTType node_type(node->GetClangType());
     uint64_t bit_offset;
-    if (ClangASTContext::GetIndexOfFieldWithName(node->GetClangAST(),node->GetClangType(),"__value_",NULL,&bit_offset) == UINT32_MAX)
+    if (node_type.GetIndexOfFieldWithName("__value_", NULL, &bit_offset) == UINT32_MAX)
         return;
     m_skip_size = bit_offset / 8u;
 }
diff --git a/source/DataFormatters/LibStdcpp.cpp b/source/DataFormatters/LibStdcpp.cpp
index a013051..e0f23cc 100644
--- a/source/DataFormatters/LibStdcpp.cpp
+++ b/source/DataFormatters/LibStdcpp.cpp
@@ -206,12 +206,12 @@
  */
 
 lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_exe_ctx_ref(),
-m_pair_address(0),
-m_pair_type(),
-m_options(),
-m_pair_sp()
+    SyntheticChildrenFrontEnd(*valobj_sp.get()),
+    m_exe_ctx_ref(),
+    m_pair_address(0),
+    m_pair_type(),
+    m_options(),
+    m_pair_sp()
 {
     if (valobj_sp)
         Update();
@@ -249,14 +249,14 @@
     
     m_pair_address += (is_64bit ? 32 : 16);
     
-    ClangASTType my_type(valobj_sp->GetClangAST(),valobj_sp->GetClangType());
-    if (ClangASTContext::GetNumTemplateArguments(valobj_sp->GetClangAST(),valobj_sp->GetClangType()) >= 1)
+    ClangASTType my_type(valobj_sp->GetClangType());
+    if (my_type.GetNumTemplateArguments() >= 1)
     {
         TemplateArgumentKind kind;
-        clang_type_t pair_type = ClangASTContext::GetTemplateArgument(valobj_sp->GetClangAST(),valobj_sp->GetClangType(), 0, kind);
+        ClangASTType pair_type = my_type.GetTemplateArgument(0, kind);
         if (kind != eTemplateArgumentKindType && kind != eTemplateArgumentKindTemplate && kind != eTemplateArgumentKindTemplateExpansion)
             return false;
-        m_pair_type = ClangASTType(valobj_sp->GetClangAST(),pair_type);
+        m_pair_type = pair_type;
     }
     else
         return false;
@@ -273,15 +273,13 @@
 lldb::ValueObjectSP
 lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
 {
-    if (m_pair_address == 0)
-        return lldb::ValueObjectSP();
-    if (m_pair_type.GetASTContext() == NULL ||
-        m_pair_type.GetOpaqueQualType() == NULL)
-        return lldb::ValueObjectSP();
-    if (!m_pair_sp)
-        m_pair_sp = ValueObject::CreateValueObjectFromAddress("pair", m_pair_address, m_exe_ctx_ref, m_pair_type);
-    if (m_pair_sp)
-        return m_pair_sp->GetChildAtIndex(idx, true);
+    if (m_pair_address != 0 && m_pair_type)
+    {
+        if (!m_pair_sp)
+            m_pair_sp = ValueObject::CreateValueObjectFromAddress("pair", m_pair_address, m_exe_ctx_ref, m_pair_type);
+        if (m_pair_sp)
+            return m_pair_sp->GetChildAtIndex(idx, true);
+    }
     return lldb::ValueObjectSP();
 }
 
diff --git a/source/DataFormatters/NSArray.cpp b/source/DataFormatters/NSArray.cpp
index cef087d..d8ee9bf 100644
--- a/source/DataFormatters/NSArray.cpp
+++ b/source/DataFormatters/NSArray.cpp
@@ -90,14 +90,18 @@
 }
 
 lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_exe_ctx_ref(),
-m_ptr_size(8),
-m_data_32(NULL),
-m_data_64(NULL)
+    SyntheticChildrenFrontEnd(*valobj_sp.get()),
+    m_exe_ctx_ref(),
+    m_ptr_size(8),
+    m_data_32(NULL),
+    m_data_64(NULL)
 {
     if (valobj_sp)
-        m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
+    {
+        clang::ASTContext *ast = valobj_sp->GetClangType().GetASTContext();
+        if (ast)
+            m_id_type = ClangASTType(ast, ast->ObjCBuiltinIdTy);
+    }
 }
 
 size_t
@@ -195,14 +199,18 @@
 }
 
 lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_exe_ctx_ref(),
-m_ptr_size(8),
-m_items(0),
-m_data_ptr(0)
+    SyntheticChildrenFrontEnd (*valobj_sp.get()),
+    m_exe_ctx_ref (),
+    m_ptr_size (8),
+    m_items (0),
+    m_data_ptr (0)
 {
     if (valobj_sp)
-        m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
+    {
+        clang::ASTContext *ast = valobj_sp->GetClangType().GetASTContext();
+        if (ast)
+            m_id_type = ClangASTType(ast, ast->ObjCBuiltinIdTy);
+    }
 }
 
 lldb_private::formatters::NSArrayISyntheticFrontEnd::~NSArrayISyntheticFrontEnd ()
diff --git a/source/DataFormatters/NSDictionary.cpp b/source/DataFormatters/NSDictionary.cpp
index c9fef42..05a5dda 100644
--- a/source/DataFormatters/NSDictionary.cpp
+++ b/source/DataFormatters/NSDictionary.cpp
@@ -30,52 +30,52 @@
 static ClangASTType
 GetLLDBNSPairType (TargetSP target_sp)
 {
-    ClangASTType clang_type = ClangASTType();
+    ClangASTType clang_type;
 
     ClangASTContext *target_ast_context = target_sp->GetScratchClangASTContext();
 
-    if (!target_ast_context)
-        return clang_type;
-    
-    const char* type_name = "__lldb_autogen_nspair";
-    
-    clang::IdentifierInfo &myIdent = target_ast_context->getASTContext()->Idents.get(type_name);
-    clang::DeclarationName myName = target_ast_context->getASTContext()->DeclarationNames.getIdentifier(&myIdent);
-
-    clang::DeclContext::lookup_const_result result = target_ast_context->getASTContext()->getTranslationUnitDecl()->lookup(myName);
-
-    clang_type_t opaque_type = NULL;
-    
-    for (clang::NamedDecl *named_decl : result)
+    if (target_ast_context)
     {
-        if (const clang::CXXRecordDecl *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(named_decl))
+        clang::ASTContext *ast = target_ast_context->getASTContext();
+
+        if (ast)
         {
-            opaque_type = clang::QualType(record_decl->getTypeForDecl(), 0).getAsOpaquePtr();
-            break;
-        }
-        else
-        {
-            // somebody else (the user?) has defined a type with the magic name already - fail!!!
-            return clang_type;
+            const char* type_name = "__lldb_autogen_nspair";
+            
+            clang::IdentifierInfo &myIdent = ast->Idents.get(type_name);
+            clang::DeclarationName myName = ast->DeclarationNames.getIdentifier(&myIdent);
+
+            clang::DeclContext::lookup_const_result result = ast->getTranslationUnitDecl()->lookup(myName);
+
+            for (clang::NamedDecl *named_decl : result)
+            {
+                if (const clang::CXXRecordDecl *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(named_decl))
+                {
+                    clang_type.SetClangType(ast, clang::QualType(record_decl->getTypeForDecl(), 0));
+                    break;
+                }
+                else
+                {
+                    // somebody else (the user?) has defined a type with the magic name already - fail!!!
+                    return clang_type;
+                }
+            }
+
+            if (!clang_type)
+            {
+                clang_type = target_ast_context->CreateRecordType(NULL, lldb::eAccessPublic, type_name, clang::TTK_Struct, lldb::eLanguageTypeC);
+                
+                if (clang_type)
+                {
+                    clang_type.StartTagDeclarationDefinition();
+                    ClangASTType id_clang_type = target_ast_context->GetBasicType (eBasicTypeObjCID);
+                    clang_type.AddFieldToRecordType("key", id_clang_type, lldb::eAccessPublic, 0);
+                    clang_type.AddFieldToRecordType("value", id_clang_type, lldb::eAccessPublic, 0);
+                    clang_type.CompleteTagDeclarationDefinition();
+                }
+            }
         }
     }
-
-    if (!opaque_type)
-    {
-        opaque_type = target_ast_context->CreateRecordType(NULL, lldb::eAccessPublic, type_name, clang::TTK_Struct, lldb::eLanguageTypeC);
-        
-        if (!opaque_type)
-            return clang_type;
-        
-        target_ast_context->StartTagDeclarationDefinition(opaque_type);
-        
-        target_ast_context->AddFieldToRecordType(opaque_type, "key", target_ast_context->GetBuiltInType_objc_id(), lldb::eAccessPublic, 0);
-        target_ast_context->AddFieldToRecordType(opaque_type, "value", target_ast_context->GetBuiltInType_objc_id(), lldb::eAccessPublic, 0);
-        
-        target_ast_context->CompleteTagDeclarationDefinition(opaque_type);
-    }
-    
-    clang_type.SetClangType(target_ast_context->getASTContext(), opaque_type);
     return clang_type;
 }
 
diff --git a/source/Expression/ASTDumper.cpp b/source/Expression/ASTDumper.cpp
index b5c7b32..5210d14 100644
--- a/source/Expression/ASTDumper.cpp
+++ b/source/Expression/ASTDumper.cpp
@@ -9,6 +9,7 @@
 
 #include "lldb/Core/Log.h"
 #include "lldb/Expression/ASTDumper.h"
+#include "lldb/Symbol/ClangASTType.h"
 
 #include "llvm/Support/raw_ostream.h"
 
@@ -77,7 +78,13 @@
 {
     m_dump = clang::QualType::getFromOpaquePtr(type).getAsString();
 }
-    
+
+ASTDumper::ASTDumper (const ClangASTType &clang_type)
+{
+    m_dump = clang_type.GetQualType().getAsString();
+}
+
+
 const char *
 ASTDumper::GetCString()
 {
diff --git a/source/Expression/ClangASTSource.cpp b/source/Expression/ClangASTSource.cpp
index 0fc3db6..49513d7 100644
--- a/source/Expression/ClangASTSource.cpp
+++ b/source/Expression/ClangASTSource.cpp
@@ -238,12 +238,12 @@
                     if (!type)
                         continue;
                     
-                    lldb::clang_type_t opaque_type = type->GetClangFullType();
+                    ClangASTType clang_type (type->GetClangFullType());
                     
-                    if (!opaque_type)
+                    if (!clang_type)
                         continue;
                     
-                    const TagType *tag_type = QualType::getFromOpaquePtr(opaque_type)->getAs<TagType>();
+                    const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>();
                     
                     if (!tag_type)
                         continue;
@@ -277,12 +277,12 @@
                 if (!type)
                     continue;
                 
-                lldb::clang_type_t opaque_type = type->GetClangFullType();
+                ClangASTType clang_type (type->GetClangFullType());
                 
-                if (!opaque_type)
+                if (!clang_type)
                     continue;
                 
-                const TagType *tag_type = QualType::getFromOpaquePtr(opaque_type)->getAs<TagType>();
+                const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>();
                 
                 if (!tag_type)
                     continue;
@@ -346,7 +346,7 @@
     if (!complete_type_sp)
         return NULL;
     
-    TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType(), complete_type_sp->GetClangAST());
+    TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType());
     lldb::clang_type_t complete_opaque_type = complete_type.GetOpaqueQualType();
     
     if (!complete_opaque_type)
@@ -696,12 +696,11 @@
                             (name_string ? name_string : "<anonymous>"));
             }
                         
-            clang::ASTContext *type_ast = type_sp->GetClangAST();
-            lldb::clang_type_t full_type = type_sp->GetClangFullType();
+            ClangASTType full_type = type_sp->GetClangFullType();
 
-            void *copied_type = GuardedCopyType(m_ast_context, type_ast, full_type);
+            ClangASTType copied_clang_type (GuardedCopyType(full_type));
                 
-            if (!copied_type)
+            if (!copied_clang_type)
             {                
                 if (log)
                     log->Printf("  CAS::FEVD[%u] - Couldn't export a type",
@@ -710,7 +709,7 @@
                 break;
             }
                 
-            context.AddTypeDecl(copied_type);
+            context.AddTypeDecl(copied_clang_type);
         }
         else
         {
@@ -750,13 +749,9 @@
                                 name.GetCString());
                 }
                 
-                const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr();
+                ClangASTType copied_clang_type (GuardedCopyType(types[0]));
                 
-                clang::QualType runtime_qual_type(runtime_clang_type, 0);
-                
-                void *copied_type = GuardedCopyType(m_ast_context, type_vendor->GetClangASTContext(), runtime_qual_type.getAsOpaquePtr());
-                
-                if (!copied_type)
+                if (!copied_clang_type)
                 {
                     if (log)
                         log->Printf("  CAS::FEVD[%u] - Couldn't export a type from the runtime",
@@ -765,7 +760,7 @@
                     break;
                 }
                 
-                context.AddTypeDecl(copied_type);
+                context.AddTypeDecl(copied_clang_type);
             }
             while(0);
         }
@@ -1688,42 +1683,43 @@
     return dyn_cast<NamespaceDecl>(copied_decl);
 }
 
-void * 
-ClangASTSource::GuardedCopyType (ASTContext *dest_context, 
-                                 ASTContext *source_context,
-                                 void *clang_type)
+ClangASTType
+ClangASTSource::GuardedCopyType (const ClangASTType &src_type)
 {
     ClangASTMetrics::RegisterLLDBImport();
     
     SetImportInProgress(true);
     
-    QualType ret_qual_type = m_ast_importer->CopyType (m_ast_context, source_context, QualType::getFromOpaquePtr(clang_type));
-    
-    void *ret = ret_qual_type.getAsOpaquePtr();
+    QualType copied_qual_type = m_ast_importer->CopyType (m_ast_context, src_type.GetASTContext(), src_type.GetQualType());
     
     SetImportInProgress(false);
     
-    if (ret && ret_qual_type->getCanonicalTypeInternal().isNull())
+    if (copied_qual_type.getAsOpaquePtr() && copied_qual_type->getCanonicalTypeInternal().isNull())
         // this shouldn't happen, but we're hardening because the AST importer seems to be generating bad types
         // on occasion.
-        return NULL;
+        return ClangASTType();
     
-    return ret;
+    return ClangASTType(m_ast_context, copied_qual_type);
 }
 
 clang::NamedDecl *
-NameSearchContext::AddVarDecl(void *type) 
+NameSearchContext::AddVarDecl(const ClangASTType &type)
 {
+    assert (type && "Type for variable must be valid!");
+
+    if (!type.IsValid())
+        return NULL;
+    
     IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
     
-    assert (type && "Type for variable must be non-NULL!");
-        
-    clang::NamedDecl *Decl = VarDecl::Create(*m_ast_source.m_ast_context, 
+    clang::ASTContext *ast = type.GetASTContext();
+
+    clang::NamedDecl *Decl = VarDecl::Create(*ast,
                                              const_cast<DeclContext*>(m_decl_context), 
                                              SourceLocation(), 
                                              SourceLocation(),
                                              ii, 
-                                             QualType::getFromOpaquePtr(type), 
+                                             type.GetQualType(),
                                              0, 
                                              SC_Static);
     m_decls.push_back(Decl);
@@ -1732,25 +1728,32 @@
 }
 
 clang::NamedDecl *
-NameSearchContext::AddFunDecl (void *type) 
+NameSearchContext::AddFunDecl (const ClangASTType &type) 
 {
-    assert (type && "Type for variable must be non-NULL!");
+    assert (type && "Type for variable must be valid!");
     
+    if (!type.IsValid())
+        return NULL;
+
     if (m_function_types.count(type))
         return NULL;
     
     m_function_types.insert(type);
     
+    QualType qual_type (type.GetQualType());
+    
+    clang::ASTContext *ast = type.GetASTContext();
+
     const bool isInlineSpecified = false;
     const bool hasWrittenPrototype = true;
     const bool isConstexprSpecified = false;
 
-    clang::FunctionDecl *func_decl = FunctionDecl::Create (*m_ast_source.m_ast_context,
+    clang::FunctionDecl *func_decl = FunctionDecl::Create (*ast,
                                                            const_cast<DeclContext*>(m_decl_context),
                                                            SourceLocation(),
                                                            SourceLocation(),
                                                            m_decl_name.getAsIdentifierInfo(),
-                                                           QualType::getFromOpaquePtr(type),
+                                                           qual_type,
                                                            NULL,
                                                            SC_Static,
                                                            isInlineSpecified,
@@ -1761,7 +1764,6 @@
     // synthesize ParmVarDecls for all of the FunctionDecl's arguments.  To do
     // this, we raid the function's FunctionProtoType for types.
     
-    QualType qual_type (QualType::getFromOpaquePtr(type));
     const FunctionProtoType *func_proto_type = qual_type.getTypePtr()->getAs<FunctionProtoType>();
     
     if (func_proto_type)
@@ -1775,7 +1777,7 @@
         {
             QualType arg_qual_type (func_proto_type->getArgType(ArgIndex));
             
-            parm_var_decls.push_back(ParmVarDecl::Create (*m_ast_source.m_ast_context,
+            parm_var_decls.push_back(ParmVarDecl::Create (*ast,
                                                           const_cast<DeclContext*>(m_decl_context),
                                                           SourceLocation(),
                                                           SourceLocation(),
@@ -1812,15 +1814,15 @@
                                                                                 ArrayRef<QualType>(),                                        // argument types
                                                                                 proto_info));
     
-    return AddFunDecl(generic_function_type.getAsOpaquePtr());
+    return AddFunDecl(ClangASTType (m_ast_source.m_ast_context, generic_function_type));
 }
 
 clang::NamedDecl *
-NameSearchContext::AddTypeDecl(void *type)
+NameSearchContext::AddTypeDecl(const ClangASTType &clang_type)
 {
-    if (type)
+    if (clang_type)
     {
-        QualType qual_type = QualType::getFromOpaquePtr(type);
+        QualType qual_type = clang_type.GetQualType();
 
         if (const TypedefType *typedef_type = llvm::dyn_cast<TypedefType>(qual_type))
         {
diff --git a/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp
index 36b72dd..26dd5e7 100644
--- a/source/Expression/ClangExpressionDeclMap.cpp
+++ b/source/Expression/ClangExpressionDeclMap.cpp
@@ -128,14 +128,7 @@
         {
             ClangExpressionVariableSP var_sp(m_found_entities.GetVariableAtIndex(entity_index));
             if (var_sp)
-            {
-                ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(GetParserID());
-                
-                if (parser_vars && parser_vars->m_lldb_value)
-                    delete parser_vars->m_lldb_value;
-            
                 var_sp->DisableParserVars(GetParserID());
-            }
         }
         
         for (size_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->GetSize();
@@ -495,7 +488,7 @@
     
     ClangExpressionVariable::ParserVars *parser_vars = entity_sp->GetParserVars(GetParserID());
 
-    ptr = parser_vars->m_lldb_value->GetScalar().ULongLong();
+    ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();
     
     return true;
 }
@@ -784,11 +777,8 @@
             {
                 VariableSP var_sp = vars.GetVariableAtIndex(i);
                 
-                if (type->GetASTContext() == var_sp->GetType()->GetClangAST())
-                {
-                    if (ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var_sp->GetType()->GetClangFullType()))
-                        return var_sp;
-                }
+                if (ClangASTContext::AreTypesSame(*type, var_sp->GetType()->GetClangFullType()))
+                    return var_sp;
             }
         }
         else
@@ -1009,30 +999,21 @@
                     if (!this_type)
                         return;
                     
-                    QualType this_qual_type = QualType::getFromOpaquePtr(this_type->GetClangFullType());
-                    const PointerType *class_pointer_type = this_qual_type->getAs<PointerType>();
+                    ClangASTType pointee_type = this_type->GetClangForwardType().GetPointeeType();
                     
-                    if (class_pointer_type)
+                    if (pointee_type.IsValid())
                     {
-                        QualType class_type = class_pointer_type->getPointeeType();
-                        
-                        if (!class_type.getAsOpaquePtr())
-                            return;
-                        
                         if (log)
                         {
                             ASTDumper ast_dumper(this_type->GetClangFullType());
                             log->Printf("  FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
                         }
                         
-                        TypeFromUser class_user_type (class_type.getAsOpaquePtr(),
-                                                        this_type->GetClangAST());
+                        TypeFromUser class_user_type(pointee_type);
                         AddOneType(context, class_user_type, current_id);
                                     
                                     
-                        TypeFromUser this_user_type(this_type->GetClangFullType(),
-                                                    this_type->GetClangAST());
-                        
+                        TypeFromUser this_user_type(this_type->GetClangFullType());
                         m_struct_vars->m_object_pointer_type = this_user_type;
                         return;
                     }
@@ -1135,19 +1116,17 @@
                     if (!self_type)
                         return;
                     
-                    QualType self_qual_type = QualType::getFromOpaquePtr(self_type->GetClangFullType());
+                    ClangASTType self_clang_type = self_type->GetClangFullType();
                     
-                    if (self_qual_type->isObjCClassType())
+                    if (self_clang_type.IsObjCClassType())
                     {
                         return;
                     }
-                    else if (self_qual_type->isObjCObjectPointerType())
+                    else if (self_clang_type.IsObjCObjectPointerType())
                     {
-                        const ObjCObjectPointerType *class_pointer_type = self_qual_type->getAs<ObjCObjectPointerType>();
-                    
-                        QualType class_type = class_pointer_type->getPointeeType();
-                        
-                        if (!class_type.getAsOpaquePtr())
+                        self_clang_type = self_clang_type.GetPointeeType();
+
+                        if (!self_clang_type)
                             return;
                         
                         if (log)
@@ -1156,13 +1135,11 @@
                             log->Printf("  FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
                         }
                         
-                        TypeFromUser class_user_type (class_type.getAsOpaquePtr(),
-                                                      self_type->GetClangAST());
+                        TypeFromUser class_user_type (self_clang_type);
                         
                         AddOneType(context, class_user_type, current_id);
                                     
-                        TypeFromUser self_user_type(self_type->GetClangFullType(),
-                                                    self_type->GetClangAST());
+                        TypeFromUser self_user_type(self_type->GetClangFullType());
                         
                         m_struct_vars->m_object_pointer_type = self_user_type;
                         return;
@@ -1420,14 +1397,11 @@
     return block_pointer_type.getAsOpaquePtr();
 }
 
-Value *
-ClangExpressionDeclMap::GetVariableValue
-(
-    VariableSP &var,
-    ASTContext *parser_ast_context,
-    TypeFromUser *user_type,
-    TypeFromParser *parser_type
-)
+bool
+ClangExpressionDeclMap::GetVariableValue (VariableSP &var,
+                                          lldb_private::Value &var_location,
+                                          TypeFromUser *user_type,
+                                          TypeFromParser *parser_type)
 {
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
@@ -1437,34 +1411,31 @@
     {
         if (log)
             log->PutCString("Skipped a definition because it has no type");
-        return NULL;
+        return false;
     }
     
-    clang_type_t var_opaque_type = var_type->GetClangFullType();
+    ClangASTType var_clang_type = var_type->GetClangFullType();
     
-    if (!var_opaque_type)
+    if (!var_clang_type)
     {
         if (log)
             log->PutCString("Skipped a definition because it has no Clang type");
-        return NULL;
+        return false;
     }
     
+    // commented out because of <rdar://problem/11024417>
     ASTContext *ast = var_type->GetClangASTContext().getASTContext();
-    
+
     if (!ast)
     {
         if (log)
             log->PutCString("There is no AST context for the current execution context");
-        return NULL;
+        return false;
     }
-
-    // commented out because of <rdar://problem/11024417>
-    //var_opaque_type = MaybePromoteToBlockPointerType (ast, var_opaque_type);
+    //var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type);
     
     DWARFExpression &var_location_expr = var->LocationExpression();
     
-    std::unique_ptr<Value> var_location(new Value);
-    
     lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
     
     Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
@@ -1483,41 +1454,34 @@
         
         if (var_location_expr.GetExpressionData(const_value_extractor))
         {
-            var_location->operator=(Value(const_value_extractor.GetDataStart(), const_value_extractor.GetByteSize()));
-            var_location->SetValueType(Value::eValueTypeHostAddress);
+            var_location = Value(const_value_extractor.GetDataStart(), const_value_extractor.GetByteSize());
+            var_location.SetValueType(Value::eValueTypeHostAddress);
         }
         else
         {
             if (log)
                 log->Printf("Error evaluating constant variable: %s", err.AsCString());
-            return NULL;
+            return false;
         }
     }
     
-    void *type_to_use = NULL;
+    ClangASTType type_to_use = GuardedCopyType(var_clang_type);
     
-    if (parser_ast_context)
+    if (!type_to_use)
     {
-        type_to_use = GuardedCopyType(parser_ast_context, ast, var_opaque_type);
+        if (log)
+            log->Printf("Couldn't copy a variable's type into the parser's AST context");
         
-        if (!type_to_use)
-        {
-            if (log)
-                log->Printf("Couldn't copy a variable's type into the parser's AST context");
-            
-            return NULL;
-        }
-        
-        if (parser_type)
-            *parser_type = TypeFromParser(type_to_use, parser_ast_context);
+        return false;
     }
-    else
-        type_to_use = var_opaque_type;
     
-    if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
-        var_location.get()->SetContext(Value::eContextTypeClangType, type_to_use);
+    if (parser_type)
+        *parser_type = TypeFromParser(type_to_use);
     
-    if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
+    if (var_location.GetContextType() == Value::eContextTypeInvalid)
+        var_location.SetClangType(type_to_use);
+    
+    if (var_location.GetValueType() == Value::eValueTypeFileAddress)
     {
         SymbolContext var_sc;
         var->CalculateSymbolContext(&var_sc);
@@ -1525,21 +1489,21 @@
         if (!var_sc.module_sp)
             return NULL;
 
-        Address so_addr(var_location->GetScalar().ULongLong(), var_sc.module_sp->GetSectionList());
+        Address so_addr(var_location.GetScalar().ULongLong(), var_sc.module_sp->GetSectionList());
         
         lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
         
         if (load_addr != LLDB_INVALID_ADDRESS)
         {
-            var_location->GetScalar() = load_addr;
-            var_location->SetValueType(Value::eValueTypeLoadAddress);
+            var_location.GetScalar() = load_addr;
+            var_location.SetValueType(Value::eValueTypeLoadAddress);
         }
     }
     
     if (user_type)
-        *user_type = TypeFromUser(var_opaque_type, ast);
+        *user_type = TypeFromUser(var_clang_type);
     
-    return var_location.release();
+    return true;
 }
 
 void
@@ -1551,11 +1515,10 @@
         
     TypeFromUser ut;
     TypeFromParser pt;
+    Value var_location;
     
-    Value *var_location = GetVariableValue (var, 
-                                            m_ast_context,
-                                            &ut,
-                                            &pt);
+    if (!GetVariableValue (var, var_location, &ut, &pt))
+        return;
     
     clang::QualType parser_opaque_type = QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
     
@@ -1568,17 +1531,14 @@
             CompleteType(tag_type->getDecl());
     }
     
-    if (!var_location)
-        return;
     
-    NamedDecl *var_decl;
-    
-    bool is_reference = ClangASTContext::IsReferenceType(pt.GetOpaqueQualType());
+    bool is_reference = pt.IsReferenceType();
 
+    NamedDecl *var_decl = NULL;
     if (is_reference)
-        var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
+        var_decl = context.AddVarDecl(pt);
     else
-        var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(pt.GetASTContext(), pt.GetOpaqueQualType()));
+        var_decl = context.AddVarDecl(pt.GetLValueReferenceType());
         
     std::string decl_name(context.m_decl_name.getAsString());
     ConstString entity_name(decl_name.c_str());
@@ -1613,10 +1573,7 @@
     
     TypeFromUser user_type (pvar_sp->GetTypeFromUser());
     
-    TypeFromParser parser_type (GuardedCopyType(m_ast_context, 
-                                                user_type.GetASTContext(), 
-                                                user_type.GetOpaqueQualType()),
-                                m_ast_context);
+    TypeFromParser parser_type (GuardedCopyType(user_type));
     
     if (!parser_type.GetOpaqueQualType())
     {
@@ -1625,14 +1582,14 @@
         return;
     }
     
-    NamedDecl *var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(parser_type.GetASTContext(), parser_type.GetOpaqueQualType()));
+    NamedDecl *var_decl = context.AddVarDecl(parser_type.GetLValueReferenceType());
     
     pvar_sp->EnableParserVars(GetParserID());
     ClangExpressionVariable::ParserVars *parser_vars = pvar_sp->GetParserVars(GetParserID());
     parser_vars->m_parser_type = parser_type;
-    parser_vars->m_named_decl  = var_decl;
-    parser_vars->m_llvm_value  = NULL;
-    parser_vars->m_lldb_value  = NULL;
+    parser_vars->m_named_decl = var_decl;
+    parser_vars->m_llvm_value = NULL;
+    parser_vars->m_lldb_value.Clear();
     
     if (log)
     {
@@ -1657,13 +1614,9 @@
 
     ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext();
     
-    TypeFromUser user_type (ClangASTContext::CreateLValueReferenceType(scratch_ast_context, ClangASTContext::GetVoidPtrType(scratch_ast_context, false)),
-                            scratch_ast_context);
-    
-    TypeFromParser parser_type (ClangASTContext::CreateLValueReferenceType(m_ast_context, ClangASTContext::GetVoidPtrType(m_ast_context, false)),
-                                m_ast_context);
-    
-    NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
+    TypeFromUser user_type (ClangASTContext::GetBasicType(scratch_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType());
+    TypeFromParser parser_type (ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType());
+    NamedDecl *var_decl = context.AddVarDecl(parser_type);
     
     std::string decl_name(context.m_decl_name.getAsString());
     ConstString entity_name(decl_name.c_str());
@@ -1674,21 +1627,20 @@
                                                                       m_parser_vars->m_target_info.address_byte_size));
     assert (entity.get());
     
-    std::unique_ptr<Value> symbol_location(new Value);
-    
+    entity->EnableParserVars(GetParserID());
+    ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
+
     const Address &symbol_address = symbol.GetAddress();
     lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
     
-    symbol_location->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
-    symbol_location->GetScalar() = symbol_load_addr;
-    symbol_location->SetValueType(Value::eValueTypeLoadAddress);
+    //parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
+    parser_vars->m_lldb_value.SetClangType(user_type);
+    parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
+    parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
     
-    entity->EnableParserVars(GetParserID());
-    ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
     parser_vars->m_parser_type = parser_type;
     parser_vars->m_named_decl  = var_decl;
     parser_vars->m_llvm_value  = NULL;
-    parser_vars->m_lldb_value  = symbol_location.release();
     parser_vars->m_lldb_sym    = &symbol;
     
     if (log)
@@ -1748,11 +1700,11 @@
             
             TypeFromUser user_type(copied_type, scratch_ast_context);
                         
-            parser_vars->m_lldb_value->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
+//            parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
+            parser_vars->m_lldb_value.SetClangType(user_type);
             parser_vars->m_parser_type = parser_type;
             
-            entity->SetClangAST(user_type.GetASTContext());
-            entity->SetClangType(user_type.GetOpaqueQualType());
+            entity->SetClangType(user_type);
             
             entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType);
         }
@@ -1768,21 +1720,20 @@
 {
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
-    void *ast_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(m_ast_context,
-                                                                          reg_info->encoding,
-                                                                          reg_info->byte_size * 8);
+    ClangASTType clang_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (m_ast_context,
+                                                                                    reg_info->encoding,
+                                                                                    reg_info->byte_size * 8);
     
-    if (!ast_type)
+    if (!clang_type)
     {
         if (log)
             log->Printf("  Tried to add a type for %s, but couldn't get one", context.m_decl_name.getAsString().c_str());
         return;
     }
     
-    TypeFromParser parser_type (ast_type,
-                                m_ast_context);
+    TypeFromParser parser_clang_type (clang_type);
     
-    NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
+    NamedDecl *var_decl = context.AddVarDecl(parser_clang_type);
     
     ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
                                                                       m_parser_vars->m_target_info.byte_order,
@@ -1794,10 +1745,10 @@
     entity->SetRegisterInfo (reg_info);
     entity->EnableParserVars(GetParserID());
     ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
-    parser_vars->m_parser_type = parser_type;
-    parser_vars->m_named_decl  = var_decl;
-    parser_vars->m_llvm_value  = NULL;
-    parser_vars->m_lldb_value  = NULL;
+    parser_vars->m_parser_type = parser_clang_type;
+    parser_vars->m_named_decl = var_decl;
+    parser_vars->m_llvm_value = NULL;
+    parser_vars->m_lldb_value.Clear();
     entity->m_flags |= ClangExpressionVariable::EVBareRegister;
     
     if (log)
@@ -1809,7 +1760,7 @@
 
 void
 ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
-                                        Function* fun,
+                                        Function* function,
                                         Symbol* symbol,
                                         unsigned int current_id)
 {
@@ -1817,51 +1768,46 @@
     
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
-    NamedDecl *fun_decl = NULL;
-    std::unique_ptr<Value> fun_location(new Value);
+    NamedDecl *function_decl = NULL;
     const Address *fun_address = NULL;
-    
-    // only valid for Functions, not for Symbols
-    void *fun_opaque_type = NULL;
-    ASTContext *fun_ast_context = NULL;
+    ClangASTType function_clang_type;
 
     bool is_indirect_function = false;
 
-    if (fun)
+    if (function)
     {
-        Type *fun_type = fun->GetType();
+        Type *function_type = function->GetType();
         
-        if (!fun_type) 
+        if (!function_type)
         {
             if (log)
                 log->PutCString("  Skipped a function because it has no type");
             return;
         }
         
-        fun_opaque_type = fun_type->GetClangFullType();
+        function_clang_type = function_type->GetClangFullType();
         
-        if (!fun_opaque_type)
+        if (!function_clang_type)
         {
             if (log)
                 log->PutCString("  Skipped a function because it has no Clang type");
             return;
         }
         
-        fun_address = &fun->GetAddressRange().GetBaseAddress();
+        fun_address = &function->GetAddressRange().GetBaseAddress();
         
-        fun_ast_context = fun_type->GetClangASTContext().getASTContext();
-        void *copied_type = GuardedCopyType(m_ast_context, fun_ast_context, fun_opaque_type);
-        if (copied_type)
+        ClangASTType copied_function_type = GuardedCopyType(function_clang_type);
+        if (copied_function_type)
         {
-            fun_decl = context.AddFunDecl(copied_type);
+            function_decl = context.AddFunDecl(copied_function_type);
             
-            if (!fun_decl)
+            if (!function_decl)
             {
                 if (log)
                 {
                     log->Printf ("  Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
-                                 fun_type->GetName().GetCString(),
-                                 fun_type->GetID());
+                                 function_type->GetName().GetCString(),
+                                 function_type->GetID());
                 }
                 
                 return;
@@ -1873,8 +1819,8 @@
             if (log)
             {
                 log->Printf ("  Failed to import the function type '%s' {0x%8.8" PRIx64 "} into the expression parser AST contenxt",
-                             fun_type->GetName().GetCString(), 
-                             fun_type->GetID());
+                             function_type->GetName().GetCString(),
+                             function_type->GetID());
             }
             
             return;
@@ -1883,7 +1829,7 @@
     else if (symbol)
     {
         fun_address = &symbol->GetAddress();
-        fun_decl = context.AddGenericFunDecl();
+        function_decl = context.AddGenericFunDecl();
         is_indirect_function = symbol->IsIndirect();
     }
     else
@@ -1897,10 +1843,22 @@
 
     lldb::addr_t load_addr = fun_address->GetCallableLoadAddress(target, is_indirect_function);
     
+    ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
+                                                                      m_parser_vars->m_target_info.byte_order,
+                                                                      m_parser_vars->m_target_info.address_byte_size));
+    assert (entity.get());
+
+    std::string decl_name(context.m_decl_name.getAsString());
+    entity->SetName(ConstString(decl_name.c_str()));
+    entity->SetClangType (function_clang_type);
+    entity->EnableParserVars(GetParserID());
+
+    ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
+    
     if (load_addr != LLDB_INVALID_ADDRESS)
     {
-        fun_location->SetValueType(Value::eValueTypeLoadAddress);
-        fun_location->GetScalar() = load_addr;
+        parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
+        parser_vars->m_lldb_value.GetScalar() = load_addr;
     }
     else
     {
@@ -1908,28 +1866,17 @@
         
         lldb::addr_t file_addr = fun_address->GetFileAddress();
         
-        fun_location->SetValueType(Value::eValueTypeFileAddress);
-        fun_location->GetScalar() = file_addr;
+        parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress);
+        parser_vars->m_lldb_value.GetScalar() = file_addr;
     }
     
-    ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
-                                                                      m_parser_vars->m_target_info.byte_order,
-                                                                      m_parser_vars->m_target_info.address_byte_size));
-    assert (entity.get());
-    std::string decl_name(context.m_decl_name.getAsString());
-    entity->SetName(ConstString(decl_name.c_str()));
-    entity->SetClangType (fun_opaque_type);
-    entity->SetClangAST (fun_ast_context);
-    
-    entity->EnableParserVars(GetParserID());
-    ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
-    parser_vars->m_named_decl  = fun_decl;
+
+    parser_vars->m_named_decl  = function_decl;
     parser_vars->m_llvm_value  = NULL;
-    parser_vars->m_lldb_value  = fun_location.release();
-        
+    
     if (log)
     {
-        ASTDumper ast_dumper(fun_decl);
+        ASTDumper ast_dumper(function_decl);
         
         StreamString ss;
         
@@ -1937,7 +1884,7 @@
         
         log->Printf("  CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
                     current_id,
-                    (fun ? "specific" : "generic"), 
+                    (function ? "specific" : "generic"),
                     decl_name.c_str(),
                     ss.GetData(),
                     ast_dumper.GetCString());
@@ -1948,12 +1895,9 @@
 ClangExpressionDeclMap::CopyClassType(TypeFromUser &ut,
                                       unsigned int current_id)
 {
-    ASTContext *parser_ast_context = m_ast_context;
-    ASTContext *user_ast_context = ut.GetASTContext();
-
-    void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
+    ClangASTType copied_clang_type = GuardedCopyType(ut);
     
-    if (!copied_type)
+    if (!copied_clang_type)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
         
@@ -1963,18 +1907,17 @@
         return TypeFromParser();
     }
 
-    if (ClangASTContext::IsAggregateType(copied_type) && ClangASTContext::GetCompleteType (parser_ast_context, copied_type))
+    if (copied_clang_type.IsAggregateType() && copied_clang_type.GetCompleteType ())
     {
-        void *args[1];
+        ClangASTType void_clang_type = ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid);
+        ClangASTType void_ptr_clang_type = void_clang_type.GetPointerType();
         
-        args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
-        
-        clang_type_t method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
-                                                                        ClangASTContext::GetBuiltInType_void(parser_ast_context),
-                                                                        args,
+        ClangASTType method_type = ClangASTContext::CreateFunctionType (m_ast_context,
+                                                                        void_clang_type,
+                                                                        &void_ptr_clang_type,
                                                                         1,
                                                                         false,
-                                                                        ClangASTContext::GetTypeQualifiers(copied_type));
+                                                                        copied_clang_type.GetTypeQualifiers());
         
         const bool is_virtual = false;
         const bool is_static = false;
@@ -1983,20 +1926,18 @@
         const bool is_attr_used = true;
         const bool is_artificial = false;
         
-        ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
-                                                   copied_type,
-                                                   "$__lldb_expr",
-                                                   method_type,
-                                                   lldb::eAccessPublic,
-                                                   is_virtual,
-                                                   is_static,
-                                                   is_inline,
-                                                   is_explicit,
-                                                   is_attr_used,
-                                                   is_artificial);
+        copied_clang_type.AddMethodToCXXRecordType ("$__lldb_expr",
+                                                    method_type,
+                                                    lldb::eAccessPublic,
+                                                    is_virtual,
+                                                    is_static,
+                                                    is_inline,
+                                                    is_explicit,
+                                                    is_attr_used,
+                                                    is_artificial);
     }
     
-    return TypeFromParser(copied_type, parser_ast_context);
+    return TypeFromParser(copied_clang_type);
 }
 
 void 
@@ -2004,12 +1945,9 @@
                                    TypeFromUser &ut,
                                    unsigned int current_id)
 {
-    ASTContext *parser_ast_context = m_ast_context;
-    ASTContext *user_ast_context = ut.GetASTContext();
+    ClangASTType copied_clang_type = GuardedCopyType(ut);
     
-    void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
-    
-    if (!copied_type)
+    if (!copied_clang_type)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
@@ -2019,5 +1957,5 @@
         return;
     }
     
-    context.AddTypeDecl(copied_type);
+    context.AddTypeDecl(copied_clang_type);
 }
diff --git a/source/Expression/ClangExpressionVariable.cpp b/source/Expression/ClangExpressionVariable.cpp
index ec08a0c..0d355ce 100644
--- a/source/Expression/ClangExpressionVariable.cpp
+++ b/source/Expression/ClangExpressionVariable.cpp
@@ -74,34 +74,23 @@
     return m_frozen_sp->GetValue().SetContext (Value::eContextTypeRegisterInfo, const_cast<RegisterInfo *>(reg_info));
 }
 
-lldb::clang_type_t
+ClangASTType
 ClangExpressionVariable::GetClangType()
 {
     return m_frozen_sp->GetClangType();
 }    
 
 void
-ClangExpressionVariable::SetClangType(lldb::clang_type_t clang_type)
+ClangExpressionVariable::SetClangType(const ClangASTType &clang_type)
 {
-    m_frozen_sp->GetValue().SetContext(Value::eContextTypeClangType, clang_type);
+    m_frozen_sp->GetValue().SetClangType(clang_type);
 }    
 
-clang::ASTContext *
-ClangExpressionVariable::GetClangAST()
-{
-    return m_frozen_sp->GetClangAST();
-}    
-
-void
-ClangExpressionVariable::SetClangAST (clang::ASTContext *ast)
-{
-    m_frozen_sp->SetClangAST (ast);
-}
 
 TypeFromUser
 ClangExpressionVariable::GetTypeFromUser()
 {
-    TypeFromUser tfu (m_frozen_sp->GetClangType(), m_frozen_sp->GetClangAST());
+    TypeFromUser tfu (m_frozen_sp->GetClangType());
     return tfu;
 }    
 
diff --git a/source/Expression/ClangFunction.cpp b/source/Expression/ClangFunction.cpp
index e37a16a..177138d 100644
--- a/source/Expression/ClangFunction.cpp
+++ b/source/Expression/ClangFunction.cpp
@@ -51,15 +51,13 @@
 ClangFunction::ClangFunction 
 (
     ExecutionContextScope &exe_scope,
-    ClangASTContext *ast_context, 
-    void *return_qualtype, 
+    const ClangASTType &return_type, 
     const Address& functionAddress, 
     const ValueList &arg_value_list
 ) :
     m_function_ptr (NULL),
     m_function_addr (functionAddress),
-    m_function_return_qual_type(return_qualtype),
-    m_clang_ast_context (ast_context),
+    m_function_return_type(return_type),
     m_wrapper_function_name ("__lldb_caller_function"),
     m_wrapper_struct_name ("__lldb_caller_struct"),
     m_wrapper_args_addrs (),
@@ -81,7 +79,7 @@
 ) :
     m_function_ptr (&function),
     m_function_addr (),
-    m_function_return_qual_type (),
+    m_function_return_type (),
     m_clang_ast_context (ast_context),
     m_wrapper_function_name ("__lldb_function_caller"),
     m_wrapper_struct_name ("__lldb_caller_struct"),
@@ -95,7 +93,7 @@
     assert (m_jit_process_wp.lock());
 
     m_function_addr = m_function_ptr->GetAddressRange().GetBaseAddress();
-    m_function_return_qual_type = m_function_ptr->GetReturnClangType();
+    m_function_return_type = m_function_ptr->GetClangType().GetFunctionReturnType();
 }
 
 //----------------------------------------------------------------------
@@ -114,8 +112,7 @@
     // FIXME: How does clang tell us there's no return value?  We need to handle that case.
     unsigned num_errors = 0;
     
-    std::string return_type_str (ClangASTType::GetTypeNameForOpaqueQualType (m_clang_ast_context->getASTContext(),
-                                                                             m_function_return_qual_type));
+    std::string return_type_str (m_function_return_type.GetTypeName());
     
     // Cons up the function we're going to wrap our call in, then compile it...
     // We declare the function "extern "C"" because the compiler might be in C++
@@ -137,16 +134,22 @@
     // to pull the defined arguments out of the function, then add the types from the
     // arguments list for the variable arguments.
 
-    size_t num_args = UINT32_MAX;
+    uint32_t num_args = UINT32_MAX;
     bool trust_function = false;
     // GetArgumentCount returns -1 for an unprototyped function.
+    ClangASTType function_clang_type;
     if (m_function_ptr)
     {
-        int num_func_args = m_function_ptr->GetArgumentCount();
-        if (num_func_args >= 0)
-            trust_function = true;
-        else
-            num_args = num_func_args;
+        function_clang_type = m_function_ptr->GetClangType();
+        if (function_clang_type)
+        {
+            int num_func_args = function_clang_type.GetFunctionArgumentCount();
+            if (num_func_args >= 0)
+            {
+                trust_function = true;
+                num_args = num_func_args;
+            }
+        }
     }
 
     if (num_args == UINT32_MAX)
@@ -160,18 +163,14 @@
 
         if (trust_function)
         {
-            lldb::clang_type_t arg_clang_type = m_function_ptr->GetArgumentTypeAtIndex(i);
-            type_name = ClangASTType::GetTypeNameForOpaqueQualType (m_clang_ast_context->getASTContext(),
-                                                                    arg_clang_type);
+            type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i).GetTypeName();
         }
         else
         {
-            Value *arg_value = m_arg_values.GetValueAtIndex(i);
-            lldb::clang_type_t clang_qual_type = arg_value->GetClangType ();
-            if (clang_qual_type != NULL)
+            ClangASTType clang_qual_type = m_arg_values.GetValueAtIndex(i)->GetClangType ();
+            if (clang_qual_type)
             {
-                type_name = ClangASTType::GetTypeNameForOpaqueQualType (m_clang_ast_context->getASTContext(),
-                                                                        clang_qual_type);
+                type_name = clang_qual_type.GetTypeName();
             }
             else
             {   
@@ -362,11 +361,11 @@
         // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings)
         
         if (arg_value->GetValueType() == Value::eValueTypeHostAddress &&
-            arg_value->GetContextType() == Value::eContextTypeClangType &&
-            ClangASTContext::IsPointerType(arg_value->GetClangType()))
+            arg_value->GetContextType() == Value::eContextTypeInvalid &&
+            arg_value->GetClangType().IsPointerType())
             continue;
         
-        const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx, m_clang_ast_context->getASTContext());
+        const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx);
 
         if (!process->WriteScalarToMemory(args_addr_ref + offset, arg_scalar, arg_scalar.GetByteSize(), error))
             return false;
@@ -464,7 +463,7 @@
     if (error.Fail())
         return false;
 
-    ret_value.SetContext (Value::eContextTypeClangType, m_function_return_qual_type);
+    ret_value.SetClangType(m_function_return_type);
     ret_value.SetValueType(Value::eValueTypeScalar);
     return true;
 }
diff --git a/source/Expression/ClangUserExpression.cpp b/source/Expression/ClangUserExpression.cpp
index c72c3b1..18f7a8d 100644
--- a/source/Expression/ClangUserExpression.cpp
+++ b/source/Expression/ClangUserExpression.cpp
@@ -297,21 +297,19 @@
                         return;
                     }
                     
-                    lldb::clang_type_t self_opaque_type = self_type->GetClangForwardType();
+                    ClangASTType self_clang_type = self_type->GetClangForwardType();
                     
-                    if (!self_opaque_type)
+                    if (!self_clang_type)
                     {
                         err.SetErrorString(selfErrorString);
                         return;
                     }
-                    
-                    clang::QualType self_qual_type = clang::QualType::getFromOpaquePtr(self_opaque_type);
-                    
-                    if (self_qual_type->isObjCClassType())
+                                        
+                    if (self_clang_type.IsObjCClassType())
                     {
                         return;
                     }
-                    else if (self_qual_type->isObjCObjectPointerType())
+                    else if (self_clang_type.IsObjCObjectPointerType())
                     {
                         m_objectivec = true;
                         m_needs_object_ptr = true;
@@ -487,6 +485,26 @@
         
     m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
     
+    class OnExit
+    {
+    public:
+        typedef std::function <void (void)> Callback;
+        
+        OnExit (Callback const &callback) :
+            m_callback(callback)
+        {
+        }
+        
+        ~OnExit ()
+        {
+            m_callback();
+        }
+    private:
+        Callback m_callback;
+    };
+    
+    OnExit on_exit([this]() { m_expr_decl_map.reset(); });
+    
     if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
     {
         error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
diff --git a/source/Expression/DWARFExpression.cpp b/source/Expression/DWARFExpression.cpp
index 07cb688..7797205 100644
--- a/source/Expression/DWARFExpression.cpp
+++ b/source/Expression/DWARFExpression.cpp
@@ -1195,7 +1195,6 @@
 DWARFExpression::Evaluate
 (
     ExecutionContextScope *exe_scope,
-    clang::ASTContext *ast_context,
     ClangExpressionVariableList *expr_locals,
     ClangExpressionDeclMap *decl_map,
     lldb::addr_t loclist_base_load_addr,
@@ -1205,14 +1204,13 @@
 ) const
 {
     ExecutionContext exe_ctx (exe_scope);
-    return Evaluate(&exe_ctx, ast_context, expr_locals, decl_map, NULL, loclist_base_load_addr, initial_value_ptr, result, error_ptr);
+    return Evaluate(&exe_ctx, expr_locals, decl_map, NULL, loclist_base_load_addr, initial_value_ptr, result, error_ptr);
 }
 
 bool
 DWARFExpression::Evaluate
 (
     ExecutionContext *exe_ctx,
-    clang::ASTContext *ast_context,
     ClangExpressionVariableList *expr_locals,
     ClangExpressionDeclMap *decl_map,
     RegisterContext *reg_ctx,
@@ -1269,7 +1267,7 @@
 
                     if (length > 0 && lo_pc <= pc && pc < hi_pc)
                     {
-                        return DWARFExpression::Evaluate (exe_ctx, ast_context, expr_locals, decl_map, reg_ctx, m_data, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr);
+                        return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, m_data, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr);
                     }
                     offset += length;
                 }
@@ -1281,7 +1279,7 @@
     }
 
     // Not a location list, just a single expression.
-    return DWARFExpression::Evaluate (exe_ctx, ast_context, expr_locals, decl_map, reg_ctx, m_data, 0, m_data.GetByteSize(), m_reg_kind, initial_value_ptr, result, error_ptr);
+    return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, m_data, 0, m_data.GetByteSize(), m_reg_kind, initial_value_ptr, result, error_ptr);
 }
 
 
@@ -1290,7 +1288,6 @@
 DWARFExpression::Evaluate
 (
     ExecutionContext *exe_ctx,
-    clang::ASTContext *ast_context,
     ClangExpressionVariableList *expr_locals,
     ClangExpressionDeclMap *decl_map,
     RegisterContext *reg_ctx,
@@ -1769,7 +1766,7 @@
                     error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_abs.");
                 return false;
             }
-            else if (stack.back().ResolveValue(exe_ctx, ast_context).AbsoluteValue() == false)
+            else if (stack.back().ResolveValue(exe_ctx).AbsoluteValue() == false)
             {
                 if (error_ptr)
                     error_ptr->SetErrorString("Failed to take the absolute value of the first stack item.");
@@ -1794,7 +1791,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) & tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) & tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -1815,7 +1812,7 @@
             else
             {
                 tmp = stack.back();
-                if (tmp.ResolveValue(exe_ctx, ast_context).IsZero())
+                if (tmp.ResolveValue(exe_ctx).IsZero())
                 {
                     if (error_ptr)
                         error_ptr->SetErrorString("Divide by zero.");
@@ -1824,8 +1821,8 @@
                 else
                 {
                     stack.pop_back();
-                    stack.back() = stack.back().ResolveValue(exe_ctx, ast_context) / tmp.ResolveValue(exe_ctx, ast_context);
-                    if (!stack.back().ResolveValue(exe_ctx, ast_context).IsValid())
+                    stack.back() = stack.back().ResolveValue(exe_ctx) / tmp.ResolveValue(exe_ctx);
+                    if (!stack.back().ResolveValue(exe_ctx).IsValid())
                     {
                         if (error_ptr)
                             error_ptr->SetErrorString("Divide failed.");
@@ -1852,7 +1849,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) - tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) - tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -1874,7 +1871,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) % tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) % tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -1896,7 +1893,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) * tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) * tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -1914,7 +1911,7 @@
             }
             else
             {
-                if (stack.back().ResolveValue(exe_ctx, ast_context).UnaryNegate() == false)
+                if (stack.back().ResolveValue(exe_ctx).UnaryNegate() == false)
                 {
                     if (error_ptr)
                         error_ptr->SetErrorString("Unary negate failed.");
@@ -1938,7 +1935,7 @@
             }
             else
             {
-                if (stack.back().ResolveValue(exe_ctx, ast_context).OnesComplement() == false)
+                if (stack.back().ResolveValue(exe_ctx).OnesComplement() == false)
                 {
                     if (error_ptr)
                         error_ptr->SetErrorString("Logical NOT failed.");
@@ -1964,7 +1961,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) | tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) | tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -1985,7 +1982,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) + tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) + tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -2006,8 +2003,8 @@
             {
                 const uint64_t uconst_value = opcodes.GetULEB128(&offset);
                 // Implicit conversion from a UINT to a Scalar...
-                stack.back().ResolveValue(exe_ctx, ast_context) += uconst_value;
-                if (!stack.back().ResolveValue(exe_ctx, ast_context).IsValid())
+                stack.back().ResolveValue(exe_ctx) += uconst_value;
+                if (!stack.back().ResolveValue(exe_ctx).IsValid())
                 {
                     if (error_ptr)
                         error_ptr->SetErrorString("DW_OP_plus_uconst failed.");
@@ -2034,7 +2031,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) <<= tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) <<= tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -2056,7 +2053,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                if (stack.back().ResolveValue(exe_ctx, ast_context).ShiftRightLogical(tmp.ResolveValue(exe_ctx, ast_context)) == false)
+                if (stack.back().ResolveValue(exe_ctx).ShiftRightLogical(tmp.ResolveValue(exe_ctx)) == false)
                 {
                     if (error_ptr)
                         error_ptr->SetErrorString("DW_OP_shr failed.");
@@ -2084,7 +2081,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) >>= tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) >>= tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -2105,7 +2102,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) ^ tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) ^ tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -2149,7 +2146,7 @@
                 stack.pop_back();
                 int16_t bra_offset = (int16_t)opcodes.GetU16(&offset);
                 Scalar zero(0);
-                if (tmp.ResolveValue(exe_ctx, ast_context) != zero)
+                if (tmp.ResolveValue(exe_ctx) != zero)
                 {
                     lldb::offset_t new_offset = offset + bra_offset;
                     if (new_offset >= opcodes_offset && new_offset < end_offset)
@@ -2184,7 +2181,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) == tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) == tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -2208,7 +2205,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) >= tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) >= tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -2232,7 +2229,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) > tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) > tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -2256,7 +2253,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) <= tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) <= tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -2280,7 +2277,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) < tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) < tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -2304,7 +2301,7 @@
             {
                 tmp = stack.back();
                 stack.pop_back();
-                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) != tmp.ResolveValue(exe_ctx, ast_context);
+                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) != tmp.ResolveValue(exe_ctx);
             }
             break;
 
@@ -2457,7 +2454,7 @@
                 if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
                 {
                     int64_t breg_offset = opcodes.GetSLEB128(&offset);
-                    tmp.ResolveValue(exe_ctx, ast_context) += (uint64_t)breg_offset;
+                    tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;
                     tmp.ClearContext();
                     stack.push_back(tmp);
                     stack.back().SetValueType (Value::eValueTypeLoadAddress);
@@ -2481,7 +2478,7 @@
                 if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
                 {
                     int64_t breg_offset = opcodes.GetSLEB128(&offset);
-                    tmp.ResolveValue(exe_ctx, ast_context) += (uint64_t)breg_offset;
+                    tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;
                     tmp.ClearContext();
                     stack.push_back(tmp);
                     stack.back().SetValueType (Value::eValueTypeLoadAddress);
@@ -2630,566 +2627,6 @@
         case DW_OP_stack_value:
             stack.back().SetValueType(Value::eValueTypeScalar);
             break;
-
-#if 0
-        //----------------------------------------------------------------------
-        // OPCODE: DW_OP_call_ref
-        // OPERANDS:
-        //      uint32_t absolute DIE offset for 32-bit DWARF or a uint64_t
-        //               absolute DIE offset for 64 bit DWARF.
-        // DESCRIPTION: Performs a subroutine call during evaluation of a DWARF
-        // expression. Takes a single operand. In the 32-bit DWARF format, the
-        // operand is a 4-byte unsigned value; in the 64-bit DWARF format, it
-        // is an 8-byte unsigned value. The operand is used as the offset of a
-        // debugging information entry in a .debug_info section which may be
-        // contained in a shared object for executable other than that
-        // containing the operator. For references from one shared object or
-        // executable to another, the relocation must be performed by the
-        // consumer.
-        //
-        // Operand interpretation of DW_OP_call_ref is exactly like that for
-        // DW_FORM_ref_addr.
-        //
-        // This operation transfers control of DWARF expression evaluation
-        // to the DW_AT_location attribute of the referenced DIE. If there is
-        // no such attribute, then there is no effect. Execution of the DWARF
-        // expression of a DW_AT_location attribute may add to and/or remove from
-        // values on the stack. Execution returns to the point following the call
-        // when the end of the attribute is reached. Values on the stack at the
-        // time of the call may be used as parameters by the called expression
-        // and values left on the stack by the called expression may be used as
-        // return values by prior agreement between the calling and called
-        // expressions.
-        //----------------------------------------------------------------------
-        case DW_OP_call_ref:
-            if (error_ptr)
-                error_ptr->SetErrorString ("Unimplemented opcode DW_OP_call_ref.");
-            return false;
-
-                //----------------------------------------------------------------------
-                // OPCODE: DW_OP_APPLE_array_ref
-                // OPERANDS: none
-                // DESCRIPTION: Pops a value off the stack and uses it as the array 
-                // index.  Pops a second value off the stack and uses it as the array
-                // itself.  Pushes a value onto the stack representing the element of
-                // the array specified by the index.
-                //----------------------------------------------------------------------
-            case DW_OP_APPLE_array_ref:
-            {
-                if (stack.size() < 2)
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_APPLE_array_ref.");
-                    return false;
-                }
-                
-                Value index_val = stack.back();
-                stack.pop_back();
-                Value array_val = stack.back();
-                stack.pop_back();
-                
-                Scalar &index_scalar = index_val.ResolveValue(exe_ctx, ast_context);
-                int64_t index = index_scalar.SLongLong(LLONG_MAX);
-                
-                if (index == LLONG_MAX)
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorString("Invalid array index.");
-                    return false;
-                }
-                
-                if (array_val.GetContextType() != Value::eContextTypeClangType)
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorString("Arrays without Clang types are unhandled at this time.");
-                    return false;
-                }
-                
-                if (array_val.GetValueType() != Value::eValueTypeLoadAddress &&
-                    array_val.GetValueType() != Value::eValueTypeHostAddress)
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorString("Array must be stored in memory.");
-                    return false;
-                }
-                
-                void *array_type = array_val.GetClangType();
-                
-                void *member_type;
-                uint64_t size = 0;
-                
-                if ((!ClangASTContext::IsPointerType(array_type, &member_type)) &&
-                    (!ClangASTContext::IsArrayType(array_type, &member_type, &size)))
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorString("Array reference from something that is neither a pointer nor an array.");
-                    return false;
-                }
-                
-                if (size && (index >= size || index < 0))
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorStringWithFormat("Out of bounds array access.  %" PRId64 " is not in [0, %" PRIu64 "]", index, size);
-                    return false;
-                }
-                
-                uint64_t member_bit_size = ClangASTType::GetClangTypeBitWidth(ast_context, member_type);
-                uint64_t member_bit_align = ClangASTType::GetTypeBitAlign(ast_context, member_type);
-                uint64_t member_bit_incr = ((member_bit_size + member_bit_align - 1) / member_bit_align) * member_bit_align;
-                if (member_bit_incr % 8)
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorStringWithFormat("Array increment is not byte aligned");
-                    return false;
-                }
-                int64_t member_offset = (int64_t)(member_bit_incr / 8) * index;
-                
-                Value member;
-                
-                member.SetContext(Value::eContextTypeClangType, member_type);
-                member.SetValueType(array_val.GetValueType());
-                
-                addr_t array_base = (addr_t)array_val.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
-                addr_t member_loc = array_base + member_offset;
-                member.GetScalar() = (uint64_t)member_loc;
-                
-                stack.push_back(member);
-            }
-                break;
-                
-        //----------------------------------------------------------------------
-        // OPCODE: DW_OP_APPLE_uninit
-        // OPERANDS: none
-        // DESCRIPTION: Lets us know that the value is currently not initialized
-        //----------------------------------------------------------------------
-        case DW_OP_APPLE_uninit:
-            //return eResultTypeErrorUninitialized;
-            break;  // Ignore this as we have seen cases where this value is incorrectly added
-
-        //----------------------------------------------------------------------
-        // OPCODE: DW_OP_APPLE_assign
-        // OPERANDS: none
-        // DESCRIPTION: Pops a value off of the stack and assigns it to the next
-        // item on the stack which must be something assignable (inferior
-        // Variable, inferior Type with address, inferior register, or
-        // expression local variable.
-        //----------------------------------------------------------------------
-        case DW_OP_APPLE_assign:
-            if (stack.size() < 2)
-            {
-                if (error_ptr)
-                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_APPLE_assign.");
-                return false;
-            }
-            else
-            {
-                tmp = stack.back();
-                stack.pop_back();
-                Value::ContextType context_type = stack.back().GetContextType();
-                StreamString new_value(Stream::eBinary, 4, lldb::endian::InlHostByteOrder());
-                switch (context_type)
-                {
-                case Value::eContextTypeClangType:
-                    {
-                        void *clang_type = stack.back().GetClangType();
-                        
-                        if (ClangASTContext::IsAggregateType (clang_type))
-                        {
-                            Value::ValueType source_value_type = tmp.GetValueType();
-                            Value::ValueType target_value_type = stack.back().GetValueType();
-                            
-                            addr_t source_addr = (addr_t)tmp.GetScalar().ULongLong();
-                            addr_t target_addr = (addr_t)stack.back().GetScalar().ULongLong();
-                            
-                            const uint64_t byte_size = ClangASTType::GetTypeByteSize(ast_context, clang_type);
-                            
-                            switch (source_value_type)
-                            {
-                            case Value::eValueTypeScalar:
-                            case Value::eValueTypeFileAddress:
-                                break;
-
-                            case Value::eValueTypeLoadAddress:
-                                switch (target_value_type)
-                                {
-                                case Value::eValueTypeLoadAddress:
-                                    {
-                                        DataBufferHeap data;
-                                        data.SetByteSize(byte_size);
-                                        
-                                        Error error;
-                                        if (process->ReadMemory (source_addr, data.GetBytes(), byte_size, error) != byte_size)
-                                        {
-                                            if (error_ptr)
-                                                error_ptr->SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
-                                            return false;
-                                        }
-                                        
-                                        if (process->WriteMemory (target_addr, data.GetBytes(), byte_size, error) != byte_size)
-                                        {
-                                            if (error_ptr)
-                                                error_ptr->SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
-                                            return false;
-                                        }
-                                    }
-                                    break;
-                                case Value::eValueTypeHostAddress:
-                                    if (process->GetByteOrder() != lldb::endian::InlHostByteOrder())
-                                    {
-                                        if (error_ptr)
-                                            error_ptr->SetErrorStringWithFormat ("Copy of composite types between incompatible byte orders is unimplemented");
-                                        return false;
-                                    }
-                                    else
-                                    {
-                                        Error error;
-                                        if (process->ReadMemory (source_addr, (uint8_t*)target_addr, byte_size, error) != byte_size)
-                                        {
-                                            if (error_ptr)
-                                                error_ptr->SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
-                                            return false;
-                                        }
-                                    }
-                                    break;
-                                default:
-                                    return false;
-                                }
-                                break;
-                            case Value::eValueTypeHostAddress:
-                                switch (target_value_type)
-                                {
-                                case Value::eValueTypeLoadAddress:
-                                    if (process->GetByteOrder() != lldb::endian::InlHostByteOrder())
-                                    {
-                                        if (error_ptr)
-                                            error_ptr->SetErrorStringWithFormat ("Copy of composite types between incompatible byte orders is unimplemented");
-                                        return false;
-                                    }
-                                    else
-                                    {
-                                        Error error;
-                                        if (process->WriteMemory (target_addr, (uint8_t*)source_addr, byte_size, error) != byte_size)
-                                        {
-                                            if (error_ptr)
-                                                error_ptr->SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
-                                            return false;
-                                        }
-                                    }
-                                case Value::eValueTypeHostAddress:
-                                    memcpy ((uint8_t*)target_addr, (uint8_t*)source_addr, byte_size);
-                                    break;
-                                default:
-                                    return false;
-                                }
-                            }
-                        }
-                        else
-                        {
-                            if (!ClangASTType::SetValueFromScalar (ast_context,
-                                                                  clang_type,
-                                                                  tmp.ResolveValue(exe_ctx, ast_context),
-                                                                  new_value))
-                            {
-                                if (error_ptr)
-                                    error_ptr->SetErrorStringWithFormat ("Couldn't extract a value from an integral type.\n");
-                                return false;
-                            }
-                                
-                            Value::ValueType value_type = stack.back().GetValueType();
-                            
-                            switch (value_type)
-                            {
-                            case Value::eValueTypeLoadAddress:
-                            case Value::eValueTypeHostAddress:
-                                {
-                                    AddressType address_type = (value_type == Value::eValueTypeLoadAddress ? eAddressTypeLoad : eAddressTypeHost);
-                                    lldb::addr_t addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
-                                    if (!ClangASTType::WriteToMemory (ast_context,
-                                                                          clang_type,
-                                                                          exe_ctx,
-                                                                          addr,
-                                                                          address_type,
-                                                                          new_value))
-                                    {
-                                        if (error_ptr)
-                                            error_ptr->SetErrorStringWithFormat ("Failed to write value to memory at 0x%" PRIx64 ".\n", addr);
-                                        return false;
-                                    }
-                                }
-                                break;
-
-                            default:
-                                break;
-                            }
-                        }
-                    }
-                    break;
-
-                default:
-                    if (error_ptr)
-                        error_ptr->SetErrorString ("Assign failed.");
-                    return false;
-                }
-            }
-            break;
-
-        //----------------------------------------------------------------------
-        // OPCODE: DW_OP_APPLE_address_of
-        // OPERANDS: none
-        // DESCRIPTION: Pops a value off of the stack and pushed its address.
-        // The top item on the stack must be a variable, or already be a memory
-        // location.
-        //----------------------------------------------------------------------
-        case DW_OP_APPLE_address_of:
-            if (stack.empty())
-            {
-                if (error_ptr)
-                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_APPLE_address_of.");
-                return false;
-            }
-            else
-            {
-                Value::ValueType value_type = stack.back().GetValueType();
-                switch (value_type)
-                {
-                default:
-                case Value::eValueTypeScalar:      // raw scalar value
-                    if (error_ptr)
-                        error_ptr->SetErrorString("Top stack item isn't a memory based object.");
-                    return false;
-
-                case Value::eValueTypeLoadAddress: // load address value
-                case Value::eValueTypeFileAddress: // file address value
-                case Value::eValueTypeHostAddress: // host address value (for memory in the process that is using liblldb)
-                    // Taking the address of an object reduces it to the address
-                    // of the value and removes any extra context it had.
-                    //stack.back().SetValueType(Value::eValueTypeScalar);
-                    stack.back().ClearContext();
-                    break;
-                }
-            }
-            break;
-
-        //----------------------------------------------------------------------
-        // OPCODE: DW_OP_APPLE_value_of
-        // OPERANDS: none
-        // DESCRIPTION: Pops a value off of the stack and pushed its value.
-        // The top item on the stack must be a variable, expression variable.
-        //----------------------------------------------------------------------
-        case DW_OP_APPLE_value_of:
-            if (stack.empty())
-            {
-                if (error_ptr)
-                    error_ptr->SetErrorString("Expression stack needs at least 1 items for DW_OP_APPLE_value_of.");
-                return false;
-            }
-            else if (!stack.back().ValueOf(exe_ctx, ast_context))
-            {
-                if (error_ptr)
-                    error_ptr->SetErrorString ("Top stack item isn't a valid candidate for DW_OP_APPLE_value_of.");
-                return false;
-            }
-            break;
-
-        //----------------------------------------------------------------------
-        // OPCODE: DW_OP_APPLE_deref_type
-        // OPERANDS: none
-        // DESCRIPTION: gets the value pointed to by the top stack item
-        //----------------------------------------------------------------------
-        case DW_OP_APPLE_deref_type:
-            {
-                if (stack.empty())
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorString("Expression stack needs at least 1 items for DW_OP_APPLE_deref_type.");
-                    return false;
-                }
-                    
-                tmp = stack.back();
-                stack.pop_back();
-                
-                if (tmp.GetContextType() != Value::eContextTypeClangType)
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorString("Item at top of expression stack must have a Clang type");
-                    return false;
-                }
-                    
-                void *ptr_type = tmp.GetClangType();
-                void *target_type;
-            
-                if (!ClangASTContext::IsPointerType(ptr_type, &target_type))
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorString("Dereferencing a non-pointer type");
-                    return false;
-                }
-                
-                // TODO do we want all pointers to be dereferenced as load addresses?
-                Value::ValueType value_type = tmp.GetValueType();
-                
-                tmp.ResolveValue(exe_ctx, ast_context);
-                
-                tmp.SetValueType(value_type);
-                tmp.SetContext(Value::eContextTypeClangType, target_type);
-                
-                stack.push_back(tmp);
-            }
-            break;
-
-        //----------------------------------------------------------------------
-        // OPCODE: DW_OP_APPLE_expr_local
-        // OPERANDS: ULEB128
-        // DESCRIPTION: pushes the expression local variable index onto the
-        // stack and set the appropriate context so we know the stack item is
-        // an expression local variable index.
-        //----------------------------------------------------------------------
-        case DW_OP_APPLE_expr_local:
-            {
-                /*
-                uint32_t idx = opcodes.GetULEB128(&offset);
-                if (expr_locals == NULL)
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_expr_local(%u) opcode encountered with no local variable list.\n", idx);
-                    return false;
-                }
-                Value *expr_local_variable = expr_locals->GetVariableAtIndex(idx);
-                if (expr_local_variable == NULL)
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_expr_local(%u) with invalid index %u.\n", idx, idx);
-                    return false;
-                }
-                 // The proxy code has been removed. If it is ever re-added, please
-                 // use shared pointers or return by value to avoid possible memory
-                 // leak (there is no leak here, but in general, no returning pointers
-                 // that must be manually freed please.
-                Value *proxy = expr_local_variable->CreateProxy();
-                stack.push_back(*proxy);
-                delete proxy;
-                //stack.back().SetContext (Value::eContextTypeClangType, expr_local_variable->GetClangType());
-                */
-            }
-            break;
-
-        //----------------------------------------------------------------------
-        // OPCODE: DW_OP_APPLE_extern
-        // OPERANDS: ULEB128
-        // DESCRIPTION: pushes a proxy for the extern object index onto the
-        // stack.
-        //----------------------------------------------------------------------
-        case DW_OP_APPLE_extern:
-            {
-                /*
-                uint32_t idx = opcodes.GetULEB128(&offset);
-                if (!decl_map)
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_extern(%u) opcode encountered with no decl map.\n", idx);
-                    return false;
-                }
-                Value *extern_var = decl_map->GetValueForIndex(idx);
-                if (!extern_var)
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_extern(%u) with invalid index %u.\n", idx, idx);
-                    return false;
-                }
-                // The proxy code has been removed. If it is ever re-added, please
-                // use shared pointers or return by value to avoid possible memory
-                // leak (there is no leak here, but in general, no returning pointers
-                // that must be manually freed please.
-                Value *proxy = extern_var->CreateProxy();
-                stack.push_back(*proxy);
-                delete proxy;
-                */
-            }
-            break;
-
-        case DW_OP_APPLE_scalar_cast:
-            if (stack.empty())
-            {
-                if (error_ptr)
-                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_APPLE_scalar_cast.");
-                return false;
-            }
-            else
-            {
-                // Simple scalar cast
-                if (!stack.back().ResolveValue(exe_ctx, ast_context).Cast((Scalar::Type)opcodes.GetU8(&offset)))
-                {
-                    if (error_ptr)
-                        error_ptr->SetErrorString("Cast failed.");
-                    return false;
-                }
-            }
-            break;
-
-
-        case DW_OP_APPLE_clang_cast:
-            if (stack.empty())
-            {
-                if (error_ptr)
-                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_APPLE_clang_cast.");
-                return false;
-            }
-            else
-            {
-                void *clang_type = (void *)opcodes.GetMaxU64(&offset, sizeof(void*));
-                stack.back().SetContext (Value::eContextTypeClangType, clang_type);
-            }
-            break;
-        //----------------------------------------------------------------------
-        // OPCODE: DW_OP_APPLE_constf
-        // OPERANDS: 1 byte float length, followed by that many bytes containing
-        // the constant float data.
-        // DESCRIPTION: Push a float value onto the expression stack.
-        //----------------------------------------------------------------------
-        case DW_OP_APPLE_constf:        // 0xF6 - 1 byte float size, followed by constant float data
-            {
-                uint8_t float_length = opcodes.GetU8(&offset);
-                if (sizeof(float) == float_length)
-                    tmp.ResolveValue(exe_ctx, ast_context) = opcodes.GetFloat (&offset);
-                else if (sizeof(double) == float_length)
-                    tmp.ResolveValue(exe_ctx, ast_context) = opcodes.GetDouble (&offset);
-                else if (sizeof(long double) == float_length)
-                    tmp.ResolveValue(exe_ctx, ast_context) = opcodes.GetLongDouble (&offset);
-                else
-                {
-                    StreamString new_value;
-                    opcodes.Dump(&new_value, offset, eFormatBytes, 1, float_length, UINT32_MAX, DW_INVALID_ADDRESS, 0, 0);
-
-                     if (error_ptr)
-                        error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_constf(<%u> %s) unsupported float size.\n", float_length, new_value.GetData());
-                    return false;
-               }
-               tmp.SetValueType(Value::eValueTypeScalar);
-               tmp.ClearContext();
-               stack.push_back(tmp);
-            }
-            break;
-        //----------------------------------------------------------------------
-        // OPCODE: DW_OP_APPLE_clear
-        // OPERANDS: none
-        // DESCRIPTION: Clears the expression stack.
-        //----------------------------------------------------------------------
-        case DW_OP_APPLE_clear:
-            stack.clear();
-            break;
-
-        //----------------------------------------------------------------------
-        // OPCODE: DW_OP_APPLE_error
-        // OPERANDS: none
-        // DESCRIPTION: Pops a value off of the stack and pushed its value.
-        // The top item on the stack must be a variable, expression variable.
-        //----------------------------------------------------------------------
-        case DW_OP_APPLE_error:         // 0xFF - Stops expression evaluation and returns an error (no args)
-            if (error_ptr)
-                error_ptr->SetErrorString ("Generic error.");
-            return false;
-#endif // #if 0
-                
         }
     }
 
diff --git a/source/Expression/IRForTarget.cpp b/source/Expression/IRForTarget.cpp
index 37b4240..7119434 100644
--- a/source/Expression/IRForTarget.cpp
+++ b/source/Expression/IRForTarget.cpp
@@ -33,6 +33,7 @@
 #include "lldb/Expression/IRInterpreter.h"
 #include "lldb/Host/Endian.h"
 #include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangASTType.h"
 
 #include <map>
 
@@ -130,7 +131,7 @@
 }
 
 static std::string
-PrintType(const Type *type, bool truncate = false)
+PrintType(const llvm::Type *type, bool truncate = false)
 {
     std::string s;
     raw_string_ostream rso(s);
@@ -565,7 +566,7 @@
                                                      &result_decl->getASTContext());
     }
     
-    if (m_result_type.GetClangTypeBitWidth() == 0)
+    if (m_result_type.GetBitSize() == 0)
     {
         lldb_private::StreamString type_desc_stream;
         m_result_type.DumpTypeDescription(&type_desc_stream);
@@ -592,7 +593,7 @@
     if (log)
         log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
                     m_result_name.GetCString(),
-                    m_result_type.GetClangTypeBitWidth() / 8);
+                    m_result_type.GetByteSize());
         
     // Construct a new result global and set up its metadata
     
@@ -1496,22 +1497,14 @@
         
         std::string name (named_decl->getName().str());
         
-        void *opaque_type = NULL;
-        clang::ASTContext *ast_context = NULL;
-        
-        if (clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl))
-        {
-            opaque_type = value_decl->getType().getAsOpaquePtr();
-            ast_context = &value_decl->getASTContext();
-        }
-        else
-        {
+        clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
+        if (value_decl == NULL)
             return false;
-        }
+
+        lldb_private::ClangASTType clang_type(&value_decl->getASTContext(), value_decl->getType());
         
-        clang::QualType qual_type;
         const Type *value_type = NULL;
-        
+
         if (name[0] == '$')
         {
             // The $__lldb_expr_result name indicates the the return value has allocated as
@@ -1523,26 +1516,26 @@
             // to the type of $__lldb_expr_result, not the type itself.
             //
             // We also do this for any user-declared persistent variables.
-            
-            qual_type = ast_context->getPointerType(clang::QualType::getFromOpaquePtr(opaque_type));
+            clang_type = clang_type.GetPointerType();
             value_type = PointerType::get(global_variable->getType(), 0);
         }
         else
         {
-            qual_type = clang::QualType::getFromOpaquePtr(opaque_type);
             value_type = global_variable->getType();
         }
-                
-        uint64_t value_size = (ast_context->getTypeSize(qual_type) + 7ull) / 8ull;
-        off_t value_alignment = (ast_context->getTypeAlign(qual_type) + 7ull) / 8ull;
+        
+        const uint64_t value_size = clang_type.GetByteSize();
+        off_t value_alignment = (clang_type.GetTypeBitAlign() + 7ull) / 8ull;
         
         if (log)
+        {
             log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRId64 "]",
                         name.c_str(), 
-                        qual_type.getAsString().c_str(), 
-                        PrintType(value_type).c_str(), 
+                        clang_type.GetQualType().getAsString().c_str(),
+                        PrintType(value_type).c_str(),
                         value_size, 
                         value_alignment);
+        }
         
         
         if (named_decl && !m_decl_map->AddValueToStruct(named_decl,
diff --git a/source/Expression/Materializer.cpp b/source/Expression/Materializer.cpp
index 52dfefd..6236eda 100644
--- a/source/Expression/Materializer.cpp
+++ b/source/Expression/Materializer.cpp
@@ -49,7 +49,7 @@
 void
 Materializer::Entity::SetSizeAndAlignmentFromType (ClangASTType &type)
 {
-    m_size = type.GetTypeByteSize();
+    m_size = type.GetByteSize();
     
     uint32_t bit_alignment = type.GetTypeBitAlign();
     
@@ -100,8 +100,7 @@
         // Put the location of the spare memory into the live data of the ValueObject.
                 
         m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope(),
-                                                                              m_persistent_variable_sp->GetTypeFromUser().GetASTContext(),
-                                                                              m_persistent_variable_sp->GetTypeFromUser().GetOpaqueQualType(),
+                                                                              m_persistent_variable_sp->GetTypeFromUser(),
                                                                               m_persistent_variable_sp->GetName(),
                                                                               mem,
                                                                               eAddressTypeLoad,
@@ -151,10 +150,12 @@
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
+        const lldb::addr_t load_addr = process_address + m_offset;
+    
         if (log)
         {
-            log->Printf("EntityPersistentVariable::Materialize [process_address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]",
-                        (uint64_t)process_address,
+            log->Printf("EntityPersistentVariable::Materialize [address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]",
+                        (uint64_t)load_addr,
                         m_persistent_variable_sp->GetName().AsCString(),
                         m_persistent_variable_sp->m_flags);
         }
@@ -173,7 +174,7 @@
         {
             Error write_error;
                         
-            map.WriteScalarToMemory(process_address + m_offset,
+            map.WriteScalarToMemory(load_addr,
                                     m_persistent_variable_sp->m_live_sp->GetValue().GetScalar(),
                                     map.GetAddressByteSize(),
                                     write_error);
@@ -190,15 +191,21 @@
         }
     }
     
-    void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
-                                lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
+    void Dematerialize (lldb::StackFrameSP &frame_sp,
+                        IRMemoryMap &map,
+                        lldb::addr_t process_address,
+                        lldb::addr_t frame_top,
+                        lldb::addr_t frame_bottom,
+                        Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
         
+        const lldb::addr_t load_addr = process_address + m_offset;
+
         if (log)
         {
-            log->Printf("EntityPersistentVariable::Dematerialize [process_address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]",
-                        (uint64_t)process_address,
+            log->Printf("EntityPersistentVariable::Dematerialize [address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]",
+                        (uint64_t)process_address + m_offset,
                         m_persistent_variable_sp->GetName().AsCString(),
                         m_persistent_variable_sp->m_flags);
         }
@@ -215,7 +222,7 @@
                 lldb::addr_t location;
                 Error read_error;
                 
-                map.ReadPointerFromMemory(&location, process_address + m_offset, read_error);
+                map.ReadPointerFromMemory(&location, load_addr, read_error);
                                 
                 if (!read_error.Success())
                 {
@@ -224,8 +231,7 @@
                 }
                                 
                 m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope (),
-                                                                                      m_persistent_variable_sp->GetTypeFromUser().GetASTContext(),
-                                                                                      m_persistent_variable_sp->GetTypeFromUser().GetOpaqueQualType(),
+                                                                                      m_persistent_variable_sp->GetTypeFromUser(),
                                                                                       m_persistent_variable_sp->GetName(),
                                                                                       location,
                                                                                       eAddressTypeLoad,
@@ -319,14 +325,16 @@
         
         Error err;
         
-        dump_stream.Printf("0x%" PRIx64 ": EntityPersistentVariable (%s)\n", process_address + m_offset, m_persistent_variable_sp->GetName().AsCString());
+        const lldb::addr_t load_addr = process_address + m_offset;
+
+        dump_stream.Printf("0x%" PRIx64 ": EntityPersistentVariable (%s)\n", load_addr, m_persistent_variable_sp->GetName().AsCString());
         
         {
             dump_stream.Printf("Pointer:\n");
             
             DataBufferHeap data (m_size, 0);
             
-            map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err);
+            map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
             
             if (!err.Success())
             {
@@ -336,7 +344,7 @@
             {
                 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                 
-                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
+                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
                 
                 dump_stream.PutChar('\n');
             }
@@ -347,7 +355,7 @@
             
             lldb::addr_t target_address;
             
-            map.ReadPointerFromMemory (&target_address, process_address + m_offset, err);
+            map.ReadPointerFromMemory (&target_address, load_addr, err);
                         
             if (!err.Success())
             {
@@ -407,17 +415,18 @@
         // Hard-coding to maximum size of a pointer since all variables are materialized by reference
         m_size = 8;
         m_alignment = 8;
-        m_is_reference = ClangASTContext::IsReferenceType(m_variable_sp->GetType()->GetClangForwardType());
+        m_is_reference = m_variable_sp->GetType()->GetClangForwardType().IsReferenceType();
     }
     
     void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
         
+        const lldb::addr_t load_addr = process_address + m_offset;
         if (log)
         {
-            log->Printf("EntityVariable::Materialize [process_address = 0x%" PRIx64 ", m_variable_sp = %s]",
-                        (uint64_t)process_address,
+            log->Printf("EntityVariable::Materialize [address = 0x%" PRIx64 ", m_variable_sp = %s]",
+                        (uint64_t)load_addr,
                         m_variable_sp->GetName().AsCString());
         }
         
@@ -442,7 +451,7 @@
             lldb::addr_t reference_addr = valobj_extractor.GetAddress(&offset);
             
             Error write_error;
-            map.WritePointerToMemory(process_address + m_offset, reference_addr, write_error);
+            map.WritePointerToMemory(load_addr, reference_addr, write_error);
             
             if (!write_error.Success())
             {
@@ -462,7 +471,7 @@
                 lldb::addr_t addr_of_valobj_addr = valobj_extractor.GetAddress(&offset);
                 
                 Error write_error;
-                map.WritePointerToMemory(process_address + m_offset, addr_of_valobj_addr, write_error);
+                map.WritePointerToMemory(load_addr, addr_of_valobj_addr, write_error);
                 
                 if (!write_error.Success())
                 {
@@ -494,7 +503,7 @@
                     return;
                 }
                 
-                size_t bit_align = ClangASTType::GetTypeBitAlign(m_variable_sp->GetType()->GetClangAST(), m_variable_sp->GetType()->GetClangLayoutType());
+                size_t bit_align = m_variable_sp->GetType()->GetClangLayoutType().GetTypeBitAlign();
                 size_t byte_align = (bit_align + 7) / 8;
                 
                 Error alloc_error;
@@ -520,7 +529,7 @@
                 
                 Error pointer_write_error;
                 
-                map.WritePointerToMemory(process_address + m_offset, m_temporary_allocation, pointer_write_error);
+                map.WritePointerToMemory(load_addr, m_temporary_allocation, pointer_write_error);
                 
                 if (!pointer_write_error.Success())
                 {
@@ -530,15 +539,20 @@
         }
     }
     
-    void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
-                        lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
+    void Dematerialize (lldb::StackFrameSP &frame_sp,
+                        IRMemoryMap &map,
+                        lldb::addr_t process_address,
+                        lldb::addr_t frame_top,
+                        lldb::addr_t frame_bottom,
+                        Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
+        const lldb::addr_t load_addr = process_address + m_offset;
         if (log)
         {
-            log->Printf("EntityVariable::Dematerialize [process_address = 0x%" PRIx64 ", m_variable_sp = %s]",
-                        (uint64_t)process_address,
+            log->Printf("EntityVariable::Dematerialize [address = 0x%" PRIx64 ", m_variable_sp = %s]",
+                        (uint64_t)load_addr,
                         m_variable_sp->GetName().AsCString());
         }
         
@@ -597,8 +611,9 @@
     void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log)
     {
         StreamString dump_stream;
-        
-        dump_stream.Printf("0x%" PRIx64 ": EntityVariable\n", process_address + m_offset);
+
+        const lldb::addr_t load_addr = process_address + m_offset;
+        dump_stream.Printf("0x%" PRIx64 ": EntityVariable\n", load_addr);
         
         Error err;
                 
@@ -609,7 +624,7 @@
             
             DataBufferHeap data (m_size, 0);
             
-            map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err);
+            map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
             
             if (!err.Success())
             {
@@ -619,7 +634,7 @@
             {
                 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                 
-                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
+                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
                 
                 lldb::offset_t offset;
                 
@@ -656,7 +671,7 @@
             {
                 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                 
-                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
+                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
                 
                 dump_stream.PutChar('\n');
             }
@@ -721,7 +736,9 @@
                 return;
             }
             
-            size_t byte_size = m_type.GetTypeByteSize();
+            const lldb::addr_t load_addr = process_address + m_offset;
+
+            size_t byte_size = m_type.GetByteSize();
             size_t bit_align = m_type.GetTypeBitAlign();
             size_t byte_align = (bit_align + 7) / 8;
             
@@ -738,7 +755,7 @@
                         
             Error pointer_write_error;
             
-            map.WritePointerToMemory(process_address + m_offset, m_temporary_allocation, pointer_write_error);
+            map.WritePointerToMemory(load_addr, m_temporary_allocation, pointer_write_error);
             
             if (!pointer_write_error.Success())
             {
@@ -747,15 +764,23 @@
         }
     }
     
-    void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
-                        lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
+    void Dematerialize (lldb::StackFrameSP &frame_sp,
+                        IRMemoryMap &map,
+                        lldb::addr_t process_address,
+                        lldb::addr_t frame_top,
+                        lldb::addr_t frame_bottom,
+                        Error &err)
     {
         err.SetErrorString("Tried to detmaterialize a result variable with the normal Dematerialize method");
     }
     
     void Dematerialize (lldb::ClangExpressionVariableSP &result_variable_sp,
-                        lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
-                        lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
+                        lldb::StackFrameSP &frame_sp,
+                        IRMemoryMap &map,
+                        lldb::addr_t process_address,
+                        lldb::addr_t frame_top,
+                        lldb::addr_t frame_bottom,
+                        Error &err)
     {
         err.Clear();
         
@@ -769,8 +794,9 @@
         
         lldb::addr_t address;
         Error read_error;
+        const lldb::addr_t load_addr = process_address + m_offset;
         
-        map.ReadPointerFromMemory (&address, process_address + m_offset, read_error);
+        map.ReadPointerFromMemory (&address, load_addr, read_error);
         
         if (!read_error.Success())
         {
@@ -809,8 +835,7 @@
         if (can_persist && m_keep_in_memory)
         {
             ret->m_live_sp = ValueObjectConstResult::Create(exe_scope,
-                                                            m_type.GetASTContext(),
-                                                            m_type.GetOpaqueQualType(),
+                                                            m_type,
                                                             name,
                                                             address,
                                                             eAddressTypeLoad,
@@ -854,8 +879,10 @@
     void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log)
     {
         StreamString dump_stream;
-                
-        dump_stream.Printf("0x%" PRIx64 ": EntityResultVariable\n", process_address + m_offset);
+        
+        const lldb::addr_t load_addr = process_address + m_offset;
+
+        dump_stream.Printf("0x%" PRIx64 ": EntityResultVariable\n", load_addr);
         
         Error err;
         
@@ -866,7 +893,7 @@
             
             DataBufferHeap data (m_size, 0);
             
-            map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err);
+            map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
             
             if (!err.Success())
             {
@@ -876,7 +903,7 @@
             {
                 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                 
-                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
+                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
                 
                 lldb::offset_t offset;
                 
@@ -913,7 +940,7 @@
             {
                 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                 
-                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
+                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
                 
                 dump_stream.PutChar('\n');
             }
@@ -970,10 +997,12 @@
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
+        const lldb::addr_t load_addr = process_address + m_offset;
+
         if (log)
         {
-            log->Printf("EntitySymbol::Materialize [process_address = 0x%" PRIx64 ", m_symbol = %s]",
-                        (uint64_t)process_address,
+            log->Printf("EntitySymbol::Materialize [address = 0x%" PRIx64 ", m_symbol = %s]",
+                        (uint64_t)load_addr,
                         m_symbol.GetName().AsCString());
         }
         
@@ -999,7 +1028,7 @@
         
         Error pointer_write_error;
         
-        map.WritePointerToMemory(process_address + m_offset, resolved_address, pointer_write_error);
+        map.WritePointerToMemory(load_addr, resolved_address, pointer_write_error);
         
         if (!pointer_write_error.Success())
         {
@@ -1008,15 +1037,21 @@
         }
     }
     
-    void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
-                                lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
+    void Dematerialize (lldb::StackFrameSP &frame_sp,
+                        IRMemoryMap &map,
+                        lldb::addr_t process_address,
+                        lldb::addr_t frame_top,
+                        lldb::addr_t frame_bottom,
+                        Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
+        const lldb::addr_t load_addr = process_address + m_offset;
+
         if (log)
         {
-            log->Printf("EntitySymbol::Dematerialize [process_address = 0x%" PRIx64 ", m_symbol = %s]",
-                        (uint64_t)process_address,
+            log->Printf("EntitySymbol::Dematerialize [address = 0x%" PRIx64 ", m_symbol = %s]",
+                        (uint64_t)load_addr,
                         m_symbol.GetName().AsCString());
         }
         
@@ -1029,14 +1064,16 @@
         
         Error err;
         
-        dump_stream.Printf("0x%" PRIx64 ": EntitySymbol (%s)\n", process_address + m_offset, m_symbol.GetName().AsCString());
+        const lldb::addr_t load_addr = process_address + m_offset;
+
+        dump_stream.Printf("0x%" PRIx64 ": EntitySymbol (%s)\n", load_addr, m_symbol.GetName().AsCString());
         
         {
             dump_stream.Printf("Pointer:\n");
             
             DataBufferHeap data (m_size, 0);
             
-            map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err);
+            map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
             
             if (!err.Success())
             {
@@ -1046,7 +1083,7 @@
             {
                 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                 
-                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
+                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
                 
                 dump_stream.PutChar('\n');
             }
@@ -1088,10 +1125,12 @@
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
         
+        const lldb::addr_t load_addr = process_address + m_offset;
+
         if (log)
         {
-            log->Printf("EntityRegister::Materialize [process_address = 0x%" PRIx64 ", m_register_info = %s]",
-                        (uint64_t)process_address,
+            log->Printf("EntityRegister::Materialize [address = 0x%" PRIx64 ", m_register_info = %s]",
+                        (uint64_t)load_addr,
                         m_register_info.name);
         }
 
@@ -1127,7 +1166,7 @@
         
         Error write_error;
         
-        map.WriteMemory(process_address + m_offset, register_data.GetDataStart(), register_data.GetByteSize(), write_error);
+        map.WriteMemory(load_addr, register_data.GetDataStart(), register_data.GetByteSize(), write_error);
         
         if (!write_error.Success())
         {
@@ -1136,15 +1175,21 @@
         }
     }
     
-    void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
-                                lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
+    void Dematerialize (lldb::StackFrameSP &frame_sp,
+                        IRMemoryMap &map,
+                        lldb::addr_t process_address,
+                        lldb::addr_t frame_top,
+                        lldb::addr_t frame_bottom,
+                        Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
         
+        const lldb::addr_t load_addr = process_address + m_offset;
+
         if (log)
         {
-            log->Printf("EntityRegister::Dematerialize [process_address = 0x%" PRIx64 ", m_register_info = %s]",
-                        (uint64_t)process_address,
+            log->Printf("EntityRegister::Dematerialize [address = 0x%" PRIx64 ", m_register_info = %s]",
+                        (uint64_t)load_addr,
                         m_register_info.name);
         }
         
@@ -1160,7 +1205,7 @@
         
         lldb::RegisterContextSP reg_context_sp = frame_sp->GetRegisterContext();
         
-        map.GetMemoryData(register_data, process_address + m_offset, m_register_info.byte_size, extract_error);
+        map.GetMemoryData(register_data, load_addr, m_register_info.byte_size, extract_error);
         
         if (!extract_error.Success())
         {
@@ -1183,14 +1228,17 @@
         
         Error err;
         
-        dump_stream.Printf("0x%" PRIx64 ": EntityRegister (%s)\n", process_address + m_offset, m_register_info.name);
+        const lldb::addr_t load_addr = process_address + m_offset;
+
+        
+        dump_stream.Printf("0x%" PRIx64 ": EntityRegister (%s)\n", load_addr, m_register_info.name);
         
         {
             dump_stream.Printf("Value:\n");
             
             DataBufferHeap data (m_size, 0);
             
-            map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err);
+            map.ReadMemory(data.GetBytes(), load_addr, m_size, err);
             
             if (!err.Success())
             {
@@ -1200,7 +1248,7 @@
             {
                 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                 
-                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
+                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr);
                 
                 dump_stream.PutChar('\n');
             }
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index bc63e59..4685c3e 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -318,8 +318,6 @@
     // For now, assume that the types in the AST values come from the Target's 
     // scratch AST.    
     
-    clang::ASTContext *ast_context = exe_ctx.GetTargetRef().GetScratchClangASTContext()->getASTContext();
-    
     // Extract the register context so we can read arguments from registers
     
     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
@@ -338,18 +336,18 @@
         if (!value)
             return false;
         
-        void *value_type = value->GetClangType();
-        if (value_type)
+        ClangASTType clang_type = value->GetClangType();
+        if (clang_type)
         {
             bool is_signed = false;
             size_t bit_width = 0;
-            if (ClangASTContext::IsIntegerType (value_type, is_signed))
+            if (clang_type.IsIntegerType (is_signed))
             {
-                bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+                bit_width = clang_type.GetBitSize();
             }
-            else if (ClangASTContext::IsPointerOrReferenceType (value_type))
+            else if (clang_type.IsPointerOrReferenceType ())
             {
-                bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+                bit_width = clang_type.GetBitSize();
             }
             else
             {
@@ -421,20 +419,20 @@
 
 ValueObjectSP
 ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread,
-                                         lldb_private::ClangASTType &ast_type) const
+                                         lldb_private::ClangASTType &clang_type) const
 {
     Value value;
     ValueObjectSP return_valobj_sp;
     
-    void *value_type = ast_type.GetOpaqueQualType();
-    if (!value_type) 
+    if (!clang_type)
         return return_valobj_sp;
     
-    clang::ASTContext *ast_context = ast_type.GetASTContext();
+    clang::ASTContext *ast_context = clang_type.GetASTContext();
     if (!ast_context)
         return return_valobj_sp;
 
-    value.SetContext (Value::eContextTypeClangType, value_type);
+    //value.SetContext (Value::eContextTypeClangType, clang_type.GetOpaqueQualType());
+    value.SetClangType (clang_type);
             
     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
     if (!reg_ctx)
@@ -446,9 +444,9 @@
     // when reading data
     
     const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
-    if (ClangASTContext::IsIntegerType (value_type, is_signed))
+    if (clang_type.IsIntegerType (is_signed))
     {
-        size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+        size_t bit_width = clang_type.GetBitSize();
         
         switch (bit_width)
         {
@@ -486,7 +484,7 @@
                 break;
         }
     }
-    else if (ClangASTContext::IsPointerType (value_type))
+    else if (clang_type.IsPointerType ())
     {
         uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
         value.GetScalar() = ptr;
@@ -499,11 +497,9 @@
     
     // If we get here, we have a valid Value, so make our ValueObject out of it:
     
-    return_valobj_sp = ValueObjectConstResult::Create(
-                                    thread.GetStackFrameAtIndex(0).get(),
-                                    ast_type.GetASTContext(),
-                                    value,
-                                    ConstString(""));
+    return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
+                                                      value,
+                                                      ConstString(""));
     return return_valobj_sp;
 }
 
@@ -517,19 +513,13 @@
         return error;
     }
     
-    clang_type_t value_type = new_value_sp->GetClangType();
-    if (!value_type)
+    ClangASTType clang_type = new_value_sp->GetClangType();
+    if (!clang_type)
     {
         error.SetErrorString ("Null clang type for return value.");
         return error;
     }
     
-    clang::ASTContext *ast_context = new_value_sp->GetClangAST();
-    if (!ast_context)
-    {
-        error.SetErrorString ("Null clang AST for return value.");
-        return error;
-    }
     Thread *thread = frame_sp->GetThread().get();
     
     bool is_signed;
@@ -539,7 +529,7 @@
     RegisterContext *reg_ctx = thread->GetRegisterContext().get();
 
     bool set_it_simple = false;
-    if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type))
+    if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
     {
         DataExtractor data;
         size_t num_bytes = new_value_sp->GetData(data);
@@ -573,7 +563,7 @@
             error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
         }
     }
-    else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex))
+    else if (clang_type.IsFloatingPointType (count, is_complex))
     {
         if (is_complex)
             error.SetErrorString ("We don't support returning complex values at present");
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index d2126bf..deb531d 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -510,16 +510,12 @@
             }
             break;
         case Value::eValueTypeHostAddress:
-            switch (val->GetContextType()) 
             {
-            default:
-                return false;
-            case Value::eContextTypeClangType:
+                ClangASTType clang_type (val->GetClangType());
+                if (clang_type)
                 {
-                    void *val_type = val->GetClangType();
-                    uint32_t cstr_length;
-                    
-                    if (ClangASTContext::IsCStringType (val_type, cstr_length))
+                    uint32_t cstr_length = 0;
+                    if (clang_type.IsCStringType (cstr_length))
                     {
                         const char *cstr = (const char*)val->GetScalar().ULongLong();
                         cstr_length = strlen(cstr);
@@ -616,11 +612,6 @@
     unsigned int num_values = values.GetSize();
     unsigned int value_index;
     
-    // Extract the Clang AST context from the PC so that we can figure out type
-    // sizes
-    
-    clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
-    
     // Get the pointer to the first stack argument so we have a place to start 
     // when reading data
     
@@ -647,35 +638,27 @@
         
         // We currently only support extracting values with Clang QualTypes.
         // Do we care about others?
-        switch (value->GetContextType())
+        ClangASTType clang_type (value->GetClangType());
+        if (clang_type)
         {
-            default:
-                return false;
-            case Value::eContextTypeClangType:
-                {
-                    void *value_type = value->GetClangType();
-                    bool is_signed;
-                    
-                    if (ClangASTContext::IsIntegerType (value_type, is_signed))
-                    {
-                        size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
-                        
-                        ReadIntegerArgument(value->GetScalar(),
-                                            bit_width, 
-                                            is_signed,
-                                            thread.GetProcess().get(), 
-                                            current_stack_argument);
-                    }
-                    else if (ClangASTContext::IsPointerType (value_type))
-                    {
-                        ReadIntegerArgument(value->GetScalar(),
-                                            32,
-                                            false,
-                                            thread.GetProcess().get(),
-                                            current_stack_argument);
-                    }
-                }
-                break;
+            bool is_signed;
+            
+            if (clang_type.IsIntegerType (is_signed))
+            {
+                ReadIntegerArgument(value->GetScalar(),
+                                    clang_type.GetBitSize(),
+                                    is_signed,
+                                    thread.GetProcess().get(), 
+                                    current_stack_argument);
+            }
+            else if (clang_type.IsPointerType())
+            {
+                ReadIntegerArgument(value->GetScalar(),
+                                    clang_type.GetBitSize(),
+                                    false,
+                                    thread.GetProcess().get(),
+                                    current_stack_argument);
+            }
         }
     }
     
@@ -692,19 +675,13 @@
         return error;
     }
     
-    clang_type_t value_type = new_value_sp->GetClangType();
-    if (!value_type)
+    ClangASTType clang_type = new_value_sp->GetClangType();
+    if (!clang_type)
     {
         error.SetErrorString ("Null clang type for return value.");
         return error;
     }
     
-    clang::ASTContext *ast_context = new_value_sp->GetClangAST();
-    if (!ast_context)
-    {
-        error.SetErrorString ("Null clang AST for return value.");
-        return error;
-    }
     Thread *thread = frame_sp->GetThread().get();
     
     bool is_signed;
@@ -714,7 +691,7 @@
     RegisterContext *reg_ctx = thread->GetRegisterContext().get();
 
     bool set_it_simple = false;
-    if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type))
+    if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
     {
         DataExtractor data;
         size_t num_bytes = new_value_sp->GetData(data);
@@ -748,7 +725,7 @@
             error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
         }
     }
-    else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex))
+    else if (clang_type.IsFloatingPointType (count, is_complex))
     {
         if (is_complex)
             error.SetErrorString ("We don't support returning complex values at present");
@@ -764,20 +741,16 @@
 
 ValueObjectSP
 ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread,
-                                ClangASTType &ast_type) const
+                                          ClangASTType &clang_type) const
 {
     Value value;
     ValueObjectSP return_valobj_sp;
     
-    void *value_type = ast_type.GetOpaqueQualType();
-    if (!value_type) 
+    if (!clang_type)
         return return_valobj_sp;
     
-    clang::ASTContext *ast_context = ast_type.GetASTContext();
-    if (!ast_context)
-        return return_valobj_sp;
-
-    value.SetContext (Value::eContextTypeClangType, value_type);
+    //value.SetContext (Value::eContextTypeClangType, clang_type.GetOpaqueQualType());
+    value.SetClangType (clang_type);
     
     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
         if (!reg_ctx)
@@ -785,9 +758,9 @@
         
     bool is_signed;
             
-    if (ClangASTContext::IsIntegerType (value_type, is_signed))
+    if (clang_type.IsIntegerType (is_signed))
     {
-        size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+        size_t bit_width = clang_type.GetBitSize();
         
         unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
         unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
@@ -827,7 +800,7 @@
                 break;
         }
     }
-    else if (ClangASTContext::IsPointerType (value_type))
+    else if (clang_type.IsPointerType ())
     {
         unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
         uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
@@ -841,11 +814,9 @@
     
     // If we get here, we have a valid Value, so make our ValueObject out of it:
     
-    return_valobj_sp = ValueObjectConstResult::Create(
-                                    thread.GetStackFrameAtIndex(0).get(),
-                                    ast_type.GetASTContext(),
-                                    value,
-                                    ConstString(""));
+    return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
+                                                      value,
+                                                      ConstString(""));
     return return_valobj_sp;
 }
 
diff --git a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
index a9b002c..1ff9124 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -313,14 +313,39 @@
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     if (log)
-        log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n  thread = %p\n  sp = 0x%" PRIx64 "\n  func_addr = 0x%" PRIx64 "\n  return_addr = 0x%" PRIx64 "\n  arg1_ptr = %p (0x%" PRIx64 ")\n  arg2_ptr = %p (0x%" PRIx64 ")\n  arg3_ptr = %p (0x%" PRIx64 ")\n)",
-                    (void*)&thread,
+    {
+        StreamString s;
+        s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
+                    thread.GetID(),
                     (uint64_t)sp,
                     (uint64_t)func_addr,
-                    (uint64_t)return_addr,
-                    arg1_ptr, arg1_ptr ? (uint64_t)*arg1_ptr : (uint64_t) 0,
-                    arg2_ptr, arg2_ptr ? (uint64_t)*arg2_ptr : (uint64_t) 0,
-                    arg3_ptr, arg3_ptr ? (uint64_t)*arg3_ptr : (uint64_t) 0);
+                    (uint64_t)return_addr);
+
+        if (arg1_ptr)
+        {
+            s.Printf (", arg1 = 0x%" PRIx64, (uint64_t)*arg1_ptr);
+            if (arg2_ptr)
+            {
+                s.Printf (", arg2 = 0x%" PRIx64, (uint64_t)*arg2_ptr);
+                if (arg3_ptr)
+                {
+                    s.Printf (", arg3 = 0x%" PRIx64, (uint64_t)*arg3_ptr);
+                    if (arg4_ptr)
+                    {
+                        s.Printf (", arg4 = 0x%" PRIx64, (uint64_t)*arg4_ptr);
+                        if (arg5_ptr)
+                        {
+                            s.Printf (", arg5 = 0x%" PRIx64, (uint64_t)*arg5_ptr);
+                            if (arg6_ptr)
+                                s.Printf (", arg6 = 0x%" PRIx64, (uint64_t)*arg6_ptr);
+                        }
+                    }
+                }
+            }
+        }
+        s.PutCString (")");
+        log->PutCString(s.GetString().c_str());
+    }
     
     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
     if (!reg_ctx)
@@ -461,12 +486,7 @@
 {
     unsigned int num_values = values.GetSize();
     unsigned int value_index;
-    
-    // For now, assume that the types in the AST values come from the Target's 
-    // scratch AST.    
-    
-    clang::ASTContext *ast = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
-    
+        
     // Extract the register context so we can read arguments from registers
     
     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
@@ -506,39 +526,30 @@
         
         // We currently only support extracting values with Clang QualTypes.
         // Do we care about others?
-        switch (value->GetContextType())
-        {
-        default:
+        ClangASTType clang_type = value->GetClangType();
+        if (!clang_type)
             return false;
-        case Value::eContextTypeClangType:
-            {
-                void *value_type = value->GetClangType();
-                bool is_signed;
-                
-                if (ClangASTContext::IsIntegerType (value_type, is_signed))
-                {
-                    size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, value_type);
-                    
-                    ReadIntegerArgument(value->GetScalar(),
-                                        bit_width, 
-                                        is_signed,
-                                        thread, 
-                                        argument_register_ids, 
-                                        current_argument_register,
-                                        current_stack_argument);
-                }
-                else if (ClangASTContext::IsPointerType (value_type))
-                {
-                    ReadIntegerArgument(value->GetScalar(),
-                                        64,
-                                        false,
-                                        thread,
-                                        argument_register_ids, 
-                                        current_argument_register,
-                                        current_stack_argument);
-                }
-            }
-            break;
+        bool is_signed;
+        
+        if (clang_type.IsIntegerType (is_signed))
+        {
+            ReadIntegerArgument(value->GetScalar(),
+                                clang_type.GetBitSize(),
+                                is_signed,
+                                thread, 
+                                argument_register_ids, 
+                                current_argument_register,
+                                current_stack_argument);
+        }
+        else if (clang_type.IsPointerType ())
+        {
+            ReadIntegerArgument(value->GetScalar(),
+                                clang_type.GetBitSize(),
+                                false,
+                                thread,
+                                argument_register_ids, 
+                                current_argument_register,
+                                current_stack_argument);
         }
     }
     
@@ -555,19 +566,13 @@
         return error;
     }
     
-    clang_type_t value_type = new_value_sp->GetClangType();
-    if (!value_type)
+    ClangASTType clang_type = new_value_sp->GetClangType();
+    if (!clang_type)
     {
         error.SetErrorString ("Null clang type for return value.");
         return error;
     }
     
-    clang::ASTContext *ast = new_value_sp->GetClangAST();
-    if (!ast)
-    {
-        error.SetErrorString ("Null clang AST for return value.");
-        return error;
-    }
     Thread *thread = frame_sp->GetThread().get();
     
     bool is_signed;
@@ -577,7 +582,7 @@
     RegisterContext *reg_ctx = thread->GetRegisterContext().get();
 
     bool set_it_simple = false;
-    if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type))
+    if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
     {
         const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
 
@@ -597,13 +602,13 @@
         }
 
     }
-    else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex))
+    else if (clang_type.IsFloatingPointType (count, is_complex))
     {
         if (is_complex)
             error.SetErrorString ("We don't support returning complex values at present");
         else
         {
-            size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, value_type);
+            size_t bit_width = clang_type.GetBitSize();
             if (bit_width <= 64)
             {
                 const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
@@ -640,38 +645,34 @@
 
 ValueObjectSP
 ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
-                                            ClangASTType &ast_type) const
+                                            ClangASTType &return_clang_type) const
 {
     ValueObjectSP return_valobj_sp;
     Value value;
     
-    clang_type_t return_value_type = ast_type.GetOpaqueQualType();
-    if (!return_value_type)
-        return return_valobj_sp;
-    
-    clang::ASTContext *ast = ast_type.GetASTContext();
-    if (!ast)
+    if (!return_clang_type)
         return return_valobj_sp;
 
-    value.SetContext (Value::eContextTypeClangType, return_value_type);
+    //value.SetContext (Value::eContextTypeClangType, return_value_type);
+    value.SetClangType (return_clang_type);
     
     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
     if (!reg_ctx)
         return return_valobj_sp;
     
-    const uint32_t type_flags = ClangASTContext::GetTypeInfo (return_value_type, ast, NULL);
-    if (type_flags & ClangASTContext::eTypeIsScalar)
+    const uint32_t type_flags = return_clang_type.GetTypeInfo ();
+    if (type_flags & ClangASTType::eTypeIsScalar)
     {
         value.SetValueType(Value::eValueTypeScalar);
 
         bool success = false;
-        if (type_flags & ClangASTContext::eTypeIsInteger)
+        if (type_flags & ClangASTType::eTypeIsInteger)
         {
             // Extract the register context so we can read arguments from registers
             
-            const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+            const size_t byte_size = return_clang_type.GetByteSize();
             uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
-            const bool is_signed = (type_flags & ClangASTContext::eTypeIsSigned) != 0;
+            const bool is_signed = (type_flags & ClangASTType::eTypeIsSigned) != 0;
             switch (byte_size)
             {
             default:
@@ -710,15 +711,15 @@
                 break;
             }
         }
-        else if (type_flags & ClangASTContext::eTypeIsFloat)
+        else if (type_flags & ClangASTType::eTypeIsFloat)
         {
-            if (type_flags & ClangASTContext::eTypeIsComplex)
+            if (type_flags & ClangASTType::eTypeIsComplex)
             {
                 // Don't handle complex yet.
             }
             else
             {
-                const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+                const size_t byte_size = return_clang_type.GetByteSize();
                 if (byte_size <= sizeof(long double))
                 {
                     const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
@@ -751,24 +752,22 @@
         
         if (success)
             return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
-                                                               ast_type.GetASTContext(),
                                                                value,
                                                                ConstString(""));
 
     }
-    else if (type_flags & ClangASTContext::eTypeIsPointer)
+    else if (type_flags & ClangASTType::eTypeIsPointer)
     {
         unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
         value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
         value.SetValueType(Value::eValueTypeScalar);
         return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
-                                                           ast_type.GetASTContext(),
                                                            value,
                                                            ConstString(""));
     }
-    else if (type_flags & ClangASTContext::eTypeIsVector)
+    else if (type_flags & ClangASTType::eTypeIsVector)
     {
-        const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+        const size_t byte_size = return_clang_type.GetByteSize();
         if (byte_size > 0)
         {
 
@@ -803,8 +802,7 @@
                                                     byte_order,
                                                     process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
                                 return_valobj_sp = ValueObjectConstResult::Create (&thread,
-                                                                                   ast,
-                                                                                   return_value_type,
+                                                                                   return_clang_type,
                                                                                    ConstString(""),
                                                                                    data);
                             }
@@ -819,29 +817,24 @@
 }
 
 ValueObjectSP
-ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type) const
+ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clang_type) const
 {
     ValueObjectSP return_valobj_sp;
+
+    if (!return_clang_type)
+        return return_valobj_sp;
     
     ExecutionContext exe_ctx (thread.shared_from_this());
-    return_valobj_sp = GetReturnValueObjectSimple(thread, ast_type);
+    return_valobj_sp = GetReturnValueObjectSimple(thread, return_clang_type);
     if (return_valobj_sp)
         return return_valobj_sp;
     
-    clang_type_t return_value_type = ast_type.GetOpaqueQualType();
-    if (!return_value_type)
-        return return_valobj_sp;
-    
-    clang::ASTContext *ast = ast_type.GetASTContext();
-    if (!ast)
-        return return_valobj_sp;
-        
     RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
     if (!reg_ctx_sp)
         return return_valobj_sp;
         
-    size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, return_value_type);
-    if (ClangASTContext::IsAggregateType(return_value_type))
+    const size_t bit_width = return_clang_type.GetBitSize();
+    if (return_clang_type.IsAggregateType())
     {
         Target *target = exe_ctx.GetTargetPtr();
         bool is_memory = true;
@@ -874,7 +867,7 @@
             uint32_t fp_bytes = 0;       // Tracks how much of the xmm registers we've consumed so far
             uint32_t integer_bytes = 0;  // Tracks how much of the rax/rds registers we've consumed so far
             
-            uint32_t num_children = ClangASTContext::GetNumFields (ast, return_value_type);
+            const uint32_t num_children = return_clang_type.GetNumFields ();
             
             // Since we are in the small struct regime, assume we are not in memory.
             is_memory = false;
@@ -887,8 +880,8 @@
                 bool is_complex;
                 uint32_t count;
                 
-                clang_type_t field_clang_type = ClangASTContext::GetFieldAtIndex (ast, return_value_type, idx, name, &field_bit_offset, NULL, NULL);
-                size_t field_bit_width = ClangASTType::GetClangTypeBitWidth(ast, field_clang_type);
+                ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
+                const size_t field_bit_width = field_clang_type.GetBitSize();
 
                 // If there are any unaligned fields, this is stored in memory.
                 if (field_bit_offset % field_bit_width != 0)
@@ -904,7 +897,7 @@
                 DataExtractor *copy_from_extractor = NULL;
                 uint32_t       copy_from_offset    = 0;
                 
-                if (ClangASTContext::IsIntegerType (field_clang_type, is_signed) || ClangASTContext::IsPointerType (field_clang_type))
+                if (field_clang_type.IsIntegerType (is_signed) || field_clang_type.IsPointerType ())
                 {
                     if (integer_bytes < 8)
                     {
@@ -937,7 +930,7 @@
                         return return_valobj_sp;
                     }
                 }
-                else if (ClangASTContext::IsFloatingPointType (field_clang_type, count, is_complex))
+                else if (field_clang_type.IsFloatingPointType (count, is_complex))
                 {
                     // Structs with long doubles are always passed in memory.
                     if (field_bit_width == 128)
@@ -970,14 +963,12 @@
                             else
                             {
                                 uint64_t next_field_bit_offset = 0;
-                                clang_type_t next_field_clang_type = ClangASTContext::GetFieldAtIndex (ast,
-                                                                                                       return_value_type,
-                                                                                                       idx + 1, 
-                                                                                                       name, 
-                                                                                                       &next_field_bit_offset,
-                                                                                                       NULL,
-                                                                                                       NULL);
-                                if (ClangASTContext::IsIntegerType (next_field_clang_type, is_signed))
+                                ClangASTType next_field_clang_type = return_clang_type.GetFieldAtIndex (idx + 1,
+                                                                                                        name,
+                                                                                                        &next_field_bit_offset,
+                                                                                                        NULL,
+                                                                                                        NULL);
+                                if (next_field_clang_type.IsIntegerType (is_signed))
                                     in_gpr = true;
                                 else
                                 {
@@ -996,14 +987,12 @@
                             else
                             {
                                 uint64_t prev_field_bit_offset = 0;
-                                clang_type_t prev_field_clang_type = ClangASTContext::GetFieldAtIndex (ast,
-                                                                                                       return_value_type,
-                                                                                                       idx - 1, 
-                                                                                                       name, 
-                                                                                                       &prev_field_bit_offset,
-                                                                                                       NULL,
-                                                                                                       NULL);
-                                if (ClangASTContext::IsIntegerType (prev_field_clang_type, is_signed))
+                                ClangASTType prev_field_clang_type = return_clang_type.GetFieldAtIndex (idx - 1,
+                                                                                                        name,
+                                                                                                        &prev_field_bit_offset,
+                                                                                                        NULL,
+                                                                                                        NULL);
+                                if (prev_field_clang_type.IsIntegerType (is_signed))
                                     in_gpr = true;
                                 else
                                 {
@@ -1067,8 +1056,7 @@
             {
                 // The result is in our data buffer.  Let's make a variable object out of it:
                 return_valobj_sp = ValueObjectConstResult::Create (&thread, 
-                                                                   ast,
-                                                                   return_value_type,
+                                                                   return_clang_type,
                                                                    ConstString(""),
                                                                    return_ext);
             }
@@ -1087,7 +1075,7 @@
             return_valobj_sp = ValueObjectMemory::Create (&thread,
                                                           "",
                                                           Address (storage_addr, NULL),
-                                                          ast_type); 
+                                                          return_clang_type); 
         }
     }
         
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index b7375d8..df83b4d 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -625,13 +625,15 @@
         ValueList argument_values;
         Value input_value;
         
-        void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
-        void *clang_uint32_type   = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
+        ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+        ClangASTType clang_uint32_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
         input_value.SetValueType (Value::eValueTypeScalar);
-        input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type);
-        argument_values.PushValue(input_value);
-        argument_values.PushValue(input_value);
-        input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
+        input_value.SetClangType (clang_uint32_type);
+//        input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type);
+        argument_values.PushValue (input_value);
+        argument_values.PushValue (input_value);
+        input_value.SetClangType (clang_void_ptr_type);
+        //        input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
         argument_values.PushValue (input_value);
         
         if (abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values))
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 8a0d218..247d7b0 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -37,9 +37,9 @@
 bool
 ItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value)
 {
-    return ClangASTContext::IsPossibleDynamicType(in_value.GetClangAST(), in_value.GetClangType(), NULL,
-                                                  true, // check for C++
-                                                  false); // do not check for ObjC
+    const bool check_cxx = true;
+    const bool check_objc = false;
+    return in_value.GetClangType().IsPossibleDynamicType (NULL, check_cxx, check_objc);
 }
 
 bool
@@ -188,7 +188,7 @@
                                 type_sp = class_types.GetTypeAtIndex(i);
                                 if (type_sp)
                                 {
-                                    if (ClangASTContext::IsCXXClassType(type_sp->GetClangFullType()))
+                                    if (type_sp->GetClangFullType().IsCXXClassType())
                                     {
                                         if (log)
                                             log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, picking this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
@@ -220,18 +220,12 @@
                         // the value we were handed.
                         if (type_sp)
                         {
-                            clang::ASTContext *in_ast_ctx = in_value.GetClangAST ();
-                            clang::ASTContext *this_ast_ctx = type_sp->GetClangAST ();
-                            if (in_ast_ctx == this_ast_ctx)
+                            if (ClangASTContext::AreTypesSame (in_value.GetClangType(),
+                                                               type_sp->GetClangFullType()))
                             {
-                                if (ClangASTContext::AreTypesSame (in_ast_ctx,
-                                                                   in_value.GetClangType(),
-                                                                   type_sp->GetClangFullType()))
-                                {
-                                    // The dynamic type we found was the same type,
-                                    // so we don't have a dynamic type here...
-                                    return false;
-                                }
+                                // The dynamic type we found was the same type,
+                                // so we don't have a dynamic type here...
+                                return false;
                             }
 
                             // The offset_to_top is two pointers above the address.
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 1f3f4e0..b21d76c 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -81,10 +81,10 @@
         return false;
     
     Target *target = exe_ctx.GetTargetPtr();
-    if (value.GetClangType())
+    ClangASTType clang_type = value.GetClangType();
+    if (clang_type)
     {
-        clang::QualType value_type = clang::QualType::getFromOpaquePtr (value.GetClangType());
-        if (!value_type->isObjCObjectPointerType())
+        if (!clang_type.IsObjCObjectPointerType())
         {
             strm.Printf ("Value doesn't point to an ObjC object.\n");
             return false;
@@ -94,10 +94,11 @@
     {
         // If it is not a pointer, see if we can make it into a pointer.
         ClangASTContext *ast_context = target->GetScratchClangASTContext();
-        void *opaque_type_ptr = ast_context->GetBuiltInType_objc_id();
-        if (opaque_type_ptr == NULL)
-            opaque_type_ptr = ast_context->GetVoidPtrType(false);
-        value.SetContext(Value::eContextTypeClangType, opaque_type_ptr);    
+        ClangASTType opaque_type = ast_context->GetBasicType(eBasicTypeObjCID);
+        if (!opaque_type)
+            opaque_type = ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+        //value.SetContext(Value::eContextTypeClangType, opaque_type_ptr);
+        value.SetClangType (opaque_type);
     }
 
     ValueList arg_value_list;
@@ -106,9 +107,10 @@
     // This is the return value:
     ClangASTContext *ast_context = target->GetScratchClangASTContext();
     
-    void *return_qualtype = ast_context->GetCStringType(true);
+    ClangASTType return_clang_type = ast_context->GetCStringType(true);
     Value ret;
-    ret.SetContext(Value::eContextTypeClangType, return_qualtype);
+//    ret.SetContext(Value::eContextTypeClangType, return_clang_type);
+    ret.SetClangType (return_clang_type);
     
     if (exe_ctx.GetFramePtr() == NULL)
     {
@@ -126,8 +128,7 @@
     
     // Now we're ready to call the function:
     ClangFunction func (*exe_ctx.GetBestExecutionContextScope(),
-                        ast_context, 
-                        return_qualtype, 
+                        return_clang_type, 
                         *function_address, 
                         arg_value_list);
 
@@ -221,10 +222,9 @@
 bool
 AppleObjCRuntime::CouldHaveDynamicValue (ValueObject &in_value)
 {
-    return ClangASTContext::IsPossibleDynamicType(in_value.GetClangAST(), in_value.GetClangType(),
-                                                  NULL,
-                                                  false, // do not check C++
-                                                  true); // check ObjC
+    return in_value.GetClangType().IsPossibleDynamicType (NULL,
+                                                          false, // do not check C++
+                                                          true); // check ObjC
 }
 
 bool
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 6d3d4fd..16ffe0b 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -178,13 +178,14 @@
 //ObjCLanguageRuntime::ObjCISA
 //AppleObjCRuntimeV1::GetISA(ValueObject& valobj)
 //{
-////    if (ClangASTType::GetMinimumLanguage(valobj.GetClangAST(),valobj.GetClangType()) != eLanguageTypeObjC)
+//    ClangASTType valobj_clang_type = valobj.GetClangType();
+////    if (valobj_clang_type.GetMinimumLanguage() != eLanguageTypeObjC)
 ////        return 0;
 //    
 //    // if we get an invalid VO (which might still happen when playing around
 //    // with pointers returned by the expression parser, don't consider this
 //    // a valid ObjC object)
-//    if (valobj.GetValue().GetContextType() == Value::eContextTypeInvalid)
+//    if (!valobj.GetClangType().IsValid())
 //        return 0;
 //    
 //    addr_t isa_pointer = valobj.GetPointerValue();
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 683645a..23a0e23 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -1613,7 +1613,7 @@
     // if we get an invalid VO (which might still happen when playing around
     // with pointers returned by the expression parser, don't consider this
     // a valid ObjC object)
-    if (valobj.GetValue().GetContextType() != Value::eContextTypeInvalid)
+    if (valobj.GetClangType().IsValid())
     {
         addr_t isa_pointer = valobj.GetPointerValue();
         
@@ -1719,8 +1719,8 @@
     }
     
     // Make some types for our arguments
-    clang_type_t clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
-    clang_type_t clang_void_pointer_type = ast->CreatePointerType(ast->GetBuiltInType_void());
+    ClangASTType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+    ClangASTType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
     
     if (!m_get_class_info_code.get())
     {
@@ -1749,19 +1749,17 @@
     {
         Value value;
         value.SetValueType (Value::eValueTypeScalar);
-        value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+//        value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+        value.SetClangType (clang_void_pointer_type);
+        arguments.PushValue (value);
         arguments.PushValue (value);
         
         value.SetValueType (Value::eValueTypeScalar);
-        value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
-        arguments.PushValue (value);
-        
-        value.SetValueType (Value::eValueTypeScalar);
-        value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+//        value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+        value.SetClangType (clang_uint32_t_type);
         arguments.PushValue (value);
         
         m_get_class_info_function.reset(new ClangFunction (*m_process,
-                                                           ast,
                                                            clang_uint32_t_type,
                                                            function_address,
                                                            arguments));
@@ -1827,7 +1825,8 @@
         
         Value return_value;
         return_value.SetValueType (Value::eValueTypeScalar);
-        return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+        //return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+        return_value.SetClangType (clang_uint32_t_type);
         return_value.GetScalar() = 0;
         
         errors.Clear();
@@ -1971,8 +1970,8 @@
     }
     
     // Make some types for our arguments
-    clang_type_t clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
-    clang_type_t clang_void_pointer_type = ast->CreatePointerType(ast->GetBuiltInType_void());
+    ClangASTType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+    ClangASTType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
     
     if (!m_get_shared_cache_class_info_code.get())
     {
@@ -2001,19 +2000,17 @@
     {
         Value value;
         value.SetValueType (Value::eValueTypeScalar);
-        value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+        //value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+        value.SetClangType (clang_void_pointer_type);
+        arguments.PushValue (value);
         arguments.PushValue (value);
         
         value.SetValueType (Value::eValueTypeScalar);
-        value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
-        arguments.PushValue (value);
-        
-        value.SetValueType (Value::eValueTypeScalar);
-        value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+        //value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+        value.SetClangType (clang_uint32_t_type);
         arguments.PushValue (value);
         
         m_get_shared_cache_class_info_function.reset(new ClangFunction (*m_process,
-                                                                        ast,
                                                                         clang_uint32_t_type,
                                                                         function_address,
                                                                         arguments));
@@ -2079,7 +2076,8 @@
         
         Value return_value;
         return_value.SetValueType (Value::eValueTypeScalar);
-        return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+        //return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+        return_value.SetClangType (clang_uint32_t_type);
         return_value.GetScalar() = 0;
         
         errors.Clear();
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index a76326e..b7c5df2 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -512,9 +512,11 @@
         ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
         ValueList argument_values;
         Value input_value;
-        void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+        ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+
         input_value.SetValueType (Value::eValueTypeScalar);
-        input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
+        //input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
+        input_value.SetClangType (clang_void_ptr_type);
         argument_values.PushValue(input_value);
         
         bool success = abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values);
@@ -525,7 +527,6 @@
         Error error;
         DataExtractor data;
         error = argument_values.GetValueAtIndex(0)->GetValueAsData (&exe_ctx, 
-                                                                    clang_ast_context->getASTContext(), 
                                                                     data, 
                                                                     0,
                                                                     NULL);
@@ -783,13 +784,12 @@
         // Next make the runner function for our implementation utility function.
         if (!m_impl_function.get())
         {
-             ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
-            lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
-             m_impl_function.reset(new ClangFunction (thread,
-                                                      clang_ast_context, 
-                                                      clang_void_ptr_type, 
-                                                      impl_code_address, 
-                                                      dispatch_values));
+            ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+            ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+            m_impl_function.reset(new ClangFunction (thread,
+                                                     clang_void_ptr_type,
+                                                     impl_code_address,
+                                                     dispatch_values));
             
             errors.Clear();        
             unsigned num_errors = m_impl_function->CompileFunction(errors);
@@ -887,9 +887,10 @@
         ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
         ValueList argument_values;
         Value void_ptr_value;
-        lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+        ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
         void_ptr_value.SetValueType (Value::eValueTypeScalar);
-        void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
+        //void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
+        void_ptr_value.SetClangType (clang_void_ptr_type);
         
         int obj_index;
         int sel_index;
@@ -949,14 +950,14 @@
                
                 Value super_value(*(argument_values.GetValueAtIndex(obj_index)));
                 super_value.GetScalar() += process->GetAddressByteSize();
-                super_value.ResolveValue (&exe_ctx, clang_ast_context->getASTContext());
+                super_value.ResolveValue (&exe_ctx);
                 
                 if (super_value.GetScalar().IsValid())
                 {
                 
                     // isa_value now holds the class pointer.  The second word of the class pointer is the super-class pointer:
                     super_value.GetScalar() += process->GetAddressByteSize();
-                    super_value.ResolveValue (&exe_ctx, clang_ast_context->getASTContext());
+                    super_value.ResolveValue (&exe_ctx);
                     if (super_value.GetScalar().IsValid())
                         isa_addr = super_value.GetScalar().ULongLong();
                     else
@@ -979,7 +980,7 @@
                
                 Value super_value(*(argument_values.GetValueAtIndex(obj_index)));
                 super_value.GetScalar() += process->GetAddressByteSize();
-                super_value.ResolveValue (&exe_ctx, clang_ast_context->getASTContext());
+                super_value.ResolveValue (&exe_ctx);
                 
                 if (super_value.GetScalar().IsValid())
                 {
@@ -1006,7 +1007,7 @@
             Value isa_value(*(argument_values.GetValueAtIndex(obj_index)));
 
             isa_value.SetValueType(Value::eValueTypeLoadAddress);
-            isa_value.ResolveValue(&exe_ctx, clang_ast_context->getASTContext());
+            isa_value.ResolveValue(&exe_ctx);
             if (isa_value.GetScalar().IsValid())
             {
                 isa_addr = isa_value.GetScalar().ULongLong();
@@ -1068,10 +1069,10 @@
             dispatch_values.PushValue (*(argument_values.GetValueAtIndex(sel_index)));
             
             Value flag_value;
-            lldb::clang_type_t clang_int_type 
-                    = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32);
+            ClangASTType clang_int_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32);
             flag_value.SetValueType (Value::eValueTypeScalar);
-            flag_value.SetContext (Value::eContextTypeClangType, clang_int_type);
+            //flag_value.SetContext (Value::eContextTypeClangType, clang_int_type);
+            flag_value.SetClangType (clang_int_type);
             
             if (this_dispatch.stret_return)
                 flag_value.GetScalar() = 1;
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index ba1d3b6..499d6d7 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -76,11 +76,11 @@
             if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
             {
                 ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
-                lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+                ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
                 ThreadPlanCallFunction *call_function_thread_plan
                   = new ThreadPlanCallFunction (*thread,
                                                 mmap_range.GetBaseAddress(),
-                                                ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type),
+                                                clang_void_ptr_type,
                                                 stop_other_threads,
                                                 unwind_on_error,
                                                 ignore_breakpoints,
@@ -222,11 +222,11 @@
     const uint32_t timeout_usec = 500000;
 
     ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
-    lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+    ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
     ThreadPlanCallFunction *call_function_thread_plan
         = new ThreadPlanCallFunction (*thread,
                                       *address,
-                                      ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type),
+                                      clang_void_ptr_type,
                                       stop_other_threads,
                                       unwind_on_error,
                                       ignore_breakpoints);
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 84343b9..4d60cf0 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -1179,7 +1179,7 @@
         dwarfexpr.SetRegisterKind (unwindplan_registerkind);
         Value result;
         Error error;
-        if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, NULL, this, 0, NULL, result, &error))
+        if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, this, 0, NULL, result, &error))
         {
             addr_t val;
             val = result.GetScalar().ULongLong();
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index fa2d058..b8d73d4 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -407,11 +407,11 @@
 //        });
 //    }
     
-    std::set<clang_type_t> clang_type_set;
+    std::set<ClangASTType> clang_type_set;
     size_t num_types_added = 0;
     for (Type *type : type_set)
     {
-        clang_type_t clang_type = type->GetClangForwardType();
+        ClangASTType clang_type = type->GetClangForwardType();
         if (clang_type_set.find(clang_type) == clang_type_set.end())
         {
             clang_type_set.insert(clang_type);
@@ -1424,7 +1424,7 @@
                                                               attributes);
             const char *name = NULL;
             Type *lldb_type = NULL;
-            clang_type_t clang_type = NULL;
+            ClangASTType clang_type;
             uint64_t uval64 = 0;
             bool uval64_valid = false;
             if (num_attributes > 0)
@@ -1465,7 +1465,7 @@
                 
                 clang::ASTContext *ast = GetClangASTContext().getASTContext();
                 if (!clang_type)
-                    clang_type = ast->VoidTy.getAsOpaquePtr();
+                    clang_type = GetClangASTContext().GetBasicType(eBasicTypeVoid);
 
                 if (clang_type)
                 {
@@ -1475,20 +1475,19 @@
                     else
                         template_param_infos.names.push_back(NULL);
     
-                    clang::QualType clang_qual_type (clang::QualType::getFromOpaquePtr (clang_type));
                     if (tag == DW_TAG_template_value_parameter &&
                         lldb_type != NULL &&
-                        ClangASTContext::IsIntegerType (clang_type, is_signed) &&
+                        clang_type.IsIntegerType (is_signed) &&
                         uval64_valid)
                     {
                         llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
                         template_param_infos.args.push_back (clang::TemplateArgument (*ast,
                                                                                       llvm::APSInt(apint),
-                                                                                      clang_qual_type));
+                                                                                      clang_type.GetQualType()));
                     }
                     else
                     {
-                        template_param_infos.args.push_back (clang::TemplateArgument (clang_qual_type));
+                        template_param_infos.args.push_back (clang::TemplateArgument (clang_type.GetQualType()));
                     }
                 }
                 else
@@ -1565,17 +1564,15 @@
 public:
     DelayedAddObjCClassProperty
     (
-        clang::ASTContext      *ast,
-        lldb::clang_type_t      class_opaque_type, 
+        const ClangASTType     &class_opaque_type,
         const char             *property_name,
-        lldb::clang_type_t      property_opaque_type,  // The property type is only required if you don't have an ivar decl
+        const ClangASTType     &property_opaque_type,  // The property type is only required if you don't have an ivar decl
         clang::ObjCIvarDecl    *ivar_decl,   
         const char             *property_setter_name,
         const char             *property_getter_name,
         uint32_t                property_attributes,
         const ClangASTMetadata *metadata
     ) :
-        m_ast                   (ast),
         m_class_opaque_type     (class_opaque_type),
         m_property_name         (property_name),
         m_property_opaque_type  (property_opaque_type),
@@ -1593,12 +1590,11 @@
     
     DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs)
     {
-      *this = rhs;
+        *this = rhs;
     }
 
     DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs)
     {
-        m_ast                  = rhs.m_ast;
         m_class_opaque_type    = rhs.m_class_opaque_type;
         m_property_name        = rhs.m_property_name;
         m_property_opaque_type = rhs.m_property_opaque_type;
@@ -1615,23 +1611,21 @@
         return *this;
     }
     
-    bool Finalize() const
+    bool
+    Finalize()
     {
-        return ClangASTContext::AddObjCClassProperty (m_ast,
-                                                      m_class_opaque_type,
-                                                      m_property_name,
-                                                      m_property_opaque_type,
-                                                      m_ivar_decl,
-                                                      m_property_setter_name,
-                                                      m_property_getter_name,
-                                                      m_property_attributes,
-                                                      m_metadata_ap.get());
+        return m_class_opaque_type.AddObjCClassProperty (m_property_name,
+                                                         m_property_opaque_type,
+                                                         m_ivar_decl,
+                                                         m_property_setter_name,
+                                                         m_property_getter_name,
+                                                         m_property_attributes,
+                                                         m_metadata_ap.get());
     }
 private:
-    clang::ASTContext      *m_ast;
-    lldb::clang_type_t      m_class_opaque_type;
+    ClangASTType            m_class_opaque_type;
     const char             *m_property_name;
-    lldb::clang_type_t      m_property_opaque_type;
+    ClangASTType            m_property_opaque_type;
     clang::ObjCIvarDecl    *m_ivar_decl;
     const char             *m_property_setter_name;
     const char             *m_property_getter_name;
@@ -1693,7 +1687,7 @@
     const SymbolContext& sc,
     DWARFCompileUnit* dwarf_cu,
     const DWARFDebugInfoEntry *parent_die,
-    clang_type_t class_clang_type,
+    ClangASTType &class_clang_type,
     const LanguageType class_language,
     std::vector<clang::CXXBaseSpecifier *>& base_classes,
     std::vector<int>& member_accessibilities,
@@ -1772,7 +1766,6 @@
                                     uint32_t block_length = form_value.Unsigned();
                                     uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
                                     if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
-                                                                  NULL, // clang::ASTContext *
                                                                   NULL, // ClangExpressionVariableList *
                                                                   NULL, // ClangExpressionDeclMap *
                                                                   NULL, // RegisterContext *
@@ -1784,7 +1777,7 @@
                                                                   memberOffset, 
                                                                   NULL))
                                     {
-                                        member_byte_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
+                                        member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
                                     }
                                 }
                                 break;
@@ -1891,10 +1884,9 @@
 
                         if (var_type)
                         {
-                            GetClangASTContext().AddVariableToRecordType (class_clang_type,
-                                                                          name,
-                                                                          var_type->GetClangLayoutType(),
-                                                                          accessibility);
+                            class_clang_type.AddVariableToRecordType (name,
+                                                                      var_type->GetClangLayoutType(),
+                                                                      accessibility);
                         }
                         break;
                     }
@@ -2008,32 +2000,30 @@
                                         
                                         if (anon_field_info.IsValid())
                                         {
-                                            clang::FieldDecl *unnamed_bitfield_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
-                                                                                                                                 NULL,
-                                                                                                                                 GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
-                                                                                                                                 accessibility,
-                                                                                                                                 anon_field_info.bit_size);
+                                            clang::FieldDecl *unnamed_bitfield_decl = class_clang_type.AddFieldToRecordType (NULL,
+                                                                                                                             GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
+                                                                                                                             accessibility,
+                                                                                                                             anon_field_info.bit_size);
                                             
                                             layout_info.field_offsets.insert(std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset));
                                         }
                                     }
                                 }
                                 
-                                clang_type_t member_clang_type = member_type->GetClangLayoutType();
+                                ClangASTType member_clang_type = member_type->GetClangLayoutType();
                                 
                                 {
                                     // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
                                     // If the current field is at the end of the structure, then there is definitely no room for extra
                                     // elements and we override the type to array[0].
                                     
-                                    clang_type_t member_array_element_type;
+                                    ClangASTType member_array_element_type;
                                     uint64_t member_array_size;
                                     bool member_array_is_incomplete;
                                     
-                                    if (GetClangASTContext().IsArrayType(member_clang_type,
-                                                                         &member_array_element_type,
-                                                                         &member_array_size,
-                                                                         &member_array_is_incomplete) &&
+                                    if (member_clang_type.IsArrayType(&member_array_element_type,
+                                                                      &member_array_size,
+                                                                      &member_array_is_incomplete) &&
                                         !member_array_is_incomplete)
                                     {
                                         uint64_t parent_byte_size = parent_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, UINT64_MAX);
@@ -2054,11 +2044,10 @@
                                     }
                                 }
                                 
-                                field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
-                                                                                        name, 
-                                                                                        member_clang_type,
-                                                                                        accessibility, 
-                                                                                        bit_size);
+                                field_decl = class_clang_type.AddFieldToRecordType (name,
+                                                                                    member_clang_type,
+                                                                                    accessibility,
+                                                                                    bit_size);
                                 
                                 GetClangASTContext().SetMetadataAsUserID (field_decl, MakeUserID(die->GetOffset()));
                                 
@@ -2094,8 +2083,7 @@
                             
                             ClangASTMetadata metadata;
                             metadata.SetUserID (MakeUserID(die->GetOffset()));
-                            delayed_properties.push_back(DelayedAddObjCClassProperty(GetClangASTContext().getASTContext(),
-                                                                                     class_clang_type,
+                            delayed_properties.push_back(DelayedAddObjCClassProperty(class_clang_type,
                                                                                      prop_name,
                                                                                      member_type->GetClangLayoutType(),
                                                                                      ivar_decl,
@@ -2162,7 +2150,6 @@
                                     if (DWARFExpression::Evaluate (NULL, 
                                                                    NULL, 
                                                                    NULL, 
-                                                                   NULL, 
                                                                    NULL,
                                                                    debug_info_data, 
                                                                    block_offset, 
@@ -2172,7 +2159,7 @@
                                                                    memberOffset, 
                                                                    NULL))
                                     {
-                                        member_byte_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
+                                        member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
                                     }
                                 }
                                 break;
@@ -2192,27 +2179,26 @@
                     Type *base_class_type = ResolveTypeUID(encoding_uid);
                     assert(base_class_type);
                     
-                    clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
+                    ClangASTType base_class_clang_type = base_class_type->GetClangFullType();
                     assert (base_class_clang_type);
                     if (class_language == eLanguageTypeObjC)
                     {
-                        GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
+                        class_clang_type.SetObjCSuperClass(base_class_clang_type);
                     }
                     else
                     {
-                        base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type, 
-                                                                                               accessibility, 
+                        base_classes.push_back (base_class_clang_type.CreateBaseClassSpecifier (accessibility,
                                                                                                is_virtual, 
                                                                                                is_base_of_class));
                         
                         if (is_virtual)
                         {
-                            layout_info.vbase_offsets.insert(std::make_pair(ClangASTType::GetAsCXXRecordDecl(class_clang_type),
+                            layout_info.vbase_offsets.insert(std::make_pair(class_clang_type.GetAsCXXRecordDecl(),
                                                                             clang::CharUnits::fromQuantity(member_byte_offset)));
                         }
                         else
                         {
-                            layout_info.base_offsets.insert(std::make_pair(ClangASTType::GetAsCXXRecordDecl(class_clang_type),
+                            layout_info.base_offsets.insert(std::make_pair(class_clang_type.GetAsCXXRecordDecl(),
                                                                            clang::CharUnits::fromQuantity(member_byte_offset)));
                         }
                     }
@@ -2331,35 +2317,35 @@
 // SymbolFileDWARF objects to detect if this DWARF file is the one that
 // can resolve a clang_type.
 bool
-SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
+SymbolFileDWARF::HasForwardDeclForClangType (const ClangASTType &clang_type)
 {
-    clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
-    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
+    ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
+    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
     return die != NULL;
 }
 
 
-lldb::clang_type_t
-SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
+bool
+SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type)
 {
     // We have a struct/union/class/enum that needs to be fully resolved.
-    clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
-    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
+    ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
+    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
     if (die == NULL)
     {
         // We have already resolved this type...
-        return clang_type;
+        return true;
     }
     // Once we start resolving this type, remove it from the forward declaration
     // map in case anyone child members or other types require this type to get resolved.
     // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
     // are done.
-    m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
+    m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers.GetOpaqueQualType());
     
 
     // Disable external storage for this type so we don't get anymore 
     // clang::ExternalASTSource queries for this type.
-    ClangASTContext::SetHasExternalStorage (clang_type, false);
+    clang_type.SetHasExternalStorage (false);
 
     DWARFDebugInfo* debug_info = DebugInfo();
 
@@ -2381,8 +2367,6 @@
     assert (clang_type);
     DWARFDebugInfoEntry::Attributes attributes;
 
-    ClangASTContext &ast = GetClangASTContext();
-
     switch (tag)
     {
     case DW_TAG_structure_type:
@@ -2396,13 +2380,12 @@
                 {
                     
                     LanguageType class_language = eLanguageTypeUnknown;
-                    bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
-                    if (is_objc_class)
+                    if (clang_type.IsObjCObjectOrInterfaceType())
                     {
                         class_language = eLanguageTypeObjC;
                         // For objective C we don't start the definition when
                         // the class is created.
-                        ast.StartTagDeclarationDefinition (clang_type);
+                        clang_type.StartTagDeclarationDefinition ();
                     }
                     
                     int tag_decl_kind = -1;
@@ -2456,7 +2439,7 @@
                     
                     if (class_language == eLanguageTypeObjC)
                     {
-                        std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(ast.getASTContext(), clang_type));
+                        std::string class_str (clang_type.GetTypeName());
                         if (!class_str.empty())
                         {
                             
@@ -2499,7 +2482,7 @@
                                 }
                             }
                             
-                            for (DelayedPropertyList::const_iterator pi = delayed_properties.begin(), pe = delayed_properties.end();
+                            for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end();
                                  pi != pe;
                                  ++pi)
                                 pi->Finalize();
@@ -2511,7 +2494,7 @@
                     if (class_language != eLanguageTypeObjC)
                     {
                         if (is_a_class && tag_decl_kind != clang::TTK_Class)
-                            ast.SetTagTypeKind (clang_type, clang::TTK_Class);
+                            clang_type.SetTagTypeKind (clang::TTK_Class);
                     }
                     
                     // Since DW_TAG_structure_type gets used for both classes
@@ -2528,29 +2511,26 @@
                     {
                         // This is a class and all members that didn't have
                         // their access specified are private.
-                        ast.SetDefaultAccessForRecordFields (clang_type, 
-                                                             eAccessPrivate, 
-                                                             &member_accessibilities.front(), 
-                                                             member_accessibilities.size());
+                        clang_type.SetDefaultAccessForRecordFields (eAccessPrivate,
+                                                                    &member_accessibilities.front(),
+                                                                    member_accessibilities.size());
                     }
                     
                     if (!base_classes.empty())
                     {
-                        ast.SetBaseClassesForClassType (clang_type, 
-                                                        &base_classes.front(), 
-                                                        base_classes.size());
+                        clang_type.SetBaseClassesForClassType (&base_classes.front(),
+                                                               base_classes.size());
                         
                         // Clang will copy each CXXBaseSpecifier in "base_classes"
                         // so we have to free them all.
-                        ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), 
-                                                                    base_classes.size());
+                        ClangASTType::DeleteBaseClassSpecifiers (&base_classes.front(),
+                                                                 base_classes.size());
                     }
                 }
             }
             
-            ast.BuildIndirectFields (clang_type);
-            
-            ast.CompleteTagDeclarationDefinition (clang_type);
+            clang_type.BuildIndirectFields ();
+            clang_type.CompleteTagDeclarationDefinition ();
             
             if (!layout_info.field_offsets.empty() ||
                 !layout_info.base_offsets.empty()  ||
@@ -2561,14 +2541,14 @@
                 if (layout_info.bit_size == 0)
                     layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, 0) * 8;
                 
-                clang::CXXRecordDecl *record_decl = ClangASTType::GetAsCXXRecordDecl(clang_type);
+                clang::CXXRecordDecl *record_decl = clang_type.GetAsCXXRecordDecl();
                 if (record_decl)
                 {
                     if (log)
                     {
                         GetObjectFile()->GetModule()->LogMessage (log,
                                                                   "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])",
-                                                                  clang_type,
+                                                                  clang_type.GetOpaqueQualType(),
                                                                   record_decl,
                                                                   layout_info.bit_size,
                                                                   layout_info.alignment,
@@ -2583,7 +2563,7 @@
                         {
                             GetObjectFile()->GetModule()->LogMessage (log,
                                                                       "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = { bit_offset=%u, name='%s' }",
-                                                                      clang_type,
+                                                                      clang_type.GetOpaqueQualType(),
                                                                       idx,
                                                                       (uint32_t)pos->second,
                                                                       pos->first->getNameAsString().c_str());
@@ -2596,7 +2576,7 @@
                         {
                             GetObjectFile()->GetModule()->LogMessage (log,
                                                                       "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] = { byte_offset=%u, name='%s' }",
-                                                                      clang_type,
+                                                                      clang_type.GetOpaqueQualType(),
                                                                       idx,
                                                                       (uint32_t)base_pos->second.getQuantity(),
                                                                       base_pos->first->getNameAsString().c_str());
@@ -2608,7 +2588,7 @@
                         {
                             GetObjectFile()->GetModule()->LogMessage (log,
                                                                       "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) vbase[%u] = { byte_offset=%u, name='%s' }",
-                                                                      clang_type,
+                                                                      clang_type.GetOpaqueQualType(),
                                                                       idx,
                                                                       (uint32_t)vbase_pos->second.getQuantity(),
                                                                       vbase_pos->first->getNameAsString().c_str());
@@ -2623,15 +2603,15 @@
         return clang_type;
 
     case DW_TAG_enumeration_type:
-        ast.StartTagDeclarationDefinition (clang_type);
+        clang_type.StartTagDeclarationDefinition ();
         if (die->HasChildren())
         {
             SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
             bool is_signed = false;
-            ast.IsIntegerType(clang_type, is_signed);
+            clang_type.IsIntegerType(is_signed);
             ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), dwarf_cu, die);
         }
-        ast.CompleteTagDeclarationDefinition (clang_type);
+        clang_type.CompleteTagDeclarationDefinition ();
         return clang_type;
 
     default:
@@ -4142,7 +4122,7 @@
                                        bool skip_artificial,
                                        bool &is_static,
                                        TypeList* type_list,
-                                       std::vector<clang_type_t>& function_param_types,
+                                       std::vector<ClangASTType>& function_param_types,
                                        std::vector<clang::ParmVarDecl*>& function_param_decls,
                                        unsigned &type_quals,
                                        ClangASTContext::TemplateParameterInfos &template_param_infos)
@@ -4308,7 +4288,7 @@
 SymbolFileDWARF::ParseChildEnumerators
 (
     const SymbolContext& sc,
-    clang_type_t enumerator_clang_type,
+    lldb_private::ClangASTType &clang_type,
     bool is_signed,
     uint32_t enumerator_byte_size,
     DWARFCompileUnit* dwarf_cu,
@@ -4370,12 +4350,11 @@
 
                 if (name && name[0] && got_value)
                 {
-                    GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type, 
-                                                                               enumerator_clang_type, 
-                                                                               decl, 
-                                                                               name, 
-                                                                               enum_value, 
-                                                                               enumerator_byte_size * 8);
+                    clang_type.AddEnumerationValueToEnumerationType (clang_type.GetEnumerationIntegerType(),
+                                                                     decl,
+                                                                     name,
+                                                                     enum_value,
+                                                                     enumerator_byte_size * 8);
                     ++enumerators_added;
                 }
             }
@@ -4643,7 +4622,7 @@
                 Type* type = ResolveType (cu, decl_ctx_die);
                 if (type)
                 {
-                    clang::DeclContext *decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
+                    clang::DeclContext *decl_ctx = type->GetClangForwardType().GetDeclContextForType ();
                     if (decl_ctx)
                     {
                         LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
@@ -5671,7 +5650,7 @@
             Declaration decl;
 
             Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
-            clang_type_t clang_type = NULL;
+            ClangASTType clang_type;
 
             dw_attr_t attr;
 
@@ -5744,7 +5723,7 @@
                             strcmp(type_name_cstr, "decltype(nullptr)") == 0 )
                         {
                             resolve_state = Type::eResolveStateFull;
-                            clang_type = ast.getASTContext()->NullPtrTy.getAsOpaquePtr();
+                            clang_type = ast.GetBasicType(eBasicTypeNullPtr);
                             break;
                         }
                         // Fall through to base type below in case we can handle the type there...
@@ -5765,7 +5744,7 @@
                     case DW_TAG_volatile_type:          encoding_data_type = Type::eEncodingIsVolatileUID;          break;
                     }
 
-                    if (clang_type == NULL && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
+                    if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
                     {
                         bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
                         
@@ -5784,7 +5763,7 @@
                                                                                   die->GetOffset(), 
                                                                                   DW_TAG_value_to_name(die->Tag()), 
                                                                                   die->GetName(this, dwarf_cu));
-                                    clang_type = ast.GetBuiltInType_objc_id();
+                                    clang_type = ast.GetBasicType(eBasicTypeObjCID);
                                     encoding_data_type = Type::eEncodingIsUID;
                                     encoding_uid = LLDB_INVALID_UID;
                                     resolve_state = Type::eResolveStateFull;
@@ -5797,7 +5776,7 @@
                                                                                   die->GetOffset(), 
                                                                                   DW_TAG_value_to_name(die->Tag()), 
                                                                                   die->GetName(this, dwarf_cu));
-                                    clang_type = ast.GetBuiltInType_objc_Class();
+                                    clang_type = ast.GetBasicType(eBasicTypeObjCClass);
                                     encoding_data_type = Type::eEncodingIsUID;
                                     encoding_uid = LLDB_INVALID_UID;
                                     resolve_state = Type::eResolveStateFull;
@@ -5809,7 +5788,7 @@
                                                                                   die->GetOffset(), 
                                                                                   DW_TAG_value_to_name(die->Tag()), 
                                                                                   die->GetName(this, dwarf_cu));
-                                    clang_type = ast.GetBuiltInType_objc_selector();
+                                    clang_type = ast.GetBasicType(eBasicTypeObjCSel);
                                     encoding_data_type = Type::eEncodingIsUID;
                                     encoding_uid = LLDB_INVALID_UID;
                                     resolve_state = Type::eResolveStateFull;
@@ -5832,7 +5811,7 @@
                                                                                           die->GetOffset(),
                                                                                           DW_TAG_value_to_name(die->Tag()),
                                                                                           die->GetName(this, dwarf_cu));
-                                            clang_type = ast.GetBuiltInType_objc_id();
+                                            clang_type = ast.GetBasicType(eBasicTypeObjCID);
                                             encoding_data_type = Type::eEncodingIsUID;
                                             encoding_uid = LLDB_INVALID_UID;
                                             resolve_state = Type::eResolveStateFull;
@@ -6109,8 +6088,8 @@
                     }
                     assert (tag_decl_kind != -1);
                     bool clang_type_was_created = false;
-                    clang_type = m_forward_decl_die_to_clang_type.lookup (die);
-                    if (clang_type == NULL)
+                    clang_type.SetClangType(ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
+                    if (!clang_type)
                     {
                         const DWARFDebugInfoEntry *decl_ctx_die;
                         
@@ -6166,7 +6145,7 @@
                     // Store a forward declaration to this class type in case any 
                     // parameters in any class methods need it for the clang 
                     // types for function prototypes.
-                    LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
+                    LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);
                     type_sp.reset (new Type (MakeUserID(die->GetOffset()), 
                                              this, 
                                              type_name_const_str, 
@@ -6202,27 +6181,21 @@
                         if (die->HasChildren() == false)
                         {
                             // No children for this struct/union/class, lets finish it
-                            ast.StartTagDeclarationDefinition (clang_type);
-                            ast.CompleteTagDeclarationDefinition (clang_type);
+                            clang_type.StartTagDeclarationDefinition ();
+                            clang_type.CompleteTagDeclarationDefinition ();
                             
                             if (tag == DW_TAG_structure_type) // this only applies in C
                             {
-                                clang::QualType qual_type = clang::QualType::getFromOpaquePtr (clang_type);
-                                const clang::RecordType *record_type = qual_type->getAs<clang::RecordType> ();
+                                clang::RecordDecl *record_decl = clang_type.GetAsRecordDecl();
                                 
-                                if (record_type)
+                                if (record_decl)
                                 {
-                                    clang::RecordDecl *record_decl = record_type->getDecl();
+                                    LayoutInfo layout_info;
                                     
-                                    if (record_decl)
-                                    {
-                                        LayoutInfo layout_info;
-                                        
-                                        layout_info.alignment = 0;
-                                        layout_info.bit_size = 0;
-                                        
-                                        m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
-                                    }
+                                    layout_info.alignment = 0;
+                                    layout_info.bit_size = 0;
+                                    
+                                    m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
                                 }
                             }
                         }
@@ -6238,16 +6211,16 @@
                             
                             if (class_language != eLanguageTypeObjC &&
                                 class_language != eLanguageTypeObjC_plus_plus)
-                                ast.StartTagDeclarationDefinition (clang_type);
+                                clang_type.StartTagDeclarationDefinition ();
 
                             // Leave this as a forward declaration until we need
                             // to know the details of the type. lldb_private::Type
                             // will automatically call the SymbolFile virtual function
                             // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
                             // When the definition needs to be defined.
-                            m_forward_decl_die_to_clang_type[die] = clang_type;
-                            m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
-                            ClangASTContext::SetHasExternalStorage (clang_type, true);
+                            m_forward_decl_die_to_clang_type[die] = clang_type.GetOpaqueQualType();
+                            m_forward_decl_clang_type_to_die[clang_type.RemoveFastQualifiers().GetOpaqueQualType()] = die;
+                            clang_type.SetHasExternalStorage (true);
                         }
                     }
                     
@@ -6303,9 +6276,9 @@
 
                         DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
 
-                        clang_type_t enumerator_clang_type = NULL;
-                        clang_type = m_forward_decl_die_to_clang_type.lookup (die);
-                        if (clang_type == NULL)
+                        ClangASTType enumerator_clang_type;
+                        clang_type.SetClangType (ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
+                        if (!clang_type)
                         {
                             if (encoding_uid != DW_INVALID_OFFSET)
                             {
@@ -6314,7 +6287,7 @@
                                     enumerator_clang_type = enumerator_type->GetClangFullType();
                             }
                             
-                            if (enumerator_clang_type == NULL)
+                            if (!enumerator_clang_type)
                                 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
                                                                                                       DW_ATE_signed,
                                                                                                       byte_size * 8);
@@ -6326,10 +6299,10 @@
                         }
                         else
                         {
-                            enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
+                            enumerator_clang_type = clang_type.GetEnumerationIntegerType ();
                         }
 
-                        LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
+                        LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);
                         
                         type_sp.reset( new Type (MakeUserID(die->GetOffset()), 
                                                  this, 
@@ -6342,15 +6315,15 @@
                                                  clang_type, 
                                                  Type::eResolveStateForward));
 
-                        ast.StartTagDeclarationDefinition (clang_type);
+                        clang_type.StartTagDeclarationDefinition ();
                         if (die->HasChildren())
                         {
                             SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
                             bool is_signed = false;
-                            ast.IsIntegerType(enumerator_clang_type, is_signed);
+                            enumerator_clang_type.IsIntegerType(is_signed);
                             ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), dwarf_cu, die);
                         }
-                        ast.CompleteTagDeclarationDefinition (clang_type);
+                        clang_type.CompleteTagDeclarationDefinition ();
                     }
                 }
                 break;
@@ -6473,7 +6446,7 @@
                     
                     DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
 
-                    clang_type_t return_clang_type = NULL;
+                    ClangASTType return_clang_type;
                     Type *func_type = NULL;
                     
                     if (type_die_offset != DW_INVALID_OFFSET)
@@ -6482,10 +6455,10 @@
                     if (func_type)
                         return_clang_type = func_type->GetClangForwardType();
                     else
-                        return_clang_type = ast.GetBuiltInType_void();
+                        return_clang_type = ast.GetBasicType(eBasicTypeVoid);
 
 
-                    std::vector<clang_type_t> function_param_types;
+                    std::vector<ClangASTType> function_param_types;
                     std::vector<clang::ParmVarDecl*> function_param_decls;
 
                     // Parse the function children for the parameters
@@ -6535,7 +6508,7 @@
                             if (objc_method.IsValid(true))
                             {
                                 SymbolContext empty_sc;
-                                clang_type_t class_opaque_type = NULL;
+                                ClangASTType class_opaque_type;
                                 ConstString class_name(objc_method.GetClassName());
                                 if (class_name)
                                 {
@@ -6544,8 +6517,8 @@
 
                                     if (complete_objc_class_type_sp)
                                     {
-                                        clang_type_t type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType();
-                                        if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
+                                        ClangASTType type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType();
+                                        if (type_clang_forward_type.IsObjCObjectOrInterfaceType ())
                                             class_opaque_type = type_clang_forward_type;
                                     }
                                 }
@@ -6557,11 +6530,10 @@
                                     if (accessibility == eAccessNone)
                                         accessibility = eAccessPublic;
 
-                                    clang::ObjCMethodDecl *objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type, 
-                                                                                                             type_name_cstr,
-                                                                                                             clang_type,
-                                                                                                             accessibility,
-                                                                                                             is_artificial);
+                                    clang::ObjCMethodDecl *objc_method_decl = class_opaque_type.AddMethodToObjCObjectType (type_name_cstr,
+                                                                                                                           clang_type,
+                                                                                                                           accessibility,
+                                                                                                                           is_artificial);
                                     type_handled = objc_method_decl != NULL;
                                     if (type_handled)
                                     {
@@ -6680,10 +6652,10 @@
                                     }
                                     else
                                     {
-                                        clang_type_t class_opaque_type = class_type->GetClangForwardType();
-                                        if (ClangASTContext::IsCXXClassType (class_opaque_type))
+                                        ClangASTType class_opaque_type = class_type->GetClangForwardType();
+                                        if (class_opaque_type.IsCXXClassType ())
                                         {
-                                            if (ClangASTContext::IsBeingDefined (class_opaque_type))
+                                            if (class_opaque_type.IsBeingDefined ())
                                             {
                                                 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
                                                 // in the DWARF for C++ methods... Default to public for now...
@@ -6709,16 +6681,15 @@
 
                                                     const bool is_attr_used = false;
                                                     
-                                                    cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type, 
-                                                                                                    type_name_cstr,
-                                                                                                    clang_type,
-                                                                                                    accessibility,
-                                                                                                    is_virtual,
-                                                                                                    is_static,
-                                                                                                    is_inline,
-                                                                                                    is_explicit,
-                                                                                                    is_attr_used,
-                                                                                                    is_artificial);
+                                                    cxx_method_decl = class_opaque_type.AddMethodToCXXRecordType (type_name_cstr,
+                                                                                                                  clang_type,
+                                                                                                                  accessibility,
+                                                                                                                  is_virtual,
+                                                                                                                  is_static,
+                                                                                                                  is_inline,
+                                                                                                                  is_explicit,
+                                                                                                                  is_attr_used,
+                                                                                                                  is_artificial);
                                                     
                                                     type_handled = cxx_method_decl != NULL;
 
@@ -6902,7 +6873,7 @@
                             ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
                             if (byte_stride == 0 && bit_stride == 0)
                                 byte_stride = element_type->GetByteSize();
-                            clang_type_t array_element_type = element_type->GetClangForwardType();
+                            ClangASTType array_element_type = element_type->GetClangForwardType();
                             uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
                             uint64_t num_elements = 0;
                             std::vector<uint64_t>::const_reverse_iterator pos;
@@ -6961,14 +6932,12 @@
                         Type *pointee_type = ResolveTypeUID(type_die_offset);
                         Type *class_type = ResolveTypeUID(containing_type_die_offset);
                         
-                        clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
-                        clang_type_t class_clang_type = class_type->GetClangLayoutType();
+                        ClangASTType pointee_clang_type = pointee_type->GetClangForwardType();
+                        ClangASTType class_clang_type = class_type->GetClangLayoutType();
 
-                        clang_type = ast.CreateMemberPointerType(pointee_clang_type, 
-                                                                 class_clang_type);
+                        clang_type = pointee_clang_type.CreateMemberPointerType(class_clang_type);
 
-                        byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(), 
-                                                                       clang_type) / 8;
+                        byte_size = clang_type.GetByteSize();
 
                         type_sp.reset( new Type (MakeUserID(die->GetOffset()), 
                                                  this, 
@@ -7761,7 +7730,7 @@
 SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
 {
     SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
-    clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
+    ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
     if (clang_type)
         symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
 }
@@ -7770,7 +7739,7 @@
 SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
 {
     SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
-    clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
+    ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
     if (clang_type)
         symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
 }
@@ -7844,8 +7813,7 @@
                 
                 Type *matching_type = ResolveType (dwarf_cu, die);
                 
-                lldb::clang_type_t type = matching_type->GetClangForwardType();
-                clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
+                clang::QualType qual_type = matching_type->GetClangForwardType().GetQualType();
                 
                 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
                 {
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 0370bc3..b6c6d94 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -107,7 +107,7 @@
     virtual size_t          ParseVariablesForContext (const lldb_private::SymbolContext& sc);
 
     virtual lldb_private::Type* ResolveTypeUID(lldb::user_id_t type_uid);
-    virtual lldb::clang_type_t ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_opaque_type);
+    virtual bool            ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_type);
 
     virtual lldb_private::Type* ResolveType (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed = true);
     virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid);
@@ -275,7 +275,7 @@
     }
 
     bool
-    HasForwardDeclForClangType (lldb::clang_type_t clang_type);
+    HasForwardDeclForClangType (const lldb_private::ClangASTType &clang_type);
 
 protected:
 
@@ -347,7 +347,7 @@
                                 const lldb_private::SymbolContext& sc,
                                 DWARFCompileUnit* dwarf_cu,
                                 const DWARFDebugInfoEntry *die,
-                                lldb::clang_type_t class_clang_type,
+                                lldb_private::ClangASTType &class_clang_type,
                                 const lldb::LanguageType class_language,
                                 std::vector<clang::CXXBaseSpecifier *>& base_classes,
                                 std::vector<int>& member_accessibilities,
@@ -365,14 +365,14 @@
                                 bool skip_artificial,
                                 bool &is_static,
                                 lldb_private::TypeList* type_list,
-                                std::vector<lldb::clang_type_t>& function_args,
+                                std::vector<lldb_private::ClangASTType>& function_args,
                                 std::vector<clang::ParmVarDecl*>& function_param_decls,
                                 unsigned &type_quals,
                                 lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
 
     size_t                  ParseChildEnumerators(
                                 const lldb_private::SymbolContext& sc,
-                                lldb::clang_type_t enumerator_qual_type,
+                                lldb_private::ClangASTType &clang_type,
                                 bool is_signed,
                                 uint32_t enumerator_byte_size,
                                 DWARFCompileUnit* dwarf_cu,
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index 42107ef..a0430e3 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -780,11 +780,11 @@
     return NULL;
 }
 
-lldb::clang_type_t
-SymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
+bool
+SymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (ClangASTType& clang_type)
 {
     // We have a struct/union/class/enum that needs to be fully resolved.
-    return NULL;
+    return false;
 }
 
 uint32_t
@@ -1385,7 +1385,7 @@
 SymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl)
 {
     SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
-    clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
+    ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
     if (clang_type)
     {
         SymbolFileDWARF *oso_dwarf;
@@ -1405,7 +1405,7 @@
 SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
 {
     SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
-    clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
+    ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
     if (clang_type)
     {
         SymbolFileDWARF *oso_dwarf;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index d38bf66..06330b9 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -77,7 +77,7 @@
     virtual lldb_private::Type* ResolveTypeUID (lldb::user_id_t type_uid);
     virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid);
     virtual clang::DeclContext* GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid);
-    virtual lldb::clang_type_t  ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type);
+    virtual bool            ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_type);
     virtual uint32_t        ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc);
     virtual uint32_t        ResolveSymbolContext (const lldb_private::FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList& sc_list);
     virtual uint32_t        FindGlobalVariables (const lldb_private::ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, lldb_private::VariableList& variables);
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index 2807869..9beba51 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -292,10 +292,10 @@
     return NULL;
 }
 
-lldb::clang_type_t
-SymbolFileSymtab::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type)
+bool
+SymbolFileSymtab::ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_opaque_type)
 {
-    return NULL;
+    return false;
 }
 
 ClangNamespaceDecl 
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
index 99f0eb1..914efe6 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -78,8 +78,8 @@
     virtual lldb_private::Type*
     ResolveTypeUID(lldb::user_id_t type_uid);
 
-    virtual lldb::clang_type_t
-    ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type);
+    virtual bool
+    ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_type);
 
     virtual uint32_t
     ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc);
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index 00ebfaa..b5c658d 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -62,6 +62,7 @@
 #include "lldb/Core/Flags.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/UniqueCStringMap.h"
 #include "lldb/Expression/ASTDumper.h"
 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
 #include "lldb/Symbol/VerifyDecl.h"
@@ -77,111 +78,8 @@
 using namespace llvm;
 using namespace clang;
 
-
-static bool
-GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool allow_completion = true)
-{
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-    case clang::Type::ConstantArray:
-    case clang::Type::IncompleteArray:
-    case clang::Type::VariableArray:
-        {
-            const clang::ArrayType *array_type = dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
-            
-            if (array_type)
-                return GetCompleteQualType (ast, array_type->getElementType(), allow_completion);
-        }
-        break;
-            
-    case clang::Type::Record:
-    case clang::Type::Enum:
-        {
-            const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr());
-            if (tag_type)
-            {
-                clang::TagDecl *tag_decl = tag_type->getDecl();
-                if (tag_decl)
-                {
-                    if (tag_decl->isCompleteDefinition())
-                        return true;
-                    
-                    if (!allow_completion)
-                        return false;
-
-                    if (tag_decl->hasExternalLexicalStorage())
-                    {
-                        if (ast)
-                        {
-                            ExternalASTSource *external_ast_source = ast->getExternalSource();
-                            if (external_ast_source)
-                            {
-                                external_ast_source->CompleteType(tag_decl);
-                                return !tag_type->isIncompleteType();
-                            }
-                        }
-                    }
-                    return false;
-                }
-            }
-
-        }
-        break;
-
-    case clang::Type::ObjCObject:
-    case clang::Type::ObjCInterface:
-        {
-            const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type);
-            if (objc_class_type)
-            {
-                clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                // We currently can't complete objective C types through the newly added ASTContext
-                // because it only supports TagDecl objects right now...
-                if (class_interface_decl)
-                {
-                    if (class_interface_decl->getDefinition())
-                        return true;
-                    
-                    if (!allow_completion)
-                        return false;
-
-                    if (class_interface_decl->hasExternalLexicalStorage())
-                    {
-                        if (ast)
-                        {
-                            ExternalASTSource *external_ast_source = ast->getExternalSource();
-                            if (external_ast_source)
-                            {
-                                external_ast_source->CompleteType (class_interface_decl);
-                                return !objc_class_type->isIncompleteType();
-                            }
-                        }
-                    }
-                    return false;
-                }
-            }
-        }
-        break;
-
-    case clang::Type::Typedef:
-        return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion);
-    
-    case clang::Type::Elaborated:
-        return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType(), allow_completion);
-
-    case clang::Type::Paren:
-        return GetCompleteQualType (ast, cast<ParenType>(qual_type)->desugar(), allow_completion);
-
-    default:
-        break;
-    }
-
-    return true;
-}
-
-static AccessSpecifier
-ConvertAccessTypeToAccessSpecifier (AccessType access)
+clang::AccessSpecifier
+ClangASTContext::ConvertAccessTypeToAccessSpecifier (AccessType access)
 {
     switch (access)
     {
@@ -194,20 +92,6 @@
     return AS_none;
 }
 
-static ObjCIvarDecl::AccessControl
-ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
-{
-    switch (access)
-    {
-    case eAccessNone:      return ObjCIvarDecl::None;
-    case eAccessPublic:    return ObjCIvarDecl::Public;
-    case eAccessPrivate:   return ObjCIvarDecl::Private;
-    case eAccessProtected: return ObjCIvarDecl::Protected;
-    case eAccessPackage:   return ObjCIvarDecl::Package;
-    }
-    return ObjCIvarDecl::None;
-}
-
 
 static void
 ParseLangArgs
@@ -393,7 +277,8 @@
     m_builtins_ap(),
     m_callback_tag_decl (NULL),
     m_callback_objc_decl (NULL),
-    m_callback_baton (NULL)
+    m_callback_baton (NULL),
+    m_pointer_byte_size (0)
 
 {
     if (target_triple && target_triple[0])
@@ -429,6 +314,7 @@
     m_identifier_table_ap.reset();
     m_selector_table_ap.reset();
     m_builtins_ap.reset();
+    m_pointer_byte_size = 0;
 }
 
 const char *
@@ -646,80 +532,279 @@
         return true;
     return false;
 }
-
-clang_type_t
+ClangASTType
 ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
 {
-    ASTContext *ast = getASTContext();
-
-    assert (ast != NULL);
-
-    return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size);
+    return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (getASTContext(), encoding, bit_size);
 }
 
-clang_type_t
+ClangASTType
 ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
 {
     if (!ast)
-        return NULL;
+        return ClangASTType();
     
     switch (encoding)
     {
     case eEncodingInvalid:
         if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
-            return ast->VoidPtrTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->VoidPtrTy.getAsOpaquePtr());
         break;
         
     case eEncodingUint:
         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
-            return ast->UnsignedCharTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
-            return ast->UnsignedShortTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
-            return ast->UnsignedIntTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr());
         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
-            return ast->UnsignedLongTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr());
         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
-            return ast->UnsignedLongLongTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr());
         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
-            return ast->UnsignedInt128Ty.getAsOpaquePtr();
+            return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr());
         break;
         
     case eEncodingSint:
         if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
-            return ast->CharTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
         if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
-            return ast->ShortTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr());
         if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
-            return ast->IntTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->IntTy.getAsOpaquePtr());
         if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
-            return ast->LongTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->LongTy.getAsOpaquePtr());
         if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
-            return ast->LongLongTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr());
         if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
-            return ast->Int128Ty.getAsOpaquePtr();
+            return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr());
         break;
         
     case eEncodingIEEE754:
         if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
-            return ast->FloatTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->FloatTy.getAsOpaquePtr());
         if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
-            return ast->DoubleTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->DoubleTy.getAsOpaquePtr());
         if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
-            return ast->LongDoubleTy.getAsOpaquePtr();
+            return ClangASTType (ast, ast->LongDoubleTy.getAsOpaquePtr());
         break;
         
     case eEncodingVector:
         // Sanity check that bit_size is a multiple of 8's.
         if (bit_size && !(bit_size & 0x7u))
-            return ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8).getAsOpaquePtr();
+            return ClangASTType (ast, ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8).getAsOpaquePtr());
         break;
     }
     
-    return NULL;
+    return ClangASTType();
 }
 
-clang_type_t
+
+
+lldb::BasicType
+ClangASTContext::GetBasicTypeEnumeration (const ConstString &name)
+{
+    if (name)
+    {
+        typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
+        static TypeNameToBasicTypeMap g_type_map;
+        static std::once_flag g_once_flag;
+        std::call_once(g_once_flag, [](){
+            // "void"
+            g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid);
+            
+            // "char"
+            g_type_map.Append(ConstString("char").GetCString(), eBasicTypeChar);
+            g_type_map.Append(ConstString("signed char").GetCString(), eBasicTypeSignedChar);
+            g_type_map.Append(ConstString("unsigned char").GetCString(), eBasicTypeUnsignedChar);
+            g_type_map.Append(ConstString("wchar_t").GetCString(), eBasicTypeWChar);
+            g_type_map.Append(ConstString("signed wchar_t").GetCString(), eBasicTypeSignedWChar);
+            g_type_map.Append(ConstString("unsigned wchar_t").GetCString(), eBasicTypeUnsignedWChar);
+            // "short"
+            g_type_map.Append(ConstString("short").GetCString(), eBasicTypeShort);
+            g_type_map.Append(ConstString("short int").GetCString(), eBasicTypeShort);
+            g_type_map.Append(ConstString("unsigned short").GetCString(), eBasicTypeUnsignedShort);
+            g_type_map.Append(ConstString("unsigned short int").GetCString(), eBasicTypeUnsignedShort);
+            
+            // "int"
+            g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt);
+            g_type_map.Append(ConstString("signed int").GetCString(), eBasicTypeInt);
+            g_type_map.Append(ConstString("unsigned int").GetCString(), eBasicTypeUnsignedInt);
+            g_type_map.Append(ConstString("unsigned").GetCString(), eBasicTypeUnsignedInt);
+            
+            // "long"
+            g_type_map.Append(ConstString("long").GetCString(), eBasicTypeLong);
+            g_type_map.Append(ConstString("long int").GetCString(), eBasicTypeLong);
+            g_type_map.Append(ConstString("unsigned long").GetCString(), eBasicTypeUnsignedLong);
+            g_type_map.Append(ConstString("unsigned long int").GetCString(), eBasicTypeUnsignedLong);
+            
+            // "long long"
+            g_type_map.Append(ConstString("long long").GetCString(), eBasicTypeLongLong);
+            g_type_map.Append(ConstString("long long int").GetCString(), eBasicTypeLongLong);
+            g_type_map.Append(ConstString("unsigned long long").GetCString(), eBasicTypeUnsignedLongLong);
+            g_type_map.Append(ConstString("unsigned long long int").GetCString(), eBasicTypeUnsignedLongLong);
+            
+            // "int128"
+            g_type_map.Append(ConstString("__int128_t").GetCString(), eBasicTypeInt128);
+            g_type_map.Append(ConstString("__uint128_t").GetCString(), eBasicTypeUnsignedInt128);
+            
+            // Miscelaneous
+            g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool);
+            g_type_map.Append(ConstString("float").GetCString(), eBasicTypeFloat);
+            g_type_map.Append(ConstString("double").GetCString(), eBasicTypeDouble);
+            g_type_map.Append(ConstString("long double").GetCString(), eBasicTypeLongDouble);
+            g_type_map.Append(ConstString("id").GetCString(), eBasicTypeObjCID);
+            g_type_map.Append(ConstString("SEL").GetCString(), eBasicTypeObjCSel);
+            g_type_map.Append(ConstString("nullptr").GetCString(), eBasicTypeNullPtr);
+            g_type_map.Sort();
+        });
+        
+        return g_type_map.Find(name.GetCString(), eBasicTypeInvalid);
+    }
+    return eBasicTypeInvalid;
+}
+
+ClangASTType
+ClangASTContext::GetBasicType (ASTContext *ast, const ConstString &name)
+{
+    if (ast)
+    {
+        lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration (name);
+        return ClangASTContext::GetBasicType (ast, basic_type);
+    }
+    return ClangASTType();
+}
+
+uint32_t
+ClangASTContext::GetPointerByteSize ()
+{
+    if (m_pointer_byte_size == 0)
+        m_pointer_byte_size = GetBasicType(lldb::eBasicTypeVoid).GetPointerType().GetByteSize();
+    return m_pointer_byte_size;
+}
+
+ClangASTType
+ClangASTContext::GetBasicType (lldb::BasicType basic_type)
+{
+    return GetBasicType (getASTContext(), basic_type);
+}
+
+ClangASTType
+ClangASTContext::GetBasicType (ASTContext *ast, lldb::BasicType basic_type)
+{
+    if (ast)
+    {
+        clang_type_t clang_type = NULL;
+        
+        switch (basic_type)
+        {
+            case eBasicTypeInvalid:
+            case eBasicTypeOther:
+                break;
+            case eBasicTypeVoid:
+                clang_type = ast->VoidTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeChar:
+                clang_type = ast->CharTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeSignedChar:
+                clang_type = ast->SignedCharTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeUnsignedChar:
+                clang_type = ast->UnsignedCharTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeWChar:
+                clang_type = ast->getWCharType().getAsOpaquePtr();
+                break;
+            case eBasicTypeSignedWChar:
+                clang_type = ast->getSignedWCharType().getAsOpaquePtr();
+                break;
+            case eBasicTypeUnsignedWChar:
+                clang_type = ast->getUnsignedWCharType().getAsOpaquePtr();
+                break;
+            case eBasicTypeChar16:
+                clang_type = ast->Char16Ty.getAsOpaquePtr();
+                break;
+            case eBasicTypeChar32:
+                clang_type = ast->Char32Ty.getAsOpaquePtr();
+                break;
+            case eBasicTypeShort:
+                clang_type = ast->ShortTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeUnsignedShort:
+                clang_type = ast->UnsignedShortTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeInt:
+                clang_type = ast->IntTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeUnsignedInt:
+                clang_type = ast->UnsignedIntTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeLong:
+                clang_type = ast->LongTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeUnsignedLong:
+                clang_type = ast->UnsignedLongTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeLongLong:
+                clang_type = ast->LongLongTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeUnsignedLongLong:
+                clang_type = ast->UnsignedLongLongTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeInt128:
+                clang_type = ast->Int128Ty.getAsOpaquePtr();
+                break;
+            case eBasicTypeUnsignedInt128:
+                clang_type = ast->UnsignedInt128Ty.getAsOpaquePtr();
+                break;
+            case eBasicTypeBool:
+                clang_type = ast->BoolTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeHalf:
+                clang_type = ast->HalfTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeFloat:
+                clang_type = ast->FloatTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeDouble:
+                clang_type = ast->DoubleTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeLongDouble:
+                clang_type = ast->LongDoubleTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeFloatComplex:
+                clang_type = ast->FloatComplexTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeDoubleComplex:
+                clang_type = ast->DoubleComplexTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeLongDoubleComplex:
+                clang_type = ast->LongDoubleComplexTy.getAsOpaquePtr();
+                break;
+            case eBasicTypeObjCID:
+                clang_type = ast->getObjCIdType().getAsOpaquePtr();
+                break;
+            case eBasicTypeObjCClass:
+                clang_type = ast->getObjCClassType().getAsOpaquePtr();
+                break;
+            case eBasicTypeObjCSel:
+                clang_type = ast->getObjCSelType().getAsOpaquePtr();
+                break;
+            case eBasicTypeNullPtr:
+                clang_type = ast->NullPtrTy.getAsOpaquePtr();
+                break;
+        }
+        
+        if (clang_type)
+            return ClangASTType (ast, clang_type);
+    }
+    return ClangASTType();
+}
+
+
+ClangASTType
 ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
 {
     ASTContext *ast = getASTContext();
@@ -735,18 +820,18 @@
                 
             case DW_ATE_address:
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
-                    return ast->VoidPtrTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->VoidPtrTy.getAsOpaquePtr());
                 break;
                 
             case DW_ATE_boolean:
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
-                    return ast->BoolTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->BoolTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
-                    return ast->UnsignedCharTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
-                    return ast->UnsignedShortTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
-                    return ast->UnsignedIntTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr());
                 break;
                 
             case DW_ATE_lo_user:
@@ -755,33 +840,33 @@
                 {
                     if (::strstr(type_name, "complex"))
                     {
-                        clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
-                        return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
+                        ClangASTType complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
+                        return ClangASTType (ast, ast->getComplexType (complex_int_clang_type.GetQualType()).getAsOpaquePtr());
                     }
                 }
                 break;
                 
             case DW_ATE_complex_float:
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
-                    return ast->FloatComplexTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->FloatComplexTy.getAsOpaquePtr());
                 else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
-                    return ast->DoubleComplexTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->DoubleComplexTy.getAsOpaquePtr());
                 else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
-                    return ast->LongDoubleComplexTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->LongDoubleComplexTy.getAsOpaquePtr());
                 else 
                 {
-                    clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
-                    return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
+                    ClangASTType complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
+                    return ClangASTType (ast, ast->getComplexType (complex_float_clang_type.GetQualType()).getAsOpaquePtr());
                 }
                 break;
                 
             case DW_ATE_float:
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
-                    return ast->FloatTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->FloatTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
-                    return ast->DoubleTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->DoubleTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
-                    return ast->LongDoubleTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->LongDoubleTy.getAsOpaquePtr());
                 break;
                 
             case DW_ATE_signed:
@@ -789,47 +874,47 @@
                 {
                     if (streq(type_name, "wchar_t") &&
                         QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
-                        return ast->WCharTy.getAsOpaquePtr();
+                        return ClangASTType (ast, ast->WCharTy.getAsOpaquePtr());
                     if (streq(type_name, "void") &&
                         QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy))
-                        return ast->VoidTy.getAsOpaquePtr();
+                        return ClangASTType (ast, ast->VoidTy.getAsOpaquePtr());
                     if (strstr(type_name, "long long") &&
                         QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
-                        return ast->LongLongTy.getAsOpaquePtr();
+                        return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr());
                     if (strstr(type_name, "long") &&
                         QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
-                        return ast->LongTy.getAsOpaquePtr();
+                        return ClangASTType (ast, ast->LongTy.getAsOpaquePtr());
                     if (strstr(type_name, "short") &&
                         QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
-                        return ast->ShortTy.getAsOpaquePtr();
+                        return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr());
                     if (strstr(type_name, "char"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
-                            return ast->CharTy.getAsOpaquePtr();
+                            return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
-                            return ast->SignedCharTy.getAsOpaquePtr();
+                            return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr());
                     }
                     if (strstr(type_name, "int"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
-                            return ast->IntTy.getAsOpaquePtr();
+                            return ClangASTType (ast, ast->IntTy.getAsOpaquePtr());
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
-                            return ast->Int128Ty.getAsOpaquePtr();
+                            return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr());
                     }
                 }
                 // We weren't able to match up a type name, just search by size
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
-                    return ast->CharTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
-                    return ast->ShortTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
-                    return ast->IntTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->IntTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
-                    return ast->LongTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->LongTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
-                    return ast->LongLongTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
-                    return ast->Int128Ty.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr());
                 break;
                 
             case DW_ATE_signed_char:
@@ -838,13 +923,13 @@
                     if (streq(type_name, "signed char"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
-                            return ast->SignedCharTy.getAsOpaquePtr();
+                            return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr());
                     }
                 }
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
-                    return ast->CharTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
-                    return ast->SignedCharTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr());
                 break;
                 
             case DW_ATE_unsigned:
@@ -853,51 +938,51 @@
                     if (strstr(type_name, "long long"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
-                            return ast->UnsignedLongLongTy.getAsOpaquePtr();
+                            return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr());
                     }
                     else if (strstr(type_name, "long"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
-                            return ast->UnsignedLongTy.getAsOpaquePtr();
+                            return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr());
                     }
                     else if (strstr(type_name, "short"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
-                            return ast->UnsignedShortTy.getAsOpaquePtr();
+                            return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
                     }
                     else if (strstr(type_name, "char"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
-                            return ast->UnsignedCharTy.getAsOpaquePtr();
+                            return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
                     }
                     else if (strstr(type_name, "int"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
-                            return ast->UnsignedIntTy.getAsOpaquePtr();
+                            return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr());
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
-                            return ast->UnsignedInt128Ty.getAsOpaquePtr();
+                            return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr());
                     }
                 }
                 // We weren't able to match up a type name, just search by size
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
-                    return ast->UnsignedCharTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
-                    return ast->UnsignedShortTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
-                    return ast->UnsignedIntTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
-                    return ast->UnsignedLongTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
-                    return ast->UnsignedLongLongTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
-                    return ast->UnsignedInt128Ty.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr());
                 break;
                 
             case DW_ATE_unsigned_char:
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
-                    return ast->UnsignedCharTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
-                    return ast->UnsignedShortTy.getAsOpaquePtr();
+                    return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
                 break;
                 
             case DW_ATE_imaginary_float:
@@ -908,11 +993,11 @@
                 {
                     if (streq(type_name, "char16_t"))
                     {
-                        return ast->Char16Ty.getAsOpaquePtr();
+                        return ClangASTType (ast, ast->Char16Ty.getAsOpaquePtr());
                     }
                     else if (streq(type_name, "char32_t"))
                     {
-                        return ast->Char32Ty.getAsOpaquePtr();
+                        return ClangASTType (ast, ast->Char32Ty.getAsOpaquePtr());
                     }
                 }
                 break;
@@ -928,89 +1013,27 @@
     {
         Host::SystemLog (Host::eSystemLogError, "error: need to add support for DW_TAG_base_type encoded with DW_ATE = 0x%x, bit_size = %u\n", dw_ate, bit_size);
     }
-    return NULL;
+    return ClangASTType ();
 }
 
-clang_type_t
-ClangASTContext::GetBuiltInType_void(ASTContext *ast)
-{
-    return ast->VoidTy.getAsOpaquePtr();
-}
-
-clang_type_t
-ClangASTContext::GetBuiltInType_bool()
-{
-    return getASTContext()->BoolTy.getAsOpaquePtr();
-}
-
-clang_type_t
-ClangASTContext::GetBuiltInType_objc_id()
-{
-    return getASTContext()->getObjCIdType().getAsOpaquePtr();
-}
-
-lldb::clang_type_t
-ClangASTContext::GetBuiltInType_objc_id(clang::ASTContext *ast)
-{
-    return ast->getObjCIdType().getAsOpaquePtr();
-}
-
-clang_type_t
-ClangASTContext::GetBuiltInType_objc_Class()
-{
-    return getASTContext()->getObjCClassType().getAsOpaquePtr();
-}
-
-clang_type_t
-ClangASTContext::GetBuiltInType_objc_selector()
-{
-    return getASTContext()->getObjCSelType().getAsOpaquePtr();
-}
-
-clang_type_t
+ClangASTType
 ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast)
 {
-    return ast->UnknownAnyTy.getAsOpaquePtr();
+    if (ast)
+        return ClangASTType (ast, ast->UnknownAnyTy.getAsOpaquePtr());
+    return ClangASTType();
 }
 
-clang_type_t
+ClangASTType
 ClangASTContext::GetCStringType (bool is_const)
 {
-    QualType char_type(getASTContext()->CharTy);
+    ASTContext *ast = getASTContext();
+    QualType char_type(ast->CharTy);
     
     if (is_const)
         char_type.addConst();
     
-    return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
-}
-
-clang_type_t
-ClangASTContext::GetVoidType()
-{
-    return GetVoidType(getASTContext());
-}
-
-clang_type_t
-ClangASTContext::GetVoidType(ASTContext *ast)
-{
-    return ast->VoidTy.getAsOpaquePtr();
-}
-
-clang_type_t
-ClangASTContext::GetVoidPtrType (bool is_const)
-{
-    return GetVoidPtrType(getASTContext(), is_const);
-}
-
-clang_type_t
-ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
-{
-    QualType void_ptr_type(ast->VoidPtrTy);
-    
-    if (is_const)
-        void_ptr_type.addConst();
-    
-    return void_ptr_type.getAsOpaquePtr();
+    return ClangASTType (ast, ast->getPointerType(char_type).getAsOpaquePtr());
 }
 
 clang::DeclContext *
@@ -1019,21 +1042,20 @@
     return ast->getTranslationUnitDecl();
 }
 
-clang_type_t
+ClangASTType
 ClangASTContext::CopyType (ASTContext *dst_ast, 
-                           ASTContext *src_ast,
-                           clang_type_t clang_type)
+                           ClangASTType src)
 {
     FileSystemOptions file_system_options;
+    ASTContext *src_ast = src.GetASTContext();
     FileManager file_manager (file_system_options);
     ASTImporter importer(*dst_ast, file_manager,
                          *src_ast, file_manager,
                          false);
     
-    QualType src (QualType::getFromOpaquePtr(clang_type));
-    QualType dst (importer.Import(src));
+    QualType dst (importer.Import(src.GetQualType()));
     
-    return dst.getAsOpaquePtr();
+    return ClangASTType (dst_ast, dst.getAsOpaquePtr());
 }
 
 
@@ -1052,16 +1074,19 @@
 }
 
 bool
-ClangASTContext::AreTypesSame (ASTContext *ast,
-                               clang_type_t type1,
-                               clang_type_t type2,
+ClangASTContext::AreTypesSame (ClangASTType type1,
+                               ClangASTType type2,
                                bool ignore_qualifiers)
 {
-    if (type1 == type2)
+    ASTContext *ast = type1.GetASTContext();
+    if (ast != type2.GetASTContext())
+        return false;
+
+    if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
         return true;
 
-    QualType type1_qual = QualType::getFromOpaquePtr(type1);
-    QualType type2_qual = QualType::getFromOpaquePtr(type2);
+    QualType type1_qual = type1.GetQualType();
+    QualType type2_qual = type2.GetQualType();
     
     if (ignore_qualifiers)
     {
@@ -1069,74 +1094,37 @@
         type2_qual = type2_qual.getUnqualifiedType();
     }
     
-    return ast->hasSameType (type1_qual,
-                             type2_qual);
-}
-
-#pragma mark CVR modifiers
-
-clang_type_t
-ClangASTContext::AddConstModifier (clang_type_t clang_type)
-{
-    if (clang_type)
-    {
-        QualType result(QualType::getFromOpaquePtr(clang_type));
-        result.addConst();
-        return result.getAsOpaquePtr();
-    }
-    return NULL;
-}
-
-clang_type_t
-ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
-{
-    if (clang_type)
-    {
-        QualType result(QualType::getFromOpaquePtr(clang_type));
-        result.getQualifiers().setRestrict (true);
-        return result.getAsOpaquePtr();
-    }
-    return NULL;
-}
-
-clang_type_t
-ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
-{
-    if (clang_type)
-    {
-        QualType result(QualType::getFromOpaquePtr(clang_type));
-        result.getQualifiers().setVolatile (true);
-        return result.getAsOpaquePtr();
-    }
-    return NULL;
+    return ast->hasSameType (type1_qual, type2_qual);
 }
 
 
-clang_type_t
+ClangASTType
 ClangASTContext::GetTypeForDecl (TagDecl *decl)
 {
     // No need to call the getASTContext() accessor (which can create the AST
     // if it isn't created yet, because we can't have created a decl in this
     // AST if our AST didn't already exist...
-    if (m_ast_ap.get())
-        return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr();
-    return NULL;
+    ASTContext *ast = m_ast_ap.get();
+    if (ast)
+        return ClangASTType (ast, ast->getTagDeclType(decl).getAsOpaquePtr());
+    return ClangASTType();
 }
 
-clang_type_t
+ClangASTType
 ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
 {
     // No need to call the getASTContext() accessor (which can create the AST
     // if it isn't created yet, because we can't have created a decl in this
     // AST if our AST didn't already exist...
-    if (m_ast_ap.get())
-        return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr();
-    return NULL;
+    ASTContext *ast = m_ast_ap.get();
+    if (ast)
+        return ClangASTType (ast, ast->getObjCInterfaceType(decl).getAsOpaquePtr());
+    return ClangASTType();
 }
 
 #pragma mark Structure, Unions, Classes
 
-clang_type_t
+ClangASTType
 ClangASTContext::CreateRecordType (DeclContext *decl_ctx,
                                    AccessType access_type,
                                    const char *name,
@@ -1181,9 +1169,9 @@
         if (decl_ctx)
             decl_ctx->addDecl (decl);
 
-        return ast->getTagDeclType(decl).getAsOpaquePtr();
+        return ClangASTType(ast, ast->getTagDeclType(decl).getAsOpaquePtr());
     }
-    return NULL;
+    return ClangASTType();
 }
 
 static TemplateParameterList *
@@ -1385,85 +1373,16 @@
     return class_template_specialization_decl;
 }
 
-lldb::clang_type_t
+ClangASTType
 ClangASTContext::CreateClassTemplateSpecializationType (ClassTemplateSpecializationDecl *class_template_specialization_decl)
 {
     if (class_template_specialization_decl)
     {
         ASTContext *ast = getASTContext();
         if (ast)
-            return ast->getTagDeclType(class_template_specialization_decl).getAsOpaquePtr();
+            return ClangASTType(ast, ast->getTagDeclType(class_template_specialization_decl).getAsOpaquePtr());
     }
-    return NULL;
-}
-
-bool
-ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern)
-{
-    if (clang_type == NULL)
-        return false;
-
-    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-    case clang::Type::Record:
-        {
-            CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-            if (cxx_record_decl)
-            {
-                cxx_record_decl->setHasExternalLexicalStorage (has_extern);
-                cxx_record_decl->setHasExternalVisibleStorage (has_extern);
-                return true;
-            }
-        }
-        break;
-
-    case clang::Type::Enum:
-        {
-            EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
-            if (enum_decl)
-            {
-                enum_decl->setHasExternalLexicalStorage (has_extern);
-                enum_decl->setHasExternalVisibleStorage (has_extern);
-                return true;
-            }
-        }
-        break;
-
-    case clang::Type::ObjCObject:
-    case clang::Type::ObjCInterface:
-        {
-            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
-            assert (objc_class_type);
-            if (objc_class_type)
-            {
-                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-            
-                if (class_interface_decl)
-                {
-                    class_interface_decl->setHasExternalLexicalStorage (has_extern);
-                    class_interface_decl->setHasExternalVisibleStorage (has_extern);
-                    return true;
-                }
-            }
-        }
-        break;
-
-    case clang::Type::Typedef:
-        return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
-    
-    case clang::Type::Elaborated:
-        return ClangASTContext::SetHasExternalStorage (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), has_extern);
-
-    case clang::Type::Paren:
-        return ClangASTContext::SetHasExternalStorage (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr(), has_extern);
-
-    default:
-        break;
-    }
-    return false;
+    return ClangASTType();
 }
 
 static bool
@@ -1722,364 +1641,8 @@
     return false;
 }
 
-CXXMethodDecl *
-ClangASTContext::AddMethodToCXXRecordType
-(
-    ASTContext *ast,
-    clang_type_t record_opaque_type,
-    const char *name,
-    clang_type_t method_opaque_type,
-    lldb::AccessType access,
-    bool is_virtual,
-    bool is_static,
-    bool is_inline,
-    bool is_explicit,
-    bool is_attr_used,
-    bool is_artificial
-)
-{
-    if (!record_opaque_type || !method_opaque_type || !name)
-        return NULL;
-    
-    assert(ast);
-    
-    IdentifierTable *identifier_table = &ast->Idents;
-    
-    assert(identifier_table);
-    
-    QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
-
-    CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
-    
-    if (cxx_record_decl == NULL)
-        return NULL;
-    
-    QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
-    
-    CXXMethodDecl *cxx_method_decl = NULL;
-    
-    DeclarationName decl_name (&identifier_table->get(name));
-
-    const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
-    
-    if (function_Type == NULL)
-        return NULL;
-
-    const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
-    
-    if (!method_function_prototype)
-        return NULL;
-    
-    unsigned int num_params = method_function_prototype->getNumArgs();
-    
-    CXXDestructorDecl *cxx_dtor_decl(NULL);
-    CXXConstructorDecl *cxx_ctor_decl(NULL);
-    
-    if (is_artificial)
-        return NULL; // skip everything artificial
-    
-    if (name[0] == '~')
-    {
-        cxx_dtor_decl = CXXDestructorDecl::Create (*ast,
-                                                   cxx_record_decl,
-                                                   SourceLocation(),
-                                                   DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
-                                                   method_qual_type,
-                                                   NULL,
-                                                   is_inline,
-                                                   is_artificial);
-        cxx_method_decl = cxx_dtor_decl;
-    }
-    else if (decl_name == cxx_record_decl->getDeclName())
-    {
-       cxx_ctor_decl = CXXConstructorDecl::Create (*ast,
-                                                   cxx_record_decl,
-                                                   SourceLocation(),
-                                                   DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
-                                                   method_qual_type,
-                                                   NULL, // TypeSourceInfo *
-                                                   is_explicit, 
-                                                   is_inline,
-                                                   is_artificial,
-                                                   false /*is_constexpr*/);
-        cxx_method_decl = cxx_ctor_decl;
-    }
-    else
-    {   
-        clang::StorageClass SC = is_static ? SC_Static : SC_None; 
-        OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
-
-        if (IsOperator (name, op_kind))
-        {
-            if (op_kind != NUM_OVERLOADED_OPERATORS)
-            {
-                // Check the number of operator parameters. Sometimes we have 
-                // seen bad DWARF that doesn't correctly describe operators and
-                // if we try to create a methed and add it to the class, clang
-                // will assert and crash, so we need to make sure things are
-                // acceptable.
-                if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params))
-                    return NULL;
-                cxx_method_decl = CXXMethodDecl::Create (*ast,
-                                                         cxx_record_decl,
-                                                         SourceLocation(),
-                                                         DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
-                                                         method_qual_type,
-                                                         NULL, // TypeSourceInfo *
-                                                         SC,
-                                                         is_inline,
-                                                         false /*is_constexpr*/,
-                                                         SourceLocation());
-            }
-            else if (num_params == 0)
-            {
-                // Conversion operators don't take params...
-                cxx_method_decl = CXXConversionDecl::Create (*ast,
-                                                             cxx_record_decl,
-                                                             SourceLocation(),
-                                                             DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
-                                                             method_qual_type,
-                                                             NULL, // TypeSourceInfo *
-                                                             is_inline,
-                                                             is_explicit,
-                                                             false /*is_constexpr*/,
-                                                             SourceLocation());
-            }
-        }
-        
-        if (cxx_method_decl == NULL)
-        {
-            cxx_method_decl = CXXMethodDecl::Create (*ast,
-                                                     cxx_record_decl,
-                                                     SourceLocation(),
-                                                     DeclarationNameInfo (decl_name, SourceLocation()),
-                                                     method_qual_type,
-                                                     NULL, // TypeSourceInfo *
-                                                     SC,
-                                                     is_inline,
-                                                     false /*is_constexpr*/,
-                                                     SourceLocation());
-        }
-    }
-
-    AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
-    
-    cxx_method_decl->setAccess (access_specifier);
-    cxx_method_decl->setVirtualAsWritten (is_virtual);
-    
-    if (is_attr_used)
-        cxx_method_decl->addAttr(::new (*ast) UsedAttr(SourceRange(), *ast));
-    
-    // Populate the method decl with parameter decls
-    
-    llvm::SmallVector<ParmVarDecl *, 12> params;
-    
-    for (unsigned param_index = 0;
-         param_index < num_params;
-         ++param_index)
-    {
-        params.push_back (ParmVarDecl::Create (*ast,
-                                               cxx_method_decl,
-                                               SourceLocation(),
-                                               SourceLocation(),
-                                               NULL, // anonymous
-                                               method_function_prototype->getArgType(param_index), 
-                                               NULL,
-                                               SC_None,
-                                               NULL));
-    }
-    
-    cxx_method_decl->setParams (ArrayRef<ParmVarDecl*>(params));
-    
-    cxx_record_decl->addDecl (cxx_method_decl);
-    
-    // Sometimes the debug info will mention a constructor (default/copy/move), 
-    // destructor, or assignment operator (copy/move) but there won't be any
-    // version of this in the code. So we check if the function was artificially
-    // generated and if it is trivial and this lets the compiler/backend know
-    // that it can inline the IR for these when it needs to and we can avoid a
-    // "missing function" error when running expressions.
-    
-    if (is_artificial)
-    {
-        if (cxx_ctor_decl && 
-            ((cxx_ctor_decl->isDefaultConstructor() && cxx_record_decl->hasTrivialDefaultConstructor ()) ||
-             (cxx_ctor_decl->isCopyConstructor()    && cxx_record_decl->hasTrivialCopyConstructor    ()) ||
-             (cxx_ctor_decl->isMoveConstructor()    && cxx_record_decl->hasTrivialMoveConstructor    ()) ))
-        {
-            cxx_ctor_decl->setDefaulted();
-            cxx_ctor_decl->setTrivial(true);
-        }
-        else if (cxx_dtor_decl)
-        {
-            if (cxx_record_decl->hasTrivialDestructor())
-            {
-                cxx_dtor_decl->setDefaulted();
-                cxx_dtor_decl->setTrivial(true);
-            }
-        }
-        else if ((cxx_method_decl->isCopyAssignmentOperator() && cxx_record_decl->hasTrivialCopyAssignment()) ||
-                 (cxx_method_decl->isMoveAssignmentOperator() && cxx_record_decl->hasTrivialMoveAssignment()))
-        {
-            cxx_method_decl->setDefaulted();
-            cxx_method_decl->setTrivial(true);
-        }
-    }
-    
-#ifdef LLDB_CONFIGURATION_DEBUG
-    VerifyDecl(cxx_method_decl);
-#endif
-
-//    printf ("decl->isPolymorphic()             = %i\n", cxx_record_decl->isPolymorphic());
-//    printf ("decl->isAggregate()               = %i\n", cxx_record_decl->isAggregate());
-//    printf ("decl->isPOD()                     = %i\n", cxx_record_decl->isPOD());
-//    printf ("decl->isEmpty()                   = %i\n", cxx_record_decl->isEmpty());
-//    printf ("decl->isAbstract()                = %i\n", cxx_record_decl->isAbstract());
-//    printf ("decl->hasTrivialConstructor()     = %i\n", cxx_record_decl->hasTrivialConstructor());
-//    printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
-//    printf ("decl->hasTrivialCopyAssignment()  = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
-//    printf ("decl->hasTrivialDestructor()      = %i\n", cxx_record_decl->hasTrivialDestructor());
-    return cxx_method_decl;
-}
-
-clang::FieldDecl *
-ClangASTContext::AddFieldToRecordType 
-(
-    ASTContext *ast,
-    clang_type_t record_clang_type, 
-    const char *name, 
-    clang_type_t field_type, 
-    AccessType access, 
-    uint32_t bitfield_bit_size
-)
-{
-    if (record_clang_type == NULL || field_type == NULL)
-        return NULL;
-
-    FieldDecl *field = NULL;
-    IdentifierTable *identifier_table = &ast->Idents;
-
-    assert (ast != NULL);
-    assert (identifier_table != NULL);
-
-    QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
-
-    const clang::Type *clang_type = record_qual_type.getTypePtr();
-    if (clang_type)
-    {
-        const RecordType *record_type = dyn_cast<RecordType>(clang_type);
-
-        if (record_type)
-        {
-            RecordDecl *record_decl = record_type->getDecl();
-
-            clang::Expr *bit_width = NULL;
-            if (bitfield_bit_size != 0)
-            {
-                APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
-                bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
-            }
-            field = FieldDecl::Create (*ast,
-                                       record_decl,
-                                       SourceLocation(),
-                                       SourceLocation(),
-                                       name ? &identifier_table->get(name) : NULL, // Identifier
-                                       QualType::getFromOpaquePtr(field_type), // Field type
-                                       NULL,            // TInfo *
-                                       bit_width,       // BitWidth
-                                       false,           // Mutable
-                                       ICIS_NoInit);    // HasInit
-            
-            if (!name) {
-                // Determine whether this field corresponds to an anonymous
-                // struct or union.
-                if (const TagType *TagT = field->getType()->getAs<TagType>()) {
-                  if (RecordDecl *Rec = dyn_cast<RecordDecl>(TagT->getDecl()))
-                    if (!Rec->getDeclName()) {
-                      Rec->setAnonymousStructOrUnion(true);
-                      field->setImplicit();
-
-                    }
-                }
-            }
-
-            if (field)
-            {
-                field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
-                
-                record_decl->addDecl(field);
-                
-#ifdef LLDB_CONFIGURATION_DEBUG
-                VerifyDecl(field);
-#endif
-            }
-        }
-        else
-        {
-            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
-            if (objc_class_type)
-            {
-                bool is_synthesized = false;
-                field = ClangASTContext::AddObjCClassIVar (ast,
-                                                           record_clang_type,
-                                                           name,
-                                                           field_type,
-                                                           access,
-                                                           bitfield_bit_size,
-                                                           is_synthesized);
-            }
-        }
-    }
-    return field;
-}
-
-clang::VarDecl *
-ClangASTContext::AddVariableToRecordType (clang::ASTContext *ast,
-                                          lldb::clang_type_t record_opaque_type,
-                                          const char *name,
-                                          lldb::clang_type_t var_type,
-                                          AccessType access)
-{
-    clang::VarDecl *var_decl = NULL;
-
-    if (record_opaque_type == NULL || var_type == NULL)
-        return NULL;
-    
-    IdentifierTable *identifier_table = &ast->Idents;
-    
-    assert (ast != NULL);
-    assert (identifier_table != NULL);
-    
-    const RecordType *record_type = dyn_cast<RecordType>(QualType::getFromOpaquePtr(record_opaque_type).getTypePtr());
-    
-    if (record_type)
-    {
-        RecordDecl *record_decl = record_type->getDecl();
-        
-        var_decl = VarDecl::Create (*ast,                                       // ASTContext &
-                                    record_decl,                                // DeclContext *
-                                    SourceLocation(),                           // SourceLocation StartLoc
-                                    SourceLocation(),                           // SourceLocation IdLoc
-                                    name ? &identifier_table->get(name) : NULL, // IdentifierInfo *
-                                    QualType::getFromOpaquePtr(var_type),       // Variable QualType
-                                    NULL,                                       // TypeSourceInfo *
-                                    SC_Static);                                 // StorageClass
-        if (var_decl)
-        {
-            var_decl->setAccess(ConvertAccessTypeToAccessSpecifier (access));
-            record_decl->addDecl(var_decl);
-                
-#ifdef LLDB_CONFIGURATION_DEBUG
-            VerifyDecl(var_decl);
-#endif
-        }
-    }
-    return var_decl;
-}
-
-
-static clang::AccessSpecifier UnifyAccessSpecifiers (clang::AccessSpecifier lhs,
-                                                     clang::AccessSpecifier rhs)
+clang::AccessSpecifier
+ClangASTContext::UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs)
 {
     clang::AccessSpecifier ret = lhs;
     
@@ -2102,115 +1665,6 @@
     return ret;
 }
 
-void
-ClangASTContext::BuildIndirectFields (clang::ASTContext *ast,
-                                      lldb::clang_type_t record_clang_type)
-{
-    QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
-
-    const RecordType *record_type = record_qual_type->getAs<RecordType>();
-    
-    if (!record_type)
-        return;
-    
-    RecordDecl *record_decl = record_type->getDecl();
-    
-    if (!record_decl)
-        return;
-    
-    typedef llvm::SmallVector <IndirectFieldDecl *, 1> IndirectFieldVector;
-    
-    IndirectFieldVector indirect_fields;
-    RecordDecl::field_iterator field_pos;
-    RecordDecl::field_iterator field_end_pos = record_decl->field_end();
-    RecordDecl::field_iterator last_field_pos = field_end_pos;
-    for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; last_field_pos = field_pos++)
-    {
-        if (field_pos->isAnonymousStructOrUnion())
-        {
-            QualType field_qual_type = field_pos->getType();
-            
-            const RecordType *field_record_type = field_qual_type->getAs<RecordType>();
-            
-            if (!field_record_type)
-                continue;
-            
-            RecordDecl *field_record_decl = field_record_type->getDecl();
-            
-            if (!field_record_decl)
-                continue;
-            
-            for (RecordDecl::decl_iterator di = field_record_decl->decls_begin(), de = field_record_decl->decls_end();
-                 di != de;
-                 ++di)
-            {
-                if (FieldDecl *nested_field_decl = dyn_cast<FieldDecl>(*di))
-                {
-                    NamedDecl **chain = new (*ast) NamedDecl*[2];
-                    chain[0] = *field_pos;
-                    chain[1] = nested_field_decl;
-                    IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast,
-                                                                                  record_decl,
-                                                                                  SourceLocation(),
-                                                                                  nested_field_decl->getIdentifier(),
-                                                                                  nested_field_decl->getType(),
-                                                                                  chain,
-                                                                                  2);
-                    
-                    indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(),
-                                                                    nested_field_decl->getAccess()));
-                    
-                    indirect_fields.push_back(indirect_field);
-                }
-                else if (IndirectFieldDecl *nested_indirect_field_decl = dyn_cast<IndirectFieldDecl>(*di))
-                {
-                    int nested_chain_size = nested_indirect_field_decl->getChainingSize();
-                    NamedDecl **chain = new (*ast) NamedDecl*[nested_chain_size + 1];
-                    chain[0] = *field_pos;
-                    
-                    int chain_index = 1;
-                    for (IndirectFieldDecl::chain_iterator nci = nested_indirect_field_decl->chain_begin(),
-                         nce = nested_indirect_field_decl->chain_end();
-                         nci < nce;
-                         ++nci)
-                    {
-                        chain[chain_index] = *nci;
-                        chain_index++;
-                    }
-                    
-                    IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast,
-                                                                                  record_decl,
-                                                                                  SourceLocation(),
-                                                                                  nested_indirect_field_decl->getIdentifier(),
-                                                                                  nested_indirect_field_decl->getType(),
-                                                                                  chain,
-                                                                                  nested_chain_size + 1);
-                                        
-                    indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(),
-                                                                    nested_indirect_field_decl->getAccess()));
-                    
-                    indirect_fields.push_back(indirect_field);
-                }
-            }
-        }
-    }
-    
-    // Check the last field to see if it has an incomplete array type as its
-    // last member and if it does, the tell the record decl about it
-    if (last_field_pos != field_end_pos)
-    {
-        if (last_field_pos->getType()->isIncompleteArrayType())
-            record_decl->hasFlexibleArrayMember();
-    }
-    
-    for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), ife = indirect_fields.end();
-         ifi < ife;
-         ++ifi)
-    {
-        record_decl->addDecl(*ifi);
-    }
-}
-
 bool
 ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
 {
@@ -2270,76 +1724,9 @@
     return false;
 }
 
-void
-ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
-{
-    if (clang_type)
-    {
-        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-
-        const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
-        if (record_type)
-        {
-            RecordDecl *record_decl = record_type->getDecl();
-            if (record_decl)
-            {
-                uint32_t field_idx;
-                RecordDecl::field_iterator field, field_end;
-                for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
-                     field != field_end;
-                     ++field, ++field_idx)
-                {
-                    // If no accessibility was assigned, assign the correct one
-                    if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
-                        field->setAccess ((AccessSpecifier)default_accessibility);
-                }
-            }
-        }
-    }
-}
-
-#pragma mark C++ Base Classes
-
-CXXBaseSpecifier *
-ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
-{
-    if (base_class_type)
-        return new CXXBaseSpecifier (SourceRange(), 
-                                     is_virtual, 
-                                     base_of_class, 
-                                     ConvertAccessTypeToAccessSpecifier (access), 
-                                     getASTContext()->getTrivialTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
-                                     SourceLocation());
-    return NULL;
-}
-
-void
-ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
-{
-    for (unsigned i=0; i<num_base_classes; ++i)
-    {
-        delete base_classes[i];
-        base_classes[i] = NULL;
-    }
-}
-
-bool
-ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
-{
-    if (class_clang_type)
-    {
-        CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
-        if (cxx_record_decl)
-        {
-            cxx_record_decl->setBases(base_classes, num_base_classes);
-            return true;
-        }
-    }
-    return false;
-}
 #pragma mark Objective C Classes
 
-clang_type_t
+ClangASTType
 ClangASTContext::CreateObjCClass
 (
     const char *name, 
@@ -2355,11 +1742,6 @@
     if (decl_ctx == NULL)
         decl_ctx = ast->getTranslationUnitDecl();
 
-    // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
-    // we will need to update this code. I was told to currently always use
-    // the CXXRecordDecl class since we often don't know from debug information
-    // if something is struct or a class, so we default to always use the more
-    // complete definition just in case.
     ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
                                                          decl_ctx,
                                                          SourceLocation(),
@@ -2372,2286 +1754,7 @@
     if (decl && metadata)
         SetMetadata(ast, decl, *metadata);
     
-    return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
-}
-
-bool
-ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
-{
-    if (class_opaque_type && super_opaque_type)
-    {
-        QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
-        QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
-        const clang::Type *class_type = class_qual_type.getTypePtr();
-        const clang::Type *super_type = super_qual_type.getTypePtr();
-        if (class_type && super_type)
-        {
-            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
-            const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
-            if (objc_class_type && objc_super_type)
-            {
-                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
-                if (class_interface_decl && super_interface_decl)
-                {
-                    class_interface_decl->setSuperClass(super_interface_decl);
-                    return true;
-                }
-            }
-        }
-    }
-    return false;
-}
-
-
-FieldDecl *
-ClangASTContext::AddObjCClassIVar 
-(
-    ASTContext *ast,
-    clang_type_t class_opaque_type, 
-    const char *name, 
-    clang_type_t ivar_opaque_type, 
-    AccessType access, 
-    uint32_t bitfield_bit_size, 
-    bool is_synthesized
-)
-{
-    if (class_opaque_type == NULL || ivar_opaque_type == NULL)
-        return NULL;
-
-    ObjCIvarDecl *field = NULL;
-    
-    IdentifierTable *identifier_table = &ast->Idents;
-
-    assert (ast != NULL);
-    assert (identifier_table != NULL);
-
-    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
-
-    const clang::Type *class_type = class_qual_type.getTypePtr();
-    if (class_type)
-    {
-        const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
-
-        if (objc_class_type)
-        {
-            ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-            
-            if (class_interface_decl)
-            {
-                clang::Expr *bit_width = NULL;
-                if (bitfield_bit_size != 0)
-                {
-                    APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
-                    bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
-                }
-                
-                field = ObjCIvarDecl::Create (*ast,
-                                              class_interface_decl,
-                                              SourceLocation(),
-                                              SourceLocation(),
-                                              name ? &identifier_table->get(name) : NULL, // Identifier
-                                              QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
-                                              NULL, // TypeSourceInfo *
-                                              ConvertAccessTypeToObjCIvarAccessControl (access),
-                                              bit_width,
-                                              is_synthesized);
-                
-                if (field)
-                {
-                    class_interface_decl->addDecl(field);
-                    
-#ifdef LLDB_CONFIGURATION_DEBUG
-                    VerifyDecl(field);
-#endif
-                    
-                    return field;
-                }
-            }
-        }
-    }
-    return NULL;
-}
-
-bool
-ClangASTContext::AddObjCClassProperty 
-(
-    ASTContext *ast,
-    clang_type_t class_opaque_type, 
-    const char *property_name,
-    clang_type_t property_opaque_type,  
-    ObjCIvarDecl *ivar_decl,
-    const char *property_setter_name,
-    const char *property_getter_name,
-    uint32_t property_attributes,
-    ClangASTMetadata *metadata
-)
-{
-    if (class_opaque_type == NULL || property_name == NULL || property_name[0] == '\0')
-        return false;
-
-    IdentifierTable *identifier_table = &ast->Idents;
-
-    assert (ast != NULL);
-    assert (identifier_table != NULL);
-
-    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
-    const clang::Type *class_type = class_qual_type.getTypePtr();
-    if (class_type)
-    {
-        const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
-
-        if (objc_class_type)
-        {
-            ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-            
-            clang_type_t property_opaque_type_to_access = NULL;
-            
-            if (property_opaque_type)
-                property_opaque_type_to_access = property_opaque_type;
-            else if (ivar_decl)
-                property_opaque_type_to_access = ivar_decl->getType().getAsOpaquePtr();
-                        
-            if (class_interface_decl && property_opaque_type_to_access)
-            {
-                clang::TypeSourceInfo *prop_type_source;
-                if (ivar_decl)
-                    prop_type_source = ast->getTrivialTypeSourceInfo (ivar_decl->getType());
-                else
-                    prop_type_source = ast->getTrivialTypeSourceInfo (QualType::getFromOpaquePtr(property_opaque_type));
-                
-                ObjCPropertyDecl *property_decl = ObjCPropertyDecl::Create(*ast, 
-                                                                           class_interface_decl, 
-                                                                           SourceLocation(), // Source Location
-                                                                           &identifier_table->get(property_name),
-                                                                           SourceLocation(), //Source Location for AT
-                                                                           SourceLocation(), //Source location for (
-                                                                           prop_type_source
-                                                                           );
-                
-                if (property_decl)
-                {
-                    if (metadata)
-                        SetMetadata(ast, property_decl, *metadata);
-                    
-                    class_interface_decl->addDecl (property_decl);
-                    
-                    Selector setter_sel, getter_sel;
-                    
-                    if (property_setter_name != NULL)
-                    {
-                        std::string property_setter_no_colon(property_setter_name, strlen(property_setter_name) - 1);
-                        clang::IdentifierInfo *setter_ident = &identifier_table->get(property_setter_no_colon.c_str());
-                        setter_sel = ast->Selectors.getSelector(1, &setter_ident);
-                    }
-                    else if (!(property_attributes & DW_APPLE_PROPERTY_readonly))
-                    {
-                        std::string setter_sel_string("set");
-                        setter_sel_string.push_back(::toupper(property_name[0]));
-                        setter_sel_string.append(&property_name[1]);
-                        clang::IdentifierInfo *setter_ident = &identifier_table->get(setter_sel_string.c_str());
-                        setter_sel = ast->Selectors.getSelector(1, &setter_ident);
-                    }
-                    property_decl->setSetterName(setter_sel);
-                    property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_setter);
-                    
-                    if (property_getter_name != NULL)
-                    {
-                        clang::IdentifierInfo *getter_ident = &identifier_table->get(property_getter_name);
-                        getter_sel = ast->Selectors.getSelector(0, &getter_ident);
-                    }
-                    else
-                    {
-                        clang::IdentifierInfo *getter_ident = &identifier_table->get(property_name);
-                        getter_sel = ast->Selectors.getSelector(0, &getter_ident);
-                    }
-                    property_decl->setGetterName(getter_sel);
-                    property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_getter);
-                        
-                    if (ivar_decl)
-                        property_decl->setPropertyIvarDecl (ivar_decl);
-                        
-                    if (property_attributes & DW_APPLE_PROPERTY_readonly) 
-                        property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readonly);
-                    if (property_attributes & DW_APPLE_PROPERTY_readwrite) 
-                        property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readwrite);
-                    if (property_attributes & DW_APPLE_PROPERTY_assign) 
-                        property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_assign);
-                    if (property_attributes & DW_APPLE_PROPERTY_retain) 
-                        property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_retain);
-                    if (property_attributes & DW_APPLE_PROPERTY_copy) 
-                        property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_copy);
-                    if (property_attributes & DW_APPLE_PROPERTY_nonatomic) 
-                        property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_nonatomic);
-                        
-                    if (!getter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(getter_sel))
-                    {
-                        QualType result_type = QualType::getFromOpaquePtr(property_opaque_type_to_access);
-                        
-                        const bool isInstance = true;
-                        const bool isVariadic = false;
-                        const bool isSynthesized = false;
-                        const bool isImplicitlyDeclared = true;
-                        const bool isDefined = false;
-                        const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None;
-                        const bool HasRelatedResultType = false;
-                        
-                        ObjCMethodDecl *getter = ObjCMethodDecl::Create(*ast, 
-                                                                        SourceLocation(), 
-                                                                        SourceLocation(), 
-                                                                        getter_sel, 
-                                                                        result_type,
-                                                                        NULL, 
-                                                                        class_interface_decl,
-                                                                        isInstance,
-                                                                        isVariadic,
-                                                                        isSynthesized,
-                                                                        isImplicitlyDeclared,
-                                                                        isDefined,
-                                                                        impControl,
-                                                                        HasRelatedResultType);
-                        
-                        if (getter && metadata)
-                            SetMetadata(ast, getter, *metadata);
-                                                
-                        getter->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(), ArrayRef<SourceLocation>());
-                        
-                        class_interface_decl->addDecl(getter);
-                    }
-                    
-                    if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel))
-                    {
-                        QualType result_type = ast->VoidTy;
-                        
-                        const bool isInstance = true;
-                        const bool isVariadic = false;
-                        const bool isSynthesized = false;
-                        const bool isImplicitlyDeclared = true;
-                        const bool isDefined = false;
-                        const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None;
-                        const bool HasRelatedResultType = false;
-                        
-                        ObjCMethodDecl *setter = ObjCMethodDecl::Create(*ast, 
-                                                                        SourceLocation(), 
-                                                                        SourceLocation(), 
-                                                                        setter_sel, 
-                                                                        result_type,
-                                                                        NULL, 
-                                                                        class_interface_decl,
-                                                                        isInstance,
-                                                                        isVariadic,
-                                                                        isSynthesized,
-                                                                        isImplicitlyDeclared,
-                                                                        isDefined,
-                                                                        impControl,
-                                                                        HasRelatedResultType);
-                        
-                        if (setter && metadata)
-                            SetMetadata(ast, setter, *metadata);
-                        
-                        llvm::SmallVector<ParmVarDecl *, 1> params;
-
-                        params.push_back (ParmVarDecl::Create (*ast,
-                                                               setter,
-                                                               SourceLocation(),
-                                                               SourceLocation(),
-                                                               NULL, // anonymous
-                                                               QualType::getFromOpaquePtr(property_opaque_type_to_access), 
-                                                               NULL,
-                                                               SC_Auto,
-                                                               NULL));
-                        
-                        setter->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>());
-                        
-                        class_interface_decl->addDecl(setter);
-                    }
-
-                    return true;
-                }
-            }
-        }
-    }
-    return false;
-}
-
-bool
-ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
-{
-    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
-
-    const clang::Type *class_type = class_qual_type.getTypePtr();
-    if (class_type)
-    {
-        const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
-
-        if (objc_class_type)
-            return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
-    }
-    return false;            
-}
-
-bool
-ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
-{
-    while (class_interface_decl)
-    {
-        if (class_interface_decl->ivar_size() > 0)
-            return true;
-        
-        if (check_superclass)
-            class_interface_decl = class_interface_decl->getSuperClass();
-        else
-            break;
-    }
-    return false;            
-}
-
-ObjCMethodDecl *
-ClangASTContext::AddMethodToObjCObjectType (ASTContext *ast,
-                                            clang_type_t class_opaque_type,
-                                            const char *name,  // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
-                                            clang_type_t method_opaque_type,
-                                            lldb::AccessType access,
-                                            bool is_artificial)
-{
-    if (class_opaque_type == NULL || method_opaque_type == NULL)
-        return NULL;
-
-    IdentifierTable *identifier_table = &ast->Idents;
-
-    assert (ast != NULL);
-    assert (identifier_table != NULL);
-
-    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
-
-    const clang::Type *class_type = class_qual_type.getTypePtr();
-    if (class_type == NULL)
-        return NULL;
-
-    const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
-
-    if (objc_class_type == NULL)
-        return NULL;
-
-    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-            
-    if (class_interface_decl == NULL)
-        return NULL;
-    
-    const char *selector_start = ::strchr (name, ' ');
-    if (selector_start == NULL)
-        return NULL;
-    
-    selector_start++;
-    llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
-
-    size_t len = 0;
-    const char *start;
-    //printf ("name = '%s'\n", name);
-
-    unsigned num_selectors_with_args = 0;
-    for (start = selector_start;
-         start && *start != '\0' && *start != ']';
-         start += len)
-    {
-        len = ::strcspn(start, ":]");
-        bool has_arg = (start[len] == ':');
-        if (has_arg)
-            ++num_selectors_with_args;
-        selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
-        if (has_arg)
-            len += 1;
-    }
-
-    
-    if (selector_idents.size() == 0)
-        return 0;
-
-    clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0, 
-                                                                          selector_idents.data());
-    
-    QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
-
-    // Populate the method decl with parameter decls
-    const clang::Type *method_type(method_qual_type.getTypePtr());
-    
-    if (method_type == NULL)
-        return NULL;
-    
-    const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
-    
-    if (!method_function_prototype)
-        return NULL;
-    
-
-    bool is_variadic = false;
-    bool is_synthesized = false;
-    bool is_defined = false;
-    ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
-
-    const unsigned num_args = method_function_prototype->getNumArgs();
-    
-    if (num_args != num_selectors_with_args)
-        return NULL; // some debug information is corrupt.  We are not going to deal with it.
-
-    ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
-                                                               SourceLocation(), // beginLoc,
-                                                               SourceLocation(), // endLoc, 
-                                                               method_selector,
-                                                               method_function_prototype->getResultType(),
-                                                               NULL, // TypeSourceInfo *ResultTInfo,
-                                                               GetDeclContextForType (class_opaque_type),
-                                                               name[0] == '-',
-                                                               is_variadic,
-                                                               is_synthesized,
-                                                               true, // is_implicitly_declared; we force this to true because we don't have source locations
-                                                               is_defined,
-                                                               imp_control,
-                                                               false /*has_related_result_type*/);
-
-
-    if (objc_method_decl == NULL)
-        return NULL;
-
-    if (num_args > 0)
-    {
-        llvm::SmallVector<ParmVarDecl *, 12> params;
-            
-        for (unsigned param_index = 0; param_index < num_args; ++param_index)
-        {
-            params.push_back (ParmVarDecl::Create (*ast,
-                                                   objc_method_decl,
-                                                   SourceLocation(),
-                                                   SourceLocation(),
-                                                   NULL, // anonymous
-                                                   method_function_prototype->getArgType(param_index), 
-                                                   NULL,
-                                                   SC_Auto,
-                                                   NULL));
-        }
-        
-        objc_method_decl->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>());
-    }
-    
-    class_interface_decl->addDecl (objc_method_decl);
-
-#ifdef LLDB_CONFIGURATION_DEBUG
-    VerifyDecl(objc_method_decl);
-#endif
-
-    return objc_method_decl;
-}
-
-size_t
-ClangASTContext::GetNumTemplateArguments (clang::ASTContext *ast, clang_type_t clang_type)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-            case clang::Type::Record:
-                if (GetCompleteQualType (ast, qual_type))
-                {
-                    const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                    if (cxx_record_decl)
-                    {
-                        const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl);
-                        if (template_decl)
-                            return template_decl->getTemplateArgs().size();
-                    }
-                }
-                break;
-                
-            case clang::Type::Typedef:                         
-                return ClangASTContext::GetNumTemplateArguments (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-                
-            case clang::Type::Elaborated:
-                return ClangASTContext::GetNumTemplateArguments (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-
-            case clang::Type::Paren:
-                return ClangASTContext::GetNumTemplateArguments(ast, cast<ParenType>(qual_type)->desugar().getAsOpaquePtr());
-                
-            default:
-                break;
-        }
-    }
-    return 0;
-}
-
-clang_type_t
-ClangASTContext::GetTemplateArgument (clang::ASTContext *ast, clang_type_t clang_type, size_t arg_idx, lldb::TemplateArgumentKind &kind)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-            case clang::Type::Record:
-                if (GetCompleteQualType (ast, qual_type))
-                {
-                    const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                    if (cxx_record_decl)
-                    {
-                        const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl);
-                        if (template_decl && arg_idx < template_decl->getTemplateArgs().size())
-                        {
-                            const TemplateArgument &template_arg = template_decl->getTemplateArgs()[arg_idx];
-                            switch (template_arg.getKind())
-                            {
-                                case clang::TemplateArgument::Null:
-                                    kind = eTemplateArgumentKindNull;
-                                    return NULL;
-
-                                case clang::TemplateArgument::Type:
-                                    kind = eTemplateArgumentKindType;
-                                    return template_arg.getAsType().getAsOpaquePtr();
-
-                                case clang::TemplateArgument::Declaration:
-                                    kind = eTemplateArgumentKindDeclaration;
-                                    return NULL;
-
-                                case clang::TemplateArgument::Integral:
-                                    kind = eTemplateArgumentKindIntegral;
-                                    return template_arg.getIntegralType().getAsOpaquePtr();
-
-                                case clang::TemplateArgument::Template:
-                                    kind = eTemplateArgumentKindTemplate;
-                                    return NULL;
-
-                                case clang::TemplateArgument::TemplateExpansion:
-                                    kind = eTemplateArgumentKindTemplateExpansion;
-                                    return NULL;
-
-                                case clang::TemplateArgument::Expression:
-                                    kind = eTemplateArgumentKindExpression;
-                                    return NULL;
-
-                                case clang::TemplateArgument::Pack:
-                                    kind = eTemplateArgumentKindPack;
-                                    return NULL;
-
-                                default:
-                                    assert (!"Unhandled TemplateArgument::ArgKind");
-                                    kind = eTemplateArgumentKindNull;
-                                    return NULL;
-                            }
-                        }
-                    }
-                }
-                break;
-                
-            case clang::Type::Typedef:                         
-                return ClangASTContext::GetTemplateArgument (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), arg_idx, kind);
-
-            case clang::Type::Elaborated:
-                return ClangASTContext::GetTemplateArgument (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), arg_idx, kind);
-               
-            case clang::Type::Paren:
-                return ClangASTContext::GetTemplateArgument(ast, cast<ParenType>(qual_type)->desugar().getAsOpaquePtr(), arg_idx, kind);
-                
-            default:
-                break;
-        }
-    }
-    kind = eTemplateArgumentKindNull;
-    return NULL;
-}
-
-uint32_t
-ClangASTContext::GetTypeInfo 
-(
-    clang_type_t clang_type, 
-    clang::ASTContext *ast, 
-    clang_type_t *pointee_or_element_clang_type
-)
-{
-    if (clang_type == NULL)
-        return 0;
-        
-    if (pointee_or_element_clang_type)
-        *pointee_or_element_clang_type = NULL;
-    
-    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-    case clang::Type::Builtin:
-        {
-            const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
-
-            uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
-            switch (builtin_type->getKind())
-            {
-            case clang::BuiltinType::ObjCId:
-            case clang::BuiltinType::ObjCClass:
-                if (ast && pointee_or_element_clang_type)
-                    *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
-                builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
-                break;
-
-            case clang::BuiltinType::ObjCSel:
-                if (ast && pointee_or_element_clang_type)
-                    *pointee_or_element_clang_type = ast->CharTy.getAsOpaquePtr();
-                builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
-                break;
-
-            case clang::BuiltinType::Bool:
-            case clang::BuiltinType::Char_U:
-            case clang::BuiltinType::UChar:
-            case clang::BuiltinType::WChar_U:
-            case clang::BuiltinType::Char16:
-            case clang::BuiltinType::Char32:
-            case clang::BuiltinType::UShort:
-            case clang::BuiltinType::UInt:
-            case clang::BuiltinType::ULong:
-            case clang::BuiltinType::ULongLong:
-            case clang::BuiltinType::UInt128:
-            case clang::BuiltinType::Char_S:
-            case clang::BuiltinType::SChar:
-            case clang::BuiltinType::WChar_S:
-            case clang::BuiltinType::Short:
-            case clang::BuiltinType::Int:
-            case clang::BuiltinType::Long:
-            case clang::BuiltinType::LongLong:
-            case clang::BuiltinType::Int128:
-            case clang::BuiltinType::Float:
-            case clang::BuiltinType::Double:
-            case clang::BuiltinType::LongDouble:
-                builtin_type_flags |= eTypeIsScalar;
-                if (builtin_type->isInteger())
-                {
-                    builtin_type_flags |= eTypeIsInteger;
-                    if (builtin_type->isSignedInteger())
-                        builtin_type_flags |= eTypeIsSigned;
-                }
-                else if (builtin_type->isFloatingPoint())
-                    builtin_type_flags |= eTypeIsFloat;
-                break;
-            default:
-                break;
-            }
-            return builtin_type_flags;
-        }
-
-    case clang::Type::BlockPointer:
-        if (pointee_or_element_clang_type)
-            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
-        return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
-
-    case clang::Type::Complex:
-        {
-            uint32_t complex_type_flags = eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
-            const ComplexType *complex_type = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal());
-            if (complex_type)
-            {
-                QualType complex_element_type (complex_type->getElementType());
-                if (complex_element_type->isIntegerType())
-                    complex_type_flags |= eTypeIsFloat;
-                else if (complex_element_type->isFloatingType())
-                    complex_type_flags |= eTypeIsInteger;
-            }
-            return complex_type_flags;
-        }
-        break;
-
-    case clang::Type::ConstantArray:
-    case clang::Type::DependentSizedArray:
-    case clang::Type::IncompleteArray:
-    case clang::Type::VariableArray:                    
-        if (pointee_or_element_clang_type)
-            *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
-        return eTypeHasChildren | eTypeIsArray;
-
-    case clang::Type::DependentName:                    return 0;
-    case clang::Type::DependentSizedExtVector:          return eTypeHasChildren | eTypeIsVector;
-    case clang::Type::DependentTemplateSpecialization:  return eTypeIsTemplate;
-    case clang::Type::Decltype:                         return 0;
-
-    case clang::Type::Enum:
-        if (pointee_or_element_clang_type)
-            *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
-        return eTypeIsEnumeration | eTypeHasValue;
-
-    case clang::Type::Elaborated:
-        return ClangASTContext::GetTypeInfo (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
-                                             ast, 
-                                             pointee_or_element_clang_type);
-
-    case clang::Type::Paren:
-        return ClangASTContext::GetTypeInfo(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
-                                            ast,
-                                            pointee_or_element_clang_type);
-
-    case clang::Type::FunctionProto:                    return eTypeIsFuncPrototype | eTypeHasValue;
-    case clang::Type::FunctionNoProto:                  return eTypeIsFuncPrototype | eTypeHasValue;
-    case clang::Type::InjectedClassName:                return 0;
-
-    case clang::Type::LValueReference:                  
-    case clang::Type::RValueReference:                  
-        if (pointee_or_element_clang_type)
-            *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
-        return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
-
-    case clang::Type::MemberPointer:                    return eTypeIsPointer   | eTypeIsMember | eTypeHasValue;
-
-    case clang::Type::ObjCObjectPointer:
-        if (pointee_or_element_clang_type)
-            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
-        return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
-
-    case clang::Type::ObjCObject:                       return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
-    case clang::Type::ObjCInterface:                    return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
-
-    case clang::Type::Pointer:                      	
-        if (pointee_or_element_clang_type)
-            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
-        return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
-
-    case clang::Type::Record:
-        if (qual_type->getAsCXXRecordDecl())
-            return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
-        else
-            return eTypeHasChildren | eTypeIsStructUnion;
-        break;
-    case clang::Type::SubstTemplateTypeParm:            return eTypeIsTemplate;
-    case clang::Type::TemplateTypeParm:                 return eTypeIsTemplate;
-    case clang::Type::TemplateSpecialization:           return eTypeIsTemplate;
-
-    case clang::Type::Typedef:                         
-        return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
-                                                                  ast, 
-                                                                  pointee_or_element_clang_type);
-
-    case clang::Type::TypeOfExpr:                       return 0;
-    case clang::Type::TypeOf:                           return 0;
-    case clang::Type::UnresolvedUsing:                  return 0;
-
-    case clang::Type::ExtVector:
-    case clang::Type::Vector:
-        {
-            uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
-            const VectorType *vector_type = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal());
-            if (vector_type)
-            {
-                if (vector_type->isIntegerType())
-                    vector_type_flags |= eTypeIsFloat;
-                else if (vector_type->isFloatingType())
-                    vector_type_flags |= eTypeIsInteger;
-            }
-            return vector_type_flags;
-        }
-    default:                                            return 0;
-    }
-    return 0;
-}
-
-
-#pragma mark Aggregate Types
-
-bool
-ClangASTContext::IsAggregateType (clang_type_t clang_type)
-{
-    if (clang_type == NULL)
-        return false;
-
-    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-    case clang::Type::IncompleteArray:
-    case clang::Type::VariableArray:
-    case clang::Type::ConstantArray:
-    case clang::Type::ExtVector:
-    case clang::Type::Vector:
-    case clang::Type::Record:
-    case clang::Type::ObjCObject:
-    case clang::Type::ObjCInterface:
-        return true;
-    case clang::Type::Elaborated:
-        return ClangASTContext::IsAggregateType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-    case clang::Type::Typedef:
-        return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-    case clang::Type::Paren:
-        return ClangASTContext::IsAggregateType (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr());
-    default:
-        break;
-    }
-    // The clang type does have a value
-    return false;
-}
-
-uint32_t
-ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
-{
-    if (clang_type == NULL)
-        return 0;
-
-    uint32_t num_children = 0;
-    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-    case clang::Type::Builtin:
-        switch (cast<clang::BuiltinType>(qual_type)->getKind())
-        {
-        case clang::BuiltinType::ObjCId:    // child is Class
-        case clang::BuiltinType::ObjCClass: // child is Class
-            num_children = 1;
-            break;
-
-        default:
-            break;
-        }
-        break;
-
-    case clang::Type::Complex: return 0;
-
-    case clang::Type::Record:
-        if (GetCompleteQualType (ast, qual_type))
-        {
-            const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
-            const RecordDecl *record_decl = record_type->getDecl();
-            assert(record_decl);
-            const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
-            if (cxx_record_decl)
-            {
-                if (omit_empty_base_classes)
-                {
-                    // Check each base classes to see if it or any of its
-                    // base classes contain any fields. This can help
-                    // limit the noise in variable views by not having to
-                    // show base classes that contain no members.
-                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
-                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
-                         base_class != base_class_end;
-                         ++base_class)
-                    {
-                        const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
-
-                        // Skip empty base classes
-                        if (RecordHasFields(base_class_decl) == false)
-                            continue;
-
-                        num_children++;
-                    }
-                }
-                else
-                {
-                    // Include all base classes
-                    num_children += cxx_record_decl->getNumBases();
-                }
-
-            }
-            RecordDecl::field_iterator field, field_end;
-            for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
-                ++num_children;
-        }
-        break;
-
-    case clang::Type::ObjCObject:
-    case clang::Type::ObjCInterface:
-        if (GetCompleteQualType (ast, qual_type))
-        {
-            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
-            assert (objc_class_type);
-            if (objc_class_type)
-            {
-                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-            
-                if (class_interface_decl)
-                {
-            
-                    ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
-                    if (superclass_interface_decl)
-                    {
-                        if (omit_empty_base_classes)
-                        {
-                            if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
-                                ++num_children;
-                        }
-                        else
-                            ++num_children;
-                    }
-                    
-                    num_children += class_interface_decl->ivar_size();
-                }
-            }
-        }
-        break;
-        
-    case clang::Type::ObjCObjectPointer:
-        {
-            const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
-            QualType pointee_type = pointer_type->getPointeeType();
-            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
-                                                                             pointee_type.getAsOpaquePtr(), 
-                                                                             omit_empty_base_classes);
-            // If this type points to a simple type, then it has 1 child
-            if (num_pointee_children == 0)
-                num_children = 1;
-            else
-                num_children = num_pointee_children;
-        }
-        break;
-
-    case clang::Type::Vector:
-    case clang::Type::ExtVector:
-        num_children = cast<VectorType>(qual_type.getTypePtr())->getNumElements();
-        break;
-
-    case clang::Type::ConstantArray:
-        num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
-        break;
-
-    case clang::Type::Pointer:
-        {
-            const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
-            QualType pointee_type (pointer_type->getPointeeType());
-            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
-                                                                             pointee_type.getAsOpaquePtr(), 
-                                                                             omit_empty_base_classes);
-            if (num_pointee_children == 0)
-            {
-                // We have a pointer to a pointee type that claims it has no children.
-                // We will want to look at
-                num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
-            }
-            else
-                num_children = num_pointee_children;
-        }
-        break;
-
-    case clang::Type::LValueReference:
-    case clang::Type::RValueReference:
-        {
-            const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
-            QualType pointee_type = reference_type->getPointeeType();
-            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
-                                                                             pointee_type.getAsOpaquePtr(), 
-                                                                             omit_empty_base_classes);
-            // If this type points to a simple type, then it has 1 child
-            if (num_pointee_children == 0)
-                num_children = 1;
-            else
-                num_children = num_pointee_children;
-        }
-        break;
-
-
-    case clang::Type::Typedef:
-        num_children = ClangASTContext::GetNumChildren (ast,
-                                                        cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), 
-                                                        omit_empty_base_classes);
-        break;
-        
-    case clang::Type::Elaborated:
-        num_children = ClangASTContext::GetNumChildren (ast, 
-                                                        cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
-                                                        omit_empty_base_classes);
-        break;
-
-    case clang::Type::Paren:
-        num_children = ClangASTContext::GetNumChildren(ast,
-                                                       llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
-                                                       omit_empty_base_classes);
-
-        break;
-    default:
-        break;
-    }
-    return num_children;
-}
-
-uint32_t
-ClangASTContext::GetNumDirectBaseClasses (clang::ASTContext *ast, clang_type_t clang_type)
-{
-    if (clang_type == NULL)
-        return 0;
-    
-    uint32_t count = 0;
-    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                if (cxx_record_decl)
-                    count = cxx_record_decl->getNumBases();
-            }
-            break;
-            
-        case clang::Type::ObjCObjectPointer:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
-                if (objc_class_type)
-                {
-                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
-                    if (class_interface_decl && class_interface_decl->getSuperClass())
-                        count = 1;
-                }
-            }
-            break;
-
-        case clang::Type::ObjCObject:
-        case clang::Type::ObjCInterface:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
-                if (objc_class_type)
-                {
-                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                    
-                    if (class_interface_decl && class_interface_decl->getSuperClass())
-                        count = 1;
-                }
-            }
-            break;
-            
-            
-        case clang::Type::Typedef:
-            count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-            break;
-            
-        case clang::Type::Elaborated:
-            count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-            break;
-            
-        case clang::Type::Paren:
-            return ClangASTContext::GetNumDirectBaseClasses(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-            
-        default:
-            break;
-    }
-    return count;
-}
-
-uint32_t 
-ClangASTContext::GetNumVirtualBaseClasses (clang::ASTContext *ast, 
-                                           clang_type_t clang_type)
-{
-    if (clang_type == NULL)
-        return 0;
-    
-    uint32_t count = 0;
-    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                if (cxx_record_decl)
-                    count = cxx_record_decl->getNumVBases();
-            }
-            break;
-            
-        case clang::Type::Typedef:
-            count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-            break;
-            
-        case clang::Type::Elaborated:
-            count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-            break;
-            
-        case clang::Type::Paren:
-            count = ClangASTContext::GetNumVirtualBaseClasses(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-            break;
-
-        default:
-            break;
-    }
-    return count;
-}
-
-uint32_t 
-ClangASTContext::GetNumFields (clang::ASTContext *ast, clang_type_t clang_type)
-{
-    if (clang_type == NULL)
-        return 0;
-    
-    uint32_t count = 0;
-    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
-                if (record_type)
-                {
-                    RecordDecl *record_decl = record_type->getDecl();
-                    if (record_decl)
-                    {
-                        uint32_t field_idx = 0;
-                        RecordDecl::field_iterator field, field_end;
-                        for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
-                            ++field_idx;
-                        count = field_idx;
-                    }
-                }
-            }
-            break;
-            
-        case clang::Type::Typedef:
-            count = ClangASTContext::GetNumFields (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-            break;
-            
-        case clang::Type::Elaborated:
-            count = ClangASTContext::GetNumFields (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-            break;
-            
-        case clang::Type::Paren:
-            count = ClangASTContext::GetNumFields(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-            break;
-            
-        case clang::Type::ObjCObjectPointer:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
-                if (objc_class_type)
-                {
-                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
-                    
-                    if (class_interface_decl)
-                        count = class_interface_decl->ivar_size();
-                }
-            }
-            break;
-        
-        case clang::Type::ObjCObject:
-        case clang::Type::ObjCInterface:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
-                if (objc_class_type)
-                {
-                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                    
-                    if (class_interface_decl)
-                        count = class_interface_decl->ivar_size();
-                }
-            }
-            break;
-
-        default:
-            break;
-    }
-    return count;
-}
-
-clang_type_t
-ClangASTContext::GetDirectBaseClassAtIndex (clang::ASTContext *ast, 
-                                            clang_type_t clang_type,
-                                            size_t idx, 
-                                            uint32_t *bit_offset_ptr)
-{
-    if (clang_type == NULL)
-        return 0;
-    
-    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                if (cxx_record_decl)
-                {
-                    uint32_t curr_idx = 0;
-                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
-                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
-                         base_class != base_class_end;
-                         ++base_class, ++curr_idx)
-                    {
-                        if (curr_idx == idx)
-                        {
-                            if (bit_offset_ptr)
-                            {
-                                const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl);
-                                const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
-                                if (base_class->isVirtual())
-                                    *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
-                                else
-                                    *bit_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
-                            }
-                            return base_class->getType().getAsOpaquePtr();
-                        }
-                    }
-                }
-            }
-            break;
-
-        case clang::Type::ObjCObjectPointer:
-            if (idx == 0 && GetCompleteQualType (ast, qual_type))
-            {
-                const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
-                if (objc_class_type)
-                {
-                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
-                    if (class_interface_decl)
-                    {
-                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
-                        if (superclass_interface_decl)
-                        {
-                            if (bit_offset_ptr)
-                                *bit_offset_ptr = 0;
-                            return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr();
-                        }
-                    }
-                }
-            }
-            break;
-            
-        case clang::Type::ObjCObject:
-        case clang::Type::ObjCInterface:
-            if (idx == 0 && GetCompleteQualType (ast, qual_type))
-            {
-                const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
-                if (objc_class_type)
-                {
-                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                    
-                    if (class_interface_decl)
-                    {
-                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
-                        if (superclass_interface_decl)
-                        {
-                            if (bit_offset_ptr)
-                                *bit_offset_ptr = 0;
-                            return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr();
-                        }
-                    }
-                }
-            }
-            break;
-            
-            
-        case clang::Type::Typedef:
-            return ClangASTContext::GetDirectBaseClassAtIndex (ast, 
-                                                               cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
-                                                               idx,
-                                                               bit_offset_ptr);
-            
-        case clang::Type::Elaborated:
-            return  ClangASTContext::GetDirectBaseClassAtIndex (ast, 
-                                                                cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
-                                                                idx,
-                                                                bit_offset_ptr);
-            
-        case clang::Type::Paren:
-            return  ClangASTContext::GetDirectBaseClassAtIndex (ast,
-                                                                cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
-                                                                idx,
-                                                                bit_offset_ptr);
-            
-        default:
-            break;
-    }
-    return NULL;
-}
-
-clang_type_t
-ClangASTContext::GetVirtualBaseClassAtIndex (clang::ASTContext *ast, 
-                                             clang_type_t clang_type,
-                                             size_t idx, 
-                                             uint32_t *bit_offset_ptr)
-{
-    if (clang_type == NULL)
-        return 0;
-    
-    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                if (cxx_record_decl)
-                {
-                    uint32_t curr_idx = 0;
-                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
-                    for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end();
-                         base_class != base_class_end;
-                         ++base_class, ++curr_idx)
-                    {
-                        if (curr_idx == idx)
-                        {
-                            if (bit_offset_ptr)
-                            {
-                                const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl);
-                                const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
-                                *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
-
-                            }
-                            return base_class->getType().getAsOpaquePtr();
-                        }
-                    }
-                }
-            }
-            break;
-            
-        case clang::Type::Typedef:
-            return ClangASTContext::GetVirtualBaseClassAtIndex (ast, 
-                                                                cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
-                                                                idx,
-                                                                bit_offset_ptr);
-            
-        case clang::Type::Elaborated:
-            return  ClangASTContext::GetVirtualBaseClassAtIndex (ast, 
-                                                                 cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
-                                                                 idx,
-                                                                 bit_offset_ptr);
-            
-        case clang::Type::Paren:
-            return  ClangASTContext::GetVirtualBaseClassAtIndex (ast,
-                                                                 cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
-                                                                 idx,
-                                                                 bit_offset_ptr);
-
-        default:
-            break;
-    }
-    return NULL;
-}
-
-static clang_type_t
-GetObjCFieldAtIndex (clang::ASTContext *ast,
-                     ObjCInterfaceDecl * class_interface_decl,
-                     size_t idx,
-                     std::string& name,
-                     uint64_t *bit_offset_ptr,
-                     uint32_t *bitfield_bit_size_ptr,
-                     bool *is_bitfield_ptr)
-{
-    if (class_interface_decl)
-    {
-        if (idx < (class_interface_decl->ivar_size()))
-        {
-            ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
-            uint32_t ivar_idx = 0;
-            
-            for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx)
-            {
-                if (ivar_idx == idx)
-                {
-                    const ObjCIvarDecl* ivar_decl = *ivar_pos;
-                    
-                    QualType ivar_qual_type(ivar_decl->getType());
-                    
-                    name.assign(ivar_decl->getNameAsString());
-                    
-                    if (bit_offset_ptr)
-                    {
-                        const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
-                        *bit_offset_ptr = interface_layout.getFieldOffset (ivar_idx);
-                    }
-                    
-                    const bool is_bitfield = ivar_pos->isBitField();
-                    
-                    if (bitfield_bit_size_ptr)
-                    {
-                        *bitfield_bit_size_ptr = 0;
-                        
-                        if (is_bitfield && ast)
-                        {
-                            Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
-                            llvm::APSInt bitfield_apsint;
-                            if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast))
-                            {
-                                *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
-                            }
-                        }
-                    }
-                    if (is_bitfield_ptr)
-                        *is_bitfield_ptr = is_bitfield;
-                    
-                    return ivar_qual_type.getAsOpaquePtr();
-                }
-            }
-        }
-    }
-    return NULL;
-}
-
-clang_type_t
-ClangASTContext::GetFieldAtIndex (clang::ASTContext *ast,
-                                  clang_type_t clang_type,
-                                  size_t idx,
-                                  std::string& name,
-                                  uint64_t *bit_offset_ptr,
-                                  uint32_t *bitfield_bit_size_ptr,
-                                  bool *is_bitfield_ptr)
-{
-    if (clang_type == NULL)
-        return 0;
-    
-    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
-                const RecordDecl *record_decl = record_type->getDecl();
-                uint32_t field_idx = 0;
-                RecordDecl::field_iterator field, field_end;
-                for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx)
-                {
-                    if (idx == field_idx)
-                    {
-                        // Print the member type if requested
-                        // Print the member name and equal sign
-                        name.assign(field->getNameAsString());
-                        
-                        // Figure out the type byte size (field_type_info.first) and
-                        // alignment (field_type_info.second) from the AST context.
-                        if (bit_offset_ptr)
-                        {
-                            const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
-                            *bit_offset_ptr = record_layout.getFieldOffset (field_idx);
-                        }
-                        
-                        const bool is_bitfield = field->isBitField();
-                        
-                        if (bitfield_bit_size_ptr)
-                        {
-                            *bitfield_bit_size_ptr = 0;
-
-                            if (is_bitfield && ast)
-                            {
-                                Expr *bitfield_bit_size_expr = field->getBitWidth();
-                                llvm::APSInt bitfield_apsint;
-                                if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast))
-                                {
-                                    *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
-                                }
-                            }
-                        }
-                        if (is_bitfield_ptr)
-                            *is_bitfield_ptr = is_bitfield;
-
-                        return field->getType().getAsOpaquePtr();
-                    }
-                }
-            }
-            break;
-            
-        case clang::Type::ObjCObjectPointer:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
-                if (objc_class_type)
-                {
-                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
-                    return GetObjCFieldAtIndex(ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
-                }
-            }
-            break;
-            
-        case clang::Type::ObjCObject:
-        case clang::Type::ObjCInterface:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
-                assert (objc_class_type);
-                if (objc_class_type)
-                {
-                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                    return GetObjCFieldAtIndex(ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
-                }
-            }
-            break;
-            
-            
-        case clang::Type::Typedef:
-            return ClangASTContext::GetFieldAtIndex (ast, 
-                                                     cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
-                                                     idx,
-                                                     name,
-                                                     bit_offset_ptr,
-                                                     bitfield_bit_size_ptr,
-                                                     is_bitfield_ptr);
-            
-        case clang::Type::Elaborated:
-            return  ClangASTContext::GetFieldAtIndex (ast, 
-                                                      cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
-                                                      idx,
-                                                      name,
-                                                      bit_offset_ptr,
-                                                      bitfield_bit_size_ptr,
-                                                      is_bitfield_ptr);
-            
-        case clang::Type::Paren:
-            return  ClangASTContext::GetFieldAtIndex (ast,
-                                                      cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
-                                                      idx,
-                                                      name,
-                                                      bit_offset_ptr,
-                                                      bitfield_bit_size_ptr,
-                                                      is_bitfield_ptr);
-            
-        default:
-            break;
-    }
-    return NULL;
-}
-
-size_t
-ClangASTContext::GetIndexOfFieldWithName (clang::ASTContext *ast,
-                                          lldb::clang_type_t clang_type,
-                                          const char* name,
-                                          lldb::clang_type_t* field_clang_type,
-                                          uint64_t *bit_offset_ptr,
-                                          uint32_t *bitfield_bit_size_ptr,
-                                          bool *is_bitfield_ptr)
-{
-    unsigned count = ClangASTContext::GetNumFields(ast, clang_type);
-    lldb::clang_type_t field_clang_type_internal;
-    std::string field_name;
-    for (unsigned index = 0; index < count; index++)
-    {
-        field_clang_type_internal = ClangASTContext::GetFieldAtIndex(ast, clang_type, index, field_name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
-        if ( strcmp(field_name.c_str(), name) == 0 )
-        {
-            if (field_clang_type)
-                *field_clang_type = field_clang_type_internal;
-            return index;
-        }
-    }
-    return UINT32_MAX;
-}
-
-lldb::BasicType
-ClangASTContext::GetLLDBBasicTypeEnumeration (clang_type_t clang_type)
-{
-    if (clang_type)
-    {
-        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        if (type_class == clang::Type::Builtin)
-        {
-            switch (cast<clang::BuiltinType>(qual_type)->getKind())
-            {
-            case clang::BuiltinType::Void:      return eBasicTypeVoid;
-            case clang::BuiltinType::Bool:      return eBasicTypeBool;
-            case clang::BuiltinType::Char_S:    return eBasicTypeSignedChar;
-            case clang::BuiltinType::Char_U:    return eBasicTypeUnsignedChar;
-            case clang::BuiltinType::Char16:    return eBasicTypeChar16;
-            case clang::BuiltinType::Char32:    return eBasicTypeChar32;
-            case clang::BuiltinType::UChar:     return eBasicTypeUnsignedChar;
-            case clang::BuiltinType::SChar:     return eBasicTypeSignedChar;
-            case clang::BuiltinType::WChar_S:   return eBasicTypeSignedWChar;
-            case clang::BuiltinType::WChar_U:   return eBasicTypeUnsignedWChar;
-            case clang::BuiltinType::Short:     return eBasicTypeShort;
-            case clang::BuiltinType::UShort:    return eBasicTypeUnsignedShort;
-            case clang::BuiltinType::Int:       return eBasicTypeInt;
-            case clang::BuiltinType::UInt:      return eBasicTypeUnsignedInt;
-            case clang::BuiltinType::Long:      return eBasicTypeLong;
-            case clang::BuiltinType::ULong:     return eBasicTypeUnsignedLong;
-            case clang::BuiltinType::LongLong:  return eBasicTypeLongLong;
-            case clang::BuiltinType::ULongLong: return eBasicTypeUnsignedLongLong;
-            case clang::BuiltinType::Int128:    return eBasicTypeInt128;
-            case clang::BuiltinType::UInt128:   return eBasicTypeUnsignedInt128;
-
-            case clang::BuiltinType::Half:      return eBasicTypeHalf;
-            case clang::BuiltinType::Float:     return eBasicTypeFloat;
-            case clang::BuiltinType::Double:    return eBasicTypeDouble;
-            case clang::BuiltinType::LongDouble:return eBasicTypeLongDouble;
-
-            case clang::BuiltinType::NullPtr:   return eBasicTypeNullPtr;
-            case clang::BuiltinType::ObjCId:    return eBasicTypeObjCID;
-            case clang::BuiltinType::ObjCClass: return eBasicTypeObjCClass;
-            case clang::BuiltinType::ObjCSel:   return eBasicTypeObjCSel;
-            case clang::BuiltinType::Dependent:
-            case clang::BuiltinType::Overload:
-            case clang::BuiltinType::BoundMember:
-            case clang::BuiltinType::PseudoObject:
-            case clang::BuiltinType::UnknownAny:
-            case clang::BuiltinType::BuiltinFn:
-            case clang::BuiltinType::ARCUnbridgedCast:
-            case clang::BuiltinType::OCLEvent:
-            case clang::BuiltinType::OCLImage1d:
-            case clang::BuiltinType::OCLImage1dArray:
-            case clang::BuiltinType::OCLImage1dBuffer:
-            case clang::BuiltinType::OCLImage2d:
-            case clang::BuiltinType::OCLImage2dArray:
-            case clang::BuiltinType::OCLImage3d:
-            case clang::BuiltinType::OCLSampler:
-                return eBasicTypeOther;
-            }
-        }
-    }
-    
-    return eBasicTypeInvalid;
-}
-
-
-
-// If a pointer to a pointee type (the clang_type arg) says that it has no 
-// children, then we either need to trust it, or override it and return a 
-// different result. For example, an "int *" has one child that is an integer, 
-// but a function pointer doesn't have any children. Likewise if a Record type
-// claims it has no children, then there really is nothing to show.
-uint32_t
-ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
-{
-    if (clang_type == NULL)
-        return 0;
-
-    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-    case clang::Type::Builtin:                  
-        switch (cast<clang::BuiltinType>(qual_type)->getKind())
-        {
-        case clang::BuiltinType::UnknownAny:
-        case clang::BuiltinType::Void:
-        case clang::BuiltinType::NullPtr:  
-        case clang::BuiltinType::OCLEvent:
-        case clang::BuiltinType::OCLImage1d:
-        case clang::BuiltinType::OCLImage1dArray:
-        case clang::BuiltinType::OCLImage1dBuffer:
-        case clang::BuiltinType::OCLImage2d:
-        case clang::BuiltinType::OCLImage2dArray:
-        case clang::BuiltinType::OCLImage3d:
-        case clang::BuiltinType::OCLSampler:
-            return 0;
-        case clang::BuiltinType::Bool:
-        case clang::BuiltinType::Char_U:
-        case clang::BuiltinType::UChar:
-        case clang::BuiltinType::WChar_U:
-        case clang::BuiltinType::Char16:
-        case clang::BuiltinType::Char32:
-        case clang::BuiltinType::UShort:
-        case clang::BuiltinType::UInt:
-        case clang::BuiltinType::ULong:
-        case clang::BuiltinType::ULongLong:
-        case clang::BuiltinType::UInt128:
-        case clang::BuiltinType::Char_S:
-        case clang::BuiltinType::SChar:
-        case clang::BuiltinType::WChar_S:
-        case clang::BuiltinType::Short:
-        case clang::BuiltinType::Int:
-        case clang::BuiltinType::Long:
-        case clang::BuiltinType::LongLong:
-        case clang::BuiltinType::Int128:
-        case clang::BuiltinType::Float:
-        case clang::BuiltinType::Double:
-        case clang::BuiltinType::LongDouble:
-        case clang::BuiltinType::Dependent:
-        case clang::BuiltinType::Overload:
-        case clang::BuiltinType::ObjCId:
-        case clang::BuiltinType::ObjCClass:
-        case clang::BuiltinType::ObjCSel:
-        case clang::BuiltinType::BoundMember:
-        case clang::BuiltinType::Half:          
-        case clang::BuiltinType::ARCUnbridgedCast:          
-        case clang::BuiltinType::PseudoObject:
-        case clang::BuiltinType::BuiltinFn:
-            return 1;
-        }
-        break;
-
-    case clang::Type::Complex:                  return 1;
-    case clang::Type::Pointer:                  return 1;
-    case clang::Type::BlockPointer:             return 0;   // If block pointers don't have debug info, then no children for them
-    case clang::Type::LValueReference:          return 1;
-    case clang::Type::RValueReference:          return 1;
-    case clang::Type::MemberPointer:            return 0;
-    case clang::Type::ConstantArray:            return 0;
-    case clang::Type::IncompleteArray:          return 0;
-    case clang::Type::VariableArray:            return 0;
-    case clang::Type::DependentSizedArray:      return 0;
-    case clang::Type::DependentSizedExtVector:  return 0;
-    case clang::Type::Vector:                   return 0;
-    case clang::Type::ExtVector:                return 0;
-    case clang::Type::FunctionProto:            return 0;   // When we function pointers, they have no children...
-    case clang::Type::FunctionNoProto:          return 0;   // When we function pointers, they have no children...
-    case clang::Type::UnresolvedUsing:          return 0;
-    case clang::Type::Paren:                    return ClangASTContext::GetNumPointeeChildren (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-    case clang::Type::Typedef:                  return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-    case clang::Type::Elaborated:               return ClangASTContext::GetNumPointeeChildren (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-    case clang::Type::TypeOfExpr:               return 0;
-    case clang::Type::TypeOf:                   return 0;
-    case clang::Type::Decltype:                 return 0;
-    case clang::Type::Record:                   return 0;
-    case clang::Type::Enum:                     return 1;
-    case clang::Type::TemplateTypeParm:         return 1;
-    case clang::Type::SubstTemplateTypeParm:    return 1;
-    case clang::Type::TemplateSpecialization:   return 1;
-    case clang::Type::InjectedClassName:        return 0;
-    case clang::Type::DependentName:            return 1;
-    case clang::Type::DependentTemplateSpecialization:  return 1;
-    case clang::Type::ObjCObject:               return 0;
-    case clang::Type::ObjCInterface:            return 0;
-    case clang::Type::ObjCObjectPointer:        return 1;
-    default: 
-        break;
-    }
-    return 0;
-}
-
-clang_type_t
-ClangASTContext::GetChildClangTypeAtIndex
-(
-    ExecutionContext *exe_ctx,
-    const char *parent_name,
-    clang_type_t parent_clang_type,
-    size_t idx,
-    bool transparent_pointers,
-    bool omit_empty_base_classes,
-    bool ignore_array_bounds,
-    std::string& child_name,
-    uint32_t &child_byte_size,
-    int32_t &child_byte_offset,
-    uint32_t &child_bitfield_bit_size,
-    uint32_t &child_bitfield_bit_offset,
-    bool &child_is_base_class,
-    bool &child_is_deref_of_parent
-)
-{
-    if (parent_clang_type)
-
-        return GetChildClangTypeAtIndex (exe_ctx,
-                                         getASTContext(),
-                                         parent_name,
-                                         parent_clang_type,
-                                         idx,
-                                         transparent_pointers,
-                                         omit_empty_base_classes,
-                                         ignore_array_bounds,
-                                         child_name,
-                                         child_byte_size,
-                                         child_byte_offset,
-                                         child_bitfield_bit_size,
-                                         child_bitfield_bit_offset,
-                                         child_is_base_class, 
-                                         child_is_deref_of_parent);
-    return NULL;
-}
-
-clang_type_t
-ClangASTContext::GetChildClangTypeAtIndex
-(
-    ExecutionContext *exe_ctx,
-    ASTContext *ast,
-    const char *parent_name,
-    clang_type_t parent_clang_type,
-    size_t idx,
-    bool transparent_pointers,
-    bool omit_empty_base_classes,
-    bool ignore_array_bounds,
-    std::string& child_name,
-    uint32_t &child_byte_size,
-    int32_t &child_byte_offset,
-    uint32_t &child_bitfield_bit_size,
-    uint32_t &child_bitfield_bit_offset,
-    bool &child_is_base_class,
-    bool &child_is_deref_of_parent
-)
-{
-    if (parent_clang_type == NULL)
-        return NULL;
-
-    QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
-    const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
-    child_bitfield_bit_size = 0;
-    child_bitfield_bit_offset = 0;
-    child_is_base_class = false;
-
-    const bool idx_is_valid = idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes);
-    uint32_t bit_offset;
-    switch (parent_type_class)
-    {
-    case clang::Type::Builtin:
-        if (idx_is_valid)
-        {
-            switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
-            {
-            case clang::BuiltinType::ObjCId:
-            case clang::BuiltinType::ObjCClass:
-                child_name = "isa";
-                child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
-                return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
-                
-            default:
-                break;
-            }
-        }
-        break;
-
-    case clang::Type::Record:
-        if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type))
-        {
-            const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
-            const RecordDecl *record_decl = record_type->getDecl();
-            assert(record_decl);
-            const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
-            uint32_t child_idx = 0;
-
-            const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
-            if (cxx_record_decl)
-            {
-                // We might have base classes to print out first
-                CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
-                for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
-                     base_class != base_class_end;
-                     ++base_class)
-                {
-                    const CXXRecordDecl *base_class_decl = NULL;
-
-                    // Skip empty base classes
-                    if (omit_empty_base_classes)
-                    {
-                        base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
-                        if (RecordHasFields(base_class_decl) == false)
-                            continue;
-                    }
-
-                    if (idx == child_idx)
-                    {
-                        if (base_class_decl == NULL)
-                            base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
-
-
-                        if (base_class->isVirtual())
-                            bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
-                        else
-                            bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
-
-                        // Base classes should be a multiple of 8 bits in size
-                        child_byte_offset = bit_offset/8;
-                        
-                        child_name = ClangASTType::GetTypeNameForQualType(ast, base_class->getType());
-
-                        uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
-
-                        // Base classes bit sizes should be a multiple of 8 bits in size
-                        assert (clang_type_info_bit_size % 8 == 0);
-                        child_byte_size = clang_type_info_bit_size / 8;
-                        child_is_base_class = true;
-                        return base_class->getType().getAsOpaquePtr();
-                    }
-                    // We don't increment the child index in the for loop since we might
-                    // be skipping empty base classes
-                    ++child_idx;
-                }
-            }
-            // Make sure index is in range...
-            uint32_t field_idx = 0;
-            RecordDecl::field_iterator field, field_end;
-            for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
-            {
-                if (idx == child_idx)
-                {
-                    // Print the member type if requested
-                    // Print the member name and equal sign
-                    child_name.assign(field->getNameAsString().c_str());
-
-                    // Figure out the type byte size (field_type_info.first) and
-                    // alignment (field_type_info.second) from the AST context.
-                    std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
-                    assert(field_idx < record_layout.getFieldCount());
-
-                    child_byte_size = field_type_info.first / 8;
-
-                    // Figure out the field offset within the current struct/union/class type
-                    bit_offset = record_layout.getFieldOffset (field_idx);
-                    child_byte_offset = bit_offset / 8;
-                    if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
-                        child_bitfield_bit_offset = bit_offset % 8;
-
-                    return field->getType().getAsOpaquePtr();
-                }
-            }
-        }
-        break;
-
-    case clang::Type::ObjCObject:
-    case clang::Type::ObjCInterface:
-        if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type))
-        {
-            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
-            assert (objc_class_type);
-            if (objc_class_type)
-            {
-                uint32_t child_idx = 0;
-                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-            
-                if (class_interface_decl)
-                {
-            
-                    const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
-                    ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
-                    if (superclass_interface_decl)
-                    {
-                        if (omit_empty_base_classes)
-                        {
-                            if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
-                            {
-                                if (idx == 0)
-                                {
-                                    QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
-                                    
-
-                                    child_name.assign(superclass_interface_decl->getNameAsString().c_str());
-
-                                    std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
-
-                                    child_byte_size = ivar_type_info.first / 8;
-                                    child_byte_offset = 0;
-                                    child_is_base_class = true;
-
-                                    return ivar_qual_type.getAsOpaquePtr();
-                                }
-
-                                ++child_idx;
-                            }
-                        }
-                        else
-                            ++child_idx;
-                    }
-
-                    const uint32_t superclass_idx = child_idx;
-
-                    if (idx < (child_idx + class_interface_decl->ivar_size()))
-                    {
-                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
-                        
-                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
-                        {
-                            if (child_idx == idx)
-                            {
-                                ObjCIvarDecl* ivar_decl = *ivar_pos;
-                                
-                                QualType ivar_qual_type(ivar_decl->getType());
-
-                                child_name.assign(ivar_decl->getNameAsString().c_str());
-
-                                std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
-
-                                child_byte_size = ivar_type_info.first / 8;
-
-                                // Figure out the field offset within the current struct/union/class type
-                                // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
-                                // that doesn't account for the space taken up by unbacked properties, or from 
-                                // the changing size of base classes that are newer than this class.
-                                // So if we have a process around that we can ask about this object, do so.
-                                child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
-                                Process *process = NULL;
-                                if (exe_ctx)
-                                    process = exe_ctx->GetProcessPtr();
-                                if (process)
-                                {
-                                    ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
-                                    if (objc_runtime != NULL)
-                                    {
-                                        ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
-                                        child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
-                                    }
-                                }
-                                
-                                // Setting this to UINT32_MAX to make sure we don't compute it twice...
-                                bit_offset = UINT32_MAX;
-                                
-                                if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
-                                {
-                                    bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
-                                    child_byte_offset = bit_offset / 8;
-                                }
-                                
-                                // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
-                                // of a bitfield within its containing object.  So regardless of where we get the byte
-                                // offset from, we still need to get the bit offset for bitfields from the layout.
-                                
-                                if (ClangASTContext::FieldIsBitfield (ast, ivar_decl, child_bitfield_bit_size))
-                                {
-                                    if (bit_offset == UINT32_MAX)
-                                        bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
-                                        
-                                    child_bitfield_bit_offset = bit_offset % 8;
-                                }
-                                return ivar_qual_type.getAsOpaquePtr();
-                            }
-                            ++child_idx;
-                        }
-                    }
-                }
-            }
-        }
-        break;
-        
-    case clang::Type::ObjCObjectPointer:
-        if (idx_is_valid)
-        {
-            const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
-            QualType pointee_type = pointer_type->getPointeeType();
-
-            if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
-            {
-                child_is_deref_of_parent = false;
-                bool tmp_child_is_deref_of_parent = false;
-                return GetChildClangTypeAtIndex (exe_ctx,
-                                                 ast,
-                                                 parent_name,
-                                                 pointer_type->getPointeeType().getAsOpaquePtr(),
-                                                 idx,
-                                                 transparent_pointers,
-                                                 omit_empty_base_classes,
-                                                 ignore_array_bounds,
-                                                 child_name,
-                                                 child_byte_size,
-                                                 child_byte_offset,
-                                                 child_bitfield_bit_size,
-                                                 child_bitfield_bit_offset,
-                                                 child_is_base_class,
-                                                 tmp_child_is_deref_of_parent);
-            }
-            else
-            {
-                child_is_deref_of_parent = true;
-                if (parent_name)
-                {
-                    child_name.assign(1, '*');
-                    child_name += parent_name;
-                }
-
-                // We have a pointer to an simple type
-                if (idx == 0 && GetCompleteQualType(ast, pointee_type))
-                {
-                    std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
-                    assert(clang_type_info.first % 8 == 0);
-                    child_byte_size = clang_type_info.first / 8;
-                    child_byte_offset = 0;
-                    return pointee_type.getAsOpaquePtr();
-                }
-            }
-        }
-        break;
-
-        case clang::Type::Vector:
-        case clang::Type::ExtVector:
-            if (idx_is_valid)
-            {
-                const VectorType *array = cast<VectorType>(parent_qual_type.getTypePtr());
-                if (array)
-                {
-                    if (GetCompleteQualType (ast, array->getElementType()))
-                    {
-                        std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
-                        
-                        char element_name[64];
-                        ::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
-                        
-                        child_name.assign(element_name);
-                        assert(field_type_info.first % 8 == 0);
-                        child_byte_size = field_type_info.first / 8;
-                        child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
-                        return array->getElementType().getAsOpaquePtr();
-                    }
-                }
-            }
-            break;
-
-        case clang::Type::ConstantArray:
-        case clang::Type::IncompleteArray:
-            if (ignore_array_bounds || idx_is_valid)
-            {
-                const ArrayType *array = cast<ArrayType>(parent_qual_type.getTypePtr());
-                if (array)
-                {
-                    if (GetCompleteQualType (ast, array->getElementType()))
-                    {
-                        std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
-                        
-                        char element_name[64];
-                        ::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
-                        
-                        child_name.assign(element_name);
-                        assert(field_type_info.first % 8 == 0);
-                        child_byte_size = field_type_info.first / 8;
-                        child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
-                        return array->getElementType().getAsOpaquePtr();
-                    }
-                }
-            }
-            break;
-            
-
-    case clang::Type::Pointer:
-        if (idx_is_valid)
-        {
-            const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
-            QualType pointee_type = pointer_type->getPointeeType();
-            
-            // Don't dereference "void *" pointers
-            if (pointee_type->isVoidType())
-                return NULL;
-
-            if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
-            {
-                child_is_deref_of_parent = false;
-                bool tmp_child_is_deref_of_parent = false;
-                return GetChildClangTypeAtIndex (exe_ctx,
-                                                 ast,
-                                                 parent_name,
-                                                 pointer_type->getPointeeType().getAsOpaquePtr(),
-                                                 idx,
-                                                 transparent_pointers,
-                                                 omit_empty_base_classes,
-                                                 ignore_array_bounds,
-                                                 child_name,
-                                                 child_byte_size,
-                                                 child_byte_offset,
-                                                 child_bitfield_bit_size,
-                                                 child_bitfield_bit_offset,
-                                                 child_is_base_class,
-                                                 tmp_child_is_deref_of_parent);
-            }
-            else
-            {
-                child_is_deref_of_parent = true;
-
-                if (parent_name)
-                {
-                    child_name.assign(1, '*');
-                    child_name += parent_name;
-                }
-
-                // We have a pointer to an simple type
-                if (idx == 0)
-                {
-                    std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
-                    assert(clang_type_info.first % 8 == 0);
-                    child_byte_size = clang_type_info.first / 8;
-                    child_byte_offset = 0;
-                    return pointee_type.getAsOpaquePtr();
-                }
-            }
-        }
-        break;
-
-    case clang::Type::LValueReference:
-    case clang::Type::RValueReference:
-        if (idx_is_valid)
-        {
-            const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
-            QualType pointee_type(reference_type->getPointeeType());
-            clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
-            if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
-            {
-                child_is_deref_of_parent = false;
-                bool tmp_child_is_deref_of_parent = false;
-                return GetChildClangTypeAtIndex (exe_ctx,
-                                                 ast,
-                                                 parent_name,
-                                                 pointee_clang_type,
-                                                 idx,
-                                                 transparent_pointers,
-                                                 omit_empty_base_classes,
-                                                 ignore_array_bounds,
-                                                 child_name,
-                                                 child_byte_size,
-                                                 child_byte_offset,
-                                                 child_bitfield_bit_size,
-                                                 child_bitfield_bit_offset,
-                                                 child_is_base_class,
-                                                 tmp_child_is_deref_of_parent);
-            }
-            else
-            {
-                if (parent_name)
-                {
-                    child_name.assign(1, '&');
-                    child_name += parent_name;
-                }
-
-                // We have a pointer to an simple type
-                if (idx == 0)
-                {
-                    std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
-                    assert(clang_type_info.first % 8 == 0);
-                    child_byte_size = clang_type_info.first / 8;
-                    child_byte_offset = 0;
-                    return pointee_type.getAsOpaquePtr();
-                }
-            }
-        }
-        break;
-
-    case clang::Type::Typedef:
-        return GetChildClangTypeAtIndex (exe_ctx,
-                                         ast,
-                                         parent_name,
-                                         cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
-                                         idx,
-                                         transparent_pointers,
-                                         omit_empty_base_classes,
-                                         ignore_array_bounds,
-                                         child_name,
-                                         child_byte_size,
-                                         child_byte_offset,
-                                         child_bitfield_bit_size,
-                                         child_bitfield_bit_offset,
-                                         child_is_base_class,
-                                         child_is_deref_of_parent);
-        break;
-
-    case clang::Type::Elaborated:
-        return GetChildClangTypeAtIndex (exe_ctx,
-                                         ast,
-                                         parent_name,
-                                         cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
-                                         idx,
-                                         transparent_pointers,
-                                         omit_empty_base_classes,
-                                         ignore_array_bounds,
-                                         child_name,
-                                         child_byte_size,
-                                         child_byte_offset,
-                                         child_bitfield_bit_size,
-                                         child_bitfield_bit_offset,
-                                         child_is_base_class,
-                                         child_is_deref_of_parent);
-            
-    case clang::Type::Paren:
-        return GetChildClangTypeAtIndex (exe_ctx,
-                                         ast,
-                                         parent_name,
-                                         llvm::cast<clang::ParenType>(parent_qual_type)->desugar().getAsOpaquePtr(),
-                                         idx,
-                                         transparent_pointers,
-                                         omit_empty_base_classes,
-                                         ignore_array_bounds,
-                                         child_name,
-                                         child_byte_size,
-                                         child_byte_offset,
-                                         child_bitfield_bit_size,
-                                         child_bitfield_bit_offset,
-                                         child_is_base_class,
-                                         child_is_deref_of_parent);
-
-
-    default:
-        break;
-    }
-    return NULL;
+    return ClangASTType (ast, ast->getObjCInterfaceType(decl));
 }
 
 static inline bool
@@ -4660,8 +1763,8 @@
     return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
 }
 
-static uint32_t
-GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
+uint32_t
+ClangASTContext::GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
 {
     uint32_t num_bases = 0;
     if (cxx_record_decl)
@@ -4689,739 +1792,6 @@
 }
 
 
-static uint32_t
-GetIndexForRecordBase
-(
-    const RecordDecl *record_decl,
-    const CXXBaseSpecifier *base_spec,
-    bool omit_empty_base_classes
-)
-{
-    uint32_t child_idx = 0;
-
-    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
-
-//    const char *super_name = record_decl->getNameAsCString();
-//    const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
-//    printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
-//
-    if (cxx_record_decl)
-    {
-        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
-        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
-             base_class != base_class_end;
-             ++base_class)
-        {
-            if (omit_empty_base_classes)
-            {
-                if (BaseSpecifierIsEmpty (base_class))
-                    continue;
-            }
-
-//            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
-//                    child_idx,
-//                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
-//
-//
-            if (base_class == base_spec)
-                return child_idx;
-            ++child_idx;
-        }
-    }
-
-    return UINT32_MAX;
-}
-
-
-static uint32_t
-GetIndexForRecordChild
-(
-    const RecordDecl *record_decl,
-    NamedDecl *canonical_decl,
-    bool omit_empty_base_classes
-)
-{
-    uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
-
-//    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
-//
-////    printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
-//    if (cxx_record_decl)
-//    {
-//        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
-//        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
-//             base_class != base_class_end;
-//             ++base_class)
-//        {
-//            if (omit_empty_base_classes)
-//            {
-//                if (BaseSpecifierIsEmpty (base_class))
-//                    continue;
-//            }
-//
-////            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
-////                    record_decl->getNameAsCString(),
-////                    canonical_decl->getNameAsCString(),
-////                    child_idx,
-////                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
-//
-//
-//            CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
-//            if (curr_base_class_decl == canonical_decl)
-//            {
-//                return child_idx;
-//            }
-//            ++child_idx;
-//        }
-//    }
-//
-//    const uint32_t num_bases = child_idx;
-    RecordDecl::field_iterator field, field_end;
-    for (field = record_decl->field_begin(), field_end = record_decl->field_end();
-         field != field_end;
-         ++field, ++child_idx)
-    {
-//            printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
-//                    record_decl->getNameAsCString(),
-//                    canonical_decl->getNameAsCString(),
-//                    child_idx - num_bases,
-//                    field->getNameAsCString());
-
-        if (field->getCanonicalDecl() == canonical_decl)
-            return child_idx;
-    }
-
-    return UINT32_MAX;
-}
-
-// Look for a child member (doesn't include base classes, but it does include
-// their members) in the type hierarchy. Returns an index path into "clang_type"
-// on how to reach the appropriate member.
-//
-//    class A
-//    {
-//    public:
-//        int m_a;
-//        int m_b;
-//    };
-//
-//    class B
-//    {
-//    };
-//
-//    class C :
-//        public B,
-//        public A
-//    {
-//    };
-//
-// If we have a clang type that describes "class C", and we wanted to looked
-// "m_b" in it:
-//
-// With omit_empty_base_classes == false we would get an integer array back with:
-// { 1,  1 }
-// The first index 1 is the child index for "class A" within class C
-// The second index 1 is the child index for "m_b" within class A
-//
-// With omit_empty_base_classes == true we would get an integer array back with:
-// { 0,  1 }
-// The first index 0 is the child index for "class A" within class C (since class B doesn't have any members it doesn't count)
-// The second index 1 is the child index for "m_b" within class A
-
-size_t
-ClangASTContext::GetIndexOfChildMemberWithName
-(
-    ASTContext *ast,
-    clang_type_t clang_type,
-    const char *name,
-    bool omit_empty_base_classes,
-    std::vector<uint32_t>& child_indexes
-)
-{
-    if (clang_type && name && name[0])
-    {
-        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-        case clang::Type::Record:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
-                const RecordDecl *record_decl = record_type->getDecl();
-
-                assert(record_decl);
-                uint32_t child_idx = 0;
-
-                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
-
-                // Try and find a field that matches NAME
-                RecordDecl::field_iterator field, field_end;
-                StringRef name_sref(name);
-                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
-                     field != field_end;
-                     ++field, ++child_idx)
-                {
-                    if (field->getName().equals (name_sref))
-                    {
-                        // We have to add on the number of base classes to this index!
-                        child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
-                        return child_indexes.size();
-                    }
-                }
-
-                if (cxx_record_decl)
-                {
-                    const RecordDecl *parent_record_decl = cxx_record_decl;
-
-                    //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
-
-                    //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
-                    // Didn't find things easily, lets let clang do its thang...
-                    IdentifierInfo & ident_ref = ast->Idents.get(name_sref);
-                    DeclarationName decl_name(&ident_ref);
-
-                    CXXBasePaths paths;
-                    if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
-                                                       decl_name.getAsOpaquePtr(),
-                                                       paths))
-                    {
-                        CXXBasePaths::const_paths_iterator path, path_end = paths.end();
-                        for (path = paths.begin(); path != path_end; ++path)
-                        {
-                            const size_t num_path_elements = path->size();
-                            for (size_t e=0; e<num_path_elements; ++e)
-                            {
-                                CXXBasePathElement elem = (*path)[e];
-
-                                child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
-                                if (child_idx == UINT32_MAX)
-                                {
-                                    child_indexes.clear();
-                                    return 0;
-                                }
-                                else
-                                {
-                                    child_indexes.push_back (child_idx);
-                                    parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
-                                }
-                            }
-                            for (NamedDecl *path_decl : path->Decls)
-                            {
-                                child_idx = GetIndexForRecordChild (parent_record_decl, path_decl, omit_empty_base_classes);
-                                if (child_idx == UINT32_MAX)
-                                {
-                                    child_indexes.clear();
-                                    return 0;
-                                }
-                                else
-                                {
-                                    child_indexes.push_back (child_idx);
-                                }
-                            }
-                        }
-                        return child_indexes.size();
-                    }
-                }
-
-            }
-            break;
-
-        case clang::Type::ObjCObject:
-        case clang::Type::ObjCInterface:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                StringRef name_sref(name);
-                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
-                assert (objc_class_type);
-                if (objc_class_type)
-                {
-                    uint32_t child_idx = 0;
-                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                
-                    if (class_interface_decl)
-                    {
-                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
-                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
-                        
-                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
-                        {
-                            const ObjCIvarDecl* ivar_decl = *ivar_pos;
-                            
-                            if (ivar_decl->getName().equals (name_sref))
-                            {
-                                if ((!omit_empty_base_classes && superclass_interface_decl) || 
-                                    ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
-                                    ++child_idx;
-
-                                child_indexes.push_back (child_idx);
-                                return child_indexes.size();
-                            }
-                        }
-
-                        if (superclass_interface_decl)
-                        {
-                            // The super class index is always zero for ObjC classes,
-                            // so we push it onto the child indexes in case we find
-                            // an ivar in our superclass...
-                            child_indexes.push_back (0);
-                            
-                            if (GetIndexOfChildMemberWithName (ast,
-                                                               ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
-                                                               name,
-                                                               omit_empty_base_classes,
-                                                               child_indexes))
-                            {
-                                // We did find an ivar in a superclass so just
-                                // return the results!
-                                return child_indexes.size();
-                            }
-                            
-                            // We didn't find an ivar matching "name" in our 
-                            // superclass, pop the superclass zero index that
-                            // we pushed on above.
-                            child_indexes.pop_back();
-                        }
-                    }
-                }
-            }
-            break;
-            
-        case clang::Type::ObjCObjectPointer:
-            {
-                return GetIndexOfChildMemberWithName (ast,
-                                                      cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
-                                                      name,
-                                                      omit_empty_base_classes,
-                                                      child_indexes);
-            }
-            break;
-
-
-        case clang::Type::ConstantArray:
-            {
-//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
-//                const uint64_t element_count = array->getSize().getLimitedValue();
-//
-//                if (idx < element_count)
-//                {
-//                    std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
-//
-//                    char element_name[32];
-//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
-//
-//                    child_name.assign(element_name);
-//                    assert(field_type_info.first % 8 == 0);
-//                    child_byte_size = field_type_info.first / 8;
-//                    child_byte_offset = idx * child_byte_size;
-//                    return array->getElementType().getAsOpaquePtr();
-//                }
-            }
-            break;
-
-//        case clang::Type::MemberPointerType:
-//            {
-//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
-//                QualType pointee_type = mem_ptr_type->getPointeeType();
-//
-//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
-//                {
-//                    return GetIndexOfChildWithName (ast,
-//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
-//                                                    name);
-//                }
-//            }
-//            break;
-//
-        case clang::Type::LValueReference:
-        case clang::Type::RValueReference:
-            {
-                const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
-                QualType pointee_type = reference_type->getPointeeType();
-
-                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
-                {
-                    return GetIndexOfChildMemberWithName (ast,
-                                                          reference_type->getPointeeType().getAsOpaquePtr(),
-                                                          name,
-                                                          omit_empty_base_classes,
-                                                          child_indexes);
-                }
-            }
-            break;
-
-        case clang::Type::Pointer:
-            {
-                const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
-                QualType pointee_type = pointer_type->getPointeeType();
-
-                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
-                {
-                    return GetIndexOfChildMemberWithName (ast,
-                                                          pointer_type->getPointeeType().getAsOpaquePtr(),
-                                                          name,
-                                                          omit_empty_base_classes,
-                                                          child_indexes);
-                }
-                else
-                {
-//                    if (parent_name)
-//                    {
-//                        child_name.assign(1, '*');
-//                        child_name += parent_name;
-//                    }
-//
-//                    // We have a pointer to an simple type
-//                    if (idx == 0)
-//                    {
-//                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
-//                        assert(clang_type_info.first % 8 == 0);
-//                        child_byte_size = clang_type_info.first / 8;
-//                        child_byte_offset = 0;
-//                        return pointee_type.getAsOpaquePtr();
-//                    }
-                }
-            }
-            break;
-
-        case clang::Type::Typedef:
-            return GetIndexOfChildMemberWithName (ast,
-                                                  cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
-                                                  name,
-                                                  omit_empty_base_classes,
-                                                  child_indexes);
-
-        case clang::Type::Elaborated:
-            return GetIndexOfChildMemberWithName (ast,
-                                                  cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
-                                                  name,
-                                                  omit_empty_base_classes,
-                                                  child_indexes);
-                
-        case clang::Type::Paren:
-            return GetIndexOfChildMemberWithName (ast,
-                                                  cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
-                                                  name,
-                                                  omit_empty_base_classes,
-                                                  child_indexes);
-
-        default:
-            break;
-        }
-    }
-    return 0;
-}
-
-
-// Get the index of the child of "clang_type" whose name matches. This function
-// doesn't descend into the children, but only looks one level deep and name
-// matches can include base class names.
-
-uint32_t
-ClangASTContext::GetIndexOfChildWithName
-(
-    ASTContext *ast,
-    clang_type_t clang_type,
-    const char *name,
-    bool omit_empty_base_classes
-)
-{
-    if (clang_type && name && name[0])
-    {
-        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-        
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-
-        switch (type_class)
-        {
-        case clang::Type::Record:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
-                const RecordDecl *record_decl = record_type->getDecl();
-
-                assert(record_decl);
-                uint32_t child_idx = 0;
-
-                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
-
-                if (cxx_record_decl)
-                {
-                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
-                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
-                         base_class != base_class_end;
-                         ++base_class)
-                    {
-                        // Skip empty base classes
-                        CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
-                        if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
-                            continue;
-
-                        std::string base_class_type_name (ClangASTType::GetTypeNameForQualType(ast, base_class->getType()));
-                        if (base_class_type_name.compare (name) == 0)
-                            return child_idx;
-                        ++child_idx;
-                    }
-                }
-
-                // Try and find a field that matches NAME
-                RecordDecl::field_iterator field, field_end;
-                StringRef name_sref(name);
-                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
-                     field != field_end;
-                     ++field, ++child_idx)
-                {
-                    if (field->getName().equals (name_sref))
-                        return child_idx;
-                }
-
-            }
-            break;
-
-        case clang::Type::ObjCObject:
-        case clang::Type::ObjCInterface:
-            if (GetCompleteQualType (ast, qual_type))
-            {
-                StringRef name_sref(name);
-                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
-                assert (objc_class_type);
-                if (objc_class_type)
-                {
-                    uint32_t child_idx = 0;
-                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                
-                    if (class_interface_decl)
-                    {
-                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
-                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
-                        
-                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
-                        {
-                            const ObjCIvarDecl* ivar_decl = *ivar_pos;
-                            
-                            if (ivar_decl->getName().equals (name_sref))
-                            {
-                                if ((!omit_empty_base_classes && superclass_interface_decl) || 
-                                    ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
-                                    ++child_idx;
-
-                                return child_idx;
-                            }
-                        }
-
-                        if (superclass_interface_decl)
-                        {
-                            if (superclass_interface_decl->getName().equals (name_sref))
-                                return 0;
-                        }
-                    }
-                }
-            }
-            break;
-            
-        case clang::Type::ObjCObjectPointer:
-            {
-                return GetIndexOfChildWithName (ast,
-                                                cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
-                                                name,
-                                                omit_empty_base_classes);
-            }
-            break;
-
-        case clang::Type::ConstantArray:
-            {
-//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
-//                const uint64_t element_count = array->getSize().getLimitedValue();
-//
-//                if (idx < element_count)
-//                {
-//                    std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
-//
-//                    char element_name[32];
-//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
-//
-//                    child_name.assign(element_name);
-//                    assert(field_type_info.first % 8 == 0);
-//                    child_byte_size = field_type_info.first / 8;
-//                    child_byte_offset = idx * child_byte_size;
-//                    return array->getElementType().getAsOpaquePtr();
-//                }
-            }
-            break;
-
-//        case clang::Type::MemberPointerType:
-//            {
-//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
-//                QualType pointee_type = mem_ptr_type->getPointeeType();
-//
-//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
-//                {
-//                    return GetIndexOfChildWithName (ast,
-//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
-//                                                    name);
-//                }
-//            }
-//            break;
-//
-        case clang::Type::LValueReference:
-        case clang::Type::RValueReference:
-            {
-                const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
-                QualType pointee_type = reference_type->getPointeeType();
-
-                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
-                {
-                    return GetIndexOfChildWithName (ast,
-                                                    reference_type->getPointeeType().getAsOpaquePtr(),
-                                                    name,
-                                                    omit_empty_base_classes);
-                }
-            }
-            break;
-
-        case clang::Type::Pointer:
-            {
-                const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
-                QualType pointee_type = pointer_type->getPointeeType();
-
-                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
-                {
-                    return GetIndexOfChildWithName (ast,
-                                                    pointer_type->getPointeeType().getAsOpaquePtr(),
-                                                    name,
-                                                    omit_empty_base_classes);
-                }
-                else
-                {
-//                    if (parent_name)
-//                    {
-//                        child_name.assign(1, '*');
-//                        child_name += parent_name;
-//                    }
-//
-//                    // We have a pointer to an simple type
-//                    if (idx == 0)
-//                    {
-//                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
-//                        assert(clang_type_info.first % 8 == 0);
-//                        child_byte_size = clang_type_info.first / 8;
-//                        child_byte_offset = 0;
-//                        return pointee_type.getAsOpaquePtr();
-//                    }
-                }
-            }
-            break;
-
-        case clang::Type::Elaborated:
-            return GetIndexOfChildWithName (ast,
-                                            cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
-                                            name,
-                                            omit_empty_base_classes);
-
-        case clang::Type::Paren:
-            return GetIndexOfChildWithName (ast,
-                                            cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
-                                            name,
-                                            omit_empty_base_classes);
-
-        case clang::Type::Typedef:
-            return GetIndexOfChildWithName (ast,
-                                            cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
-                                            name,
-                                            omit_empty_base_classes);
-
-        default:
-            break;
-        }
-    }
-    return UINT32_MAX;
-}
-
-#pragma mark TagType
-
-bool
-ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
-{
-    if (tag_clang_type)
-    {
-        QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
-        const clang::Type *clang_type = tag_qual_type.getTypePtr();
-        if (clang_type)
-        {
-            const TagType *tag_type = dyn_cast<TagType>(clang_type);
-            if (tag_type)
-            {
-                TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
-                if (tag_decl)
-                {
-                    tag_decl->setTagKind ((TagDecl::TagKind)kind);
-                    return true;
-                }
-            }
-        }
-    }
-    return false;
-}
-
-
-#pragma mark DeclContext Functions
-
-DeclContext *
-ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
-{
-    if (clang_type == NULL)
-        return NULL;
-
-    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-    case clang::Type::UnaryTransform:           break;
-    case clang::Type::FunctionNoProto:          break;
-    case clang::Type::FunctionProto:            break;
-    case clang::Type::IncompleteArray:          break;
-    case clang::Type::VariableArray:            break;
-    case clang::Type::ConstantArray:            break;
-    case clang::Type::DependentSizedArray:      break;
-    case clang::Type::ExtVector:                break;
-    case clang::Type::DependentSizedExtVector:  break;
-    case clang::Type::Vector:                   break;
-    case clang::Type::Builtin:                  break;
-    case clang::Type::BlockPointer:             break;
-    case clang::Type::Pointer:                  break;
-    case clang::Type::LValueReference:          break;
-    case clang::Type::RValueReference:          break;
-    case clang::Type::MemberPointer:            break;
-    case clang::Type::Complex:                  break;
-    case clang::Type::ObjCObject:               break;
-    case clang::Type::ObjCInterface:            return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
-    case clang::Type::ObjCObjectPointer:        return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
-    case clang::Type::Record:                   return cast<RecordType>(qual_type)->getDecl();
-    case clang::Type::Enum:                     return cast<EnumType>(qual_type)->getDecl();
-    case clang::Type::Typedef:                  return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-    case clang::Type::Elaborated:               return ClangASTContext::GetDeclContextForType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-    case clang::Type::Paren:                    return ClangASTContext::GetDeclContextForType (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr());
-    case clang::Type::TypeOfExpr:               break;
-    case clang::Type::TypeOf:                   break;
-    case clang::Type::Decltype:                 break;
-    //case clang::Type::QualifiedName:          break;
-    case clang::Type::TemplateSpecialization:   break;
-    case clang::Type::DependentTemplateSpecialization:  break;
-    case clang::Type::TemplateTypeParm:         break;
-    case clang::Type::SubstTemplateTypeParm:    break;
-    case clang::Type::SubstTemplateTypeParmPack:break;
-    case clang::Type::PackExpansion:            break;
-    case clang::Type::UnresolvedUsing:          break;
-    case clang::Type::Attributed:               break;
-    case clang::Type::Auto:                     break;
-    case clang::Type::InjectedClassName:        break;
-    case clang::Type::DependentName:            break;
-    case clang::Type::Atomic:                   break;
-    }
-    // No DeclContext in this type...
-    return NULL;
-}
-
 #pragma mark Namespace Declarations
 
 NamespaceDecl *
@@ -5527,7 +1897,11 @@
 #pragma mark Function Types
 
 FunctionDecl *
-ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
+ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx,
+                                            const char *name,
+                                            const ClangASTType &function_clang_type,
+                                            int storage,
+                                            bool is_inline)
 {
     FunctionDecl *func_decl = NULL;
     ASTContext *ast = getASTContext();
@@ -5545,7 +1919,7 @@
                                           SourceLocation(),
                                           SourceLocation(),
                                           DeclarationName (&ast->Idents.get(name)),
-                                          QualType::getFromOpaquePtr(function_clang_type),
+                                          function_clang_type.GetQualType(),
                                           NULL,
                                           (FunctionDecl::StorageClass)storage,
                                           is_inline,
@@ -5559,7 +1933,7 @@
                                           SourceLocation(),
                                           SourceLocation(),
                                           DeclarationName (),
-                                          QualType::getFromOpaquePtr(function_clang_type),
+                                          function_clang_type.GetQualType(),
                                           NULL,
                                           (FunctionDecl::StorageClass)storage,
                                           is_inline,
@@ -5576,10 +1950,10 @@
     return func_decl;
 }
 
-clang_type_t
+ClangASTType
 ClangASTContext::CreateFunctionType (ASTContext *ast,
-                                     clang_type_t result_type, 
-                                     clang_type_t *args, 
+                                     const ClangASTType& result_type,
+                                     const ClangASTType *args,
                                      unsigned num_args, 
                                      bool is_variadic, 
                                      unsigned type_quals)
@@ -5587,7 +1961,7 @@
     assert (ast != NULL);
     std::vector<QualType> qual_type_args;
     for (unsigned i=0; i<num_args; ++i)
-        qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
+        qual_type_args.push_back (args[i].GetQualType());
 
     // TODO: Detect calling convention in DWARF?
     FunctionProtoType::ExtProtoInfo proto_info;
@@ -5598,13 +1972,13 @@
     proto_info.NumExceptions = 0;
     proto_info.Exceptions = NULL;
     
-    return ast->getFunctionType (QualType::getFromOpaquePtr(result_type),
-                                 qual_type_args,
-                                 proto_info).getAsOpaquePtr();
+    return ClangASTType (ast, ast->getFunctionType (result_type.GetQualType(),
+                                                    qual_type_args,
+                                                    proto_info).getAsOpaquePtr());
 }
 
 ParmVarDecl *
-ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
+ClangASTContext::CreateParameterDeclaration (const char *name, const ClangASTType &param_type, int storage)
 {
     ASTContext *ast = getASTContext();
     assert (ast != NULL);
@@ -5613,7 +1987,7 @@
                                 SourceLocation(),
                                 SourceLocation(),
                                 name && name[0] ? &ast->Idents.get(name) : NULL,
-                                QualType::getFromOpaquePtr(param_type),
+                                param_type.GetQualType(),
                                 NULL,
                                 (VarDecl::StorageClass)storage,
                                 0);
@@ -5629,21 +2003,19 @@
 
 #pragma mark Array Types
 
-clang_type_t
-ClangASTContext::CreateArrayType (clang_type_t element_type,
+ClangASTType
+ClangASTContext::CreateArrayType (const ClangASTType &element_type,
                                   size_t element_count,
                                   bool is_vector)
 {
-    if (element_type)
+    if (element_type.IsValid())
     {
         ASTContext *ast = getASTContext();
         assert (ast != NULL);
 
-        QualType element_qual_type(QualType::getFromOpaquePtr(element_type));
-
         if (is_vector)
         {
-            return ast->getExtVectorType(element_qual_type, element_count).getAsOpaquePtr();
+            return ClangASTType (ast, ast->getExtVectorType(element_type.GetQualType(), element_count).getAsOpaquePtr());
         }
         else
         {
@@ -5651,129 +2023,38 @@
             llvm::APInt ap_element_count (64, element_count);
             if (element_count == 0)
             {
-                return ast->getIncompleteArrayType(element_qual_type,
-                                                   ArrayType::Normal,
-                                                   0).getAsOpaquePtr();
-
+                return ClangASTType (ast, ast->getIncompleteArrayType (element_type.GetQualType(),
+                                                                       ArrayType::Normal,
+                                                                       0).getAsOpaquePtr());
             }
             else
             {
-                return ast->getConstantArrayType(element_qual_type,
-                                                 ap_element_count,
-                                                 ArrayType::Normal,
-                                                 0).getAsOpaquePtr(); // ElemQuals
+                return ClangASTType (ast, ast->getConstantArrayType (element_type.GetQualType(),
+                                                                     ap_element_count,
+                                                                     ArrayType::Normal,
+                                                                     0).getAsOpaquePtr());
             }
         }
     }
-    return NULL;
+    return ClangASTType();
 }
 
 
-#pragma mark TagDecl
-
-bool
-ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        const clang::Type *t = qual_type.getTypePtr();
-        if (t)
-        {
-            const TagType *tag_type = dyn_cast<TagType>(t);
-            if (tag_type)
-            {
-                TagDecl *tag_decl = tag_type->getDecl();
-                if (tag_decl)
-                {
-                    tag_decl->startDefinition();
-                    return true;
-                }
-            }
-            
-            const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(t);
-            if (object_type)
-            {
-                ObjCInterfaceDecl *interface_decl = object_type->getInterface();
-                if (interface_decl)
-                {
-                    interface_decl->startDefinition();
-                    return true;
-                }
-            }
-        }
-    }
-    return false;
-}
-
-bool
-ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        
-        CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-        
-        if (cxx_record_decl)
-        {
-            cxx_record_decl->completeDefinition();
-            
-            return true;
-        }
-        
-        const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
-        
-        if (enum_type)
-        {
-            EnumDecl *enum_decl = enum_type->getDecl();
-            
-            if (enum_decl)
-            {
-                /// TODO This really needs to be fixed.
-                
-                unsigned NumPositiveBits = 1;
-                unsigned NumNegativeBits = 0;
-                
-                ASTContext *ast = getASTContext();
-
-                QualType promotion_qual_type;
-                // If the enum integer type is less than an integer in bit width,
-                // then we must promote it to an integer size.
-                if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
-                {
-                    if (enum_decl->getIntegerType()->isSignedIntegerType())
-                        promotion_qual_type = ast->IntTy;
-                    else
-                        promotion_qual_type = ast->UnsignedIntTy;
-                }
-                else
-                    promotion_qual_type = enum_decl->getIntegerType();
-
-                enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
 
 #pragma mark Enumeration Types
 
-clang_type_t
+ClangASTType
 ClangASTContext::CreateEnumerationType 
 (
     const char *name, 
     DeclContext *decl_ctx, 
     const Declaration &decl, 
-    clang_type_t integer_qual_type
+    const ClangASTType &integer_clang_type
 )
 {
     // TODO: Do something intelligent with the Declaration object passed in
     // like maybe filling in the SourceLocation with it...
     ASTContext *ast = getASTContext();
-    assert (ast != NULL);
 
     // TODO: ask about these...
 //    const bool IsScoped = false;
@@ -5793,896 +2074,13 @@
     if (enum_decl)
     {
         // TODO: check if we should be setting the promotion type too?
-        enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
+        enum_decl->setIntegerType(integer_clang_type.GetQualType());
         
         enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
         
-        return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
+        return ClangASTType (ast, ast->getTagDeclType(enum_decl).getAsOpaquePtr());
     }
-    return NULL;
-}
-
-clang_type_t
-ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
-{
-    QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
-
-    const clang::Type *clang_type = enum_qual_type.getTypePtr();
-    if (clang_type)
-    {
-        const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
-        if (enum_type)
-        {
-            EnumDecl *enum_decl = enum_type->getDecl();
-            if (enum_decl)
-                return enum_decl->getIntegerType().getAsOpaquePtr();
-        }
-    }
-    return NULL;
-}
-bool
-ClangASTContext::AddEnumerationValueToEnumerationType
-(
-    clang_type_t enum_clang_type,
-    clang_type_t enumerator_clang_type,
-    const Declaration &decl,
-    const char *name,
-    int64_t enum_value,
-    uint32_t enum_value_bit_size
-)
-{
-    if (enum_clang_type && enumerator_clang_type && name)
-    {
-        // TODO: Do something intelligent with the Declaration object passed in
-        // like maybe filling in the SourceLocation with it...
-        ASTContext *ast = getASTContext();
-        IdentifierTable *identifier_table = getIdentifierTable();
-
-        assert (ast != NULL);
-        assert (identifier_table != NULL);
-        QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
-
-        bool is_signed = false;
-        IsIntegerType (enumerator_clang_type, is_signed);
-        const clang::Type *clang_type = enum_qual_type.getTypePtr();
-        if (clang_type)
-        {
-            const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
-
-            if (enum_type)
-            {
-                llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed);
-                enum_llvm_apsint = enum_value;
-                EnumConstantDecl *enumerator_decl =
-                    EnumConstantDecl::Create (*ast,
-                                              enum_type->getDecl(),
-                                              SourceLocation(),
-                                              name ? &identifier_table->get(name) : NULL,    // Identifier
-                                              QualType::getFromOpaquePtr(enumerator_clang_type),
-                                              NULL,
-                                              enum_llvm_apsint);
-                
-                if (enumerator_decl)
-                {
-                    enum_type->getDecl()->addDecl(enumerator_decl);
-                    
-#ifdef LLDB_CONFIGURATION_DEBUG
-                    VerifyDecl(enumerator_decl);
-#endif
-                    
-                    return true;
-                }
-            }
-        }
-    }
-    return false;
-}
-
-#pragma mark Pointers & References
-
-clang_type_t
-ClangASTContext::CreatePointerType (clang_type_t clang_type)
-{
-    return CreatePointerType (getASTContext(), clang_type);
-}
-
-clang_type_t
-ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
-{
-    if (ast && clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-        case clang::Type::ObjCObject:
-        case clang::Type::ObjCInterface:
-            return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
-
-        default:
-            return ast->getPointerType(qual_type).getAsOpaquePtr();
-        }
-    }
-    return NULL;
-}
-
-clang_type_t
-ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
-                                            clang_type_t clang_type)
-{
-    if (clang_type)
-        return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
-    return NULL;
-}
-
-clang_type_t
-ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
-                                            clang_type_t clang_type)
-{
-    if (clang_type)
-        return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
-    return NULL;
-}
-
-clang_type_t
-ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
-{
-    if (clang_pointee_type && clang_pointee_type)
-        return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
-                                                     QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
-    return NULL;
-}
-
-uint64_t
-ClangASTContext::GetPointerBitSize ()
-{
-    ASTContext *ast = getASTContext();
-    return ast->getTypeSize(ast->VoidPtrTy);
-}
-
-bool
-ClangASTContext::IsPossibleDynamicType (clang::ASTContext *ast,
-                                        clang_type_t clang_type,
-                                        clang_type_t *dynamic_pointee_type,
-                                        bool check_cplusplus,
-                                        bool check_objc)
-{
-    QualType pointee_qual_type;
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type).getCanonicalType());
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        bool success = false;
-        switch (type_class)
-        {
-            case clang::Type::Builtin:
-                if (check_objc && cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId)
-                {
-                    if (dynamic_pointee_type)
-                        *dynamic_pointee_type = clang_type;
-                    return true;
-                }
-                break;
-
-            case clang::Type::ObjCObjectPointer:
-                if (check_objc)
-                {
-                    if (dynamic_pointee_type)
-                        *dynamic_pointee_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
-                    return true;
-                }
-                break;
-
-            case clang::Type::Pointer:
-                pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
-                success = true;
-                break;
-                
-            case clang::Type::LValueReference:
-            case clang::Type::RValueReference:
-                pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
-                success = true;
-                break;
-                
-            case clang::Type::Typedef:
-                return ClangASTContext::IsPossibleDynamicType (ast,
-                                                               cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
-                                                               dynamic_pointee_type,
-                                                               check_cplusplus,
-                                                               check_objc);
-            
-            case clang::Type::Elaborated:
-                return ClangASTContext::IsPossibleDynamicType (ast,
-                                                               cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
-                                                               dynamic_pointee_type,
-                                                               check_cplusplus,
-                                                               check_objc);
-
-            case clang::Type::Paren:
-                return ClangASTContext::IsPossibleDynamicType (ast,
-                                                               cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
-                                                               dynamic_pointee_type,
-                                                               check_cplusplus,
-                                                               check_objc);
-            default:
-                break;
-        }
-        
-        if (success)
-        {
-            // Check to make sure what we are pointing too is a possible dynamic C++ type
-            // We currently accept any "void *" (in case we have a class that has been
-            // watered down to an opaque pointer) and virtual C++ classes.
-            const clang::Type::TypeClass pointee_type_class = pointee_qual_type.getCanonicalType()->getTypeClass();
-            switch (pointee_type_class)
-            {
-                case clang::Type::Builtin:
-                    switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
-                    {
-                        case clang::BuiltinType::UnknownAny:
-                        case clang::BuiltinType::Void:
-                            if (dynamic_pointee_type)
-                                *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
-                            return true;
-                            
-                        case clang::BuiltinType::NullPtr:  
-                        case clang::BuiltinType::Bool:
-                        case clang::BuiltinType::Char_U:
-                        case clang::BuiltinType::UChar:
-                        case clang::BuiltinType::WChar_U:
-                        case clang::BuiltinType::Char16:
-                        case clang::BuiltinType::Char32:
-                        case clang::BuiltinType::UShort:
-                        case clang::BuiltinType::UInt:
-                        case clang::BuiltinType::ULong:
-                        case clang::BuiltinType::ULongLong:
-                        case clang::BuiltinType::UInt128:
-                        case clang::BuiltinType::Char_S:
-                        case clang::BuiltinType::SChar:
-                        case clang::BuiltinType::WChar_S:
-                        case clang::BuiltinType::Short:
-                        case clang::BuiltinType::Int:
-                        case clang::BuiltinType::Long:
-                        case clang::BuiltinType::LongLong:
-                        case clang::BuiltinType::Int128:
-                        case clang::BuiltinType::Float:
-                        case clang::BuiltinType::Double:
-                        case clang::BuiltinType::LongDouble:
-                        case clang::BuiltinType::Dependent:
-                        case clang::BuiltinType::Overload:
-                        case clang::BuiltinType::ObjCId:
-                        case clang::BuiltinType::ObjCClass:
-                        case clang::BuiltinType::ObjCSel:
-                        case clang::BuiltinType::BoundMember:
-                        case clang::BuiltinType::Half:          
-                        case clang::BuiltinType::ARCUnbridgedCast:          
-                        case clang::BuiltinType::PseudoObject:
-                        case clang::BuiltinType::BuiltinFn:
-                        case clang::BuiltinType::OCLEvent:
-                        case clang::BuiltinType::OCLImage1d:
-                        case clang::BuiltinType::OCLImage1dArray:
-                        case clang::BuiltinType::OCLImage1dBuffer:
-                        case clang::BuiltinType::OCLImage2d:
-                        case clang::BuiltinType::OCLImage2dArray:
-                        case clang::BuiltinType::OCLImage3d:
-                        case clang::BuiltinType::OCLSampler:
-                            break;
-                    }
-                    break;
-
-                case clang::Type::Record:
-                    if (check_cplusplus)
-                    {
-                        CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
-                        if (cxx_record_decl)
-                        {
-                            bool is_complete = cxx_record_decl->isCompleteDefinition();
-                            
-                            if (is_complete)
-                                success = cxx_record_decl->isDynamicClass();
-                            else
-                            {
-                                ClangASTMetadata *metadata = GetMetadata (ast, cxx_record_decl);
-                                if (metadata)
-                                    success = metadata->GetIsDynamicCXXType();
-                                else
-                                {
-                                    is_complete = ClangASTContext::GetCompleteType (ast, pointee_qual_type.getAsOpaquePtr());
-                                    if (is_complete)
-                                        success = cxx_record_decl->isDynamicClass();
-                                    else
-                                        success = false;
-                                }
-                            }
-
-                            if (success)
-                            {
-                                if (dynamic_pointee_type)
-                                    *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
-                                return true;
-                            }
-                        }
-                    }
-                    break;
-                    
-                case clang::Type::ObjCObject:
-                case clang::Type::ObjCInterface:
-                    if (check_objc)
-                    {
-                        if (dynamic_pointee_type)
-                            *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
-                        return true;
-                    }
-                    break;
-
-                default:
-                    break;
-            }
-        }
-    }
-    if (dynamic_pointee_type)
-        *dynamic_pointee_type = NULL;
-    return false;
-}
-
-
-bool
-ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
-{
-    return IsPossibleDynamicType (ast,
-                                  clang_type,
-                                  dynamic_pointee_type,
-                                  true,     // Check for dynamic C++ types
-                                  false);   // Check for dynamic ObjC types
-}
-
-bool
-ClangASTContext::IsReferenceType (clang_type_t clang_type, clang_type_t *target_type)
-{
-    if (clang_type == NULL)
-        return false;
-    
-    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-
-    switch (type_class)
-    {
-    case clang::Type::LValueReference:
-        if (target_type)
-            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
-        return true;
-    case clang::Type::RValueReference:
-        if (target_type)
-            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
-        return true;
-    case clang::Type::Typedef:
-        return ClangASTContext::IsReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-    case clang::Type::Elaborated:
-        return ClangASTContext::IsReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-    case clang::Type::Paren:
-        return ClangASTContext::IsReferenceType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-
-    default:
-        break;
-    }
-    
-    return false;
-}
-
-bool
-ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
-{
-    if (clang_type == NULL)
-        return false;
-
-    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-    case clang::Type::Builtin:
-        switch (cast<clang::BuiltinType>(qual_type)->getKind())
-        {
-        default:
-            break;
-        case clang::BuiltinType::ObjCId:
-        case clang::BuiltinType::ObjCClass:
-            return true;
-        }
-        return false;
-    case clang::Type::ObjCObjectPointer:
-        if (target_type)
-            *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
-        return true;
-    case clang::Type::BlockPointer:
-        if (target_type)
-            *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
-        return true;
-    case clang::Type::Pointer:
-        if (target_type)
-            *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
-        return true;
-    case clang::Type::MemberPointer:
-        if (target_type)
-            *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
-        return true;
-    case clang::Type::LValueReference:
-        if (target_type)
-            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
-        return true;
-    case clang::Type::RValueReference:
-        if (target_type)
-            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
-        return true;
-    case clang::Type::Typedef:
-        return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-    case clang::Type::Elaborated:
-        return ClangASTContext::IsPointerOrReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-    case clang::Type::Paren:
-        return ClangASTContext::IsPointerOrReferenceType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-    default:
-        break;
-    }
-    return false;
-}
-
-bool
-ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
-{
-    if (!clang_type)
-        return false;
-    
-    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-    const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
-    
-    if (builtin_type)
-    {
-        if (builtin_type->isInteger())
-        {
-            is_signed = builtin_type->isSignedInteger();
-            return true;
-        }
-    }
-    
-    return false;
-}
-
-bool
-ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t *target_type)
-{
-    if (target_type)
-        *target_type = NULL;
-
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-        case clang::Type::Builtin:
-            switch (cast<clang::BuiltinType>(qual_type)->getKind())
-            {
-            default:
-                break;
-            case clang::BuiltinType::ObjCId:
-            case clang::BuiltinType::ObjCClass:
-                return true;
-            }
-            return false;
-        case clang::Type::ObjCObjectPointer:
-            if (target_type)
-                *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
-            return true;
-        case clang::Type::BlockPointer:
-            if (target_type)
-                *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
-            return true;
-        case clang::Type::Pointer:
-            if (target_type)
-                *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
-            return true;
-        case clang::Type::MemberPointer:
-            if (target_type)
-                *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
-            return true;
-        case clang::Type::Typedef:
-            return ClangASTContext::IsPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
-        case clang::Type::Elaborated:
-            return ClangASTContext::IsPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), target_type);
-        case clang::Type::Paren:
-            return ClangASTContext::IsPointerType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), target_type);
-        default:
-            break;
-        }
-    }
-    return false;
-}
-
-bool
-ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
-        if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
-        {
-            clang::BuiltinType::Kind kind = BT->getKind();
-            if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
-            {
-                count = 1;
-                is_complex = false;
-                return true;
-            }
-        }
-        else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
-        {
-            if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
-            {
-                count = 2;
-                is_complex = true;
-                return true;
-            }
-        }
-        else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
-        {
-            if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
-            {
-                count = VT->getNumElements();
-                is_complex = false;
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-bool
-ClangASTContext::IsScalarType (lldb::clang_type_t clang_type)
-{
-    bool is_signed;
-    if (ClangASTContext::IsIntegerType(clang_type, is_signed))
-        return true;
-    
-    uint32_t count;
-    bool is_complex;
-    return ClangASTContext::IsFloatingPointType(clang_type, count, is_complex) && !is_complex;
-}
-
-bool
-ClangASTContext::IsPointerToScalarType (lldb::clang_type_t clang_type)
-{
-    if (!IsPointerType(clang_type))
-        return false;
-    
-    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-    lldb::clang_type_t pointee_type = qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr();
-    return IsScalarType(pointee_type);
-}
-
-bool
-ClangASTContext::IsArrayOfScalarType (lldb::clang_type_t clang_type)
-{
-    clang_type = GetAsArrayType(clang_type, NULL, NULL, NULL);
-    
-    if (clang_type == 0)
-        return false;
-    
-    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-    lldb::clang_type_t item_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
-    return IsScalarType(item_type);
-}
-
-
-bool
-ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        
-        CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-        if (cxx_record_decl)
-        {
-            class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
-            return true;
-        }
-    }
-    class_name.clear();
-    return false;
-}
-
-
-bool
-ClangASTContext::IsCXXClassType (clang_type_t clang_type)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        if (qual_type->getAsCXXRecordDecl() != NULL)
-            return true;
-    }
-    return false;
-}
-
-bool
-ClangASTContext::IsBeingDefined (lldb::clang_type_t clang_type)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type);
-        if (tag_type)
-            return tag_type->isBeingDefined();
-    }
-    return false;
-}
-
-bool 
-ClangASTContext::IsObjCClassType (clang_type_t clang_type)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        if (qual_type->isObjCObjectOrInterfaceType())
-            return true;
-    }
-    return false;
-}
-
-bool
-ClangASTContext::IsObjCObjectPointerType (lldb::clang_type_t clang_type, clang_type_t *class_type)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        if (qual_type->isObjCObjectPointerType())
-        {
-            if (class_type)
-            {
-                *class_type = NULL;
-                
-                if (!qual_type->isObjCClassType() &&
-                    !qual_type->isObjCIdType())
-                {
-                    const ObjCObjectPointerType *obj_pointer_type = dyn_cast<ObjCObjectPointerType>(qual_type);
-                    if (!obj_pointer_type)
-                        *class_type = NULL;
-                    else
-                        *class_type = QualType(obj_pointer_type->getInterfaceType(), 0).getAsOpaquePtr();
-                }
-            }
-            return true;
-        }
-    }
-    return false;
-}
-
-bool
-ClangASTContext::GetObjCClassName (lldb::clang_type_t clang_type,
-                                   std::string &class_name)
-{
-    if (!clang_type)
-        return false;
-        
-    const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(QualType::getFromOpaquePtr(clang_type));
-    if (!object_type)
-        return false;
-    
-    const ObjCInterfaceDecl *interface = object_type->getInterface();
-    if (!interface)
-        return false;
-    
-    class_name = interface->getNameAsString();
-    return true;
-}
-
-bool 
-ClangASTContext::IsCharType (clang_type_t clang_type)
-{
-    if (clang_type)
-        return QualType::getFromOpaquePtr(clang_type)->isCharType();
-    return false;
-}
-
-bool
-ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
-{
-    clang_type_t pointee_or_element_clang_type = NULL;
-    Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
-    
-    if (pointee_or_element_clang_type == NULL)
-        return false;
-
-    if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
-    {
-        QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
-        
-        if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
-        {
-            QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-            if (type_flags.Test (eTypeIsArray))
-            {
-                // We know the size of the array and it could be a C string
-                // since it is an array of characters
-                length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
-                return true;
-            }
-            else
-            {
-                length = 0;
-                return true;
-            }
-
-        }
-    }
-    return false;
-}
-
-bool
-ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        
-        if (qual_type->isFunctionPointerType())
-            return true;
-    
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-        default:
-            break;
-        case clang::Type::Typedef:
-            return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-        case clang::Type::Elaborated:
-            return ClangASTContext::IsFunctionPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-        case clang::Type::Paren:
-            return ClangASTContext::IsFunctionPointerType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-
-        case clang::Type::LValueReference:
-        case clang::Type::RValueReference:
-            {
-                const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
-                if (reference_type)
-                    return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
-            }
-            break;
-        }
-    }
-    return false;
-}
-
-size_t
-ClangASTContext::GetArraySize (clang_type_t clang_type)
-{
-    if (clang_type)
-    {
-        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-        case clang::Type::ConstantArray:
-            {
-                const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
-                if (array)
-                    return array->getSize().getLimitedValue();
-            }
-            break;
-
-        case clang::Type::Typedef:
-            return ClangASTContext::GetArraySize(cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-            
-        case clang::Type::Elaborated:
-            return ClangASTContext::GetArraySize(cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-
-        case clang::Type::Paren:
-            return ClangASTContext::GetArraySize(cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-                
-        default:
-            break;
-        }
-    }
-    return 0;
-}
-
-clang_type_t
-ClangASTContext::GetAsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size, bool *is_incomplete)
-{
-    if (is_incomplete)
-        *is_incomplete = false;
-    if (!clang_type)
-        return 0;
-    
-    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-    
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-    default:
-        break;
-
-    case clang::Type::ConstantArray:
-        if (member_type)
-            *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
-        if (size)
-            *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
-        return clang_type;
-
-    case clang::Type::IncompleteArray:
-        if (member_type)
-            *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
-        if (size)
-            *size = 0;
-        if (is_incomplete)
-            *is_incomplete = true;
-        return clang_type;
-
-    case clang::Type::VariableArray:
-        if (member_type)
-            *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
-        if (size)
-            *size = 0;
-        return clang_type;
-
-    case clang::Type::DependentSizedArray:
-        if (member_type)
-            *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
-        if (size)
-            *size = 0;
-        return clang_type;
-    
-    case clang::Type::Typedef:
-        return ClangASTContext::GetAsArrayType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
-                                                member_type, 
-                                                size,
-                                                is_incomplete);
-    
-    case clang::Type::Elaborated:
-        return ClangASTContext::GetAsArrayType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
-                                                member_type,
-                                                size,
-                                                is_incomplete);
-    case clang::Type::Paren:
-        return ClangASTContext::GetAsArrayType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
-                                                member_type,
-                                                size,
-                                                is_incomplete);
-    }
-    return 0;
-}
-
-
-#pragma mark Typedefs
-
-clang_type_t
-ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        ASTContext *ast = getASTContext();
-        IdentifierTable *identifier_table = getIdentifierTable();
-        assert (ast != NULL);
-        assert (identifier_table != NULL);
-        if (decl_ctx == NULL)
-            decl_ctx = ast->getTranslationUnitDecl();
-        TypedefDecl *decl = TypedefDecl::Create (*ast,
-                                                 decl_ctx,
-                                                 SourceLocation(),
-                                                 SourceLocation(),
-                                                 name ? &identifier_table->get(name) : NULL, // Identifier
-                                                 ast->getTrivialTypeSourceInfo(qual_type));
-        
-        //decl_ctx->addDecl (decl);
-
-        decl->setAccess(AS_public); // TODO respect proper access specifier
-
-        // Get a uniqued QualType for the typedef decl type
-        return ast->getTypedefType (decl).getAsOpaquePtr();
-    }
-    return NULL;
+    return ClangASTType();
 }
 
 // Disable this for now since I can't seem to get a nicely formatted float
@@ -6726,103 +2124,23 @@
 //  return false;
 //}
 
-size_t
-ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
-{
-    if (clang_type)
-    {
-        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-        uint32_t count = 0;
-        bool is_complex = false;
-        if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
-        {
-            // TODO: handle complex and vector types
-            if (count != 1)
-                return false;
 
-            StringRef s_sref(s);
-            APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
-
-            const uint64_t bit_size = ast->getTypeSize (qual_type);
-            const uint64_t byte_size = bit_size / 8;
-            if (dst_size >= byte_size)
-            {
-                if (bit_size == sizeof(float)*8)
-                {
-                    float float32 = ap_float.convertToFloat();
-                    ::memcpy (dst, &float32, byte_size);
-                    return byte_size;
-                }
-                else if (bit_size >= 64)
-                {
-                    llvm::APInt ap_int(ap_float.bitcastToAPInt());
-                    ::memcpy (dst, ap_int.getRawData(), byte_size);
-                    return byte_size;
-                }
-            }
-        }
-    }
-    return 0;
-}
-
-lldb::clang_type_t
+ClangASTType
 ClangASTContext::GetFloatTypeFromBitSize (clang::ASTContext *ast,
                                           size_t bit_size)
 {
     if (ast)
     {
         if (bit_size == ast->getTypeSize(ast->FloatTy))
-            return ast->FloatTy.getAsOpaquePtr();
+            return ClangASTType(ast, ast->FloatTy.getAsOpaquePtr());
         else if (bit_size == ast->getTypeSize(ast->DoubleTy))
-            return ast->DoubleTy.getAsOpaquePtr();
+            return ClangASTType(ast, ast->DoubleTy.getAsOpaquePtr());
         else if (bit_size == ast->getTypeSize(ast->LongDoubleTy))
-            return ast->LongDoubleTy.getAsOpaquePtr();
+            return ClangASTType(ast, ast->LongDoubleTy.getAsOpaquePtr());
         else if (bit_size == ast->getTypeSize(ast->HalfTy))
-            return ast->HalfTy.getAsOpaquePtr();
+            return ClangASTType(ast, ast->HalfTy.getAsOpaquePtr());
     }
-    return NULL;
-}
-
-unsigned
-ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
-{
-    assert (clang_type);
-    
-    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-    
-    return qual_type.getQualifiers().getCVRQualifiers();
-}
-
-bool
-ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
-{
-    if (clang_type == NULL)
-        return false;
-
-    return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type));
-}
-
-
-bool
-ClangASTContext::GetCompleteType (clang_type_t clang_type)
-{
-    return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
-}
-
-bool
-ClangASTContext::IsCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
-{
-    if (clang_type == NULL)
-        return false;
-    
-    return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type), false); // just check but don't let it actually complete
-}
-
-
-bool
-ClangASTContext::IsCompleteType (clang_type_t clang_type)
-{   
-    return ClangASTContext::IsCompleteType (getASTContext(), clang_type);
+    return ClangASTType();
 }
 
 bool
diff --git a/source/Symbol/ClangASTImporter.cpp b/source/Symbol/ClangASTImporter.cpp
index 1439c30..1529496 100644
--- a/source/Symbol/ClangASTImporter.cpp
+++ b/source/Symbol/ClangASTImporter.cpp
@@ -568,8 +568,8 @@
     }
 }
 
-clang::Decl 
-*ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
+clang::Decl *
+ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
 {
     ClangASTMetrics::RegisterClangImport();
     
diff --git a/source/Symbol/ClangASTType.cpp b/source/Symbol/ClangASTType.cpp
index c6c5c05..c2fbe27 100644
--- a/source/Symbol/ClangASTType.cpp
+++ b/source/Symbol/ClangASTType.cpp
@@ -13,10 +13,13 @@
 
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/Type.h"
 
@@ -36,9 +39,9 @@
 #include "lldb/Core/Scalar.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/StreamString.h"
-#include "lldb/Core/UniqueCStringMap.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/VerifyDecl.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 
@@ -46,211 +49,655 @@
 
 using namespace lldb;
 using namespace lldb_private;
+using namespace clang;
+using namespace llvm;
 
+static bool
+GetCompleteQualType (ASTContext *ast, QualType qual_type, bool allow_completion = true)
+{
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::ConstantArray:
+        case clang::Type::IncompleteArray:
+        case clang::Type::VariableArray:
+        {
+            const ArrayType *array_type = dyn_cast<ArrayType>(qual_type.getTypePtr());
+            
+            if (array_type)
+                return GetCompleteQualType (ast, array_type->getElementType(), allow_completion);
+        }
+            break;
+            
+        case clang::Type::Record:
+        case clang::Type::Enum:
+        {
+            const TagType *tag_type = dyn_cast<TagType>(qual_type.getTypePtr());
+            if (tag_type)
+            {
+                TagDecl *tag_decl = tag_type->getDecl();
+                if (tag_decl)
+                {
+                    if (tag_decl->isCompleteDefinition())
+                        return true;
+                    
+                    if (!allow_completion)
+                        return false;
+                    
+                    if (tag_decl->hasExternalLexicalStorage())
+                    {
+                        if (ast)
+                        {
+                            ExternalASTSource *external_ast_source = ast->getExternalSource();
+                            if (external_ast_source)
+                            {
+                                external_ast_source->CompleteType(tag_decl);
+                                return !tag_type->isIncompleteType();
+                            }
+                        }
+                    }
+                    return false;
+                }
+            }
+            
+        }
+            break;
+            
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+        {
+            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
+            if (objc_class_type)
+            {
+                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                // We currently can't complete objective C types through the newly added ASTContext
+                // because it only supports TagDecl objects right now...
+                if (class_interface_decl)
+                {
+                    if (class_interface_decl->getDefinition())
+                        return true;
+                    
+                    if (!allow_completion)
+                        return false;
+                    
+                    if (class_interface_decl->hasExternalLexicalStorage())
+                    {
+                        if (ast)
+                        {
+                            ExternalASTSource *external_ast_source = ast->getExternalSource();
+                            if (external_ast_source)
+                            {
+                                external_ast_source->CompleteType (class_interface_decl);
+                                return !objc_class_type->isIncompleteType();
+                            }
+                        }
+                    }
+                    return false;
+                }
+            }
+        }
+            break;
+            
+        case clang::Type::Typedef:
+            return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion);
+            
+        case clang::Type::Elaborated:
+            return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType(), allow_completion);
+            
+        case clang::Type::Paren:
+            return GetCompleteQualType (ast, cast<ParenType>(qual_type)->desugar(), allow_completion);
+            
+        default:
+            break;
+    }
+    
+    return true;
+}
+
+static ObjCIvarDecl::AccessControl
+ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
+{
+    switch (access)
+    {
+        case eAccessNone:      return ObjCIvarDecl::None;
+        case eAccessPublic:    return ObjCIvarDecl::Public;
+        case eAccessPrivate:   return ObjCIvarDecl::Private;
+        case eAccessProtected: return ObjCIvarDecl::Protected;
+        case eAccessPackage:   return ObjCIvarDecl::Package;
+    }
+    return ObjCIvarDecl::None;
+}
+
+//----------------------------------------------------------------------
+// Tests
+//----------------------------------------------------------------------
+
+ClangASTType::ClangASTType (clang::ASTContext *ast,
+                            clang::QualType qual_type) :
+    m_type (qual_type.getAsOpaquePtr()),
+    m_ast (ast)
+{
+}
 
 ClangASTType::~ClangASTType()
 {
 }
 
-std::string
-ClangASTType::GetTypeNameForQualType (clang::ASTContext *ast, clang::QualType qual_type)
+//----------------------------------------------------------------------
+// Tests
+//----------------------------------------------------------------------
+
+bool
+ClangASTType::IsAggregateType () const
 {
-    std::string type_name;
+    if (!IsValid())
+        return false;
     
-    clang::PrintingPolicy printing_policy (ast->getPrintingPolicy());
-    printing_policy.SuppressTagKeyword = true;
-    printing_policy.LangOpts.WChar = true;
-    const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
-    if (typedef_type)
-    {
-        const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
-        type_name = typedef_decl->getQualifiedNameAsString(printing_policy);
-    }
-    else
-    {
-        type_name = qual_type.getAsString(printing_policy);
-    }
-    return type_name;
-}
-
-std::string
-ClangASTType::GetTypeNameForOpaqueQualType (clang::ASTContext *ast, clang_type_t opaque_qual_type)
-{
-    return GetTypeNameForQualType (ast, clang::QualType::getFromOpaquePtr(opaque_qual_type));
-}
-
-ClangASTType
-ClangASTType::GetCanonicalType (clang::ASTContext *ast, lldb::clang_type_t opaque_qual_type)
-{
-    if (ast && opaque_qual_type)
-        return ClangASTType (ast,
-                             clang::QualType::getFromOpaquePtr(opaque_qual_type).getCanonicalType().getAsOpaquePtr());
-    return ClangASTType();
-}
-
-ConstString
-ClangASTType::GetConstTypeName ()
-{
-    // TODO: verify if we actually need to complete a type just to get its type name????
-    if (!ClangASTContext::GetCompleteType (this->m_ast, this->m_type))
-        return ConstString("<invalid>");
-    return GetConstTypeName (m_ast, m_type);
-}
-
-ConstString
-ClangASTType::GetConstQualifiedTypeName ()
-{
-    // TODO: verify if we actually need to complete a type just to get its fully qualified type name????
-    if (!ClangASTContext::GetCompleteType (this->m_ast, this->m_type))
-        return ConstString("<invalid>");
-    return GetConstQualifiedTypeName (m_ast, m_type);
-}
-
-ConstString
-ClangASTType::GetConstQualifiedTypeName (clang::ASTContext *ast, clang_type_t clang_type)
-{
-    if (ast == NULL || clang_type == NULL)
-        return ConstString("<invalid>");
-
-    return ConstString (GetTypeNameForQualType (ast, clang::QualType::getFromOpaquePtr(clang_type)).c_str());
-}
-
-
-ConstString
-ClangASTType::GetConstTypeName (clang::ASTContext *ast, clang_type_t clang_type)
-{
-    if (!clang_type)
-        return ConstString("<invalid>");
+    QualType qual_type (GetCanonicalQualType());
     
-    std::string type_name (GetTypeNameForOpaqueQualType(ast, clang_type));
-    ConstString const_type_name;
-    if (type_name.empty())
-        const_type_name.SetCString ("<invalid>");
-    else
-        const_type_name.SetCString(type_name.c_str());
-    return const_type_name;
-}
-
-clang_type_t
-ClangASTType::GetPointeeType () const
-{
-    return GetPointeeType (m_type);
-}
-
-clang_type_t
-ClangASTType::GetPointeeType (clang_type_t clang_type)
-{
-    if (clang_type)
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
     {
-        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-        
-        return qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr();
+        case clang::Type::IncompleteArray:
+        case clang::Type::VariableArray:
+        case clang::Type::ConstantArray:
+        case clang::Type::ExtVector:
+        case clang::Type::Vector:
+        case clang::Type::Record:
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            return true;
+        case clang::Type::Elaborated:
+            return ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsAggregateType();
+        case clang::Type::Typedef:
+            return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsAggregateType();
+        case clang::Type::Paren:
+            return ClangASTType(m_ast, cast<ParenType>(qual_type)->desugar()).IsAggregateType();
+        default:
+            break;
     }
-    return NULL;
-}
-
-lldb::clang_type_t
-ClangASTType::GetArrayElementType (uint64_t& stride)
-{
-    return GetArrayElementType(m_ast, m_type, stride);
-}
-
-lldb::clang_type_t
-ClangASTType::GetArrayElementType (clang::ASTContext* ast,
-                                   lldb::clang_type_t opaque_clang_qual_type,
-                                   uint64_t& stride)
-{
-    if (opaque_clang_qual_type)
-    {
-        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
-        
-        lldb::clang_type_t ret_type = qual_type.getTypePtr()->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified().getAsOpaquePtr();
-        
-        // TODO: the real stride will be >= this value.. find the real one!
-        stride = GetTypeByteSize(ast, ret_type);
-        
-        return ret_type;
-        
-    }
-    return NULL;
-
-}
-
-lldb::clang_type_t
-ClangASTType::GetPointerType () const
-{
-    return GetPointerType (m_ast, m_type);
-}
-
-lldb::clang_type_t
-ClangASTType::GetPointerType (clang::ASTContext *ast_context,
-                              lldb::clang_type_t opaque_clang_qual_type)
-{
-    if (opaque_clang_qual_type)
-    {
-        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
-        
-        return ast_context->getPointerType(qual_type).getAsOpaquePtr();
-    }
-    return NULL;
-}
-
-ClangASTType
-ClangASTType::GetFullyUnqualifiedType ()
-{
-    return GetFullyUnqualifiedType(m_ast, m_type);
-}
-
-static clang::QualType GetFullyUnqualifiedType_Impl (clang::QualType Ty,
-                                                     clang::ASTContext * ctx)
-{
-    if (Ty->isPointerType())
-        Ty = ctx->getPointerType(GetFullyUnqualifiedType_Impl(Ty->getPointeeType(),ctx));
-    else
-        Ty = Ty.getUnqualifiedType();
-    Ty.removeLocalConst();
-    Ty.removeLocalRestrict();
-    Ty.removeLocalVolatile();
-    return Ty;
-}
-
-ClangASTType
-ClangASTType::GetFullyUnqualifiedType (clang::ASTContext *ast_context, lldb::clang_type_t clang_type)
-{
-    return ClangASTType(ast_context,GetFullyUnqualifiedType_Impl(clang::QualType::getFromOpaquePtr(clang_type),ast_context).getAsOpaquePtr());
-}
-
-lldb::Encoding
-ClangASTType::GetEncoding (uint64_t &count)
-{
-    return GetEncoding(m_type, count);
-}
-
-
-lldb::LanguageType
-ClangASTType::GetMinimumLanguage ()
-{
-    return ClangASTType::GetMinimumLanguage (m_ast,
-                                             m_type);
+    // The clang type does have a value
+    return false;
 }
 
 bool
-ClangASTType::IsPolymorphicClass (clang::ASTContext *ast_context, lldb::clang_type_t clang_type)
+ClangASTType::IsArrayType (ClangASTType *element_type_ptr,
+                           uint64_t *size,
+                           bool *is_incomplete) const
 {
-    if (clang_type)
+    if (IsValid())
     {
-        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type).getCanonicalType());
+        QualType qual_type (GetCanonicalQualType());
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            default:
+                break;
+                
+            case clang::Type::ConstantArray:
+                if (element_type_ptr)
+                    element_type_ptr->SetClangType (m_ast, cast<ConstantArrayType>(qual_type)->getElementType());
+                if (size)
+                    *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
+                return true;
+                
+            case clang::Type::IncompleteArray:
+                if (element_type_ptr)
+                    element_type_ptr->SetClangType (m_ast, cast<IncompleteArrayType>(qual_type)->getElementType());
+                if (size)
+                    *size = 0;
+                if (is_incomplete)
+                    *is_incomplete = true;
+                return true;
+                
+            case clang::Type::VariableArray:
+                if (element_type_ptr)
+                    element_type_ptr->SetClangType (m_ast, cast<VariableArrayType>(qual_type)->getElementType());
+                if (size)
+                    *size = 0;
+                return true;
+                
+            case clang::Type::DependentSizedArray:
+                if (element_type_ptr)
+                    element_type_ptr->SetClangType (m_ast, cast<DependentSizedArrayType>(qual_type)->getElementType());
+                if (size)
+                    *size = 0;
+                return true;
+                
+            case clang::Type::Typedef:
+                return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsArrayType (element_type_ptr,
+                                                                                                                       size,
+                                                                                                                       is_incomplete);
+            case clang::Type::Elaborated:
+                return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsArrayType (element_type_ptr,
+                                                                                                          size,
+                                                                                                          is_incomplete);
+            case clang::Type::Paren:
+                return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsArrayType (element_type_ptr,
+                                                                                                       size,
+                                                                                                       is_incomplete);
+        }
+    }
+    if (element_type_ptr)
+        element_type_ptr->Clear();
+    if (size)
+        *size = 0;
+    if (is_incomplete)
+        *is_incomplete = false;
+    return 0;
+}
+
+
+bool
+ClangASTType::IsCharType () const
+{
+    if (!IsValid())
+        return false;
+    return GetQualType().getUnqualifiedType()->isCharType();
+}
+
+
+bool
+ClangASTType::IsCompleteType () const
+{
+    if (!IsValid())
+        return false;
+    const bool allow_completion = false;
+    return GetCompleteQualType (m_ast, GetQualType(), allow_completion);
+}
+
+bool
+ClangASTType::IsConst() const
+{
+    return GetQualType().isConstQualified();
+}
+
+bool
+ClangASTType::IsCStringType (uint32_t &length) const
+{
+    ClangASTType pointee_or_element_clang_type;
+    length = 0;
+    Flags type_flags (GetTypeInfo (&pointee_or_element_clang_type));
+    
+    if (!pointee_or_element_clang_type.IsValid())
+        return false;
+    
+    if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
+    {        
+        if (pointee_or_element_clang_type.IsCharType())
+        {
+            if (type_flags.Test (eTypeIsArray))
+            {
+                // We know the size of the array and it could be a C string
+                // since it is an array of characters
+                length = cast<ConstantArrayType>(GetCanonicalQualType().getTypePtr())->getSize().getLimitedValue();
+            }
+            return true;
+            
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTType::IsFunctionType (bool *is_variadic_ptr) const
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetCanonicalQualType());
+        
+        if (qual_type->isFunctionType())
+        {
+            if (is_variadic_ptr)
+            {
+                const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+                if (function_proto_type)
+                    *is_variadic_ptr = function_proto_type->isVariadic();
+                else
+                    *is_variadic_ptr = false;
+            }
+            return true;
+        }
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            default:
+                break;
+            case clang::Type::Typedef:
+                return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsFunctionType();
+            case clang::Type::Elaborated:
+                return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsFunctionType();
+            case clang::Type::Paren:
+                return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsFunctionType();
+                
+            case clang::Type::LValueReference:
+            case clang::Type::RValueReference:
+                {
+                    const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+                    if (reference_type)
+                        return ClangASTType (m_ast, reference_type->getPointeeType()).IsFunctionType();
+                }
+                break;
+        }
+    }
+    return false;
+}
+
+
+bool
+ClangASTType::IsFunctionPointerType () const
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetCanonicalQualType());
+        
+        if (qual_type->isFunctionPointerType())
+            return true;
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+        default:
+            break;
+        case clang::Type::Typedef:
+            return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsFunctionPointerType();
+        case clang::Type::Elaborated:
+            return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsFunctionPointerType();
+        case clang::Type::Paren:
+            return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsFunctionPointerType();
+            
+        case clang::Type::LValueReference:
+        case clang::Type::RValueReference:
+            {
+                const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+                if (reference_type)
+                    return ClangASTType (m_ast, reference_type->getPointeeType()).IsFunctionPointerType();
+            }
+            break;
+        }
+    }
+    return false;
+
+}
+
+bool
+ClangASTType::IsIntegerType (bool &is_signed) const
+{
+    if (!IsValid())
+        return false;
+    
+    QualType qual_type (GetCanonicalQualType());
+    const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
+    
+    if (builtin_type)
+    {
+        if (builtin_type->isInteger())
+        {
+            is_signed = builtin_type->isSignedInteger();
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+bool
+ClangASTType::IsPointerType (ClangASTType *pointee_type) const
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetCanonicalQualType());
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Builtin:
+                switch (cast<clang::BuiltinType>(qual_type)->getKind())
+                {
+                    default:
+                        break;
+                    case clang::BuiltinType::ObjCId:
+                    case clang::BuiltinType::ObjCClass:
+                        return true;
+                }
+                return false;
+            case clang::Type::ObjCObjectPointer:
+                if (pointee_type)
+                    pointee_type->SetClangType (m_ast, cast<ObjCObjectPointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::BlockPointer:
+                if (pointee_type)
+                    pointee_type->SetClangType (m_ast, cast<BlockPointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::Pointer:
+                if (pointee_type)
+                    pointee_type->SetClangType (m_ast, cast<PointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::MemberPointer:
+                if (pointee_type)
+                    pointee_type->SetClangType (m_ast, cast<MemberPointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::Typedef:
+                return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPointerType(pointee_type);
+            case clang::Type::Elaborated:
+                return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsPointerType(pointee_type);
+            case clang::Type::Paren:
+                return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsPointerType(pointee_type);
+            default:
+                break;
+        }
+    }
+    if (pointee_type)
+        pointee_type->Clear();
+    return false;
+}
+
+
+bool
+ClangASTType::IsPointerOrReferenceType (ClangASTType *pointee_type) const
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetCanonicalQualType());
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Builtin:
+                switch (cast<clang::BuiltinType>(qual_type)->getKind())
+            {
+                default:
+                    break;
+                case clang::BuiltinType::ObjCId:
+                case clang::BuiltinType::ObjCClass:
+                    return true;
+            }
+                return false;
+            case clang::Type::ObjCObjectPointer:
+                if (pointee_type)
+                    pointee_type->SetClangType(m_ast, cast<ObjCObjectPointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::BlockPointer:
+                if (pointee_type)
+                    pointee_type->SetClangType(m_ast, cast<BlockPointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::Pointer:
+                if (pointee_type)
+                    pointee_type->SetClangType(m_ast, cast<PointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::MemberPointer:
+                if (pointee_type)
+                    pointee_type->SetClangType(m_ast, cast<MemberPointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::LValueReference:
+                if (pointee_type)
+                    pointee_type->SetClangType(m_ast, cast<LValueReferenceType>(qual_type)->desugar());
+                return true;
+            case clang::Type::RValueReference:
+                if (pointee_type)
+                    pointee_type->SetClangType(m_ast, cast<LValueReferenceType>(qual_type)->desugar());
+                return true;
+            case clang::Type::Typedef:
+                return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPointerOrReferenceType(pointee_type);
+            case clang::Type::Elaborated:
+                return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsPointerOrReferenceType(pointee_type);
+            case clang::Type::Paren:
+                return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsPointerOrReferenceType(pointee_type);
+            default:
+                break;
+        }
+    }
+    if (pointee_type)
+        pointee_type->Clear();
+    return false;
+}
+
+
+bool
+ClangASTType::IsReferenceType (ClangASTType *pointee_type) const
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetCanonicalQualType());
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        
+        switch (type_class)
+        {
+            case clang::Type::LValueReference:
+                if (pointee_type)
+                    pointee_type->SetClangType(m_ast, cast<LValueReferenceType>(qual_type)->desugar());
+                return true;
+            case clang::Type::RValueReference:
+                if (pointee_type)
+                    pointee_type->SetClangType(m_ast, cast<LValueReferenceType>(qual_type)->desugar());
+                return true;
+            case clang::Type::Typedef:
+                return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsReferenceType(pointee_type);
+            case clang::Type::Elaborated:
+                return ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsReferenceType(pointee_type);
+            case clang::Type::Paren:
+                return ClangASTType(m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsReferenceType(pointee_type);
+                
+            default:
+                break;
+        }
+    }
+    if (pointee_type)
+        pointee_type->Clear();
+    return false;
+}
+
+bool
+ClangASTType::IsFloatingPointType (uint32_t &count, bool &is_complex) const
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetCanonicalQualType());
+        
+        if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
+        {
+            clang::BuiltinType::Kind kind = BT->getKind();
+            if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
+            {
+                count = 1;
+                is_complex = false;
+                return true;
+            }
+        }
+        else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
+        {
+            if (ClangASTType (m_ast, CT->getElementType()).IsFloatingPointType (count, is_complex))
+            {
+                count = 2;
+                is_complex = true;
+                return true;
+            }
+        }
+        else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
+        {
+            if (ClangASTType (m_ast, VT->getElementType()).IsFloatingPointType (count, is_complex))
+            {
+                count = VT->getNumElements();
+                is_complex = false;
+                return true;
+            }
+        }
+    }
+    count = 0;
+    is_complex = false;
+    return false;
+}
+
+
+bool
+ClangASTType::IsDefined() const
+{
+    if (!IsValid())
+        return false;
+
+    QualType qual_type(GetQualType());
+    const TagType *tag_type = dyn_cast<TagType>(qual_type.getTypePtr());
+    if (tag_type)
+    {
+        TagDecl *tag_decl = tag_type->getDecl();
+        if (tag_decl)
+            return tag_decl->isCompleteDefinition();
+        return false;
+    }
+    else
+    {
+        const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
+        if (objc_class_type)
+        {
+            ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+            if (class_interface_decl)
+                return class_interface_decl->getDefinition() != NULL;
+            return false;
+        }
+    }
+    return true;
+}
+
+bool
+ClangASTType::IsObjCClassType () const
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetCanonicalQualType());
+    
+        const ObjCObjectPointerType *obj_pointer_type = dyn_cast<ObjCObjectPointerType>(qual_type);
+
+        if (obj_pointer_type)
+            return obj_pointer_type->isObjCClassType();
+    }
+    return false;
+}
+
+bool
+ClangASTType::IsObjCObjectOrInterfaceType () const
+{
+    if (IsValid())
+        return GetCanonicalQualType()->isObjCObjectOrInterfaceType();
+    return false;
+}
+
+bool
+ClangASTType::IsPolymorphicClass () const
+{
+    if (IsValid())
+    {
+        QualType qual_type(GetCanonicalQualType());
         const clang::Type::TypeClass type_class = qual_type->getTypeClass();
         switch (type_class)
         {
             case clang::Type::Record:
-                if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+                if (GetCompleteType())
                 {
-                    const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-                    const clang::RecordDecl *record_decl = record_type->getDecl();
+                    const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+                    const RecordDecl *record_decl = record_type->getDecl();
                     if (record_decl)
                     {
-                        const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+                        const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
                         if (cxx_record_decl)
                             return cxx_record_decl->isPolymorphic();
                     }
@@ -264,13 +711,661 @@
     return false;
 }
 
-lldb::TypeClass
-ClangASTType::GetTypeClass (clang::ASTContext *ast_context, lldb::clang_type_t clang_type)
+bool
+ClangASTType::IsPossibleDynamicType (ClangASTType *dynamic_pointee_type,
+                                     bool check_cplusplus,
+                                     bool check_objc) const
 {
-    if (clang_type == NULL)
-        return lldb::eTypeClassInvalid;
+    QualType pointee_qual_type;
+    if (m_type)
+    {
+        QualType qual_type (GetCanonicalQualType());
+        bool success = false;
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Builtin:
+                if (check_objc && cast<BuiltinType>(qual_type)->getKind() == BuiltinType::ObjCId)
+                {
+                    if (dynamic_pointee_type)
+                        dynamic_pointee_type->SetClangType(m_ast, m_type);
+                    return true;
+                }
+                break;
+                
+            case clang::Type::ObjCObjectPointer:
+                if (check_objc)
+                {
+                    if (dynamic_pointee_type)
+                        dynamic_pointee_type->SetClangType(m_ast, cast<ObjCObjectPointerType>(qual_type)->getPointeeType());
+                    return true;
+                }
+                break;
+                
+            case clang::Type::Pointer:
+                pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
+                success = true;
+                break;
+                
+            case clang::Type::LValueReference:
+            case clang::Type::RValueReference:
+                pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
+                success = true;
+                break;
+                
+            case clang::Type::Typedef:
+                return ClangASTType (m_ast,
+                                     cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPossibleDynamicType (dynamic_pointee_type,
+                                                                                                                          check_cplusplus,
+                                                                                                                          check_objc);
+                
+            case clang::Type::Elaborated:
+                return ClangASTType (m_ast,
+                                     cast<ElaboratedType>(qual_type)->getNamedType()).IsPossibleDynamicType (dynamic_pointee_type,
+                                                                                                             check_cplusplus,
+                                                                                                             check_objc);
+                
+            case clang::Type::Paren:
+                return ClangASTType (m_ast,
+                                     cast<ParenType>(qual_type)->desugar()).IsPossibleDynamicType (dynamic_pointee_type,
+                                                                                                   check_cplusplus,
+                                                                                                   check_objc);
+            default:
+                break;
+        }
+        
+        if (success)
+        {
+            // Check to make sure what we are pointing too is a possible dynamic C++ type
+            // We currently accept any "void *" (in case we have a class that has been
+            // watered down to an opaque pointer) and virtual C++ classes.
+            const clang::Type::TypeClass pointee_type_class = pointee_qual_type.getCanonicalType()->getTypeClass();
+            switch (pointee_type_class)
+            {
+                case clang::Type::Builtin:
+                    switch (cast<BuiltinType>(pointee_qual_type)->getKind())
+                {
+                    case BuiltinType::UnknownAny:
+                    case BuiltinType::Void:
+                        if (dynamic_pointee_type)
+                            dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type);
+                        return true;
+                        
+                    case BuiltinType::NullPtr:
+                    case BuiltinType::Bool:
+                    case BuiltinType::Char_U:
+                    case BuiltinType::UChar:
+                    case BuiltinType::WChar_U:
+                    case BuiltinType::Char16:
+                    case BuiltinType::Char32:
+                    case BuiltinType::UShort:
+                    case BuiltinType::UInt:
+                    case BuiltinType::ULong:
+                    case BuiltinType::ULongLong:
+                    case BuiltinType::UInt128:
+                    case BuiltinType::Char_S:
+                    case BuiltinType::SChar:
+                    case BuiltinType::WChar_S:
+                    case BuiltinType::Short:
+                    case BuiltinType::Int:
+                    case BuiltinType::Long:
+                    case BuiltinType::LongLong:
+                    case BuiltinType::Int128:
+                    case BuiltinType::Float:
+                    case BuiltinType::Double:
+                    case BuiltinType::LongDouble:
+                    case BuiltinType::Dependent:
+                    case BuiltinType::Overload:
+                    case BuiltinType::ObjCId:
+                    case BuiltinType::ObjCClass:
+                    case BuiltinType::ObjCSel:
+                    case BuiltinType::BoundMember:
+                    case BuiltinType::Half:
+                    case BuiltinType::ARCUnbridgedCast:
+                    case BuiltinType::PseudoObject:
+                    case BuiltinType::BuiltinFn:
+                    case BuiltinType::OCLEvent:
+                    case BuiltinType::OCLImage1d:
+                    case BuiltinType::OCLImage1dArray:
+                    case BuiltinType::OCLImage1dBuffer:
+                    case BuiltinType::OCLImage2d:
+                    case BuiltinType::OCLImage2dArray:
+                    case BuiltinType::OCLImage3d:
+                    case BuiltinType::OCLSampler:
+                        break;
+                }
+                    break;
+                    
+                case clang::Type::Record:
+                    if (check_cplusplus)
+                    {
+                        CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
+                        if (cxx_record_decl)
+                        {
+                            bool is_complete = cxx_record_decl->isCompleteDefinition();
+                            
+                            if (is_complete)
+                                success = cxx_record_decl->isDynamicClass();
+                            else
+                            {
+                                ClangASTMetadata *metadata = ClangASTContext::GetMetadata (m_ast, cxx_record_decl);
+                                if (metadata)
+                                    success = metadata->GetIsDynamicCXXType();
+                                else
+                                {
+                                    is_complete = ClangASTType(m_ast, pointee_qual_type).GetCompleteType();
+                                    if (is_complete)
+                                        success = cxx_record_decl->isDynamicClass();
+                                    else
+                                        success = false;
+                                }
+                            }
+                            
+                            if (success)
+                            {
+                                if (dynamic_pointee_type)
+                                    dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type);
+                                return true;
+                            }
+                        }
+                    }
+                    break;
+                    
+                case clang::Type::ObjCObject:
+                case clang::Type::ObjCInterface:
+                    if (check_objc)
+                    {
+                        if (dynamic_pointee_type)
+                            dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type);
+                        return true;
+                    }
+                    break;
+                    
+                default:
+                    break;
+            }
+        }
+    }
+    if (dynamic_pointee_type)
+        dynamic_pointee_type->Clear();
+    return false;
+}
 
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+
+bool
+ClangASTType::IsScalarType () const
+{
+    if (!IsValid())
+        return false;
+
+    return (GetTypeInfo (NULL) & eTypeIsScalar) != 0;
+}
+
+bool
+ClangASTType::IsTypedefType () const
+{
+    if (!IsValid())
+        return false;
+    return GetQualType()->getTypeClass() == clang::Type::Typedef;
+}
+
+bool
+ClangASTType::IsVoidType () const
+{
+    if (!IsValid())
+        return false;
+    return GetCanonicalQualType()->isVoidType();
+}
+
+bool
+ClangASTType::IsPointerToScalarType () const
+{
+    if (!IsValid())
+        return false;
+    
+    return IsPointerType() && GetPointeeType().IsScalarType();
+}
+
+bool
+ClangASTType::IsArrayOfScalarType () const
+{
+    ClangASTType element_type;
+    if (IsArrayType(&element_type, NULL, NULL))
+        return element_type.IsScalarType();
+    return false;
+}
+
+
+bool
+ClangASTType::GetCXXClassName (std::string &class_name) const
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetCanonicalQualType());
+        
+        CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+        if (cxx_record_decl)
+        {
+            class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
+            return true;
+        }
+    }
+    class_name.clear();
+    return false;
+}
+
+
+bool
+ClangASTType::IsCXXClassType () const
+{
+    if (!IsValid())
+        return false;
+    
+    QualType qual_type (GetCanonicalQualType());
+    if (qual_type->getAsCXXRecordDecl() != NULL)
+        return true;
+    return false;
+}
+
+bool
+ClangASTType::IsBeingDefined () const
+{
+    if (!IsValid())
+        return false;
+    QualType qual_type (GetCanonicalQualType());
+    const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type);
+    if (tag_type)
+        return tag_type->isBeingDefined();
+    return false;
+}
+
+bool
+ClangASTType::IsObjCObjectPointerType (ClangASTType *class_type_ptr)
+{
+    if (!IsValid())
+        return false;
+    
+    QualType qual_type (GetCanonicalQualType());
+
+    if (qual_type->isObjCObjectPointerType())
+    {
+        if (class_type_ptr)
+        {
+            if (!qual_type->isObjCClassType() &&
+                !qual_type->isObjCIdType())
+            {
+                const ObjCObjectPointerType *obj_pointer_type = dyn_cast<ObjCObjectPointerType>(qual_type);
+                if (obj_pointer_type == NULL)
+                    class_type_ptr->Clear();
+                else
+                    class_type_ptr->SetClangType (m_ast, QualType(obj_pointer_type->getInterfaceType(), 0));
+            }
+        }
+        return true;
+    }
+    if (class_type_ptr)
+        class_type_ptr->Clear();
+    return false;
+}
+
+bool
+ClangASTType::GetObjCClassName (std::string &class_name)
+{
+    if (!IsValid())
+        return false;
+    
+    QualType qual_type (GetCanonicalQualType());
+
+    const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(qual_type);
+    if (object_type)
+    {
+        const ObjCInterfaceDecl *interface = object_type->getInterface();
+        if (interface)
+        {
+            class_name = interface->getNameAsString();
+            return true;
+        }
+    }
+    return false;
+}
+
+
+//----------------------------------------------------------------------
+// Type Completion
+//----------------------------------------------------------------------
+
+bool
+ClangASTType::GetCompleteType () const
+{
+    if (!IsValid())
+        return false;
+    const bool allow_completion = true;
+    return GetCompleteQualType (m_ast, GetQualType(), allow_completion);
+}
+
+//----------------------------------------------------------------------
+// AST related queries
+//----------------------------------------------------------------------
+size_t
+ClangASTType::GetPointerByteSize () const
+{
+    if (m_ast)
+        return m_ast->getTypeSize(m_ast->VoidPtrTy) / 8;
+    return 0;
+}
+
+ConstString
+ClangASTType::GetConstQualifiedTypeName () const
+{
+    return GetConstTypeName ();
+}
+
+ConstString
+ClangASTType::GetConstTypeName () const
+{
+    if (IsValid())
+    {
+        std::string type_name (GetTypeName());
+        if (!type_name.empty())
+            return ConstString (type_name.c_str());
+    }
+    return ConstString("<invalid>");
+}
+
+std::string
+ClangASTType::GetTypeName () const
+{
+    std::string type_name;
+    if (IsValid())
+    {
+        PrintingPolicy printing_policy (m_ast->getPrintingPolicy());
+        QualType qual_type(GetQualType());
+        printing_policy.SuppressTagKeyword = true;
+        printing_policy.LangOpts.WChar = true;
+        const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
+        if (typedef_type)
+        {
+            const TypedefNameDecl *typedef_decl = typedef_type->getDecl();
+            type_name = typedef_decl->getQualifiedNameAsString(printing_policy);
+        }
+        else
+        {
+            type_name = qual_type.getAsString(printing_policy);
+        }
+    }
+    return type_name;
+}
+
+
+uint32_t
+ClangASTType::GetTypeInfo (ClangASTType *pointee_or_element_clang_type) const
+{
+    if (!IsValid())
+        return 0;
+    
+    if (pointee_or_element_clang_type)
+        pointee_or_element_clang_type->Clear();
+    
+    QualType qual_type (GetQualType());
+    
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Builtin:
+        {
+            const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
+            
+            uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
+            switch (builtin_type->getKind())
+            {
+                case clang::BuiltinType::ObjCId:
+                case clang::BuiltinType::ObjCClass:
+                    if (pointee_or_element_clang_type)
+                        pointee_or_element_clang_type->SetClangType(m_ast, m_ast->ObjCBuiltinClassTy);
+                    builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
+                    break;
+                    
+                case clang::BuiltinType::ObjCSel:
+                    if (pointee_or_element_clang_type)
+                        pointee_or_element_clang_type->SetClangType(m_ast, m_ast->CharTy);
+                    builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
+                    break;
+                    
+                case clang::BuiltinType::Bool:
+                case clang::BuiltinType::Char_U:
+                case clang::BuiltinType::UChar:
+                case clang::BuiltinType::WChar_U:
+                case clang::BuiltinType::Char16:
+                case clang::BuiltinType::Char32:
+                case clang::BuiltinType::UShort:
+                case clang::BuiltinType::UInt:
+                case clang::BuiltinType::ULong:
+                case clang::BuiltinType::ULongLong:
+                case clang::BuiltinType::UInt128:
+                case clang::BuiltinType::Char_S:
+                case clang::BuiltinType::SChar:
+                case clang::BuiltinType::WChar_S:
+                case clang::BuiltinType::Short:
+                case clang::BuiltinType::Int:
+                case clang::BuiltinType::Long:
+                case clang::BuiltinType::LongLong:
+                case clang::BuiltinType::Int128:
+                case clang::BuiltinType::Float:
+                case clang::BuiltinType::Double:
+                case clang::BuiltinType::LongDouble:
+                    builtin_type_flags |= eTypeIsScalar;
+                    if (builtin_type->isInteger())
+                    {
+                        builtin_type_flags |= eTypeIsInteger;
+                        if (builtin_type->isSignedInteger())
+                            builtin_type_flags |= eTypeIsSigned;
+                    }
+                    else if (builtin_type->isFloatingPoint())
+                        builtin_type_flags |= eTypeIsFloat;
+                    break;
+                default:
+                    break;
+            }
+            return builtin_type_flags;
+        }
+            
+        case clang::Type::BlockPointer:
+            if (pointee_or_element_clang_type)
+                pointee_or_element_clang_type->SetClangType(m_ast, qual_type->getPointeeType());
+            return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
+            
+        case clang::Type::Complex:
+        {
+            uint32_t complex_type_flags = eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
+            const ComplexType *complex_type = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal());
+            if (complex_type)
+            {
+                QualType complex_element_type (complex_type->getElementType());
+                if (complex_element_type->isIntegerType())
+                    complex_type_flags |= eTypeIsFloat;
+                else if (complex_element_type->isFloatingType())
+                    complex_type_flags |= eTypeIsInteger;
+            }
+            return complex_type_flags;
+        }
+            break;
+            
+        case clang::Type::ConstantArray:
+        case clang::Type::DependentSizedArray:
+        case clang::Type::IncompleteArray:
+        case clang::Type::VariableArray:
+            if (pointee_or_element_clang_type)
+                pointee_or_element_clang_type->SetClangType(m_ast, cast<ArrayType>(qual_type.getTypePtr())->getElementType());
+            return eTypeHasChildren | eTypeIsArray;
+            
+        case clang::Type::DependentName:                    return 0;
+        case clang::Type::DependentSizedExtVector:          return eTypeHasChildren | eTypeIsVector;
+        case clang::Type::DependentTemplateSpecialization:  return eTypeIsTemplate;
+        case clang::Type::Decltype:                         return 0;
+            
+        case clang::Type::Enum:
+            if (pointee_or_element_clang_type)
+                pointee_or_element_clang_type->SetClangType(m_ast, cast<EnumType>(qual_type)->getDecl()->getIntegerType());
+            return eTypeIsEnumeration | eTypeHasValue;
+            
+        case clang::Type::Elaborated:
+            return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetTypeInfo (pointee_or_element_clang_type);
+        case clang::Type::Paren:
+            return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetTypeInfo (pointee_or_element_clang_type);
+            
+        case clang::Type::FunctionProto:                    return eTypeIsFuncPrototype | eTypeHasValue;
+        case clang::Type::FunctionNoProto:                  return eTypeIsFuncPrototype | eTypeHasValue;
+        case clang::Type::InjectedClassName:                return 0;
+            
+        case clang::Type::LValueReference:
+        case clang::Type::RValueReference:
+            if (pointee_or_element_clang_type)
+                pointee_or_element_clang_type->SetClangType(m_ast, cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType());
+            return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
+            
+        case clang::Type::MemberPointer:                    return eTypeIsPointer   | eTypeIsMember | eTypeHasValue;
+            
+        case clang::Type::ObjCObjectPointer:
+            if (pointee_or_element_clang_type)
+                pointee_or_element_clang_type->SetClangType(m_ast, qual_type->getPointeeType());
+            return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
+            
+        case clang::Type::ObjCObject:                       return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
+        case clang::Type::ObjCInterface:                    return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
+            
+        case clang::Type::Pointer:
+            if (pointee_or_element_clang_type)
+                pointee_or_element_clang_type->SetClangType(m_ast, qual_type->getPointeeType());
+            return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
+            
+        case clang::Type::Record:
+            if (qual_type->getAsCXXRecordDecl())
+                return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
+            else
+                return eTypeHasChildren | eTypeIsStructUnion;
+            break;
+        case clang::Type::SubstTemplateTypeParm:            return eTypeIsTemplate;
+        case clang::Type::TemplateTypeParm:                 return eTypeIsTemplate;
+        case clang::Type::TemplateSpecialization:           return eTypeIsTemplate;
+            
+        case clang::Type::Typedef:
+            return eTypeIsTypedef | ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetTypeInfo (pointee_or_element_clang_type);
+        case clang::Type::TypeOfExpr:                       return 0;
+        case clang::Type::TypeOf:                           return 0;
+        case clang::Type::UnresolvedUsing:                  return 0;
+            
+        case clang::Type::ExtVector:
+        case clang::Type::Vector:
+        {
+            uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
+            const VectorType *vector_type = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal());
+            if (vector_type)
+            {
+                if (vector_type->isIntegerType())
+                    vector_type_flags |= eTypeIsFloat;
+                else if (vector_type->isFloatingType())
+                    vector_type_flags |= eTypeIsInteger;
+            }
+            return vector_type_flags;
+        }
+        default:                                            return 0;
+    }
+    return 0;
+}
+
+
+
+lldb::LanguageType
+ClangASTType::GetMinimumLanguage ()
+{
+    if (!IsValid())
+        return lldb::eLanguageTypeC;
+    
+    // If the type is a reference, then resolve it to what it refers to first:
+    QualType qual_type (GetCanonicalQualType().getNonReferenceType());
+    if (qual_type->isAnyPointerType())
+    {
+        if (qual_type->isObjCObjectPointerType())
+            return lldb::eLanguageTypeObjC;
+        
+        QualType pointee_type (qual_type->getPointeeType());
+        if (pointee_type->getPointeeCXXRecordDecl() != NULL)
+            return lldb::eLanguageTypeC_plus_plus;
+        if (pointee_type->isObjCObjectOrInterfaceType())
+            return lldb::eLanguageTypeObjC;
+        if (pointee_type->isObjCClassType())
+            return lldb::eLanguageTypeObjC;
+        if (pointee_type.getTypePtr() == m_ast->ObjCBuiltinIdTy.getTypePtr())
+            return lldb::eLanguageTypeObjC;
+    }
+    else
+    {
+        if (qual_type->isObjCObjectOrInterfaceType())
+            return lldb::eLanguageTypeObjC;
+        if (qual_type->getAsCXXRecordDecl())
+            return lldb::eLanguageTypeC_plus_plus;
+        switch (qual_type->getTypeClass())
+        {
+            default:
+                break;
+            case clang::Type::Builtin:
+                switch (cast<BuiltinType>(qual_type)->getKind())
+            {
+                default:
+                case BuiltinType::Void:
+                case BuiltinType::Bool:
+                case BuiltinType::Char_U:
+                case BuiltinType::UChar:
+                case BuiltinType::WChar_U:
+                case BuiltinType::Char16:
+                case BuiltinType::Char32:
+                case BuiltinType::UShort:
+                case BuiltinType::UInt:
+                case BuiltinType::ULong:
+                case BuiltinType::ULongLong:
+                case BuiltinType::UInt128:
+                case BuiltinType::Char_S:
+                case BuiltinType::SChar:
+                case BuiltinType::WChar_S:
+                case BuiltinType::Short:
+                case BuiltinType::Int:
+                case BuiltinType::Long:
+                case BuiltinType::LongLong:
+                case BuiltinType::Int128:
+                case BuiltinType::Float:
+                case BuiltinType::Double:
+                case BuiltinType::LongDouble:
+                    break;
+                    
+                case BuiltinType::NullPtr:
+                    return eLanguageTypeC_plus_plus;
+                    
+                case BuiltinType::ObjCId:
+                case BuiltinType::ObjCClass:
+                case BuiltinType::ObjCSel:
+                    return eLanguageTypeObjC;
+                    
+                case BuiltinType::Dependent:
+                case BuiltinType::Overload:
+                case BuiltinType::BoundMember:
+                case BuiltinType::UnknownAny:
+                    break;
+            }
+                break;
+            case clang::Type::Typedef:
+                return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetMinimumLanguage();
+        }
+    }
+    return lldb::eLanguageTypeC;
+}
+
+lldb::TypeClass
+ClangASTType::GetTypeClass () const
+{
+    if (!IsValid())
+        return lldb::eTypeClassInvalid;
+    
+    QualType qual_type(GetQualType());
     
     switch (qual_type->getTypeClass())
     {
@@ -299,10 +1394,9 @@
         case clang::Type::ObjCObject:               return lldb::eTypeClassObjCObject;
         case clang::Type::ObjCInterface:            return lldb::eTypeClassObjCInterface;
         case clang::Type::Record:
-            if (ClangASTContext::GetCompleteType (ast_context, clang_type))
             {
-                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-                const clang::RecordDecl *record_decl = record_type->getDecl();
+                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+                const RecordDecl *record_decl = record_type->getDecl();
                 if (record_decl->isUnion())
                     return lldb::eTypeClassUnion;
                 else if (record_decl->isStruct())
@@ -315,10 +1409,10 @@
         case clang::Type::Typedef:                  return lldb::eTypeClassTypedef;
         case clang::Type::UnresolvedUsing:          break;
         case clang::Type::Paren:
-            return ClangASTType::GetTypeClass (ast_context, llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+            return ClangASTType(m_ast, cast<ParenType>(qual_type)->desugar()).GetTypeClass();
         case clang::Type::Elaborated:
-            return ClangASTType::GetTypeClass (ast_context, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-
+            return ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetTypeClass();
+            
         case clang::Type::Attributed:               break;
         case clang::Type::TemplateTypeParm:         break;
         case clang::Type::SubstTemplateTypeParm:    break;
@@ -337,439 +1431,4120 @@
     }
     // We don't know hot to display this type...
     return lldb::eTypeClassOther;
+    
+}
 
+void
+ClangASTType::SetClangType (clang::ASTContext *ast, clang::QualType qual_type)
+{
+    m_ast = ast;
+    m_type = qual_type.getAsOpaquePtr();
+}
+
+unsigned
+ClangASTType::GetTypeQualifiers() const
+{
+    if (IsValid())
+        return GetQualType().getQualifiers().getCVRQualifiers();
+    return 0;
+}
+
+//----------------------------------------------------------------------
+// Creating related types
+//----------------------------------------------------------------------
+
+ClangASTType
+ClangASTType::AddConstModifier () const
+{
+    if (m_type)
+    {
+        QualType result(GetQualType());
+        result.addConst();
+        return ClangASTType (m_ast, result);
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::AddRestrictModifier () const
+{
+    if (m_type)
+    {
+        QualType result(GetQualType());
+        result.getQualifiers().setRestrict (true);
+        return ClangASTType (m_ast, result);
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::AddVolatileModifier () const
+{
+    if (m_type)
+    {
+        QualType result(GetQualType());
+        result.getQualifiers().setVolatile (true);
+        return ClangASTType (m_ast, result);
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetArrayElementType (uint64_t& stride) const
+{
+    if (IsValid())
+    {
+        QualType qual_type(GetCanonicalQualType());
+        
+        ClangASTType element_type (m_ast, qual_type.getTypePtr()->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
+        
+        // TODO: the real stride will be >= this value.. find the real one!
+        stride = element_type.GetByteSize();
+        
+        return element_type;
+        
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetCanonicalType () const
+{
+    if (IsValid())
+        return ClangASTType (m_ast, GetCanonicalQualType());
+    return ClangASTType();
+}
+
+static QualType
+GetFullyUnqualifiedType_Impl (ASTContext *ast, QualType qual_type)
+{
+    if (qual_type->isPointerType())
+        qual_type = ast->getPointerType(GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType()));
+    else
+        qual_type = qual_type.getUnqualifiedType();
+    qual_type.removeLocalConst();
+    qual_type.removeLocalRestrict();
+    qual_type.removeLocalVolatile();
+    return qual_type;
+}
+
+ClangASTType
+ClangASTType::GetFullyUnqualifiedType () const
+{
+    if (IsValid())
+        return ClangASTType(m_ast, GetFullyUnqualifiedType_Impl(m_ast, GetQualType()));
+    return ClangASTType();
 }
 
 
-lldb::LanguageType
-ClangASTType::GetMinimumLanguage (clang::ASTContext *ctx,
-                                  lldb::clang_type_t clang_type)
+int
+ClangASTType::GetFunctionArgumentCount () const
 {
-    if (clang_type == NULL)
-        return lldb::eLanguageTypeC;
-
-    // If the type is a reference, then resolve it to what it refers to first:     
-    clang::QualType qual_type (clang::QualType::getFromOpaquePtr(clang_type).getNonReferenceType());
-    if (qual_type->isAnyPointerType())
+    if (IsValid())
     {
-        if (qual_type->isObjCObjectPointerType())
-            return lldb::eLanguageTypeObjC;
-        
-        clang::QualType pointee_type (qual_type->getPointeeType());
-        if (pointee_type->getPointeeCXXRecordDecl() != NULL)
-            return lldb::eLanguageTypeC_plus_plus;
-        if (pointee_type->isObjCObjectOrInterfaceType())
-            return lldb::eLanguageTypeObjC;
-        if (pointee_type->isObjCClassType())
-            return lldb::eLanguageTypeObjC;
-        if (pointee_type.getTypePtr() == ctx->ObjCBuiltinIdTy.getTypePtr())
-            return lldb::eLanguageTypeObjC;
+        const FunctionProtoType* func = dyn_cast<FunctionProtoType>(GetCanonicalQualType());
+        if (func)
+            return func->getNumArgs();
     }
-    else
+    return -1;
+}
+
+ClangASTType
+ClangASTType::GetFunctionArgumentTypeAtIndex (size_t idx)
+{
+    if (IsValid())
     {
-        if (qual_type->isObjCObjectOrInterfaceType())
-            return lldb::eLanguageTypeObjC;
-        if (qual_type->getAsCXXRecordDecl())
-            return lldb::eLanguageTypeC_plus_plus;
-        switch (qual_type->getTypeClass())
+        const FunctionProtoType* func = dyn_cast<FunctionProtoType>(GetCanonicalQualType());
+        if (func)
         {
-        default:
-                break;
-        case clang::Type::Builtin:
-          switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
-            {
-                default:
-                case clang::BuiltinType::Void:
-                case clang::BuiltinType::Bool:
-                case clang::BuiltinType::Char_U:
-                case clang::BuiltinType::UChar:
-                case clang::BuiltinType::WChar_U:
-                case clang::BuiltinType::Char16:
-                case clang::BuiltinType::Char32:
-                case clang::BuiltinType::UShort:
-                case clang::BuiltinType::UInt:
-                case clang::BuiltinType::ULong:
-                case clang::BuiltinType::ULongLong:
-                case clang::BuiltinType::UInt128:
-                case clang::BuiltinType::Char_S:
-                case clang::BuiltinType::SChar:
-                case clang::BuiltinType::WChar_S:
-                case clang::BuiltinType::Short:
-                case clang::BuiltinType::Int:
-                case clang::BuiltinType::Long:
-                case clang::BuiltinType::LongLong:
-                case clang::BuiltinType::Int128:
-                case clang::BuiltinType::Float:
-                case clang::BuiltinType::Double:
-                case clang::BuiltinType::LongDouble:
-                    break;
-
-                case clang::BuiltinType::NullPtr:   
-                    return eLanguageTypeC_plus_plus;
-                    
-                case clang::BuiltinType::ObjCId:
-                case clang::BuiltinType::ObjCClass:
-                case clang::BuiltinType::ObjCSel:   
-                    return eLanguageTypeObjC;
-
-                case clang::BuiltinType::Dependent:
-                case clang::BuiltinType::Overload:
-                case clang::BuiltinType::BoundMember:
-                case clang::BuiltinType::UnknownAny:
-                    break;
-            }
-            break;
-        case clang::Type::Typedef:
-            return GetMinimumLanguage(ctx,
-                                      llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+            const uint32_t num_args = func->getNumArgs();
+            if (idx < num_args)
+                return ClangASTType(m_ast, func->getArgType(idx));
         }
     }
-    return lldb::eLanguageTypeC;
+    return ClangASTType();
 }
 
+ClangASTType
+ClangASTType::GetFunctionReturnType () const
+{
+    if (IsValid())
+    {
+        QualType qual_type(GetCanonicalQualType());
+        const FunctionProtoType* func = dyn_cast<FunctionProtoType>(qual_type.getTypePtr());
+        if (func)
+            return ClangASTType(m_ast, func->getResultType());
+    }
+    return ClangASTType();
+}
+
+
+ClangASTType
+ClangASTType::GetLValueReferenceType () const
+{
+    if (IsValid())
+    {
+        return ClangASTType(m_ast, m_ast->getLValueReferenceType(GetQualType()));
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetRValueReferenceType () const
+{
+    if (IsValid())
+    {
+        return ClangASTType(m_ast, m_ast->getRValueReferenceType(GetQualType()));
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetNonReferenceType () const
+{
+    if (IsValid())
+        return ClangASTType(m_ast, GetQualType().getNonReferenceType());
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::CreateTypedefType (const char *typedef_name,
+                                 clang::DeclContext *decl_ctx) const
+{
+    if (IsValid() && typedef_name && typedef_name[0])
+    {
+        QualType qual_type (GetQualType());
+        if (decl_ctx == NULL)
+            decl_ctx = m_ast->getTranslationUnitDecl();
+        TypedefDecl *decl = TypedefDecl::Create (*m_ast,
+                                                 decl_ctx,
+                                                 SourceLocation(),
+                                                 SourceLocation(),
+                                                 &m_ast->Idents.get(typedef_name),
+                                                 m_ast->getTrivialTypeSourceInfo(qual_type));
+        
+        decl->setAccess(AS_public); // TODO respect proper access specifier
+        
+        // Get a uniqued QualType for the typedef decl type
+        return ClangASTType (m_ast, m_ast->getTypedefType (decl));
+    }
+    return ClangASTType();
+
+}
+
+ClangASTType
+ClangASTType::GetPointeeType () const
+{
+    if (m_type)
+    {
+        QualType qual_type(GetQualType());
+        return ClangASTType (m_ast, qual_type.getTypePtr()->getPointeeType());
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetPointerType () const
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetQualType());
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::ObjCObject:
+            case clang::Type::ObjCInterface:
+                return ClangASTType(m_ast, m_ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr());
+                
+            default:
+                return ClangASTType(m_ast, m_ast->getPointerType(qual_type).getAsOpaquePtr());
+        }
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetTypedefedType () const
+{
+    if (IsValid())
+    {
+        const TypedefType *typedef_type = dyn_cast<TypedefType>(GetQualType());
+        if (typedef_type)
+            return ClangASTType (m_ast, typedef_type->getDecl()->getUnderlyingType());
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::RemoveFastQualifiers () const
+{
+    if (m_type)
+    {
+        QualType qual_type(GetQualType());
+        qual_type.getQualifiers().removeFastQualifiers();
+        return ClangASTType (m_ast, qual_type);
+    }
+    return ClangASTType();
+}
+
+
+//----------------------------------------------------------------------
+// Create related types using the current type's AST
+//----------------------------------------------------------------------
+
+ClangASTType
+ClangASTType::GetBasicTypeFromAST (lldb::BasicType basic_type) const
+{
+    if (IsValid())
+        return ClangASTContext::GetBasicType(m_ast, basic_type);
+    return ClangASTType();
+}
+//----------------------------------------------------------------------
+// Exploring the type
+//----------------------------------------------------------------------
+
+uint64_t
+ClangASTType::GetBitSize () const
+{
+    if (GetCompleteType ())
+    {
+        QualType qual_type(GetCanonicalQualType());
+        const uint32_t bit_size = m_ast->getTypeSize (qual_type);
+        if (bit_size == 0)
+        {
+            if (qual_type->isIncompleteArrayType())
+                return m_ast->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
+        }
+        if (qual_type->isObjCObjectOrInterfaceType())
+            return bit_size + m_ast->getTypeSize(m_ast->ObjCBuiltinClassTy);
+        return bit_size;
+    }
+    return 0;
+}
+
+uint64_t
+ClangASTType::GetByteSize () const
+{
+    return (GetBitSize () + 7) / 8;
+}
+
+size_t
+ClangASTType::GetTypeBitAlign () const
+{
+    if (GetCompleteType ())
+        return m_ast->getTypeAlign(GetQualType());
+    return 0;
+}
+
+
 lldb::Encoding
-ClangASTType::GetEncoding (clang_type_t clang_type, uint64_t &count)
+ClangASTType::GetEncoding (uint64_t &count) const
 {
+    if (!IsValid())
+        return lldb::eEncodingInvalid;
+    
     count = 1;
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-
+    QualType qual_type(GetCanonicalQualType());
+    
     switch (qual_type->getTypeClass())
     {
-    case clang::Type::UnaryTransform:
-        break;
-            
-    case clang::Type::FunctionNoProto:
-    case clang::Type::FunctionProto:
-        break;
-
-    case clang::Type::IncompleteArray:
-    case clang::Type::VariableArray:
-        break;
-
-    case clang::Type::ConstantArray:
-        break;
-
-    case clang::Type::ExtVector:
-    case clang::Type::Vector:
-        // TODO: Set this to more than one???
-        break;
-
-    case clang::Type::Builtin:
-        switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
-        {
-        default: assert(0 && "Unknown builtin type!");
-        case clang::BuiltinType::Void:
+        case clang::Type::UnaryTransform:
             break;
-
-        case clang::BuiltinType::Bool:
-        case clang::BuiltinType::Char_S:
-        case clang::BuiltinType::SChar:
-        case clang::BuiltinType::WChar_S:
-        case clang::BuiltinType::Char16:
-        case clang::BuiltinType::Char32:
-        case clang::BuiltinType::Short:
-        case clang::BuiltinType::Int:
-        case clang::BuiltinType::Long:
-        case clang::BuiltinType::LongLong:
-        case clang::BuiltinType::Int128:        return lldb::eEncodingSint;
-
-        case clang::BuiltinType::Char_U:
-        case clang::BuiltinType::UChar:
-        case clang::BuiltinType::WChar_U:
-        case clang::BuiltinType::UShort:
-        case clang::BuiltinType::UInt:
-        case clang::BuiltinType::ULong:
-        case clang::BuiltinType::ULongLong:
-        case clang::BuiltinType::UInt128:       return lldb::eEncodingUint;
-
-        case clang::BuiltinType::Float:
-        case clang::BuiltinType::Double:
-        case clang::BuiltinType::LongDouble:    return lldb::eEncodingIEEE754;
-        
-        case clang::BuiltinType::ObjCClass:
-        case clang::BuiltinType::ObjCId:
-        case clang::BuiltinType::ObjCSel:       return lldb::eEncodingUint;
-
-        case clang::BuiltinType::NullPtr:       return lldb::eEncodingUint;
+            
+        case clang::Type::FunctionNoProto:
+        case clang::Type::FunctionProto:
+            break;
+            
+        case clang::Type::IncompleteArray:
+        case clang::Type::VariableArray:
+            break;
+            
+        case clang::Type::ConstantArray:
+            break;
+            
+        case clang::Type::ExtVector:
+        case clang::Type::Vector:
+            // TODO: Set this to more than one???
+            break;
+            
+        case clang::Type::Builtin:
+            switch (cast<BuiltinType>(qual_type)->getKind())
+        {
+            default: assert(0 && "Unknown builtin type!");
+            case BuiltinType::Void:
+                break;
+                
+            case BuiltinType::Bool:
+            case BuiltinType::Char_S:
+            case BuiltinType::SChar:
+            case BuiltinType::WChar_S:
+            case BuiltinType::Char16:
+            case BuiltinType::Char32:
+            case BuiltinType::Short:
+            case BuiltinType::Int:
+            case BuiltinType::Long:
+            case BuiltinType::LongLong:
+            case BuiltinType::Int128:        return lldb::eEncodingSint;
+                
+            case BuiltinType::Char_U:
+            case BuiltinType::UChar:
+            case BuiltinType::WChar_U:
+            case BuiltinType::UShort:
+            case BuiltinType::UInt:
+            case BuiltinType::ULong:
+            case BuiltinType::ULongLong:
+            case BuiltinType::UInt128:       return lldb::eEncodingUint;
+                
+            case BuiltinType::Float:
+            case BuiltinType::Double:
+            case BuiltinType::LongDouble:    return lldb::eEncodingIEEE754;
+                
+            case BuiltinType::ObjCClass:
+            case BuiltinType::ObjCId:
+            case BuiltinType::ObjCSel:       return lldb::eEncodingUint;
+                
+            case BuiltinType::NullPtr:       return lldb::eEncodingUint;
         }
-        break;
-    // All pointer types are represented as unsigned integer encodings.
-    // We may nee to add a eEncodingPointer if we ever need to know the
-    // difference
-    case clang::Type::ObjCObjectPointer:
-    case clang::Type::BlockPointer:
-    case clang::Type::Pointer:
-    case clang::Type::LValueReference:
-    case clang::Type::RValueReference:
-    case clang::Type::MemberPointer:            return lldb::eEncodingUint;
-    case clang::Type::Complex:
+            break;
+            // All pointer types are represented as unsigned integer encodings.
+            // We may nee to add a eEncodingPointer if we ever need to know the
+            // difference
+        case clang::Type::ObjCObjectPointer:
+        case clang::Type::BlockPointer:
+        case clang::Type::Pointer:
+        case clang::Type::LValueReference:
+        case clang::Type::RValueReference:
+        case clang::Type::MemberPointer:            return lldb::eEncodingUint;
+        case clang::Type::Complex:
         {
             lldb::Encoding encoding = lldb::eEncodingIEEE754;
             if (qual_type->isComplexType())
                 encoding = lldb::eEncodingIEEE754;
             else
             {
-                const clang::ComplexType *complex_type = qual_type->getAsComplexIntegerType();
+                const ComplexType *complex_type = qual_type->getAsComplexIntegerType();
                 if (complex_type)
-                    encoding = GetEncoding (complex_type->getElementType().getAsOpaquePtr(), count);
-                else 
+                    encoding = ClangASTType(m_ast, complex_type->getElementType()).GetEncoding(count);
+                else
                     encoding = lldb::eEncodingSint;
             }
             count = 2;
             return encoding;
         }
-
-    case clang::Type::ObjCInterface:            break;
-    case clang::Type::Record:                   break;
-    case clang::Type::Enum:                     return lldb::eEncodingSint;
-    case clang::Type::Typedef:
-        return GetEncoding(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), count);
-
-    case clang::Type::Elaborated:
-        return ClangASTType::GetEncoding (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), count);
-
-    case clang::Type::Paren:
-        return ClangASTType::GetEncoding (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), count);
             
-    case clang::Type::DependentSizedArray:
-    case clang::Type::DependentSizedExtVector:
-    case clang::Type::UnresolvedUsing:
-    case clang::Type::Attributed:
-    case clang::Type::TemplateTypeParm:
-    case clang::Type::SubstTemplateTypeParm:
-    case clang::Type::SubstTemplateTypeParmPack:
-    case clang::Type::Auto:
-    case clang::Type::InjectedClassName:
-    case clang::Type::DependentName:
-    case clang::Type::DependentTemplateSpecialization:
-    case clang::Type::PackExpansion:
-    case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:            break;
+        case clang::Type::Record:                   break;
+        case clang::Type::Enum:                     return lldb::eEncodingSint;
+        case clang::Type::Typedef:
+            return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetEncoding(count);
             
-    case clang::Type::TypeOfExpr:
-    case clang::Type::TypeOf:
-    case clang::Type::Decltype:
-    case clang::Type::TemplateSpecialization:
-    case clang::Type::Atomic:
-        break;
-
+        case clang::Type::Elaborated:
+            return ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetEncoding(count);
+            
+        case clang::Type::Paren:
+            return ClangASTType(m_ast, cast<ParenType>(qual_type)->desugar()).GetEncoding(count);
+            
+        case clang::Type::DependentSizedArray:
+        case clang::Type::DependentSizedExtVector:
+        case clang::Type::UnresolvedUsing:
+        case clang::Type::Attributed:
+        case clang::Type::TemplateTypeParm:
+        case clang::Type::SubstTemplateTypeParm:
+        case clang::Type::SubstTemplateTypeParmPack:
+        case clang::Type::Auto:
+        case clang::Type::InjectedClassName:
+        case clang::Type::DependentName:
+        case clang::Type::DependentTemplateSpecialization:
+        case clang::Type::PackExpansion:
+        case clang::Type::ObjCObject:
+            
+        case clang::Type::TypeOfExpr:
+        case clang::Type::TypeOf:
+        case clang::Type::Decltype:
+        case clang::Type::TemplateSpecialization:
+        case clang::Type::Atomic:
+            break;
+            
     }
     count = 0;
     return lldb::eEncodingInvalid;
 }
 
 lldb::Format
-ClangASTType::GetFormat ()
+ClangASTType::GetFormat () const
 {
-    return GetFormat (m_type);
-}
-
-lldb::Format
-ClangASTType::GetFormat (clang_type_t clang_type)
-{
-    if (clang_type == NULL)
+    if (!IsValid())
         return lldb::eFormatDefault;
-        
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-
+    
+    QualType qual_type(GetCanonicalQualType());
+    
     switch (qual_type->getTypeClass())
     {
-    case clang::Type::UnaryTransform:
-        break;
-        
-    case clang::Type::FunctionNoProto:
-    case clang::Type::FunctionProto:
-        break;
-
-    case clang::Type::IncompleteArray:
-    case clang::Type::VariableArray:
-        break;
-
-    case clang::Type::ConstantArray:
-        return lldb::eFormatVoid; // no value
-
-    case clang::Type::ExtVector:
-    case clang::Type::Vector:
-        break;
-
-    case clang::Type::Builtin:
-        switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
-        {
-        //default: assert(0 && "Unknown builtin type!");
-        case clang::BuiltinType::UnknownAny:
-        case clang::BuiltinType::Void:
-        case clang::BuiltinType::BoundMember:
+        case clang::Type::UnaryTransform:
             break;
-
-        case clang::BuiltinType::Bool:          return lldb::eFormatBoolean;
-        case clang::BuiltinType::Char_S:
-        case clang::BuiltinType::SChar:
-        case clang::BuiltinType::WChar_S:
-        case clang::BuiltinType::Char_U:
-        case clang::BuiltinType::UChar:
-        case clang::BuiltinType::WChar_U:       return lldb::eFormatChar;
-        case clang::BuiltinType::Char16:        return lldb::eFormatUnicode16;
-        case clang::BuiltinType::Char32:        return lldb::eFormatUnicode32;
-        case clang::BuiltinType::UShort:        return lldb::eFormatUnsigned;
-        case clang::BuiltinType::Short:         return lldb::eFormatDecimal;
-        case clang::BuiltinType::UInt:          return lldb::eFormatUnsigned;
-        case clang::BuiltinType::Int:           return lldb::eFormatDecimal;
-        case clang::BuiltinType::ULong:         return lldb::eFormatUnsigned;
-        case clang::BuiltinType::Long:          return lldb::eFormatDecimal;
-        case clang::BuiltinType::ULongLong:     return lldb::eFormatUnsigned;
-        case clang::BuiltinType::LongLong:      return lldb::eFormatDecimal;
-        case clang::BuiltinType::UInt128:       return lldb::eFormatUnsigned;
-        case clang::BuiltinType::Int128:        return lldb::eFormatDecimal;
-        case clang::BuiltinType::Float:         return lldb::eFormatFloat;
-        case clang::BuiltinType::Double:        return lldb::eFormatFloat;
-        case clang::BuiltinType::LongDouble:    return lldb::eFormatFloat;
-        case clang::BuiltinType::NullPtr:       
-        case clang::BuiltinType::Overload:
-        case clang::BuiltinType::Dependent:
-        case clang::BuiltinType::ObjCId:
-        case clang::BuiltinType::ObjCClass:
-        case clang::BuiltinType::ObjCSel:       
-        case clang::BuiltinType::Half:          
-        case clang::BuiltinType::ARCUnbridgedCast:          
-        case clang::BuiltinType::PseudoObject:
-        case clang::BuiltinType::BuiltinFn:
-        case clang::BuiltinType::OCLEvent:
-        case clang::BuiltinType::OCLImage1d:
-        case clang::BuiltinType::OCLImage1dArray:
-        case clang::BuiltinType::OCLImage1dBuffer:
-        case clang::BuiltinType::OCLImage2d:
-        case clang::BuiltinType::OCLImage2dArray:
-        case clang::BuiltinType::OCLImage3d:
-        case clang::BuiltinType::OCLSampler:
-            return lldb::eFormatHex;
+            
+        case clang::Type::FunctionNoProto:
+        case clang::Type::FunctionProto:
+            break;
+            
+        case clang::Type::IncompleteArray:
+        case clang::Type::VariableArray:
+            break;
+            
+        case clang::Type::ConstantArray:
+            return lldb::eFormatVoid; // no value
+            
+        case clang::Type::ExtVector:
+        case clang::Type::Vector:
+            break;
+            
+        case clang::Type::Builtin:
+            switch (cast<BuiltinType>(qual_type)->getKind())
+        {
+                //default: assert(0 && "Unknown builtin type!");
+            case BuiltinType::UnknownAny:
+            case BuiltinType::Void:
+            case BuiltinType::BoundMember:
+                break;
+                
+            case BuiltinType::Bool:          return lldb::eFormatBoolean;
+            case BuiltinType::Char_S:
+            case BuiltinType::SChar:
+            case BuiltinType::WChar_S:
+            case BuiltinType::Char_U:
+            case BuiltinType::UChar:
+            case BuiltinType::WChar_U:       return lldb::eFormatChar;
+            case BuiltinType::Char16:        return lldb::eFormatUnicode16;
+            case BuiltinType::Char32:        return lldb::eFormatUnicode32;
+            case BuiltinType::UShort:        return lldb::eFormatUnsigned;
+            case BuiltinType::Short:         return lldb::eFormatDecimal;
+            case BuiltinType::UInt:          return lldb::eFormatUnsigned;
+            case BuiltinType::Int:           return lldb::eFormatDecimal;
+            case BuiltinType::ULong:         return lldb::eFormatUnsigned;
+            case BuiltinType::Long:          return lldb::eFormatDecimal;
+            case BuiltinType::ULongLong:     return lldb::eFormatUnsigned;
+            case BuiltinType::LongLong:      return lldb::eFormatDecimal;
+            case BuiltinType::UInt128:       return lldb::eFormatUnsigned;
+            case BuiltinType::Int128:        return lldb::eFormatDecimal;
+            case BuiltinType::Float:         return lldb::eFormatFloat;
+            case BuiltinType::Double:        return lldb::eFormatFloat;
+            case BuiltinType::LongDouble:    return lldb::eFormatFloat;
+            case BuiltinType::NullPtr:
+            case BuiltinType::Overload:
+            case BuiltinType::Dependent:
+            case BuiltinType::ObjCId:
+            case BuiltinType::ObjCClass:
+            case BuiltinType::ObjCSel:
+            case BuiltinType::Half:
+            case BuiltinType::ARCUnbridgedCast:
+            case BuiltinType::PseudoObject:
+            case BuiltinType::BuiltinFn:
+            case BuiltinType::OCLEvent:
+            case BuiltinType::OCLImage1d:
+            case BuiltinType::OCLImage1dArray:
+            case BuiltinType::OCLImage1dBuffer:
+            case BuiltinType::OCLImage2d:
+            case BuiltinType::OCLImage2dArray:
+            case BuiltinType::OCLImage3d:
+            case BuiltinType::OCLSampler:
+                return lldb::eFormatHex;
         }
-        break;
-    case clang::Type::ObjCObjectPointer:        return lldb::eFormatHex;
-    case clang::Type::BlockPointer:             return lldb::eFormatHex;
-    case clang::Type::Pointer:                  return lldb::eFormatHex;
-    case clang::Type::LValueReference:
-    case clang::Type::RValueReference:          return lldb::eFormatHex;
-    case clang::Type::MemberPointer:            break;
-    case clang::Type::Complex:
+            break;
+        case clang::Type::ObjCObjectPointer:        return lldb::eFormatHex;
+        case clang::Type::BlockPointer:             return lldb::eFormatHex;
+        case clang::Type::Pointer:                  return lldb::eFormatHex;
+        case clang::Type::LValueReference:
+        case clang::Type::RValueReference:          return lldb::eFormatHex;
+        case clang::Type::MemberPointer:            break;
+        case clang::Type::Complex:
         {
             if (qual_type->isComplexType())
                 return lldb::eFormatComplex;
             else
                 return lldb::eFormatComplexInteger;
         }
-    case clang::Type::ObjCInterface:            break;
-    case clang::Type::Record:                   break;
-    case clang::Type::Enum:                     return lldb::eFormatEnum;
-    case clang::Type::Typedef:
-        return ClangASTType::GetFormat(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-    case clang::Type::Auto:
-        return ClangASTType::GetFormat(llvm::cast<clang::AutoType>(qual_type)->desugar().getAsOpaquePtr());
-    case clang::Type::Paren:
-        return ClangASTType::GetFormat(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-    case clang::Type::Elaborated:
-        return ClangASTType::GetFormat(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-    case clang::Type::DependentSizedArray:
-    case clang::Type::DependentSizedExtVector:
-    case clang::Type::UnresolvedUsing:
-    case clang::Type::Attributed:
-    case clang::Type::TemplateTypeParm:
-    case clang::Type::SubstTemplateTypeParm:
-    case clang::Type::SubstTemplateTypeParmPack:
-    case clang::Type::InjectedClassName:
-    case clang::Type::DependentName:
-    case clang::Type::DependentTemplateSpecialization:
-    case clang::Type::PackExpansion:
-    case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:            break;
+        case clang::Type::Record:                   break;
+        case clang::Type::Enum:                     return lldb::eFormatEnum;
+        case clang::Type::Typedef:
+            return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetFormat();
+        case clang::Type::Auto:
+            return ClangASTType (m_ast, cast<AutoType>(qual_type)->desugar()).GetFormat();
+        case clang::Type::Paren:
+            return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetFormat();
+        case clang::Type::Elaborated:
+            return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetFormat();
+        case clang::Type::DependentSizedArray:
+        case clang::Type::DependentSizedExtVector:
+        case clang::Type::UnresolvedUsing:
+        case clang::Type::Attributed:
+        case clang::Type::TemplateTypeParm:
+        case clang::Type::SubstTemplateTypeParm:
+        case clang::Type::SubstTemplateTypeParmPack:
+        case clang::Type::InjectedClassName:
+        case clang::Type::DependentName:
+        case clang::Type::DependentTemplateSpecialization:
+        case clang::Type::PackExpansion:
+        case clang::Type::ObjCObject:
             
-    case clang::Type::TypeOfExpr:
-    case clang::Type::TypeOf:
-    case clang::Type::Decltype:
-    case clang::Type::TemplateSpecialization:
-    case clang::Type::Atomic:
+        case clang::Type::TypeOfExpr:
+        case clang::Type::TypeOf:
+        case clang::Type::Decltype:
+        case clang::Type::TemplateSpecialization:
+        case clang::Type::Atomic:
             break;
     }
     // We don't know hot to display this type...
     return lldb::eFormatBytes;
 }
 
+static bool
+ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
+{
+    while (class_interface_decl)
+    {
+        if (class_interface_decl->ivar_size() > 0)
+            return true;
+        
+        if (check_superclass)
+            class_interface_decl = class_interface_decl->getSuperClass();
+        else
+            break;
+    }
+    return false;
+}
+
+uint32_t
+ClangASTType::GetNumChildren (bool omit_empty_base_classes) const
+{
+    if (!IsValid())
+        return 0;
+    
+    uint32_t num_children = 0;
+    QualType qual_type(GetQualType());
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Builtin:
+            switch (cast<BuiltinType>(qual_type)->getKind())
+        {
+            case BuiltinType::ObjCId:    // child is Class
+            case BuiltinType::ObjCClass: // child is Class
+                num_children = 1;
+                break;
+                
+            default:
+                break;
+        }
+            break;
+            
+        case clang::Type::Complex: return 0;
+            
+        case clang::Type::Record:
+            if (GetCompleteQualType (m_ast, qual_type))
+            {
+                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+                const RecordDecl *record_decl = record_type->getDecl();
+                assert(record_decl);
+                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+                if (cxx_record_decl)
+                {
+                    if (omit_empty_base_classes)
+                    {
+                        // Check each base classes to see if it or any of its
+                        // base classes contain any fields. This can help
+                        // limit the noise in variable views by not having to
+                        // show base classes that contain no members.
+                        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+                        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+                             base_class != base_class_end;
+                             ++base_class)
+                        {
+                            const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+                            
+                            // Skip empty base classes
+                            if (ClangASTContext::RecordHasFields(base_class_decl) == false)
+                                continue;
+                            
+                            num_children++;
+                        }
+                    }
+                    else
+                    {
+                        // Include all base classes
+                        num_children += cxx_record_decl->getNumBases();
+                    }
+                    
+                }
+                RecordDecl::field_iterator field, field_end;
+                for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
+                    ++num_children;
+            }
+            break;
+            
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (GetCompleteQualType (m_ast, qual_type))
+            {
+                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+                assert (objc_class_type);
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    
+                    if (class_interface_decl)
+                    {
+                        
+                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                        if (superclass_interface_decl)
+                        {
+                            if (omit_empty_base_classes)
+                            {
+                                if (ObjCDeclHasIVars (superclass_interface_decl, true))
+                                    ++num_children;
+                            }
+                            else
+                                ++num_children;
+                        }
+                        
+                        num_children += class_interface_decl->ivar_size();
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+        {
+            const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
+            QualType pointee_type = pointer_type->getPointeeType();
+            uint32_t num_pointee_children = ClangASTType (m_ast,pointee_type).GetNumChildren (omit_empty_base_classes);
+            // If this type points to a simple type, then it has 1 child
+            if (num_pointee_children == 0)
+                num_children = 1;
+            else
+                num_children = num_pointee_children;
+        }
+            break;
+            
+        case clang::Type::Vector:
+        case clang::Type::ExtVector:
+            num_children = cast<VectorType>(qual_type.getTypePtr())->getNumElements();
+            break;
+            
+        case clang::Type::ConstantArray:
+            num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
+            break;
+            
+        case clang::Type::Pointer:
+        {
+            const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
+            QualType pointee_type (pointer_type->getPointeeType());
+            uint32_t num_pointee_children = ClangASTType (m_ast,pointee_type).GetNumChildren (omit_empty_base_classes);
+            if (num_pointee_children == 0)
+            {
+                // We have a pointer to a pointee type that claims it has no children.
+                // We will want to look at
+                num_children = ClangASTType (m_ast, pointee_type).GetNumPointeeChildren();
+            }
+            else
+                num_children = num_pointee_children;
+        }
+            break;
+            
+        case clang::Type::LValueReference:
+        case clang::Type::RValueReference:
+        {
+            const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+            QualType pointee_type = reference_type->getPointeeType();
+            uint32_t num_pointee_children = ClangASTType (m_ast, pointee_type).GetNumChildren (omit_empty_base_classes);
+            // If this type points to a simple type, then it has 1 child
+            if (num_pointee_children == 0)
+                num_children = 1;
+            else
+                num_children = num_pointee_children;
+        }
+            break;
+            
+            
+        case clang::Type::Typedef:
+            num_children = ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumChildren (omit_empty_base_classes);
+            break;
+            
+        case clang::Type::Elaborated:
+            num_children = ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumChildren (omit_empty_base_classes);
+            break;
+            
+        case clang::Type::Paren:
+            num_children = ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetNumChildren (omit_empty_base_classes);
+            break;
+        default:
+            break;
+    }
+    return num_children;
+}
+
+lldb::BasicType
+ClangASTType::GetBasicTypeEnumeration () const
+{
+    if (IsValid())
+    {
+        QualType qual_type(GetQualType());
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        if (type_class == clang::Type::Builtin)
+        {
+            switch (cast<clang::BuiltinType>(qual_type)->getKind())
+            {
+                case clang::BuiltinType::Void:      return eBasicTypeVoid;
+                case clang::BuiltinType::Bool:      return eBasicTypeBool;
+                case clang::BuiltinType::Char_S:    return eBasicTypeSignedChar;
+                case clang::BuiltinType::Char_U:    return eBasicTypeUnsignedChar;
+                case clang::BuiltinType::Char16:    return eBasicTypeChar16;
+                case clang::BuiltinType::Char32:    return eBasicTypeChar32;
+                case clang::BuiltinType::UChar:     return eBasicTypeUnsignedChar;
+                case clang::BuiltinType::SChar:     return eBasicTypeSignedChar;
+                case clang::BuiltinType::WChar_S:   return eBasicTypeSignedWChar;
+                case clang::BuiltinType::WChar_U:   return eBasicTypeUnsignedWChar;
+                case clang::BuiltinType::Short:     return eBasicTypeShort;
+                case clang::BuiltinType::UShort:    return eBasicTypeUnsignedShort;
+                case clang::BuiltinType::Int:       return eBasicTypeInt;
+                case clang::BuiltinType::UInt:      return eBasicTypeUnsignedInt;
+                case clang::BuiltinType::Long:      return eBasicTypeLong;
+                case clang::BuiltinType::ULong:     return eBasicTypeUnsignedLong;
+                case clang::BuiltinType::LongLong:  return eBasicTypeLongLong;
+                case clang::BuiltinType::ULongLong: return eBasicTypeUnsignedLongLong;
+                case clang::BuiltinType::Int128:    return eBasicTypeInt128;
+                case clang::BuiltinType::UInt128:   return eBasicTypeUnsignedInt128;
+                    
+                case clang::BuiltinType::Half:      return eBasicTypeHalf;
+                case clang::BuiltinType::Float:     return eBasicTypeFloat;
+                case clang::BuiltinType::Double:    return eBasicTypeDouble;
+                case clang::BuiltinType::LongDouble:return eBasicTypeLongDouble;
+                    
+                case clang::BuiltinType::NullPtr:   return eBasicTypeNullPtr;
+                case clang::BuiltinType::ObjCId:    return eBasicTypeObjCID;
+                case clang::BuiltinType::ObjCClass: return eBasicTypeObjCClass;
+                case clang::BuiltinType::ObjCSel:   return eBasicTypeObjCSel;
+                case clang::BuiltinType::Dependent:
+                case clang::BuiltinType::Overload:
+                case clang::BuiltinType::BoundMember:
+                case clang::BuiltinType::PseudoObject:
+                case clang::BuiltinType::UnknownAny:
+                case clang::BuiltinType::BuiltinFn:
+                case clang::BuiltinType::ARCUnbridgedCast:
+                case clang::BuiltinType::OCLEvent:
+                case clang::BuiltinType::OCLImage1d:
+                case clang::BuiltinType::OCLImage1dArray:
+                case clang::BuiltinType::OCLImage1dBuffer:
+                case clang::BuiltinType::OCLImage2d:
+                case clang::BuiltinType::OCLImage2dArray:
+                case clang::BuiltinType::OCLImage3d:
+                case clang::BuiltinType::OCLSampler:
+                    return eBasicTypeOther;
+            }
+        }
+    }
+    return eBasicTypeInvalid;
+}
+
+
+#pragma mark Aggregate Types
+
+uint32_t
+ClangASTType::GetNumDirectBaseClasses () const
+{
+    if (!IsValid())
+        return 0;
+    
+    uint32_t count = 0;
+    QualType qual_type(GetCanonicalQualType());
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteType())
+            {
+                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                    count = cxx_record_decl->getNumBases();
+            }
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            if (GetCompleteType())
+            {
+                const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+                    if (class_interface_decl && class_interface_decl->getSuperClass())
+                        count = 1;
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (GetCompleteType())
+            {
+                const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    
+                    if (class_interface_decl && class_interface_decl->getSuperClass())
+                        count = 1;
+                }
+            }
+            break;
+            
+            
+        case clang::Type::Typedef:
+            count = ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumDirectBaseClasses ();
+            break;
+            
+        case clang::Type::Elaborated:
+            count = ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumDirectBaseClasses ();
+            break;
+            
+        case clang::Type::Paren:
+            return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetNumDirectBaseClasses ();
+            
+        default:
+            break;
+    }
+    return count;
+}
+
+uint32_t
+ClangASTType::GetNumVirtualBaseClasses () const
+{
+    if (!IsValid())
+        return 0;
+    
+    uint32_t count = 0;
+    QualType qual_type(GetCanonicalQualType());
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteType())
+            {
+                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                    count = cxx_record_decl->getNumVBases();
+            }
+            break;
+            
+        case clang::Type::Typedef:
+            count = ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumVirtualBaseClasses();
+            break;
+            
+        case clang::Type::Elaborated:
+            count = ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumVirtualBaseClasses();
+            break;
+            
+        case clang::Type::Paren:
+            count = ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetNumVirtualBaseClasses();
+            break;
+            
+        default:
+            break;
+    }
+    return count;
+}
+
+uint32_t
+ClangASTType::GetNumFields () const
+{
+    if (!IsValid())
+        return 0;
+    
+    uint32_t count = 0;
+    QualType qual_type(GetCanonicalQualType());
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteType())
+            {
+                const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
+                if (record_type)
+                {
+                    RecordDecl *record_decl = record_type->getDecl();
+                    if (record_decl)
+                    {
+                        uint32_t field_idx = 0;
+                        RecordDecl::field_iterator field, field_end;
+                        for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
+                            ++field_idx;
+                        count = field_idx;
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::Typedef:
+            count = ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumFields();
+            break;
+            
+        case clang::Type::Elaborated:
+            count = ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumFields();
+            break;
+            
+        case clang::Type::Paren:
+            count = ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetNumFields();
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            if (GetCompleteType())
+            {
+                const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+                    
+                    if (class_interface_decl)
+                        count = class_interface_decl->ivar_size();
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (GetCompleteType())
+            {
+                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    
+                    if (class_interface_decl)
+                        count = class_interface_decl->ivar_size();
+                }
+            }
+            break;
+            
+        default:
+            break;
+    }
+    return count;
+}
+
+ClangASTType
+ClangASTType::GetDirectBaseClassAtIndex (size_t idx, uint32_t *bit_offset_ptr) const
+{
+    if (!IsValid())
+        return ClangASTType();
+    
+    QualType qual_type(GetCanonicalQualType());
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteType())
+            {
+                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                {
+                    uint32_t curr_idx = 0;
+                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+                         base_class != base_class_end;
+                         ++base_class, ++curr_idx)
+                    {
+                        if (curr_idx == idx)
+                        {
+                            if (bit_offset_ptr)
+                            {
+                                const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(cxx_record_decl);
+                                const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+                                if (base_class->isVirtual())
+                                    *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+                                else
+                                    *bit_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
+                            }
+                            return ClangASTType (m_ast, base_class->getType());
+                        }
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            if (idx == 0 && GetCompleteType())
+            {
+                const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+                    if (class_interface_decl)
+                    {
+                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                        if (superclass_interface_decl)
+                        {
+                            if (bit_offset_ptr)
+                                *bit_offset_ptr = 0;
+                            return ClangASTType (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
+                        }
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (idx == 0 && GetCompleteType())
+            {
+                const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    
+                    if (class_interface_decl)
+                    {
+                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                        if (superclass_interface_decl)
+                        {
+                            if (bit_offset_ptr)
+                                *bit_offset_ptr = 0;
+                            return ClangASTType (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
+                        }
+                    }
+                }
+            }
+            break;
+            
+            
+        case clang::Type::Typedef:
+            return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr);
+            
+        case clang::Type::Elaborated:
+            return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr);
+            
+        case clang::Type::Paren:
+            return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr);
+            
+        default:
+            break;
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetVirtualBaseClassAtIndex (size_t idx, uint32_t *bit_offset_ptr) const
+{
+    if (!IsValid())
+        return ClangASTType();
+    
+    QualType qual_type(GetCanonicalQualType());
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteType())
+            {
+                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                {
+                    uint32_t curr_idx = 0;
+                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+                    for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end();
+                         base_class != base_class_end;
+                         ++base_class, ++curr_idx)
+                    {
+                        if (curr_idx == idx)
+                        {
+                            if (bit_offset_ptr)
+                            {
+                                const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(cxx_record_decl);
+                                const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+                                *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+                                
+                            }
+                            return ClangASTType (m_ast, base_class->getType());
+                        }
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::Typedef:
+            return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr);
+            
+        case clang::Type::Elaborated:
+            return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr);
+            
+        case clang::Type::Paren:
+            return  ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr);
+            
+        default:
+            break;
+    }
+    return ClangASTType();
+}
+
+static clang_type_t
+GetObjCFieldAtIndex (clang::ASTContext *ast,
+                     ObjCInterfaceDecl *class_interface_decl,
+                     size_t idx,
+                     std::string& name,
+                     uint64_t *bit_offset_ptr,
+                     uint32_t *bitfield_bit_size_ptr,
+                     bool *is_bitfield_ptr)
+{
+    if (class_interface_decl)
+    {
+        if (idx < (class_interface_decl->ivar_size()))
+        {
+            ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+            uint32_t ivar_idx = 0;
+            
+            for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx)
+            {
+                if (ivar_idx == idx)
+                {
+                    const ObjCIvarDecl* ivar_decl = *ivar_pos;
+                    
+                    QualType ivar_qual_type(ivar_decl->getType());
+                    
+                    name.assign(ivar_decl->getNameAsString());
+                    
+                    if (bit_offset_ptr)
+                    {
+                        const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
+                        *bit_offset_ptr = interface_layout.getFieldOffset (ivar_idx);
+                    }
+                    
+                    const bool is_bitfield = ivar_pos->isBitField();
+                    
+                    if (bitfield_bit_size_ptr)
+                    {
+                        *bitfield_bit_size_ptr = 0;
+                        
+                        if (is_bitfield && ast)
+                        {
+                            Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
+                            llvm::APSInt bitfield_apsint;
+                            if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast))
+                            {
+                                *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+                            }
+                        }
+                    }
+                    if (is_bitfield_ptr)
+                        *is_bitfield_ptr = is_bitfield;
+                    
+                    return ivar_qual_type.getAsOpaquePtr();
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+ClangASTType
+ClangASTType::GetFieldAtIndex (size_t idx,
+                               std::string& name,
+                               uint64_t *bit_offset_ptr,
+                               uint32_t *bitfield_bit_size_ptr,
+                               bool *is_bitfield_ptr) const
+{
+    if (!IsValid())
+        return ClangASTType();
+    
+    QualType qual_type(GetCanonicalQualType());
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteType())
+            {
+                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+                const RecordDecl *record_decl = record_type->getDecl();
+                uint32_t field_idx = 0;
+                RecordDecl::field_iterator field, field_end;
+                for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx)
+                {
+                    if (idx == field_idx)
+                    {
+                        // Print the member type if requested
+                        // Print the member name and equal sign
+                        name.assign(field->getNameAsString());
+                        
+                        // Figure out the type byte size (field_type_info.first) and
+                        // alignment (field_type_info.second) from the AST context.
+                        if (bit_offset_ptr)
+                        {
+                            const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(record_decl);
+                            *bit_offset_ptr = record_layout.getFieldOffset (field_idx);
+                        }
+                        
+                        const bool is_bitfield = field->isBitField();
+                        
+                        if (bitfield_bit_size_ptr)
+                        {
+                            *bitfield_bit_size_ptr = 0;
+                            
+                            if (is_bitfield)
+                            {
+                                Expr *bitfield_bit_size_expr = field->getBitWidth();
+                                llvm::APSInt bitfield_apsint;
+                                if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *m_ast))
+                                {
+                                    *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+                                }
+                            }
+                        }
+                        if (is_bitfield_ptr)
+                            *is_bitfield_ptr = is_bitfield;
+                        
+                        return ClangASTType (m_ast, field->getType());
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            if (GetCompleteType())
+            {
+                const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+                    return ClangASTType (m_ast, GetObjCFieldAtIndex(m_ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr));
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (GetCompleteType())
+            {
+                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+                assert (objc_class_type);
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    return ClangASTType (m_ast, GetObjCFieldAtIndex(m_ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr));
+                }
+            }
+            break;
+            
+            
+        case clang::Type::Typedef:
+            return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).
+                        GetFieldAtIndex (idx,
+                                         name,
+                                         bit_offset_ptr,
+                                         bitfield_bit_size_ptr,
+                                         is_bitfield_ptr);
+            
+        case clang::Type::Elaborated:
+            return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).
+                        GetFieldAtIndex (idx,
+                                         name,
+                                         bit_offset_ptr,
+                                         bitfield_bit_size_ptr,
+                                         is_bitfield_ptr);
+            
+        case clang::Type::Paren:
+            return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).
+                        GetFieldAtIndex (idx,
+                                         name,
+                                         bit_offset_ptr,
+                                         bitfield_bit_size_ptr,
+                                         is_bitfield_ptr);
+            
+        default:
+            break;
+    }
+    return ClangASTType();
+}
+
+uint32_t
+ClangASTType::GetIndexOfFieldWithName (const char* name,
+                                       ClangASTType* field_clang_type_ptr,
+                                       uint64_t *bit_offset_ptr,
+                                       uint32_t *bitfield_bit_size_ptr,
+                                       bool *is_bitfield_ptr) const
+{
+    unsigned count = GetNumFields();
+    std::string field_name;
+    for (unsigned index = 0; index < count; index++)
+    {
+        ClangASTType field_clang_type (GetFieldAtIndex(index, field_name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr));
+        if (strcmp(field_name.c_str(), name) == 0)
+        {
+            if (field_clang_type_ptr)
+                *field_clang_type_ptr = field_clang_type;
+            return index;
+        }
+    }
+    return UINT32_MAX;
+}
+
+// If a pointer to a pointee type (the clang_type arg) says that it has no
+// children, then we either need to trust it, or override it and return a
+// different result. For example, an "int *" has one child that is an integer,
+// but a function pointer doesn't have any children. Likewise if a Record type
+// claims it has no children, then there really is nothing to show.
+uint32_t
+ClangASTType::GetNumPointeeChildren () const
+{
+    if (!IsValid())
+        return 0;
+    
+    QualType qual_type(GetCanonicalQualType());
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Builtin:
+            switch (cast<clang::BuiltinType>(qual_type)->getKind())
+        {
+            case clang::BuiltinType::UnknownAny:
+            case clang::BuiltinType::Void:
+            case clang::BuiltinType::NullPtr:
+            case clang::BuiltinType::OCLEvent:
+            case clang::BuiltinType::OCLImage1d:
+            case clang::BuiltinType::OCLImage1dArray:
+            case clang::BuiltinType::OCLImage1dBuffer:
+            case clang::BuiltinType::OCLImage2d:
+            case clang::BuiltinType::OCLImage2dArray:
+            case clang::BuiltinType::OCLImage3d:
+            case clang::BuiltinType::OCLSampler:
+                return 0;
+            case clang::BuiltinType::Bool:
+            case clang::BuiltinType::Char_U:
+            case clang::BuiltinType::UChar:
+            case clang::BuiltinType::WChar_U:
+            case clang::BuiltinType::Char16:
+            case clang::BuiltinType::Char32:
+            case clang::BuiltinType::UShort:
+            case clang::BuiltinType::UInt:
+            case clang::BuiltinType::ULong:
+            case clang::BuiltinType::ULongLong:
+            case clang::BuiltinType::UInt128:
+            case clang::BuiltinType::Char_S:
+            case clang::BuiltinType::SChar:
+            case clang::BuiltinType::WChar_S:
+            case clang::BuiltinType::Short:
+            case clang::BuiltinType::Int:
+            case clang::BuiltinType::Long:
+            case clang::BuiltinType::LongLong:
+            case clang::BuiltinType::Int128:
+            case clang::BuiltinType::Float:
+            case clang::BuiltinType::Double:
+            case clang::BuiltinType::LongDouble:
+            case clang::BuiltinType::Dependent:
+            case clang::BuiltinType::Overload:
+            case clang::BuiltinType::ObjCId:
+            case clang::BuiltinType::ObjCClass:
+            case clang::BuiltinType::ObjCSel:
+            case clang::BuiltinType::BoundMember:
+            case clang::BuiltinType::Half:
+            case clang::BuiltinType::ARCUnbridgedCast:
+            case clang::BuiltinType::PseudoObject:
+            case clang::BuiltinType::BuiltinFn:
+                return 1;
+        }
+            break;
+            
+        case clang::Type::Complex:                  return 1;
+        case clang::Type::Pointer:                  return 1;
+        case clang::Type::BlockPointer:             return 0;   // If block pointers don't have debug info, then no children for them
+        case clang::Type::LValueReference:          return 1;
+        case clang::Type::RValueReference:          return 1;
+        case clang::Type::MemberPointer:            return 0;
+        case clang::Type::ConstantArray:            return 0;
+        case clang::Type::IncompleteArray:          return 0;
+        case clang::Type::VariableArray:            return 0;
+        case clang::Type::DependentSizedArray:      return 0;
+        case clang::Type::DependentSizedExtVector:  return 0;
+        case clang::Type::Vector:                   return 0;
+        case clang::Type::ExtVector:                return 0;
+        case clang::Type::FunctionProto:            return 0;   // When we function pointers, they have no children...
+        case clang::Type::FunctionNoProto:          return 0;   // When we function pointers, they have no children...
+        case clang::Type::UnresolvedUsing:          return 0;
+        case clang::Type::Paren:                    return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetNumPointeeChildren ();
+        case clang::Type::Typedef:                  return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumPointeeChildren ();
+        case clang::Type::Elaborated:               return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumPointeeChildren ();
+        case clang::Type::TypeOfExpr:               return 0;
+        case clang::Type::TypeOf:                   return 0;
+        case clang::Type::Decltype:                 return 0;
+        case clang::Type::Record:                   return 0;
+        case clang::Type::Enum:                     return 1;
+        case clang::Type::TemplateTypeParm:         return 1;
+        case clang::Type::SubstTemplateTypeParm:    return 1;
+        case clang::Type::TemplateSpecialization:   return 1;
+        case clang::Type::InjectedClassName:        return 0;
+        case clang::Type::DependentName:            return 1;
+        case clang::Type::DependentTemplateSpecialization:  return 1;
+        case clang::Type::ObjCObject:               return 0;
+        case clang::Type::ObjCInterface:            return 0;
+        case clang::Type::ObjCObjectPointer:        return 1;
+        default: 
+            break;
+    }
+    return 0;
+}
+
+
+ClangASTType
+ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
+                                        const char *parent_name,
+                                        size_t idx,
+                                        bool transparent_pointers,
+                                        bool omit_empty_base_classes,
+                                        bool ignore_array_bounds,
+                                        std::string& child_name,
+                                        uint32_t &child_byte_size,
+                                        int32_t &child_byte_offset,
+                                        uint32_t &child_bitfield_bit_size,
+                                        uint32_t &child_bitfield_bit_offset,
+                                        bool &child_is_base_class,
+                                        bool &child_is_deref_of_parent) const
+{
+    if (!IsValid())
+        return ClangASTType();
+    
+    QualType parent_qual_type(GetCanonicalQualType());
+    const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
+    child_bitfield_bit_size = 0;
+    child_bitfield_bit_offset = 0;
+    child_is_base_class = false;
+    
+    const bool idx_is_valid = idx < GetNumChildren (omit_empty_base_classes);
+    uint32_t bit_offset;
+    switch (parent_type_class)
+    {
+        case clang::Type::Builtin:
+            if (idx_is_valid)
+            {
+                switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
+                {
+                    case clang::BuiltinType::ObjCId:
+                    case clang::BuiltinType::ObjCClass:
+                        child_name = "isa";
+                        child_byte_size = m_ast->getTypeSize(m_ast->ObjCBuiltinClassTy) / CHAR_BIT;
+                        return ClangASTType (m_ast, m_ast->ObjCBuiltinClassTy);
+                        
+                    default:
+                        break;
+                }
+            }
+            break;
+            
+        case clang::Type::Record:
+            if (idx_is_valid && GetCompleteType())
+            {
+                const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
+                const RecordDecl *record_decl = record_type->getDecl();
+                assert(record_decl);
+                const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(record_decl);
+                uint32_t child_idx = 0;
+                
+                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+                if (cxx_record_decl)
+                {
+                    // We might have base classes to print out first
+                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+                         base_class != base_class_end;
+                         ++base_class)
+                    {
+                        const CXXRecordDecl *base_class_decl = NULL;
+                        
+                        // Skip empty base classes
+                        if (omit_empty_base_classes)
+                        {
+                            base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+                            if (ClangASTContext::RecordHasFields(base_class_decl) == false)
+                                continue;
+                        }
+                        
+                        if (idx == child_idx)
+                        {
+                            if (base_class_decl == NULL)
+                                base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+                            
+                            
+                            if (base_class->isVirtual())
+                                bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+                            else
+                                bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
+                            
+                            // Base classes should be a multiple of 8 bits in size
+                            child_byte_offset = bit_offset/8;
+                            ClangASTType base_class_clang_type(m_ast, base_class->getType());
+                            child_name = base_class_clang_type.GetTypeName();
+                            uint64_t base_class_clang_type_bit_size = base_class_clang_type.GetBitSize();
+                            
+                            // Base classes bit sizes should be a multiple of 8 bits in size
+                            assert (base_class_clang_type_bit_size % 8 == 0);
+                            child_byte_size = base_class_clang_type_bit_size / 8;
+                            child_is_base_class = true;
+                            return base_class_clang_type;
+                        }
+                        // We don't increment the child index in the for loop since we might
+                        // be skipping empty base classes
+                        ++child_idx;
+                    }
+                }
+                // Make sure index is in range...
+                uint32_t field_idx = 0;
+                RecordDecl::field_iterator field, field_end;
+                for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
+                {
+                    if (idx == child_idx)
+                    {
+                        // Print the member type if requested
+                        // Print the member name and equal sign
+                        child_name.assign(field->getNameAsString().c_str());
+                        
+                        // Figure out the type byte size (field_type_info.first) and
+                        // alignment (field_type_info.second) from the AST context.
+                        ClangASTType field_clang_type (m_ast, field->getType());
+                        assert(field_idx < record_layout.getFieldCount());
+                        child_byte_size = field_clang_type.GetByteSize();
+                        
+                        // Figure out the field offset within the current struct/union/class type
+                        bit_offset = record_layout.getFieldOffset (field_idx);
+                        child_byte_offset = bit_offset / 8;
+                        if (ClangASTContext::FieldIsBitfield (m_ast, *field, child_bitfield_bit_size))
+                            child_bitfield_bit_offset = bit_offset % 8;
+                        
+                        return field_clang_type;
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (idx_is_valid && GetCompleteType())
+            {
+                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
+                assert (objc_class_type);
+                if (objc_class_type)
+                {
+                    uint32_t child_idx = 0;
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    
+                    if (class_interface_decl)
+                    {
+                        
+                        const ASTRecordLayout &interface_layout = m_ast->getASTObjCInterfaceLayout(class_interface_decl);
+                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                        if (superclass_interface_decl)
+                        {
+                            if (omit_empty_base_classes)
+                            {
+                                ClangASTType base_class_clang_type (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
+                                if (base_class_clang_type.GetNumChildren(omit_empty_base_classes) > 0)
+                                {
+                                    if (idx == 0)
+                                    {
+                                        QualType ivar_qual_type(m_ast->getObjCInterfaceType(superclass_interface_decl));
+                                        
+                                        
+                                        child_name.assign(superclass_interface_decl->getNameAsString().c_str());
+                                        
+                                        std::pair<uint64_t, unsigned> ivar_type_info = m_ast->getTypeInfo(ivar_qual_type.getTypePtr());
+                                        
+                                        child_byte_size = ivar_type_info.first / 8;
+                                        child_byte_offset = 0;
+                                        child_is_base_class = true;
+                                        
+                                        return ClangASTType (m_ast, ivar_qual_type);
+                                    }
+                                    
+                                    ++child_idx;
+                                }
+                            }
+                            else
+                                ++child_idx;
+                        }
+                        
+                        const uint32_t superclass_idx = child_idx;
+                        
+                        if (idx < (child_idx + class_interface_decl->ivar_size()))
+                        {
+                            ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+                            
+                            for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
+                            {
+                                if (child_idx == idx)
+                                {
+                                    ObjCIvarDecl* ivar_decl = *ivar_pos;
+                                    
+                                    QualType ivar_qual_type(ivar_decl->getType());
+                                    
+                                    child_name.assign(ivar_decl->getNameAsString().c_str());
+                                    
+                                    std::pair<uint64_t, unsigned> ivar_type_info = m_ast->getTypeInfo(ivar_qual_type.getTypePtr());
+                                    
+                                    child_byte_size = ivar_type_info.first / 8;
+                                    
+                                    // Figure out the field offset within the current struct/union/class type
+                                    // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
+                                    // that doesn't account for the space taken up by unbacked properties, or from
+                                    // the changing size of base classes that are newer than this class.
+                                    // So if we have a process around that we can ask about this object, do so.
+                                    child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
+                                    Process *process = NULL;
+                                    if (exe_ctx)
+                                        process = exe_ctx->GetProcessPtr();
+                                    if (process)
+                                    {
+                                        ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
+                                        if (objc_runtime != NULL)
+                                        {
+                                            ClangASTType parent_ast_type (m_ast, parent_qual_type);
+                                            child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
+                                        }
+                                    }
+                                    
+                                    // Setting this to UINT32_MAX to make sure we don't compute it twice...
+                                    bit_offset = UINT32_MAX;
+                                    
+                                    if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
+                                    {
+                                        bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
+                                        child_byte_offset = bit_offset / 8;
+                                    }
+                                    
+                                    // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
+                                    // of a bitfield within its containing object.  So regardless of where we get the byte
+                                    // offset from, we still need to get the bit offset for bitfields from the layout.
+                                    
+                                    if (ClangASTContext::FieldIsBitfield (m_ast, ivar_decl, child_bitfield_bit_size))
+                                    {
+                                        if (bit_offset == UINT32_MAX)
+                                            bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
+                                        
+                                        child_bitfield_bit_offset = bit_offset % 8;
+                                    }
+                                    return ClangASTType (m_ast, ivar_qual_type);
+                                }
+                                ++child_idx;
+                            }
+                        }
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            if (idx_is_valid)
+            {
+                ClangASTType pointee_clang_type (GetPointeeType());
+                
+                if (transparent_pointers && pointee_clang_type.IsAggregateType())
+                {
+                    child_is_deref_of_parent = false;
+                    bool tmp_child_is_deref_of_parent = false;
+                    return pointee_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+                                                                        parent_name,
+                                                                        idx,
+                                                                        transparent_pointers,
+                                                                        omit_empty_base_classes,
+                                                                        ignore_array_bounds,
+                                                                        child_name,
+                                                                        child_byte_size,
+                                                                        child_byte_offset,
+                                                                        child_bitfield_bit_size,
+                                                                        child_bitfield_bit_offset,
+                                                                        child_is_base_class,
+                                                                        tmp_child_is_deref_of_parent);
+                }
+                else
+                {
+                    child_is_deref_of_parent = true;
+                    if (parent_name)
+                    {
+                        child_name.assign(1, '*');
+                        child_name += parent_name;
+                    }
+                    
+                    // We have a pointer to an simple type
+                    if (idx == 0 && pointee_clang_type.GetCompleteType())
+                    {
+                        child_byte_size = pointee_clang_type.GetByteSize();
+                        child_byte_offset = 0;
+                        return pointee_clang_type;
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::Vector:
+        case clang::Type::ExtVector:
+            if (idx_is_valid)
+            {
+                const VectorType *array = cast<VectorType>(parent_qual_type.getTypePtr());
+                if (array)
+                {
+                    ClangASTType element_type (m_ast, array->getElementType());
+                    if (element_type.GetCompleteType())
+                    {
+                        char element_name[64];
+                        ::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
+                        child_name.assign(element_name);
+                        child_byte_size = element_type.GetByteSize();
+                        child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+                        return element_type;
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ConstantArray:
+        case clang::Type::IncompleteArray:
+            if (ignore_array_bounds || idx_is_valid)
+            {
+                const ArrayType *array = cast<ArrayType>(parent_qual_type.getTypePtr());
+                if (array)
+                {
+                    ClangASTType element_type (m_ast, array->getElementType());
+                    if (element_type.GetCompleteType())
+                    {
+                        char element_name[64];
+                        ::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
+                        child_name.assign(element_name);
+                        child_byte_size = element_type.GetByteSize();
+                        child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+                        return element_type;
+                    }
+                }
+            }
+            break;
+            
+            
+        case clang::Type::Pointer:
+            if (idx_is_valid)
+            {
+                ClangASTType pointee_clang_type (GetPointeeType());
+                
+                // Don't dereference "void *" pointers
+                if (pointee_clang_type.IsVoidType())
+                    return ClangASTType();
+                
+                if (transparent_pointers && pointee_clang_type.IsAggregateType ())
+                {
+                    child_is_deref_of_parent = false;
+                    bool tmp_child_is_deref_of_parent = false;
+                    return pointee_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+                                                                        parent_name,
+                                                                        idx,
+                                                                        transparent_pointers,
+                                                                        omit_empty_base_classes,
+                                                                        ignore_array_bounds,
+                                                                        child_name,
+                                                                        child_byte_size,
+                                                                        child_byte_offset,
+                                                                        child_bitfield_bit_size,
+                                                                        child_bitfield_bit_offset,
+                                                                        child_is_base_class,
+                                                                        tmp_child_is_deref_of_parent);
+                }
+                else
+                {
+                    child_is_deref_of_parent = true;
+                    
+                    if (parent_name)
+                    {
+                        child_name.assign(1, '*');
+                        child_name += parent_name;
+                    }
+                    
+                    // We have a pointer to an simple type
+                    if (idx == 0)
+                    {
+                        child_byte_size = pointee_clang_type.GetByteSize();
+                        child_byte_offset = 0;
+                        return pointee_clang_type;
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::LValueReference:
+        case clang::Type::RValueReference:
+            if (idx_is_valid)
+            {
+                const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
+                ClangASTType pointee_clang_type (m_ast, reference_type->getPointeeType());
+                if (transparent_pointers && pointee_clang_type.IsAggregateType ())
+                {
+                    child_is_deref_of_parent = false;
+                    bool tmp_child_is_deref_of_parent = false;
+                    return pointee_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+                                                                        parent_name,
+                                                                        idx,
+                                                                        transparent_pointers,
+                                                                        omit_empty_base_classes,
+                                                                        ignore_array_bounds,
+                                                                        child_name,
+                                                                        child_byte_size,
+                                                                        child_byte_offset,
+                                                                        child_bitfield_bit_size,
+                                                                        child_bitfield_bit_offset,
+                                                                        child_is_base_class,
+                                                                        tmp_child_is_deref_of_parent);
+                }
+                else
+                {
+                    if (parent_name)
+                    {
+                        child_name.assign(1, '&');
+                        child_name += parent_name;
+                    }
+                    
+                    // We have a pointer to an simple type
+                    if (idx == 0)
+                    {
+                        child_byte_size = pointee_clang_type.GetByteSize();
+                        child_byte_offset = 0;
+                        return pointee_clang_type;
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::Typedef:
+            {
+                ClangASTType typedefed_clang_type (m_ast, cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType());
+                return typedefed_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+                                                                      parent_name,
+                                                                      idx,
+                                                                      transparent_pointers,
+                                                                      omit_empty_base_classes,
+                                                                      ignore_array_bounds,
+                                                                      child_name,
+                                                                      child_byte_size,
+                                                                      child_byte_offset,
+                                                                      child_bitfield_bit_size,
+                                                                      child_bitfield_bit_offset,
+                                                                      child_is_base_class,
+                                                                      child_is_deref_of_parent);
+            }
+            break;
+            
+        case clang::Type::Elaborated:
+            {
+                ClangASTType elaborated_clang_type (m_ast, cast<ElaboratedType>(parent_qual_type)->getNamedType());
+                return elaborated_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+                                                                       parent_name,
+                                                                       idx,
+                                                                       transparent_pointers,
+                                                                       omit_empty_base_classes,
+                                                                       ignore_array_bounds,
+                                                                       child_name,
+                                                                       child_byte_size,
+                                                                       child_byte_offset,
+                                                                       child_bitfield_bit_size,
+                                                                       child_bitfield_bit_offset,
+                                                                       child_is_base_class,
+                                                                       child_is_deref_of_parent);
+            }
+            
+        case clang::Type::Paren:
+            {
+                ClangASTType paren_clang_type (m_ast, llvm::cast<clang::ParenType>(parent_qual_type)->desugar());
+                return paren_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+                                                                  parent_name,
+                                                                  idx,
+                                                                  transparent_pointers,
+                                                                  omit_empty_base_classes,
+                                                                  ignore_array_bounds,
+                                                                  child_name,
+                                                                  child_byte_size,
+                                                                  child_byte_offset,
+                                                                  child_bitfield_bit_size,
+                                                                  child_bitfield_bit_offset,
+                                                                  child_is_base_class,
+                                                                  child_is_deref_of_parent);
+            }
+            
+            
+        default:
+            break;
+    }
+    return ClangASTType();
+}
+
+static inline bool
+BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
+{
+    return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
+}
+
+static uint32_t
+GetIndexForRecordBase
+(
+ const RecordDecl *record_decl,
+ const CXXBaseSpecifier *base_spec,
+ bool omit_empty_base_classes
+ )
+{
+    uint32_t child_idx = 0;
+    
+    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+    
+    //    const char *super_name = record_decl->getNameAsCString();
+    //    const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
+    //    printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
+    //
+    if (cxx_record_decl)
+    {
+        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+             base_class != base_class_end;
+             ++base_class)
+        {
+            if (omit_empty_base_classes)
+            {
+                if (BaseSpecifierIsEmpty (base_class))
+                    continue;
+            }
+            
+            //            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
+            //                    child_idx,
+            //                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
+            //
+            //
+            if (base_class == base_spec)
+                return child_idx;
+            ++child_idx;
+        }
+    }
+    
+    return UINT32_MAX;
+}
+
+
+static uint32_t
+GetIndexForRecordChild (const RecordDecl *record_decl,
+                        NamedDecl *canonical_decl,
+                        bool omit_empty_base_classes)
+{
+    uint32_t child_idx = ClangASTContext::GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl),
+                                                             omit_empty_base_classes);
+    
+    RecordDecl::field_iterator field, field_end;
+    for (field = record_decl->field_begin(), field_end = record_decl->field_end();
+         field != field_end;
+         ++field, ++child_idx)
+    {
+        if (field->getCanonicalDecl() == canonical_decl)
+            return child_idx;
+    }
+    
+    return UINT32_MAX;
+}
+
+// Look for a child member (doesn't include base classes, but it does include
+// their members) in the type hierarchy. Returns an index path into "clang_type"
+// on how to reach the appropriate member.
+//
+//    class A
+//    {
+//    public:
+//        int m_a;
+//        int m_b;
+//    };
+//
+//    class B
+//    {
+//    };
+//
+//    class C :
+//        public B,
+//        public A
+//    {
+//    };
+//
+// If we have a clang type that describes "class C", and we wanted to looked
+// "m_b" in it:
+//
+// With omit_empty_base_classes == false we would get an integer array back with:
+// { 1,  1 }
+// The first index 1 is the child index for "class A" within class C
+// The second index 1 is the child index for "m_b" within class A
+//
+// With omit_empty_base_classes == true we would get an integer array back with:
+// { 0,  1 }
+// The first index 0 is the child index for "class A" within class C (since class B doesn't have any members it doesn't count)
+// The second index 1 is the child index for "m_b" within class A
+
+size_t
+ClangASTType::GetIndexOfChildMemberWithName (const char *name,
+                                             bool omit_empty_base_classes,
+                                             std::vector<uint32_t>& child_indexes) const
+{
+    if (IsValid() && name && name[0])
+    {
+        QualType qual_type(GetCanonicalQualType());
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Record:
+                if (GetCompleteType ())
+                {
+                    const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+                    const RecordDecl *record_decl = record_type->getDecl();
+                    
+                    assert(record_decl);
+                    uint32_t child_idx = 0;
+                    
+                    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+                    
+                    // Try and find a field that matches NAME
+                    RecordDecl::field_iterator field, field_end;
+                    StringRef name_sref(name);
+                    for (field = record_decl->field_begin(), field_end = record_decl->field_end();
+                         field != field_end;
+                         ++field, ++child_idx)
+                    {
+                        if (field->getName().equals (name_sref))
+                        {
+                            // We have to add on the number of base classes to this index!
+                            child_indexes.push_back (child_idx + ClangASTContext::GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
+                            return child_indexes.size();
+                        }
+                    }
+                    
+                    if (cxx_record_decl)
+                    {
+                        const RecordDecl *parent_record_decl = cxx_record_decl;
+                        
+                        //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
+                        
+                        //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
+                        // Didn't find things easily, lets let clang do its thang...
+                        IdentifierInfo & ident_ref = m_ast->Idents.get(name_sref);
+                        DeclarationName decl_name(&ident_ref);
+                        
+                        CXXBasePaths paths;
+                        if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
+                                                           decl_name.getAsOpaquePtr(),
+                                                           paths))
+                        {
+                            CXXBasePaths::const_paths_iterator path, path_end = paths.end();
+                            for (path = paths.begin(); path != path_end; ++path)
+                            {
+                                const size_t num_path_elements = path->size();
+                                for (size_t e=0; e<num_path_elements; ++e)
+                                {
+                                    CXXBasePathElement elem = (*path)[e];
+                                    
+                                    child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
+                                    if (child_idx == UINT32_MAX)
+                                    {
+                                        child_indexes.clear();
+                                        return 0;
+                                    }
+                                    else
+                                    {
+                                        child_indexes.push_back (child_idx);
+                                        parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
+                                    }
+                                }
+                                for (NamedDecl *path_decl : path->Decls)
+                                {
+                                    child_idx = GetIndexForRecordChild (parent_record_decl, path_decl, omit_empty_base_classes);
+                                    if (child_idx == UINT32_MAX)
+                                    {
+                                        child_indexes.clear();
+                                        return 0;
+                                    }
+                                    else
+                                    {
+                                        child_indexes.push_back (child_idx);
+                                    }
+                                }
+                            }
+                            return child_indexes.size();
+                        }
+                    }
+                    
+                }
+                break;
+                
+            case clang::Type::ObjCObject:
+            case clang::Type::ObjCInterface:
+                if (GetCompleteType ())
+                {
+                    StringRef name_sref(name);
+                    const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+                    assert (objc_class_type);
+                    if (objc_class_type)
+                    {
+                        uint32_t child_idx = 0;
+                        ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                        
+                        if (class_interface_decl)
+                        {
+                            ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+                            ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                            
+                            for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
+                            {
+                                const ObjCIvarDecl* ivar_decl = *ivar_pos;
+                                
+                                if (ivar_decl->getName().equals (name_sref))
+                                {
+                                    if ((!omit_empty_base_classes && superclass_interface_decl) ||
+                                        ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
+                                        ++child_idx;
+                                    
+                                    child_indexes.push_back (child_idx);
+                                    return child_indexes.size();
+                                }
+                            }
+                            
+                            if (superclass_interface_decl)
+                            {
+                                // The super class index is always zero for ObjC classes,
+                                // so we push it onto the child indexes in case we find
+                                // an ivar in our superclass...
+                                child_indexes.push_back (0);
+                                
+                                ClangASTType superclass_clang_type (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
+                                if (superclass_clang_type.GetIndexOfChildMemberWithName (name,
+                                                                                         omit_empty_base_classes,
+                                                                                         child_indexes))
+                                {
+                                    // We did find an ivar in a superclass so just
+                                    // return the results!
+                                    return child_indexes.size();
+                                }
+                                
+                                // We didn't find an ivar matching "name" in our
+                                // superclass, pop the superclass zero index that
+                                // we pushed on above.
+                                child_indexes.pop_back();
+                            }
+                        }
+                    }
+                }
+                break;
+                
+            case clang::Type::ObjCObjectPointer:
+                {
+                    ClangASTType objc_object_clang_type (m_ast, cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
+                    return objc_object_clang_type.GetIndexOfChildMemberWithName (name,
+                                                                                 omit_empty_base_classes,
+                                                                                 child_indexes);
+                }
+                break;
+                
+                
+            case clang::Type::ConstantArray:
+            {
+                //                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
+                //                const uint64_t element_count = array->getSize().getLimitedValue();
+                //
+                //                if (idx < element_count)
+                //                {
+                //                    std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
+                //
+                //                    char element_name[32];
+                //                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
+                //
+                //                    child_name.assign(element_name);
+                //                    assert(field_type_info.first % 8 == 0);
+                //                    child_byte_size = field_type_info.first / 8;
+                //                    child_byte_offset = idx * child_byte_size;
+                //                    return array->getElementType().getAsOpaquePtr();
+                //                }
+            }
+                break;
+                
+                //        case clang::Type::MemberPointerType:
+                //            {
+                //                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
+                //                QualType pointee_type = mem_ptr_type->getPointeeType();
+                //
+                //                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+                //                {
+                //                    return GetIndexOfChildWithName (ast,
+                //                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
+                //                                                    name);
+                //                }
+                //            }
+                //            break;
+                //
+            case clang::Type::LValueReference:
+            case clang::Type::RValueReference:
+                {
+                    const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+                    QualType pointee_type(reference_type->getPointeeType());
+                    ClangASTType pointee_clang_type (m_ast, pointee_type);
+                    
+                    if (pointee_clang_type.IsAggregateType ())
+                    {
+                        return pointee_clang_type.GetIndexOfChildMemberWithName (name,
+                                                                                 omit_empty_base_classes,
+                                                                                 child_indexes);
+                    }
+                }
+                break;
+                
+            case clang::Type::Pointer:
+            {
+                ClangASTType pointee_clang_type (GetPointeeType());
+                
+                if (pointee_clang_type.IsAggregateType ())
+                {
+                    return pointee_clang_type.GetIndexOfChildMemberWithName (name,
+                                                                             omit_empty_base_classes,
+                                                                             child_indexes);
+                }
+            }
+                break;
+                
+            case clang::Type::Typedef:
+                return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildMemberWithName (name,
+                                                                                                                                         omit_empty_base_classes,
+                                                                                                                                         child_indexes);
+                
+            case clang::Type::Elaborated:
+                return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildMemberWithName (name,
+                                                                                                                            omit_empty_base_classes,
+                                                                                                                            child_indexes);
+                
+            case clang::Type::Paren:
+                return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildMemberWithName (name,
+                                                                                                                         omit_empty_base_classes,
+                                                                                                                         child_indexes);
+                
+            default:
+                break;
+        }
+    }
+    return 0;
+}
+
+
+// Get the index of the child of "clang_type" whose name matches. This function
+// doesn't descend into the children, but only looks one level deep and name
+// matches can include base class names.
+
+uint32_t
+ClangASTType::GetIndexOfChildWithName (const char *name, bool omit_empty_base_classes) const
+{
+    if (IsValid() && name && name[0])
+    {
+        QualType qual_type(GetCanonicalQualType());
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        
+        switch (type_class)
+        {
+            case clang::Type::Record:
+                if (GetCompleteType ())
+                {
+                    const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+                    const RecordDecl *record_decl = record_type->getDecl();
+                    
+                    assert(record_decl);
+                    uint32_t child_idx = 0;
+                    
+                    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+                    
+                    if (cxx_record_decl)
+                    {
+                        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+                        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+                             base_class != base_class_end;
+                             ++base_class)
+                        {
+                            // Skip empty base classes
+                            CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+                            if (omit_empty_base_classes && ClangASTContext::RecordHasFields(base_class_decl) == false)
+                                continue;
+                            
+                            ClangASTType base_class_clang_type (m_ast, base_class->getType());
+                            std::string base_class_type_name (base_class_clang_type.GetTypeName());
+                            if (base_class_type_name.compare (name) == 0)
+                                return child_idx;
+                            ++child_idx;
+                        }
+                    }
+                    
+                    // Try and find a field that matches NAME
+                    RecordDecl::field_iterator field, field_end;
+                    StringRef name_sref(name);
+                    for (field = record_decl->field_begin(), field_end = record_decl->field_end();
+                         field != field_end;
+                         ++field, ++child_idx)
+                    {
+                        if (field->getName().equals (name_sref))
+                            return child_idx;
+                    }
+                    
+                }
+                break;
+                
+            case clang::Type::ObjCObject:
+            case clang::Type::ObjCInterface:
+                if (GetCompleteType())
+                {
+                    StringRef name_sref(name);
+                    const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+                    assert (objc_class_type);
+                    if (objc_class_type)
+                    {
+                        uint32_t child_idx = 0;
+                        ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                        
+                        if (class_interface_decl)
+                        {
+                            ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+                            ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                            
+                            for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
+                            {
+                                const ObjCIvarDecl* ivar_decl = *ivar_pos;
+                                
+                                if (ivar_decl->getName().equals (name_sref))
+                                {
+                                    if ((!omit_empty_base_classes && superclass_interface_decl) ||
+                                        ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
+                                        ++child_idx;
+                                    
+                                    return child_idx;
+                                }
+                            }
+                            
+                            if (superclass_interface_decl)
+                            {
+                                if (superclass_interface_decl->getName().equals (name_sref))
+                                    return 0;
+                            }
+                        }
+                    }
+                }
+                break;
+                
+            case clang::Type::ObjCObjectPointer:
+                {
+                    ClangASTType pointee_clang_type (m_ast, cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
+                    return pointee_clang_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
+                }
+                break;
+                
+            case clang::Type::ConstantArray:
+            {
+                //                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
+                //                const uint64_t element_count = array->getSize().getLimitedValue();
+                //
+                //                if (idx < element_count)
+                //                {
+                //                    std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
+                //
+                //                    char element_name[32];
+                //                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
+                //
+                //                    child_name.assign(element_name);
+                //                    assert(field_type_info.first % 8 == 0);
+                //                    child_byte_size = field_type_info.first / 8;
+                //                    child_byte_offset = idx * child_byte_size;
+                //                    return array->getElementType().getAsOpaquePtr();
+                //                }
+            }
+                break;
+                
+                //        case clang::Type::MemberPointerType:
+                //            {
+                //                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
+                //                QualType pointee_type = mem_ptr_type->getPointeeType();
+                //
+                //                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+                //                {
+                //                    return GetIndexOfChildWithName (ast,
+                //                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
+                //                                                    name);
+                //                }
+                //            }
+                //            break;
+                //
+            case clang::Type::LValueReference:
+            case clang::Type::RValueReference:
+                {
+                    const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+                    ClangASTType pointee_type (m_ast, reference_type->getPointeeType());
+                    
+                    if (pointee_type.IsAggregateType ())
+                    {
+                        return pointee_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
+                    }
+                }
+                break;
+                
+            case clang::Type::Pointer:
+                {
+                    const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
+                    ClangASTType pointee_type (m_ast, pointer_type->getPointeeType());
+                    
+                    if (pointee_type.IsAggregateType ())
+                    {
+                        return pointee_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
+                    }
+                    else
+                    {
+                        //                    if (parent_name)
+                        //                    {
+                        //                        child_name.assign(1, '*');
+                        //                        child_name += parent_name;
+                        //                    }
+                        //
+                        //                    // We have a pointer to an simple type
+                        //                    if (idx == 0)
+                        //                    {
+                        //                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+                        //                        assert(clang_type_info.first % 8 == 0);
+                        //                        child_byte_size = clang_type_info.first / 8;
+                        //                        child_byte_offset = 0;
+                        //                        return pointee_type.getAsOpaquePtr();
+                        //                    }
+                    }
+                }
+                break;
+                
+            case clang::Type::Elaborated:
+                return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
+                
+            case clang::Type::Paren:
+                return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildWithName (name, omit_empty_base_classes);
+                
+            case clang::Type::Typedef:
+                return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
+                
+            default:
+                break;
+        }
+    }
+    return UINT32_MAX;
+}
+
+
+size_t
+ClangASTType::GetNumTemplateArguments () const
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetCanonicalQualType());
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Record:
+                if (GetCompleteType ())
+                {
+                    const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                    if (cxx_record_decl)
+                    {
+                        const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl);
+                        if (template_decl)
+                            return template_decl->getTemplateArgs().size();
+                    }
+                }
+                break;
+                
+            case clang::Type::Typedef:
+                return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumTemplateArguments();
+                
+            case clang::Type::Elaborated:
+                return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumTemplateArguments();
+                
+            case clang::Type::Paren:
+                return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetNumTemplateArguments();
+                
+            default:
+                break;
+        }
+    }
+    return 0;
+}
+
+ClangASTType
+ClangASTType::GetTemplateArgument (size_t arg_idx, lldb::TemplateArgumentKind &kind) const
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetCanonicalQualType());
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Record:
+                if (GetCompleteType ())
+                {
+                    const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                    if (cxx_record_decl)
+                    {
+                        const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl);
+                        if (template_decl && arg_idx < template_decl->getTemplateArgs().size())
+                        {
+                            const TemplateArgument &template_arg = template_decl->getTemplateArgs()[arg_idx];
+                            switch (template_arg.getKind())
+                            {
+                                case clang::TemplateArgument::Null:
+                                    kind = eTemplateArgumentKindNull;
+                                    return ClangASTType();
+                                    
+                                case clang::TemplateArgument::Type:
+                                    kind = eTemplateArgumentKindType;
+                                    return ClangASTType(m_ast, template_arg.getAsType());
+                                    
+                                case clang::TemplateArgument::Declaration:
+                                    kind = eTemplateArgumentKindDeclaration;
+                                    return ClangASTType();
+                                    
+                                case clang::TemplateArgument::Integral:
+                                    kind = eTemplateArgumentKindIntegral;
+                                    return ClangASTType(m_ast, template_arg.getIntegralType());
+                                    
+                                case clang::TemplateArgument::Template:
+                                    kind = eTemplateArgumentKindTemplate;
+                                    return ClangASTType();
+                                    
+                                case clang::TemplateArgument::TemplateExpansion:
+                                    kind = eTemplateArgumentKindTemplateExpansion;
+                                    return ClangASTType();
+                                    
+                                case clang::TemplateArgument::Expression:
+                                    kind = eTemplateArgumentKindExpression;
+                                    return ClangASTType();
+                                    
+                                case clang::TemplateArgument::Pack:
+                                    kind = eTemplateArgumentKindPack;
+                                    return ClangASTType();
+                                    
+                                default:
+                                    assert (!"Unhandled TemplateArgument::ArgKind");
+                                    break;
+                            }
+                        }
+                    }
+                }
+                break;
+                
+            case clang::Type::Typedef:
+                return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetTemplateArgument (arg_idx, kind);
+                
+            case clang::Type::Elaborated:
+                return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetTemplateArgument (arg_idx, kind);
+                
+            case clang::Type::Paren:
+                return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetTemplateArgument (arg_idx, kind);
+                
+            default:
+                break;
+        }
+    }
+    kind = eTemplateArgumentKindNull;
+    return ClangASTType ();
+}
+
+static bool
+IsOperator (const char *name, OverloadedOperatorKind &op_kind)
+{
+    if (name == NULL || name[0] == '\0')
+        return false;
+    
+#define OPERATOR_PREFIX "operator"
+#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
+    
+    const char *post_op_name = NULL;
+    
+    bool no_space = true;
+    
+    if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
+        return false;
+    
+    post_op_name = name + OPERATOR_PREFIX_LENGTH;
+    
+    if (post_op_name[0] == ' ')
+    {
+        post_op_name++;
+        no_space = false;
+    }
+    
+#undef OPERATOR_PREFIX
+#undef OPERATOR_PREFIX_LENGTH
+    
+    // This is an operator, set the overloaded operator kind to invalid
+    // in case this is a conversion operator...
+    op_kind = NUM_OVERLOADED_OPERATORS;
+    
+    switch (post_op_name[0])
+    {
+        default:
+            if (no_space)
+                return false;
+            break;
+        case 'n':
+            if (no_space)
+                return false;
+            if  (strcmp (post_op_name, "new") == 0)
+                op_kind = OO_New;
+            else if (strcmp (post_op_name, "new[]") == 0)
+                op_kind = OO_Array_New;
+            break;
+            
+        case 'd':
+            if (no_space)
+                return false;
+            if (strcmp (post_op_name, "delete") == 0)
+                op_kind = OO_Delete;
+            else if (strcmp (post_op_name, "delete[]") == 0)
+                op_kind = OO_Array_Delete;
+            break;
+            
+        case '+':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Plus;
+            else if (post_op_name[2] == '\0')
+            {
+                if (post_op_name[1] == '=')
+                    op_kind = OO_PlusEqual;
+                else if (post_op_name[1] == '+')
+                    op_kind = OO_PlusPlus;
+            }
+            break;
+            
+        case '-':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Minus;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '=': op_kind = OO_MinusEqual; break;
+                    case '-': op_kind = OO_MinusMinus; break;
+                    case '>': op_kind = OO_Arrow; break;
+                }
+            }
+            else if (post_op_name[3] == '\0')
+            {
+                if (post_op_name[2] == '*')
+                    op_kind = OO_ArrowStar; break;
+            }
+            break;
+            
+        case '*':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Star;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = OO_StarEqual;
+            break;
+            
+        case '/':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Slash;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = OO_SlashEqual;
+            break;
+            
+        case '%':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Percent;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = OO_PercentEqual;
+            break;
+            
+            
+        case '^':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Caret;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = OO_CaretEqual;
+            break;
+            
+        case '&':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Amp;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '=': op_kind = OO_AmpEqual; break;
+                    case '&': op_kind = OO_AmpAmp; break;
+                }
+            }
+            break;
+            
+        case '|':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Pipe;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '=': op_kind = OO_PipeEqual; break;
+                    case '|': op_kind = OO_PipePipe; break;
+                }
+            }
+            break;
+            
+        case '~':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Tilde;
+            break;
+            
+        case '!':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Exclaim;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = OO_ExclaimEqual;
+            break;
+            
+        case '=':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Equal;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = OO_EqualEqual;
+            break;
+            
+        case '<':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Less;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '<': op_kind = OO_LessLess; break;
+                    case '=': op_kind = OO_LessEqual; break;
+                }
+            }
+            else if (post_op_name[3] == '\0')
+            {
+                if (post_op_name[2] == '=')
+                    op_kind = OO_LessLessEqual;
+            }
+            break;
+            
+        case '>':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Greater;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '>': op_kind = OO_GreaterGreater; break;
+                    case '=': op_kind = OO_GreaterEqual; break;
+                }
+            }
+            else if (post_op_name[1] == '>' &&
+                     post_op_name[2] == '=' &&
+                     post_op_name[3] == '\0')
+            {
+                op_kind = OO_GreaterGreaterEqual;
+            }
+            break;
+            
+        case ',':
+            if (post_op_name[1] == '\0')
+                op_kind = OO_Comma;
+            break;
+            
+        case '(':
+            if (post_op_name[1] == ')' && post_op_name[2] == '\0')
+                op_kind = OO_Call;
+            break;
+            
+        case '[':
+            if (post_op_name[1] == ']' && post_op_name[2] == '\0')
+                op_kind = OO_Subscript;
+            break;
+    }
+    
+    return true;
+}
+
+static inline bool
+check_op_param (uint32_t op_kind, bool unary, bool binary, uint32_t num_params)
+{
+    // Special-case call since it can take any number of operands
+    if(op_kind == OO_Call)
+        return true;
+    
+    // The parameter count doens't include "this"
+    if (num_params == 0)
+        return unary;
+    if (num_params == 1)
+        return binary;
+    else
+        return false;
+}
+
+clang::RecordDecl *
+ClangASTType::GetAsRecordDecl () const
+{
+    const RecordType *record_type = dyn_cast<RecordType>(GetCanonicalQualType());
+    if (record_type)
+        return record_type->getDecl();
+    return NULL;
+}
+
+clang::CXXRecordDecl *
+ClangASTType::GetAsCXXRecordDecl () const
+{
+    return GetCanonicalQualType()->getAsCXXRecordDecl();
+}
+
+ObjCInterfaceDecl *
+ClangASTType::GetAsObjCInterfaceDecl () const
+{
+    const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(GetCanonicalQualType());
+    if (objc_class_type)
+        return objc_class_type->getInterface();
+    return NULL;
+}
+
+clang::FieldDecl *
+ClangASTType::AddFieldToRecordType (const char *name,
+                                    const ClangASTType &field_clang_type,
+                                    AccessType access,
+                                    uint32_t bitfield_bit_size)
+{
+    if (!IsValid() || !field_clang_type.IsValid())
+        return NULL;
+    
+    FieldDecl *field = NULL;
+
+    clang::Expr *bit_width = NULL;
+    if (bitfield_bit_size != 0)
+    {
+        APInt bitfield_bit_size_apint(m_ast->getTypeSize(m_ast->IntTy), bitfield_bit_size);
+        bit_width = new (*m_ast)IntegerLiteral (*m_ast, bitfield_bit_size_apint, m_ast->IntTy, SourceLocation());
+    }
+
+    RecordDecl *record_decl = GetAsRecordDecl ();
+    if (record_decl)
+    {
+        field = FieldDecl::Create (*m_ast,
+                                   record_decl,
+                                   SourceLocation(),
+                                   SourceLocation(),
+                                   name ? &m_ast->Idents.get(name) : NULL,  // Identifier
+                                   field_clang_type.GetQualType(),          // Field type
+                                   NULL,            // TInfo *
+                                   bit_width,       // BitWidth
+                                   false,           // Mutable
+                                   ICIS_NoInit);    // HasInit
+        
+        if (!name)
+        {
+            // Determine whether this field corresponds to an anonymous
+            // struct or union.
+            if (const TagType *TagT = field->getType()->getAs<TagType>()) {
+                if (RecordDecl *Rec = dyn_cast<RecordDecl>(TagT->getDecl()))
+                    if (!Rec->getDeclName()) {
+                        Rec->setAnonymousStructOrUnion(true);
+                        field->setImplicit();
+                        
+                    }
+            }
+        }
+        
+        if (field)
+        {
+            field->setAccess (ClangASTContext::ConvertAccessTypeToAccessSpecifier (access));
+            
+            record_decl->addDecl(field);
+            
+#ifdef LLDB_CONFIGURATION_DEBUG
+            VerifyDecl(field);
+#endif
+        }
+    }
+    else
+    {
+        ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
+        
+        if (class_interface_decl)
+        {
+            const bool is_synthesized = false;
+            
+            field_clang_type.GetCompleteType();
+
+            field = ObjCIvarDecl::Create (*m_ast,
+                                          class_interface_decl,
+                                          SourceLocation(),
+                                          SourceLocation(),
+                                          name ? &m_ast->Idents.get(name) : NULL,   // Identifier
+                                          field_clang_type.GetQualType(),           // Field type
+                                          NULL,                                     // TypeSourceInfo *
+                                          ConvertAccessTypeToObjCIvarAccessControl (access),
+                                          bit_width,
+                                          is_synthesized);
+            
+            if (field)
+            {
+                class_interface_decl->addDecl(field);
+                
+#ifdef LLDB_CONFIGURATION_DEBUG
+                VerifyDecl(field);
+#endif
+            }
+        }
+    }
+    return field;
+}
 
 void
-ClangASTType::DumpValue
-(
-    ExecutionContext *exe_ctx,
-    Stream *s,
-    lldb::Format format,
-    const lldb_private::DataExtractor &data,
-    lldb::offset_t data_byte_offset,
-    size_t data_byte_size,
-    uint32_t bitfield_bit_size,
-    uint32_t bitfield_bit_offset,
-    bool show_types,
-    bool show_summary,
-    bool verbose,
-    uint32_t depth
-)
+ClangASTType::BuildIndirectFields ()
 {
-    return DumpValue (m_ast, 
-                      m_type,
-                      exe_ctx,
-                      s,
-                      format,
-                      data,
-                      data_byte_offset,
-                      data_byte_size,
-                      bitfield_bit_size,
-                      bitfield_bit_offset,
-                      show_types,
-                      show_summary,
-                      verbose,
-                      depth);
+    RecordDecl *record_decl = GetAsRecordDecl();
+    
+    if (!record_decl)
+        return;
+    
+    typedef llvm::SmallVector <IndirectFieldDecl *, 1> IndirectFieldVector;
+    
+    IndirectFieldVector indirect_fields;
+    RecordDecl::field_iterator field_pos;
+    RecordDecl::field_iterator field_end_pos = record_decl->field_end();
+    RecordDecl::field_iterator last_field_pos = field_end_pos;
+    for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; last_field_pos = field_pos++)
+    {
+        if (field_pos->isAnonymousStructOrUnion())
+        {
+            QualType field_qual_type = field_pos->getType();
+            
+            const RecordType *field_record_type = field_qual_type->getAs<RecordType>();
+            
+            if (!field_record_type)
+                continue;
+            
+            RecordDecl *field_record_decl = field_record_type->getDecl();
+            
+            if (!field_record_decl)
+                continue;
+            
+            for (RecordDecl::decl_iterator di = field_record_decl->decls_begin(), de = field_record_decl->decls_end();
+                 di != de;
+                 ++di)
+            {
+                if (FieldDecl *nested_field_decl = dyn_cast<FieldDecl>(*di))
+                {
+                    NamedDecl **chain = new (*m_ast) NamedDecl*[2];
+                    chain[0] = *field_pos;
+                    chain[1] = nested_field_decl;
+                    IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*m_ast,
+                                                                                  record_decl,
+                                                                                  SourceLocation(),
+                                                                                  nested_field_decl->getIdentifier(),
+                                                                                  nested_field_decl->getType(),
+                                                                                  chain,
+                                                                                  2);
+                    
+                    indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(field_pos->getAccess(),
+                                                                                     nested_field_decl->getAccess()));
+                    
+                    indirect_fields.push_back(indirect_field);
+                }
+                else if (IndirectFieldDecl *nested_indirect_field_decl = dyn_cast<IndirectFieldDecl>(*di))
+                {
+                    int nested_chain_size = nested_indirect_field_decl->getChainingSize();
+                    NamedDecl **chain = new (*m_ast) NamedDecl*[nested_chain_size + 1];
+                    chain[0] = *field_pos;
+                    
+                    int chain_index = 1;
+                    for (IndirectFieldDecl::chain_iterator nci = nested_indirect_field_decl->chain_begin(),
+                         nce = nested_indirect_field_decl->chain_end();
+                         nci < nce;
+                         ++nci)
+                    {
+                        chain[chain_index] = *nci;
+                        chain_index++;
+                    }
+                    
+                    IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*m_ast,
+                                                                                  record_decl,
+                                                                                  SourceLocation(),
+                                                                                  nested_indirect_field_decl->getIdentifier(),
+                                                                                  nested_indirect_field_decl->getType(),
+                                                                                  chain,
+                                                                                  nested_chain_size + 1);
+                    
+                    indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(field_pos->getAccess(),
+                                                                                     nested_indirect_field_decl->getAccess()));
+                    
+                    indirect_fields.push_back(indirect_field);
+                }
+            }
+        }
+    }
+    
+    // Check the last field to see if it has an incomplete array type as its
+    // last member and if it does, the tell the record decl about it
+    if (last_field_pos != field_end_pos)
+    {
+        if (last_field_pos->getType()->isIncompleteArrayType())
+            record_decl->hasFlexibleArrayMember();
+    }
+    
+    for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), ife = indirect_fields.end();
+         ifi < ife;
+         ++ifi)
+    {
+        record_decl->addDecl(*ifi);
+    }
 }
-                      
-#define DEPTH_INCREMENT 2
-void
-ClangASTType::DumpValue
-(
-    clang::ASTContext *ast_context,
-    clang_type_t clang_type,
-    ExecutionContext *exe_ctx,
-    Stream *s,
-    lldb::Format format,
-    const lldb_private::DataExtractor &data,
-    lldb::offset_t data_byte_offset,
-    size_t data_byte_size,
-    uint32_t bitfield_bit_size,
-    uint32_t bitfield_bit_offset,
-    bool show_types,
-    bool show_summary,
-    bool verbose,
-    uint32_t depth
-)
+
+clang::VarDecl *
+ClangASTType::AddVariableToRecordType (const char *name,
+                                       const ClangASTType &var_type,
+                                       AccessType access)
 {
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+    clang::VarDecl *var_decl = NULL;
+    
+    if (!IsValid() || !var_type.IsValid())
+        return NULL;
+    
+    RecordDecl *record_decl = GetAsRecordDecl ();
+    if (record_decl)
+    {        
+        var_decl = VarDecl::Create (*m_ast,                                     // ASTContext &
+                                    record_decl,                                // DeclContext *
+                                    SourceLocation(),                           // SourceLocation StartLoc
+                                    SourceLocation(),                           // SourceLocation IdLoc
+                                    name ? &m_ast->Idents.get(name) : NULL,     // IdentifierInfo *
+                                    var_type.GetQualType(),                     // Variable QualType
+                                    NULL,                                       // TypeSourceInfo *
+                                    SC_Static);                                 // StorageClass
+        if (var_decl)
+        {
+            var_decl->setAccess(ClangASTContext::ConvertAccessTypeToAccessSpecifier (access));
+            record_decl->addDecl(var_decl);
+            
+#ifdef LLDB_CONFIGURATION_DEBUG
+            VerifyDecl(var_decl);
+#endif
+        }
+    }
+    return var_decl;
+}
+
+
+CXXMethodDecl *
+ClangASTType::AddMethodToCXXRecordType (const char *name,
+                                        const ClangASTType &method_clang_type,
+                                        lldb::AccessType access,
+                                        bool is_virtual,
+                                        bool is_static,
+                                        bool is_inline,
+                                        bool is_explicit,
+                                        bool is_attr_used,
+                                        bool is_artificial)
+{
+    if (!IsValid() || !method_clang_type.IsValid() || name == NULL || name[0] == '\0')
+        return NULL;
+    
+    QualType record_qual_type(GetCanonicalQualType());
+    
+    CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
+    
+    if (cxx_record_decl == NULL)
+        return NULL;
+    
+    QualType method_qual_type (method_clang_type.GetQualType());
+    
+    CXXMethodDecl *cxx_method_decl = NULL;
+    
+    DeclarationName decl_name (&m_ast->Idents.get(name));
+    
+    const clang::FunctionType *function_type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
+    
+    if (function_type == NULL)
+        return NULL;
+    
+    const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_type));
+    
+    if (!method_function_prototype)
+        return NULL;
+    
+    unsigned int num_params = method_function_prototype->getNumArgs();
+    
+    CXXDestructorDecl *cxx_dtor_decl(NULL);
+    CXXConstructorDecl *cxx_ctor_decl(NULL);
+    
+    if (is_artificial)
+        return NULL; // skip everything artificial
+    
+    if (name[0] == '~')
+    {
+        cxx_dtor_decl = CXXDestructorDecl::Create (*m_ast,
+                                                   cxx_record_decl,
+                                                   SourceLocation(),
+                                                   DeclarationNameInfo (m_ast->DeclarationNames.getCXXDestructorName (m_ast->getCanonicalType (record_qual_type)), SourceLocation()),
+                                                   method_qual_type,
+                                                   NULL,
+                                                   is_inline,
+                                                   is_artificial);
+        cxx_method_decl = cxx_dtor_decl;
+    }
+    else if (decl_name == cxx_record_decl->getDeclName())
+    {
+        cxx_ctor_decl = CXXConstructorDecl::Create (*m_ast,
+                                                    cxx_record_decl,
+                                                    SourceLocation(),
+                                                    DeclarationNameInfo (m_ast->DeclarationNames.getCXXConstructorName (m_ast->getCanonicalType (record_qual_type)), SourceLocation()),
+                                                    method_qual_type,
+                                                    NULL, // TypeSourceInfo *
+                                                    is_explicit,
+                                                    is_inline,
+                                                    is_artificial,
+                                                    false /*is_constexpr*/);
+        cxx_method_decl = cxx_ctor_decl;
+    }
+    else
+    {
+        clang::StorageClass SC = is_static ? SC_Static : SC_None;
+        OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
+        
+        if (IsOperator (name, op_kind))
+        {
+            if (op_kind != NUM_OVERLOADED_OPERATORS)
+            {
+                // Check the number of operator parameters. Sometimes we have
+                // seen bad DWARF that doesn't correctly describe operators and
+                // if we try to create a methed and add it to the class, clang
+                // will assert and crash, so we need to make sure things are
+                // acceptable.
+                if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params))
+                    return NULL;
+                cxx_method_decl = CXXMethodDecl::Create (*m_ast,
+                                                         cxx_record_decl,
+                                                         SourceLocation(),
+                                                         DeclarationNameInfo (m_ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
+                                                         method_qual_type,
+                                                         NULL, // TypeSourceInfo *
+                                                         SC,
+                                                         is_inline,
+                                                         false /*is_constexpr*/,
+                                                         SourceLocation());
+            }
+            else if (num_params == 0)
+            {
+                // Conversion operators don't take params...
+                cxx_method_decl = CXXConversionDecl::Create (*m_ast,
+                                                             cxx_record_decl,
+                                                             SourceLocation(),
+                                                             DeclarationNameInfo (m_ast->DeclarationNames.getCXXConversionFunctionName (m_ast->getCanonicalType (function_type->getResultType())), SourceLocation()),
+                                                             method_qual_type,
+                                                             NULL, // TypeSourceInfo *
+                                                             is_inline,
+                                                             is_explicit,
+                                                             false /*is_constexpr*/,
+                                                             SourceLocation());
+            }
+        }
+        
+        if (cxx_method_decl == NULL)
+        {
+            cxx_method_decl = CXXMethodDecl::Create (*m_ast,
+                                                     cxx_record_decl,
+                                                     SourceLocation(),
+                                                     DeclarationNameInfo (decl_name, SourceLocation()),
+                                                     method_qual_type,
+                                                     NULL, // TypeSourceInfo *
+                                                     SC,
+                                                     is_inline,
+                                                     false /*is_constexpr*/,
+                                                     SourceLocation());
+        }
+    }
+    
+    AccessSpecifier access_specifier = ClangASTContext::ConvertAccessTypeToAccessSpecifier (access);
+    
+    cxx_method_decl->setAccess (access_specifier);
+    cxx_method_decl->setVirtualAsWritten (is_virtual);
+    
+    if (is_attr_used)
+        cxx_method_decl->addAttr(::new (*m_ast) UsedAttr(SourceRange(), *m_ast));
+    
+    // Populate the method decl with parameter decls
+    
+    llvm::SmallVector<ParmVarDecl *, 12> params;
+    
+    for (unsigned param_index = 0;
+         param_index < num_params;
+         ++param_index)
+    {
+        params.push_back (ParmVarDecl::Create (*m_ast,
+                                               cxx_method_decl,
+                                               SourceLocation(),
+                                               SourceLocation(),
+                                               NULL, // anonymous
+                                               method_function_prototype->getArgType(param_index),
+                                               NULL,
+                                               SC_None,
+                                               NULL));
+    }
+    
+    cxx_method_decl->setParams (ArrayRef<ParmVarDecl*>(params));
+    
+    cxx_record_decl->addDecl (cxx_method_decl);
+    
+    // Sometimes the debug info will mention a constructor (default/copy/move),
+    // destructor, or assignment operator (copy/move) but there won't be any
+    // version of this in the code. So we check if the function was artificially
+    // generated and if it is trivial and this lets the compiler/backend know
+    // that it can inline the IR for these when it needs to and we can avoid a
+    // "missing function" error when running expressions.
+    
+    if (is_artificial)
+    {
+        if (cxx_ctor_decl &&
+            ((cxx_ctor_decl->isDefaultConstructor() && cxx_record_decl->hasTrivialDefaultConstructor ()) ||
+             (cxx_ctor_decl->isCopyConstructor()    && cxx_record_decl->hasTrivialCopyConstructor    ()) ||
+             (cxx_ctor_decl->isMoveConstructor()    && cxx_record_decl->hasTrivialMoveConstructor    ()) ))
+        {
+            cxx_ctor_decl->setDefaulted();
+            cxx_ctor_decl->setTrivial(true);
+        }
+        else if (cxx_dtor_decl)
+        {
+            if (cxx_record_decl->hasTrivialDestructor())
+            {
+                cxx_dtor_decl->setDefaulted();
+                cxx_dtor_decl->setTrivial(true);
+            }
+        }
+        else if ((cxx_method_decl->isCopyAssignmentOperator() && cxx_record_decl->hasTrivialCopyAssignment()) ||
+                 (cxx_method_decl->isMoveAssignmentOperator() && cxx_record_decl->hasTrivialMoveAssignment()))
+        {
+            cxx_method_decl->setDefaulted();
+            cxx_method_decl->setTrivial(true);
+        }
+    }
+    
+#ifdef LLDB_CONFIGURATION_DEBUG
+    VerifyDecl(cxx_method_decl);
+#endif
+    
+    //    printf ("decl->isPolymorphic()             = %i\n", cxx_record_decl->isPolymorphic());
+    //    printf ("decl->isAggregate()               = %i\n", cxx_record_decl->isAggregate());
+    //    printf ("decl->isPOD()                     = %i\n", cxx_record_decl->isPOD());
+    //    printf ("decl->isEmpty()                   = %i\n", cxx_record_decl->isEmpty());
+    //    printf ("decl->isAbstract()                = %i\n", cxx_record_decl->isAbstract());
+    //    printf ("decl->hasTrivialConstructor()     = %i\n", cxx_record_decl->hasTrivialConstructor());
+    //    printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
+    //    printf ("decl->hasTrivialCopyAssignment()  = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
+    //    printf ("decl->hasTrivialDestructor()      = %i\n", cxx_record_decl->hasTrivialDestructor());
+    return cxx_method_decl;
+}
+
+
+#pragma mark C++ Base Classes
+
+CXXBaseSpecifier *
+ClangASTType::CreateBaseClassSpecifier (AccessType access, bool is_virtual, bool base_of_class)
+{
+    if (IsValid())
+        return new CXXBaseSpecifier (SourceRange(),
+                                     is_virtual,
+                                     base_of_class,
+                                     ClangASTContext::ConvertAccessTypeToAccessSpecifier (access),
+                                     m_ast->getTrivialTypeSourceInfo (GetQualType()),
+                                     SourceLocation());
+    return NULL;
+}
+
+void
+ClangASTType::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
+{
+    for (unsigned i=0; i<num_base_classes; ++i)
+    {
+        delete base_classes[i];
+        base_classes[i] = NULL;
+    }
+}
+
+bool
+ClangASTType::SetBaseClassesForClassType (CXXBaseSpecifier const * const *base_classes,
+                                          unsigned num_base_classes)
+{
+    if (IsValid())
+    {
+        CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl();
+        if (cxx_record_decl)
+        {
+            cxx_record_decl->setBases(base_classes, num_base_classes);
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTType::SetObjCSuperClass (const ClangASTType &superclass_clang_type)
+{
+    if (IsValid() && superclass_clang_type.IsValid())
+    {
+        ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
+        ObjCInterfaceDecl *super_interface_decl = superclass_clang_type.GetAsObjCInterfaceDecl ();
+        if (class_interface_decl && super_interface_decl)
+        {
+            class_interface_decl->setSuperClass(super_interface_decl);
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTType::AddObjCClassProperty (const char *property_name,
+                                    const ClangASTType &property_clang_type,
+                                    ObjCIvarDecl *ivar_decl,
+                                    const char *property_setter_name,
+                                    const char *property_getter_name,
+                                    uint32_t property_attributes,
+                                    ClangASTMetadata *metadata)
+{
+    if (!IsValid() || !property_clang_type.IsValid() || property_name == NULL || property_name[0] == '\0')
+        return false;
+        
+    ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
+    
+    if (class_interface_decl)
+    {
+        ClangASTType property_clang_type_to_access;
+        
+        if (property_clang_type.IsValid())
+            property_clang_type_to_access = property_clang_type;
+        else if (ivar_decl)
+            property_clang_type_to_access = ClangASTType (m_ast, ivar_decl->getType());
+        
+        if (class_interface_decl && property_clang_type_to_access.IsValid())
+        {
+            clang::TypeSourceInfo *prop_type_source;
+            if (ivar_decl)
+                prop_type_source = m_ast->getTrivialTypeSourceInfo (ivar_decl->getType());
+            else
+                prop_type_source = m_ast->getTrivialTypeSourceInfo (property_clang_type.GetQualType());
+            
+            ObjCPropertyDecl *property_decl = ObjCPropertyDecl::Create (*m_ast,
+                                                                        class_interface_decl,
+                                                                        SourceLocation(), // Source Location
+                                                                        &m_ast->Idents.get(property_name),
+                                                                        SourceLocation(), //Source Location for AT
+                                                                        SourceLocation(), //Source location for (
+                                                                        prop_type_source);
+            
+            if (property_decl)
+            {
+                if (metadata)
+                    ClangASTContext::SetMetadata(m_ast, property_decl, *metadata);
+                
+                class_interface_decl->addDecl (property_decl);
+                
+                Selector setter_sel, getter_sel;
+                
+                if (property_setter_name != NULL)
+                {
+                    std::string property_setter_no_colon(property_setter_name, strlen(property_setter_name) - 1);
+                    clang::IdentifierInfo *setter_ident = &m_ast->Idents.get(property_setter_no_colon.c_str());
+                    setter_sel = m_ast->Selectors.getSelector(1, &setter_ident);
+                }
+                else if (!(property_attributes & DW_APPLE_PROPERTY_readonly))
+                {
+                    std::string setter_sel_string("set");
+                    setter_sel_string.push_back(::toupper(property_name[0]));
+                    setter_sel_string.append(&property_name[1]);
+                    clang::IdentifierInfo *setter_ident = &m_ast->Idents.get(setter_sel_string.c_str());
+                    setter_sel = m_ast->Selectors.getSelector(1, &setter_ident);
+                }
+                property_decl->setSetterName(setter_sel);
+                property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_setter);
+                
+                if (property_getter_name != NULL)
+                {
+                    clang::IdentifierInfo *getter_ident = &m_ast->Idents.get(property_getter_name);
+                    getter_sel = m_ast->Selectors.getSelector(0, &getter_ident);
+                }
+                else
+                {
+                    clang::IdentifierInfo *getter_ident = &m_ast->Idents.get(property_name);
+                    getter_sel = m_ast->Selectors.getSelector(0, &getter_ident);
+                }
+                property_decl->setGetterName(getter_sel);
+                property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_getter);
+                
+                if (ivar_decl)
+                    property_decl->setPropertyIvarDecl (ivar_decl);
+                
+                if (property_attributes & DW_APPLE_PROPERTY_readonly)
+                    property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readonly);
+                if (property_attributes & DW_APPLE_PROPERTY_readwrite)
+                    property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readwrite);
+                if (property_attributes & DW_APPLE_PROPERTY_assign)
+                    property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_assign);
+                if (property_attributes & DW_APPLE_PROPERTY_retain)
+                    property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_retain);
+                if (property_attributes & DW_APPLE_PROPERTY_copy)
+                    property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_copy);
+                if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
+                    property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_nonatomic);
+                
+                if (!getter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(getter_sel))
+                {
+                    const bool isInstance = true;
+                    const bool isVariadic = false;
+                    const bool isSynthesized = false;
+                    const bool isImplicitlyDeclared = true;
+                    const bool isDefined = false;
+                    const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None;
+                    const bool HasRelatedResultType = false;
+                    
+                    ObjCMethodDecl *getter = ObjCMethodDecl::Create (*m_ast,
+                                                                     SourceLocation(),
+                                                                     SourceLocation(),
+                                                                     getter_sel,
+                                                                     property_clang_type_to_access.GetQualType(),
+                                                                     NULL,
+                                                                     class_interface_decl,
+                                                                     isInstance,
+                                                                     isVariadic,
+                                                                     isSynthesized,
+                                                                     isImplicitlyDeclared,
+                                                                     isDefined,
+                                                                     impControl,
+                                                                     HasRelatedResultType);
+                    
+                    if (getter && metadata)
+                        ClangASTContext::SetMetadata(m_ast, getter, *metadata);
+                    
+                    getter->setMethodParams(*m_ast, ArrayRef<ParmVarDecl*>(), ArrayRef<SourceLocation>());
+                    
+                    class_interface_decl->addDecl(getter);
+                }
+                
+                if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel))
+                {
+                    QualType result_type = m_ast->VoidTy;
+                    
+                    const bool isInstance = true;
+                    const bool isVariadic = false;
+                    const bool isSynthesized = false;
+                    const bool isImplicitlyDeclared = true;
+                    const bool isDefined = false;
+                    const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None;
+                    const bool HasRelatedResultType = false;
+                    
+                    ObjCMethodDecl *setter = ObjCMethodDecl::Create (*m_ast,
+                                                                     SourceLocation(),
+                                                                     SourceLocation(),
+                                                                     setter_sel,
+                                                                     result_type,
+                                                                     NULL,
+                                                                     class_interface_decl,
+                                                                     isInstance,
+                                                                     isVariadic,
+                                                                     isSynthesized,
+                                                                     isImplicitlyDeclared,
+                                                                     isDefined,
+                                                                     impControl,
+                                                                     HasRelatedResultType);
+                    
+                    if (setter && metadata)
+                        ClangASTContext::SetMetadata(m_ast, setter, *metadata);
+                    
+                    llvm::SmallVector<ParmVarDecl *, 1> params;
+                    
+                    params.push_back (ParmVarDecl::Create (*m_ast,
+                                                           setter,
+                                                           SourceLocation(),
+                                                           SourceLocation(),
+                                                           NULL, // anonymous
+                                                           property_clang_type_to_access.GetQualType(),
+                                                           NULL,
+                                                           SC_Auto,
+                                                           NULL));
+                    
+                    setter->setMethodParams(*m_ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>());
+                    
+                    class_interface_decl->addDecl(setter);
+                }
+                
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTType::IsObjCClassTypeAndHasIVars (bool check_superclass) const
+{
+    ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
+    if (class_interface_decl)
+        return ObjCDeclHasIVars (class_interface_decl, check_superclass);
+    return false;
+}
+
+
+ObjCMethodDecl *
+ClangASTType::AddMethodToObjCObjectType (const char *name,  // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
+                                         const ClangASTType &method_clang_type,
+                                         lldb::AccessType access,
+                                         bool is_artificial)
+{
+    if (!IsValid() || !method_clang_type.IsValid())
+        return NULL;
+
+    ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl();
+    
+    if (class_interface_decl == NULL)
+        return NULL;
+    
+    const char *selector_start = ::strchr (name, ' ');
+    if (selector_start == NULL)
+        return NULL;
+    
+    selector_start++;
+    llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
+    
+    size_t len = 0;
+    const char *start;
+    //printf ("name = '%s'\n", name);
+    
+    unsigned num_selectors_with_args = 0;
+    for (start = selector_start;
+         start && *start != '\0' && *start != ']';
+         start += len)
+    {
+        len = ::strcspn(start, ":]");
+        bool has_arg = (start[len] == ':');
+        if (has_arg)
+            ++num_selectors_with_args;
+        selector_idents.push_back (&m_ast->Idents.get (StringRef (start, len)));
+        if (has_arg)
+            len += 1;
+    }
+    
+    
+    if (selector_idents.size() == 0)
+        return 0;
+    
+    clang::Selector method_selector = m_ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
+                                                                    selector_idents.data());
+    
+    QualType method_qual_type (method_clang_type.GetQualType());
+    
+    // Populate the method decl with parameter decls
+    const clang::Type *method_type(method_qual_type.getTypePtr());
+    
+    if (method_type == NULL)
+        return NULL;
+    
+    const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
+    
+    if (!method_function_prototype)
+        return NULL;
+    
+    
+    bool is_variadic = false;
+    bool is_synthesized = false;
+    bool is_defined = false;
+    ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
+    
+    const unsigned num_args = method_function_prototype->getNumArgs();
+    
+    if (num_args != num_selectors_with_args)
+        return NULL; // some debug information is corrupt.  We are not going to deal with it.
+    
+    ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*m_ast,
+                                                               SourceLocation(), // beginLoc,
+                                                               SourceLocation(), // endLoc,
+                                                               method_selector,
+                                                               method_function_prototype->getResultType(),
+                                                               NULL, // TypeSourceInfo *ResultTInfo,
+                                                               GetDeclContextForType (),
+                                                               name[0] == '-',
+                                                               is_variadic,
+                                                               is_synthesized,
+                                                               true, // is_implicitly_declared; we force this to true because we don't have source locations
+                                                               is_defined,
+                                                               imp_control,
+                                                               false /*has_related_result_type*/);
+    
+    
+    if (objc_method_decl == NULL)
+        return NULL;
+    
+    if (num_args > 0)
+    {
+        llvm::SmallVector<ParmVarDecl *, 12> params;
+        
+        for (unsigned param_index = 0; param_index < num_args; ++param_index)
+        {
+            params.push_back (ParmVarDecl::Create (*m_ast,
+                                                   objc_method_decl,
+                                                   SourceLocation(),
+                                                   SourceLocation(),
+                                                   NULL, // anonymous
+                                                   method_function_prototype->getArgType(param_index),
+                                                   NULL,
+                                                   SC_Auto,
+                                                   NULL));
+        }
+        
+        objc_method_decl->setMethodParams(*m_ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>());
+    }
+    
+    class_interface_decl->addDecl (objc_method_decl);
+    
+#ifdef LLDB_CONFIGURATION_DEBUG
+    VerifyDecl(objc_method_decl);
+#endif
+    
+    return objc_method_decl;
+}
+
+
+clang::DeclContext *
+ClangASTType::GetDeclContextForType () const
+{
+    if (!IsValid())
+        return NULL;
+    
+    QualType qual_type(GetCanonicalQualType());
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::UnaryTransform:           break;
+        case clang::Type::FunctionNoProto:          break;
+        case clang::Type::FunctionProto:            break;
+        case clang::Type::IncompleteArray:          break;
+        case clang::Type::VariableArray:            break;
+        case clang::Type::ConstantArray:            break;
+        case clang::Type::DependentSizedArray:      break;
+        case clang::Type::ExtVector:                break;
+        case clang::Type::DependentSizedExtVector:  break;
+        case clang::Type::Vector:                   break;
+        case clang::Type::Builtin:                  break;
+        case clang::Type::BlockPointer:             break;
+        case clang::Type::Pointer:                  break;
+        case clang::Type::LValueReference:          break;
+        case clang::Type::RValueReference:          break;
+        case clang::Type::MemberPointer:            break;
+        case clang::Type::Complex:                  break;
+        case clang::Type::ObjCObject:               break;
+        case clang::Type::ObjCInterface:            return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
+        case clang::Type::ObjCObjectPointer:        return ClangASTType (m_ast, cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType()).GetDeclContextForType();
+        case clang::Type::Record:                   return cast<RecordType>(qual_type)->getDecl();
+        case clang::Type::Enum:                     return cast<EnumType>(qual_type)->getDecl();
+        case clang::Type::Typedef:                  return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetDeclContextForType();
+        case clang::Type::Elaborated:               return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetDeclContextForType();
+        case clang::Type::Paren:                    return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetDeclContextForType();
+        case clang::Type::TypeOfExpr:               break;
+        case clang::Type::TypeOf:                   break;
+        case clang::Type::Decltype:                 break;
+            //case clang::Type::QualifiedName:          break;
+        case clang::Type::TemplateSpecialization:   break;
+        case clang::Type::DependentTemplateSpecialization:  break;
+        case clang::Type::TemplateTypeParm:         break;
+        case clang::Type::SubstTemplateTypeParm:    break;
+        case clang::Type::SubstTemplateTypeParmPack:break;
+        case clang::Type::PackExpansion:            break;
+        case clang::Type::UnresolvedUsing:          break;
+        case clang::Type::Attributed:               break;
+        case clang::Type::Auto:                     break;
+        case clang::Type::InjectedClassName:        break;
+        case clang::Type::DependentName:            break;
+        case clang::Type::Atomic:                   break;
+    }
+    // No DeclContext in this type...
+    return NULL;
+}
+
+bool
+ClangASTType::SetDefaultAccessForRecordFields (int default_accessibility,
+                                               int *assigned_accessibilities,
+                                               size_t num_assigned_accessibilities)
+{
+    if (IsValid())
+    {
+        RecordDecl *record_decl = GetAsRecordDecl();
+        if (record_decl)
+        {
+            uint32_t field_idx;
+            RecordDecl::field_iterator field, field_end;
+            for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
+                 field != field_end;
+                 ++field, ++field_idx)
+            {
+                // If no accessibility was assigned, assign the correct one
+                if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
+                    field->setAccess ((AccessSpecifier)default_accessibility);
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+
+bool
+ClangASTType::SetHasExternalStorage (bool has_extern)
+{
+    if (!IsValid())
+        return false;
+    
+    QualType qual_type (GetCanonicalQualType());
+    
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+        {
+            CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+            if (cxx_record_decl)
+            {
+                cxx_record_decl->setHasExternalLexicalStorage (has_extern);
+                cxx_record_decl->setHasExternalVisibleStorage (has_extern);
+                return true;
+            }
+        }
+            break;
+            
+        case clang::Type::Enum:
+        {
+            EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
+            if (enum_decl)
+            {
+                enum_decl->setHasExternalLexicalStorage (has_extern);
+                enum_decl->setHasExternalVisibleStorage (has_extern);
+                return true;
+            }
+        }
+            break;
+            
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+        {
+            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+            assert (objc_class_type);
+            if (objc_class_type)
+            {
+                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                
+                if (class_interface_decl)
+                {
+                    class_interface_decl->setHasExternalLexicalStorage (has_extern);
+                    class_interface_decl->setHasExternalVisibleStorage (has_extern);
+                    return true;
+                }
+            }
+        }
+            break;
+            
+        case clang::Type::Typedef:
+            return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).SetHasExternalStorage (has_extern);
+            
+        case clang::Type::Elaborated:
+            return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).SetHasExternalStorage (has_extern);
+            
+        case clang::Type::Paren:
+            return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).SetHasExternalStorage (has_extern);
+            
+        default:
+            break;
+    }
+    return false;
+}
+
+bool
+ClangASTType::SetTagTypeKind (int kind) const
+{
+    if (IsValid())
+    {
+        QualType tag_qual_type(GetQualType());
+        const clang::Type *clang_type = tag_qual_type.getTypePtr();
+        if (clang_type)
+        {
+            const TagType *tag_type = dyn_cast<TagType>(clang_type);
+            if (tag_type)
+            {
+                TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
+                if (tag_decl)
+                {
+                    tag_decl->setTagKind ((TagDecl::TagKind)kind);
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+
+#pragma mark TagDecl
+
+bool
+ClangASTType::StartTagDeclarationDefinition ()
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetQualType());
+        const clang::Type *t = qual_type.getTypePtr();
+        if (t)
+        {
+            const TagType *tag_type = dyn_cast<TagType>(t);
+            if (tag_type)
+            {
+                TagDecl *tag_decl = tag_type->getDecl();
+                if (tag_decl)
+                {
+                    tag_decl->startDefinition();
+                    return true;
+                }
+            }
+            
+            const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(t);
+            if (object_type)
+            {
+                ObjCInterfaceDecl *interface_decl = object_type->getInterface();
+                if (interface_decl)
+                {
+                    interface_decl->startDefinition();
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTType::CompleteTagDeclarationDefinition ()
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetQualType());
+        
+        CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+        
+        if (cxx_record_decl)
+        {
+            cxx_record_decl->completeDefinition();
+            
+            return true;
+        }
+        
+        const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
+        
+        if (enum_type)
+        {
+            EnumDecl *enum_decl = enum_type->getDecl();
+            
+            if (enum_decl)
+            {
+                /// TODO This really needs to be fixed.
+                
+                unsigned NumPositiveBits = 1;
+                unsigned NumNegativeBits = 0;
+                                
+                QualType promotion_qual_type;
+                // If the enum integer type is less than an integer in bit width,
+                // then we must promote it to an integer size.
+                if (m_ast->getTypeSize(enum_decl->getIntegerType()) < m_ast->getTypeSize(m_ast->IntTy))
+                {
+                    if (enum_decl->getIntegerType()->isSignedIntegerType())
+                        promotion_qual_type = m_ast->IntTy;
+                    else
+                        promotion_qual_type = m_ast->UnsignedIntTy;
+                }
+                else
+                    promotion_qual_type = enum_decl->getIntegerType();
+                
+                enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+
+
+
+
+
+
+bool
+ClangASTType::AddEnumerationValueToEnumerationType (const ClangASTType &enumerator_clang_type,
+                                                    const Declaration &decl,
+                                                    const char *name,
+                                                    int64_t enum_value,
+                                                    uint32_t enum_value_bit_size)
+{
+    if (IsValid() && enumerator_clang_type.IsValid() && name && name[0])
+    {
+        QualType enum_qual_type (GetCanonicalQualType());
+        
+        bool is_signed = false;
+        enumerator_clang_type.IsIntegerType (is_signed);
+        const clang::Type *clang_type = enum_qual_type.getTypePtr();
+        if (clang_type)
+        {
+            const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
+            
+            if (enum_type)
+            {
+                llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed);
+                enum_llvm_apsint = enum_value;
+                EnumConstantDecl *enumerator_decl =
+                EnumConstantDecl::Create (*m_ast,
+                                          enum_type->getDecl(),
+                                          SourceLocation(),
+                                          name ? &m_ast->Idents.get(name) : NULL,    // Identifier
+                                          enumerator_clang_type.GetQualType(),
+                                          NULL,
+                                          enum_llvm_apsint);
+                
+                if (enumerator_decl)
+                {
+                    enum_type->getDecl()->addDecl(enumerator_decl);
+                    
+#ifdef LLDB_CONFIGURATION_DEBUG
+                    VerifyDecl(enumerator_decl);
+#endif
+                    
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+
+ClangASTType
+ClangASTType::GetEnumerationIntegerType () const
+{
+    QualType enum_qual_type (GetCanonicalQualType());
+    const clang::Type *clang_type = enum_qual_type.getTypePtr();
+    if (clang_type)
+    {
+        const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
+        if (enum_type)
+        {
+            EnumDecl *enum_decl = enum_type->getDecl();
+            if (enum_decl)
+                return ClangASTType (m_ast, enum_decl->getIntegerType());
+        }
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::CreateMemberPointerType (const ClangASTType &pointee_type) const
+{
+    if (IsValid() && pointee_type.IsValid())
+    {
+        return ClangASTType (m_ast, m_ast->getMemberPointerType (pointee_type.GetQualType(),
+                                                                 GetQualType().getTypePtr()));
+    }
+    return ClangASTType();
+}
+
+
+size_t
+ClangASTType::ConvertStringToFloatValue (const char *s, uint8_t *dst, size_t dst_size) const
+{
+    if (IsValid())
+    {
+        QualType qual_type (GetCanonicalQualType());
+        uint32_t count = 0;
+        bool is_complex = false;
+        if (IsFloatingPointType (count, is_complex))
+        {
+            // TODO: handle complex and vector types
+            if (count != 1)
+                return false;
+            
+            StringRef s_sref(s);
+            APFloat ap_float(m_ast->getFloatTypeSemantics(qual_type), s_sref);
+            
+            const uint64_t bit_size = m_ast->getTypeSize (qual_type);
+            const uint64_t byte_size = bit_size / 8;
+            if (dst_size >= byte_size)
+            {
+                if (bit_size == sizeof(float)*8)
+                {
+                    float float32 = ap_float.convertToFloat();
+                    ::memcpy (dst, &float32, byte_size);
+                    return byte_size;
+                }
+                else if (bit_size >= 64)
+                {
+                    llvm::APInt ap_int(ap_float.bitcastToAPInt());
+                    ::memcpy (dst, ap_int.getRawData(), byte_size);
+                    return byte_size;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+
+
+//----------------------------------------------------------------------
+// Dumping types
+//----------------------------------------------------------------------
+#define DEPTH_INCREMENT 2
+
+void
+ClangASTType::DumpValue (ExecutionContext *exe_ctx,
+                         Stream *s,
+                         lldb::Format format,
+                         const lldb_private::DataExtractor &data,
+                         lldb::offset_t data_byte_offset,
+                         size_t data_byte_size,
+                         uint32_t bitfield_bit_size,
+                         uint32_t bitfield_bit_offset,
+                         bool show_types,
+                         bool show_summary,
+                         bool verbose,
+                         uint32_t depth)
+{
+    if (!IsValid())
+        return;
+
+    QualType qual_type(GetQualType());
     switch (qual_type->getTypeClass())
     {
     case clang::Type::Record:
-        if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+        if (GetCompleteType ())
         {
-            const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-            const clang::RecordDecl *record_decl = record_type->getDecl();
+            const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+            const RecordDecl *record_decl = record_type->getDecl();
             assert(record_decl);
             uint32_t field_bit_offset = 0;
             uint32_t field_byte_offset = 0;
-            const clang::ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
+            const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(record_decl);
             uint32_t child_idx = 0;
 
-
-            const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+            const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
             if (cxx_record_decl)
             {
                 // We might have base classes to print out first
-                clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+                CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
                 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
                      base_class != base_class_end;
                      ++base_class)
                 {
-                    const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
+                    const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
 
                     // Skip empty base classes
                     if (verbose == false && ClangASTContext::RecordHasFields(base_class_decl) == false)
@@ -786,35 +5561,34 @@
                     else
                         s->PutChar(',');
 
-                    clang::QualType base_class_qual_type = base_class->getType();
+                    QualType base_class_qual_type = base_class->getType();
                     std::string base_class_type_name(base_class_qual_type.getAsString());
 
                     // Indent and print the base class type name
                     s->Printf("\n%*s%s ", depth + DEPTH_INCREMENT, "", base_class_type_name.c_str());
 
-                    std::pair<uint64_t, unsigned> base_class_type_info = ast_context->getTypeInfo(base_class_qual_type);
+                    std::pair<uint64_t, unsigned> base_class_type_info = m_ast->getTypeInfo(base_class_qual_type);
 
                     // Dump the value of the member
-                    DumpValue (ast_context,                        // The clang AST context for this type
-                               base_class_qual_type.getAsOpaquePtr(),// The clang type we want to dump
-                               exe_ctx,
-                               s,                                  // Stream to dump to
-                               ClangASTType::GetFormat(base_class_qual_type.getAsOpaquePtr()), // The format with which to display the member
-                               data,                               // Data buffer containing all bytes for this type
-                               data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
-                               base_class_type_info.first / 8,     // Size of this type in bytes
-                               0,                                  // Bitfield bit size
-                               0,                                  // Bitfield bit offset
-                               show_types,                         // Boolean indicating if we should show the variable types
-                               show_summary,                       // Boolean indicating if we should show a summary for the current type
-                               verbose,                            // Verbose output?
-                               depth + DEPTH_INCREMENT);           // Scope depth for any types that have children
+                    ClangASTType base_clang_type(m_ast, base_class_qual_type);
+                    base_clang_type.DumpValue (exe_ctx,
+                                               s,                                   // Stream to dump to
+                                               base_clang_type.GetFormat(),         // The format with which to display the member
+                                               data,                                // Data buffer containing all bytes for this type
+                                               data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
+                                               base_class_type_info.first / 8,      // Size of this type in bytes
+                                               0,                                   // Bitfield bit size
+                                               0,                                   // Bitfield bit offset
+                                               show_types,                          // Boolean indicating if we should show the variable types
+                                               show_summary,                        // Boolean indicating if we should show a summary for the current type
+                                               verbose,                             // Verbose output?
+                                               depth + DEPTH_INCREMENT);            // Scope depth for any types that have children
                     
                     ++child_idx;
                 }
             }
             uint32_t field_idx = 0;
-            clang::RecordDecl::field_iterator field, field_end;
+            RecordDecl::field_iterator field, field_end;
             for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
             {
                 // Print the starting squiggly bracket (if this is the
@@ -828,18 +5602,18 @@
                 // Indent
                 s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
 
-                clang::QualType field_type = field->getType();
+                QualType field_type = field->getType();
                 // Print the member type if requested
                 // Figure out the type byte size (field_type_info.first) and
                 // alignment (field_type_info.second) from the AST context.
-                std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field_type);
+                std::pair<uint64_t, unsigned> field_type_info = m_ast->getTypeInfo(field_type);
                 assert(field_idx < record_layout.getFieldCount());
                 // Figure out the field offset within the current struct/union/class type
                 field_bit_offset = record_layout.getFieldOffset (field_idx);
                 field_byte_offset = field_bit_offset / 8;
                 uint32_t field_bitfield_bit_size = 0;
                 uint32_t field_bitfield_bit_offset = 0;
-                if (ClangASTContext::FieldIsBitfield (ast_context, *field, field_bitfield_bit_size))
+                if (ClangASTContext::FieldIsBitfield (m_ast, *field, field_bitfield_bit_size))
                     field_bitfield_bit_offset = field_bit_offset % 8;
 
                 if (show_types)
@@ -855,20 +5629,19 @@
 
 
                 // Dump the value of the member
-                DumpValue (ast_context,                    // The clang AST context for this type
-                           field_type.getAsOpaquePtr(),    // The clang type we want to dump
-                           exe_ctx,
-                           s,                              // Stream to dump to
-                           ClangASTType::GetFormat(field_type.getAsOpaquePtr()),   // The format with which to display the member
-                           data,                           // Data buffer containing all bytes for this type
-                           data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
-                           field_type_info.first / 8,      // Size of this type in bytes
-                           field_bitfield_bit_size,        // Bitfield bit size
-                           field_bitfield_bit_offset,      // Bitfield bit offset
-                           show_types,                     // Boolean indicating if we should show the variable types
-                           show_summary,                   // Boolean indicating if we should show a summary for the current type
-                           verbose,                        // Verbose output?
-                           depth + DEPTH_INCREMENT);       // Scope depth for any types that have children
+                ClangASTType field_clang_type (m_ast, field_type);
+                field_clang_type.DumpValue (exe_ctx,
+                                            s,                              // Stream to dump to
+                                            field_clang_type.GetFormat(),   // The format with which to display the member
+                                            data,                           // Data buffer containing all bytes for this type
+                                            data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
+                                            field_type_info.first / 8,      // Size of this type in bytes
+                                            field_bitfield_bit_size,        // Bitfield bit size
+                                            field_bitfield_bit_offset,      // Bitfield bit offset
+                                            show_types,                     // Boolean indicating if we should show the variable types
+                                            show_summary,                   // Boolean indicating if we should show a summary for the current type
+                                            verbose,                        // Verbose output?
+                                            depth + DEPTH_INCREMENT);       // Scope depth for any types that have children
             }
 
             // Indent the trailing squiggly bracket
@@ -878,12 +5651,12 @@
         return;
 
     case clang::Type::Enum:
-        if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+        if (GetCompleteType ())
         {
-            const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
-            const clang::EnumDecl *enum_decl = enum_type->getDecl();
+            const EnumType *enum_type = cast<EnumType>(qual_type.getTypePtr());
+            const EnumDecl *enum_decl = enum_type->getDecl();
             assert(enum_decl);
-            clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
+            EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
             lldb::offset_t offset = data_byte_offset;
             const int64_t enum_value = data.GetMaxU64Bitfield(&offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
             for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
@@ -902,9 +5675,9 @@
 
     case clang::Type::ConstantArray:
         {
-            const clang::ConstantArrayType *array = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
+            const ConstantArrayType *array = cast<ConstantArrayType>(qual_type.getTypePtr());
             bool is_array_of_characters = false;
-            clang::QualType element_qual_type = array->getElementType();
+            QualType element_qual_type = array->getElementType();
 
             const clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
             if (canonical_type)
@@ -912,7 +5685,7 @@
 
             const uint64_t element_count = array->getSize().getLimitedValue();
 
-            std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(element_qual_type);
+            std::pair<uint64_t, unsigned> field_type_info = m_ast->getTypeInfo(element_qual_type);
 
             uint32_t element_idx = 0;
             uint32_t element_offset = 0;
@@ -928,7 +5701,8 @@
             }
             else
             {
-                lldb::Format element_format = ClangASTType::GetFormat(element_qual_type.getAsOpaquePtr());
+                ClangASTType element_clang_type(m_ast, element_qual_type);
+                lldb::Format element_format = element_clang_type.GetFormat();
 
                 for (element_idx = 0; element_idx < element_count; ++element_idx)
                 {
@@ -947,20 +5721,18 @@
                     element_offset = element_idx * element_stride;
 
                     // Dump the value of the member
-                    DumpValue (ast_context,                    // The clang AST context for this type
-                               element_qual_type.getAsOpaquePtr(), // The clang type we want to dump
-                               exe_ctx,
-                               s,                              // Stream to dump to
-                               element_format,                 // The format with which to display the element
-                               data,                           // Data buffer containing all bytes for this type
-                               data_byte_offset + element_offset,// Offset into "data" where to grab value from
-                               element_byte_size,              // Size of this type in bytes
-                               0,                              // Bitfield bit size
-                               0,                              // Bitfield bit offset
-                               show_types,                     // Boolean indicating if we should show the variable types
-                               show_summary,                   // Boolean indicating if we should show a summary for the current type
-                               verbose,                        // Verbose output?
-                               depth + DEPTH_INCREMENT);       // Scope depth for any types that have children
+                    element_clang_type.DumpValue (exe_ctx,
+                                                  s,                              // Stream to dump to
+                                                  element_format,                 // The format with which to display the element
+                                                  data,                           // Data buffer containing all bytes for this type
+                                                  data_byte_offset + element_offset,// Offset into "data" where to grab value from
+                                                  element_byte_size,              // Size of this type in bytes
+                                                  0,                              // Bitfield bit size
+                                                  0,                              // Bitfield bit offset
+                                                  show_types,                     // Boolean indicating if we should show the variable types
+                                                  show_summary,                   // Boolean indicating if we should show a summary for the current type
+                                                  verbose,                        // Verbose output?
+                                                  depth + DEPTH_INCREMENT);       // Scope depth for any types that have children
                 }
 
                 // Indent the trailing squiggly bracket
@@ -972,88 +5744,96 @@
 
     case clang::Type::Typedef:
         {
-            clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType();
-            lldb::Format typedef_format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr());
-            std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type);
+            QualType typedef_qual_type = cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType();
+            
+            ClangASTType typedef_clang_type (m_ast, typedef_qual_type);
+            lldb::Format typedef_format = typedef_clang_type.GetFormat();
+            std::pair<uint64_t, unsigned> typedef_type_info = m_ast->getTypeInfo(typedef_qual_type);
             uint64_t typedef_byte_size = typedef_type_info.first / 8;
 
-            return DumpValue (ast_context,        // The clang AST context for this type
-                              typedef_qual_type.getAsOpaquePtr(), // The clang type we want to dump
-                              exe_ctx,
-                              s,                  // Stream to dump to
-                              typedef_format,     // The format with which to display the element
-                              data,               // Data buffer containing all bytes for this type
-                              data_byte_offset,   // Offset into "data" where to grab value from
-                              typedef_byte_size,  // Size of this type in bytes
-                              bitfield_bit_size,  // Bitfield bit size
-                              bitfield_bit_offset,// Bitfield bit offset
-                              show_types,         // Boolean indicating if we should show the variable types
-                              show_summary,       // Boolean indicating if we should show a summary for the current type
-                              verbose,            // Verbose output?
-                              depth);             // Scope depth for any types that have children
+            return typedef_clang_type.DumpValue (exe_ctx,
+                                                 s,                  // Stream to dump to
+                                                 typedef_format,     // The format with which to display the element
+                                                 data,               // Data buffer containing all bytes for this type
+                                                 data_byte_offset,   // Offset into "data" where to grab value from
+                                                 typedef_byte_size,  // Size of this type in bytes
+                                                 bitfield_bit_size,  // Bitfield bit size
+                                                 bitfield_bit_offset,// Bitfield bit offset
+                                                 show_types,         // Boolean indicating if we should show the variable types
+                                                 show_summary,       // Boolean indicating if we should show a summary for the current type
+                                                 verbose,            // Verbose output?
+                                                 depth);             // Scope depth for any types that have children
         }
         break;
 
     case clang::Type::Elaborated:
         {
-            clang::QualType elaborated_qual_type = llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
-            lldb::Format elaborated_format = ClangASTType::GetFormat(elaborated_qual_type.getAsOpaquePtr());
-            std::pair<uint64_t, unsigned> elaborated_type_info = ast_context->getTypeInfo(elaborated_qual_type);
+            QualType elaborated_qual_type = cast<ElaboratedType>(qual_type)->getNamedType();
+            ClangASTType elaborated_clang_type (m_ast, elaborated_qual_type);
+            lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
+            std::pair<uint64_t, unsigned> elaborated_type_info = m_ast->getTypeInfo(elaborated_qual_type);
             uint64_t elaborated_byte_size = elaborated_type_info.first / 8;
 
-            return DumpValue (ast_context,        // The clang AST context for this type
-                              elaborated_qual_type.getAsOpaquePtr(),    // The clang type we want to dump
-                              exe_ctx,
-                              s,                  // Stream to dump to
-                              elaborated_format,  // The format with which to display the element
-                              data,               // Data buffer containing all bytes for this type
-                              data_byte_offset,   // Offset into "data" where to grab value from
-                              elaborated_byte_size,  // Size of this type in bytes
-                              bitfield_bit_size,  // Bitfield bit size
-                              bitfield_bit_offset,// Bitfield bit offset
-                              show_types,         // Boolean indicating if we should show the variable types
-                              show_summary,       // Boolean indicating if we should show a summary for the current type
-                              verbose,            // Verbose output?
-                              depth);             // Scope depth for any types that have children
+            return elaborated_clang_type.DumpValue (exe_ctx,
+                                                    s,                  // Stream to dump to
+                                                    elaborated_format,  // The format with which to display the element
+                                                    data,               // Data buffer containing all bytes for this type
+                                                    data_byte_offset,   // Offset into "data" where to grab value from
+                                                    elaborated_byte_size,  // Size of this type in bytes
+                                                    bitfield_bit_size,  // Bitfield bit size
+                                                    bitfield_bit_offset,// Bitfield bit offset
+                                                    show_types,         // Boolean indicating if we should show the variable types
+                                                    show_summary,       // Boolean indicating if we should show a summary for the current type
+                                                    verbose,            // Verbose output?
+                                                    depth);             // Scope depth for any types that have children
         }
         break;
             
     case clang::Type::Paren:
-    {
-        clang::QualType desugar_qual_type = llvm::cast<clang::ParenType>(qual_type)->desugar();
-        lldb::Format desugar_format = ClangASTType::GetFormat(desugar_qual_type.getAsOpaquePtr());
-        std::pair<uint64_t, unsigned> desugar_type_info = ast_context->getTypeInfo(desugar_qual_type);
-        uint64_t desugar_byte_size = desugar_type_info.first / 8;
-        
-        return DumpValue (ast_context,        // The clang AST context for this type
-                          desugar_qual_type.getAsOpaquePtr(),    // The clang type we want to dump
-                          exe_ctx,
-                          s,                  // Stream to dump to
-                          desugar_format,  // The format with which to display the element
-                          data,               // Data buffer containing all bytes for this type
-                          data_byte_offset,   // Offset into "data" where to grab value from
-                          desugar_byte_size,  // Size of this type in bytes
-                          bitfield_bit_size,  // Bitfield bit size
-                          bitfield_bit_offset,// Bitfield bit offset
-                          show_types,         // Boolean indicating if we should show the variable types
-                          show_summary,       // Boolean indicating if we should show a summary for the current type
-                          verbose,            // Verbose output?
-                          depth);             // Scope depth for any types that have children
-    }
+        {
+            QualType desugar_qual_type = cast<ParenType>(qual_type)->desugar();
+            ClangASTType desugar_clang_type (m_ast, desugar_qual_type);
+
+            lldb::Format desugar_format = desugar_clang_type.GetFormat();
+            std::pair<uint64_t, unsigned> desugar_type_info = m_ast->getTypeInfo(desugar_qual_type);
+            uint64_t desugar_byte_size = desugar_type_info.first / 8;
+            
+            return desugar_clang_type.DumpValue (exe_ctx,
+                                                 s,                  // Stream to dump to
+                                                 desugar_format,  // The format with which to display the element
+                                                 data,               // Data buffer containing all bytes for this type
+                                                 data_byte_offset,   // Offset into "data" where to grab value from
+                                                 desugar_byte_size,  // Size of this type in bytes
+                                                 bitfield_bit_size,  // Bitfield bit size
+                                                 bitfield_bit_offset,// Bitfield bit offset
+                                                 show_types,         // Boolean indicating if we should show the variable types
+                                                 show_summary,       // Boolean indicating if we should show a summary for the current type
+                                                 verbose,            // Verbose output?
+                                                 depth);             // Scope depth for any types that have children
+        }
         break;
 
     default:
         // We are down the a scalar type that we just need to display.
-        data.Dump(s, data_byte_offset, format, data_byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset);
+        data.Dump(s,
+                  data_byte_offset,
+                  format,
+                  data_byte_size,
+                  1,
+                  UINT32_MAX,
+                  LLDB_INVALID_ADDRESS,
+                  bitfield_bit_size,
+                  bitfield_bit_offset);
 
         if (show_summary)
-            DumpSummary (ast_context, clang_type, exe_ctx, s, data, data_byte_offset, data_byte_size);
+            DumpSummary (exe_ctx, s, data, data_byte_offset, data_byte_size);
         break;
     }
 }
 
 
 
+
 bool
 ClangASTType::DumpTypeValue (Stream *s,
                              lldb::Format format,
@@ -1064,72 +5844,48 @@
                              uint32_t bitfield_bit_offset,
                              ExecutionContextScope *exe_scope)
 {
-    return DumpTypeValue (m_ast,
-                          m_type,
-                          s,
-                          format,
-                          data,
-                          byte_offset,
-                          byte_size,
-                          bitfield_bit_size,
-                          bitfield_bit_offset,
-                          exe_scope);
-}
-
-
-bool
-ClangASTType::DumpTypeValue (clang::ASTContext *ast_context,
-                             clang_type_t clang_type,
-                             Stream *s,
-                             lldb::Format format,
-                             const lldb_private::DataExtractor &data,
-                             lldb::offset_t byte_offset,
-                             size_t byte_size,
-                             uint32_t bitfield_bit_size,
-                             uint32_t bitfield_bit_offset,
-                             ExecutionContextScope *exe_scope)
-{
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-    if (ClangASTContext::IsAggregateType (clang_type))
+    if (!IsValid())
+        return false;
+    if (IsAggregateType())
     {
-        return 0;
+        return false;
     }
     else
     {
+        QualType qual_type(GetQualType());
+
         const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-            
         switch (type_class)
         {
         case clang::Type::Typedef:
             {
-                clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType();
+                QualType typedef_qual_type = cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType();
+                ClangASTType typedef_clang_type (m_ast, typedef_qual_type);
                 if (format == eFormatDefault)
-                    format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr());
-                std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type);
+                    format = typedef_clang_type.GetFormat();
+                std::pair<uint64_t, unsigned> typedef_type_info = m_ast->getTypeInfo(typedef_qual_type);
                 uint64_t typedef_byte_size = typedef_type_info.first / 8;
 
-                return ClangASTType::DumpTypeValue (ast_context,            // The clang AST context for this type
-                                                    typedef_qual_type.getAsOpaquePtr(),     // The clang type we want to dump
-                                                    s,
-                                                    format,                 // The format with which to display the element
-                                                    data,                   // Data buffer containing all bytes for this type
-                                                    byte_offset,            // Offset into "data" where to grab value from
-                                                    typedef_byte_size,      // Size of this type in bytes
-                                                    bitfield_bit_size,      // Size in bits of a bitfield value, if zero don't treat as a bitfield
-                                                    bitfield_bit_offset,    // Offset in bits of a bitfield value if bitfield_bit_size != 0
-                                                    exe_scope);
+                return typedef_clang_type.DumpTypeValue (s,
+                                                         format,                 // The format with which to display the element
+                                                         data,                   // Data buffer containing all bytes for this type
+                                                         byte_offset,            // Offset into "data" where to grab value from
+                                                         typedef_byte_size,      // Size of this type in bytes
+                                                         bitfield_bit_size,      // Size in bits of a bitfield value, if zero don't treat as a bitfield
+                                                         bitfield_bit_offset,    // Offset in bits of a bitfield value if bitfield_bit_size != 0
+                                                         exe_scope);
             }
             break;
 
         case clang::Type::Enum:
             // If our format is enum or default, show the enumeration value as
             // its enumeration string value, else just display it as requested.
-            if ((format == eFormatEnum || format == eFormatDefault) && ClangASTContext::GetCompleteType (ast_context, clang_type))
+            if ((format == eFormatEnum || format == eFormatDefault) && GetCompleteType ())
             {
-                const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
-                const clang::EnumDecl *enum_decl = enum_type->getDecl();
+                const EnumType *enum_type = cast<EnumType>(qual_type.getTypePtr());
+                const EnumDecl *enum_decl = enum_type->getDecl();
                 assert(enum_decl);
-                clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
+                EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
                 const bool is_signed = qual_type->isSignedIntegerOrEnumerationType();
                 lldb::offset_t offset = byte_offset;
                 if (is_signed)
@@ -1241,38 +5997,14 @@
 
 
 void
-ClangASTType::DumpSummary
-(
-    ExecutionContext *exe_ctx,
-    Stream *s,
-    const lldb_private::DataExtractor &data,
-    lldb::offset_t data_byte_offset,
-    size_t data_byte_size
-)
-{
-    return DumpSummary (m_ast,
-                        m_type,
-                        exe_ctx, 
-                        s, 
-                        data, 
-                        data_byte_offset, 
-                        data_byte_size);
-}
-
-void
-ClangASTType::DumpSummary
-(
-    clang::ASTContext *ast_context,
-    clang_type_t clang_type,
-    ExecutionContext *exe_ctx,
-    Stream *s,
-    const lldb_private::DataExtractor &data,
-    lldb::offset_t data_byte_offset,
-    size_t data_byte_size
-)
+ClangASTType::DumpSummary (ExecutionContext *exe_ctx,
+                           Stream *s,
+                           const lldb_private::DataExtractor &data,
+                           lldb::offset_t data_byte_offset,
+                           size_t data_byte_size)
 {
     uint32_t length = 0;
-    if (ClangASTContext::IsCStringType (clang_type, length))
+    if (IsCStringType (length))
     {
         if (exe_ctx)
         {
@@ -1312,104 +6044,8 @@
     }
 }
 
-uint64_t
-ClangASTType::GetClangTypeByteSize ()
-{
-    return (GetClangTypeBitWidth (m_ast, m_type) + 7) / 8;
-}
-
-uint64_t
-ClangASTType::GetClangTypeByteSize (clang::ASTContext *ast_context, clang_type_t clang_type)
-{
-    return (GetClangTypeBitWidth (ast_context, clang_type) + 7) / 8;
-}
-
-uint64_t
-ClangASTType::GetClangTypeBitWidth ()
-{
-    return GetClangTypeBitWidth (m_ast, m_type);
-}
-
-uint64_t
-ClangASTType::GetClangTypeBitWidth (clang::ASTContext *ast_context, clang_type_t clang_type)
-{
-    if (ClangASTContext::GetCompleteType (ast_context, clang_type))
-    {
-        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-        const uint32_t bit_size = ast_context->getTypeSize (qual_type);
-        if (bit_size == 0)
-        {
-            if (qual_type->isIncompleteArrayType())
-                return ast_context->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
-        }
-        return bit_size;
-    }
-    return 0;
-}
-
-size_t
-ClangASTType::GetTypeBitAlign ()
-{
-    return GetTypeBitAlign (m_ast, m_type);
-}
-
-size_t
-ClangASTType::GetTypeBitAlign (clang::ASTContext *ast_context, clang_type_t clang_type)
-{
-    if (ClangASTContext::GetCompleteType (ast_context, clang_type))
-        return ast_context->getTypeAlign(clang::QualType::getFromOpaquePtr(clang_type));
-    return 0;
-}
-
-
-bool
-ClangASTType::IsDefined()
-{
-    return ClangASTType::IsDefined (m_type);
-}
-
-bool
-ClangASTType::IsDefined (clang_type_t clang_type)
-{
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-    const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
-    if (tag_type)
-    {
-        clang::TagDecl *tag_decl = tag_type->getDecl();
-        if (tag_decl)
-            return tag_decl->isCompleteDefinition();
-        return false;
-    }
-    else
-    {
-        const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
-        if (objc_class_type)
-        {
-            clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-            if (class_interface_decl)
-                return class_interface_decl->getDefinition() != NULL;
-            return false;
-        }
-    }
-    return true;
-}
-
-bool
-ClangASTType::IsConst()
-{
-    return ClangASTType::IsConst (m_type);
-}
-
-bool
-ClangASTType::IsConst (lldb::clang_type_t clang_type)
-{
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-    
-    return qual_type.isConstQualified();
-}
-
 void
-ClangASTType::DumpTypeDescription ()
+ClangASTType::DumpTypeDescription () const
 {
     StreamFile s (stdout, false);
     DumpTypeDescription (&s);
@@ -1421,22 +6057,14 @@
 }
 
 void
-ClangASTType::DumpTypeDescription (Stream *s)
+ClangASTType::DumpTypeDescription (Stream *s) const
 {
-    return DumpTypeDescription (m_ast, m_type, s);
-}
-
-// Dump the full description of a type. For classes this means all of the
-// ivars and member functions, for structs/unions all of the members. 
-void
-ClangASTType::DumpTypeDescription (clang::ASTContext *ast_context, clang_type_t clang_type, Stream *s)
-{
-    if (clang_type)
+    if (IsValid())
     {
-        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+        QualType qual_type(GetQualType());
 
-        llvm::SmallVector<char, 1024> buf;
-        llvm::raw_svector_ostream llvm_ostrm (buf);
+        SmallVector<char, 1024> buf;
+        raw_svector_ostream llvm_ostrm (buf);
 
         const clang::Type::TypeClass type_class = qual_type->getTypeClass();
         switch (type_class)
@@ -1444,16 +6072,16 @@
         case clang::Type::ObjCObject:
         case clang::Type::ObjCInterface:
             {
-                ClangASTContext::GetCompleteType (ast_context, clang_type);
+                GetCompleteType ();
                 
-                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
                 assert (objc_class_type);
                 if (objc_class_type)
                 {
-                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
                     if (class_interface_decl)
                     {
-                        clang::PrintingPolicy policy = ast_context->getPrintingPolicy();
+                        PrintingPolicy policy = m_ast->getPrintingPolicy();
                         class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
                     }
                 }
@@ -1462,10 +6090,10 @@
         
         case clang::Type::Typedef:
             {
-                const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
+                const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
                 if (typedef_type)
                 {
-                    const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
+                    const TypedefNameDecl *typedef_decl = typedef_type->getDecl();
                     std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString());
                     if (!clang_typedef_name.empty())
                     {
@@ -1477,38 +6105,34 @@
             break;
 
         case clang::Type::Elaborated:
-            DumpTypeDescription (ast_context,
-                                 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
-                                 s);
+            ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).DumpTypeDescription(s);
             return;
 
         case clang::Type::Paren:
-            DumpTypeDescription (ast_context,
-                                 llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
-                                 s);
+            ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).DumpTypeDescription(s);
             return;
 
         case clang::Type::Record:
             {
-                ClangASTContext::GetCompleteType (ast_context, clang_type);
+                GetCompleteType ();
                 
-                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-                const clang::RecordDecl *record_decl = record_type->getDecl();
-                const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+                const RecordDecl *record_decl = record_type->getDecl();
+                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
 
                 if (cxx_record_decl)
-                    cxx_record_decl->print(llvm_ostrm, ast_context->getPrintingPolicy(), s->GetIndentLevel());
+                    cxx_record_decl->print(llvm_ostrm, m_ast->getPrintingPolicy(), s->GetIndentLevel());
                 else
-                    record_decl->print(llvm_ostrm, ast_context->getPrintingPolicy(), s->GetIndentLevel());
+                    record_decl->print(llvm_ostrm, m_ast->getPrintingPolicy(), s->GetIndentLevel());
             }
             break;
 
         default:
             {
-                const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
+                const TagType *tag_type = dyn_cast<TagType>(qual_type.getTypePtr());
                 if (tag_type)
                 {
-                    clang::TagDecl *tag_decl = tag_type->getDecl();
+                    TagDecl *tag_decl = tag_type->getDecl();
                     if (tag_decl)
                         tag_decl->print(llvm_ostrm, 0);
                 }
@@ -1530,49 +6154,27 @@
 }
 
 bool
-ClangASTType::GetValueAsScalar
-(
-    const lldb_private::DataExtractor &data,
-    lldb::offset_t data_byte_offset,
-    size_t data_byte_size,
-    Scalar &value
-)
+ClangASTType::GetValueAsScalar (const lldb_private::DataExtractor &data,
+                                lldb::offset_t data_byte_offset,
+                                size_t data_byte_size,
+                                Scalar &value) const
 {
-    return GetValueAsScalar (m_ast, 
-                             m_type, 
-                             data, 
-                             data_byte_offset, 
-                             data_byte_size, 
-                             value);
-}
+    if (!IsValid())
+        return false;
 
-bool
-ClangASTType::GetValueAsScalar
-(
-    clang::ASTContext *ast_context,
-    clang_type_t clang_type,
-    const lldb_private::DataExtractor &data,
-    lldb::offset_t data_byte_offset,
-    size_t data_byte_size,
-    Scalar &value
-)
-{
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-
-    if (ClangASTContext::IsAggregateType (clang_type))
+    if (IsAggregateType ())
     {
         return false;   // Aggregate types don't have scalar values
     }
     else
     {
         uint64_t count = 0;
-        lldb::Encoding encoding = GetEncoding (clang_type, count);
+        lldb::Encoding encoding = GetEncoding (count);
 
         if (encoding == lldb::eEncodingInvalid || count != 1)
             return false;
 
-        uint64_t bit_width = ast_context->getTypeSize(qual_type);
-        uint64_t byte_size = (bit_width + 7 ) / 8;
+        const uint64_t byte_size = GetByteSize();
         lldb::offset_t offset = data_byte_offset;
         switch (encoding)
         {
@@ -1690,31 +6292,17 @@
 bool
 ClangASTType::SetValueFromScalar (const Scalar &value, Stream &strm)
 {
-    return SetValueFromScalar (m_ast, m_type, value, strm);
-}
-
-bool
-ClangASTType::SetValueFromScalar
-(
-    clang::ASTContext *ast_context,
-    clang_type_t clang_type,
-    const Scalar &value,
-    Stream &strm
-)
-{
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-
     // Aggregate types don't have scalar values
-    if (!ClangASTContext::IsAggregateType (clang_type))
+    if (!IsAggregateType ())
     {
         strm.GetFlags().Set(Stream::eBinary);
         uint64_t count = 0;
-        lldb::Encoding encoding = GetEncoding (clang_type, count);
+        lldb::Encoding encoding = GetEncoding (count);
 
         if (encoding == lldb::eEncodingInvalid || count != 1)
             return false;
 
-        const uint64_t bit_width = ast_context->getTypeSize(qual_type);
+        const uint64_t bit_width = GetBitSize();
         // This function doesn't currently handle non-byte aligned assignments
         if ((bit_width % 8) != 0)
             return false;
@@ -1783,66 +6371,24 @@
                               AddressType address_type,
                               lldb_private::DataExtractor &data)
 {
-    return ReadFromMemory (m_ast,
-                           m_type,
-                           exe_ctx, 
-                           addr,
-                           address_type,
-                           data);
-}
+    if (!IsValid())
+        return false;
 
-uint64_t
-ClangASTType::GetTypeByteSize() const
-{
-    return GetTypeByteSize (m_ast, m_type);
-}
-
-uint64_t
-ClangASTType::GetTypeByteSize(clang::ASTContext *ast_context, lldb::clang_type_t opaque_clang_qual_type)
-{
-    
-    if (ClangASTContext::GetCompleteType (ast_context, opaque_clang_qual_type))
-    {
-        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
-        
-        uint64_t byte_size = (ast_context->getTypeSize (qual_type) + (uint64_t)7) / (uint64_t)8;
-        
-        if (ClangASTContext::IsObjCClassType(opaque_clang_qual_type))
-            byte_size += ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / 8; // isa
-        
-        return byte_size;
-    }
-    return 0;
-}
-
-
-bool
-ClangASTType::ReadFromMemory (clang::ASTContext *ast_context,
-                              clang_type_t clang_type,
-                              lldb_private::ExecutionContext *exe_ctx,
-                              lldb::addr_t addr,
-                              AddressType address_type,
-                              lldb_private::DataExtractor &data)
-{
+    // Can't convert a file address to anything valid without more
+    // context (which Module it came from)
     if (address_type == eAddressTypeFile)
-    {
-        // Can't convert a file address to anything valid without more
-        // context (which Module it came from)
-        return false;
-    }
-    
-    if (!ClangASTContext::GetCompleteType(ast_context, clang_type))
         return false;
     
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+    if (!GetCompleteType())
+        return false;
     
-    const uint64_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
+    const uint64_t byte_size = GetByteSize();
     if (data.GetByteSize() < byte_size)
     {
         lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
         data.SetData(data_sp);
     }
-
+    
     uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size);
     if (dst != NULL)
     {
@@ -1870,41 +6416,23 @@
 }
 
 bool
-ClangASTType::WriteToMemory
-(
-    lldb_private::ExecutionContext *exe_ctx,
-    lldb::addr_t addr,
-    AddressType address_type,
-    StreamString &new_value
-)
+ClangASTType::WriteToMemory (lldb_private::ExecutionContext *exe_ctx,
+                             lldb::addr_t addr,
+                             AddressType address_type,
+                             StreamString &new_value)
 {
-    return WriteToMemory (m_ast,
-                          m_type,
-                          exe_ctx,
-                          addr,
-                          address_type,
-                          new_value);
-}
-
-bool
-ClangASTType::WriteToMemory
-(
-    clang::ASTContext *ast_context,
-    clang_type_t clang_type,
-    lldb_private::ExecutionContext *exe_ctx,
-    lldb::addr_t addr,
-    AddressType address_type,
-    StreamString &new_value
-)
-{
-    if (address_type == eAddressTypeFile)
-    {
-        // Can't convert a file address to anything valid without more
-        // context (which Module it came from)
+    if (!IsValid())
         return false;
-    }
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-    const uint64_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
+
+    // Can't convert a file address to anything valid without more
+    // context (which Module it came from)
+    if (address_type == eAddressTypeFile)
+        return false;
+        
+    if (!GetCompleteType())
+        return false;
+
+    const uint64_t byte_size = GetByteSize();
 
     if (byte_size > 0)
     {
@@ -1930,21 +6458,13 @@
 }
 
 
-lldb::clang_type_t
-ClangASTType::RemoveFastQualifiers (lldb::clang_type_t clang_type)
-{
-    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-    qual_type.getQualifiers().removeFastQualifiers();
-    return qual_type.getAsOpaquePtr();
-}
-
-clang::CXXRecordDecl *
-ClangASTType::GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type)
-{
-    if (opaque_clang_qual_type)
-        return clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)->getAsCXXRecordDecl();
-    return NULL;
-}
+//CXXRecordDecl *
+//ClangASTType::GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type)
+//{
+//    if (opaque_clang_qual_type)
+//        return QualType::getFromOpaquePtr(opaque_clang_qual_type)->getAsCXXRecordDecl();
+//    return NULL;
+//}
 
 bool
 lldb_private::operator == (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs)
@@ -1959,190 +6479,4 @@
     return lhs.GetASTContext() != rhs.GetASTContext() || lhs.GetOpaqueQualType() != rhs.GetOpaqueQualType();
 }
 
-lldb::BasicType
-ClangASTType::GetBasicTypeEnumeration (const ConstString &name)
-{
-    if (name)
-    {
-        typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
-        static TypeNameToBasicTypeMap g_type_map;
-        static std::once_flag g_once_flag;
-        std::call_once(g_once_flag, [](){
-            // "void"
-            g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid);
-            
-            // "char"
-            g_type_map.Append(ConstString("char").GetCString(), eBasicTypeChar);
-            g_type_map.Append(ConstString("signed char").GetCString(), eBasicTypeSignedChar);
-            g_type_map.Append(ConstString("unsigned char").GetCString(), eBasicTypeUnsignedChar);
-            g_type_map.Append(ConstString("wchar_t").GetCString(), eBasicTypeWChar);
-            g_type_map.Append(ConstString("signed wchar_t").GetCString(), eBasicTypeSignedWChar);
-            g_type_map.Append(ConstString("unsigned wchar_t").GetCString(), eBasicTypeUnsignedWChar);
-            // "short"
-            g_type_map.Append(ConstString("short").GetCString(), eBasicTypeShort);
-            g_type_map.Append(ConstString("short int").GetCString(), eBasicTypeShort);
-            g_type_map.Append(ConstString("unsigned short").GetCString(), eBasicTypeUnsignedShort);
-            g_type_map.Append(ConstString("unsigned short int").GetCString(), eBasicTypeUnsignedShort);
-            
-            // "int"
-            g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt);
-            g_type_map.Append(ConstString("signed int").GetCString(), eBasicTypeInt);
-            g_type_map.Append(ConstString("unsigned int").GetCString(), eBasicTypeUnsignedInt);
-            g_type_map.Append(ConstString("unsigned").GetCString(), eBasicTypeUnsignedInt);
-            
-            // "long"
-            g_type_map.Append(ConstString("long").GetCString(), eBasicTypeLong);
-            g_type_map.Append(ConstString("long int").GetCString(), eBasicTypeLong);
-            g_type_map.Append(ConstString("unsigned long").GetCString(), eBasicTypeUnsignedLong);
-            g_type_map.Append(ConstString("unsigned long int").GetCString(), eBasicTypeUnsignedLong);
-            
-            // "long long"
-            g_type_map.Append(ConstString("long long").GetCString(), eBasicTypeLongLong);
-            g_type_map.Append(ConstString("long long int").GetCString(), eBasicTypeLongLong);
-            g_type_map.Append(ConstString("unsigned long long").GetCString(), eBasicTypeUnsignedLongLong);
-            g_type_map.Append(ConstString("unsigned long long int").GetCString(), eBasicTypeUnsignedLongLong);
-
-            // "int128"
-            g_type_map.Append(ConstString("__int128_t").GetCString(), eBasicTypeInt128);
-            g_type_map.Append(ConstString("__uint128_t").GetCString(), eBasicTypeUnsignedInt128);
-            
-            // Miscelaneous
-            g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool);
-            g_type_map.Append(ConstString("float").GetCString(), eBasicTypeFloat);
-            g_type_map.Append(ConstString("double").GetCString(), eBasicTypeDouble);
-            g_type_map.Append(ConstString("long double").GetCString(), eBasicTypeLongDouble);
-            g_type_map.Append(ConstString("id").GetCString(), eBasicTypeObjCID);
-            g_type_map.Append(ConstString("SEL").GetCString(), eBasicTypeObjCSel);
-            g_type_map.Append(ConstString("nullptr").GetCString(), eBasicTypeNullPtr);
-            g_type_map.Sort();
-        });
-
-        return g_type_map.Find(name.GetCString(), eBasicTypeInvalid);
-    }
-    return eBasicTypeInvalid;
-}
-
-ClangASTType
-ClangASTType::GetBasicType (clang::ASTContext *ast, const ConstString &name)
-{
-    if (ast)
-    {
-        lldb::BasicType basic_type = ClangASTType::GetBasicTypeEnumeration (name);
-        return ClangASTType::GetBasicType (ast, basic_type);
-    }
-    return ClangASTType();
-}
-
-ClangASTType
-ClangASTType::GetBasicType (clang::ASTContext *ast, lldb::BasicType type)
-{
-    if (ast)
-    {
-        clang_type_t clang_type = NULL;
-        
-        switch (type)
-        {
-            case eBasicTypeInvalid:
-            case eBasicTypeOther:
-                break;
-            case eBasicTypeVoid:
-                clang_type = ast->VoidTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeChar:
-                clang_type = ast->CharTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeSignedChar:
-                clang_type = ast->SignedCharTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeUnsignedChar:
-                clang_type = ast->UnsignedCharTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeWChar:
-                clang_type = ast->getWCharType().getAsOpaquePtr();
-                break;
-            case eBasicTypeSignedWChar:
-                clang_type = ast->getSignedWCharType().getAsOpaquePtr();
-                break;
-            case eBasicTypeUnsignedWChar:
-                clang_type = ast->getUnsignedWCharType().getAsOpaquePtr();
-                break;
-            case eBasicTypeChar16:
-                clang_type = ast->Char16Ty.getAsOpaquePtr();
-                break;
-            case eBasicTypeChar32:
-                clang_type = ast->Char32Ty.getAsOpaquePtr();
-                break;
-            case eBasicTypeShort:
-                clang_type = ast->ShortTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeUnsignedShort:
-                clang_type = ast->UnsignedShortTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeInt:
-                clang_type = ast->IntTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeUnsignedInt:
-                clang_type = ast->UnsignedIntTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeLong:
-                clang_type = ast->LongTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeUnsignedLong:
-                clang_type = ast->UnsignedLongTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeLongLong:
-                clang_type = ast->LongLongTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeUnsignedLongLong:
-                clang_type = ast->UnsignedLongLongTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeInt128:
-                clang_type = ast->Int128Ty.getAsOpaquePtr();
-                break;
-            case eBasicTypeUnsignedInt128:
-                clang_type = ast->UnsignedInt128Ty.getAsOpaquePtr();
-                break;
-            case eBasicTypeBool:
-                clang_type = ast->BoolTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeHalf:
-                clang_type = ast->HalfTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeFloat:
-                clang_type = ast->FloatTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeDouble:
-                clang_type = ast->DoubleTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeLongDouble:
-                clang_type = ast->LongDoubleTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeFloatComplex:
-                clang_type = ast->FloatComplexTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeDoubleComplex:
-                clang_type = ast->DoubleComplexTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeLongDoubleComplex:
-                clang_type = ast->LongDoubleComplexTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeObjCID:
-                clang_type = ast->ObjCBuiltinIdTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeObjCClass:
-                clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeObjCSel:
-                clang_type = ast->ObjCBuiltinSelTy.getAsOpaquePtr();
-                break;
-            case eBasicTypeNullPtr:
-                clang_type = ast->NullPtrTy.getAsOpaquePtr();
-                break;
-        }
-        
-        if (clang_type)
-            return ClangASTType (ast, clang_type);
-    }
-    return ClangASTType();
-}
 
diff --git a/source/Symbol/Function.cpp b/source/Symbol/Function.cpp
index 594cb39..31334a6 100644
--- a/source/Symbol/Function.cpp
+++ b/source/Symbol/Function.cpp
@@ -12,13 +12,10 @@
 #include "lldb/Core/Section.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Symbol/ClangASTType.h"
-#include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/SymbolVendor.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/CanonicalType.h"
 #include "llvm/Support/Casting.h"
 
 using namespace lldb;
@@ -484,64 +481,13 @@
     return m_type;
 }
 
-clang_type_t
-Function::GetReturnClangType ()
+ClangASTType
+Function::GetClangType()
 {
-    Type *type = GetType();
-    if (type)
-    {
-        clang::QualType clang_type (clang::QualType::getFromOpaquePtr(type->GetClangFullType()));
-        const clang::FunctionType *function_type = llvm::dyn_cast<clang::FunctionType> (clang_type);
-        if (function_type)
-            return function_type->getResultType().getAsOpaquePtr();
-    }
-    return NULL;
-}
-
-int
-Function::GetArgumentCount ()
-{
-    clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetClangFullType()));
-    assert (clang_type->isFunctionType());
-    if (!clang_type->isFunctionProtoType())
-        return -1;
-
-    const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(clang_type);
-    if (function_proto_type != NULL)
-        return function_proto_type->getNumArgs();
-
-    return 0;
-}
-
-clang_type_t
-Function::GetArgumentTypeAtIndex (size_t idx)
-{
-    clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetClangFullType()));
-    const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(clang_type);
-    if (function_proto_type)
-    {
-        unsigned num_args = function_proto_type->getNumArgs();
-        if (idx >= num_args)
-            return NULL;
-        
-        return (function_proto_type->arg_type_begin())[idx].getAsOpaquePtr();
-    }
-    return NULL;
-}
-
-bool
-Function::IsVariadic ()
-{
-   const clang::Type *clang_type = static_cast<clang::QualType *>(GetType()->GetClangFullType())->getTypePtr();
-   assert (clang_type->isFunctionType());
-   if (!clang_type->isFunctionProtoType())
-        return false;
-
-    const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(clang_type);
-    if (function_proto_type)
-        return function_proto_type->isVariadic();
-
-    return false;
+    Type *function_type = GetType();
+    if (function_type)
+        return function_type->GetClangFullType();
+    return ClangASTType();
 }
 
 uint32_t
diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp
index 0646a40..0af2359 100644
--- a/source/Symbol/Type.cpp
+++ b/source/Symbol/Type.cpp
@@ -83,7 +83,7 @@
     user_id_t encoding_uid,
     EncodingDataType encoding_uid_type,
     const Declaration& decl,
-    clang_type_t clang_type,
+    const ClangASTType &clang_type,
     ResolveState clang_type_resolve_state
 ) :
     std::enable_shared_from_this<Type> (),
@@ -113,7 +113,7 @@
     m_encoding_uid_type (eEncodingInvalid),
     m_byte_size (0),
     m_decl (),
-    m_clang_type (NULL)
+    m_clang_type ()
 {
     m_flags.clang_type_resolve_state = eResolveStateUnresolved;
     m_flags.is_complete_objc_class = false;
@@ -172,10 +172,10 @@
     bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose);
     m_decl.Dump(s, show_fullpaths);
 
-    if (m_clang_type)
+    if (m_clang_type.IsValid())
     {
         *s << ", clang_type = \"";
-        ClangASTType::DumpTypeDescription (GetClangAST(), m_clang_type, s);
+        GetClangForwardType().DumpTypeDescription(s);
         *s << '"';
     }
     else if (m_encoding_uid != LLDB_INVALID_UID)
@@ -220,11 +220,10 @@
     bool show_fullpaths = false;
     m_decl.Dump (s,show_fullpaths);
 
-    if (m_clang_type)
+    if (m_clang_type.IsValid())
     {
-        *s << ", clang_type = " << m_clang_type << ' ';
-
-        ClangASTType::DumpTypeDescription (GetClangAST(), m_clang_type, s);
+        *s << ", clang_type = " << m_clang_type.GetOpaqueQualType() << ' ';
+        GetClangForwardType().DumpTypeDescription (s);
     }
     else if (m_encoding_uid != LLDB_INVALID_UID)
     {
@@ -254,10 +253,7 @@
 Type::GetName()
 {
     if (!m_name)
-    {
-        if (ResolveClangType(eResolveStateForward))
-            m_name = ClangASTType::GetConstTypeName (GetClangASTContext ().getASTContext(), m_clang_type);
-    }
+        m_name = GetClangForwardType().GetConstTypeName();
     return m_name;
 }
 
@@ -292,20 +288,18 @@
             s->PutCString(") ");
         }
 
-        ClangASTType::DumpValue (GetClangAST (),
-                                               m_clang_type,
-                                               exe_ctx,
-                                               s,
-                                               format == lldb::eFormatDefault ? GetFormat() : format,
-                                               data,
-                                               data_byte_offset,
-                                               GetByteSize(),
-                                               0, // Bitfield bit size
-                                               0, // Bitfield bit offset
-                                               show_types,
-                                               show_summary,
-                                               verbose,
-                                               0);
+        GetClangForwardType().DumpValue (exe_ctx,
+                                         s,
+                                         format == lldb::eFormatDefault ? GetFormat() : format,
+                                         data,
+                                         data_byte_offset,
+                                         GetByteSize(),
+                                         0, // Bitfield bit size
+                                         0, // Bitfield bit offset
+                                         show_types,
+                                         show_summary,
+                                         verbose,
+                                         0);
     }
 }
 
@@ -339,10 +333,7 @@
                 if (encoding_type)
                     m_byte_size = encoding_type->GetByteSize();
                 if (m_byte_size == 0)
-                {
-                    uint32_t bit_width = ClangASTType::GetClangTypeBitWidth (GetClangAST(), GetClangLayoutType());
-                    m_byte_size = (bit_width + 7 ) / 8;
-                }
+                    m_byte_size = GetClangLayoutType().GetByteSize();
             }
             break;
 
@@ -350,7 +341,7 @@
         case eEncodingIsPointerUID:
         case eEncodingIsLValueReferenceUID:
         case eEncodingIsRValueReferenceUID:
-            m_byte_size = m_symbol_file->GetClangASTContext().GetPointerBitSize() / 8;
+            m_byte_size = m_symbol_file->GetClangASTContext().GetPointerByteSize();
             break;
         }
     }
@@ -361,21 +352,13 @@
 uint32_t
 Type::GetNumChildren (bool omit_empty_base_classes)
 {
-    if (ResolveClangType(eResolveStateForward))
-    {
-        return ClangASTContext::GetNumChildren (m_symbol_file->GetClangASTContext().getASTContext(),
-                                                m_clang_type, 
-                                                omit_empty_base_classes);
-    }
-    return 0;
+    return GetClangForwardType().GetNumChildren(omit_empty_base_classes);
 }
 
 bool
 Type::IsAggregateType ()
 {
-    if (ResolveClangType(eResolveStateForward))
-        return ClangASTContext::IsAggregateType (m_clang_type);
-    return false;
+    return GetClangForwardType().IsAggregateType();
 }
 
 lldb::TypeSP
@@ -396,10 +379,7 @@
 lldb::Format
 Type::GetFormat ()
 {
-    // Make sure we resolve our type if it already hasn't been.
-    if (!ResolveClangType(eResolveStateForward))
-        return lldb::eFormatInvalid;
-    return ClangASTType::GetFormat (m_clang_type);
+    return GetClangForwardType().GetFormat();
 }
 
 
@@ -408,14 +388,9 @@
 Type::GetEncoding (uint64_t &count)
 {
     // Make sure we resolve our type if it already hasn't been.
-    if (!ResolveClangType(eResolveStateForward))
-        return lldb::eEncodingInvalid;
-
-    return ClangASTType::GetEncoding (m_clang_type, count);
+    return GetClangForwardType().GetEncoding(count);
 }
 
-
-
 bool
 Type::DumpValueInMemory
 (
@@ -514,7 +489,7 @@
 Type::ResolveClangType (ResolveState clang_type_resolve_state)
 {
     Type *encoding_type = NULL;
-    if (m_clang_type == NULL)
+    if (!m_clang_type.IsValid())
     {
         encoding_type = GetEncodingType();
         if (encoding_type)
@@ -522,42 +497,44 @@
             switch (m_encoding_uid_type)
             {
             case eEncodingIsUID:
-                if (encoding_type->ResolveClangType(clang_type_resolve_state))
                 {
-                    m_clang_type = encoding_type->m_clang_type;
-                    m_flags.clang_type_resolve_state = encoding_type->m_flags.clang_type_resolve_state;
+                    ClangASTType encoding_clang_type = encoding_type->GetClangForwardType();
+                    if (encoding_clang_type.IsValid())
+                    {
+                        m_clang_type = encoding_clang_type;
+                        m_flags.clang_type_resolve_state = encoding_type->m_flags.clang_type_resolve_state;
+                    }
                 }
                 break;
 
             case eEncodingIsConstUID:
-                m_clang_type = ClangASTContext::AddConstModifier (encoding_type->GetClangForwardType());
+                m_clang_type = encoding_type->GetClangForwardType().AddConstModifier();
                 break;
 
             case eEncodingIsRestrictUID:
-                m_clang_type = ClangASTContext::AddRestrictModifier (encoding_type->GetClangForwardType());
+                m_clang_type = encoding_type->GetClangForwardType().AddRestrictModifier();
                 break;
 
             case eEncodingIsVolatileUID:
-                m_clang_type = ClangASTContext::AddVolatileModifier (encoding_type->GetClangForwardType());
+                m_clang_type = encoding_type->GetClangForwardType().AddVolatileModifier();
                 break;
 
             case eEncodingIsTypedefUID:
-                m_clang_type = CreateClangTypedefType (this, encoding_type);
-                // Clear the name so it can get fully qualified in case the
-                // typedef is in a namespace.
+                m_clang_type = encoding_type->GetClangForwardType().CreateTypedefType (GetName().AsCString(),
+                                                                                       GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID()));
                 m_name.Clear();
                 break;
 
             case eEncodingIsPointerUID:
-                m_clang_type = CreateClangPointerType (encoding_type);
+                m_clang_type = encoding_type->GetClangForwardType().GetPointerType();
                 break;
 
             case eEncodingIsLValueReferenceUID:
-                m_clang_type = CreateClangLValueReferenceType (encoding_type);
+                m_clang_type = encoding_type->GetClangForwardType().GetLValueReferenceType();
                 break;
 
             case eEncodingIsRValueReferenceUID:
-                m_clang_type = CreateClangRValueReferenceType (encoding_type);
+                m_clang_type = encoding_type->GetClangForwardType().GetRValueReferenceType();
                 break;
 
             default:
@@ -568,7 +545,7 @@
         else
         {
             // We have no encoding type, return void?
-            clang_type_t void_clang_type = GetClangASTContext().GetBuiltInType_void();
+            ClangASTType void_clang_type (ClangASTContext::GetBasicType(GetClangASTContext().getASTContext(), eBasicTypeVoid));
             switch (m_encoding_uid_type)
             {
             case eEncodingIsUID:
@@ -576,31 +553,32 @@
                 break;
 
             case eEncodingIsConstUID:
-                m_clang_type = ClangASTContext::AddConstModifier (void_clang_type);
+                m_clang_type = void_clang_type.AddConstModifier ();
                 break;
 
             case eEncodingIsRestrictUID:
-                m_clang_type = ClangASTContext::AddRestrictModifier (void_clang_type);
+                m_clang_type = void_clang_type.AddRestrictModifier ();
                 break;
 
             case eEncodingIsVolatileUID:
-                m_clang_type = ClangASTContext::AddVolatileModifier (void_clang_type);
+                m_clang_type = void_clang_type.AddVolatileModifier ();
                 break;
 
             case eEncodingIsTypedefUID:
-                m_clang_type = GetClangASTContext().CreateTypedefType (m_name.AsCString(), void_clang_type, NULL);
+                m_clang_type = void_clang_type.CreateTypedefType (GetName().AsCString(),
+                                                                  GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID()));
                 break;
 
             case eEncodingIsPointerUID:
-                m_clang_type = GetClangASTContext().CreatePointerType (void_clang_type);
+                m_clang_type = void_clang_type.GetPointerType ();
                 break;
 
             case eEncodingIsLValueReferenceUID:
-                m_clang_type = GetClangASTContext().CreateLValueReferenceType (void_clang_type);
+                m_clang_type = void_clang_type.GetLValueReferenceType ();
                 break;
 
             case eEncodingIsRValueReferenceUID:
-                m_clang_type = GetClangASTContext().CreateRValueReferenceType (void_clang_type);
+                m_clang_type = void_clang_type.GetRValueReferenceType ();
                 break;
 
             default:
@@ -611,13 +589,12 @@
     }
     
     // Check if we have a forward reference to a class/struct/union/enum?
-    if (m_clang_type && m_flags.clang_type_resolve_state < clang_type_resolve_state)
+    if (m_clang_type.IsValid() && m_flags.clang_type_resolve_state < clang_type_resolve_state)
     {
         m_flags.clang_type_resolve_state = eResolveStateFull;
-        if (!ClangASTType::IsDefined (m_clang_type))
+        if (!m_clang_type.IsDefined ())
         {
-            // We have a forward declaration, we need to resolve it to a complete
-            // definition.
+            // We have a forward declaration, we need to resolve it to a complete definition.
             m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type);
         }
     }
@@ -648,7 +625,7 @@
             encoding_type->ResolveClangType (encoding_clang_type_resolve_state);
         }
     }
-    return m_clang_type != NULL;
+    return m_clang_type.IsValid();
 }
 uint32_t
 Type::GetEncodingMask ()
@@ -661,33 +638,27 @@
     return encoding_mask;
 }
 
-clang_type_t 
+ClangASTType
 Type::GetClangFullType ()
 {
     ResolveClangType(eResolveStateFull);
     return m_clang_type;
 }
 
-clang_type_t 
+ClangASTType
 Type::GetClangLayoutType ()
 {
     ResolveClangType(eResolveStateLayout);
     return m_clang_type;
 }
 
-clang_type_t 
+ClangASTType 
 Type::GetClangForwardType ()
 {
     ResolveClangType (eResolveStateForward);
     return m_clang_type;
 }
 
-clang::ASTContext *
-Type::GetClangAST ()
-{
-    return GetClangASTContext().getASTContext();
-}
-
 ClangASTContext &
 Type::GetClangASTContext ()
 {
@@ -710,6 +681,8 @@
 }
 
 
+#if 0  // START REMOVE
+// Move this into ClangASTType
 void *
 Type::CreateClangPointerType (Type *type)
 {
@@ -739,6 +712,7 @@
     assert(type);
     return GetClangASTContext().CreateRValueReferenceType (type->GetClangForwardType());
 }
+#endif // END REMOVE
 
 bool
 Type::IsRealObjCClass()
@@ -747,7 +721,7 @@
     // those don't have any information.  We could extend this to only return true for "full 
     // definitions" if we can figure that out.
     
-    if (ClangASTContext::IsObjCClassType(m_clang_type) && GetByteSize() != 0)
+    if (m_clang_type.IsObjCObjectOrInterfaceType() && GetByteSize() != 0)
         return true;
     else
         return false;
@@ -756,8 +730,7 @@
 ConstString
 Type::GetQualifiedName ()
 {
-    ConstString qualified_name (ClangASTType::GetTypeNameForOpaqueQualType (GetClangASTContext ().getASTContext(), GetClangForwardType()).c_str());
-    return qualified_name;
+    return GetClangForwardType().GetConstTypeName();
 }
 
 
@@ -938,12 +911,13 @@
 }
 
 TypeImpl::TypeImpl(const lldb_private::ClangASTType& clang_ast_type) :
-    m_clang_ast_type(clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType()),
+    m_clang_ast_type(clang_ast_type),
     m_type_sp()
-{}
+{
+}
 
 TypeImpl::TypeImpl(const lldb::TypeSP& type) :
-    m_clang_ast_type(type->GetClangAST(), type->GetClangFullType()),
+    m_clang_ast_type(type->GetClangForwardType()),
     m_type_sp(type)
 {
 }
@@ -953,7 +927,7 @@
 {
     if (type_sp)
     {
-        m_clang_ast_type.SetClangType (type_sp->GetClangAST(), type_sp->GetClangFullType());
+        m_clang_ast_type = type_sp->GetClangForwardType();
         m_type_sp = type_sp;
     }
     else
@@ -998,9 +972,7 @@
 {
     if (m_clang_ast_type.IsValid())
     {
-        ClangASTType::DumpTypeDescription (m_clang_ast_type.GetASTContext(), 
-                                           m_clang_ast_type.GetOpaqueQualType(), 
-                                           &strm);
+        m_clang_ast_type.DumpTypeDescription (&strm);
     }
     else
     {
@@ -1013,6 +985,6 @@
 TypeImpl::GetName ()
 {
     if (m_clang_ast_type.IsValid())
-        return m_clang_ast_type.GetConstQualifiedTypeName();
+        return m_clang_ast_type.GetConstTypeName();
     return ConstString();
 }
diff --git a/source/Symbol/TypeHierarchyNavigator.cpp b/source/Symbol/TypeHierarchyNavigator.cpp
deleted file mode 100644
index e046204..0000000
--- a/source/Symbol/TypeHierarchyNavigator.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-//===-- TypeHierarchyNavigator.cpp -----------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/ASTContext.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/ValueObject.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/TypeHierarchyNavigator.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-bool
-TypeHierarchyNavigator::LoopThrough(TypeHierarchyNavigatorCallback callback,
-                                    void* callback_baton)
-{
-    return LoopThrough(m_root_type,
-                callback,
-                eRootType,
-                (callback_baton ? callback_baton : m_default_callback_baton));
-}
-
-bool
-TypeHierarchyNavigator::LoopThrough(const clang::QualType& qual_type,
-                                    TypeHierarchyNavigatorCallback callback,
-                                    RelationshipToCurrentType reason_why_here,
-                                    void* callback_baton)
-{
-    if (qual_type.isNull())
-        return true;
-    clang::QualType type = qual_type.getUnqualifiedType();
-    type.removeLocalConst(); type.removeLocalVolatile(); type.removeLocalRestrict();
-    const clang::Type* typePtr = type.getTypePtrOrNull();
-    if (!typePtr)
-        return true;
-    if (!callback(type, reason_why_here, callback_baton))
-        return false;
-    // look for a "base type", whatever that means
-    if (typePtr->isReferenceType())
-    {
-        if (LoopThrough(type.getNonReferenceType(), callback, eStrippedReference, callback_baton) == false)
-            return false;
-    }
-    if (typePtr->isPointerType())
-    {
-        if (LoopThrough(typePtr->getPointeeType(), callback, eStrippedPointer, callback_baton) == false)
-            return false;
-    }
-    if (typePtr->isObjCObjectPointerType())
-    {
-        /*
-         for some reason, C++ can quite easily obtain the type hierarchy for a ValueObject
-         even if the VO represent a pointer-to-class, as long as the typePtr is right
-         Objective-C on the other hand cannot really complete an @interface when
-         the VO refers to a pointer-to-@interface
-         */
-        Error error;
-        ValueObject* target = m_value_object.Dereference(error).get();
-        if (error.Fail() || !target)
-            return true;
-        if (LoopThrough(typePtr->getPointeeType(), callback, eStrippedPointer, callback_baton) == false)
-            return false;
-    }
-    const clang::ObjCObjectType *objc_class_type = typePtr->getAs<clang::ObjCObjectType>();
-    if (objc_class_type)
-    {
-        clang::ASTContext *ast = m_value_object.GetClangAST();
-        if (ClangASTContext::GetCompleteType(ast, m_value_object.GetClangType()) && !objc_class_type->isObjCId())
-        {
-            clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-            if (class_interface_decl)
-            {
-                clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
-                if (superclass_interface_decl)
-                {
-                    clang::QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
-                    return LoopThrough(ivar_qual_type, callback, eObjCBaseClass, callback_baton);
-                }
-            }
-        }
-    }
-    // for C++ classes, navigate up the hierarchy
-    if (typePtr->isRecordType())
-    {
-        clang::CXXRecordDecl* record = typePtr->getAsCXXRecordDecl();
-        if (record)
-        {
-            if (!record->hasDefinition())
-                ClangASTContext::GetCompleteType(m_value_object.GetClangAST(), m_value_object.GetClangType());
-            if (record->hasDefinition())
-            {
-                clang::CXXRecordDecl::base_class_iterator pos,end;
-                if ( record->getNumBases() > 0)
-                {
-                    end = record->bases_end();
-                    for (pos = record->bases_begin(); pos != end; pos++)
-                        if (LoopThrough(pos->getType(), callback, eCXXBaseClass, callback_baton) == false)
-                            return false;
-                }
-                if (record->getNumVBases() > 0)
-                {
-                    end = record->vbases_end();
-                    for (pos = record->vbases_begin(); pos != end; pos++)
-                        if (LoopThrough(pos->getType(), callback, eCXXVBaseClass, callback_baton) == false)
-                            return false;
-                }
-            }
-        }
-    }
-    // try to strip typedef chains
-    const clang::TypedefType* type_tdef = type->getAs<clang::TypedefType>();
-    if (type_tdef)
-        return LoopThrough(type_tdef->getDecl()->getUnderlyingType(), callback, eStrippedTypedef, callback_baton);
-    else
-        return true;
-}
diff --git a/source/Symbol/TypeList.cpp b/source/Symbol/TypeList.cpp
index df0723e..a033edd 100644
--- a/source/Symbol/TypeList.cpp
+++ b/source/Symbol/TypeList.cpp
@@ -259,8 +259,7 @@
 
         if (type_class != eTypeClassAny)
         {
-            match_type_class = ClangASTType::GetTypeClass (the_type->GetClangAST(),
-                                                           the_type->GetClangForwardType());
+            match_type_class = the_type->GetClangForwardType().GetTypeClass ();
             if ((match_type_class & type_class) == 0)
                 continue;
         }
@@ -349,43 +348,9 @@
     for (pos = m_types.begin(); pos != end; ++pos)
     {
         Type* the_type = pos->second.get();
-        TypeClass match_type_class = ClangASTType::GetTypeClass (the_type->GetClangAST(),
-                                                                 the_type->GetClangForwardType());
+        TypeClass match_type_class = the_type->GetClangForwardType().GetTypeClass ();
         if (match_type_class & type_class)
             matching_types.insert (*pos);
     }
     m_types.swap(matching_types);
 }
-
-//void *
-//TypeList::CreateClangPointerType (Type *type)
-//{
-//    assert(type);
-//    return m_ast.CreatePointerType(type->GetClangForwardType());
-//}
-//
-//void *
-//TypeList::CreateClangTypedefType (Type *typedef_type, Type *base_type)
-//{
-//    assert(typedef_type && base_type);
-//    return m_ast.CreateTypedefType (typedef_type->GetName().AsCString(), 
-//                                    base_type->GetClangForwardType(), 
-//                                    typedef_type->GetSymbolFile()->GetClangDeclContextForTypeUID(typedef_type->GetID()));
-//}
-//
-//void *
-//TypeList::CreateClangLValueReferenceType (Type *type)
-//{
-//    assert(type);
-//    return m_ast.CreateLValueReferenceType(type->GetClangForwardType());
-//}
-//
-//void *
-//TypeList::CreateClangRValueReferenceType (Type *type)
-//{
-//    assert(type);
-//    return m_ast.CreateRValueReferenceType (type->GetClangForwardType());
-//}
-//
-
-
diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp
index bcbea2f..36439b5 100644
--- a/source/Symbol/Variable.cpp
+++ b/source/Symbol/Variable.cpp
@@ -547,18 +547,13 @@
 {
 
     // We are in a type parsing child members
-    const uint32_t num_bases = ClangASTContext::GetNumDirectBaseClasses(clang_type.GetASTContext(),
-                                                                        clang_type.GetOpaqueQualType());
+    const uint32_t num_bases = clang_type.GetNumDirectBaseClasses();
     
     if (num_bases > 0)
     {
         for (uint32_t i = 0; i < num_bases; ++i)
         {
-            ClangASTType base_class_type (clang_type.GetASTContext(),
-                                          ClangASTContext::GetDirectBaseClassAtIndex (clang_type.GetASTContext(),
-                                                                                      clang_type.GetOpaqueQualType(),
-                                                                                      i,
-                                                                                      NULL));
+            ClangASTType base_class_type (clang_type.GetDirectBaseClassAtIndex (i, NULL));
             
             PrivateAutoCompleteMembers (frame,
                                         partial_member_name,
@@ -570,18 +565,13 @@
         }
     }
 
-    const uint32_t num_vbases = ClangASTContext::GetNumVirtualBaseClasses(clang_type.GetASTContext(),
-                                                                          clang_type.GetOpaqueQualType());
+    const uint32_t num_vbases = clang_type.GetNumVirtualBaseClasses();
     
     if (num_vbases > 0)
     {
         for (uint32_t i = 0; i < num_vbases; ++i)
         {
-            ClangASTType vbase_class_type (clang_type.GetASTContext(),
-                                          ClangASTContext::GetVirtualBaseClassAtIndex(clang_type.GetASTContext(),
-                                                                                      clang_type.GetOpaqueQualType(),
-                                                                                      i,
-                                                                                      NULL));
+            ClangASTType vbase_class_type (clang_type.GetVirtualBaseClassAtIndex(i,NULL));
             
             PrivateAutoCompleteMembers (frame,
                                         partial_member_name,
@@ -594,8 +584,7 @@
     }
 
     // We are in a type parsing child members
-    const uint32_t num_fields = ClangASTContext::GetNumFields(clang_type.GetASTContext(),
-                                                              clang_type.GetOpaqueQualType());
+    const uint32_t num_fields = clang_type.GetNumFields();
     
     if (num_fields > 0)
     {
@@ -603,20 +592,13 @@
         {
             std::string member_name;
             
-            lldb::clang_type_t member_type = ClangASTContext::GetFieldAtIndex (clang_type.GetASTContext(),
-                                                                               clang_type.GetOpaqueQualType(),
-                                                                               i,
-                                                                               member_name,
-                                                                               NULL,
-                                                                               NULL,
-                                                                               NULL);
+            ClangASTType member_clang_type = clang_type.GetFieldAtIndex (i, member_name, NULL, NULL, NULL);
             
             if (partial_member_name.empty() ||
                 member_name.find(partial_member_name) == 0)
             {
                 if (member_name == partial_member_name)
                 {
-                    ClangASTType member_clang_type (clang_type.GetASTContext(), member_type);
                     PrivateAutoComplete (frame,
                                          partial_path,
                                          prefix_path + member_name, // Anything that has been resolved already will be in here
@@ -683,7 +665,7 @@
                 case eTypeClassPointer:
                     {
                         bool omit_empty_base_classes = true;
-                        if (ClangASTContext::GetNumChildren (clang_type.GetASTContext(), clang_type.GetPointeeType(), omit_empty_base_classes) > 0)
+                        if (clang_type.GetNumChildren (omit_empty_base_classes) > 0)
                             matches.AppendString (prefix_path + "->");
                         else
                         {
@@ -747,7 +729,7 @@
                 {
                     case lldb::eTypeClassPointer:
                         {
-                            ClangASTType pointee_type(clang_type.GetASTContext(), clang_type.GetPointeeType());
+                            ClangASTType pointee_type(clang_type.GetPointeeType());
                             if (partial_path[2])
                             {
                                 // If there is more after the "->", then search deeper
@@ -859,7 +841,7 @@
                                 Type *variable_type = variable->GetType();
                                 if (variable_type)
                                 {
-                                    ClangASTType variable_clang_type (variable_type->GetClangAST(), variable_type->GetClangForwardType());
+                                    ClangASTType variable_clang_type (variable_type->GetClangForwardType());
                                     PrivateAutoComplete (frame,
                                                          remaining_partial_path,
                                                          prefix_path + token, // Anything that has been resolved already will be in here
diff --git a/source/Target/ObjCLanguageRuntime.cpp b/source/Target/ObjCLanguageRuntime.cpp
index 1aeb725..64ddfcc 100644
--- a/source/Target/ObjCLanguageRuntime.cpp
+++ b/source/Target/ObjCLanguageRuntime.cpp
@@ -131,7 +131,7 @@
             {
                 TypeSP type_sp (types.GetTypeAtIndex(i));
                 
-                if (ClangASTContext::IsObjCClassType(type_sp->GetClangForwardType()))
+                if (type_sp->GetClangForwardType().IsObjCObjectOrInterfaceType())
                 {
                     if (type_sp->IsCompleteObjCClass())
                     {
@@ -532,7 +532,7 @@
     // if we get an invalid VO (which might still happen when playing around
     // with pointers returned by the expression parser, don't consider this
     // a valid ObjC object)
-    if (valobj.GetValue().GetContextType() != Value::eContextTypeInvalid)
+    if (valobj.GetClangType().IsValid())
     {
         addr_t isa_pointer = valobj.GetPointerValue();
         if (isa_pointer != LLDB_INVALID_ADDRESS)
diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp
index b0293be..3c4c43d 100644
--- a/source/Target/StackFrame.cpp
+++ b/source/Target/StackFrame.cpp
@@ -645,9 +645,9 @@
                         {
                             // Make sure we aren't trying to deref an objective
                             // C ivar if this is not allowed
-                            const uint32_t pointer_type_flags = ClangASTContext::GetTypeInfo (valobj_sp->GetClangType(), NULL, NULL);
-                            if ((pointer_type_flags & ClangASTContext::eTypeIsObjC) &&
-                                (pointer_type_flags & ClangASTContext::eTypeIsPointer))
+                            const uint32_t pointer_type_flags = valobj_sp->GetClangType().GetTypeInfo (NULL);
+                            if ((pointer_type_flags & ClangASTType::eTypeIsObjC) &&
+                                (pointer_type_flags & ClangASTType::eTypeIsPointer))
                             {
                                 // This was an objective C object pointer and 
                                 // it was requested we skip any fragile ivars
@@ -759,7 +759,7 @@
                             if (end && *end == ']'
                                 && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go
                             {
-                                if (ClangASTContext::IsPointerToScalarType(valobj_sp->GetClangType()) && deref)
+                                if (valobj_sp->GetClangType().IsPointerToScalarType() && deref)
                                 {
                                     // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr
                                     // and extract bit low out of it. reading array item low
@@ -777,7 +777,7 @@
                                     valobj_sp = temp;
                                     deref = false;
                                 }
-                                else if (ClangASTContext::IsArrayOfScalarType(valobj_sp->GetClangType()) && deref)
+                                else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref)
                                 {
                                     // what we have is *arr[low]. the most similar C++ syntax is to get arr[0]
                                     // (an operation that is equivalent to deref-ing arr)
@@ -802,9 +802,9 @@
                                 {
                                     bool is_objc_pointer = true;
                                     
-                                    if (ClangASTType::GetMinimumLanguage(valobj_sp->GetClangAST(), valobj_sp->GetClangType()) != eLanguageTypeObjC)
+                                    if (valobj_sp->GetClangType().GetMinimumLanguage() != eLanguageTypeObjC)
                                         is_objc_pointer = false;
-                                    else if (!ClangASTContext::IsPointerType(valobj_sp->GetClangType()))
+                                    else if (!valobj_sp->GetClangType().IsPointerType())
                                         is_objc_pointer = false;
 
                                     if (no_synth_child && is_objc_pointer)
@@ -861,7 +861,7 @@
                                         }
                                     }
                                 }
-                                else if (ClangASTContext::IsArrayType (valobj_sp->GetClangType(), NULL, NULL, &is_incomplete_array))
+                                else if (valobj_sp->GetClangType().IsArrayType (NULL, NULL, &is_incomplete_array))
                                 {
                                     // Pass false to dynamic_value here so we can tell the difference between
                                     // no dynamic value and no member of this type...
@@ -878,7 +878,7 @@
                                                                         var_expr_path_strm.GetString().c_str());
                                     }
                                 }
-                                else if (ClangASTContext::IsScalarType(valobj_sp->GetClangType()))
+                                else if (valobj_sp->GetClangType().IsScalarType())
                                 {
                                     // this is a bitfield asking to display just one bit
                                     child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true);
@@ -961,7 +961,7 @@
                                         final_index = temp;
                                     }
                                     
-                                    if (ClangASTContext::IsPointerToScalarType(valobj_sp->GetClangType()) && deref)
+                                    if (valobj_sp->GetClangType().IsPointerToScalarType() && deref)
                                     {
                                         // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr
                                         // and extract bits low thru high out of it. reading array items low thru high
@@ -979,7 +979,7 @@
                                         valobj_sp = temp;
                                         deref = false;
                                     }
-                                    else if (ClangASTContext::IsArrayOfScalarType(valobj_sp->GetClangType()) && deref)
+                                    else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref)
                                     {
                                         // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0]
                                         // (an operation that is equivalent to deref-ing arr)
@@ -1122,7 +1122,7 @@
             if (m_sc.function->GetFrameBaseExpression().IsLocationList())
                 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr());
 
-            if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false)
+            if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false)
             {
                 // We should really have an error if evaluate returns, but in case
                 // we don't, lets set the error to something at least.
@@ -1131,7 +1131,7 @@
             }
             else
             {
-                m_frame_base = expr_value.ResolveValue(&exe_ctx, NULL);
+                m_frame_base = expr_value.ResolveValue(&exe_ctx);
             }
         }
         else
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 508238d..12ec40f 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -1677,13 +1677,12 @@
             Type *function_type = sc.function->GetType();
             if (function_type)
             {
-                clang_type_t return_type = sc.function->GetReturnClangType();
+                ClangASTType return_type = sc.function->GetClangType().GetFunctionReturnType();
                 if (return_type)
                 {
-                    ClangASTType ast_type (function_type->GetClangAST(), return_type);
                     StreamString s;
-                    ast_type.DumpTypeDescription(&s);
-                    ValueObjectSP cast_value_sp = return_value_sp->Cast(ast_type);
+                    return_type.DumpTypeDescription(&s);
+                    ValueObjectSP cast_value_sp = return_value_sp->Cast(return_type);
                     if (cast_value_sp)
                     {
                         cast_value_sp->SetFormat(eFormatHex);
diff --git a/source/Target/ThreadPlanStepOut.cpp b/source/Target/ThreadPlanStepOut.cpp
index 71ccf80..ba52958 100644
--- a/source/Target/ThreadPlanStepOut.cpp
+++ b/source/Target/ThreadPlanStepOut.cpp
@@ -464,17 +464,12 @@
         
     if (m_immediate_step_from_function != NULL)
     {
-        Type *return_type = m_immediate_step_from_function->GetType();
-        lldb::clang_type_t return_clang_type = m_immediate_step_from_function->GetReturnClangType();
-        if (return_type && return_clang_type)
+        ClangASTType return_clang_type = m_immediate_step_from_function->GetClangType().GetFunctionReturnType();
+        if (return_clang_type)
         {
-            ClangASTType ast_type (return_type->GetClangAST(), return_clang_type);
-            
             lldb::ABISP abi_sp = m_thread.GetProcess()->GetABI();
             if (abi_sp)
-            {
-                m_return_valobj_sp = abi_sp->GetReturnValueObject(m_thread, ast_type);
-            }
+                m_return_valobj_sp = abi_sp->GetReturnValueObject(m_thread, return_clang_type);
         }
     }
 }
diff --git a/source/Target/ThreadPlanTracer.cpp b/source/Target/ThreadPlanTracer.cpp
index 7242b8e..af6cef7 100644
--- a/source/Target/ThreadPlanTracer.cpp
+++ b/source/Target/ThreadPlanTracer.cpp
@@ -136,8 +136,7 @@
         
             if (exe_module)
             {
-                m_intptr_type = TypeFromUser(exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, target_sp->GetArchitecture().GetAddressByteSize() * 8),
-                                             exe_module->GetClangASTContext().getASTContext());
+                m_intptr_type = TypeFromUser(exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, target_sp->GetArchitecture().GetAddressByteSize() * 8));
             }
         }        
     }
@@ -243,7 +242,8 @@
         {
             Value value;
             value.SetValueType (Value::eValueTypeScalar);
-            value.SetContext (Value::eContextTypeClangType, intptr_type.GetOpaqueQualType());
+//            value.SetContext (Value::eContextTypeClangType, intptr_type.GetOpaqueQualType());
+            value.SetClangType (intptr_type);
             value_list.PushValue (value);
         }
         
diff --git a/test/lang/objc/blocks/TestObjCIvarsInBlocks.py b/test/lang/objc/blocks/TestObjCIvarsInBlocks.py
index b91c9e8..955bd6d 100644
--- a/test/lang/objc/blocks/TestObjCIvarsInBlocks.py
+++ b/test/lang/objc/blocks/TestObjCIvarsInBlocks.py
@@ -111,7 +111,9 @@
         expr = frame.EvaluateExpression("(ret)")
         self.assertTrue (expr, "Successfully got a local variable in a block in a class method.")
 
-        self.assertTrue (expr.GetValueAsSigned (error) == 5, "The local variable in the block was what we expected.")
+        ret_value_signed = expr.GetValueAsSigned (error)
+        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__':
     import atexit