diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp
index 31a4eba..4977ee6 100644
--- a/lldb/source/API/SBType.cpp
+++ b/lldb/source/API/SBType.cpp
@@ -30,7 +30,7 @@
 }
 
 SBType::SBType (const ClangASTType &type) :
-    m_opaque_sp(new TypeImpl(ClangASTType(type.GetASTContext(),
+    m_opaque_sp(new TypeImpl(ClangASTType(type.GetTypeSystem(),
                                           type.GetOpaqueQualType())))
 {
 }
@@ -342,8 +342,13 @@
 SBType
 SBType::GetBasicType(lldb::BasicType basic_type)
 {
-    if (IsValid())
-        return SBType (ClangASTContext::GetBasicType (m_opaque_sp->GetClangASTContext(false), basic_type));
+    if (IsValid() && m_opaque_sp->IsValid())
+    {
+        ClangASTContext* ast = m_opaque_sp->GetTypeSystem(false)->AsClangASTContext();
+        if (ast)
+            return SBType (ClangASTContext::GetBasicType (ast->getASTContext(), basic_type));
+    }
+    
     return SBType();
 }
 
@@ -351,7 +356,7 @@
 SBType::GetNumberOfDirectBaseClasses ()
 {
     if (IsValid())
-        return m_opaque_sp->GetClangASTType(true).GetNumDirectBaseClasses();
+        return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetClangASTType(true));
     return 0;
 }
 
@@ -359,7 +364,7 @@
 SBType::GetNumberOfVirtualBaseClasses ()
 {
     if (IsValid())
-        return m_opaque_sp->GetClangASTType(true).GetNumVirtualBaseClasses();
+        return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetClangASTType(true));
     return 0;
 }
 
@@ -398,7 +403,7 @@
         if (this_type.IsValid())
         {
             uint32_t bit_offset = 0;
-            ClangASTType base_class_type (this_type.GetDirectBaseClassAtIndex(idx, &bit_offset));
+            ClangASTType base_class_type (ClangASTContext::GetDirectBaseClassAtIndex(this_type, idx, &bit_offset));
             if (base_class_type.IsValid())
             {
                 sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
@@ -419,7 +424,7 @@
         if (this_type.IsValid())
         {
             uint32_t bit_offset = 0;
-            ClangASTType base_class_type (this_type.GetVirtualBaseClassAtIndex(idx, &bit_offset));
+            ClangASTType base_class_type (ClangASTContext::GetVirtualBaseClassAtIndex(this_type, idx, &bit_offset));
             if (base_class_type.IsValid())
             {
                 sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
@@ -435,14 +440,14 @@
     SBTypeEnumMemberList sb_enum_member_list;
     if (IsValid())
     {
-        const clang::EnumDecl *enum_decl = m_opaque_sp->GetClangASTType(true).GetFullyUnqualifiedType().GetAsEnumDecl();
+        const clang::EnumDecl *enum_decl = ClangASTContext::GetAsEnumDecl(m_opaque_sp->GetClangASTType(true).GetFullyUnqualifiedType());
         if (enum_decl)
         {
             clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
             for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
             {
                 SBTypeEnumMember enum_member;
-                enum_member.reset(new TypeEnumMemberImpl(*enum_pos, ClangASTType(m_opaque_sp->GetClangASTContext(true), enum_decl->getIntegerType())));
+                enum_member.reset(new TypeEnumMemberImpl(*enum_pos, ClangASTType(m_opaque_sp->GetTypeSystem(true), enum_decl->getIntegerType().getAsOpaquePtr())));
                 sb_enum_member_list.Append(enum_member);
             }
         }
@@ -528,7 +533,7 @@
 SBType::GetNumberOfTemplateArguments ()
 {
     if (IsValid())
-        return m_opaque_sp->GetClangASTType(false).GetNumTemplateArguments();
+        return ClangASTContext::GetNumTemplateArguments(m_opaque_sp->GetClangASTType(false));
     return 0;
 }
 
@@ -538,7 +543,7 @@
     if (IsValid())
     {
         TemplateArgumentKind kind = eTemplateArgumentKindNull;
-        ClangASTType template_arg_type = m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
+        ClangASTType template_arg_type = ClangASTContext::GetTemplateArgument(m_opaque_sp->GetClangASTType(false), idx, kind);
         if (template_arg_type.IsValid())
             return SBType(template_arg_type);
     }
@@ -551,7 +556,7 @@
 {
     TemplateArgumentKind kind = eTemplateArgumentKindNull;
     if (IsValid())
-        m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
+        ClangASTContext::GetTemplateArgument(m_opaque_sp->GetClangASTType(false), idx, kind);
     return kind;
 }
 
diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp
index d589800..9410f73 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -33,6 +33,7 @@
 #include "lldb/Interpreter/OptionGroupOutputFile.h"
 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
 #include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/TypeList.h"
 #include "lldb/Target/MemoryHistory.h"
 #include "lldb/Target/Process.h"
@@ -532,7 +533,7 @@
                 clang::TypeDecl *tdecl = target->GetPersistentVariables().GetPersistentType(ConstString(lookup_type_name));
                 if (tdecl)
                 {
-                    clang_ast_type.SetClangType(&tdecl->getASTContext(),(const lldb::clang_type_t)tdecl->getTypeForDecl());
+                    clang_ast_type.SetClangType(ClangASTContext::GetASTContext(&tdecl->getASTContext()),(const lldb::clang_type_t)tdecl->getTypeForDecl());
                 }
             }
             
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 8718b37..48b8c5c 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -338,11 +338,11 @@
     ClangASTType class_type;
     bool is_pointer_type = false;
     
-    if (clang_type.IsObjCObjectPointerType(&class_type))
+    if (ClangASTContext::IsObjCObjectPointerType(clang_type, &class_type))
     {
         is_pointer_type = true;
     }
-    else if (clang_type.IsObjCObjectOrInterfaceType())
+    else if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type))
     {
         class_type = clang_type;
     }
@@ -2419,7 +2419,7 @@
         bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
         ClangASTType clang_type = GetClangType();
         std::string cxx_class_name;
-        bool this_had_base_class = clang_type.GetCXXClassName (cxx_class_name);
+        bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name);
         if (this_had_base_class)
         {
             if (parent_had_base_class)
diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp
index 89b98a1..9eaa6c3 100644
--- a/lldb/source/Core/ValueObjectDynamicValue.cpp
+++ b/lldb/source/Core/ValueObjectDynamicValue.cpp
@@ -154,7 +154,7 @@
         if (parent.IsPointerType())
             corrected_type = orig_type.GetPointerType ();
         else if (parent.IsPointerOrReferenceType())
-            corrected_type = orig_type.GetLValueReferenceType ();
+            corrected_type = ClangASTContext::GetLValueReferenceType(orig_type);
         ret.SetClangASTType(corrected_type);
     }
     else /*if (m_dynamic_type_info.HasName())*/
diff --git a/lldb/source/Core/ValueObjectMemory.cpp b/lldb/source/Core/ValueObjectMemory.cpp
index 9f19531..31a8d5c 100644
--- a/lldb/source/Core/ValueObjectMemory.cpp
+++ b/lldb/source/Core/ValueObjectMemory.cpp
@@ -97,7 +97,7 @@
     m_clang_type(ast_type)
 {
     // Do not attempt to construct one of these objects with no variable!
-    assert (m_clang_type.GetASTContext());
+    assert (m_clang_type.GetTypeSystem());
     assert (m_clang_type.GetOpaqueQualType());
     
     TargetSP target_sp (GetTargetSP());
diff --git a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
index 49eacee..507d671 100644
--- a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
+++ b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
@@ -312,7 +312,8 @@
     if (data_addr == 0 || data_addr == LLDB_INVALID_ADDRESS)
         return false;
 
-    clang::ASTContext* ast = valobj.GetClangType().GetASTContext();
+    ClangASTContext* lldb_ast = valobj.GetClangType().GetTypeSystem()->AsClangASTContext();
+    clang::ASTContext* ast = lldb_ast ? lldb_ast->getASTContext() : nullptr;
     
     if (!ast)
         return false;
diff --git a/lldb/source/DataFormatters/CoreMedia.cpp b/lldb/source/DataFormatters/CoreMedia.cpp
index 5c33c0b..172bdf0 100644
--- a/lldb/source/DataFormatters/CoreMedia.cpp
+++ b/lldb/source/DataFormatters/CoreMedia.cpp
@@ -21,7 +21,9 @@
 bool
 lldb_private::formatters::CMTimeSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
 {
-    ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(valobj.GetClangType().GetASTContext());
+    if (!valobj.GetClangType().IsValid())
+        return false;
+    ClangASTContext *ast_ctx = valobj.GetClangType().GetTypeSystem()->AsClangASTContext();
     if (!ast_ctx)
         return false;
     
diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp
index 7132a68..f994e32 100644
--- a/lldb/source/DataFormatters/FormatManager.cpp
+++ b/lldb/source/DataFormatters/FormatManager.cpp
@@ -171,7 +171,7 @@
                                    bool did_strip_typedef,
                                    bool root_level)
 {
-    clang_type = clang_type.RemoveFastQualifiers();
+    clang_type = ClangASTContext::RemoveFastQualifiers(clang_type);
     ConstString type_name(clang_type.GetConstTypeName());
     if (valobj.GetBitfieldBitSize() > 0)
     {
@@ -201,7 +201,7 @@
         if (non_ref_type.IsTypedefType())
         {
             ClangASTType deffed_referenced_type = non_ref_type.GetTypedefedType();
-            deffed_referenced_type = is_rvalue_ref ? deffed_referenced_type.GetRValueReferenceType() : deffed_referenced_type.GetLValueReferenceType();
+            deffed_referenced_type = is_rvalue_ref ? ClangASTContext::GetRValueReferenceType(deffed_referenced_type) : ClangASTContext::GetRValueReferenceType(deffed_referenced_type);
             GetPossibleMatches(valobj,
                                deffed_referenced_type,
                                reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
diff --git a/lldb/source/DataFormatters/LibCxxInitializerList.cpp b/lldb/source/DataFormatters/LibCxxInitializerList.cpp
index 0dcef98..1f79f00 100644
--- a/lldb/source/DataFormatters/LibCxxInitializerList.cpp
+++ b/lldb/source/DataFormatters/LibCxxInitializerList.cpp
@@ -101,7 +101,7 @@
     m_num_elements = 0;
     m_children.clear();
     lldb::TemplateArgumentKind kind;
-    m_element_type = m_backend.GetClangType().GetTemplateArgument(0, kind);
+    m_element_type = ClangASTContext::GetTemplateArgument(m_backend.GetClangType(), 0, kind);
     if (kind != lldb::eTemplateArgumentKindType || false == m_element_type.IsValid())
         return false;
     
diff --git a/lldb/source/DataFormatters/LibCxxList.cpp b/lldb/source/DataFormatters/LibCxxList.cpp
index f3e07fe..e70cd91 100644
--- a/lldb/source/DataFormatters/LibCxxList.cpp
+++ b/lldb/source/DataFormatters/LibCxxList.cpp
@@ -335,10 +335,10 @@
     if (list_type.IsReferenceType())
         list_type = list_type.GetNonReferenceType();
 
-    if (list_type.GetNumTemplateArguments() == 0)
+    if (ClangASTContext::GetNumTemplateArguments(list_type) == 0)
         return false;
     lldb::TemplateArgumentKind kind;
-    m_element_type = list_type.GetTemplateArgument(0, kind);
+    m_element_type = ClangASTContext::GetTemplateArgument(list_type, 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/lldb/source/DataFormatters/LibCxxMap.cpp b/lldb/source/DataFormatters/LibCxxMap.cpp
index 2ff6232..2782a3b0 100644
--- a/lldb/source/DataFormatters/LibCxxMap.cpp
+++ b/lldb/source/DataFormatters/LibCxxMap.cpp
@@ -279,7 +279,7 @@
 bool
 lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType()
 {
-    if (m_element_type.GetOpaqueQualType() && m_element_type.GetASTContext())
+    if (m_element_type.GetOpaqueQualType() && m_element_type.GetTypeSystem())
         return true;
     m_element_type.Clear();
     ValueObjectSP deref;
diff --git a/lldb/source/DataFormatters/LibStdcpp.cpp b/lldb/source/DataFormatters/LibStdcpp.cpp
index 2b3bcb5..16ee2c1 100644
--- a/lldb/source/DataFormatters/LibStdcpp.cpp
+++ b/lldb/source/DataFormatters/LibStdcpp.cpp
@@ -79,10 +79,10 @@
     m_pair_address += (is_64bit ? 32 : 16);
     
     ClangASTType my_type(valobj_sp->GetClangType());
-    if (my_type.GetNumTemplateArguments() >= 1)
+    if (ClangASTContext::GetNumTemplateArguments(my_type) >= 1)
     {
         TemplateArgumentKind kind;
-        ClangASTType pair_type = my_type.GetTemplateArgument(0, kind);
+        ClangASTType pair_type = ClangASTContext::GetTemplateArgument(my_type, 0, kind);
         if (kind != eTemplateArgumentKindType && kind != eTemplateArgumentKindTemplate && kind != eTemplateArgumentKindTemplateExpansion)
             return false;
         m_pair_type = pair_type;
diff --git a/lldb/source/DataFormatters/NSArray.cpp b/lldb/source/DataFormatters/NSArray.cpp
index 640982e..0e665bd 100644
--- a/lldb/source/DataFormatters/NSArray.cpp
+++ b/lldb/source/DataFormatters/NSArray.cpp
@@ -528,11 +528,11 @@
     m_items (0),
     m_data_ptr (0)
 {
-    if (valobj_sp)
+    if (valobj_sp && valobj_sp->GetClangType().IsValid())
     {
-        clang::ASTContext *ast = valobj_sp->GetClangType().GetASTContext();
+        ClangASTContext *ast = valobj_sp->GetClangType().GetTypeSystem()->AsClangASTContext();
         if (ast)
-            m_id_type = ClangASTType(ast, ast->ObjCBuiltinIdTy);
+            m_id_type = ClangASTType(ast->getASTContext(), ast->getASTContext()->ObjCBuiltinIdTy);
     }
 }
 
diff --git a/lldb/source/DataFormatters/NSDictionary.cpp b/lldb/source/DataFormatters/NSDictionary.cpp
index 30bc3ac..30e9d34 100644
--- a/lldb/source/DataFormatters/NSDictionary.cpp
+++ b/lldb/source/DataFormatters/NSDictionary.cpp
@@ -44,11 +44,11 @@
             
             if (clang_type)
             {
-                clang_type.StartTagDeclarationDefinition();
+                ClangASTContext::StartTagDeclarationDefinition(clang_type);
                 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();
+                ClangASTContext::AddFieldToRecordType(clang_type, "key", id_clang_type, lldb::eAccessPublic, 0);
+                ClangASTContext::AddFieldToRecordType(clang_type, "value", id_clang_type, lldb::eAccessPublic, 0);
+                ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
             }
         }
     }
diff --git a/lldb/source/DataFormatters/NSIndexPath.cpp b/lldb/source/DataFormatters/NSIndexPath.cpp
index 6932211..363069f 100644
--- a/lldb/source/DataFormatters/NSIndexPath.cpp
+++ b/lldb/source/DataFormatters/NSIndexPath.cpp
@@ -49,7 +49,10 @@
     {
         m_impl.m_mode = Mode::Invalid;
         
-        m_ast_ctx = ClangASTContext::GetASTContext(m_backend.GetClangType().GetASTContext());
+        TypeSystem* type_system = m_backend.GetClangType().GetTypeSystem();
+        if (!type_system)
+            return false;
+        m_ast_ctx = type_system->AsClangASTContext();
         if (!m_ast_ctx)
             return false;
         
diff --git a/lldb/source/DataFormatters/VectorType.cpp b/lldb/source/DataFormatters/VectorType.cpp
index 57bf696..1d6fc66 100644
--- a/lldb/source/DataFormatters/VectorType.cpp
+++ b/lldb/source/DataFormatters/VectorType.cpp
@@ -231,7 +231,7 @@
                 ClangASTType parent_type(m_backend.GetClangType());
                 ClangASTType element_type;
                 parent_type.IsVectorType(&element_type, nullptr);
-                m_child_type = ::GetClangTypeForFormat(m_parent_format, element_type, ClangASTContext::GetASTContext(parent_type.GetASTContext()));
+                m_child_type = ::GetClangTypeForFormat(m_parent_format, element_type, parent_type.GetTypeSystem()->AsClangASTContext());
                 m_num_children = ::CalculateNumChildren(parent_type,
                                                         m_child_type);
                 m_item_format = GetItemFormatForFormat(m_parent_format,
diff --git a/lldb/source/Expression/ASTDumper.cpp b/lldb/source/Expression/ASTDumper.cpp
index 5210d14..80faeb3 100644
--- a/lldb/source/Expression/ASTDumper.cpp
+++ b/lldb/source/Expression/ASTDumper.cpp
@@ -9,6 +9,7 @@
 
 #include "lldb/Core/Log.h"
 #include "lldb/Expression/ASTDumper.h"
+#include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/ClangASTType.h"
 
 #include "llvm/Support/raw_ostream.h"
@@ -81,7 +82,7 @@
 
 ASTDumper::ASTDumper (const ClangASTType &clang_type)
 {
-    m_dump = clang_type.GetQualType().getAsString();
+    m_dump = ClangASTContext::GetQualType(clang_type).getAsString();
 }
 
 
diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp
index 3988cd6..b6ea7a8 100644
--- a/lldb/source/Expression/ClangASTSource.cpp
+++ b/lldb/source/Expression/ClangASTSource.cpp
@@ -277,7 +277,7 @@
                     if (!clang_type)
                         continue;
 
-                    const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>();
+                    const TagType *tag_type = ClangASTContext::GetQualType(clang_type)->getAs<TagType>();
 
                     if (!tag_type)
                         continue;
@@ -316,7 +316,7 @@
                 if (!clang_type)
                     continue;
 
-                const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>();
+                const TagType *tag_type = ClangASTContext::GetQualType(clang_type)->getAs<TagType>();
 
                 if (!tag_type)
                     continue;
@@ -1886,9 +1886,13 @@
 {
     ClangASTMetrics::RegisterLLDBImport();
 
+    ClangASTContext* src_ast = src_type.GetTypeSystem()->AsClangASTContext();
+    if (!src_ast)
+        return ClangASTType();
+    
     SetImportInProgress(true);
 
-    QualType copied_qual_type = m_ast_importer->CopyType (m_ast_context, src_type.GetASTContext(), src_type.GetQualType());
+    QualType copied_qual_type = m_ast_importer->CopyType (m_ast_context, src_ast->getASTContext(), ClangASTContext::GetQualType(src_type));
 
     SetImportInProgress(false);
 
@@ -1908,16 +1912,20 @@
     if (!type.IsValid())
         return NULL;
 
+    ClangASTContext* lldb_ast = type.GetTypeSystem()->AsClangASTContext();
+    if (!lldb_ast)
+        return NULL;
+    
     IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
 
-    clang::ASTContext *ast = type.GetASTContext();
+    clang::ASTContext *ast = lldb_ast->getASTContext();
 
     clang::NamedDecl *Decl = VarDecl::Create(*ast,
                                              const_cast<DeclContext*>(m_decl_context),
                                              SourceLocation(),
                                              SourceLocation(),
                                              ii,
-                                             type.GetQualType(),
+                                             ClangASTContext::GetQualType(type),
                                              0,
                                              SC_Static);
     m_decls.push_back(Decl);
@@ -1935,12 +1943,16 @@
 
     if (m_function_types.count(type))
         return NULL;
+    
+    ClangASTContext* lldb_ast = type.GetTypeSystem()->AsClangASTContext();
+    if (!lldb_ast)
+        return NULL;
 
     m_function_types.insert(type);
 
-    QualType qual_type (type.GetQualType());
+    QualType qual_type (ClangASTContext::GetQualType(type));
 
-    clang::ASTContext *ast = type.GetASTContext();
+    clang::ASTContext *ast = lldb_ast->getASTContext();
 
     const bool isInlineSpecified = false;
     const bool hasWrittenPrototype = true;
@@ -2031,7 +2043,7 @@
 {
     if (clang_type)
     {
-        QualType qual_type = clang_type.GetQualType();
+        QualType qual_type = ClangASTContext::GetQualType(clang_type);
 
         if (const TypedefType *typedef_type = llvm::dyn_cast<TypedefType>(qual_type))
         {
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp
index 7574723..d00e455 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -201,10 +201,10 @@
         if (target == NULL)
             return false;
 
-        ASTContext *context(target->GetScratchClangASTContext()->getASTContext());
+        ClangASTContext *context(target->GetScratchClangASTContext());
 
-        TypeFromUser user_type(m_ast_importer->DeportType(context,
-                                                          parser_type.GetASTContext(),
+        TypeFromUser user_type(m_ast_importer->DeportType(context->getASTContext(),
+                                                          parser_type.GetTypeSystem()->AsClangASTContext()->getASTContext(),
                                                           parser_type.GetOpaqueQualType()),
                                context);
 
@@ -241,10 +241,10 @@
     if (target == NULL)
         return false;
 
-    ASTContext *context(target->GetScratchClangASTContext()->getASTContext());
+    ClangASTContext *context(target->GetScratchClangASTContext());
 
-    TypeFromUser user_type(m_ast_importer->DeportType(context,
-                                                      parser_type.GetASTContext(),
+    TypeFromUser user_type(m_ast_importer->DeportType(context->getASTContext(),
+                                                      parser_type.GetTypeSystem()->AsClangASTContext()->getASTContext(),
                                                       parser_type.GetOpaqueQualType()),
                            context);
 
@@ -1041,7 +1041,7 @@
                 QualType class_qual_type(class_decl->getTypeForDecl(), 0);
 
                 TypeFromUser class_user_type (class_qual_type.getAsOpaquePtr(),
-                                              &class_decl->getASTContext());
+                                              ClangASTContext::GetASTContext(&class_decl->getASTContext()));
 
                 if (log)
                 {
@@ -1079,7 +1079,7 @@
                     QualType class_pointer_type = method_decl->getASTContext().getPointerType(class_qual_type);
 
                     TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(),
-                                                &method_decl->getASTContext());
+                                                ClangASTContext::GetASTContext(&method_decl->getASTContext()));
 
                     m_struct_vars->m_object_pointer_type = self_user_type;
                 }
@@ -1169,7 +1169,7 @@
                     return; // This is unlikely, but we have seen crashes where this occurred
 
                 TypeFromUser class_user_type(QualType(interface_type, 0).getAsOpaquePtr(),
-                                             &method_decl->getASTContext());
+                                             ClangASTContext::GetASTContext(&method_decl->getASTContext()));
 
                 if (log)
                 {
@@ -1186,7 +1186,7 @@
                     QualType class_pointer_type = method_decl->getASTContext().getObjCObjectPointerType(QualType(interface_type, 0));
 
                     TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(),
-                                                &method_decl->getASTContext());
+                                                ClangASTContext::GetASTContext(&method_decl->getASTContext()));
 
                     m_struct_vars->m_object_pointer_type = self_user_type;
                 }
@@ -1196,7 +1196,7 @@
                     QualType class_type = method_decl->getASTContext().getObjCClassType();
 
                     TypeFromUser self_user_type(class_type.getAsOpaquePtr(),
-                                                &method_decl->getASTContext());
+                                                ClangASTContext::GetASTContext(&method_decl->getASTContext()));
 
                     m_struct_vars->m_object_pointer_type = self_user_type;
                 }
@@ -1225,11 +1225,11 @@
 
                     ClangASTType self_clang_type = self_type->GetClangFullType();
 
-                    if (self_clang_type.IsObjCClassType())
+                    if (ClangASTContext::IsObjCClassType(self_clang_type))
                     {
                         return;
                     }
-                    else if (self_clang_type.IsObjCObjectPointerType())
+                    else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type))
                     {
                         self_clang_type = self_clang_type.GetPointeeType();
 
@@ -1726,7 +1726,7 @@
     if (is_reference)
         var_decl = context.AddVarDecl(pt);
     else
-        var_decl = context.AddVarDecl(pt.GetLValueReferenceType());
+        var_decl = context.AddVarDecl(ClangASTContext::GetLValueReferenceType(pt));
 
     std::string decl_name(context.m_decl_name.getAsString());
     ConstString entity_name(decl_name.c_str());
@@ -1770,7 +1770,7 @@
         return;
     }
 
-    NamedDecl *var_decl = context.AddVarDecl(parser_type.GetLValueReferenceType());
+    NamedDecl *var_decl = context.AddVarDecl(ClangASTContext::GetLValueReferenceType(parser_type));
 
     pvar_sp->EnableParserVars(GetParserID());
     ClangExpressionVariable::ParserVars *parser_vars = pvar_sp->GetParserVars(GetParserID());
@@ -1802,8 +1802,8 @@
 
     ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext();
 
-    TypeFromUser user_type (ClangASTContext::GetBasicType(scratch_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType());
-    TypeFromParser parser_type (ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType());
+    TypeFromUser user_type (ClangASTContext::GetLValueReferenceType(ClangASTContext::GetBasicType(scratch_ast_context, eBasicTypeVoid).GetPointerType()));
+    TypeFromParser parser_type (ClangASTContext::GetLValueReferenceType(ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid).GetPointerType()));
     NamedDecl *var_decl = context.AddVarDecl(parser_type);
 
     std::string decl_name(context.m_decl_name.getAsString());
@@ -1845,7 +1845,7 @@
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
 
-    ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext();
+    ClangASTContext *scratch_ast_context = target->GetScratchClangASTContext();
 
     for (size_t index = 0, num_entities = m_found_entities.GetSize();
          index < num_entities;
@@ -1874,9 +1874,9 @@
             }
 
             QualType var_type = var_decl->getType();
-            TypeFromParser parser_type(var_type.getAsOpaquePtr(), &var_decl->getASTContext());
+            TypeFromParser parser_type(var_type.getAsOpaquePtr(), ClangASTContext::GetASTContext(&var_decl->getASTContext()));
 
-            lldb::clang_type_t copied_type = m_ast_importer->CopyType(scratch_ast_context, &var_decl->getASTContext(), var_type.getAsOpaquePtr());
+            lldb::clang_type_t copied_type = m_ast_importer->CopyType(scratch_ast_context->getASTContext(), &var_decl->getASTContext(), var_type.getAsOpaquePtr());
 
             if (!copied_type)
             {
@@ -2114,15 +2114,17 @@
         const bool is_attr_used = true;
         const bool is_artificial = false;
 
-        copied_clang_type.AddMethodToCXXRecordType ("$__lldb_expr",
-                                                    method_type,
-                                                    lldb::eAccessPublic,
-                                                    is_virtual,
-                                                    is_static,
-                                                    is_inline,
-                                                    is_explicit,
-                                                    is_attr_used,
-                                                    is_artificial);
+        ClangASTContext::GetASTContext(m_ast_context)->
+            AddMethodToCXXRecordType (copied_clang_type.GetOpaqueQualType(),
+                                      "$__lldb_expr",
+                                      method_type,
+                                      lldb::eAccessPublic,
+                                      is_virtual,
+                                      is_static,
+                                      is_inline,
+                                      is_explicit,
+                                      is_attr_used,
+                                      is_artificial);
     }
 
     return TypeFromParser(copied_clang_type);
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp
index 38e6ddb..ebdc45c 100644
--- a/lldb/source/Expression/ClangUserExpression.cpp
+++ b/lldb/source/Expression/ClangUserExpression.cpp
@@ -313,11 +313,11 @@
                         return;
                     }
 
-                    if (self_clang_type.IsObjCClassType())
+                    if (ClangASTContext::IsObjCClassType(self_clang_type))
                     {
                         return;
                     }
-                    else if (self_clang_type.IsObjCObjectPointerType())
+                    else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type))
                     {
                         m_objectivec = true;
                         m_needs_object_ptr = true;
diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp
index e1059c3..eb4c919 100644
--- a/lldb/source/Expression/IRForTarget.cpp
+++ b/lldb/source/Expression/IRForTarget.cpp
@@ -575,14 +575,14 @@
             clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
 
             m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
-                                                         &result_decl->getASTContext());
+                                                         lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
         }
         else if (pointer_objcobjpointertype)
         {
             clang::QualType element_qual_type = clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
 
             m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
-                                                         &result_decl->getASTContext());
+                                                         lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
         }
         else
         {
@@ -598,7 +598,7 @@
     else
     {
         m_result_type = lldb_private::TypeFromParser(result_var->getType().getAsOpaquePtr(),
-                                                     &result_decl->getASTContext());
+                                                     lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
     }
 
 
@@ -1241,7 +1241,7 @@
     clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
 
     lldb_private::TypeFromParser result_decl_type (decl->getType().getAsOpaquePtr(),
-                                                   &decl->getASTContext());
+                                                   lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
 
     StringRef decl_name (decl->getName());
     lldb_private::ConstString persistent_variable_name (decl_name.data(), decl_name.size());
@@ -1539,7 +1539,7 @@
         {
             log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRIu64 "]",
                         name.c_str(),
-                        clang_type.GetQualType().getAsString().c_str(),
+                        lldb_private::ClangASTContext::GetQualType(clang_type).getAsString().c_str(),
                         PrintType(value_type).c_str(),
                         value_size,
                         value_alignment);
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index 700d223..3e0861b 100644
--- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -424,7 +424,8 @@
     if (!clang_type)
         return return_valobj_sp;
     
-    clang::ASTContext *ast_context = clang_type.GetASTContext();
+    ClangASTContext* ast = clang_type.GetTypeSystem()->AsClangASTContext();
+    clang::ASTContext *ast_context = ast ? ast->getASTContext() : nullptr;
     if (!ast_context)
         return return_valobj_sp;
 
diff --git a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
index 50a9863..4425dd7 100644
--- a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
+++ b/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
@@ -408,10 +408,6 @@
     if (!clang_type)
         return return_valobj_sp;
     
-    clang::ASTContext *ast_context = clang_type.GetASTContext();
-    if (!ast_context)
-        return return_valobj_sp;
-
     //value.SetContext (Value::eContextTypeClangType, clang_type.GetOpaqueQualType());
     value.SetClangType (clang_type);
             
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 7d21b77..e4b17af 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -189,7 +189,7 @@
                                 type_sp = class_types.GetTypeAtIndex(i);
                                 if (type_sp)
                                 {
-                                    if (type_sp->GetClangFullType().IsCXXClassType())
+                                    if (ClangASTContext::IsCXXClassType(type_sp->GetClangFullType()))
                                     {
                                         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",
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 76ac690..5236af2 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -363,7 +363,7 @@
         
         clang::Selector sel = ast_ctx.Selectors.getSelector(is_zero_argument ? 0 : selector_components.size(), selector_components.data());
         
-        clang::QualType ret_type = type_realizer_sp->RealizeType(interface_decl->getASTContext(), m_type_vector[0].c_str(), for_expression).GetQualType();
+        clang::QualType ret_type = ClangASTContext::GetQualType(type_realizer_sp->RealizeType(interface_decl->getASTContext(), m_type_vector[0].c_str(), for_expression));
         
         if (ret_type.isNull())
             return NULL;
@@ -390,7 +390,7 @@
              ++ai)
         {
             const bool for_expression = true;
-            clang::QualType arg_type = type_realizer_sp->RealizeType(ast_ctx, m_type_vector[ai].c_str(), for_expression).GetQualType();
+            clang::QualType arg_type = ClangASTContext::GetQualType(type_realizer_sp->RealizeType(ast_ctx, m_type_vector[ai].c_str(), for_expression));
             
             if (arg_type.isNull())
                 return NULL; // well, we just wasted a bunch of time.  Wish we could delete the stuff we'd just made!
@@ -512,7 +512,7 @@
                                                                           clang::SourceLocation(),
                                                                           clang::SourceLocation(),
                                                                           &m_ast_ctx.getASTContext()->Idents.get(name),
-                                                                          ivar_type.GetQualType(),
+                                                                          ClangASTContext::GetQualType(ivar_type),
                                                                           type_source_info,                      // TypeSourceInfo *
                                                                           clang::ObjCIvarDecl::Public,
                                                                           0,
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 258df3f..4434404 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -92,7 +92,7 @@
     ClangASTType clang_type = value.GetClangType();
     if (clang_type)
     {
-        if (!clang_type.IsObjCObjectPointerType())
+        if (!ClangASTContext::IsObjCObjectPointerType(clang_type))
         {
             strm.Printf ("Value doesn't point to an ObjC object.\n");
             return false;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index dfb6094..019c094 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -139,7 +139,7 @@
     ClangASTType union_type(lldb_ctx->CreateRecordType(nullptr, lldb::eAccessPublic, name.c_str(), kind, lldb::eLanguageTypeC));
     if (union_type)
     {
-        union_type.StartTagDeclarationDefinition();
+        ClangASTContext::StartTagDeclarationDefinition(union_type);
         
         unsigned int count = 0;
         for (auto element: elements)
@@ -150,13 +150,12 @@
                 elem_name.Printf("__unnamed_%u",count);
                 element.name = std::string(elem_name.GetData());
             }
-            union_type.AddFieldToRecordType(element.name.c_str(), ClangASTType(&ast_ctx,element.type.getAsOpaquePtr()), lldb::eAccessPublic, element.bitfield);
+            ClangASTContext::AddFieldToRecordType(union_type, element.name.c_str(), ClangASTType(&ast_ctx, element.type), lldb::eAccessPublic, element.bitfield);
             ++count;
         }
-        
-        union_type.CompleteTagDeclarationDefinition();
+        ClangASTContext::CompleteTagDeclarationDefinition(union_type);
     }
-    return union_type.GetQualType();
+    return ClangASTContext::GetQualType(union_type);
 }
 
 clang::QualType
@@ -171,8 +170,8 @@
     ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
     if (!lldb_ctx)
         return clang::QualType();
-    ClangASTType array_type(lldb_ctx->CreateArrayType(ClangASTType(&ast_ctx,element_type.getAsOpaquePtr()), size, false));
-    return array_type.GetQualType();
+    ClangASTType array_type(lldb_ctx->CreateArrayType(ClangASTType(&ast_ctx, element_type), size, false));
+    return ClangASTContext::GetQualType(array_type);
 }
 
 // the runtime can emit these in the form of @"SomeType", giving more specifics
@@ -263,7 +262,7 @@
             return ast_ctx.getObjCIdType();
 #endif
         
-        return ClangASTContext::GetTypeForDecl(decls[0]).GetPointerType().GetQualType();
+        return ClangASTContext::GetQualType(ClangASTContext::GetTypeForDecl(decls[0]).GetPointerType());
     }
     else
     {
@@ -392,7 +391,7 @@
     {
         StringLexer lexer(name);
         clang::QualType qual_type = BuildType(ast_ctx, lexer, for_expression);
-        return ClangASTType(&ast_ctx, qual_type.getAsOpaquePtr());
+        return ClangASTType(&ast_ctx, qual_type);
     }
     return ClangASTType();
 }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 7ed2998..c618ffc 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1591,11 +1591,11 @@
                         llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
                         template_param_infos.args.push_back (clang::TemplateArgument (*ast,
                                                                                       llvm::APSInt(apint),
-                                                                                      clang_type.GetQualType()));
+                                                                                      ClangASTContext::GetQualType(clang_type)));
                     }
                     else
                     {
-                        template_param_infos.args.push_back (clang::TemplateArgument (clang_type.GetQualType()));
+                        template_param_infos.args.push_back (clang::TemplateArgument (ClangASTContext::GetQualType(clang_type)));
                     }
                 }
                 else
@@ -1722,13 +1722,16 @@
     bool
     Finalize()
     {
-        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());
+        ClangASTContext* ast = m_class_opaque_type.GetTypeSystem()->AsClangASTContext();
+        assert(ast);
+        return ast->AddObjCClassProperty (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());
     }
 private:
     ClangASTType            m_class_opaque_type;
@@ -1822,6 +1825,9 @@
     uint32_t member_idx = 0;
     BitfieldInfo last_field_info;
     ModuleSP module = GetObjectFile()->GetModule();
+    ClangASTContext* ast = class_clang_type.GetTypeSystem()->AsClangASTContext();
+    if (ast == nullptr)
+        return 0;
 
     for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
     {
@@ -2010,7 +2016,8 @@
                         {
                             if (accessibility == eAccessNone)
                                 accessibility = eAccessPublic;
-                            class_clang_type.AddVariableToRecordType (name,
+                            ClangASTContext::AddVariableToRecordType (class_clang_type,
+                                                                      name,
                                                                       var_type->GetClangLayoutType(),
                                                                       accessibility);
                         }
@@ -2127,10 +2134,12 @@
                                         
                                         if (anon_field_info.IsValid())
                                         {
-                                            clang::FieldDecl *unnamed_bitfield_decl = class_clang_type.AddFieldToRecordType (NULL,
-                                                                                                                             GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
-                                                                                                                             accessibility,
-                                                                                                                             anon_field_info.bit_size);
+                                            clang::FieldDecl *unnamed_bitfield_decl =
+                                                ClangASTContext::AddFieldToRecordType (class_clang_type,
+                                                                                       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));
@@ -2177,7 +2186,8 @@
                                     }
                                 }
                                 
-                                field_decl = class_clang_type.AddFieldToRecordType (name,
+                                field_decl = ClangASTContext::AddFieldToRecordType (class_clang_type,
+                                                                                    name,
                                                                                     member_clang_type,
                                                                                     accessibility,
                                                                                     bit_size);
@@ -2332,13 +2342,14 @@
                     assert (base_class_clang_type);
                     if (class_language == eLanguageTypeObjC)
                     {
-                        class_clang_type.SetObjCSuperClass(base_class_clang_type);
+                        ast->SetObjCSuperClass(class_clang_type, base_class_clang_type);
                     }
                     else
                     {
-                        base_classes.push_back (base_class_clang_type.CreateBaseClassSpecifier (accessibility,
-                                                                                               is_virtual, 
-                                                                                               is_base_of_class));
+                        base_classes.push_back (ast->CreateBaseClassSpecifier (base_class_clang_type.GetOpaqueQualType(),
+                                                                               accessibility,
+                                                                               is_virtual,
+                                                                               is_base_of_class));
                         
                         if (is_virtual)
                         {
@@ -2353,7 +2364,7 @@
                         else
                         {
                             layout_info.base_offsets.insert(
-                                std::make_pair(base_class_clang_type.GetAsCXXRecordDecl(),
+                                std::make_pair(ast->GetAsCXXRecordDecl(base_class_clang_type.GetOpaqueQualType()),
                                                clang::CharUnits::fromQuantity(member_byte_offset)));
                         }
                     }
@@ -2474,7 +2485,7 @@
 bool
 SymbolFileDWARF::HasForwardDeclForClangType (const ClangASTType &clang_type)
 {
-    ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
+    ClangASTType clang_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(clang_type);
     const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
     return die != NULL;
 }
@@ -2484,7 +2495,7 @@
 SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type)
 {
     // We have a struct/union/class/enum that needs to be fully resolved.
-    ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
+    ClangASTType clang_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(clang_type);
     const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
     if (die == NULL)
     {
@@ -2497,9 +2508,16 @@
     // are done.
     m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers.GetOpaqueQualType());
 
+    ClangASTContext* ast = clang_type.GetTypeSystem()->AsClangASTContext();
+    if (ast == NULL)
+    {
+        // Not a clang type
+        return true;
+    }
+    
     // Disable external storage for this type so we don't get anymore 
     // clang::ExternalASTSource queries for this type.
-    clang_type.SetHasExternalStorage (false);
+    ast->SetHasExternalStorage (clang_type.GetOpaqueQualType(), false);
 
     DWARFDebugInfo* debug_info = DebugInfo();
 
@@ -2530,12 +2548,12 @@
                 if (die->HasChildren())
                 {
                     LanguageType class_language = eLanguageTypeUnknown;
-                    if (clang_type.IsObjCObjectOrInterfaceType())
+                    if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type))
                     {
                         class_language = eLanguageTypeObjC;
                         // For objective C we don't start the definition when
                         // the class is created.
-                        clang_type.StartTagDeclarationDefinition ();
+                        ClangASTContext::StartTagDeclarationDefinition (clang_type);
                     }
 
                     int tag_decl_kind = -1;
@@ -2642,7 +2660,7 @@
                     if (class_language != eLanguageTypeObjC)
                     {
                         if (is_a_class && tag_decl_kind != clang::TTK_Class)
-                            clang_type.SetTagTypeKind (clang::TTK_Class);
+                            GetClangASTContext().SetTagTypeKind (ClangASTContext::GetQualType(clang_type), clang::TTK_Class);
                     }
 
                     // Since DW_TAG_structure_type gets used for both classes
@@ -2659,9 +2677,10 @@
                     {
                         // This is a class and all members that didn't have
                         // their access specified are private.
-                        clang_type.SetDefaultAccessForRecordFields (eAccessPrivate,
-                                                                    &member_accessibilities.front(),
-                                                                    member_accessibilities.size());
+                        GetClangASTContext().SetDefaultAccessForRecordFields (ast->GetAsRecordDecl(clang_type),
+                                                                              eAccessPrivate,
+                                                                              &member_accessibilities.front(),
+                                                                              member_accessibilities.size());
                     }
 
                     if (!base_classes.empty())
@@ -2692,24 +2711,26 @@
                                     // below. Since we provide layout assistance, all ivars in this
                                     // class and other classes will be fine, this is the best we can do
                                     // short of crashing.
-                                    base_class_type.StartTagDeclarationDefinition ();
-                                    base_class_type.CompleteTagDeclarationDefinition ();
+                                    
+                                    ClangASTContext::StartTagDeclarationDefinition (base_class_type);
+                                    ClangASTContext::CompleteTagDeclarationDefinition (base_class_type);
                                 }
                             }
                         }
-                        clang_type.SetBaseClassesForClassType (&base_classes.front(),
-                                                               base_classes.size());
+                        ast->SetBaseClassesForClassType (clang_type.GetOpaqueQualType(),
+                                                           &base_classes.front(),
+                                                           base_classes.size());
 
                         // Clang will copy each CXXBaseSpecifier in "base_classes"
                         // so we have to free them all.
-                        ClangASTType::DeleteBaseClassSpecifiers (&base_classes.front(),
-                                                                 base_classes.size());
+                        ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
+                                                                    base_classes.size());
                     }
                 }
             }
 
-            clang_type.BuildIndirectFields ();
-            clang_type.CompleteTagDeclarationDefinition ();
+            ClangASTContext::BuildIndirectFields (clang_type);
+            ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
 
             if (!layout_info.field_offsets.empty() ||
                 !layout_info.base_offsets.empty()  ||
@@ -2720,7 +2741,7 @@
                 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 = clang_type.GetAsCXXRecordDecl();
+                clang::CXXRecordDecl *record_decl = ast->GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
                 if (record_decl)
                 {
                     if (log)
@@ -2785,7 +2806,7 @@
         return (bool)clang_type;
 
     case DW_TAG_enumeration_type:
-        clang_type.StartTagDeclarationDefinition ();
+        ClangASTContext::StartTagDeclarationDefinition (clang_type);
         if (die->HasChildren())
         {
             SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
@@ -2793,7 +2814,7 @@
             clang_type.IsIntegerType(is_signed);
             ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), dwarf_cu, die);
         }
-        clang_type.CompleteTagDeclarationDefinition ();
+        ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
         return (bool)clang_type;
 
     default:
@@ -4664,12 +4685,17 @@
 
                 if (name && name[0] && got_value)
                 {
-                    clang_type.AddEnumerationValueToEnumerationType (clang_type.GetEnumerationIntegerType(),
-                                                                     decl,
-                                                                     name,
-                                                                     enum_value,
-                                                                     enumerator_byte_size * 8);
-                    ++enumerators_added;
+                    ClangASTContext* ast = clang_type.GetTypeSystem()->AsClangASTContext();
+                    if (ast)
+                    {
+                        ast->AddEnumerationValueToEnumerationType (clang_type.GetOpaqueQualType(),
+                                                                   ast->GetEnumerationIntegerType(clang_type.GetOpaqueQualType()),
+                                                                   decl,
+                                                                   name,
+                                                                   enum_value,
+                                                                   enumerator_byte_size * 8);
+                        ++enumerators_added;
+                    }
                 }
             }
         }
@@ -4936,7 +4962,7 @@
                 Type* type = ResolveType (cu, decl_ctx_die);
                 if (type)
                 {
-                    clang::DeclContext *decl_ctx = type->GetClangForwardType().GetDeclContextForType ();
+                    clang::DeclContext *decl_ctx = GetClangASTContext().GetDeclContextForType(type->GetClangForwardType());
                     if (decl_ctx)
                     {
                         LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
@@ -6238,7 +6264,7 @@
                     }
                     assert (tag_decl_kind != -1);
                     bool clang_type_was_created = false;
-                    clang_type.SetClangType(ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
+                    clang_type.SetClangType(&ast, m_forward_decl_die_to_clang_type.lookup (die));
                     if (!clang_type)
                     {
                         const DWARFDebugInfoEntry *decl_ctx_die;
@@ -6295,7 +6321,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(clang_type.GetDeclContextForType(), die);
+                    LinkDeclContextToDIE(ast.GetDeclContextForType(clang_type), die);
                     type_sp.reset (new Type (MakeUserID(die->GetOffset()), 
                                              this, 
                                              type_name_const_str, 
@@ -6360,12 +6386,12 @@
                         if (die->HasChildren() == false)
                         {
                             // No children for this struct/union/class, lets finish it
-                            clang_type.StartTagDeclarationDefinition ();
-                            clang_type.CompleteTagDeclarationDefinition ();
+                            ClangASTContext::StartTagDeclarationDefinition (clang_type);
+                            ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
 
                             if (tag == DW_TAG_structure_type) // this only applies in C
                             {
-                                clang::RecordDecl *record_decl = clang_type.GetAsRecordDecl();
+                                clang::RecordDecl *record_decl = ClangASTContext::GetAsRecordDecl(clang_type);
 
                                 if (record_decl)
                                     m_record_decl_to_layout_map.insert(std::make_pair(record_decl, LayoutInfo()));
@@ -6383,7 +6409,7 @@
 
                             if (class_language != eLanguageTypeObjC &&
                                 class_language != eLanguageTypeObjC_plus_plus)
-                                clang_type.StartTagDeclarationDefinition ();
+                                ClangASTContext::StartTagDeclarationDefinition (clang_type);
 
                             // Leave this as a forward declaration until we need
                             // to know the details of the type. lldb_private::Type
@@ -6391,8 +6417,8 @@
                             // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
                             // When the definition needs to be defined.
                             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);
+                            m_forward_decl_clang_type_to_die[ClangASTContext::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] = die;
+                            ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), true);
                         }
                     }
 
@@ -6448,7 +6474,7 @@
                         DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
 
                         ClangASTType enumerator_clang_type;
-                        clang_type.SetClangType (ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
+                        clang_type.SetClangType (&ast, m_forward_decl_die_to_clang_type.lookup (die));
                         if (!clang_type)
                         {
                             if (encoding_uid != DW_INVALID_OFFSET)
@@ -6470,10 +6496,10 @@
                         }
                         else
                         {
-                            enumerator_clang_type = clang_type.GetEnumerationIntegerType ();
+                            enumerator_clang_type = ast.GetEnumerationIntegerType (clang_type.GetOpaqueQualType());
                         }
 
-                        LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);
+                        LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
 
                         type_sp.reset( new Type (MakeUserID(die->GetOffset()), 
                                                  this, 
@@ -6486,7 +6512,7 @@
                                                  clang_type, 
                                                  Type::eResolveStateForward));
 
-                        clang_type.StartTagDeclarationDefinition ();
+                        ClangASTContext::StartTagDeclarationDefinition (clang_type);
                         if (die->HasChildren())
                         {
                             SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
@@ -6494,7 +6520,7 @@
                             enumerator_clang_type.IsIntegerType(is_signed);
                             ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), dwarf_cu, die);
                         }
-                        clang_type.CompleteTagDeclarationDefinition ();
+                        ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
                     }
                 }
                 break;
@@ -6684,7 +6710,7 @@
                                     if (complete_objc_class_type_sp)
                                     {
                                         ClangASTType type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType();
-                                        if (type_clang_forward_type.IsObjCObjectOrInterfaceType ())
+                                        if (ClangASTContext::IsObjCObjectOrInterfaceType(type_clang_forward_type))
                                             class_opaque_type = type_clang_forward_type;
                                     }
                                 }
@@ -6696,10 +6722,11 @@
                                     if (accessibility == eAccessNone)
                                         accessibility = eAccessPublic;
 
-                                    clang::ObjCMethodDecl *objc_method_decl = class_opaque_type.AddMethodToObjCObjectType (type_name_cstr,
-                                                                                                                           clang_type,
-                                                                                                                           accessibility,
-                                                                                                                           is_artificial);
+                                    clang::ObjCMethodDecl *objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
+                                                                                                             type_name_cstr,
+                                                                                                             clang_type,
+                                                                                                             accessibility,
+                                                                                                             is_artificial);
                                     type_handled = objc_method_decl != NULL;
                                     if (type_handled)
                                     {
@@ -6819,7 +6846,7 @@
                                     else
                                     {
                                         ClangASTType class_opaque_type = class_type->GetClangForwardType();
-                                        if (class_opaque_type.IsCXXClassType ())
+                                        if (ClangASTContext::IsCXXClassType(class_opaque_type))
                                         {
                                             if (class_opaque_type.IsBeingDefined ())
                                             {
@@ -6847,15 +6874,16 @@
 
                                                     const bool is_attr_used = false;
 
-                                                    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);
+                                                    cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type.GetOpaqueQualType(),
+                                                                                                    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;
 
@@ -7108,7 +7136,7 @@
                         ClangASTType pointee_clang_type = pointee_type->GetClangForwardType();
                         ClangASTType class_clang_type = class_type->GetClangLayoutType();
 
-                        clang_type = pointee_clang_type.CreateMemberPointerType(class_clang_type);
+                        clang_type = ClangASTContext::CreateMemberPointerType(pointee_clang_type, class_clang_type);
 
                         byte_size = clang_type.GetByteSize(nullptr);
 
@@ -8025,7 +8053,7 @@
                 
                 Type *matching_type = ResolveType (dwarf_cu, die);
                 
-                clang::QualType qual_type = matching_type->GetClangForwardType().GetQualType();
+                clang::QualType qual_type = ClangASTContext::GetQualType(matching_type->GetClangForwardType());
                 
                 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
                 {
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index 9b18ead..d047aaa 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -448,12 +448,13 @@
         {
             ClangASTType uint16 = ast_ctx->GetIntTypeFromBitSize(16, false);
             ClangASTType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s", clang::TTK_Struct, lldb::eLanguageTypeC);
-            dispatch_tsd_indexes_s.StartTagDeclarationDefinition();
-            dispatch_tsd_indexes_s.AddFieldToRecordType ("dti_version", uint16, lldb::eAccessPublic, 0);
-            dispatch_tsd_indexes_s.AddFieldToRecordType ("dti_queue_index", uint16, lldb::eAccessPublic, 0);
-            dispatch_tsd_indexes_s.AddFieldToRecordType ("dti_voucher_index", uint16, lldb::eAccessPublic, 0);
-            dispatch_tsd_indexes_s.AddFieldToRecordType ("dti_qos_class_index", uint16, lldb::eAccessPublic, 0);
-            dispatch_tsd_indexes_s.CompleteTagDeclarationDefinition();
+
+            ClangASTContext::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
+            ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_version", uint16, lldb::eAccessPublic, 0);
+            ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_queue_index", uint16, lldb::eAccessPublic, 0);
+            ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_voucher_index", uint16, lldb::eAccessPublic, 0);
+            ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_qos_class_index", uint16, lldb::eAccessPublic, 0);
+            ClangASTContext::CompleteTagDeclarationDefinition(dispatch_tsd_indexes_s);
 
             ProcessStructReader struct_reader (m_process, m_dispatch_tsd_indexes_addr, dispatch_tsd_indexes_s);
 
diff --git a/lldb/source/Symbol/CMakeLists.txt b/lldb/source/Symbol/CMakeLists.txt
index c6f551a..0d936b7 100644
--- a/lldb/source/Symbol/CMakeLists.txt
+++ b/lldb/source/Symbol/CMakeLists.txt
@@ -24,6 +24,7 @@
   Symtab.cpp
   Type.cpp
   TypeList.cpp
+  TypeSystem.cpp
   UnwindPlan.cpp
   UnwindTable.cpp
   Variable.cpp
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 3c3e2e5..bb762c2 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -41,6 +41,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/VTableBuilder.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
@@ -58,14 +59,18 @@
 #include <assert.h>
 #endif
 
+#include "llvm/Support/Signals.h"
+
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/dwarf.h"
 #include "lldb/Core/Flags.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/StreamFile.h"
 #include "lldb/Core/ThreadSafeDenseMap.h"
 #include "lldb/Core/UniqueCStringMap.h"
 #include "lldb/Expression/ASTDumper.h"
+#include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
 #include "lldb/Symbol/VerifyDecl.h"
 #include "lldb/Target/ExecutionContext.h"
@@ -572,57 +577,56 @@
 {
     if (!ast)
         return ClangASTType();
-    
     switch (encoding)
     {
     case eEncodingInvalid:
         if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
-            return ClangASTType (ast, ast->VoidPtrTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->VoidPtrTy);
         break;
         
     case eEncodingUint:
         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
-            return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->UnsignedCharTy);
         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
-            return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->UnsignedShortTy);
         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
-            return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->UnsignedIntTy);
         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
-            return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->UnsignedLongTy);
         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
-            return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->UnsignedLongLongTy);
         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
-            return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr());
+            return ClangASTType (ast, ast->UnsignedInt128Ty);
         break;
         
     case eEncodingSint:
         if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
-            return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->CharTy);
         if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
-            return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->ShortTy);
         if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
-            return ClangASTType (ast, ast->IntTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->IntTy);
         if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
-            return ClangASTType (ast, ast->LongTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->LongTy);
         if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
-            return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->LongLongTy);
         if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
-            return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr());
+            return ClangASTType (ast, ast->Int128Ty);
         break;
         
     case eEncodingIEEE754:
         if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
-            return ClangASTType (ast, ast->FloatTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->FloatTy);
         if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
-            return ClangASTType (ast, ast->DoubleTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->DoubleTy);
         if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
-            return ClangASTType (ast, ast->LongDoubleTy.getAsOpaquePtr());
+            return ClangASTType (ast, ast->LongDoubleTy);
         break;
         
     case eEncodingVector:
         // Sanity check that bit_size is a multiple of 8's.
         if (bit_size && !(bit_size & 0x7u))
-            return ClangASTType (ast, ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8).getAsOpaquePtr());
+            return ClangASTType (ast, ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8));
         break;
     }
     
@@ -827,7 +831,7 @@
         }
         
         if (clang_type)
-            return ClangASTType (ast, clang_type);
+            return ClangASTType (GetASTContext(ast), clang_type);
     }
     return ClangASTType();
 }
@@ -849,18 +853,18 @@
                 
             case DW_ATE_address:
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
-                    return ClangASTType (ast, ast->VoidPtrTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->VoidPtrTy);
                 break;
                 
             case DW_ATE_boolean:
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
-                    return ClangASTType (ast, ast->BoolTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->BoolTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
-                    return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->UnsignedCharTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
-                    return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->UnsignedShortTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
-                    return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->UnsignedIntTy);
                 break;
                 
             case DW_ATE_lo_user:
@@ -870,39 +874,39 @@
                     if (::strstr(type_name, "complex"))
                     {
                         ClangASTType complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
-                        return ClangASTType (ast, ast->getComplexType (complex_int_clang_type.GetQualType()).getAsOpaquePtr());
+                        return ClangASTType (ast, ast->getComplexType (GetQualType(complex_int_clang_type)));
                     }
                 }
                 break;
                 
             case DW_ATE_complex_float:
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
-                    return ClangASTType (ast, ast->FloatComplexTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->FloatComplexTy);
                 else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
-                    return ClangASTType (ast, ast->DoubleComplexTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->DoubleComplexTy);
                 else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
-                    return ClangASTType (ast, ast->LongDoubleComplexTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->LongDoubleComplexTy);
                 else 
                 {
                     ClangASTType complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
-                    return ClangASTType (ast, ast->getComplexType (complex_float_clang_type.GetQualType()).getAsOpaquePtr());
+                    return ClangASTType (ast, ast->getComplexType (GetQualType(complex_float_clang_type)));
                 }
                 break;
                 
             case DW_ATE_float:
                 if (streq(type_name, "float") && QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
-                    return ClangASTType (ast, ast->FloatTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->FloatTy);
                 if (streq(type_name, "double") && QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
-                    return ClangASTType (ast, ast->DoubleTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->DoubleTy);
                 if (streq(type_name, "long double") && QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
-                    return ClangASTType (ast, ast->LongDoubleTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->LongDoubleTy);
                 // Fall back to not requring a name match
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
-                    return ClangASTType (ast, ast->FloatTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->FloatTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
-                    return ClangASTType (ast, ast->DoubleTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->DoubleTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
-                    return ClangASTType (ast, ast->LongDoubleTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->LongDoubleTy);
                 break;
                 
             case DW_ATE_signed:
@@ -911,57 +915,57 @@
                     if (streq(type_name, "wchar_t") &&
                         QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy) &&
                         (getTargetInfo() && TargetInfo::isTypeSigned (getTargetInfo()->getWCharType())))
-                        return ClangASTType (ast, ast->WCharTy.getAsOpaquePtr());
+                        return ClangASTType (ast, ast->WCharTy);
                     if (streq(type_name, "void") &&
                         QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy))
-                        return ClangASTType (ast, ast->VoidTy.getAsOpaquePtr());
+                        return ClangASTType (ast, ast->VoidTy);
                     if (strstr(type_name, "long long") &&
                         QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
-                        return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr());
+                        return ClangASTType (ast, ast->LongLongTy);
                     if (strstr(type_name, "long") &&
                         QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
-                        return ClangASTType (ast, ast->LongTy.getAsOpaquePtr());
+                        return ClangASTType (ast, ast->LongTy);
                     if (strstr(type_name, "short") &&
                         QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
-                        return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr());
+                        return ClangASTType (ast, ast->ShortTy);
                     if (strstr(type_name, "char"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
-                            return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
+                            return ClangASTType (ast, ast->CharTy);
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
-                            return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr());
+                            return ClangASTType (ast, ast->SignedCharTy);
                     }
                     if (strstr(type_name, "int"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
-                            return ClangASTType (ast, ast->IntTy.getAsOpaquePtr());
+                            return ClangASTType (ast, ast->IntTy);
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
-                            return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr());
+                            return ClangASTType (ast, ast->Int128Ty);
                     }
                 }
                 // We weren't able to match up a type name, just search by size
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
-                    return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->CharTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
-                    return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->ShortTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
-                    return ClangASTType (ast, ast->IntTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->IntTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
-                    return ClangASTType (ast, ast->LongTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->LongTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
-                    return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->LongLongTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
-                    return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->Int128Ty);
                 break;
 
             case DW_ATE_signed_char:
                 if (ast->getLangOpts().CharIsSigned && type_name && streq(type_name, "char"))
                 {
                     if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
-                        return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
+                        return ClangASTType (ast, ast->CharTy);
                 }
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
-                    return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->SignedCharTy);
                 break;
                 
             case DW_ATE_unsigned:
@@ -972,62 +976,62 @@
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
                         {
                             if (!(getTargetInfo() && TargetInfo::isTypeSigned (getTargetInfo()->getWCharType())))
-                                return ClangASTType (ast, ast->WCharTy.getAsOpaquePtr());
+                                return ClangASTType (ast, ast->WCharTy);
                         }
                     }
                     if (strstr(type_name, "long long"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
-                            return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr());
+                            return ClangASTType (ast, ast->UnsignedLongLongTy);
                     }
                     else if (strstr(type_name, "long"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
-                            return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr());
+                            return ClangASTType (ast, ast->UnsignedLongTy);
                     }
                     else if (strstr(type_name, "short"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
-                            return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
+                            return ClangASTType (ast, ast->UnsignedShortTy);
                     }
                     else if (strstr(type_name, "char"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
-                            return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
+                            return ClangASTType (ast, ast->UnsignedCharTy);
                     }
                     else if (strstr(type_name, "int"))
                     {
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
-                            return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr());
+                            return ClangASTType (ast, ast->UnsignedIntTy);
                         if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
-                            return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr());
+                            return ClangASTType (ast, ast->UnsignedInt128Ty);
                     }
                 }
                 // We weren't able to match up a type name, just search by size
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
-                    return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->UnsignedCharTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
-                    return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->UnsignedShortTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
-                    return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->UnsignedIntTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
-                    return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->UnsignedLongTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
-                    return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->UnsignedLongLongTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
-                    return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->UnsignedInt128Ty);
                 break;
 
             case DW_ATE_unsigned_char:
                 if (!ast->getLangOpts().CharIsSigned && type_name && streq(type_name, "char"))
                 {
                     if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
-                        return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
+                        return ClangASTType (ast, ast->CharTy);
                 }
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
-                    return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->UnsignedCharTy);
                 if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
-                    return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
+                    return ClangASTType (ast, ast->UnsignedShortTy);
                 break;
                 
             case DW_ATE_imaginary_float:
@@ -1038,11 +1042,11 @@
                 {
                     if (streq(type_name, "char16_t"))
                     {
-                        return ClangASTType (ast, ast->Char16Ty.getAsOpaquePtr());
+                        return ClangASTType (ast, ast->Char16Ty);
                     }
                     else if (streq(type_name, "char32_t"))
                     {
-                        return ClangASTType (ast, ast->Char32Ty.getAsOpaquePtr());
+                        return ClangASTType (ast, ast->Char32Ty);
                     }
                 }
                 break;
@@ -1065,7 +1069,7 @@
 ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast)
 {
     if (ast)
-        return ClangASTType (ast, ast->UnknownAnyTy.getAsOpaquePtr());
+        return ClangASTType (ast, ast->UnknownAnyTy);
     return ClangASTType();
 }
 
@@ -1078,7 +1082,7 @@
     if (is_const)
         char_type.addConst();
     
-    return ClangASTType (ast, ast->getPointerType(char_type).getAsOpaquePtr());
+    return ClangASTType (ast, ast->getPointerType(char_type));
 }
 
 clang::DeclContext *
@@ -1092,15 +1096,17 @@
                            ClangASTType src)
 {
     FileSystemOptions file_system_options;
-    ASTContext *src_ast = src.GetASTContext();
+    ClangASTContext *src_ast = src.GetTypeSystem()->AsClangASTContext();
+    if (src_ast == nullptr)
+        return ClangASTType();
     FileManager file_manager (file_system_options);
     ASTImporter importer(*dst_ast, file_manager,
-                         *src_ast, file_manager,
+                         *src_ast->getASTContext(), file_manager,
                          false);
     
-    QualType dst (importer.Import(src.GetQualType()));
+    QualType dst (importer.Import(GetQualType(src)));
     
-    return ClangASTType (dst_ast, dst.getAsOpaquePtr());
+    return ClangASTType (dst_ast, dst);
 }
 
 
@@ -1123,15 +1129,15 @@
                                ClangASTType type2,
                                bool ignore_qualifiers)
 {
-    ASTContext *ast = type1.GetASTContext();
-    if (ast != type2.GetASTContext())
+    TypeSystem *ast = type1.GetTypeSystem();
+    if (!ast->AsClangASTContext() || ast != type2.GetTypeSystem())
         return false;
 
     if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
         return true;
 
-    QualType type1_qual = type1.GetQualType();
-    QualType type2_qual = type2.GetQualType();
+    QualType type1_qual = GetQualType(type1);
+    QualType type2_qual = GetQualType(type2);
     
     if (ignore_qualifiers)
     {
@@ -1139,7 +1145,7 @@
         type2_qual = type2_qual.getUnqualifiedType();
     }
     
-    return ast->hasSameType (type1_qual, type2_qual);
+    return ast->AsClangASTContext()->getASTContext()->hasSameType (type1_qual, type2_qual);
 }
 
 ClangASTType
@@ -1161,7 +1167,7 @@
     // AST if our AST didn't already exist...
     ASTContext *ast = &decl->getASTContext();
     if (ast)
-        return ClangASTType (ast, ast->getTagDeclType(decl).getAsOpaquePtr());
+        return ClangASTType (ast, ast->getTagDeclType(decl));
     return ClangASTType();
 }
 
@@ -1173,7 +1179,7 @@
     // AST if our AST didn't already exist...
     ASTContext *ast = &decl->getASTContext();
     if (ast)
-        return ClangASTType (ast, ast->getObjCInterfaceType(decl).getAsOpaquePtr());
+        return ClangASTType (ast, ast->getObjCInterfaceType(decl));
     return ClangASTType();
 }
 
@@ -1230,7 +1236,7 @@
         if (decl_ctx)
             decl_ctx->addDecl (decl);
 
-        return ClangASTType(ast, ast->getTagDeclType(decl).getAsOpaquePtr());
+        return ClangASTType(ast, ast->getTagDeclType(decl));
     }
     return ClangASTType();
 }
@@ -1441,7 +1447,7 @@
     {
         ASTContext *ast = getASTContext();
         if (ast)
-            return ClangASTType(ast, ast->getTagDeclType(class_template_specialization_decl).getAsOpaquePtr());
+            return ClangASTType(ast, ast->getTagDeclType(class_template_specialization_decl));
     }
     return ClangASTType();
 }
@@ -1764,7 +1770,7 @@
                                           SourceLocation(),
                                           SourceLocation(),
                                           DeclarationName (&ast->Idents.get(name)),
-                                          function_clang_type.GetQualType(),
+                                          GetQualType(function_clang_type),
                                           nullptr,
                                           (clang::StorageClass)storage,
                                           is_inline,
@@ -1778,7 +1784,7 @@
                                           SourceLocation(),
                                           SourceLocation(),
                                           DeclarationName (),
-                                          function_clang_type.GetQualType(),
+                                          GetQualType(function_clang_type),
                                           nullptr,
                                           (clang::StorageClass)storage,
                                           is_inline,
@@ -1806,7 +1812,7 @@
     assert (ast != nullptr);
     std::vector<QualType> qual_type_args;
     for (unsigned i=0; i<num_args; ++i)
-        qual_type_args.push_back (args[i].GetQualType());
+        qual_type_args.push_back (GetQualType(args[i]));
 
     // TODO: Detect calling convention in DWARF?
     FunctionProtoType::ExtProtoInfo proto_info;
@@ -1815,9 +1821,9 @@
     proto_info.TypeQuals = type_quals;
     proto_info.RefQualifier = RQ_None;
 
-    return ClangASTType (ast, ast->getFunctionType (result_type.GetQualType(),
+    return ClangASTType (ast, ast->getFunctionType (GetQualType(result_type),
                                                     qual_type_args,
-                                                    proto_info).getAsOpaquePtr());
+                                                    proto_info));
 }
 
 ParmVarDecl *
@@ -1830,7 +1836,7 @@
                                 SourceLocation(),
                                 SourceLocation(),
                                 name && name[0] ? &ast->Idents.get(name) : nullptr,
-                                param_type.GetQualType(),
+                                GetQualType(param_type),
                                 nullptr,
                                 (clang::StorageClass)storage,
                                 nullptr);
@@ -1858,7 +1864,7 @@
 
         if (is_vector)
         {
-            return ClangASTType (ast, ast->getExtVectorType(element_type.GetQualType(), element_count).getAsOpaquePtr());
+            return ClangASTType (ast, ast->getExtVectorType(GetQualType(element_type), element_count));
         }
         else
         {
@@ -1866,16 +1872,16 @@
             llvm::APInt ap_element_count (64, element_count);
             if (element_count == 0)
             {
-                return ClangASTType (ast, ast->getIncompleteArrayType (element_type.GetQualType(),
+                return ClangASTType (ast, ast->getIncompleteArrayType (GetQualType(element_type),
                                                                        ArrayType::Normal,
-                                                                       0).getAsOpaquePtr());
+                                                                       0));
             }
             else
             {
-                return ClangASTType (ast, ast->getConstantArrayType (element_type.GetQualType(),
+                return ClangASTType (ast, ast->getConstantArrayType (GetQualType(element_type),
                                                                      ap_element_count,
                                                                      ArrayType::Normal,
-                                                                     0).getAsOpaquePtr());
+                                                                     0));
             }
         }
     }
@@ -1891,34 +1897,34 @@
     if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
         return type;
     type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC);
-    type.StartTagDeclarationDefinition();
+    StartTagDeclarationDefinition(type);
     for (const auto& field : type_fields)
-        type.AddFieldToRecordType(field.first, field.second, lldb::eAccessPublic, 0);
+        AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic, 0);
     if (packed)
-        type.SetIsPacked();
-    type.CompleteTagDeclarationDefinition();
+        SetIsPacked(type);
+    CompleteTagDeclarationDefinition(type);
     return type;
 }
 
 #pragma mark Enumeration Types
 
 ClangASTType
-ClangASTContext::CreateEnumerationType 
+ClangASTContext::CreateEnumerationType
 (
-    const char *name, 
-    DeclContext *decl_ctx, 
-    const Declaration &decl, 
-    const ClangASTType &integer_clang_type
-)
+ const char *name,
+ DeclContext *decl_ctx,
+ const Declaration &decl,
+ 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();
-
+    
     // TODO: ask about these...
-//    const bool IsScoped = false;
-//    const bool IsFixed = false;
-
+    //    const bool IsScoped = false;
+    //    const bool IsFixed = false;
+    
     EnumDecl *enum_decl = EnumDecl::Create (*ast,
                                             decl_ctx,
                                             SourceLocation(),
@@ -1933,11 +1939,11 @@
     if (enum_decl)
     {
         // TODO: check if we should be setting the promotion type too?
-        enum_decl->setIntegerType(integer_clang_type.GetQualType());
+        enum_decl->setIntegerType(GetQualType(integer_clang_type));
         
         enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
         
-        return ClangASTType (ast, ast->getTagDeclType(enum_decl).getAsOpaquePtr());
+        return ClangASTType (ast, ast->getTagDeclType(enum_decl));
     }
     return ClangASTType();
 }
@@ -1992,42 +1998,42 @@
         if (is_signed)
         {
             if (bit_size == ast->getTypeSize(ast->SignedCharTy))
-                return ClangASTType(ast, ast->SignedCharTy.getAsOpaquePtr());
+                return ClangASTType(ast, ast->SignedCharTy);
             
             if (bit_size == ast->getTypeSize(ast->ShortTy))
-                return ClangASTType(ast, ast->ShortTy.getAsOpaquePtr());
+                return ClangASTType(ast, ast->ShortTy);
             
             if (bit_size == ast->getTypeSize(ast->IntTy))
-                return ClangASTType(ast, ast->IntTy.getAsOpaquePtr());
+                return ClangASTType(ast, ast->IntTy);
             
             if (bit_size == ast->getTypeSize(ast->LongTy))
-                return ClangASTType(ast, ast->LongTy.getAsOpaquePtr());
+                return ClangASTType(ast, ast->LongTy);
             
             if (bit_size == ast->getTypeSize(ast->LongLongTy))
-                return ClangASTType(ast, ast->LongLongTy.getAsOpaquePtr());
+                return ClangASTType(ast, ast->LongLongTy);
             
             if (bit_size == ast->getTypeSize(ast->Int128Ty))
-                return ClangASTType(ast, ast->Int128Ty.getAsOpaquePtr());
+                return ClangASTType(ast, ast->Int128Ty);
         }
         else
         {
             if (bit_size == ast->getTypeSize(ast->UnsignedCharTy))
-                return ClangASTType(ast, ast->UnsignedCharTy.getAsOpaquePtr());
+                return ClangASTType(ast, ast->UnsignedCharTy);
             
             if (bit_size == ast->getTypeSize(ast->UnsignedShortTy))
-                return ClangASTType(ast, ast->UnsignedShortTy.getAsOpaquePtr());
+                return ClangASTType(ast, ast->UnsignedShortTy);
             
             if (bit_size == ast->getTypeSize(ast->UnsignedIntTy))
-                return ClangASTType(ast, ast->UnsignedIntTy.getAsOpaquePtr());
+                return ClangASTType(ast, ast->UnsignedIntTy);
             
             if (bit_size == ast->getTypeSize(ast->UnsignedLongTy))
-                return ClangASTType(ast, ast->UnsignedLongTy.getAsOpaquePtr());
+                return ClangASTType(ast, ast->UnsignedLongTy);
             
             if (bit_size == ast->getTypeSize(ast->UnsignedLongLongTy))
-                return ClangASTType(ast, ast->UnsignedLongLongTy.getAsOpaquePtr());
+                return ClangASTType(ast, ast->UnsignedLongLongTy);
             
             if (bit_size == ast->getTypeSize(ast->UnsignedInt128Ty))
-                return ClangASTType(ast, ast->UnsignedInt128Ty.getAsOpaquePtr());
+                return ClangASTType(ast, ast->UnsignedInt128Ty);
         }
     }
     return ClangASTType();
@@ -2048,13 +2054,13 @@
     if (ast)
     {
         if (bit_size == ast->getTypeSize(ast->FloatTy))
-            return ClangASTType(ast, ast->FloatTy.getAsOpaquePtr());
+            return ClangASTType(ast, ast->FloatTy);
         else if (bit_size == ast->getTypeSize(ast->DoubleTy))
-            return ClangASTType(ast, ast->DoubleTy.getAsOpaquePtr());
+            return ClangASTType(ast, ast->DoubleTy);
         else if (bit_size == ast->getTypeSize(ast->LongDoubleTy))
-            return ClangASTType(ast, ast->LongDoubleTy.getAsOpaquePtr());
+            return ClangASTType(ast, ast->LongDoubleTy);
         else if (bit_size == ast->getTypeSize(ast->HalfTy))
-            return ClangASTType(ast, ast->HalfTy.getAsOpaquePtr());
+            return ClangASTType(ast, ast->HalfTy);
     }
     return ClangASTType();
 }
@@ -2204,3 +2210,6578 @@
     return false;
 }
 
+
+bool
+ClangASTContext::SetTagTypeKind (clang::QualType tag_qual_type, int kind) const
+{
+    const clang::Type *clang_type = tag_qual_type.getTypePtr();
+    if (clang_type)
+    {
+        const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
+        if (tag_type)
+        {
+            clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
+            if (tag_decl)
+            {
+                tag_decl->setTagKind ((clang::TagDecl::TagKind)kind);
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+
+bool
+ClangASTContext::SetDefaultAccessForRecordFields (clang::RecordDecl* record_decl,
+                                                  int default_accessibility,
+                                                  int *assigned_accessibilities,
+                                                  size_t num_assigned_accessibilities)
+{
+    if (record_decl)
+    {
+        uint32_t field_idx;
+        clang::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 ((clang::AccessSpecifier)default_accessibility);
+        }
+        return true;
+    }
+    return false;
+}
+
+clang::DeclContext *
+ClangASTContext::GetDeclContextForType (clang::QualType type)
+{
+    if (type.isNull())
+        return nullptr;
+    
+    clang::QualType qual_type = type.getCanonicalType();
+    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 llvm::cast<clang::ObjCObjectType>(qual_type.getTypePtr())->getInterface();
+        case clang::Type::ObjCObjectPointer:        return GetDeclContextForType (llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
+        case clang::Type::Record:                   return llvm::cast<clang::RecordType>(qual_type)->getDecl();
+        case clang::Type::Enum:                     return llvm::cast<clang::EnumType>(qual_type)->getDecl();
+        case clang::Type::Typedef:                  return GetDeclContextForType (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType());
+        case clang::Type::Elaborated:               return GetDeclContextForType (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
+        case clang::Type::Paren:                    return GetDeclContextForType (llvm::cast<clang::ParenType>(qual_type)->desugar());
+        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;
+        case clang::Type::Adjusted:                 break;
+            
+            // pointer type decayed from an array or function type.
+        case clang::Type::Decayed:                  break;
+    }
+    // No DeclContext in this type...
+    return nullptr;
+}
+
+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 = llvm::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 = llvm::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)
+                        {
+                            clang::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 = llvm::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)
+                        {
+                            clang::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, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion);
+            
+        case clang::Type::Elaborated:
+            return GetCompleteQualType (ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(), allow_completion);
+            
+        case clang::Type::Paren:
+            return GetCompleteQualType (ast, llvm::cast<clang::ParenType>(qual_type)->desugar(), allow_completion);
+            
+        default:
+            break;
+    }
+    
+    return true;
+}
+
+static clang::ObjCIvarDecl::AccessControl
+ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
+{
+    switch (access)
+    {
+        case eAccessNone:      return clang::ObjCIvarDecl::None;
+        case eAccessPublic:    return clang::ObjCIvarDecl::Public;
+        case eAccessPrivate:   return clang::ObjCIvarDecl::Private;
+        case eAccessProtected: return clang::ObjCIvarDecl::Protected;
+        case eAccessPackage:   return clang::ObjCIvarDecl::Package;
+    }
+    return clang::ObjCIvarDecl::None;
+}
+
+
+//----------------------------------------------------------------------
+// Tests
+//----------------------------------------------------------------------
+
+bool
+ClangASTContext::IsAggregateType (void* type)
+{
+    clang::QualType qual_type (GetCanonicalQualType(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 IsAggregateType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+        case clang::Type::Typedef:
+            return IsAggregateType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+        case clang::Type::Paren:
+            return IsAggregateType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+        default:
+            break;
+    }
+    // The clang type does have a value
+    return false;
+}
+
+bool
+ClangASTContext::IsArrayType (void* type,
+                                 ClangASTType *element_type_ptr,
+                                 uint64_t *size,
+                                 bool *is_incomplete)
+{
+    clang::QualType qual_type (GetCanonicalQualType(type));
+    
+    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 (getASTContext(), llvm::cast<clang::ConstantArrayType>(qual_type)->getElementType());
+            if (size)
+                *size = llvm::cast<clang::ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
+            return true;
+            
+        case clang::Type::IncompleteArray:
+            if (element_type_ptr)
+                element_type_ptr->SetClangType (getASTContext(), llvm::cast<clang::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 (getASTContext(), llvm::cast<clang::VariableArrayType>(qual_type)->getElementType());
+            if (size)
+                *size = 0;
+            return true;
+            
+        case clang::Type::DependentSizedArray:
+            if (element_type_ptr)
+                element_type_ptr->SetClangType (getASTContext(), llvm::cast<clang::DependentSizedArrayType>(qual_type)->getElementType());
+            if (size)
+                *size = 0;
+            return true;
+            
+        case clang::Type::Typedef:
+            return IsArrayType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+                               element_type_ptr,
+                               size,
+                               is_incomplete);
+        case clang::Type::Elaborated:
+            return IsArrayType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+                               element_type_ptr,
+                               size,
+                               is_incomplete);
+        case clang::Type::Paren:
+            return IsArrayType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+                               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
+ClangASTContext::IsVectorType (void* type,
+                                  ClangASTType *element_type,
+                                  uint64_t *size)
+{
+    clang::QualType qual_type (GetCanonicalQualType(type));
+    
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Vector:
+        {
+            const clang::VectorType *vector_type = qual_type->getAs<clang::VectorType>();
+            if (vector_type)
+            {
+                if (size)
+                    *size = vector_type->getNumElements();
+                if (element_type)
+                    *element_type = ClangASTType(getASTContext(), vector_type->getElementType());
+            }
+            return true;
+        }
+            break;
+        case clang::Type::ExtVector:
+        {
+            const clang::ExtVectorType *ext_vector_type = qual_type->getAs<clang::ExtVectorType>();
+            if (ext_vector_type)
+            {
+                if (size)
+                    *size = ext_vector_type->getNumElements();
+                if (element_type)
+                    *element_type = ClangASTType(getASTContext(), ext_vector_type->getElementType());
+            }
+            return true;
+        }
+        default:
+            break;
+    }
+    return false;
+}
+
+bool
+ClangASTContext::IsRuntimeGeneratedType (void* type)
+{
+    clang::DeclContext* decl_ctx = ClangASTContext::GetASTContext(getASTContext())->GetDeclContextForType(GetQualType(type));
+    if (!decl_ctx)
+        return false;
+    
+    if (!llvm::isa<clang::ObjCInterfaceDecl>(decl_ctx))
+        return false;
+    
+    clang::ObjCInterfaceDecl *result_iface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
+    
+    ClangASTMetadata* ast_metadata = ClangASTContext::GetMetadata(getASTContext(), result_iface_decl);
+    if (!ast_metadata)
+        return false;
+    return (ast_metadata->GetISAPtr() != 0);
+}
+
+bool
+ClangASTContext::IsCharType (void* type)
+{
+    return GetQualType(type).getUnqualifiedType()->isCharType();
+}
+
+
+bool
+ClangASTContext::IsCompleteType (void* type)
+{
+    const bool allow_completion = false;
+    return GetCompleteQualType (getASTContext(), GetQualType(type), allow_completion);
+}
+
+bool
+ClangASTContext::IsConst(void* type)
+{
+    return GetQualType(type).isConstQualified();
+}
+
+bool
+ClangASTContext::IsCStringType (void* type, uint32_t &length)
+{
+    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 = llvm::cast<clang::ConstantArrayType>(GetCanonicalQualType(type).getTypePtr())->getSize().getLimitedValue();
+            }
+            return true;
+            
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::IsFunctionType (void* type, bool *is_variadic_ptr)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        
+        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 IsFunctionType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+            case clang::Type::Elaborated:
+                return IsFunctionType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+            case clang::Type::Paren:
+                return IsFunctionType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+            case clang::Type::LValueReference:
+            case clang::Type::RValueReference:
+            {
+                const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+                if (reference_type)
+                    return IsFunctionType(reference_type->getPointeeType().getAsOpaquePtr());
+            }
+                break;
+        }
+    }
+    return false;
+}
+
+// Used to detect "Homogeneous Floating-point Aggregates"
+uint32_t
+ClangASTContext::IsHomogeneousAggregate (void* type, ClangASTType* base_type_ptr)
+{
+    if (!type)
+        return 0;
+    
+    clang::QualType qual_type(GetCanonicalQualType(type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteType (type))
+            {
+                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                {
+                    if (cxx_record_decl->getNumBases() ||
+                        cxx_record_decl->isDynamicClass())
+                        return 0;
+                }
+                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+                if (record_type)
+                {
+                    const clang::RecordDecl *record_decl = record_type->getDecl();
+                    if (record_decl)
+                    {
+                        // We are looking for a structure that contains only floating point types
+                        clang::RecordDecl::field_iterator field_pos, field_end = record_decl->field_end();
+                        uint32_t num_fields = 0;
+                        bool is_hva = false;
+                        bool is_hfa = false;
+                        clang::QualType base_qual_type;
+                        for (field_pos = record_decl->field_begin(); field_pos != field_end; ++field_pos)
+                        {
+                            clang::QualType field_qual_type = field_pos->getType();
+                            if (field_qual_type->isFloatingType())
+                            {
+                                if (field_qual_type->isComplexType())
+                                    return 0;
+                                else
+                                {
+                                    if (num_fields == 0)
+                                        base_qual_type = field_qual_type;
+                                    else
+                                    {
+                                        if (is_hva)
+                                            return 0;
+                                        is_hfa = true;
+                                        if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
+                                            return 0;
+                                    }
+                                }
+                            }
+                            else if (field_qual_type->isVectorType() || field_qual_type->isExtVectorType())
+                            {
+                                const clang::VectorType *array = field_qual_type.getTypePtr()->getAs<clang::VectorType>();
+                                if (array && array->getNumElements() <= 4)
+                                {
+                                    if (num_fields == 0)
+                                        base_qual_type = array->getElementType();
+                                    else
+                                    {
+                                        if (is_hfa)
+                                            return 0;
+                                        is_hva = true;
+                                        if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
+                                            return 0;
+                                    }
+                                }
+                                else
+                                    return 0;
+                            }
+                            else
+                                return 0;
+                            ++num_fields;
+                        }
+                        if (base_type_ptr)
+                            *base_type_ptr = ClangASTType (getASTContext(), base_qual_type);
+                        return num_fields;
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::Typedef:
+            return IsHomogeneousAggregate(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), base_type_ptr);
+            
+        case clang::Type::Elaborated:
+            return  IsHomogeneousAggregate(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), base_type_ptr);
+        default:
+            break;
+    }
+    return 0;
+}
+
+size_t
+ClangASTContext::GetNumberOfFunctionArguments (void* type)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+        if (func)
+            return func->getNumParams();
+    }
+    return 0;
+}
+
+ClangASTType
+ClangASTContext::GetFunctionArgumentAtIndex (void* type, const size_t index)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+        if (func)
+        {
+            if (index < func->getNumParams())
+                return ClangASTType(getASTContext(), func->getParamType(index));
+        }
+    }
+    return ClangASTType();
+}
+
+bool
+ClangASTContext::IsFunctionPointerType (void* type)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(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 IsFunctionPointerType (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+            case clang::Type::Elaborated:
+                return IsFunctionPointerType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());        case clang::Type::Paren:
+                return IsFunctionPointerType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+                
+            case clang::Type::LValueReference:
+            case clang::Type::RValueReference:
+            {
+                const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+                if (reference_type)
+                    return IsFunctionPointerType(reference_type->getPointeeType().getAsOpaquePtr());
+            }
+                break;
+        }
+    }
+    return false;
+    
+}
+
+bool
+ClangASTContext::IsIntegerType (void* type, bool &is_signed)
+{
+    if (!type)
+        return false;
+    
+    clang::QualType qual_type (GetCanonicalQualType(type));
+    const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());
+    
+    if (builtin_type)
+    {
+        if (builtin_type->isInteger())
+        {
+            is_signed = builtin_type->isSignedInteger();
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+bool
+ClangASTContext::IsPointerType (void* type, ClangASTType *pointee_type)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Builtin:
+                switch (llvm::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 (getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::BlockPointer:
+                if (pointee_type)
+                    pointee_type->SetClangType (getASTContext(), llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::Pointer:
+                if (pointee_type)
+                    pointee_type->SetClangType (getASTContext(), llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::MemberPointer:
+                if (pointee_type)
+                    pointee_type->SetClangType (getASTContext(), llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::Typedef:
+                return IsPointerType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), pointee_type);
+            case clang::Type::Elaborated:
+                return IsPointerType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), pointee_type);
+            case clang::Type::Paren:
+                return IsPointerType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), pointee_type);
+            default:
+                break;
+        }
+    }
+    if (pointee_type)
+        pointee_type->Clear();
+    return false;
+}
+
+
+bool
+ClangASTContext::IsPointerOrReferenceType (void* type, ClangASTType *pointee_type)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Builtin:
+                switch (llvm::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(getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::BlockPointer:
+                if (pointee_type)
+                    pointee_type->SetClangType(getASTContext(), llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::Pointer:
+                if (pointee_type)
+                    pointee_type->SetClangType(getASTContext(), llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::MemberPointer:
+                if (pointee_type)
+                    pointee_type->SetClangType(getASTContext(), llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
+                return true;
+            case clang::Type::LValueReference:
+                if (pointee_type)
+                    pointee_type->SetClangType(getASTContext(), llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
+                return true;
+            case clang::Type::RValueReference:
+                if (pointee_type)
+                    pointee_type->SetClangType(getASTContext(), llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
+                return true;
+            case clang::Type::Typedef:
+                return IsPointerOrReferenceType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), pointee_type);
+            case clang::Type::Elaborated:
+                return IsPointerOrReferenceType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), pointee_type);
+            case clang::Type::Paren:
+                return IsPointerOrReferenceType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), pointee_type);
+            default:
+                break;
+        }
+    }
+    if (pointee_type)
+        pointee_type->Clear();
+    return false;
+}
+
+
+bool
+ClangASTContext::IsReferenceType (void* type, ClangASTType *pointee_type, bool* is_rvalue)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        
+        switch (type_class)
+        {
+            case clang::Type::LValueReference:
+                if (pointee_type)
+                    pointee_type->SetClangType(getASTContext(), llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
+                if (is_rvalue)
+                    *is_rvalue = false;
+                return true;
+            case clang::Type::RValueReference:
+                if (pointee_type)
+                    pointee_type->SetClangType(getASTContext(), llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
+                if (is_rvalue)
+                    *is_rvalue = true;
+                return true;
+            case clang::Type::Typedef:
+                return IsReferenceType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), pointee_type, is_rvalue);
+            case clang::Type::Elaborated:
+                return IsReferenceType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), pointee_type, is_rvalue);
+            case clang::Type::Paren:
+                return IsReferenceType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), pointee_type, is_rvalue);
+                
+            default:
+                break;
+        }
+    }
+    if (pointee_type)
+        pointee_type->Clear();
+    return false;
+}
+
+bool
+ClangASTContext::IsFloatingPointType (void* type, uint32_t &count, bool &is_complex)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        
+        if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal()))
+        {
+            clang::BuiltinType::Kind kind = BT->getKind();
+            if (kind >= clang::BuiltinType::Float && kind <= clang::BuiltinType::LongDouble)
+            {
+                count = 1;
+                is_complex = false;
+                return true;
+            }
+        }
+        else if (const clang::ComplexType *CT = llvm::dyn_cast<clang::ComplexType>(qual_type->getCanonicalTypeInternal()))
+        {
+            if (IsFloatingPointType (CT->getElementType().getAsOpaquePtr(), count, is_complex))
+            {
+                count = 2;
+                is_complex = true;
+                return true;
+            }
+        }
+        else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>(qual_type->getCanonicalTypeInternal()))
+        {
+            if (IsFloatingPointType (VT->getElementType().getAsOpaquePtr(), count, is_complex))
+            {
+                count = VT->getNumElements();
+                is_complex = false;
+                return true;
+            }
+        }
+    }
+    count = 0;
+    is_complex = false;
+    return false;
+}
+
+
+bool
+ClangASTContext::IsDefined(void* type)
+{
+    if (!type)
+        return false;
+    
+    clang::QualType qual_type(GetQualType(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() != nullptr;
+            return false;
+        }
+    }
+    return true;
+}
+
+bool
+ClangASTContext::IsObjCClassType (const ClangASTType& type)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        
+        const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
+        
+        if (obj_pointer_type)
+            return obj_pointer_type->isObjCClassType();
+    }
+    return false;
+}
+
+bool
+ClangASTContext::IsObjCObjectOrInterfaceType (const ClangASTType& type)
+{
+    if (type)
+        return GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
+    return false;
+}
+
+bool
+ClangASTContext::IsPolymorphicClass (void* type)
+{
+    if (type)
+    {
+        clang::QualType qual_type(GetCanonicalQualType(type));
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Record:
+                if (GetCompleteType(type))
+                {
+                    const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+                    const clang::RecordDecl *record_decl = record_type->getDecl();
+                    if (record_decl)
+                    {
+                        const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+                        if (cxx_record_decl)
+                            return cxx_record_decl->isPolymorphic();
+                    }
+                }
+                break;
+                
+            default:
+                break;
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::IsPossibleDynamicType (void* type, ClangASTType *dynamic_pointee_type,
+                                           bool check_cplusplus,
+                                           bool check_objc)
+{
+    clang::QualType pointee_qual_type;
+    if (type)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        bool success = false;
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Builtin:
+                if (check_objc && llvm::cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId)
+                {
+                    if (dynamic_pointee_type)
+                        dynamic_pointee_type->SetClangType(this, type);
+                    return true;
+                }
+                break;
+                
+            case clang::Type::ObjCObjectPointer:
+                if (check_objc)
+                {
+                    if (dynamic_pointee_type)
+                        dynamic_pointee_type->SetClangType(getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
+                    return true;
+                }
+                break;
+                
+            case clang::Type::Pointer:
+                pointee_qual_type = llvm::cast<clang::PointerType>(qual_type)->getPointeeType();
+                success = true;
+                break;
+                
+            case clang::Type::LValueReference:
+            case clang::Type::RValueReference:
+                pointee_qual_type = llvm::cast<clang::ReferenceType>(qual_type)->getPointeeType();
+                success = true;
+                break;
+                
+            case clang::Type::Typedef:
+                return IsPossibleDynamicType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+                                             dynamic_pointee_type,
+                                             check_cplusplus,
+                                             check_objc);
+                
+            case clang::Type::Elaborated:
+                return IsPossibleDynamicType (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+                                              dynamic_pointee_type,
+                                              check_cplusplus,
+                                              check_objc);
+                
+            case clang::Type::Paren:
+                return IsPossibleDynamicType(llvm::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 (llvm::cast<clang::BuiltinType>(pointee_qual_type)->getKind())
+                {
+                    case clang::BuiltinType::UnknownAny:
+                    case clang::BuiltinType::Void:
+                        if (dynamic_pointee_type)
+                            dynamic_pointee_type->SetClangType(getASTContext(), pointee_qual_type);
+                        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)
+                    {
+                        clang::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 (getASTContext(), cxx_record_decl);
+                                if (metadata)
+                                    success = metadata->GetIsDynamicCXXType();
+                                else
+                                {
+                                    is_complete = ClangASTType(getASTContext(), 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(getASTContext(), 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(getASTContext(), pointee_qual_type);
+                        return true;
+                    }
+                    break;
+                    
+                default:
+                    break;
+            }
+        }
+    }
+    if (dynamic_pointee_type)
+        dynamic_pointee_type->Clear();
+    return false;
+}
+
+
+bool
+ClangASTContext::IsScalarType (void* type)
+{
+    if (!type)
+        return false;
+    
+    return (GetTypeInfo (nullptr) & eTypeIsScalar) != 0;
+}
+
+bool
+ClangASTContext::IsTypedefType (void* type)
+{
+    if (!type)
+        return false;
+    return GetQualType(type)->getTypeClass() == clang::Type::Typedef;
+}
+
+bool
+ClangASTContext::IsVoidType (void* type)
+{
+    if (!type)
+        return false;
+    return GetCanonicalQualType(type)->isVoidType();
+}
+
+bool
+ClangASTContext::GetCXXClassName (const ClangASTType& type, std::string &class_name)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        
+        clang::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 (const ClangASTType& type)
+{
+    if (!type)
+        return false;
+    
+    clang::QualType qual_type (GetCanonicalQualType(type));
+    if (qual_type->getAsCXXRecordDecl() != nullptr)
+        return true;
+    return false;
+}
+
+bool
+ClangASTContext::IsBeingDefined (void* type)
+{
+    if (!type)
+        return false;
+    clang::QualType qual_type (GetCanonicalQualType(type));
+    const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type);
+    if (tag_type)
+        return tag_type->isBeingDefined();
+    return false;
+}
+
+bool
+ClangASTContext::IsObjCObjectPointerType (const ClangASTType& type, ClangASTType *class_type_ptr)
+{
+    if (!type)
+        return false;
+
+    clang::QualType qual_type (GetCanonicalQualType(type));
+    
+    if (qual_type->isObjCObjectPointerType())
+    {
+        if (class_type_ptr)
+        {
+            if (!qual_type->isObjCClassType() &&
+                !qual_type->isObjCIdType())
+            {
+                const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
+                if (obj_pointer_type == nullptr)
+                    class_type_ptr->Clear();
+                else
+                    class_type_ptr->SetClangType (type.GetTypeSystem(), clang::QualType(obj_pointer_type->getInterfaceType(), 0).getAsOpaquePtr());
+            }
+        }
+        return true;
+    }
+    if (class_type_ptr)
+        class_type_ptr->Clear();
+    return false;
+}
+
+bool
+ClangASTContext::GetObjCClassName (const ClangASTType& type, std::string &class_name)
+{
+    if (!type)
+        return false;
+    
+    clang::QualType qual_type (GetCanonicalQualType(type));
+    
+    const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+    if (object_type)
+    {
+        const clang::ObjCInterfaceDecl *interface = object_type->getInterface();
+        if (interface)
+        {
+            class_name = interface->getNameAsString();
+            return true;
+        }
+    }
+    return false;
+}
+
+
+//----------------------------------------------------------------------
+// Type Completion
+//----------------------------------------------------------------------
+
+bool
+ClangASTContext::GetCompleteType (void* type)
+{
+    if (!type)
+        return false;
+    const bool allow_completion = true;
+    return GetCompleteQualType (getASTContext(), GetQualType(type), allow_completion);
+}
+
+ConstString
+ClangASTContext::GetTypeName (void* type)
+{
+    std::string type_name;
+    if (type)
+    {
+        clang::PrintingPolicy printing_policy (getASTContext()->getPrintingPolicy());
+        clang::QualType qual_type(GetQualType(type));
+        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();
+        }
+        else
+        {
+            type_name = qual_type.getAsString(printing_policy);
+        }
+    }
+    return ConstString(type_name);
+}
+
+uint32_t
+ClangASTContext::GetTypeInfo (void* type, ClangASTType *pointee_or_element_clang_type)
+{
+    if (!type)
+        return 0;
+    
+    if (pointee_or_element_clang_type)
+        pointee_or_element_clang_type->Clear();
+    
+    clang::QualType qual_type (GetQualType(type));
+    
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Builtin:
+        {
+            const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::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(getASTContext(), getASTContext()->ObjCBuiltinClassTy);
+                    builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
+                    break;
+                    
+                case clang::BuiltinType::ObjCSel:
+                    if (pointee_or_element_clang_type)
+                        pointee_or_element_clang_type->SetClangType(getASTContext(), getASTContext()->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(getASTContext(), qual_type->getPointeeType());
+            return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
+            
+        case clang::Type::Complex:
+        {
+            uint32_t complex_type_flags = eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
+            const clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>(qual_type->getCanonicalTypeInternal());
+            if (complex_type)
+            {
+                clang::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(getASTContext(), llvm::cast<clang::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(getASTContext(), llvm::cast<clang::EnumType>(qual_type)->getDecl()->getIntegerType());
+            return eTypeIsEnumeration | eTypeHasValue;
+            
+        case clang::Type::Elaborated:
+            return ClangASTType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetTypeInfo (pointee_or_element_clang_type);
+        case clang::Type::Paren:
+            return ClangASTType (getASTContext(), llvm::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(getASTContext(), llvm::cast<clang::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(getASTContext(), 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(getASTContext(), 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 (getASTContext(), llvm::cast<clang::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 clang::VectorType *vector_type = llvm::dyn_cast<clang::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
+ClangASTContext::GetMinimumLanguage (void* type)
+{
+    if (!type)
+        return lldb::eLanguageTypeC;
+    
+    // If the type is a reference, then resolve it to what it refers to first:
+    clang::QualType qual_type (GetCanonicalQualType(type).getNonReferenceType());
+    if (qual_type->isAnyPointerType())
+    {
+        if (qual_type->isObjCObjectPointerType())
+            return lldb::eLanguageTypeObjC;
+        
+        clang::QualType pointee_type (qual_type->getPointeeType());
+        if (pointee_type->getPointeeCXXRecordDecl() != nullptr)
+            return lldb::eLanguageTypeC_plus_plus;
+        if (pointee_type->isObjCObjectOrInterfaceType())
+            return lldb::eLanguageTypeObjC;
+        if (pointee_type->isObjCClassType())
+            return lldb::eLanguageTypeObjC;
+        if (pointee_type.getTypePtr() == getASTContext()->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 (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 ClangASTType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetMinimumLanguage();
+        }
+    }
+    return lldb::eLanguageTypeC;
+}
+
+lldb::TypeClass
+ClangASTContext::GetTypeClass (void* type)
+{
+    if (!type)
+        return lldb::eTypeClassInvalid;
+    
+    clang::QualType qual_type(GetQualType(type));
+    
+    switch (qual_type->getTypeClass())
+    {
+        case clang::Type::UnaryTransform:           break;
+        case clang::Type::FunctionNoProto:          return lldb::eTypeClassFunction;
+        case clang::Type::FunctionProto:            return lldb::eTypeClassFunction;
+        case clang::Type::IncompleteArray:          return lldb::eTypeClassArray;
+        case clang::Type::VariableArray:            return lldb::eTypeClassArray;
+        case clang::Type::ConstantArray:            return lldb::eTypeClassArray;
+        case clang::Type::DependentSizedArray:      return lldb::eTypeClassArray;
+        case clang::Type::DependentSizedExtVector:  return lldb::eTypeClassVector;
+        case clang::Type::ExtVector:                return lldb::eTypeClassVector;
+        case clang::Type::Vector:                   return lldb::eTypeClassVector;
+        case clang::Type::Builtin:                  return lldb::eTypeClassBuiltin;
+        case clang::Type::ObjCObjectPointer:        return lldb::eTypeClassObjCObjectPointer;
+        case clang::Type::BlockPointer:             return lldb::eTypeClassBlockPointer;
+        case clang::Type::Pointer:                  return lldb::eTypeClassPointer;
+        case clang::Type::LValueReference:          return lldb::eTypeClassReference;
+        case clang::Type::RValueReference:          return lldb::eTypeClassReference;
+        case clang::Type::MemberPointer:            return lldb::eTypeClassMemberPointer;
+        case clang::Type::Complex:
+            if (qual_type->isComplexType())
+                return lldb::eTypeClassComplexFloat;
+            else
+                return lldb::eTypeClassComplexInteger;
+        case clang::Type::ObjCObject:               return lldb::eTypeClassObjCObject;
+        case clang::Type::ObjCInterface:            return lldb::eTypeClassObjCInterface;
+        case clang::Type::Record:
+        {
+            const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+            const clang::RecordDecl *record_decl = record_type->getDecl();
+            if (record_decl->isUnion())
+                return lldb::eTypeClassUnion;
+            else if (record_decl->isStruct())
+                return lldb::eTypeClassStruct;
+            else
+                return lldb::eTypeClassClass;
+        }
+            break;
+        case clang::Type::Enum:                     return lldb::eTypeClassEnumeration;
+        case clang::Type::Typedef:                  return lldb::eTypeClassTypedef;
+        case clang::Type::UnresolvedUsing:          break;
+        case clang::Type::Paren:
+            return ClangASTType(getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetTypeClass();
+        case clang::Type::Elaborated:
+            return ClangASTType(getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetTypeClass();
+            
+        case clang::Type::Attributed:               break;
+        case clang::Type::TemplateTypeParm:         break;
+        case clang::Type::SubstTemplateTypeParm:    break;
+        case clang::Type::SubstTemplateTypeParmPack:break;
+        case clang::Type::Auto:                     break;
+        case clang::Type::InjectedClassName:        break;
+        case clang::Type::DependentName:            break;
+        case clang::Type::DependentTemplateSpecialization: break;
+        case clang::Type::PackExpansion:            break;
+            
+        case clang::Type::TypeOfExpr:               break;
+        case clang::Type::TypeOf:                   break;
+        case clang::Type::Decltype:                 break;
+        case clang::Type::TemplateSpecialization:   break;
+        case clang::Type::Atomic:                   break;
+            
+            // pointer type decayed from an array or function type.
+        case clang::Type::Decayed:                  break;
+        case clang::Type::Adjusted:                 break;
+    }
+    // We don't know hot to display this type...
+    return lldb::eTypeClassOther;
+    
+}
+
+unsigned
+ClangASTContext::GetTypeQualifiers(void* type)
+{
+    if (type)
+        return GetQualType(type).getQualifiers().getCVRQualifiers();
+    return 0;
+}
+
+//----------------------------------------------------------------------
+// Creating related types
+//----------------------------------------------------------------------
+
+ClangASTType
+ClangASTContext::AddConstModifier (const ClangASTType& type)
+{
+    if (type && type.GetTypeSystem()->AsClangASTContext())
+    {
+        clang::QualType result(GetQualType(type));
+        result.addConst();
+        return ClangASTType (type.GetTypeSystem(), result.getAsOpaquePtr());
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::AddRestrictModifier (const ClangASTType& type)
+{
+    if (type && type.GetTypeSystem()->AsClangASTContext())
+    {
+        clang::QualType result(GetQualType(type));
+        result.getQualifiers().setRestrict (true);
+        return ClangASTType (type.GetTypeSystem(), result.getAsOpaquePtr());
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::AddVolatileModifier (const ClangASTType& type)
+{
+    if (type && type.GetTypeSystem()->AsClangASTContext())
+    {
+        clang::QualType result(GetQualType(type));
+        result.getQualifiers().setVolatile (true);
+        return ClangASTType (type.GetTypeSystem(), result.getAsOpaquePtr());
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::GetArrayElementType (void* type, uint64_t *stride)
+{
+    if (type)
+    {
+        clang::QualType qual_type(GetCanonicalQualType(type));
+        
+        const clang::Type *array_eletype = qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
+        
+        if (!array_eletype)
+            return ClangASTType();
+        
+        ClangASTType element_type (getASTContext(), array_eletype->getCanonicalTypeUnqualified());
+        
+        // TODO: the real stride will be >= this value.. find the real one!
+        if (stride)
+            *stride = element_type.GetByteSize(nullptr);
+        
+        return element_type;
+        
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::GetCanonicalType (void* type)
+{
+    if (type)
+        return ClangASTType (getASTContext(), GetCanonicalQualType(type));
+    return ClangASTType();
+}
+
+static clang::QualType
+GetFullyUnqualifiedType_Impl (clang::ASTContext *ast, clang::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
+ClangASTContext::GetFullyUnqualifiedType (void* type)
+{
+    if (type)
+        return ClangASTType(getASTContext(), GetFullyUnqualifiedType_Impl(getASTContext(), GetQualType(type)));
+    return ClangASTType();
+}
+
+
+int
+ClangASTContext::GetFunctionArgumentCount (void* type)
+{
+    if (type)
+    {
+        const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType(type));
+        if (func)
+            return func->getNumParams();
+    }
+    return -1;
+}
+
+ClangASTType
+ClangASTContext::GetFunctionArgumentTypeAtIndex (void* type, size_t idx)
+{
+    if (type)
+    {
+        const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType(type));
+        if (func)
+        {
+            const uint32_t num_args = func->getNumParams();
+            if (idx < num_args)
+                return ClangASTType(getASTContext(), func->getParamType(idx));
+        }
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::GetFunctionReturnType (void* type)
+{
+    if (type)
+    {
+        clang::QualType qual_type(GetCanonicalQualType(type));
+        const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+        if (func)
+            return ClangASTType(getASTContext(), func->getReturnType());
+    }
+    return ClangASTType();
+}
+
+size_t
+ClangASTContext::GetNumMemberFunctions (void* type)
+{
+    size_t num_functions = 0;
+    if (type)
+    {
+        clang::QualType qual_type(GetCanonicalQualType(type));
+        switch (qual_type->getTypeClass()) {
+            case clang::Type::Record:
+                if (GetCompleteQualType (getASTContext(), qual_type))
+                {
+                    const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+                    const clang::RecordDecl *record_decl = record_type->getDecl();
+                    assert(record_decl);
+                    const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+                    if (cxx_record_decl)
+                        num_functions = std::distance(cxx_record_decl->method_begin(), cxx_record_decl->method_end());
+                }
+                break;
+                
+            case clang::Type::ObjCObjectPointer:
+                if (GetCompleteType(type))
+                {
+                    const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+                    if (objc_class_type)
+                    {
+                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+                        if (class_interface_decl)
+                            num_functions = std::distance(class_interface_decl->meth_begin(), class_interface_decl->meth_end());
+                    }
+                }
+                break;
+                
+            case clang::Type::ObjCObject:
+            case clang::Type::ObjCInterface:
+                if (GetCompleteType(type))
+                {
+                    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+                    if (objc_class_type)
+                    {
+                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                        if (class_interface_decl)
+                            num_functions = std::distance(class_interface_decl->meth_begin(), class_interface_decl->meth_end());
+                    }
+                }
+                break;
+                
+                
+            case clang::Type::Typedef:
+                return ClangASTType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumMemberFunctions();
+                
+            case clang::Type::Elaborated:
+                return ClangASTType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumMemberFunctions();
+                
+            case clang::Type::Paren:
+                return ClangASTType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumMemberFunctions();
+                
+            default:
+                break;
+        }
+    }
+    return num_functions;
+}
+
+TypeMemberFunctionImpl
+ClangASTContext::GetMemberFunctionAtIndex (void* type, size_t idx)
+{
+    std::string name("");
+    MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
+    ClangASTType clang_type{};
+    clang::ObjCMethodDecl *method_decl(nullptr);
+    if (type)
+    {
+        clang::QualType qual_type(GetCanonicalQualType(type));
+        switch (qual_type->getTypeClass()) {
+            case clang::Type::Record:
+                if (GetCompleteQualType (getASTContext(), qual_type))
+                {
+                    const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+                    const clang::RecordDecl *record_decl = record_type->getDecl();
+                    assert(record_decl);
+                    const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+                    if (cxx_record_decl)
+                    {
+                        auto method_iter = cxx_record_decl->method_begin();
+                        auto method_end = cxx_record_decl->method_end();
+                        if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
+                        {
+                            std::advance(method_iter, idx);
+                            auto method_decl = method_iter->getCanonicalDecl();
+                            if (method_decl)
+                            {
+                                if (!method_decl->getName().empty())
+                                    name.assign(method_decl->getName().data());
+                                else
+                                    name.clear();
+                                if (method_decl->isStatic())
+                                    kind = lldb::eMemberFunctionKindStaticMethod;
+                                else if (llvm::isa<clang::CXXConstructorDecl>(method_decl))
+                                    kind = lldb::eMemberFunctionKindConstructor;
+                                else if (llvm::isa<clang::CXXDestructorDecl>(method_decl))
+                                    kind = lldb::eMemberFunctionKindDestructor;
+                                else
+                                    kind = lldb::eMemberFunctionKindInstanceMethod;
+                                clang_type = ClangASTType(getASTContext(),method_decl->getType());
+                            }
+                        }
+                    }
+                }
+                break;
+                
+            case clang::Type::ObjCObjectPointer:
+                if (GetCompleteType(type))
+                {
+                    const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+                    if (objc_class_type)
+                    {
+                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+                        if (class_interface_decl)
+                        {
+                            auto method_iter = class_interface_decl->meth_begin();
+                            auto method_end = class_interface_decl->meth_end();
+                            if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
+                            {
+                                std::advance(method_iter, idx);
+                                method_decl = method_iter->getCanonicalDecl();
+                                if (method_decl)
+                                {
+                                    name = method_decl->getSelector().getAsString();
+                                    if (method_decl->isClassMethod())
+                                        kind = lldb::eMemberFunctionKindStaticMethod;
+                                    else
+                                        kind = lldb::eMemberFunctionKindInstanceMethod;
+                                }
+                            }
+                        }
+                    }
+                }
+                break;
+                
+            case clang::Type::ObjCObject:
+            case clang::Type::ObjCInterface:
+                if (GetCompleteType(type))
+                {
+                    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+                    if (objc_class_type)
+                    {
+                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                        if (class_interface_decl)
+                        {
+                            auto method_iter = class_interface_decl->meth_begin();
+                            auto method_end = class_interface_decl->meth_end();
+                            if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
+                            {
+                                std::advance(method_iter, idx);
+                                method_decl = method_iter->getCanonicalDecl();
+                                if (method_decl)
+                                {
+                                    name = method_decl->getSelector().getAsString();
+                                    if (method_decl->isClassMethod())
+                                        kind = lldb::eMemberFunctionKindStaticMethod;
+                                    else
+                                        kind = lldb::eMemberFunctionKindInstanceMethod;
+                                }
+                            }
+                        }
+                    }
+                }
+                break;
+                
+            case clang::Type::Typedef:
+                return GetMemberFunctionAtIndex(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), idx);
+                
+            case clang::Type::Elaborated:
+                return GetMemberFunctionAtIndex(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), idx);
+                
+            case clang::Type::Paren:
+                return GetMemberFunctionAtIndex(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx);
+                
+            default:
+                break;
+        }
+    }
+    
+    if (kind == eMemberFunctionKindUnknown)
+        return TypeMemberFunctionImpl();
+    if (method_decl)
+        return TypeMemberFunctionImpl(method_decl, name, kind);
+    if (type)
+        return TypeMemberFunctionImpl(clang_type, name, kind);
+    
+    return TypeMemberFunctionImpl();
+}
+
+ClangASTType
+ClangASTContext::GetLValueReferenceType (const ClangASTType& type)
+{
+    if (type)
+    {
+        ClangASTContext* ast = type.GetTypeSystem()->AsClangASTContext();
+        if (ast)
+            return ClangASTType(ast->getASTContext(), ast->getASTContext()->getLValueReferenceType(GetQualType(type)));
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::GetRValueReferenceType (const ClangASTType& type)
+{
+    if (type)
+    {
+        ClangASTContext* ast = type.GetTypeSystem()->AsClangASTContext();
+        if (ast)
+            return ClangASTType(ast->getASTContext(), ast->getASTContext()->getRValueReferenceType(GetQualType(type)));
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::GetNonReferenceType (void* type)
+{
+    if (type)
+        return ClangASTType(getASTContext(), GetQualType(type).getNonReferenceType());
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::CreateTypedefType (const ClangASTType& type,
+                                    const char *typedef_name,
+                                    clang::DeclContext *decl_ctx)
+{
+    if (type && typedef_name && typedef_name[0])
+    {
+        ClangASTContext* ast = type.GetTypeSystem()->AsClangASTContext();
+        if (!ast)
+            return ClangASTType();
+        clang::ASTContext* clang_ast = ast->getASTContext();
+        clang::QualType qual_type (GetQualType(type));
+        if (decl_ctx == nullptr)
+            decl_ctx = ast->getASTContext()->getTranslationUnitDecl();
+        clang::TypedefDecl *decl = clang::TypedefDecl::Create (*clang_ast,
+                                                               decl_ctx,
+                                                               clang::SourceLocation(),
+                                                               clang::SourceLocation(),
+                                                               &clang_ast->Idents.get(typedef_name),
+                                                               clang_ast->getTrivialTypeSourceInfo(qual_type));
+        
+        decl->setAccess(clang::AS_public); // TODO respect proper access specifier
+        
+        // Get a uniqued clang::QualType for the typedef decl type
+        return ClangASTType (clang_ast, clang_ast->getTypedefType (decl));
+    }
+    return ClangASTType();
+    
+}
+
+ClangASTType
+ClangASTContext::GetPointeeType (void* type)
+{
+    if (type)
+    {
+        clang::QualType qual_type(GetQualType(type));
+        return ClangASTType (getASTContext(), qual_type.getTypePtr()->getPointeeType());
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::GetPointerType (void* type)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetQualType(type));
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::ObjCObject:
+            case clang::Type::ObjCInterface:
+                return ClangASTType(getASTContext(), getASTContext()->getObjCObjectPointerType(qual_type));
+                
+            default:
+                return ClangASTType(getASTContext(), getASTContext()->getPointerType(qual_type));
+        }
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::GetTypedefedType (void* type)
+{
+    if (type)
+    {
+        const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(GetQualType(type));
+        if (typedef_type)
+            return ClangASTType (getASTContext(), typedef_type->getDecl()->getUnderlyingType());
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::RemoveFastQualifiers (const ClangASTType& type)
+{
+    if (type && type.GetTypeSystem()->AsClangASTContext())
+    {
+        clang::QualType qual_type(GetQualType(type));
+        qual_type.getQualifiers().removeFastQualifiers();
+        return ClangASTType (type.GetTypeSystem(), qual_type.getAsOpaquePtr());
+    }
+    return type;
+}
+
+
+//----------------------------------------------------------------------
+// Create related types using the current type's AST
+//----------------------------------------------------------------------
+
+ClangASTType
+ClangASTContext::GetBasicTypeFromAST (void* type, lldb::BasicType basic_type)
+{
+    if (type)
+        return ClangASTContext::GetBasicType(getASTContext(), basic_type);
+    return ClangASTType();
+}
+//----------------------------------------------------------------------
+// Exploring the type
+//----------------------------------------------------------------------
+
+uint64_t
+ClangASTContext::GetBitSize (void* type, ExecutionContextScope *exe_scope)
+{
+    if (GetCompleteType (type))
+    {
+        clang::QualType qual_type(GetCanonicalQualType(type));
+        switch (qual_type->getTypeClass())
+        {
+            case clang::Type::ObjCInterface:
+            case clang::Type::ObjCObject:
+            {
+                ExecutionContext exe_ctx (exe_scope);
+                Process *process = exe_ctx.GetProcessPtr();
+                if (process)
+                {
+                    ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
+                    if (objc_runtime)
+                    {
+                        uint64_t bit_size = 0;
+                        if (objc_runtime->GetTypeBitSize(ClangASTType(getASTContext(), qual_type), bit_size))
+                            return bit_size;
+                    }
+                }
+                else
+                {
+                    static bool g_printed = false;
+                    if (!g_printed)
+                    {
+                        StreamString s;
+                        DumpTypeDescription(&s);
+                        
+                        llvm::outs() << "warning: trying to determine the size of type ";
+                        llvm::outs() << s.GetString() << "\n";
+                        llvm::outs() << "without a valid ExecutionContext. this is not reliable. please file a bug against LLDB.\n";
+                        llvm::outs() << "backtrace:\n";
+                        llvm::sys::PrintStackTrace(llvm::outs());
+                        llvm::outs() << "\n";
+                        g_printed = true;
+                    }
+                }
+            }
+                // fallthrough
+            default:
+                const uint32_t bit_size = getASTContext()->getTypeSize (qual_type);
+                if (bit_size == 0)
+                {
+                    if (qual_type->isIncompleteArrayType())
+                        return getASTContext()->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
+                }
+                if (qual_type->isObjCObjectOrInterfaceType())
+                    return bit_size + getASTContext()->getTypeSize(getASTContext()->ObjCBuiltinClassTy);
+                return bit_size;
+        }
+    }
+    return 0;
+}
+
+size_t
+ClangASTContext::GetTypeBitAlign (void* type)
+{
+    if (GetCompleteType(type))
+        return getASTContext()->getTypeAlign(GetQualType(type));
+    return 0;
+}
+
+
+lldb::Encoding
+ClangASTContext::GetEncoding (void* type, uint64_t &count)
+{
+    if (!type)
+        return lldb::eEncodingInvalid;
+    
+    count = 1;
+    clang::QualType qual_type(GetCanonicalQualType(type));
+    
+    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:
+                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;
+        }
+            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();
+                if (complex_type)
+                    encoding = ClangASTType(getASTContext(), 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 ClangASTType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetEncoding(count);
+            
+        case clang::Type::Elaborated:
+            return ClangASTType(getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetEncoding(count);
+            
+        case clang::Type::Paren:
+            return ClangASTType(getASTContext(), llvm::cast<clang::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:
+        case clang::Type::Adjusted:
+            break;
+            
+            // pointer type decayed from an array or function type.
+        case clang::Type::Decayed:
+            break;
+    }
+    count = 0;
+    return lldb::eEncodingInvalid;
+}
+
+lldb::Format
+ClangASTContext::GetFormat (void* type)
+{
+    if (!type)
+        return lldb::eFormatDefault;
+    
+    clang::QualType qual_type(GetCanonicalQualType(type));
+    
+    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:
+                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;
+        }
+            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 (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetFormat();
+        case clang::Type::Auto:
+            return ClangASTType (getASTContext(), llvm::cast<clang::AutoType>(qual_type)->desugar()).GetFormat();
+        case clang::Type::Paren:
+            return ClangASTType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetFormat();
+        case clang::Type::Elaborated:
+            return ClangASTType (getASTContext(), llvm::cast<clang::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::Adjusted:
+            break;
+            
+            // pointer type decayed from an array or function type.
+        case clang::Type::Decayed:
+            break;
+    }
+    // We don't know hot to display this type...
+    return lldb::eFormatBytes;
+}
+
+static bool
+ObjCDeclHasIVars (clang::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
+ClangASTContext::GetNumChildren (void* type, bool omit_empty_base_classes)
+{
+    if (!type)
+        return 0;
+    
+    uint32_t num_children = 0;
+    clang::QualType qual_type(GetQualType(type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Builtin:
+            switch (llvm::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 (getASTContext(), qual_type))
+            {
+                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+                const clang::RecordDecl *record_decl = record_type->getDecl();
+                assert(record_decl);
+                const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::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.
+                        clang::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());
+                            
+                            // 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();
+                    }
+                    
+                }
+                clang::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 (getASTContext(), qual_type))
+            {
+                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+                assert (objc_class_type);
+                if (objc_class_type)
+                {
+                    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)
+                        {
+                            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 clang::ObjCObjectPointerType *pointer_type = llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr());
+            clang::QualType pointee_type = pointer_type->getPointeeType();
+            uint32_t num_pointee_children = ClangASTType (getASTContext(),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 = llvm::cast<clang::VectorType>(qual_type.getTypePtr())->getNumElements();
+            break;
+            
+        case clang::Type::ConstantArray:
+            num_children = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
+            break;
+            
+        case clang::Type::Pointer:
+        {
+            const clang::PointerType *pointer_type = llvm::cast<clang::PointerType>(qual_type.getTypePtr());
+            clang::QualType pointee_type (pointer_type->getPointeeType());
+            uint32_t num_pointee_children = ClangASTType (getASTContext(),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 = GetNumPointeeChildren (pointee_type);
+            }
+            else
+                num_children = num_pointee_children;
+        }
+            break;
+            
+        case clang::Type::LValueReference:
+        case clang::Type::RValueReference:
+        {
+            const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+            clang::QualType pointee_type = reference_type->getPointeeType();
+            uint32_t num_pointee_children = ClangASTType (getASTContext(), 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 (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumChildren (omit_empty_base_classes);
+            break;
+            
+        case clang::Type::Elaborated:
+            num_children = ClangASTType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumChildren (omit_empty_base_classes);
+            break;
+            
+        case clang::Type::Paren:
+            num_children = ClangASTType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumChildren (omit_empty_base_classes);
+            break;
+        default:
+            break;
+    }
+    return num_children;
+}
+
+lldb::BasicType
+ClangASTContext::GetBasicTypeEnumeration (void* type)
+{
+    if (type)
+    {
+        clang::QualType qual_type(GetQualType(type));
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        if (type_class == clang::Type::Builtin)
+        {
+            switch (llvm::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
+ClangASTContext::GetNumDirectBaseClasses (const ClangASTType& type)
+{
+    if (!type)
+        return 0;
+    ClangASTContext *ast = type.GetTypeSystem()->AsClangASTContext();
+    if (!ast)
+        return 0;
+    
+    uint32_t count = 0;
+    clang::QualType qual_type(GetCanonicalQualType(type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (ast->GetCompleteType(type.GetOpaqueQualType()))
+            {
+                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                    count = cxx_record_decl->getNumBases();
+            }
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            count = GetNumDirectBaseClasses(ast->GetPointeeType(type.GetOpaqueQualType()));
+            break;
+            
+        case clang::Type::ObjCObject:
+            if (ast->GetCompleteType(type.GetOpaqueQualType()))
+            {
+                const clang::ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
+                if (objc_class_type)
+                {
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    
+                    if (class_interface_decl && class_interface_decl->getSuperClass())
+                        count = 1;
+                }
+            }
+            break;
+        case clang::Type::ObjCInterface:
+            if (ast->GetCompleteType(type.GetOpaqueQualType()))
+            {
+                const clang::ObjCInterfaceType *objc_interface_type = qual_type->getAs<clang::ObjCInterfaceType>();
+                if (objc_interface_type)
+                {
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_interface_type->getInterface();
+                    
+                    if (class_interface_decl && class_interface_decl->getSuperClass())
+                        count = 1;
+                }
+            }
+            break;
+            
+            
+        case clang::Type::Typedef:
+            count = GetNumDirectBaseClasses(ClangASTType (ast->getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()));
+            break;
+            
+        case clang::Type::Elaborated:
+            count = GetNumDirectBaseClasses(ClangASTType (ast->getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()));
+            break;
+            
+        case clang::Type::Paren:
+            return GetNumDirectBaseClasses(ClangASTType (ast->getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()));
+            
+        default:
+            break;
+    }
+    return count;
+}
+
+uint32_t
+ClangASTContext::GetNumVirtualBaseClasses (const ClangASTType& type)
+{
+    if (!type)
+        return 0;
+    ClangASTContext *ast = type.GetTypeSystem()->AsClangASTContext();
+    if (!ast)
+        return 0;
+    
+    uint32_t count = 0;
+    clang::QualType qual_type(GetCanonicalQualType(type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (ast->GetCompleteType(type.GetOpaqueQualType()))
+            {
+                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                    count = cxx_record_decl->getNumVBases();
+            }
+            break;
+            
+        case clang::Type::Typedef:
+            count = GetNumVirtualBaseClasses(ClangASTType (ast->getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()));
+            break;
+            
+        case clang::Type::Elaborated:
+            count = GetNumVirtualBaseClasses(ClangASTType (ast->getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()));
+            break;
+            
+        case clang::Type::Paren:
+            count = GetNumVirtualBaseClasses(ClangASTType (ast->getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()));
+            break;
+            
+        default:
+            break;
+    }
+    return count;
+}
+
+uint32_t
+ClangASTContext::GetNumFields (void* type)
+{
+    if (!type)
+        return 0;
+    
+    uint32_t count = 0;
+    clang::QualType qual_type(GetCanonicalQualType(type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteType(type))
+            {
+                const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
+                if (record_type)
+                {
+                    clang::RecordDecl *record_decl = record_type->getDecl();
+                    if (record_decl)
+                    {
+                        uint32_t field_idx = 0;
+                        clang::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 (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumFields();
+            break;
+            
+        case clang::Type::Elaborated:
+            count = ClangASTType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumFields();
+            break;
+            
+        case clang::Type::Paren:
+            count = ClangASTType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumFields();
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            if (GetCompleteType(type))
+            {
+                const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+                if (objc_class_type)
+                {
+                    clang::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(type))
+            {
+                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+                if (objc_class_type)
+                {
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    
+                    if (class_interface_decl)
+                        count = class_interface_decl->ivar_size();
+                }
+            }
+            break;
+            
+        default:
+            break;
+    }
+    return count;
+}
+
+ClangASTType
+ClangASTContext::GetDirectBaseClassAtIndex (const ClangASTType& type, size_t idx, uint32_t *bit_offset_ptr)
+{
+    if (!type)
+        return ClangASTType();
+    ClangASTContext *ast = type.GetTypeSystem()->AsClangASTContext();
+    if (!ast)
+        return ClangASTType();
+    
+    clang::QualType qual_type(GetCanonicalQualType(type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (ast->GetCompleteType(type.GetOpaqueQualType()))
+            {
+                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                {
+                    uint32_t curr_idx = 0;
+                    clang::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 clang::ASTRecordLayout &record_layout = ast->getASTContext()->getASTRecordLayout(cxx_record_decl);
+                                const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::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 (ast, base_class->getType().getAsOpaquePtr());
+                        }
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            return GetDirectBaseClassAtIndex(ast->GetPointeeType(type.GetOpaqueQualType()), idx, bit_offset_ptr);
+            
+        case clang::Type::ObjCObject:
+            if (idx == 0 && ast->GetCompleteType(type.GetOpaqueQualType()))
+            {
+                const clang::ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
+                if (objc_class_type)
+                {
+                    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)
+                        {
+                            if (bit_offset_ptr)
+                                *bit_offset_ptr = 0;
+                            return ClangASTType (ast->getASTContext(), ast->getASTContext()->getObjCInterfaceType(superclass_interface_decl));
+                        }
+                    }
+                }
+            }
+            break;
+        case clang::Type::ObjCInterface:
+            if (idx == 0 && ast->GetCompleteType(type.GetOpaqueQualType()))
+            {
+                const clang::ObjCObjectType *objc_interface_type = qual_type->getAs<clang::ObjCInterfaceType>();
+                if (objc_interface_type)
+                {
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_interface_type->getInterface();
+                    
+                    if (class_interface_decl)
+                    {
+                        clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                        if (superclass_interface_decl)
+                        {
+                            if (bit_offset_ptr)
+                                *bit_offset_ptr = 0;
+                            return ClangASTType (ast->getASTContext(), ast->getASTContext()->getObjCInterfaceType(superclass_interface_decl));
+                        }
+                    }
+                }
+            }
+            break;
+            
+            
+        case clang::Type::Typedef:
+            return GetDirectBaseClassAtIndex (ClangASTType (ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), idx, bit_offset_ptr);
+            
+        case clang::Type::Elaborated:
+            return GetDirectBaseClassAtIndex (ClangASTType (ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), idx, bit_offset_ptr);
+            
+        case clang::Type::Paren:
+            return GetDirectBaseClassAtIndex (ClangASTType (ast, llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), idx, bit_offset_ptr);
+            
+        default:
+            break;
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::GetVirtualBaseClassAtIndex (const ClangASTType& type, size_t idx, uint32_t *bit_offset_ptr)
+{
+    if (!type)
+        return ClangASTType();
+    ClangASTContext *ast = type.GetTypeSystem()->AsClangASTContext();
+    if (!ast)
+        return ClangASTType();
+    
+    clang::QualType qual_type(GetCanonicalQualType(type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (ast->GetCompleteType(type.GetOpaqueQualType()))
+            {
+                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                {
+                    uint32_t curr_idx = 0;
+                    clang::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 clang::ASTRecordLayout &record_layout = ast->getASTContext()->getASTRecordLayout(cxx_record_decl);
+                                const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
+                                *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+                                
+                            }
+                            return ClangASTType (ast, base_class->getType().getAsOpaquePtr());
+                        }
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::Typedef:
+            return GetVirtualBaseClassAtIndex (ClangASTType (ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), idx, bit_offset_ptr);
+            
+        case clang::Type::Elaborated:
+            return GetVirtualBaseClassAtIndex (ClangASTType (ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), idx, bit_offset_ptr);
+            
+        case clang::Type::Paren:
+            return  GetVirtualBaseClassAtIndex (ClangASTType (ast, llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), idx, bit_offset_ptr);
+            
+        default:
+            break;
+    }
+    return ClangASTType();
+}
+
+static clang_type_t
+GetObjCFieldAtIndex (clang::ASTContext *ast,
+                     clang::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()))
+        {
+            clang::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 clang::ObjCIvarDecl* ivar_decl = *ivar_pos;
+                    
+                    clang::QualType ivar_qual_type(ivar_decl->getType());
+                    
+                    name.assign(ivar_decl->getNameAsString());
+                    
+                    if (bit_offset_ptr)
+                    {
+                        const clang::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)
+                        {
+                            clang::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 nullptr;
+}
+
+ClangASTType
+ClangASTContext::GetFieldAtIndex (void* type, size_t idx,
+                                     std::string& name,
+                                     uint64_t *bit_offset_ptr,
+                                     uint32_t *bitfield_bit_size_ptr,
+                                     bool *is_bitfield_ptr)
+{
+    if (!type)
+        return ClangASTType();
+    
+    clang::QualType qual_type(GetCanonicalQualType(type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteType(type))
+            {
+                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+                const clang::RecordDecl *record_decl = record_type->getDecl();
+                uint32_t field_idx = 0;
+                clang::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 clang::ASTRecordLayout &record_layout = getASTContext()->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)
+                            {
+                                clang::Expr *bitfield_bit_size_expr = field->getBitWidth();
+                                llvm::APSInt bitfield_apsint;
+                                if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *getASTContext()))
+                                {
+                                    *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+                                }
+                            }
+                        }
+                        if (is_bitfield_ptr)
+                            *is_bitfield_ptr = is_bitfield;
+                        
+                        return ClangASTType (getASTContext(), field->getType());
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            if (GetCompleteType(type))
+            {
+                const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+                if (objc_class_type)
+                {
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+                    return ClangASTType (this, GetObjCFieldAtIndex(getASTContext(), 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(type))
+            {
+                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+                assert (objc_class_type);
+                if (objc_class_type)
+                {
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    return ClangASTType (this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr));
+                }
+            }
+            break;
+            
+            
+        case clang::Type::Typedef:
+            return ClangASTType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).
+            GetFieldAtIndex (idx,
+                             name,
+                             bit_offset_ptr,
+                             bitfield_bit_size_ptr,
+                             is_bitfield_ptr);
+            
+        case clang::Type::Elaborated:
+            return ClangASTType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).
+            GetFieldAtIndex (idx,
+                             name,
+                             bit_offset_ptr,
+                             bitfield_bit_size_ptr,
+                             is_bitfield_ptr);
+            
+        case clang::Type::Paren:
+            return ClangASTType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).
+            GetFieldAtIndex (idx,
+                             name,
+                             bit_offset_ptr,
+                             bitfield_bit_size_ptr,
+                             is_bitfield_ptr);
+            
+        default:
+            break;
+    }
+    return ClangASTType();
+}
+
+// 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::QualType type)
+{
+    if (type.isNull())
+        return 0;
+    
+    clang::QualType qual_type(type.getCanonicalType());
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Builtin:
+            switch (llvm::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 GetNumPointeeChildren (llvm::cast<clang::ParenType>(qual_type)->desugar());
+        case clang::Type::Typedef:                  return GetNumPointeeChildren (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType());
+        case clang::Type::Elaborated:               return GetNumPointeeChildren (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
+        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
+ClangASTContext::GetChildClangTypeAtIndex (void* type, ExecutionContext *exe_ctx,
+                                              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,
+                                              ValueObject *valobj)
+{
+    if (!type)
+        return ClangASTType();
+    
+    clang::QualType parent_qual_type(GetCanonicalQualType(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 < GetNumChildren (type, omit_empty_base_classes);
+    uint32_t bit_offset;
+    switch (parent_type_class)
+    {
+        case clang::Type::Builtin:
+            if (idx_is_valid)
+            {
+                switch (llvm::cast<clang::BuiltinType>(parent_qual_type)->getKind())
+                {
+                    case clang::BuiltinType::ObjCId:
+                    case clang::BuiltinType::ObjCClass:
+                        child_name = "isa";
+                        child_byte_size = getASTContext()->getTypeSize(getASTContext()->ObjCBuiltinClassTy) / CHAR_BIT;
+                        return ClangASTType (getASTContext(), getASTContext()->ObjCBuiltinClassTy);
+                        
+                    default:
+                        break;
+                }
+            }
+            break;
+            
+        case clang::Type::Record:
+            if (idx_is_valid && GetCompleteType(type))
+            {
+                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(parent_qual_type.getTypePtr());
+                const clang::RecordDecl *record_decl = record_type->getDecl();
+                assert(record_decl);
+                const clang::ASTRecordLayout &record_layout = getASTContext()->getASTRecordLayout(record_decl);
+                uint32_t child_idx = 0;
+                
+                const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::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;
+                    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 = nullptr;
+                        
+                        // Skip empty base classes
+                        if (omit_empty_base_classes)
+                        {
+                            base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
+                            if (ClangASTContext::RecordHasFields(base_class_decl) == false)
+                                continue;
+                        }
+                        
+                        if (idx == child_idx)
+                        {
+                            if (base_class_decl == nullptr)
+                                base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
+                            
+                            
+                            if (base_class->isVirtual())
+                            {
+                                bool handled = false;
+                                if (valobj)
+                                {
+                                    Error err;
+                                    AddressType addr_type = eAddressTypeInvalid;
+                                    lldb::addr_t vtable_ptr_addr = valobj->GetCPPVTableAddress(addr_type);
+                                    
+                                    if (vtable_ptr_addr != LLDB_INVALID_ADDRESS && addr_type == eAddressTypeLoad)
+                                    {
+                                        
+                                        ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
+                                        Process *process = exe_ctx.GetProcessPtr();
+                                        if (process)
+                                        {
+                                            clang::VTableContextBase *vtable_ctx = getASTContext()->getVTableContext();
+                                            if (vtable_ctx)
+                                            {
+                                                if (vtable_ctx->isMicrosoft())
+                                                {
+                                                    clang::MicrosoftVTableContext *msoft_vtable_ctx = static_cast<clang::MicrosoftVTableContext *>(vtable_ctx);
+                                                    
+                                                    if (vtable_ptr_addr)
+                                                    {
+                                                        const lldb::addr_t vbtable_ptr_addr = vtable_ptr_addr + record_layout.getVBPtrOffset().getQuantity();
+                                                        
+                                                        const lldb::addr_t vbtable_ptr = process->ReadPointerFromMemory(vbtable_ptr_addr, err);
+                                                        if (vbtable_ptr != LLDB_INVALID_ADDRESS)
+                                                        {
+                                                            // Get the index into the virtual base table. The index is the index in uint32_t from vbtable_ptr
+                                                            const unsigned vbtable_index = msoft_vtable_ctx->getVBTableIndex(cxx_record_decl, base_class_decl);
+                                                            const lldb::addr_t base_offset_addr = vbtable_ptr + vbtable_index * 4;
+                                                            const uint32_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, 4, UINT32_MAX, err);
+                                                            if (base_offset != UINT32_MAX)
+                                                            {
+                                                                handled = true;
+                                                                bit_offset = base_offset * 8;
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                                else
+                                                {
+                                                    clang::ItaniumVTableContext *itanium_vtable_ctx = static_cast<clang::ItaniumVTableContext *>(vtable_ctx);
+                                                    if (vtable_ptr_addr)
+                                                    {
+                                                        const lldb::addr_t vtable_ptr = process->ReadPointerFromMemory(vtable_ptr_addr, err);
+                                                        if (vtable_ptr != LLDB_INVALID_ADDRESS)
+                                                        {
+                                                            clang::CharUnits base_offset_offset = itanium_vtable_ctx->getVirtualBaseOffsetOffset(cxx_record_decl, base_class_decl);
+                                                            const lldb::addr_t base_offset_addr = vtable_ptr + base_offset_offset.getQuantity();
+                                                            const uint32_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, 4, UINT32_MAX, err);
+                                                            if (base_offset != UINT32_MAX)
+                                                            {
+                                                                handled = true;
+                                                                bit_offset = base_offset * 8;
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                    
+                                }
+                                if (!handled)
+                                    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(getASTContext(), base_class->getType());
+                            child_name = base_class_clang_type.GetTypeName().AsCString("");
+                            uint64_t base_class_clang_type_bit_size = base_class_clang_type.GetBitSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+                            
+                            // 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;
+                clang::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 (getASTContext(), field->getType());
+                        assert(field_idx < record_layout.getFieldCount());
+                        child_byte_size = field_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+                        
+                        // 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 (getASTContext(), *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(type))
+            {
+                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(parent_qual_type.getTypePtr());
+                assert (objc_class_type);
+                if (objc_class_type)
+                {
+                    uint32_t child_idx = 0;
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    
+                    if (class_interface_decl)
+                    {
+                        
+                        const clang::ASTRecordLayout &interface_layout = getASTContext()->getASTObjCInterfaceLayout(class_interface_decl);
+                        clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                        if (superclass_interface_decl)
+                        {
+                            if (omit_empty_base_classes)
+                            {
+                                ClangASTType base_class_clang_type (getASTContext(), getASTContext()->getObjCInterfaceType(superclass_interface_decl));
+                                if (base_class_clang_type.GetNumChildren(omit_empty_base_classes) > 0)
+                                {
+                                    if (idx == 0)
+                                    {
+                                        clang::QualType ivar_qual_type(getASTContext()->getObjCInterfaceType(superclass_interface_decl));
+                                        
+                                        
+                                        child_name.assign(superclass_interface_decl->getNameAsString().c_str());
+                                        
+                                        clang::TypeInfo ivar_type_info = getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());
+                                        
+                                        child_byte_size = ivar_type_info.Width / 8;
+                                        child_byte_offset = 0;
+                                        child_is_base_class = true;
+                                        
+                                        return ClangASTType (getASTContext(), ivar_qual_type);
+                                    }
+                                    
+                                    ++child_idx;
+                                }
+                            }
+                            else
+                                ++child_idx;
+                        }
+                        
+                        const uint32_t superclass_idx = child_idx;
+                        
+                        if (idx < (child_idx + class_interface_decl->ivar_size()))
+                        {
+                            clang::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)
+                                {
+                                    clang::ObjCIvarDecl* ivar_decl = *ivar_pos;
+                                    
+                                    clang::QualType ivar_qual_type(ivar_decl->getType());
+                                    
+                                    child_name.assign(ivar_decl->getNameAsString().c_str());
+                                    
+                                    clang::TypeInfo  ivar_type_info = getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());
+                                    
+                                    child_byte_size = ivar_type_info.Width / 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 = nullptr;
+                                    if (exe_ctx)
+                                        process = exe_ctx->GetProcessPtr();
+                                    if (process)
+                                    {
+                                        ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
+                                        if (objc_runtime != nullptr)
+                                        {
+                                            ClangASTType parent_ast_type (getASTContext(), 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 == static_cast<int32_t>(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 (getASTContext(), 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 (getASTContext(), ivar_qual_type);
+                                }
+                                ++child_idx;
+                            }
+                        }
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            if (idx_is_valid)
+            {
+                ClangASTType pointee_clang_type (GetPointeeType(type));
+                
+                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,
+                                                                        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,
+                                                                        valobj);
+                }
+                else
+                {
+                    child_is_deref_of_parent = true;
+                    const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
+                    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(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+                        child_byte_offset = 0;
+                        return pointee_clang_type;
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::Vector:
+        case clang::Type::ExtVector:
+            if (idx_is_valid)
+            {
+                const clang::VectorType *array = llvm::cast<clang::VectorType>(parent_qual_type.getTypePtr());
+                if (array)
+                {
+                    ClangASTType element_type (getASTContext(), array->getElementType());
+                    if (element_type.GetCompleteType())
+                    {
+                        char element_name[64];
+                        ::snprintf (element_name, sizeof (element_name), "[%" PRIu64 "]", static_cast<uint64_t>(idx));
+                        child_name.assign(element_name);
+                        child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+                        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 clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe();
+                if (array)
+                {
+                    ClangASTType element_type (getASTContext(), array->getElementType());
+                    if (element_type.GetCompleteType())
+                    {
+                        char element_name[64];
+                        ::snprintf (element_name, sizeof (element_name), "[%" PRIu64 "]", static_cast<uint64_t>(idx));
+                        child_name.assign(element_name);
+                        child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+                        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(type));
+                
+                // 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,
+                                                                        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,
+                                                                        valobj);
+                }
+                else
+                {
+                    child_is_deref_of_parent = true;
+                    
+                    const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
+                    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(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+                        child_byte_offset = 0;
+                        return pointee_clang_type;
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::LValueReference:
+        case clang::Type::RValueReference:
+            if (idx_is_valid)
+            {
+                const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
+                ClangASTType pointee_clang_type (getASTContext(), 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,
+                                                                        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,
+                                                                        valobj);
+                }
+                else
+                {
+                    const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
+                    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(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+                        child_byte_offset = 0;
+                        return pointee_clang_type;
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::Typedef:
+        {
+            ClangASTType typedefed_clang_type (getASTContext(), llvm::cast<clang::TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType());
+            return typedefed_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+                                                                  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,
+                                                                  valobj);
+        }
+            break;
+            
+        case clang::Type::Elaborated:
+        {
+            ClangASTType elaborated_clang_type (getASTContext(), llvm::cast<clang::ElaboratedType>(parent_qual_type)->getNamedType());
+            return elaborated_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+                                                                   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,
+                                                                   valobj);
+        }
+            
+        case clang::Type::Paren:
+        {
+            ClangASTType paren_clang_type (getASTContext(), llvm::cast<clang::ParenType>(parent_qual_type)->desugar());
+            return paren_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+                                                              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,
+                                                              valobj);
+        }
+            
+            
+        default:
+            break;
+    }
+    return ClangASTType();
+}
+
+static uint32_t
+GetIndexForRecordBase
+(
+ const clang::RecordDecl *record_decl,
+ const clang::CXXBaseSpecifier *base_spec,
+ bool omit_empty_base_classes
+ )
+{
+    uint32_t child_idx = 0;
+    
+    const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+    
+    //    const char *super_name = record_decl->getNameAsCString();
+    //    const char *base_name = base_spec->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString();
+    //    printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
+    //
+    if (cxx_record_decl)
+    {
+        clang::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<clang::RecordType>()->getDecl()->getNameAsCString());
+            //
+            //
+            if (base_class == base_spec)
+                return child_idx;
+            ++child_idx;
+        }
+    }
+    
+    return UINT32_MAX;
+}
+
+
+static uint32_t
+GetIndexForRecordChild (const clang::RecordDecl *record_decl,
+                        clang::NamedDecl *canonical_decl,
+                        bool omit_empty_base_classes)
+{
+    uint32_t child_idx = ClangASTContext::GetNumBaseClasses (llvm::dyn_cast<clang::CXXRecordDecl>(record_decl),
+                                                             omit_empty_base_classes);
+    
+    clang::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
+ClangASTContext::GetIndexOfChildMemberWithName (void* type, const char *name,
+                                                   bool omit_empty_base_classes,
+                                                   std::vector<uint32_t>& child_indexes)
+{
+    if (type && name && name[0])
+    {
+        clang::QualType qual_type(GetCanonicalQualType(type));
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Record:
+                if (GetCompleteType(type))
+                {
+                    const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+                    const clang::RecordDecl *record_decl = record_type->getDecl();
+                    
+                    assert(record_decl);
+                    uint32_t child_idx = 0;
+                    
+                    const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+                    
+                    // Try and find a field that matches NAME
+                    clang::RecordDecl::field_iterator field, field_end;
+                    llvm::StringRef name_sref(name);
+                    for (field = record_decl->field_begin(), field_end = record_decl->field_end();
+                         field != field_end;
+                         ++field, ++child_idx)
+                    {
+                        llvm::StringRef field_name = field->getName();
+                        if (field_name.empty())
+                        {
+                            ClangASTType field_type(getASTContext(),field->getType());
+                            child_indexes.push_back(child_idx);
+                            if (field_type.GetIndexOfChildMemberWithName(name,  omit_empty_base_classes, child_indexes))
+                                return child_indexes.size();
+                            child_indexes.pop_back();
+                            
+                        }
+                        else if (field_name.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 clang::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...
+                        clang::IdentifierInfo & ident_ref = getASTContext()->Idents.get(name_sref);
+                        clang::DeclarationName decl_name(&ident_ref);
+                        
+                        clang::CXXBasePaths paths;
+                        if (cxx_record_decl->lookupInBases(clang::CXXRecordDecl::FindOrdinaryMember,
+                                                           decl_name.getAsOpaquePtr(),
+                                                           paths))
+                        {
+                            clang::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)
+                                {
+                                    clang::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 = llvm::cast<clang::RecordDecl>(elem.Base->getType()->getAs<clang::RecordType>()->getDecl());
+                                    }
+                                }
+                                for (clang::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(type))
+                {
+                    llvm::StringRef name_sref(name);
+                    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+                    assert (objc_class_type);
+                    if (objc_class_type)
+                    {
+                        uint32_t child_idx = 0;
+                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                        
+                        if (class_interface_decl)
+                        {
+                            clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+                            clang::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 clang::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 (getASTContext(), getASTContext()->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 (getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
+                return objc_object_clang_type.GetIndexOfChildMemberWithName (name,
+                                                                             omit_empty_base_classes,
+                                                                             child_indexes);
+            }
+                break;
+                
+                
+            case clang::Type::ConstantArray:
+            {
+                //                const clang::ConstantArrayType *array = llvm::cast<clang::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 = llvm::cast<MemberPointerType>(qual_type.getTypePtr());
+                //                clang::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 clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+                clang::QualType pointee_type(reference_type->getPointeeType());
+                ClangASTType pointee_clang_type (getASTContext(), 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(type));
+                
+                if (pointee_clang_type.IsAggregateType ())
+                {
+                    return pointee_clang_type.GetIndexOfChildMemberWithName (name,
+                                                                             omit_empty_base_classes,
+                                                                             child_indexes);
+                }
+            }
+                break;
+                
+            case clang::Type::Typedef:
+                return ClangASTType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildMemberWithName (name,
+                                                                                                                                                      omit_empty_base_classes,
+                                                                                                                                                      child_indexes);
+                
+            case clang::Type::Elaborated:
+                return ClangASTType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildMemberWithName (name,
+                                                                                                                                         omit_empty_base_classes,
+                                                                                                                                         child_indexes);
+                
+            case clang::Type::Paren:
+                return ClangASTType (getASTContext(), llvm::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
+ClangASTContext::GetIndexOfChildWithName (void* type, const char *name, bool omit_empty_base_classes)
+{
+    if (type && name && name[0])
+    {
+        clang::QualType qual_type(GetCanonicalQualType(type));
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        
+        switch (type_class)
+        {
+            case clang::Type::Record:
+                if (GetCompleteType(type))
+                {
+                    const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+                    const clang::RecordDecl *record_decl = record_type->getDecl();
+                    
+                    assert(record_decl);
+                    uint32_t child_idx = 0;
+                    
+                    const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+                    
+                    if (cxx_record_decl)
+                    {
+                        clang::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
+                            clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
+                            if (omit_empty_base_classes && ClangASTContext::RecordHasFields(base_class_decl) == false)
+                                continue;
+                            
+                            ClangASTType base_class_clang_type (getASTContext(), base_class->getType());
+                            std::string base_class_type_name (base_class_clang_type.GetTypeName().AsCString(""));
+                            if (base_class_type_name.compare (name) == 0)
+                                return child_idx;
+                            ++child_idx;
+                        }
+                    }
+                    
+                    // Try and find a field that matches NAME
+                    clang::RecordDecl::field_iterator field, field_end;
+                    llvm::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(type))
+                {
+                    llvm::StringRef name_sref(name);
+                    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+                    assert (objc_class_type);
+                    if (objc_class_type)
+                    {
+                        uint32_t child_idx = 0;
+                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                        
+                        if (class_interface_decl)
+                        {
+                            clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+                            clang::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 clang::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 (getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
+                return pointee_clang_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
+            }
+                break;
+                
+            case clang::Type::ConstantArray:
+            {
+                //                const clang::ConstantArrayType *array = llvm::cast<clang::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 = llvm::cast<MemberPointerType>(qual_type.getTypePtr());
+                //                clang::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 clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+                ClangASTType pointee_type (getASTContext(), reference_type->getPointeeType());
+                
+                if (pointee_type.IsAggregateType ())
+                {
+                    return pointee_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
+                }
+            }
+                break;
+                
+            case clang::Type::Pointer:
+            {
+                const clang::PointerType *pointer_type = llvm::cast<clang::PointerType>(qual_type.getTypePtr());
+                ClangASTType pointee_type (getASTContext(), 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 (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
+                
+            case clang::Type::Paren:
+                return ClangASTType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildWithName (name, omit_empty_base_classes);
+                
+            case clang::Type::Typedef:
+                return ClangASTType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
+                
+            default:
+                break;
+        }
+    }
+    return UINT32_MAX;
+}
+
+
+size_t
+ClangASTContext::GetNumTemplateArguments (const ClangASTType& type)
+{
+    if (!type)
+        return 0;
+    ClangASTContext* ast = type.GetTypeSystem()->AsClangASTContext();
+    if (ast)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Record:
+                if (ast->GetCompleteType(type.GetOpaqueQualType()))
+                {
+                    const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                    if (cxx_record_decl)
+                    {
+                        const clang::ClassTemplateSpecializationDecl *template_decl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(cxx_record_decl);
+                        if (template_decl)
+                            return template_decl->getTemplateArgs().size();
+                    }
+                }
+                break;
+                
+            case clang::Type::Typedef:
+                return GetNumTemplateArguments(ClangASTType (ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
+                
+            case clang::Type::Elaborated:
+                return GetNumTemplateArguments(ClangASTType (ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
+                
+            case clang::Type::Paren:
+                return GetNumTemplateArguments(ClangASTType (ast, llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+                
+            default:
+                break;
+        }
+    }
+    return 0;
+}
+
+ClangASTType
+ClangASTContext::GetTemplateArgument (const ClangASTType& type, size_t arg_idx, lldb::TemplateArgumentKind &kind)
+{
+    if (!type)
+        return ClangASTType();
+    ClangASTContext* ast = type.GetTypeSystem()->AsClangASTContext();
+    if (ast)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Record:
+                if (ast->GetCompleteType(type.GetOpaqueQualType()))
+                {
+                    const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                    if (cxx_record_decl)
+                    {
+                        const clang::ClassTemplateSpecializationDecl *template_decl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(cxx_record_decl);
+                        if (template_decl && arg_idx < template_decl->getTemplateArgs().size())
+                        {
+                            const clang::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(ast, template_arg.getAsType().getAsOpaquePtr());
+                                    
+                                case clang::TemplateArgument::Declaration:
+                                    kind = eTemplateArgumentKindDeclaration;
+                                    return ClangASTType();
+                                    
+                                case clang::TemplateArgument::Integral:
+                                    kind = eTemplateArgumentKindIntegral;
+                                    return ClangASTType(ast, template_arg.getIntegralType().getAsOpaquePtr());
+                                    
+                                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 clang::TemplateArgument::ArgKind");
+                                    break;
+                            }
+                        }
+                    }
+                }
+                break;
+                
+            case clang::Type::Typedef:
+                return GetTemplateArgument(ClangASTType (ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), arg_idx, kind);
+                
+            case clang::Type::Elaborated:
+                return GetTemplateArgument(ClangASTType (ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), arg_idx, kind);
+                
+            case clang::Type::Paren:
+                return GetTemplateArgument(ClangASTType (ast, llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), arg_idx, kind);
+                
+            default:
+                break;
+        }
+    }
+    kind = eTemplateArgumentKindNull;
+    return ClangASTType ();
+}
+
+static bool
+IsOperator (const char *name, clang::OverloadedOperatorKind &op_kind)
+{
+    if (name == nullptr || name[0] == '\0')
+        return false;
+    
+#define OPERATOR_PREFIX "operator"
+#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
+    
+    const char *post_op_name = nullptr;
+    
+    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 = clang::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 = clang::OO_New;
+            else if (strcmp (post_op_name, "new[]") == 0)
+                op_kind = clang::OO_Array_New;
+            break;
+            
+        case 'd':
+            if (no_space)
+                return false;
+            if (strcmp (post_op_name, "delete") == 0)
+                op_kind = clang::OO_Delete;
+            else if (strcmp (post_op_name, "delete[]") == 0)
+                op_kind = clang::OO_Array_Delete;
+            break;
+            
+        case '+':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Plus;
+            else if (post_op_name[2] == '\0')
+            {
+                if (post_op_name[1] == '=')
+                    op_kind = clang::OO_PlusEqual;
+                else if (post_op_name[1] == '+')
+                    op_kind = clang::OO_PlusPlus;
+            }
+            break;
+            
+        case '-':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Minus;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '=': op_kind = clang::OO_MinusEqual; break;
+                    case '-': op_kind = clang::OO_MinusMinus; break;
+                    case '>': op_kind = clang::OO_Arrow; break;
+                }
+            }
+            else if (post_op_name[3] == '\0')
+            {
+                if (post_op_name[2] == '*')
+                    op_kind = clang::OO_ArrowStar; break;
+            }
+            break;
+            
+        case '*':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Star;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = clang::OO_StarEqual;
+            break;
+            
+        case '/':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Slash;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = clang::OO_SlashEqual;
+            break;
+            
+        case '%':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Percent;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = clang::OO_PercentEqual;
+            break;
+            
+            
+        case '^':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Caret;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = clang::OO_CaretEqual;
+            break;
+            
+        case '&':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Amp;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '=': op_kind = clang::OO_AmpEqual; break;
+                    case '&': op_kind = clang::OO_AmpAmp; break;
+                }
+            }
+            break;
+            
+        case '|':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Pipe;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '=': op_kind = clang::OO_PipeEqual; break;
+                    case '|': op_kind = clang::OO_PipePipe; break;
+                }
+            }
+            break;
+            
+        case '~':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Tilde;
+            break;
+            
+        case '!':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Exclaim;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = clang::OO_ExclaimEqual;
+            break;
+            
+        case '=':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Equal;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = clang::OO_EqualEqual;
+            break;
+            
+        case '<':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Less;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '<': op_kind = clang::OO_LessLess; break;
+                    case '=': op_kind = clang::OO_LessEqual; break;
+                }
+            }
+            else if (post_op_name[3] == '\0')
+            {
+                if (post_op_name[2] == '=')
+                    op_kind = clang::OO_LessLessEqual;
+            }
+            break;
+            
+        case '>':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Greater;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '>': op_kind = clang::OO_GreaterGreater; break;
+                    case '=': op_kind = clang::OO_GreaterEqual; break;
+                }
+            }
+            else if (post_op_name[1] == '>' &&
+                     post_op_name[2] == '=' &&
+                     post_op_name[3] == '\0')
+            {
+                op_kind = clang::OO_GreaterGreaterEqual;
+            }
+            break;
+            
+        case ',':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Comma;
+            break;
+            
+        case '(':
+            if (post_op_name[1] == ')' && post_op_name[2] == '\0')
+                op_kind = clang::OO_Call;
+            break;
+            
+        case '[':
+            if (post_op_name[1] == ']' && post_op_name[2] == '\0')
+                op_kind = clang::OO_Subscript;
+            break;
+    }
+    
+    return true;
+}
+
+clang::EnumDecl *
+ClangASTContext::GetAsEnumDecl (const ClangASTType& type)
+{
+    const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type));
+    if (enutype)
+        return enutype->getDecl();
+    return NULL;
+}
+
+clang::RecordDecl *
+ClangASTContext::GetAsRecordDecl (const ClangASTType& type)
+{
+    const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(GetCanonicalQualType(type));
+    if (record_type)
+        return record_type->getDecl();
+    return nullptr;
+}
+
+clang::CXXRecordDecl *
+ClangASTContext::GetAsCXXRecordDecl (void* type)
+{
+    return GetCanonicalQualType(type)->getAsCXXRecordDecl();
+}
+
+clang::ObjCInterfaceDecl *
+ClangASTContext::GetAsObjCInterfaceDecl (const ClangASTType& type)
+{
+    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(GetCanonicalQualType(type));
+    if (objc_class_type)
+        return objc_class_type->getInterface();
+    return nullptr;
+}
+
+clang::FieldDecl *
+ClangASTContext::AddFieldToRecordType (const ClangASTType& type, const char *name,
+                                       const ClangASTType &field_clang_type,
+                                       AccessType access,
+                                       uint32_t bitfield_bit_size)
+{
+    if (!type.IsValid() || !field_clang_type.IsValid())
+        return nullptr;
+    ClangASTContext* ast = type.GetTypeSystem()->AsClangASTContext();
+    if (!ast)
+        return nullptr;
+    clang::ASTContext* clang_ast = ast->getASTContext();
+    
+    clang::FieldDecl *field = nullptr;
+    
+    clang::Expr *bit_width = nullptr;
+    if (bitfield_bit_size != 0)
+    {
+        llvm::APInt bitfield_bit_size_apint(clang_ast->getTypeSize(clang_ast->IntTy), bitfield_bit_size);
+        bit_width = new (*clang_ast)clang::IntegerLiteral (*clang_ast, bitfield_bit_size_apint, clang_ast->IntTy, clang::SourceLocation());
+    }
+    
+    clang::RecordDecl *record_decl = ast->GetAsRecordDecl (type);
+    if (record_decl)
+    {
+        field = clang::FieldDecl::Create (*clang_ast,
+                                          record_decl,
+                                          clang::SourceLocation(),
+                                          clang::SourceLocation(),
+                                          name ? &clang_ast->Idents.get(name) : nullptr,  // Identifier
+                                          GetQualType(field_clang_type),             // Field type
+                                          nullptr,                                    // TInfo *
+                                          bit_width,                                  // BitWidth
+                                          false,                                      // Mutable
+                                          clang::ICIS_NoInit);                        // HasInit
+        
+        if (!name)
+        {
+            // Determine whether this field corresponds to an anonymous
+            // struct or union.
+            if (const clang::TagType *TagT = field->getType()->getAs<clang::TagType>()) {
+                if (clang::RecordDecl *Rec = llvm::dyn_cast<clang::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
+    {
+        clang::ObjCInterfaceDecl *class_interface_decl = ast->GetAsObjCInterfaceDecl (type);
+        
+        if (class_interface_decl)
+        {
+            const bool is_synthesized = false;
+            
+            field_clang_type.GetCompleteType();
+            
+            field = clang::ObjCIvarDecl::Create (*clang_ast,
+                                                 class_interface_decl,
+                                                 clang::SourceLocation(),
+                                                 clang::SourceLocation(),
+                                                 name ? &clang_ast->Idents.get(name) : nullptr,   // Identifier
+                                                 GetQualType(field_clang_type),           // Field type
+                                                 nullptr,                                     // TypeSourceInfo *
+                                                 ConvertAccessTypeToObjCIvarAccessControl (access),
+                                                 bit_width,
+                                                 is_synthesized);
+            
+            if (field)
+            {
+                class_interface_decl->addDecl(field);
+                
+#ifdef LLDB_CONFIGURATION_DEBUG
+                VerifyDecl(field);
+#endif
+            }
+        }
+    }
+    return field;
+}
+
+void
+ClangASTContext::BuildIndirectFields (const ClangASTType& type)
+{
+    ClangASTContext* ast = nullptr;
+    if (type)
+        ast = type.GetTypeSystem()->AsClangASTContext();
+    if (!ast)
+        return;
+
+    clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
+    
+    if (!record_decl)
+        return;
+    
+    typedef llvm::SmallVector <clang::IndirectFieldDecl *, 1> IndirectFieldVector;
+    
+    IndirectFieldVector indirect_fields;
+    clang::RecordDecl::field_iterator field_pos;
+    clang::RecordDecl::field_iterator field_end_pos = record_decl->field_end();
+    clang::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())
+        {
+            clang::QualType field_qual_type = field_pos->getType();
+            
+            const clang::RecordType *field_record_type = field_qual_type->getAs<clang::RecordType>();
+            
+            if (!field_record_type)
+                continue;
+            
+            clang::RecordDecl *field_record_decl = field_record_type->getDecl();
+            
+            if (!field_record_decl)
+                continue;
+            
+            for (clang::RecordDecl::decl_iterator di = field_record_decl->decls_begin(), de = field_record_decl->decls_end();
+                 di != de;
+                 ++di)
+            {
+                if (clang::FieldDecl *nested_field_decl = llvm::dyn_cast<clang::FieldDecl>(*di))
+                {
+                    clang::NamedDecl **chain = new (*ast->getASTContext()) clang::NamedDecl*[2];
+                    chain[0] = *field_pos;
+                    chain[1] = nested_field_decl;
+                    clang::IndirectFieldDecl *indirect_field = clang::IndirectFieldDecl::Create(*ast->getASTContext(),
+                                                                                                record_decl,
+                                                                                                clang::SourceLocation(),
+                                                                                                nested_field_decl->getIdentifier(),
+                                                                                                nested_field_decl->getType(),
+                                                                                                chain,
+                                                                                                2);
+                    
+                    indirect_field->setImplicit();
+                    
+                    indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(field_pos->getAccess(),
+                                                                                     nested_field_decl->getAccess()));
+                    
+                    indirect_fields.push_back(indirect_field);
+                }
+                else if (clang::IndirectFieldDecl *nested_indirect_field_decl = llvm::dyn_cast<clang::IndirectFieldDecl>(*di))
+                {
+                    int nested_chain_size = nested_indirect_field_decl->getChainingSize();
+                    clang::NamedDecl **chain = new (*ast->getASTContext()) clang::NamedDecl*[nested_chain_size + 1];
+                    chain[0] = *field_pos;
+                    
+                    int chain_index = 1;
+                    for (clang::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++;
+                    }
+                    
+                    clang::IndirectFieldDecl *indirect_field = clang::IndirectFieldDecl::Create(*ast->getASTContext(),
+                                                                                                record_decl,
+                                                                                                clang::SourceLocation(),
+                                                                                                nested_indirect_field_decl->getIdentifier(),
+                                                                                                nested_indirect_field_decl->getType(),
+                                                                                                chain,
+                                                                                                nested_chain_size + 1);
+                    
+                    indirect_field->setImplicit();
+                    
+                    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);
+    }
+}
+
+void
+ClangASTContext::SetIsPacked (const ClangASTType& type)
+{
+    clang::RecordDecl *record_decl = GetAsRecordDecl(type);
+    
+    if (!record_decl)
+        return;
+    
+    record_decl->addAttr(clang::PackedAttr::CreateImplicit(*type.GetTypeSystem()->AsClangASTContext()->getASTContext()));
+}
+
+clang::VarDecl *
+ClangASTContext::AddVariableToRecordType (const ClangASTType& type, const char *name,
+                                          const ClangASTType &var_type,
+                                          AccessType access)
+{
+    clang::VarDecl *var_decl = nullptr;
+    
+    if (!type.IsValid() || !var_type.IsValid())
+        return nullptr;
+    ClangASTContext* ast = type.GetTypeSystem()->AsClangASTContext();
+    if (!ast)
+        return nullptr;
+    
+    clang::RecordDecl *record_decl = ast->GetAsRecordDecl (type);
+    if (record_decl)
+    {
+        var_decl = clang::VarDecl::Create (*ast->getASTContext(),                      // ASTContext &
+                                           record_decl,                                // DeclContext *
+                                           clang::SourceLocation(),                    // clang::SourceLocation StartLoc
+                                           clang::SourceLocation(),                    // clang::SourceLocation IdLoc
+                                           name ? &ast->getASTContext()->Idents.get(name) : nullptr,  // clang::IdentifierInfo *
+                                           GetQualType(var_type),                      // Variable clang::QualType
+                                           nullptr,                                    // TypeSourceInfo *
+                                           clang::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;
+}
+
+
+clang::CXXMethodDecl *
+ClangASTContext::AddMethodToCXXRecordType (void* type, 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 (!type || !method_clang_type.IsValid() || name == nullptr || name[0] == '\0')
+        return nullptr;
+    
+    clang::QualType record_qual_type(GetCanonicalQualType(type));
+    
+    clang::CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
+    
+    if (cxx_record_decl == nullptr)
+        return nullptr;
+    
+    clang::QualType method_qual_type (GetQualType(method_clang_type));
+    
+    clang::CXXMethodDecl *cxx_method_decl = nullptr;
+    
+    clang::DeclarationName decl_name (&getASTContext()->Idents.get(name));
+    
+    const clang::FunctionType *function_type = llvm::dyn_cast<clang::FunctionType>(method_qual_type.getTypePtr());
+    
+    if (function_type == nullptr)
+        return nullptr;
+    
+    const clang::FunctionProtoType *method_function_prototype (llvm::dyn_cast<clang::FunctionProtoType>(function_type));
+    
+    if (!method_function_prototype)
+        return nullptr;
+    
+    unsigned int num_params = method_function_prototype->getNumParams();
+    
+    clang::CXXDestructorDecl *cxx_dtor_decl(nullptr);
+    clang::CXXConstructorDecl *cxx_ctor_decl(nullptr);
+    
+    if (is_artificial)
+        return nullptr; // skip everything artificial
+    
+    if (name[0] == '~')
+    {
+        cxx_dtor_decl = clang::CXXDestructorDecl::Create (*getASTContext(),
+                                                          cxx_record_decl,
+                                                          clang::SourceLocation(),
+                                                          clang::DeclarationNameInfo (getASTContext()->DeclarationNames.getCXXDestructorName (getASTContext()->getCanonicalType (record_qual_type)), clang::SourceLocation()),
+                                                          method_qual_type,
+                                                          nullptr,
+                                                          is_inline,
+                                                          is_artificial);
+        cxx_method_decl = cxx_dtor_decl;
+    }
+    else if (decl_name == cxx_record_decl->getDeclName())
+    {
+        cxx_ctor_decl = clang::CXXConstructorDecl::Create (*getASTContext(),
+                                                           cxx_record_decl,
+                                                           clang::SourceLocation(),
+                                                           clang::DeclarationNameInfo (getASTContext()->DeclarationNames.getCXXConstructorName (getASTContext()->getCanonicalType (record_qual_type)), clang::SourceLocation()),
+                                                           method_qual_type,
+                                                           nullptr, // TypeSourceInfo *
+                                                           is_explicit,
+                                                           is_inline,
+                                                           is_artificial,
+                                                           false /*is_constexpr*/);
+        cxx_method_decl = cxx_ctor_decl;
+    }
+    else
+    {
+        clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None;
+        clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
+        
+        if (IsOperator (name, op_kind))
+        {
+            if (op_kind != clang::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 nullptr;
+                cxx_method_decl = clang::CXXMethodDecl::Create (*getASTContext(),
+                                                                cxx_record_decl,
+                                                                clang::SourceLocation(),
+                                                                clang::DeclarationNameInfo (getASTContext()->DeclarationNames.getCXXOperatorName (op_kind), clang::SourceLocation()),
+                                                                method_qual_type,
+                                                                nullptr, // TypeSourceInfo *
+                                                                SC,
+                                                                is_inline,
+                                                                false /*is_constexpr*/,
+                                                                clang::SourceLocation());
+            }
+            else if (num_params == 0)
+            {
+                // Conversion operators don't take params...
+                cxx_method_decl = clang::CXXConversionDecl::Create (*getASTContext(),
+                                                                    cxx_record_decl,
+                                                                    clang::SourceLocation(),
+                                                                    clang::DeclarationNameInfo (getASTContext()->DeclarationNames.getCXXConversionFunctionName (getASTContext()->getCanonicalType (function_type->getReturnType())), clang::SourceLocation()),
+                                                                    method_qual_type,
+                                                                    nullptr, // TypeSourceInfo *
+                                                                    is_inline,
+                                                                    is_explicit,
+                                                                    false /*is_constexpr*/,
+                                                                    clang::SourceLocation());
+            }
+        }
+        
+        if (cxx_method_decl == nullptr)
+        {
+            cxx_method_decl = clang::CXXMethodDecl::Create (*getASTContext(),
+                                                            cxx_record_decl,
+                                                            clang::SourceLocation(),
+                                                            clang::DeclarationNameInfo (decl_name, clang::SourceLocation()),
+                                                            method_qual_type,
+                                                            nullptr, // TypeSourceInfo *
+                                                            SC,
+                                                            is_inline,
+                                                            false /*is_constexpr*/,
+                                                            clang::SourceLocation());
+        }
+    }
+    
+    clang::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(clang::UsedAttr::CreateImplicit(*getASTContext()));
+    
+    // Populate the method decl with parameter decls
+    
+    llvm::SmallVector<clang::ParmVarDecl *, 12> params;
+    
+    for (unsigned param_index = 0;
+         param_index < num_params;
+         ++param_index)
+    {
+        params.push_back (clang::ParmVarDecl::Create (*getASTContext(),
+                                                      cxx_method_decl,
+                                                      clang::SourceLocation(),
+                                                      clang::SourceLocation(),
+                                                      nullptr, // anonymous
+                                                      method_function_prototype->getParamType(param_index),
+                                                      nullptr,
+                                                      clang::SC_None,
+                                                      nullptr));
+    }
+    
+    cxx_method_decl->setParams (llvm::ArrayRef<clang::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
+
+clang::CXXBaseSpecifier *
+ClangASTContext::CreateBaseClassSpecifier (void* type, AccessType access, bool is_virtual, bool base_of_class)
+{
+    if (type)
+        return new clang::CXXBaseSpecifier (clang::SourceRange(),
+                                            is_virtual,
+                                            base_of_class,
+                                            ClangASTContext::ConvertAccessTypeToAccessSpecifier (access),
+                                            getASTContext()->getTrivialTypeSourceInfo (GetQualType(type)),
+                                            clang::SourceLocation());
+    return nullptr;
+}
+
+void
+ClangASTContext::DeleteBaseClassSpecifiers (clang::CXXBaseSpecifier **base_classes, unsigned num_base_classes)
+{
+    for (unsigned i=0; i<num_base_classes; ++i)
+    {
+        delete base_classes[i];
+        base_classes[i] = nullptr;
+    }
+}
+
+bool
+ClangASTContext::SetBaseClassesForClassType (void* type, clang::CXXBaseSpecifier const * const *base_classes,
+                                                unsigned num_base_classes)
+{
+    if (type)
+    {
+        clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type);
+        if (cxx_record_decl)
+        {
+            cxx_record_decl->setBases(base_classes, num_base_classes);
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::SetObjCSuperClass (const ClangASTType& type, const ClangASTType &superclass_clang_type)
+{
+    if (type && superclass_clang_type.IsValid() && superclass_clang_type.GetTypeSystem() == type.GetTypeSystem())
+    {
+        clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl (type);
+        clang::ObjCInterfaceDecl *super_interface_decl = GetAsObjCInterfaceDecl (superclass_clang_type);
+        if (class_interface_decl && super_interface_decl)
+        {
+            class_interface_decl->setSuperClass(super_interface_decl);
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::AddObjCClassProperty (const ClangASTType& type,
+                                       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)
+{
+    if (!type || !property_clang_type.IsValid() || property_name == nullptr || property_name[0] == '\0')
+        return false;
+    ClangASTContext* ast = type.GetTypeSystem()->AsClangASTContext();
+    if (!ast)
+        return false;
+    clang::ASTContext* clang_ast = ast->getASTContext();
+    
+    clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl (type);
+    
+    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 (clang_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 = clang_ast->getTrivialTypeSourceInfo (ivar_decl->getType());
+            else
+                prop_type_source = clang_ast->getTrivialTypeSourceInfo (GetQualType(property_clang_type));
+            
+            clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create (*clang_ast,
+                                                                                      class_interface_decl,
+                                                                                      clang::SourceLocation(), // Source Location
+                                                                                      &clang_ast->Idents.get(property_name),
+                                                                                      clang::SourceLocation(), //Source Location for AT
+                                                                                      clang::SourceLocation(), //Source location for (
+                                                                                      prop_type_source);
+            
+            if (property_decl)
+            {
+                if (metadata)
+                    ClangASTContext::SetMetadata(clang_ast, property_decl, *metadata);
+                
+                class_interface_decl->addDecl (property_decl);
+                
+                clang::Selector setter_sel, getter_sel;
+                
+                if (property_setter_name != nullptr)
+                {
+                    std::string property_setter_no_colon(property_setter_name, strlen(property_setter_name) - 1);
+                    clang::IdentifierInfo *setter_ident = &clang_ast->Idents.get(property_setter_no_colon.c_str());
+                    setter_sel = clang_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 = &clang_ast->Idents.get(setter_sel_string.c_str());
+                    setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident);
+                }
+                property_decl->setSetterName(setter_sel);
+                property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_setter);
+                
+                if (property_getter_name != nullptr)
+                {
+                    clang::IdentifierInfo *getter_ident = &clang_ast->Idents.get(property_getter_name);
+                    getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident);
+                }
+                else
+                {
+                    clang::IdentifierInfo *getter_ident = &clang_ast->Idents.get(property_name);
+                    getter_sel = clang_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 clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None;
+                    const bool HasRelatedResultType = false;
+                    
+                    clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create (*clang_ast,
+                                                                                   clang::SourceLocation(),
+                                                                                   clang::SourceLocation(),
+                                                                                   getter_sel,
+                                                                                   GetQualType(property_clang_type_to_access),
+                                                                                   nullptr,
+                                                                                   class_interface_decl,
+                                                                                   isInstance,
+                                                                                   isVariadic,
+                                                                                   isSynthesized,
+                                                                                   isImplicitlyDeclared,
+                                                                                   isDefined,
+                                                                                   impControl,
+                                                                                   HasRelatedResultType);
+                    
+                    if (getter && metadata)
+                        ClangASTContext::SetMetadata(clang_ast, getter, *metadata);
+                    
+                    if (getter)
+                    {
+                        getter->setMethodParams(*clang_ast, llvm::ArrayRef<clang::ParmVarDecl*>(), llvm::ArrayRef<clang::SourceLocation>());
+                        
+                        class_interface_decl->addDecl(getter);
+                    }
+                }
+                
+                if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel))
+                {
+                    clang::QualType result_type = clang_ast->VoidTy;
+                    
+                    const bool isInstance = true;
+                    const bool isVariadic = false;
+                    const bool isSynthesized = false;
+                    const bool isImplicitlyDeclared = true;
+                    const bool isDefined = false;
+                    const clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None;
+                    const bool HasRelatedResultType = false;
+                    
+                    clang::ObjCMethodDecl *setter = clang::ObjCMethodDecl::Create (*clang_ast,
+                                                                                   clang::SourceLocation(),
+                                                                                   clang::SourceLocation(),
+                                                                                   setter_sel,
+                                                                                   result_type,
+                                                                                   nullptr,
+                                                                                   class_interface_decl,
+                                                                                   isInstance,
+                                                                                   isVariadic,
+                                                                                   isSynthesized,
+                                                                                   isImplicitlyDeclared,
+                                                                                   isDefined,
+                                                                                   impControl,
+                                                                                   HasRelatedResultType);
+                    
+                    if (setter && metadata)
+                        ClangASTContext::SetMetadata(clang_ast, setter, *metadata);
+                    
+                    llvm::SmallVector<clang::ParmVarDecl *, 1> params;
+                    
+                    params.push_back (clang::ParmVarDecl::Create (*clang_ast,
+                                                                  setter,
+                                                                  clang::SourceLocation(),
+                                                                  clang::SourceLocation(),
+                                                                  nullptr, // anonymous
+                                                                  GetQualType(property_clang_type_to_access),
+                                                                  nullptr,
+                                                                  clang::SC_Auto,
+                                                                  nullptr));
+                    
+                    if (setter)
+                    {
+                        setter->setMethodParams(*clang_ast, llvm::ArrayRef<clang::ParmVarDecl*>(params), llvm::ArrayRef<clang::SourceLocation>());
+                        
+                        class_interface_decl->addDecl(setter);
+                    }
+                }
+                
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::IsObjCClassTypeAndHasIVars (const ClangASTType& type, bool check_superclass)
+{
+    clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl (type);
+    if (class_interface_decl)
+        return ObjCDeclHasIVars (class_interface_decl, check_superclass);
+    return false;
+}
+
+
+clang::ObjCMethodDecl *
+ClangASTContext::AddMethodToObjCObjectType (const ClangASTType& type,
+                                            const char *name,  // the full symbol name as seen in the symbol table (void* type, "-[NString stringWithCString:]")
+                                            const ClangASTType &method_clang_type,
+                                            lldb::AccessType access,
+                                            bool is_artificial)
+{
+    if (!type || !method_clang_type.IsValid())
+        return nullptr;
+    
+    clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
+    
+    if (class_interface_decl == nullptr)
+        return nullptr;
+    clang::ASTContext* ast = type.GetTypeSystem()->AsClangASTContext()->getASTContext();
+    
+    const char *selector_start = ::strchr (name, ' ');
+    if (selector_start == nullptr)
+        return nullptr;
+    
+    selector_start++;
+    llvm::SmallVector<clang::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 (&ast->Idents.get (llvm::StringRef (start, len)));
+        if (has_arg)
+            len += 1;
+    }
+    
+    
+    if (selector_idents.size() == 0)
+        return nullptr;
+    
+    clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
+                                                                    selector_idents.data());
+    
+    clang::QualType method_qual_type (GetQualType(method_clang_type));
+    
+    // Populate the method decl with parameter decls
+    const clang::Type *method_type(method_qual_type.getTypePtr());
+    
+    if (method_type == nullptr)
+        return nullptr;
+    
+    const clang::FunctionProtoType *method_function_prototype (llvm::dyn_cast<clang::FunctionProtoType>(method_type));
+    
+    if (!method_function_prototype)
+        return nullptr;
+    
+    
+    bool is_variadic = false;
+    bool is_synthesized = false;
+    bool is_defined = false;
+    clang::ObjCMethodDecl::ImplementationControl imp_control = clang::ObjCMethodDecl::None;
+    
+    const unsigned num_args = method_function_prototype->getNumParams();
+    
+    if (num_args != num_selectors_with_args)
+        return nullptr; // some debug information is corrupt.  We are not going to deal with it.
+    
+    clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create (*ast,
+                                                                             clang::SourceLocation(), // beginLoc,
+                                                                             clang::SourceLocation(), // endLoc,
+                                                                             method_selector,
+                                                                             method_function_prototype->getReturnType(),
+                                                                             nullptr, // TypeSourceInfo *ResultTInfo,
+                                                                             ClangASTContext::GetASTContext(ast)->GetDeclContextForType(GetQualType(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 == nullptr)
+        return nullptr;
+    
+    if (num_args > 0)
+    {
+        llvm::SmallVector<clang::ParmVarDecl *, 12> params;
+        
+        for (unsigned param_index = 0; param_index < num_args; ++param_index)
+        {
+            params.push_back (clang::ParmVarDecl::Create (*ast,
+                                                          objc_method_decl,
+                                                          clang::SourceLocation(),
+                                                          clang::SourceLocation(),
+                                                          nullptr, // anonymous
+                                                          method_function_prototype->getParamType(param_index),
+                                                          nullptr,
+                                                          clang::SC_Auto,
+                                                          nullptr));
+        }
+        
+        objc_method_decl->setMethodParams(*ast, llvm::ArrayRef<clang::ParmVarDecl*>(params), llvm::ArrayRef<clang::SourceLocation>());
+    }
+    
+    class_interface_decl->addDecl (objc_method_decl);
+    
+#ifdef LLDB_CONFIGURATION_DEBUG
+    VerifyDecl(objc_method_decl);
+#endif
+    
+    return objc_method_decl;
+}
+
+bool
+ClangASTContext::SetHasExternalStorage (void* type, bool has_extern)
+{
+    if (!type)
+        return false;
+    
+    clang::QualType qual_type (GetCanonicalQualType(type));
+    
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+        {
+            clang::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:
+        {
+            clang::EnumDecl *enum_decl = llvm::cast<clang::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 clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+            assert (objc_class_type);
+            if (objc_class_type)
+            {
+                clang::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 SetHasExternalStorage(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
+            
+        case clang::Type::Elaborated:
+            return SetHasExternalStorage (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), has_extern);
+            
+        case clang::Type::Paren:
+            return SetHasExternalStorage (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), has_extern);
+            
+        default:
+            break;
+    }
+    return false;
+}
+
+
+#pragma mark TagDecl
+
+bool
+ClangASTContext::StartTagDeclarationDefinition (const ClangASTType &type)
+{
+    if (type)
+    {
+        
+        clang::QualType qual_type (GetQualType(type));
+        const clang::Type *t = qual_type.getTypePtr();
+        if (t)
+        {
+            const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(t);
+            if (tag_type)
+            {
+                clang::TagDecl *tag_decl = tag_type->getDecl();
+                if (tag_decl)
+                {
+                    tag_decl->startDefinition();
+                    return true;
+                }
+            }
+            
+            const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(t);
+            if (object_type)
+            {
+                clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface();
+                if (interface_decl)
+                {
+                    interface_decl->startDefinition();
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::CompleteTagDeclarationDefinition (const ClangASTType& type)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetQualType(type));
+        if (qual_type.isNull())
+            return false;
+        clang::ASTContext* ast = type.GetTypeSystem()->AsClangASTContext()->getASTContext();
+        
+        clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+        
+        if (cxx_record_decl)
+        {
+            cxx_record_decl->completeDefinition();
+            
+            return true;
+        }
+        
+        const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(qual_type.getTypePtr());
+        
+        if (enutype)
+        {
+            clang::EnumDecl *enum_decl = enutype->getDecl();
+            
+            if (enum_decl)
+            {
+                /// TODO This really needs to be fixed.
+                
+                unsigned NumPositiveBits = 1;
+                unsigned NumNegativeBits = 0;
+                
+                clang::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;
+}
+
+
+
+
+
+
+
+bool
+ClangASTContext::AddEnumerationValueToEnumerationType (void* type, const ClangASTType &enumerator_clang_type,
+                                                          const Declaration &decl,
+                                                          const char *name,
+                                                          int64_t enum_value,
+                                                          uint32_t enum_value_bit_size)
+{
+    if (type && enumerator_clang_type.IsValid() && name && name[0])
+    {
+        clang::QualType enum_qual_type (GetCanonicalQualType(type));
+        
+        bool is_signed = false;
+        enumerator_clang_type.IsIntegerType (is_signed);
+        const clang::Type *clang_type = enum_qual_type.getTypePtr();
+        if (clang_type)
+        {
+            const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(clang_type);
+            
+            if (enutype)
+            {
+                llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed);
+                enum_llvm_apsint = enum_value;
+                clang::EnumConstantDecl *enumerator_decl =
+                clang::EnumConstantDecl::Create (*getASTContext(),
+                                                 enutype->getDecl(),
+                                                 clang::SourceLocation(),
+                                                 name ? &getASTContext()->Idents.get(name) : nullptr,    // Identifier
+                                                 GetQualType(enumerator_clang_type),
+                                                 nullptr,
+                                                 enum_llvm_apsint);
+                
+                if (enumerator_decl)
+                {
+                    enutype->getDecl()->addDecl(enumerator_decl);
+                    
+#ifdef LLDB_CONFIGURATION_DEBUG
+                    VerifyDecl(enumerator_decl);
+#endif
+                    
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+
+ClangASTType
+ClangASTContext::GetEnumerationIntegerType (void* type)
+{
+    clang::QualType enum_qual_type (GetCanonicalQualType(type));
+    const clang::Type *clang_type = enum_qual_type.getTypePtr();
+    if (clang_type)
+    {
+        const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(clang_type);
+        if (enutype)
+        {
+            clang::EnumDecl *enum_decl = enutype->getDecl();
+            if (enum_decl)
+                return ClangASTType (getASTContext(), enum_decl->getIntegerType());
+        }
+    }
+    return ClangASTType();
+}
+
+ClangASTType
+ClangASTContext::CreateMemberPointerType (const ClangASTType& type, const ClangASTType &pointee_type)
+{
+    if (type && pointee_type.IsValid() && type.GetTypeSystem() == pointee_type.GetTypeSystem())
+    {
+        ClangASTContext* ast = type.GetTypeSystem()->AsClangASTContext();
+        if (!ast)
+            return ClangASTType();
+        return ClangASTType (ast->getASTContext(),
+                             ast->getASTContext()->getMemberPointerType (GetQualType(pointee_type),
+                                                                         GetQualType(type).getTypePtr()));
+    }
+    return ClangASTType();
+}
+
+
+size_t
+ClangASTContext::ConvertStringToFloatValue (void* type, const char *s, uint8_t *dst, size_t dst_size)
+{
+    if (type)
+    {
+        clang::QualType qual_type (GetCanonicalQualType(type));
+        uint32_t count = 0;
+        bool is_complex = false;
+        if (IsFloatingPointType (type, count, is_complex))
+        {
+            // TODO: handle complex and vector types
+            if (count != 1)
+                return false;
+            
+            llvm::StringRef s_sref(s);
+            llvm::APFloat ap_float(getASTContext()->getFloatTypeSemantics(qual_type), s_sref);
+            
+            const uint64_t bit_size = getASTContext()->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
+ClangASTContext::DumpValue (void* 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)
+{
+    if (!type)
+        return;
+    
+    clang::QualType qual_type(GetQualType(type));
+    switch (qual_type->getTypeClass())
+    {
+        case clang::Type::Record:
+            if (GetCompleteType(type))
+            {
+                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+                const clang::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 = getASTContext()->getASTRecordLayout(record_decl);
+                uint32_t child_idx = 0;
+                
+                const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::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;
+                    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());
+                        
+                        // Skip empty base classes
+                        if (verbose == false && ClangASTContext::RecordHasFields(base_class_decl) == false)
+                            continue;
+                        
+                        if (base_class->isVirtual())
+                            field_bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+                        else
+                            field_bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
+                        field_byte_offset = field_bit_offset / 8;
+                        assert (field_bit_offset % 8 == 0);
+                        if (child_idx == 0)
+                            s->PutChar('{');
+                        else
+                            s->PutChar(',');
+                        
+                        clang::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());
+                        
+                        clang::TypeInfo base_class_type_info = getASTContext()->getTypeInfo(base_class_qual_type);
+                        
+                        // Dump the value of the member
+                        ClangASTType base_clang_type(getASTContext(), 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.Width / 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;
+                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
+                    // first member) or comman (for member 2 and beyong) for
+                    // the struct/union/class member.
+                    if (child_idx == 0)
+                        s->PutChar('{');
+                    else
+                        s->PutChar(',');
+                    
+                    // Indent
+                    s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
+                    
+                    clang::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.
+                    clang::TypeInfo field_type_info = getASTContext()->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 (getASTContext(), *field, field_bitfield_bit_size))
+                        field_bitfield_bit_offset = field_bit_offset % 8;
+                    
+                    if (show_types)
+                    {
+                        std::string field_type_name(field_type.getAsString());
+                        if (field_bitfield_bit_size > 0)
+                            s->Printf("(%s:%u) ", field_type_name.c_str(), field_bitfield_bit_size);
+                        else
+                            s->Printf("(%s) ", field_type_name.c_str());
+                    }
+                    // Print the member name and equal sign
+                    s->Printf("%s = ", field->getNameAsString().c_str());
+                    
+                    
+                    // Dump the value of the member
+                    ClangASTType field_clang_type (getASTContext(), 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.Width / 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
+                if (child_idx > 0)
+                    s->Printf("\n%*s}", depth, "");
+            }
+            return;
+            
+        case clang::Type::Enum:
+            if (GetCompleteType(type))
+            {
+                const clang::EnumType *enutype = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
+                const clang::EnumDecl *enum_decl = enutype->getDecl();
+                assert(enum_decl);
+                clang::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)
+                {
+                    if (enum_pos->getInitVal() == enum_value)
+                    {
+                        s->Printf("%s", enum_pos->getNameAsString().c_str());
+                        return;
+                    }
+                }
+                // If we have gotten here we didn't get find the enumerator in the
+                // enum decl, so just print the integer.
+                s->Printf("%" PRIi64, enum_value);
+            }
+            return;
+            
+        case clang::Type::ConstantArray:
+        {
+            const clang::ConstantArrayType *array = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
+            bool is_array_of_characters = false;
+            clang::QualType element_qual_type = array->getElementType();
+            
+            const clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
+            if (canonical_type)
+                is_array_of_characters = canonical_type->isCharType();
+            
+            const uint64_t element_count = array->getSize().getLimitedValue();
+            
+            clang::TypeInfo field_type_info = getASTContext()->getTypeInfo(element_qual_type);
+            
+            uint32_t element_idx = 0;
+            uint32_t element_offset = 0;
+            uint64_t element_byte_size = field_type_info.Width / 8;
+            uint32_t element_stride = element_byte_size;
+            
+            if (is_array_of_characters)
+            {
+                s->PutChar('"');
+                data.Dump(s, data_byte_offset, lldb::eFormatChar, element_byte_size, element_count, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
+                s->PutChar('"');
+                return;
+            }
+            else
+            {
+                ClangASTType element_clang_type(getASTContext(), element_qual_type);
+                lldb::Format element_format = element_clang_type.GetFormat();
+                
+                for (element_idx = 0; element_idx < element_count; ++element_idx)
+                {
+                    // Print the starting squiggly bracket (if this is the
+                    // first member) or comman (for member 2 and beyong) for
+                    // the struct/union/class member.
+                    if (element_idx == 0)
+                        s->PutChar('{');
+                    else
+                        s->PutChar(',');
+                    
+                    // Indent and print the index
+                    s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx);
+                    
+                    // Figure out the field offset within the current struct/union/class type
+                    element_offset = element_idx * element_stride;
+                    
+                    // Dump the value of the member
+                    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
+                if (element_idx > 0)
+                    s->Printf("\n%*s}", depth, "");
+            }
+        }
+            return;
+            
+        case clang::Type::Typedef:
+        {
+            clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType();
+            
+            ClangASTType typedef_clang_type (getASTContext(), typedef_qual_type);
+            lldb::Format typedef_format = typedef_clang_type.GetFormat();
+            clang::TypeInfo typedef_type_info = getASTContext()->getTypeInfo(typedef_qual_type);
+            uint64_t typedef_byte_size = typedef_type_info.Width / 8;
+            
+            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();
+            ClangASTType elaborated_clang_type (getASTContext(), elaborated_qual_type);
+            lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
+            clang::TypeInfo elaborated_type_info = getASTContext()->getTypeInfo(elaborated_qual_type);
+            uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
+            
+            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();
+            ClangASTType desugar_clang_type (getASTContext(), desugar_qual_type);
+            
+            lldb::Format desugar_format = desugar_clang_type.GetFormat();
+            clang::TypeInfo desugar_type_info = getASTContext()->getTypeInfo(desugar_qual_type);
+            uint64_t desugar_byte_size = desugar_type_info.Width / 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);
+            
+            if (show_summary)
+                DumpSummary (type, exe_ctx, s, data, data_byte_offset, data_byte_size);
+            break;
+    }
+}
+
+
+
+
+bool
+ClangASTContext::DumpTypeValue (void* 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)
+{
+    if (!type)
+        return false;
+    if (IsAggregateType(type))
+    {
+        return false;
+    }
+    else
+    {
+        clang::QualType qual_type(GetQualType(type));
+        
+        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();
+                ClangASTType typedef_clang_type (getASTContext(), typedef_qual_type);
+                if (format == eFormatDefault)
+                    format = typedef_clang_type.GetFormat();
+                clang::TypeInfo typedef_type_info = getASTContext()->getTypeInfo(typedef_qual_type);
+                uint64_t typedef_byte_size = typedef_type_info.Width / 8;
+                
+                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) && GetCompleteType(type))
+                {
+                    const clang::EnumType *enutype = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
+                    const clang::EnumDecl *enum_decl = enutype->getDecl();
+                    assert(enum_decl);
+                    clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
+                    const bool is_signed = qual_type->isSignedIntegerOrEnumerationType();
+                    lldb::offset_t offset = byte_offset;
+                    if (is_signed)
+                    {
+                        const int64_t enum_svalue = data.GetMaxS64Bitfield (&offset, 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)
+                        {
+                            if (enum_pos->getInitVal().getSExtValue() == enum_svalue)
+                            {
+                                s->PutCString (enum_pos->getNameAsString().c_str());
+                                return true;
+                            }
+                        }
+                        // If we have gotten here we didn't get find the enumerator in the
+                        // enum decl, so just print the integer.
+                        s->Printf("%" PRIi64, enum_svalue);
+                    }
+                    else
+                    {
+                        const uint64_t enum_uvalue = data.GetMaxU64Bitfield (&offset, 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)
+                        {
+                            if (enum_pos->getInitVal().getZExtValue() == enum_uvalue)
+                            {
+                                s->PutCString (enum_pos->getNameAsString().c_str());
+                                return true;
+                            }
+                        }
+                        // If we have gotten here we didn't get find the enumerator in the
+                        // enum decl, so just print the integer.
+                        s->Printf("%" PRIu64, enum_uvalue);
+                    }
+                    return true;
+                }
+                // format was not enum, just fall through and dump the value as requested....
+                
+            default:
+                // We are down the a scalar type that we just need to display.
+            {
+                uint32_t item_count = 1;
+                // A few formats, we might need to modify our size and count for depending
+                // on how we are trying to display the value...
+                switch (format)
+                {
+                    default:
+                    case eFormatBoolean:
+                    case eFormatBinary:
+                    case eFormatComplex:
+                    case eFormatCString:         // NULL terminated C strings
+                    case eFormatDecimal:
+                    case eFormatEnum:
+                    case eFormatHex:
+                    case eFormatHexUppercase:
+                    case eFormatFloat:
+                    case eFormatOctal:
+                    case eFormatOSType:
+                    case eFormatUnsigned:
+                    case eFormatPointer:
+                    case eFormatVectorOfChar:
+                    case eFormatVectorOfSInt8:
+                    case eFormatVectorOfUInt8:
+                    case eFormatVectorOfSInt16:
+                    case eFormatVectorOfUInt16:
+                    case eFormatVectorOfSInt32:
+                    case eFormatVectorOfUInt32:
+                    case eFormatVectorOfSInt64:
+                    case eFormatVectorOfUInt64:
+                    case eFormatVectorOfFloat32:
+                    case eFormatVectorOfFloat64:
+                    case eFormatVectorOfUInt128:
+                        break;
+                        
+                    case eFormatChar:
+                    case eFormatCharPrintable:
+                    case eFormatCharArray:
+                    case eFormatBytes:
+                    case eFormatBytesWithASCII:
+                        item_count = byte_size;
+                        byte_size = 1;
+                        break;
+                        
+                    case eFormatUnicode16:
+                        item_count = byte_size / 2;
+                        byte_size = 2;
+                        break;
+                        
+                    case eFormatUnicode32:
+                        item_count = byte_size / 4;
+                        byte_size = 4;
+                        break;
+                }
+                return data.Dump (s,
+                                  byte_offset,
+                                  format,
+                                  byte_size,
+                                  item_count,
+                                  UINT32_MAX,
+                                  LLDB_INVALID_ADDRESS,
+                                  bitfield_bit_size,
+                                  bitfield_bit_offset,
+                                  exe_scope);
+            }
+                break;
+        }
+    }
+    return 0;
+}
+
+
+
+void
+ClangASTContext::DumpSummary (void* type, 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 (IsCStringType (type, length))
+    {
+        if (exe_ctx)
+        {
+            Process *process = exe_ctx->GetProcessPtr();
+            if (process)
+            {
+                lldb::offset_t offset = data_byte_offset;
+                lldb::addr_t pointer_address = data.GetMaxU64(&offset, data_byte_size);
+                std::vector<uint8_t> buf;
+                if (length > 0)
+                    buf.resize (length);
+                else
+                    buf.resize (256);
+                
+                lldb_private::DataExtractor cstr_data(&buf.front(), buf.size(), process->GetByteOrder(), 4);
+                buf.back() = '\0';
+                size_t bytes_read;
+                size_t total_cstr_len = 0;
+                Error error;
+                while ((bytes_read = process->ReadMemory (pointer_address, &buf.front(), buf.size(), error)) > 0)
+                {
+                    const size_t len = strlen((const char *)&buf.front());
+                    if (len == 0)
+                        break;
+                    if (total_cstr_len == 0)
+                        s->PutCString (" \"");
+                    cstr_data.Dump(s, 0, lldb::eFormatChar, 1, len, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
+                    total_cstr_len += len;
+                    if (len < buf.size())
+                        break;
+                    pointer_address += total_cstr_len;
+                }
+                if (total_cstr_len > 0)
+                    s->PutChar ('"');
+            }
+        }
+    }
+}
+
+void
+ClangASTContext::DumpTypeDescription (void* type)
+{
+    StreamFile s (stdout, false);
+    DumpTypeDescription (&s);
+    ClangASTMetadata *metadata = ClangASTContext::GetMetadata (getASTContext(), type);
+    if (metadata)
+    {
+        metadata->Dump (&s);
+    }
+}
+
+void
+ClangASTContext::DumpTypeDescription (void* type, Stream *s)
+{
+    if (type)
+    {
+        clang::QualType qual_type(GetQualType(type));
+        
+        llvm::SmallVector<char, 1024> buf;
+        llvm::raw_svector_ostream llvm_ostrm (buf);
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::ObjCObject:
+            case clang::Type::ObjCInterface:
+            {
+                GetCompleteType(type);
+                
+                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+                assert (objc_class_type);
+                if (objc_class_type)
+                {
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    if (class_interface_decl)
+                    {
+                        clang::PrintingPolicy policy = getASTContext()->getPrintingPolicy();
+                        class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
+                    }
+                }
+            }
+                break;
+                
+            case clang::Type::Typedef:
+            {
+                const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
+                if (typedef_type)
+                {
+                    const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
+                    std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString());
+                    if (!clang_typedef_name.empty())
+                    {
+                        s->PutCString ("typedef ");
+                        s->PutCString (clang_typedef_name.c_str());
+                    }
+                }
+            }
+                break;
+                
+            case clang::Type::Elaborated:
+                ClangASTType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).DumpTypeDescription(s);
+                return;
+                
+            case clang::Type::Paren:
+                ClangASTType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).DumpTypeDescription(s);
+                return;
+                
+            case clang::Type::Record:
+            {
+                GetCompleteType(type);
+                
+                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);
+                
+                if (cxx_record_decl)
+                    cxx_record_decl->print(llvm_ostrm, getASTContext()->getPrintingPolicy(), s->GetIndentLevel());
+                else
+                    record_decl->print(llvm_ostrm, getASTContext()->getPrintingPolicy(), s->GetIndentLevel());
+            }
+                break;
+                
+            default:
+            {
+                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)
+                        tag_decl->print(llvm_ostrm, 0);
+                }
+                else
+                {
+                    std::string clang_type_name(qual_type.getAsString());
+                    if (!clang_type_name.empty())
+                        s->PutCString (clang_type_name.c_str());
+                }
+            }
+        }
+        
+        llvm_ostrm.flush();
+        if (buf.size() > 0)
+        {
+            s->Write (buf.data(), buf.size());
+        }
+    }
+}
diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp
index 94e0663..06dd03d 100644
--- a/lldb/source/Symbol/ClangASTType.cpp
+++ b/lldb/source/Symbol/ClangASTType.cpp
@@ -55,130 +55,17 @@
 using namespace lldb;
 using namespace lldb_private;
 
-static bool
-GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool allow_completion = true)
+ClangASTType::ClangASTType (TypeSystem *type_system,
+                            void* type) :
+m_type (type),
+m_type_system (type_system)
 {
-    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 = llvm::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 = llvm::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)
-                        {
-                            clang::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 = llvm::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)
-                        {
-                            clang::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, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion);
-            
-        case clang::Type::Elaborated:
-            return GetCompleteQualType (ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(), allow_completion);
-            
-        case clang::Type::Paren:
-            return GetCompleteQualType (ast, llvm::cast<clang::ParenType>(qual_type)->desugar(), allow_completion);
-            
-        default:
-            break;
-    }
-    
-    return true;
 }
 
-static clang::ObjCIvarDecl::AccessControl
-ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
-{
-    switch (access)
-    {
-        case eAccessNone:      return clang::ObjCIvarDecl::None;
-        case eAccessPublic:    return clang::ObjCIvarDecl::Public;
-        case eAccessPrivate:   return clang::ObjCIvarDecl::Private;
-        case eAccessProtected: return clang::ObjCIvarDecl::Protected;
-        case eAccessPackage:   return clang::ObjCIvarDecl::Package;
-    }
-    return clang::ObjCIvarDecl::None;
-}
-
-//----------------------------------------------------------------------
-// Tests
-//----------------------------------------------------------------------
-
 ClangASTType::ClangASTType (clang::ASTContext *ast,
                             clang::QualType qual_type) :
     m_type (qual_type.getAsOpaquePtr()),
-    m_ast (ast)
+m_type_system (ClangASTContext::GetASTContext(ast))
 {
 }
 
@@ -193,33 +80,8 @@
 bool
 ClangASTType::IsAggregateType () const
 {
-    if (!IsValid())
-        return false;
-    
-    clang::QualType qual_type (GetCanonicalQualType());
-    
-    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 ClangASTType(m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsAggregateType();
-        case clang::Type::Typedef:
-            return ClangASTType(m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsAggregateType();
-        case clang::Type::Paren:
-            return ClangASTType(m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsAggregateType();
-        default:
-            break;
-    }
-    // The clang type does have a value
+    if (IsValid())
+        return m_type_system->IsAggregateType(m_type);
     return false;
 }
 
@@ -229,59 +91,8 @@
                            bool *is_incomplete) const
 {
     if (IsValid())
-    {
-        clang::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, llvm::cast<clang::ConstantArrayType>(qual_type)->getElementType());
-                if (size)
-                    *size = llvm::cast<clang::ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
-                return true;
-                
-            case clang::Type::IncompleteArray:
-                if (element_type_ptr)
-                    element_type_ptr->SetClangType (m_ast, llvm::cast<clang::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, llvm::cast<clang::VariableArrayType>(qual_type)->getElementType());
-                if (size)
-                    *size = 0;
-                return true;
-                
-            case clang::Type::DependentSizedArray:
-                if (element_type_ptr)
-                    element_type_ptr->SetClangType (m_ast, llvm::cast<clang::DependentSizedArrayType>(qual_type)->getElementType());
-                if (size)
-                    *size = 0;
-                return true;
-                
-            case clang::Type::Typedef:
-                return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsArrayType (element_type_ptr,
-                                                                                                                       size,
-                                                                                                                       is_incomplete);
-            case clang::Type::Elaborated:
-                return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsArrayType (element_type_ptr,
-                                                                                                          size,
-                                                                                                          is_incomplete);
-            case clang::Type::Paren:
-                return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsArrayType (element_type_ptr,
-                                                                                                       size,
-                                                                                                       is_incomplete);
-        }
-    }
+        return m_type_system->IsArrayType(m_type, element_type_ptr, size, is_incomplete);
+
     if (element_type_ptr)
         element_type_ptr->Clear();
     if (size)
@@ -296,113 +107,48 @@
                             uint64_t *size) const
 {
     if (IsValid())
-    {
-        clang::QualType qual_type (GetCanonicalQualType());
-        
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-            case clang::Type::Vector:
-            {
-                const clang::VectorType *vector_type = qual_type->getAs<clang::VectorType>();
-                if (vector_type)
-                {
-                    if (size)
-                        *size = vector_type->getNumElements();
-                    if (element_type)
-                        *element_type = ClangASTType(m_ast, vector_type->getElementType().getAsOpaquePtr());
-                }
-                return true;
-            }
-                break;
-            case clang::Type::ExtVector:
-            {
-                const clang::ExtVectorType *ext_vector_type = qual_type->getAs<clang::ExtVectorType>();
-                if (ext_vector_type)
-                {
-                    if (size)
-                        *size = ext_vector_type->getNumElements();
-                    if (element_type)
-                        *element_type = ClangASTType(m_ast, ext_vector_type->getElementType().getAsOpaquePtr());
-                }
-                return true;
-            }
-            default:
-                break;
-        }
-    }
+        return m_type_system->IsVectorType(m_type, element_type, size);
     return false;
 }
 
 bool
 ClangASTType::IsRuntimeGeneratedType () const
 {
-    if (!IsValid())
-        return false;
-    
-    clang::DeclContext* decl_ctx = GetDeclContextForType();
-    if (!decl_ctx)
-        return false;
-
-    if (!llvm::isa<clang::ObjCInterfaceDecl>(decl_ctx))
-        return false;
-    
-    clang::ObjCInterfaceDecl *result_iface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
-    
-    ClangASTMetadata* ast_metadata = ClangASTContext::GetMetadata(m_ast, result_iface_decl);
-    if (!ast_metadata)
-        return false;
-    return (ast_metadata->GetISAPtr() != 0);
+    if (IsValid())
+        return m_type_system->IsRuntimeGeneratedType(m_type);
+    return false;
 }
 
 bool
 ClangASTType::IsCharType () const
 {
-    if (!IsValid())
-        return false;
-    return GetQualType().getUnqualifiedType()->isCharType();
+    if (IsValid())
+        return m_type_system->IsCharType(m_type);
+    return false;
 }
 
 
 bool
 ClangASTType::IsCompleteType () const
 {
-    if (!IsValid())
-        return false;
-    const bool allow_completion = false;
-    return GetCompleteQualType (m_ast, GetQualType(), allow_completion);
+    if (IsValid())
+        return m_type_system->IsCompleteType(m_type);
+    return false;
 }
 
 bool
 ClangASTType::IsConst() const
 {
-    return GetQualType().isConstQualified();
+    if (IsValid())
+        return m_type_system->IsConst(m_type);
+    return false;
 }
 
 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 = llvm::cast<clang::ConstantArrayType>(GetCanonicalQualType().getTypePtr())->getSize().getLimitedValue();
-            }
-            return true;
-            
-        }
-    }
+    if (IsValid())
+        return m_type_system->IsCStringType(m_type, length);
     return false;
 }
 
@@ -410,44 +156,7 @@
 ClangASTType::IsFunctionType (bool *is_variadic_ptr) const
 {
     if (IsValid())
-    {
-        clang::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, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsFunctionType();
-            case clang::Type::Elaborated:
-                return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsFunctionType();
-            case clang::Type::Paren:
-                return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsFunctionType();
-                
-            case clang::Type::LValueReference:
-            case clang::Type::RValueReference:
-                {
-                    const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
-                    if (reference_type)
-                        return ClangASTType (m_ast, reference_type->getPointeeType()).IsFunctionType();
-                }
-                break;
-        }
-    }
+        return m_type_system->IsFunctionType(m_type, is_variadic_ptr);
     return false;
 }
 
@@ -455,95 +164,8 @@
 uint32_t
 ClangASTType::IsHomogeneousAggregate (ClangASTType* base_type_ptr) const
 {
-    if (!IsValid())
-        return 0;
-    
-    clang::QualType qual_type(GetCanonicalQualType());
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteType ())
-            {
-                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                if (cxx_record_decl)
-                {
-                    if (cxx_record_decl->getNumBases() ||
-                        cxx_record_decl->isDynamicClass())
-                        return 0;
-                }
-                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-                if (record_type)
-                {
-                    const clang::RecordDecl *record_decl = record_type->getDecl();
-                    if (record_decl)
-                    {
-                        // We are looking for a structure that contains only floating point types
-                        clang::RecordDecl::field_iterator field_pos, field_end = record_decl->field_end();
-                        uint32_t num_fields = 0;
-                        bool is_hva = false;
-                        bool is_hfa = false;
-                        clang::QualType base_qual_type;
-                        for (field_pos = record_decl->field_begin(); field_pos != field_end; ++field_pos)
-                        {
-                            clang::QualType field_qual_type = field_pos->getType();
-                            if (field_qual_type->isFloatingType())
-                            {
-                                if (field_qual_type->isComplexType())
-                                    return 0;
-                                else
-                                {
-                                    if (num_fields == 0)
-                                        base_qual_type = field_qual_type;
-                                    else
-                                    {
-                                        if (is_hva)
-                                            return 0;
-                                        is_hfa = true;
-                                        if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
-                                            return 0;
-                                    }
-                                }
-                            }
-                            else if (field_qual_type->isVectorType() || field_qual_type->isExtVectorType())
-                            {
-                                const clang::VectorType *array = field_qual_type.getTypePtr()->getAs<clang::VectorType>();
-                                if (array && array->getNumElements() <= 4)
-                                {
-                                    if (num_fields == 0)
-                                        base_qual_type = array->getElementType();
-                                    else
-                                    {
-                                        if (is_hfa)
-                                            return 0;
-                                        is_hva = true;
-                                        if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
-                                            return 0;
-                                    }
-                                }
-                                else
-                                    return 0;
-                            }
-                            else
-                                return 0;
-                            ++num_fields;
-                        }
-                        if (base_type_ptr)
-                            *base_type_ptr = ClangASTType (m_ast, base_qual_type);
-                        return num_fields;
-                    }
-                }
-            }
-            break;
-            
-        case clang::Type::Typedef:
-            return ClangASTType(m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsHomogeneousAggregate (base_type_ptr);
-            
-        case clang::Type::Elaborated:
-            return  ClangASTType(m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsHomogeneousAggregate (base_type_ptr);
-        default:
-            break;
-    }
+    if (IsValid())
+        return m_type_system->IsHomogeneousAggregate(m_type, base_type_ptr);
     return 0;
 }
 
@@ -551,12 +173,7 @@
 ClangASTType::GetNumberOfFunctionArguments () const
 {
     if (IsValid())
-    {
-        clang::QualType qual_type (GetCanonicalQualType());
-        const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
-        if (func)
-            return func->getNumParams();
-    }
+        return m_type_system->GetNumberOfFunctionArguments(m_type);
     return 0;
 }
 
@@ -564,15 +181,7 @@
 ClangASTType::GetFunctionArgumentAtIndex (const size_t index) const
 {
     if (IsValid())
-    {
-        clang::QualType qual_type (GetCanonicalQualType());
-        const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
-        if (func)
-        {
-            if (index < func->getNumParams())
-                return ClangASTType(m_ast, func->getParamType(index).getAsOpaquePtr());
-        }
-    }
+        return m_type_system->GetFunctionArgumentAtIndex(m_type, index);
     return ClangASTType();
 }
 
@@ -580,34 +189,7 @@
 ClangASTType::IsFunctionPointerType () const
 {
     if (IsValid())
-    {
-        clang::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, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsFunctionPointerType();
-        case clang::Type::Elaborated:
-            return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsFunctionPointerType();
-        case clang::Type::Paren:
-            return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsFunctionPointerType();
-            
-        case clang::Type::LValueReference:
-        case clang::Type::RValueReference:
-            {
-                const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
-                if (reference_type)
-                    return ClangASTType (m_ast, reference_type->getPointeeType()).IsFunctionPointerType();
-            }
-            break;
-        }
-    }
+        return m_type_system->IsFunctionPointerType(m_type);
     return false;
 
 }
@@ -615,21 +197,8 @@
 bool
 ClangASTType::IsIntegerType (bool &is_signed) const
 {
-    if (!IsValid())
-        return false;
-    
-    clang::QualType qual_type (GetCanonicalQualType());
-    const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());
-    
-    if (builtin_type)
-    {
-        if (builtin_type->isInteger())
-        {
-            is_signed = builtin_type->isSignedInteger();
-            return true;
-        }
-    }
-    
+    if (IsValid())
+        return m_type_system->IsIntegerType(m_type, is_signed);
     return false;
 }
 
@@ -638,45 +207,7 @@
 {
     if (IsValid())
     {
-        clang::QualType qual_type (GetCanonicalQualType());
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-            case clang::Type::Builtin:
-                switch (llvm::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, llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
-                return true;
-            case clang::Type::BlockPointer:
-                if (pointee_type)
-                    pointee_type->SetClangType (m_ast, llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
-                return true;
-            case clang::Type::Pointer:
-                if (pointee_type)
-                    pointee_type->SetClangType (m_ast, llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
-                return true;
-            case clang::Type::MemberPointer:
-                if (pointee_type)
-                    pointee_type->SetClangType (m_ast, llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
-                return true;
-            case clang::Type::Typedef:
-                return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPointerType(pointee_type);
-            case clang::Type::Elaborated:
-                return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsPointerType(pointee_type);
-            case clang::Type::Paren:
-                return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsPointerType(pointee_type);
-            default:
-                break;
-        }
+        return m_type_system->IsPointerType(m_type, pointee_type);
     }
     if (pointee_type)
         pointee_type->Clear();
@@ -689,53 +220,7 @@
 {
     if (IsValid())
     {
-        clang::QualType qual_type (GetCanonicalQualType());
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-            case clang::Type::Builtin:
-                switch (llvm::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, llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
-                return true;
-            case clang::Type::BlockPointer:
-                if (pointee_type)
-                    pointee_type->SetClangType(m_ast, llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
-                return true;
-            case clang::Type::Pointer:
-                if (pointee_type)
-                    pointee_type->SetClangType(m_ast, llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
-                return true;
-            case clang::Type::MemberPointer:
-                if (pointee_type)
-                    pointee_type->SetClangType(m_ast, llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
-                return true;
-            case clang::Type::LValueReference:
-                if (pointee_type)
-                    pointee_type->SetClangType(m_ast, llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
-                return true;
-            case clang::Type::RValueReference:
-                if (pointee_type)
-                    pointee_type->SetClangType(m_ast, llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
-                return true;
-            case clang::Type::Typedef:
-                return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPointerOrReferenceType(pointee_type);
-            case clang::Type::Elaborated:
-                return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsPointerOrReferenceType(pointee_type);
-            case clang::Type::Paren:
-                return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsPointerOrReferenceType(pointee_type);
-            default:
-                break;
-        }
+        return m_type_system->IsPointerOrReferenceType(m_type, pointee_type);
     }
     if (pointee_type)
         pointee_type->Clear();
@@ -748,33 +233,7 @@
 {
     if (IsValid())
     {
-        clang::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, llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
-                if (is_rvalue)
-                    *is_rvalue = false;
-                return true;
-            case clang::Type::RValueReference:
-                if (pointee_type)
-                    pointee_type->SetClangType(m_ast, llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
-                if (is_rvalue)
-                    *is_rvalue = true;
-                return true;
-            case clang::Type::Typedef:
-                return ClangASTType(m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsReferenceType(pointee_type, is_rvalue);
-            case clang::Type::Elaborated:
-                return ClangASTType(m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsReferenceType(pointee_type, is_rvalue);
-            case clang::Type::Paren:
-                return ClangASTType(m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsReferenceType(pointee_type, is_rvalue);
-                
-            default:
-                break;
-        }
+        return m_type_system->IsReferenceType(m_type, pointee_type, is_rvalue);
     }
     if (pointee_type)
         pointee_type->Clear();
@@ -786,36 +245,7 @@
 {
     if (IsValid())
     {
-        clang::QualType qual_type (GetCanonicalQualType());
-        
-        if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal()))
-        {
-            clang::BuiltinType::Kind kind = BT->getKind();
-            if (kind >= clang::BuiltinType::Float && kind <= clang::BuiltinType::LongDouble)
-            {
-                count = 1;
-                is_complex = false;
-                return true;
-            }
-        }
-        else if (const clang::ComplexType *CT = llvm::dyn_cast<clang::ComplexType>(qual_type->getCanonicalTypeInternal()))
-        {
-            if (ClangASTType (m_ast, CT->getElementType()).IsFloatingPointType (count, is_complex))
-            {
-                count = 2;
-                is_complex = true;
-                return true;
-            }
-        }
-        else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>(qual_type->getCanonicalTypeInternal()))
-        {
-            if (ClangASTType (m_ast, VT->getElementType()).IsFloatingPointType (count, is_complex))
-            {
-                count = VT->getNumElements();
-                is_complex = false;
-                return true;
-            }
-        }
+        return m_type_system->IsFloatingPointType(m_type, count, is_complex);
     }
     count = 0;
     is_complex = false;
@@ -826,81 +256,17 @@
 bool
 ClangASTType::IsDefined() const
 {
-    if (!IsValid())
-        return false;
-
-    clang::QualType qual_type(GetQualType());
-    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() != nullptr;
-            return false;
-        }
-    }
+    if (IsValid())
+        return m_type_system->IsDefined(m_type);
     return true;
 }
 
 bool
-ClangASTType::IsObjCClassType () const
-{
-    if (IsValid())
-    {
-        clang::QualType qual_type (GetCanonicalQualType());
-    
-        const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::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())
     {
-        clang::QualType qual_type(GetCanonicalQualType());
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-            case clang::Type::Record:
-                if (GetCompleteType())
-                {
-                    const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-                    const clang::RecordDecl *record_decl = record_type->getDecl();
-                    if (record_decl)
-                    {
-                        const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
-                        if (cxx_record_decl)
-                            return cxx_record_decl->isPolymorphic();
-                    }
-                }
-                break;
-                
-            default:
-                break;
-        }
+        return m_type_system->IsPolymorphicClass(m_type);
     }
     return false;
 }
@@ -910,178 +276,8 @@
                                      bool check_cplusplus,
                                      bool check_objc) const
 {
-    clang::QualType pointee_qual_type;
-    if (m_type)
-    {
-        clang::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 && llvm::cast<clang::BuiltinType>(qual_type)->getKind() == clang::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, llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
-                    return true;
-                }
-                break;
-                
-            case clang::Type::Pointer:
-                pointee_qual_type = llvm::cast<clang::PointerType>(qual_type)->getPointeeType();
-                success = true;
-                break;
-                
-            case clang::Type::LValueReference:
-            case clang::Type::RValueReference:
-                pointee_qual_type = llvm::cast<clang::ReferenceType>(qual_type)->getPointeeType();
-                success = true;
-                break;
-                
-            case clang::Type::Typedef:
-                return ClangASTType (m_ast,
-                                     llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPossibleDynamicType (dynamic_pointee_type,
-                                                                                                                          check_cplusplus,
-                                                                                                                          check_objc);
-                
-            case clang::Type::Elaborated:
-                return ClangASTType (m_ast,
-                                     llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsPossibleDynamicType (dynamic_pointee_type,
-                                                                                                             check_cplusplus,
-                                                                                                             check_objc);
-                
-            case clang::Type::Paren:
-                return ClangASTType (m_ast,
-                                     llvm::cast<clang::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 (llvm::cast<clang::BuiltinType>(pointee_qual_type)->getKind())
-                {
-                    case clang::BuiltinType::UnknownAny:
-                    case clang::BuiltinType::Void:
-                        if (dynamic_pointee_type)
-                            dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type);
-                        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)
-                    {
-                        clang::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();
+    if (IsValid())
+        return m_type_system->IsPossibleDynamicType(m_type, dynamic_pointee_type, check_cplusplus, check_objc);
     return false;
 }
 
@@ -1092,7 +288,7 @@
     if (!IsValid())
         return false;
 
-    return (GetTypeInfo (nullptr) & eTypeIsScalar) != 0;
+    return m_type_system->IsScalarType(m_type);
 }
 
 bool
@@ -1100,7 +296,7 @@
 {
     if (!IsValid())
         return false;
-    return GetQualType()->getTypeClass() == clang::Type::Typedef;
+    return m_type_system->IsTypedefType(m_type);
 }
 
 bool
@@ -1108,7 +304,7 @@
 {
     if (!IsValid())
         return false;
-    return GetCanonicalQualType()->isVoidType();
+    return m_type_system->IsVoidType(m_type);
 }
 
 bool
@@ -1129,101 +325,14 @@
     return false;
 }
 
-
-bool
-ClangASTType::GetCXXClassName (std::string &class_name) const
-{
-    if (IsValid())
-    {
-        clang::QualType qual_type (GetCanonicalQualType());
-        
-        clang::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;
-    
-    clang::QualType qual_type (GetCanonicalQualType());
-    if (qual_type->getAsCXXRecordDecl() != nullptr)
-        return true;
-    return false;
-}
-
 bool
 ClangASTType::IsBeingDefined () const
 {
     if (!IsValid())
         return false;
-    clang::QualType qual_type (GetCanonicalQualType());
-    const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type);
-    if (tag_type)
-        return tag_type->isBeingDefined();
-    return false;
+    return m_type_system->IsBeingDefined(m_type);
 }
 
-bool
-ClangASTType::IsObjCObjectPointerType (ClangASTType *class_type_ptr)
-{
-    if (!IsValid())
-        return false;
-    
-    clang::QualType qual_type (GetCanonicalQualType());
-
-    if (qual_type->isObjCObjectPointerType())
-    {
-        if (class_type_ptr)
-        {
-            if (!qual_type->isObjCClassType() &&
-                !qual_type->isObjCIdType())
-            {
-                const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
-                if (obj_pointer_type == nullptr)
-                    class_type_ptr->Clear();
-                else
-                    class_type_ptr->SetClangType (m_ast, clang::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;
-    
-    clang::QualType qual_type (GetCanonicalQualType());
-
-    const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
-    if (object_type)
-    {
-        const clang::ObjCInterfaceDecl *interface = object_type->getInterface();
-        if (interface)
-        {
-            class_name = interface->getNameAsString();
-            return true;
-        }
-    }
-    return false;
-}
-
-
 //----------------------------------------------------------------------
 // Type Completion
 //----------------------------------------------------------------------
@@ -1233,8 +342,7 @@
 {
     if (!IsValid())
         return false;
-    const bool allow_completion = true;
-    return GetCompleteQualType (m_ast, GetQualType(), allow_completion);
+    return m_type_system->GetCompleteType(m_type);
 }
 
 //----------------------------------------------------------------------
@@ -1243,8 +351,8 @@
 size_t
 ClangASTType::GetPointerByteSize () const
 {
-    if (m_ast)
-        return m_ast->getTypeSize(m_ast->VoidPtrTy) / 8;
+    if (m_type_system)
+        return m_type_system->GetPointerByteSize();
     return 0;
 }
 
@@ -1272,20 +380,7 @@
     std::string type_name;
     if (IsValid())
     {
-        clang::PrintingPolicy printing_policy (m_ast->getPrintingPolicy());
-        clang::QualType qual_type(GetQualType());
-        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();
-        }
-        else
-        {
-            type_name = qual_type.getAsString(printing_policy);
-        }
+        m_type_system->GetTypeName(m_type);
     }
     return ConstString(type_name);
 }
@@ -1302,174 +397,7 @@
     if (!IsValid())
         return 0;
     
-    if (pointee_or_element_clang_type)
-        pointee_or_element_clang_type->Clear();
-    
-    clang::QualType qual_type (GetQualType());
-    
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Builtin:
-        {
-            const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::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 clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>(qual_type->getCanonicalTypeInternal());
-            if (complex_type)
-            {
-                clang::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, llvm::cast<clang::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, llvm::cast<clang::EnumType>(qual_type)->getDecl()->getIntegerType());
-            return eTypeIsEnumeration | eTypeHasValue;
-            
-        case clang::Type::Elaborated:
-            return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetTypeInfo (pointee_or_element_clang_type);
-        case clang::Type::Paren:
-            return ClangASTType (m_ast, llvm::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, llvm::cast<clang::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, llvm::cast<clang::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 clang::VectorType *vector_type = llvm::dyn_cast<clang::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;
+    return m_type_system->GetTypeInfo(m_type);
 }
 
 
@@ -1480,82 +408,7 @@
     if (!IsValid())
         return lldb::eLanguageTypeC;
     
-    // If the type is a reference, then resolve it to what it refers to first:
-    clang::QualType qual_type (GetCanonicalQualType().getNonReferenceType());
-    if (qual_type->isAnyPointerType())
-    {
-        if (qual_type->isObjCObjectPointerType())
-            return lldb::eLanguageTypeObjC;
-        
-        clang::QualType pointee_type (qual_type->getPointeeType());
-        if (pointee_type->getPointeeCXXRecordDecl() != nullptr)
-            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 (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 ClangASTType(m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetMinimumLanguage();
-        }
-    }
-    return lldb::eLanguageTypeC;
+    return m_type_system->GetMinimumLanguage(m_type);
 }
 
 lldb::TypeClass
@@ -1564,83 +417,21 @@
     if (!IsValid())
         return lldb::eTypeClassInvalid;
     
-    clang::QualType qual_type(GetQualType());
+    return m_type_system->GetTypeClass(m_type);
     
-    switch (qual_type->getTypeClass())
-    {
-        case clang::Type::UnaryTransform:           break;
-        case clang::Type::FunctionNoProto:          return lldb::eTypeClassFunction;
-        case clang::Type::FunctionProto:            return lldb::eTypeClassFunction;
-        case clang::Type::IncompleteArray:          return lldb::eTypeClassArray;
-        case clang::Type::VariableArray:            return lldb::eTypeClassArray;
-        case clang::Type::ConstantArray:            return lldb::eTypeClassArray;
-        case clang::Type::DependentSizedArray:      return lldb::eTypeClassArray;
-        case clang::Type::DependentSizedExtVector:  return lldb::eTypeClassVector;
-        case clang::Type::ExtVector:                return lldb::eTypeClassVector;
-        case clang::Type::Vector:                   return lldb::eTypeClassVector;
-        case clang::Type::Builtin:                  return lldb::eTypeClassBuiltin;
-        case clang::Type::ObjCObjectPointer:        return lldb::eTypeClassObjCObjectPointer;
-        case clang::Type::BlockPointer:             return lldb::eTypeClassBlockPointer;
-        case clang::Type::Pointer:                  return lldb::eTypeClassPointer;
-        case clang::Type::LValueReference:          return lldb::eTypeClassReference;
-        case clang::Type::RValueReference:          return lldb::eTypeClassReference;
-        case clang::Type::MemberPointer:            return lldb::eTypeClassMemberPointer;
-        case clang::Type::Complex:
-            if (qual_type->isComplexType())
-                return lldb::eTypeClassComplexFloat;
-            else
-                return lldb::eTypeClassComplexInteger;
-        case clang::Type::ObjCObject:               return lldb::eTypeClassObjCObject;
-        case clang::Type::ObjCInterface:            return lldb::eTypeClassObjCInterface;
-        case clang::Type::Record:
-            {
-                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-                const clang::RecordDecl *record_decl = record_type->getDecl();
-                if (record_decl->isUnion())
-                    return lldb::eTypeClassUnion;
-                else if (record_decl->isStruct())
-                    return lldb::eTypeClassStruct;
-                else
-                    return lldb::eTypeClassClass;
-            }
-            break;
-        case clang::Type::Enum:                     return lldb::eTypeClassEnumeration;
-        case clang::Type::Typedef:                  return lldb::eTypeClassTypedef;
-        case clang::Type::UnresolvedUsing:          break;
-        case clang::Type::Paren:
-            return ClangASTType(m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetTypeClass();
-        case clang::Type::Elaborated:
-            return ClangASTType(m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetTypeClass();
-            
-        case clang::Type::Attributed:               break;
-        case clang::Type::TemplateTypeParm:         break;
-        case clang::Type::SubstTemplateTypeParm:    break;
-        case clang::Type::SubstTemplateTypeParmPack:break;
-        case clang::Type::Auto:                     break;
-        case clang::Type::InjectedClassName:        break;
-        case clang::Type::DependentName:            break;
-        case clang::Type::DependentTemplateSpecialization: break;
-        case clang::Type::PackExpansion:            break;
-            
-        case clang::Type::TypeOfExpr:               break;
-        case clang::Type::TypeOf:                   break;
-        case clang::Type::Decltype:                 break;
-        case clang::Type::TemplateSpecialization:   break;
-        case clang::Type::Atomic:                   break;
+}
 
-        // pointer type decayed from an array or function type.
-        case clang::Type::Decayed:                  break;
-        case clang::Type::Adjusted:                 break;
-    }
-    // We don't know hot to display this type...
-    return lldb::eTypeClassOther;
-    
+void
+ClangASTType::SetClangType (TypeSystem* type_system, void*  type)
+{
+    m_type_system = type_system;
+    m_type = type;
 }
 
 void
 ClangASTType::SetClangType (clang::ASTContext *ast, clang::QualType qual_type)
 {
-    m_ast = ast;
+    m_type_system = ClangASTContext::GetASTContext(ast);
     m_type = qual_type.getAsOpaquePtr();
 }
 
@@ -1648,7 +439,7 @@
 ClangASTType::GetTypeQualifiers() const
 {
     if (IsValid())
-        return GetQualType().getQualifiers().getCVRQualifiers();
+        return m_type_system->GetTypeQualifiers(m_type);
     return 0;
 }
 
@@ -1657,60 +448,11 @@
 //----------------------------------------------------------------------
 
 ClangASTType
-ClangASTType::AddConstModifier () const
-{
-    if (m_type)
-    {
-        clang::QualType result(GetQualType());
-        result.addConst();
-        return ClangASTType (m_ast, result);
-    }
-    return ClangASTType();
-}
-
-ClangASTType
-ClangASTType::AddRestrictModifier () const
-{
-    if (m_type)
-    {
-        clang::QualType result(GetQualType());
-        result.getQualifiers().setRestrict (true);
-        return ClangASTType (m_ast, result);
-    }
-    return ClangASTType();
-}
-
-ClangASTType
-ClangASTType::AddVolatileModifier () const
-{
-    if (m_type)
-    {
-        clang::QualType result(GetQualType());
-        result.getQualifiers().setVolatile (true);
-        return ClangASTType (m_ast, result);
-    }
-    return ClangASTType();
-}
-
-ClangASTType
 ClangASTType::GetArrayElementType (uint64_t *stride) const
 {
     if (IsValid())
     {
-        clang::QualType qual_type(GetCanonicalQualType());
-        
-        const clang::Type *array_elem_type = qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
-        
-        if (!array_elem_type)
-            return ClangASTType();
-        
-        ClangASTType element_type (m_ast, array_elem_type->getCanonicalTypeUnqualified());
-        
-        // TODO: the real stride will be >= this value.. find the real one!
-        if (stride)
-            *stride = element_type.GetByteSize(nullptr);
-        
-        return element_type;
+        return m_type_system->GetArrayElementType(m_type, stride);
         
     }
     return ClangASTType();
@@ -1720,28 +462,15 @@
 ClangASTType::GetCanonicalType () const
 {
     if (IsValid())
-        return ClangASTType (m_ast, GetCanonicalQualType());
+        return m_type_system->GetCanonicalType(m_type);
     return ClangASTType();
 }
 
-static clang::QualType
-GetFullyUnqualifiedType_Impl (clang::ASTContext *ast, clang::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 m_type_system->GetFullyUnqualifiedType(m_type);
     return ClangASTType();
 }
 
@@ -1751,9 +480,7 @@
 {
     if (IsValid())
     {
-        const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType());
-        if (func)
-            return func->getNumParams();
+        return m_type_system->GetFunctionArgumentCount(m_type);
     }
     return -1;
 }
@@ -1763,13 +490,7 @@
 {
     if (IsValid())
     {
-        const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType());
-        if (func)
-        {
-            const uint32_t num_args = func->getNumParams();
-            if (idx < num_args)
-                return ClangASTType(m_ast, func->getParamType(idx));
-        }
+        return m_type_system->GetFunctionArgumentTypeAtIndex(m_type, idx);
     }
     return ClangASTType();
 }
@@ -1779,10 +500,7 @@
 {
     if (IsValid())
     {
-        clang::QualType qual_type(GetCanonicalQualType());
-        const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
-        if (func)
-            return ClangASTType(m_ast, func->getReturnType());
+        return m_type_system->GetFunctionReturnType(m_type);
     }
     return ClangASTType();
 }
@@ -1790,257 +508,37 @@
 size_t
 ClangASTType::GetNumMemberFunctions () const
 {
-    size_t num_functions = 0;
     if (IsValid())
     {
-        clang::QualType qual_type(GetCanonicalQualType());
-        switch (qual_type->getTypeClass()) {
-            case clang::Type::Record:
-                if (GetCompleteQualType (m_ast, qual_type))
-                {
-                    const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-                    const clang::RecordDecl *record_decl = record_type->getDecl();
-                    assert(record_decl);
-                    const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
-                    if (cxx_record_decl)
-                        num_functions = std::distance(cxx_record_decl->method_begin(), cxx_record_decl->method_end());
-                }
-                break;
-                
-            case clang::Type::ObjCObjectPointer:
-                if (GetCompleteType())
-                {
-                    const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
-                    if (objc_class_type)
-                    {
-                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
-                        if (class_interface_decl)
-                            num_functions = std::distance(class_interface_decl->meth_begin(), class_interface_decl->meth_end());
-                    }
-                }
-                break;
-                
-            case clang::Type::ObjCObject:
-            case clang::Type::ObjCInterface:
-                if (GetCompleteType())
-                {
-                    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
-                    if (objc_class_type)
-                    {
-                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                        if (class_interface_decl)
-                            num_functions = std::distance(class_interface_decl->meth_begin(), class_interface_decl->meth_end());
-                    }
-                }
-                break;
-                
-                
-            case clang::Type::Typedef:
-                return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumMemberFunctions();
-                
-            case clang::Type::Elaborated:
-                return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumMemberFunctions();
-                
-            case clang::Type::Paren:
-                return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumMemberFunctions();
-                
-            default:
-                break;
-        }
+        return m_type_system->GetNumMemberFunctions(m_type);
     }
-    return num_functions;
+    return 0;
 }
 
 TypeMemberFunctionImpl
 ClangASTType::GetMemberFunctionAtIndex (size_t idx)
 {
-    std::string name("");
-    MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
-    ClangASTType type{};
-    clang::ObjCMethodDecl *method_decl(nullptr);
     if (IsValid())
     {
-        clang::QualType qual_type(GetCanonicalQualType());
-        switch (qual_type->getTypeClass()) {
-            case clang::Type::Record:
-                if (GetCompleteQualType (m_ast, qual_type))
-                {
-                    const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-                    const clang::RecordDecl *record_decl = record_type->getDecl();
-                    assert(record_decl);
-                    const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
-                    if (cxx_record_decl)
-                    {
-                        auto method_iter = cxx_record_decl->method_begin();
-                        auto method_end = cxx_record_decl->method_end();
-                        if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
-                        {
-                            std::advance(method_iter, idx);
-                            auto method_decl = method_iter->getCanonicalDecl();
-                            if (method_decl)
-                            {
-                                if (!method_decl->getName().empty())
-                                    name.assign(method_decl->getName().data());
-                                else
-                                    name.clear();
-                                if (method_decl->isStatic())
-                                    kind = lldb::eMemberFunctionKindStaticMethod;
-                                else if (llvm::isa<clang::CXXConstructorDecl>(method_decl))
-                                    kind = lldb::eMemberFunctionKindConstructor;
-                                else if (llvm::isa<clang::CXXDestructorDecl>(method_decl))
-                                    kind = lldb::eMemberFunctionKindDestructor;
-                                else
-                                    kind = lldb::eMemberFunctionKindInstanceMethod;
-                                type = ClangASTType(m_ast,method_decl->getType().getAsOpaquePtr());
-                            }
-                        }
-                    }
-                }
-                break;
-                
-            case clang::Type::ObjCObjectPointer:
-                if (GetCompleteType())
-                {
-                    const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
-                    if (objc_class_type)
-                    {
-                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
-                        if (class_interface_decl)
-                        {
-                            auto method_iter = class_interface_decl->meth_begin();
-                            auto method_end = class_interface_decl->meth_end();
-                            if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
-                            {
-                                std::advance(method_iter, idx);
-                                method_decl = method_iter->getCanonicalDecl();
-                                if (method_decl)
-                                {
-                                    name = method_decl->getSelector().getAsString();
-                                    if (method_decl->isClassMethod())
-                                        kind = lldb::eMemberFunctionKindStaticMethod;
-                                    else
-                                        kind = lldb::eMemberFunctionKindInstanceMethod;
-                                }
-                            }
-                        }
-                    }
-                }
-                break;
-                
-            case clang::Type::ObjCObject:
-            case clang::Type::ObjCInterface:
-                if (GetCompleteType())
-                {
-                    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
-                    if (objc_class_type)
-                    {
-                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                        if (class_interface_decl)
-                        {
-                            auto method_iter = class_interface_decl->meth_begin();
-                            auto method_end = class_interface_decl->meth_end();
-                            if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
-                            {
-                                std::advance(method_iter, idx);
-                                method_decl = method_iter->getCanonicalDecl();
-                                if (method_decl)
-                                {
-                                    name = method_decl->getSelector().getAsString();
-                                    if (method_decl->isClassMethod())
-                                        kind = lldb::eMemberFunctionKindStaticMethod;
-                                    else
-                                        kind = lldb::eMemberFunctionKindInstanceMethod;
-                                }
-                            }
-                        }
-                    }
-                }
-                break;
-
-            case clang::Type::Typedef:
-                return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetMemberFunctionAtIndex(idx);
-                
-            case clang::Type::Elaborated:
-                return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetMemberFunctionAtIndex(idx);
-                
-            case clang::Type::Paren:
-                return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetMemberFunctionAtIndex(idx);
-                
-            default:
-                break;
-        }
+        return m_type_system->GetMemberFunctionAtIndex(m_type, idx);
     }
-    
-    if (kind == eMemberFunctionKindUnknown)
-        return TypeMemberFunctionImpl();
-    if (method_decl)
-        return TypeMemberFunctionImpl(method_decl, name, kind);
-    if (type)
-        return TypeMemberFunctionImpl(type, name, kind);
-    
     return TypeMemberFunctionImpl();
 }
 
 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 m_type_system->GetNonReferenceType(m_type);
     return ClangASTType();
 }
 
 ClangASTType
-ClangASTType::CreateTypedefType (const char *typedef_name,
-                                 clang::DeclContext *decl_ctx) const
-{
-    if (IsValid() && typedef_name && typedef_name[0])
-    {
-        clang::QualType qual_type (GetQualType());
-        if (decl_ctx == nullptr)
-            decl_ctx = m_ast->getTranslationUnitDecl();
-        clang::TypedefDecl *decl = clang::TypedefDecl::Create (*m_ast,
-                                                               decl_ctx,
-                                                               clang::SourceLocation(),
-                                                               clang::SourceLocation(),
-                                                               &m_ast->Idents.get(typedef_name),
-                                                               m_ast->getTrivialTypeSourceInfo(qual_type));
-        
-        decl->setAccess(clang::AS_public); // TODO respect proper access specifier
-        
-        // Get a uniqued clang::QualType for the typedef decl type
-        return ClangASTType (m_ast, m_ast->getTypedefType (decl));
-    }
-    return ClangASTType();
-
-}
-
-ClangASTType
 ClangASTType::GetPointeeType () const
 {
-    if (m_type)
+    if (IsValid())
     {
-        clang::QualType qual_type(GetQualType());
-        return ClangASTType (m_ast, qual_type.getTypePtr()->getPointeeType());
+        return m_type_system->GetPointeeType(m_type);
     }
     return ClangASTType();
 }
@@ -2050,18 +548,7 @@
 {
     if (IsValid())
     {
-        clang::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 m_type_system->GetPointerType(m_type);
     }
     return ClangASTType();
 }
@@ -2071,21 +558,7 @@
 {
     if (IsValid())
     {
-        const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(GetQualType());
-        if (typedef_type)
-            return ClangASTType (m_ast, typedef_type->getDecl()->getUnderlyingType());
-    }
-    return ClangASTType();
-}
-
-ClangASTType
-ClangASTType::RemoveFastQualifiers () const
-{
-    if (m_type)
-    {
-        clang::QualType qual_type(GetQualType());
-        qual_type.getQualifiers().removeFastQualifiers();
-        return ClangASTType (m_ast, qual_type);
+        return m_type_system->GetTypedefedType(m_type);
     }
     return ClangASTType();
 }
@@ -2099,7 +572,7 @@
 ClangASTType::GetBasicTypeFromAST (lldb::BasicType basic_type) const
 {
     if (IsValid())
-        return ClangASTContext::GetBasicType(m_ast, basic_type);
+        return m_type_system->GetBasicTypeFromAST(m_type, basic_type);
     return ClangASTType();
 }
 //----------------------------------------------------------------------
@@ -2109,56 +582,9 @@
 uint64_t
 ClangASTType::GetBitSize (ExecutionContextScope *exe_scope) const
 {
-    if (GetCompleteType ())
+    if (IsValid())
     {
-        clang::QualType qual_type(GetCanonicalQualType());
-        switch (qual_type->getTypeClass())
-        {
-            case clang::Type::ObjCInterface:
-            case clang::Type::ObjCObject:
-            {
-                ExecutionContext exe_ctx (exe_scope);
-                Process *process = exe_ctx.GetProcessPtr();
-                if (process)
-                {
-                    ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
-                    if (objc_runtime)
-                    {
-                        uint64_t bit_size = 0;
-                        if (objc_runtime->GetTypeBitSize(*this, bit_size))
-                            return bit_size;
-                    }
-                }
-                else
-                {
-                    static bool g_printed = false;
-                    if (!g_printed)
-                    {
-                        StreamString s;
-                        DumpTypeDescription(&s);
-
-                        llvm::outs() << "warning: trying to determine the size of type ";
-                        llvm::outs() << s.GetString() << "\n";
-                        llvm::outs() << "without a valid ExecutionContext. this is not reliable. please file a bug against LLDB.\n";
-                        llvm::outs() << "backtrace:\n";
-                        llvm::sys::PrintStackTrace(llvm::outs());
-                        llvm::outs() << "\n";
-                        g_printed = true;
-                    }
-                }
-            }
-                // fallthrough
-            default:
-                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 m_type_system->GetBitSize(m_type, exe_scope);
     }
     return 0;
 }
@@ -2173,8 +599,8 @@
 size_t
 ClangASTType::GetTypeBitAlign () const
 {
-    if (GetCompleteType ())
-        return m_ast->getTypeAlign(GetQualType());
+    if (IsValid())
+        return m_type_system->GetTypeBitAlign(m_type);
     return 0;
 }
 
@@ -2185,135 +611,7 @@
     if (!IsValid())
         return lldb::eEncodingInvalid;
     
-    count = 1;
-    clang::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:
-                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;
-        }
-            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();
-                if (complex_type)
-                    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 ClangASTType(m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetEncoding(count);
-            
-        case clang::Type::Elaborated:
-            return ClangASTType(m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetEncoding(count);
-            
-        case clang::Type::Paren:
-            return ClangASTType(m_ast, llvm::cast<clang::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:
-        case clang::Type::Adjusted:
-            break;
-
-        // pointer type decayed from an array or function type.
-        case clang::Type::Decayed:
-            break;
-    }
-    count = 0;
-    return lldb::eEncodingInvalid;
+    return m_type_system->GetEncoding(m_type, count);
 }
 
 lldb::Format
@@ -2322,147 +620,7 @@
     if (!IsValid())
         return lldb::eFormatDefault;
     
-    clang::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:
-                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;
-        }
-            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 (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetFormat();
-        case clang::Type::Auto:
-            return ClangASTType (m_ast, llvm::cast<clang::AutoType>(qual_type)->desugar()).GetFormat();
-        case clang::Type::Paren:
-            return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetFormat();
-        case clang::Type::Elaborated:
-            return ClangASTType (m_ast, llvm::cast<clang::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::Adjusted:
-            break;
-
-        // pointer type decayed from an array or function type.
-        case clang::Type::Decayed:
-            break;
-    }
-    // We don't know hot to display this type...
-    return lldb::eFormatBytes;
-}
-
-static bool
-ObjCDeclHasIVars (clang::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;
+    return m_type_system->GetFormat(m_type);
 }
 
 uint32_t
@@ -2470,168 +628,7 @@
 {
     if (!IsValid())
         return 0;
-    
-    uint32_t num_children = 0;
-    clang::QualType qual_type(GetQualType());
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Builtin:
-            switch (llvm::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 (m_ast, qual_type))
-            {
-                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-                const clang::RecordDecl *record_decl = record_type->getDecl();
-                assert(record_decl);
-                const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::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.
-                        clang::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());
-                            
-                            // 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();
-                    }
-                    
-                }
-                clang::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 clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
-                assert (objc_class_type);
-                if (objc_class_type)
-                {
-                    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)
-                        {
-                            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 clang::ObjCObjectPointerType *pointer_type = llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr());
-            clang::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 = llvm::cast<clang::VectorType>(qual_type.getTypePtr())->getNumElements();
-            break;
-            
-        case clang::Type::ConstantArray:
-            num_children = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
-            break;
-            
-        case clang::Type::Pointer:
-        {
-            const clang::PointerType *pointer_type = llvm::cast<clang::PointerType>(qual_type.getTypePtr());
-            clang::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 clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
-            clang::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, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumChildren (omit_empty_base_classes);
-            break;
-            
-        case clang::Type::Elaborated:
-            num_children = ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumChildren (omit_empty_base_classes);
-            break;
-            
-        case clang::Type::Paren:
-            num_children = ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumChildren (omit_empty_base_classes);
-            break;
-        default:
-            break;
-    }
-    return num_children;
+    return m_type_system->GetNumChildren(m_type, omit_empty_base_classes);
 }
 
 lldb::BasicType
@@ -2639,463 +636,19 @@
 {
     if (IsValid())
     {
-        clang::QualType qual_type(GetQualType());
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        if (type_class == clang::Type::Builtin)
-        {
-            switch (llvm::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 m_type_system->GetBasicTypeEnumeration(m_type);
     }
     return eBasicTypeInvalid;
 }
 
-
 #pragma mark Aggregate Types
 
 uint32_t
-ClangASTType::GetNumDirectBaseClasses () const
-{
-    if (!IsValid())
-        return 0;
-    
-    uint32_t count = 0;
-    clang::QualType qual_type(GetCanonicalQualType());
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteType())
-            {
-                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                if (cxx_record_decl)
-                    count = cxx_record_decl->getNumBases();
-            }
-            break;
-            
-        case clang::Type::ObjCObjectPointer:
-            count = GetPointeeType().GetNumDirectBaseClasses();
-            break;
-            
-        case clang::Type::ObjCObject:
-            if (GetCompleteType())
-            {
-                const clang::ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
-                if (objc_class_type)
-                {
-                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                    
-                    if (class_interface_decl && class_interface_decl->getSuperClass())
-                        count = 1;
-                }
-            }
-            break;
-        case clang::Type::ObjCInterface:
-            if (GetCompleteType())
-            {
-                const clang::ObjCInterfaceType *objc_interface_type = qual_type->getAs<clang::ObjCInterfaceType>();
-                if (objc_interface_type)
-                {
-                    clang::ObjCInterfaceDecl *class_interface_decl = objc_interface_type->getInterface();
-                    
-                    if (class_interface_decl && class_interface_decl->getSuperClass())
-                        count = 1;
-                }
-            }
-            break;
-            
-            
-        case clang::Type::Typedef:
-            count = ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumDirectBaseClasses ();
-            break;
-            
-        case clang::Type::Elaborated:
-            count = ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumDirectBaseClasses ();
-            break;
-            
-        case clang::Type::Paren:
-            return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumDirectBaseClasses ();
-            
-        default:
-            break;
-    }
-    return count;
-}
-
-uint32_t
-ClangASTType::GetNumVirtualBaseClasses () const
-{
-    if (!IsValid())
-        return 0;
-    
-    uint32_t count = 0;
-    clang::QualType qual_type(GetCanonicalQualType());
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteType())
-            {
-                const clang::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, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumVirtualBaseClasses();
-            break;
-            
-        case clang::Type::Elaborated:
-            count = ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumVirtualBaseClasses();
-            break;
-            
-        case clang::Type::Paren:
-            count = ClangASTType (m_ast, llvm::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;
-    clang::QualType qual_type(GetCanonicalQualType());
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteType())
-            {
-                const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
-                if (record_type)
-                {
-                    clang::RecordDecl *record_decl = record_type->getDecl();
-                    if (record_decl)
-                    {
-                        uint32_t field_idx = 0;
-                        clang::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, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumFields();
-            break;
-            
-        case clang::Type::Elaborated:
-            count = ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumFields();
-            break;
-            
-        case clang::Type::Paren:
-            count = ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumFields();
-            break;
-            
-        case clang::Type::ObjCObjectPointer:
-            if (GetCompleteType())
-            {
-                const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
-                if (objc_class_type)
-                {
-                    clang::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 clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
-                if (objc_class_type)
-                {
-                    clang::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();
-    
-    clang::QualType qual_type(GetCanonicalQualType());
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteType())
-            {
-                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                if (cxx_record_decl)
-                {
-                    uint32_t curr_idx = 0;
-                    clang::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 clang::ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(cxx_record_decl);
-                                const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::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:
-            return GetPointeeType().GetDirectBaseClassAtIndex(idx,bit_offset_ptr);
-            
-        case clang::Type::ObjCObject:
-            if (idx == 0 && GetCompleteType())
-            {
-                const clang::ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
-                if (objc_class_type)
-                {
-                    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)
-                        {
-                            if (bit_offset_ptr)
-                                *bit_offset_ptr = 0;
-                            return ClangASTType (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
-                        }
-                    }
-                }
-            }
-            break;
-        case clang::Type::ObjCInterface:
-            if (idx == 0 && GetCompleteType())
-            {
-                const clang::ObjCObjectType *objc_interface_type = qual_type->getAs<clang::ObjCInterfaceType>();
-                if (objc_interface_type)
-                {
-                    clang::ObjCInterfaceDecl *class_interface_decl = objc_interface_type->getInterface();
-                    
-                    if (class_interface_decl)
-                    {
-                        clang::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, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr);
-            
-        case clang::Type::Elaborated:
-            return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr);
-            
-        case clang::Type::Paren:
-            return ClangASTType (m_ast, llvm::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();
-    
-    clang::QualType qual_type(GetCanonicalQualType());
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteType())
-            {
-                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                if (cxx_record_decl)
-                {
-                    uint32_t curr_idx = 0;
-                    clang::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 clang::ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(cxx_record_decl);
-                                const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::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, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr);
-            
-        case clang::Type::Elaborated:
-            return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr);
-            
-        case clang::Type::Paren:
-            return  ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr);
-            
-        default:
-            break;
-    }
-    return ClangASTType();
-}
-
-static clang_type_t
-GetObjCFieldAtIndex (clang::ASTContext *ast,
-                     clang::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()))
-        {
-            clang::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 clang::ObjCIvarDecl* ivar_decl = *ivar_pos;
-                    
-                    clang::QualType ivar_qual_type(ivar_decl->getType());
-                    
-                    name.assign(ivar_decl->getNameAsString());
-                    
-                    if (bit_offset_ptr)
-                    {
-                        const clang::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)
-                        {
-                            clang::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 nullptr;
+    return m_type_system->GetNumFields(m_type);
 }
 
 ClangASTType
@@ -3107,114 +660,7 @@
 {
     if (!IsValid())
         return ClangASTType();
-    
-    clang::QualType qual_type(GetCanonicalQualType());
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-            if (GetCompleteType())
-            {
-                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-                const clang::RecordDecl *record_decl = record_type->getDecl();
-                uint32_t field_idx = 0;
-                clang::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 clang::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)
-                            {
-                                clang::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 clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
-                if (objc_class_type)
-                {
-                    clang::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 clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
-                assert (objc_class_type);
-                if (objc_class_type)
-                {
-                    clang::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, llvm::cast<clang::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, llvm::cast<clang::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, llvm::cast<clang::ParenType>(qual_type)->desugar()).
-                        GetFieldAtIndex (idx,
-                                         name,
-                                         bit_offset_ptr,
-                                         bitfield_bit_size_ptr,
-                                         is_bitfield_ptr);
-            
-        default:
-            break;
-    }
-    return ClangASTType();
+    return m_type_system->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
 }
 
 uint32_t
@@ -3239,112 +685,6 @@
     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;
-    
-    clang::QualType qual_type(GetCanonicalQualType());
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Builtin:
-            switch (llvm::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, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumPointeeChildren ();
-        case clang::Type::Typedef:                  return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumPointeeChildren ();
-        case clang::Type::Elaborated:               return ClangASTType (m_ast, llvm::cast<clang::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,
                                         size_t idx,
@@ -3362,646 +702,10 @@
 {
     if (!IsValid())
         return ClangASTType();
-    
-    clang::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 (llvm::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 clang::RecordType *record_type = llvm::cast<clang::RecordType>(parent_qual_type.getTypePtr());
-                const clang::RecordDecl *record_decl = record_type->getDecl();
-                assert(record_decl);
-                const clang::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);
-                if (cxx_record_decl)
-                {
-                    // We might have base classes to print out first
-                    clang::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 = nullptr;
-                        
-                        // Skip empty base classes
-                        if (omit_empty_base_classes)
-                        {
-                            base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
-                            if (ClangASTContext::RecordHasFields(base_class_decl) == false)
-                                continue;
-                        }
-                        
-                        if (idx == child_idx)
-                        {
-                            if (base_class_decl == nullptr)
-                                base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
-                            
-                            
-                            if (base_class->isVirtual())
-                            {
-                                bool handled = false;
-                                if (valobj)
-                                {
-                                    Error err;
-                                    AddressType addr_type = eAddressTypeInvalid;
-                                    lldb::addr_t vtable_ptr_addr = valobj->GetCPPVTableAddress(addr_type);
-                                    
-                                    if (vtable_ptr_addr != LLDB_INVALID_ADDRESS && addr_type == eAddressTypeLoad)
-                                    {
-                                        
-                                        ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
-                                        Process *process = exe_ctx.GetProcessPtr();
-                                        if (process)
-                                        {
-                                            clang::VTableContextBase *vtable_ctx = m_ast->getVTableContext();
-                                            if (vtable_ctx)
-                                            {
-                                                if (vtable_ctx->isMicrosoft())
-                                                {
-                                                    clang::MicrosoftVTableContext *msoft_vtable_ctx = static_cast<clang::MicrosoftVTableContext *>(vtable_ctx);
-                                                    
-                                                    if (vtable_ptr_addr)
-                                                    {
-                                                        const lldb::addr_t vbtable_ptr_addr = vtable_ptr_addr + record_layout.getVBPtrOffset().getQuantity();
-                                                        
-                                                        const lldb::addr_t vbtable_ptr = process->ReadPointerFromMemory(vbtable_ptr_addr, err);
-                                                        if (vbtable_ptr != LLDB_INVALID_ADDRESS)
-                                                        {
-                                                            // Get the index into the virtual base table. The index is the index in uint32_t from vbtable_ptr
-                                                            const unsigned vbtable_index = msoft_vtable_ctx->getVBTableIndex(cxx_record_decl, base_class_decl);
-                                                            const lldb::addr_t base_offset_addr = vbtable_ptr + vbtable_index * 4;
-                                                            const uint32_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, 4, UINT32_MAX, err);
-                                                            if (base_offset != UINT32_MAX)
-                                                            {
-                                                                handled = true;
-                                                                bit_offset = base_offset * 8;
-                                                            }
-                                                        }
-                                                    }
-                                                }
-                                                else
-                                                {
-                                                    clang::ItaniumVTableContext *itanium_vtable_ctx = static_cast<clang::ItaniumVTableContext *>(vtable_ctx);
-                                                    if (vtable_ptr_addr)
-                                                    {
-                                                        const lldb::addr_t vtable_ptr = process->ReadPointerFromMemory(vtable_ptr_addr, err);
-                                                        if (vtable_ptr != LLDB_INVALID_ADDRESS)
-                                                        {
-                                                            clang::CharUnits base_offset_offset = itanium_vtable_ctx->getVirtualBaseOffsetOffset(cxx_record_decl, base_class_decl);
-                                                            const lldb::addr_t base_offset_addr = vtable_ptr + base_offset_offset.getQuantity();
-                                                            const uint32_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, 4, UINT32_MAX, err);
-                                                            if (base_offset != UINT32_MAX)
-                                                            {
-                                                                handled = true;
-                                                                bit_offset = base_offset * 8;
-                                                            }
-                                                        }
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-
-                                }
-                                if (!handled)
-                                    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().AsCString("");
-                            uint64_t base_class_clang_type_bit_size = base_class_clang_type.GetBitSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
-                            
-                            // 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;
-                clang::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(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
-                        
-                        // 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 clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(parent_qual_type.getTypePtr());
-                assert (objc_class_type);
-                if (objc_class_type)
-                {
-                    uint32_t child_idx = 0;
-                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                    
-                    if (class_interface_decl)
-                    {
-                        
-                        const clang::ASTRecordLayout &interface_layout = m_ast->getASTObjCInterfaceLayout(class_interface_decl);
-                        clang::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)
-                                    {
-                                        clang::QualType ivar_qual_type(m_ast->getObjCInterfaceType(superclass_interface_decl));
-                                        
-                                        
-                                        child_name.assign(superclass_interface_decl->getNameAsString().c_str());
-                                        
-                                        clang::TypeInfo ivar_type_info = m_ast->getTypeInfo(ivar_qual_type.getTypePtr());
-                                        
-                                        child_byte_size = ivar_type_info.Width / 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()))
-                        {
-                            clang::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)
-                                {
-                                    clang::ObjCIvarDecl* ivar_decl = *ivar_pos;
-                                    
-                                    clang::QualType ivar_qual_type(ivar_decl->getType());
-                                    
-                                    child_name.assign(ivar_decl->getNameAsString().c_str());
-                                    
-                                    clang::TypeInfo  ivar_type_info = m_ast->getTypeInfo(ivar_qual_type.getTypePtr());
-                                    
-                                    child_byte_size = ivar_type_info.Width / 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 = nullptr;
-                                    if (exe_ctx)
-                                        process = exe_ctx->GetProcessPtr();
-                                    if (process)
-                                    {
-                                        ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
-                                        if (objc_runtime != nullptr)
-                                        {
-                                            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 == static_cast<int32_t>(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,
-                                                                        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,
-                                                                        valobj);
-                }
-                else
-                {
-                    child_is_deref_of_parent = true;
-                    const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
-                    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(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
-                        child_byte_offset = 0;
-                        return pointee_clang_type;
-                    }
-                }
-            }
-            break;
-            
-        case clang::Type::Vector:
-        case clang::Type::ExtVector:
-            if (idx_is_valid)
-            {
-                const clang::VectorType *array = llvm::cast<clang::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), "[%" PRIu64 "]", static_cast<uint64_t>(idx));
-                        child_name.assign(element_name);
-                        child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
-                        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 clang::ArrayType *array = GetQualType()->getAsArrayTypeUnsafe();
-                if (array)
-                {
-                    ClangASTType element_type (m_ast, array->getElementType());
-                    if (element_type.GetCompleteType())
-                    {
-                        char element_name[64];
-                        ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]", static_cast<uint64_t>(idx));
-                        child_name.assign(element_name);
-                        child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
-                        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,
-                                                                        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,
-                                                                        valobj);
-                }
-                else
-                {
-                    child_is_deref_of_parent = true;
-                    
-                    const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
-                    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(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
-                        child_byte_offset = 0;
-                        return pointee_clang_type;
-                    }
-                }
-            }
-            break;
-            
-        case clang::Type::LValueReference:
-        case clang::Type::RValueReference:
-            if (idx_is_valid)
-            {
-                const clang::ReferenceType *reference_type = llvm::cast<clang::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,
-                                                                        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,
-                                                                        valobj);
-                }
-                else
-                {
-                    const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
-                    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(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
-                        child_byte_offset = 0;
-                        return pointee_clang_type;
-                    }
-                }
-            }
-            break;
-            
-        case clang::Type::Typedef:
-            {
-                ClangASTType typedefed_clang_type (m_ast, llvm::cast<clang::TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType());
-                return typedefed_clang_type.GetChildClangTypeAtIndex (exe_ctx,
-                                                                      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,
-                                                                      valobj);
-            }
-            break;
-            
-        case clang::Type::Elaborated:
-            {
-                ClangASTType elaborated_clang_type (m_ast, llvm::cast<clang::ElaboratedType>(parent_qual_type)->getNamedType());
-                return elaborated_clang_type.GetChildClangTypeAtIndex (exe_ctx,
-                                                                       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,
-                                                                       valobj);
-            }
-            
-        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,
-                                                                  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,
-                                                                  valobj);
-            }
-            
-            
-        default:
-            break;
-    }
-    return ClangASTType();
-}
-
-static inline bool
-BaseSpecifierIsEmpty (const clang::CXXBaseSpecifier *b)
-{
-    return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
-}
-
-static uint32_t
-GetIndexForRecordBase
-(
- const clang::RecordDecl *record_decl,
- const clang::CXXBaseSpecifier *base_spec,
- bool omit_empty_base_classes
- )
-{
-    uint32_t child_idx = 0;
-    
-    const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
-    
-    //    const char *super_name = record_decl->getNameAsCString();
-    //    const char *base_name = base_spec->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString();
-    //    printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
-    //
-    if (cxx_record_decl)
-    {
-        clang::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<clang::RecordType>()->getDecl()->getNameAsCString());
-            //
-            //
-            if (base_class == base_spec)
-                return child_idx;
-            ++child_idx;
-        }
-    }
-    
-    return UINT32_MAX;
+    return m_type_system->GetChildClangTypeAtIndex(m_type, exe_ctx, 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, valobj);
 }
 
 
-static uint32_t
-GetIndexForRecordChild (const clang::RecordDecl *record_decl,
-                        clang::NamedDecl *canonical_decl,
-                        bool omit_empty_base_classes)
-{
-    uint32_t child_idx = ClangASTContext::GetNumBaseClasses (llvm::dyn_cast<clang::CXXRecordDecl>(record_decl),
-                                                             omit_empty_base_classes);
-    
-    clang::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,
@@ -4010,254 +714,7 @@
 {
     if (IsValid() && name && name[0])
     {
-        clang::QualType qual_type(GetCanonicalQualType());
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-            case clang::Type::Record:
-                if (GetCompleteType ())
-                {
-                    const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-                    const clang::RecordDecl *record_decl = record_type->getDecl();
-                    
-                    assert(record_decl);
-                    uint32_t child_idx = 0;
-                    
-                    const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
-                    
-                    // Try and find a field that matches NAME
-                    clang::RecordDecl::field_iterator field, field_end;
-                    llvm::StringRef name_sref(name);
-                    for (field = record_decl->field_begin(), field_end = record_decl->field_end();
-                         field != field_end;
-                         ++field, ++child_idx)
-                    {
-                        llvm::StringRef field_name = field->getName();
-                        if (field_name.empty())
-                        {
-                            ClangASTType field_type(m_ast,field->getType());
-                            child_indexes.push_back(child_idx);
-                            if (field_type.GetIndexOfChildMemberWithName(name,  omit_empty_base_classes, child_indexes))
-                                return child_indexes.size();
-                            child_indexes.pop_back();
-                                
-                        }
-                        else if (field_name.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 clang::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...
-                        clang::IdentifierInfo & ident_ref = m_ast->Idents.get(name_sref);
-                        clang::DeclarationName decl_name(&ident_ref);
-                        
-                        clang::CXXBasePaths paths;
-                        if (cxx_record_decl->lookupInBases(clang::CXXRecordDecl::FindOrdinaryMember,
-                                                           decl_name.getAsOpaquePtr(),
-                                                           paths))
-                        {
-                            clang::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)
-                                {
-                                    clang::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 = llvm::cast<clang::RecordDecl>(elem.Base->getType()->getAs<clang::RecordType>()->getDecl());
-                                    }
-                                }
-                                for (clang::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 ())
-                {
-                    llvm::StringRef name_sref(name);
-                    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
-                    assert (objc_class_type);
-                    if (objc_class_type)
-                    {
-                        uint32_t child_idx = 0;
-                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                        
-                        if (class_interface_decl)
-                        {
-                            clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
-                            clang::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 clang::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, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
-                    return objc_object_clang_type.GetIndexOfChildMemberWithName (name,
-                                                                                 omit_empty_base_classes,
-                                                                                 child_indexes);
-                }
-                break;
-                
-                
-            case clang::Type::ConstantArray:
-            {
-                //                const clang::ConstantArrayType *array = llvm::cast<clang::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 = llvm::cast<MemberPointerType>(qual_type.getTypePtr());
-                //                clang::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 clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
-                    clang::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, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildMemberWithName (name,
-                                                                                                                                         omit_empty_base_classes,
-                                                                                                                                         child_indexes);
-                
-            case clang::Type::Elaborated:
-                return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildMemberWithName (name,
-                                                                                                                            omit_empty_base_classes,
-                                                                                                                            child_indexes);
-                
-            case clang::Type::Paren:
-                return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildMemberWithName (name,
-                                                                                                                         omit_empty_base_classes,
-                                                                                                                         child_indexes);
-                
-            default:
-                break;
-        }
+        return m_type_system->GetIndexOfChildMemberWithName(m_type, name, omit_empty_base_classes, child_indexes);
     }
     return 0;
 }
@@ -4271,1782 +728,18 @@
 ClangASTType::GetIndexOfChildWithName (const char *name, bool omit_empty_base_classes) const
 {
     if (IsValid() && name && name[0])
-    {
-        clang::QualType qual_type(GetCanonicalQualType());
-        
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        
-        switch (type_class)
-        {
-            case clang::Type::Record:
-                if (GetCompleteType ())
-                {
-                    const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-                    const clang::RecordDecl *record_decl = record_type->getDecl();
-                    
-                    assert(record_decl);
-                    uint32_t child_idx = 0;
-                    
-                    const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
-                    
-                    if (cxx_record_decl)
-                    {
-                        clang::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
-                            clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::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().AsCString(""));
-                            if (base_class_type_name.compare (name) == 0)
-                                return child_idx;
-                            ++child_idx;
-                        }
-                    }
-                    
-                    // Try and find a field that matches NAME
-                    clang::RecordDecl::field_iterator field, field_end;
-                    llvm::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())
-                {
-                    llvm::StringRef name_sref(name);
-                    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
-                    assert (objc_class_type);
-                    if (objc_class_type)
-                    {
-                        uint32_t child_idx = 0;
-                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                        
-                        if (class_interface_decl)
-                        {
-                            clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
-                            clang::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 clang::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, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
-                    return pointee_clang_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
-                }
-                break;
-                
-            case clang::Type::ConstantArray:
-            {
-                //                const clang::ConstantArrayType *array = llvm::cast<clang::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 = llvm::cast<MemberPointerType>(qual_type.getTypePtr());
-                //                clang::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 clang::ReferenceType *reference_type = llvm::cast<clang::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 clang::PointerType *pointer_type = llvm::cast<clang::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, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
-                
-            case clang::Type::Paren:
-                return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildWithName (name, omit_empty_base_classes);
-                
-            case clang::Type::Typedef:
-                return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
-                
-            default:
-                break;
-        }
-    }
+        return m_type_system->GetIndexOfChildWithName(m_type, name, omit_empty_base_classes);
     return UINT32_MAX;
 }
 
-
-size_t
-ClangASTType::GetNumTemplateArguments () const
-{
-    if (IsValid())
-    {
-        clang::QualType qual_type (GetCanonicalQualType());
-        
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-            case clang::Type::Record:
-                if (GetCompleteType ())
-                {
-                    const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                    if (cxx_record_decl)
-                    {
-                        const clang::ClassTemplateSpecializationDecl *template_decl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(cxx_record_decl);
-                        if (template_decl)
-                            return template_decl->getTemplateArgs().size();
-                    }
-                }
-                break;
-                
-            case clang::Type::Typedef:
-                return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumTemplateArguments();
-                
-            case clang::Type::Elaborated:
-                return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumTemplateArguments();
-                
-            case clang::Type::Paren:
-                return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumTemplateArguments();
-                
-            default:
-                break;
-        }
-    }
-    return 0;
-}
-
-ClangASTType
-ClangASTType::GetTemplateArgument (size_t arg_idx, lldb::TemplateArgumentKind &kind) const
-{
-    if (IsValid())
-    {
-        clang::QualType qual_type (GetCanonicalQualType());
-        
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-            case clang::Type::Record:
-                if (GetCompleteType ())
-                {
-                    const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                    if (cxx_record_decl)
-                    {
-                        const clang::ClassTemplateSpecializationDecl *template_decl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(cxx_record_decl);
-                        if (template_decl && arg_idx < template_decl->getTemplateArgs().size())
-                        {
-                            const clang::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 clang::TemplateArgument::ArgKind");
-                                    break;
-                            }
-                        }
-                    }
-                }
-                break;
-                
-            case clang::Type::Typedef:
-                return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetTemplateArgument (arg_idx, kind);
-                
-            case clang::Type::Elaborated:
-                return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetTemplateArgument (arg_idx, kind);
-                
-            case clang::Type::Paren:
-                return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetTemplateArgument (arg_idx, kind);
-                
-            default:
-                break;
-        }
-    }
-    kind = eTemplateArgumentKindNull;
-    return ClangASTType ();
-}
-
-static bool
-IsOperator (const char *name, clang::OverloadedOperatorKind &op_kind)
-{
-    if (name == nullptr || name[0] == '\0')
-        return false;
-    
-#define OPERATOR_PREFIX "operator"
-#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
-    
-    const char *post_op_name = nullptr;
-    
-    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 = clang::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 = clang::OO_New;
-            else if (strcmp (post_op_name, "new[]") == 0)
-                op_kind = clang::OO_Array_New;
-            break;
-            
-        case 'd':
-            if (no_space)
-                return false;
-            if (strcmp (post_op_name, "delete") == 0)
-                op_kind = clang::OO_Delete;
-            else if (strcmp (post_op_name, "delete[]") == 0)
-                op_kind = clang::OO_Array_Delete;
-            break;
-            
-        case '+':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Plus;
-            else if (post_op_name[2] == '\0')
-            {
-                if (post_op_name[1] == '=')
-                    op_kind = clang::OO_PlusEqual;
-                else if (post_op_name[1] == '+')
-                    op_kind = clang::OO_PlusPlus;
-            }
-            break;
-            
-        case '-':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Minus;
-            else if (post_op_name[2] == '\0')
-            {
-                switch (post_op_name[1])
-                {
-                    case '=': op_kind = clang::OO_MinusEqual; break;
-                    case '-': op_kind = clang::OO_MinusMinus; break;
-                    case '>': op_kind = clang::OO_Arrow; break;
-                }
-            }
-            else if (post_op_name[3] == '\0')
-            {
-                if (post_op_name[2] == '*')
-                    op_kind = clang::OO_ArrowStar; break;
-            }
-            break;
-            
-        case '*':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Star;
-            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
-                op_kind = clang::OO_StarEqual;
-            break;
-            
-        case '/':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Slash;
-            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
-                op_kind = clang::OO_SlashEqual;
-            break;
-            
-        case '%':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Percent;
-            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
-                op_kind = clang::OO_PercentEqual;
-            break;
-            
-            
-        case '^':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Caret;
-            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
-                op_kind = clang::OO_CaretEqual;
-            break;
-            
-        case '&':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Amp;
-            else if (post_op_name[2] == '\0')
-            {
-                switch (post_op_name[1])
-                {
-                    case '=': op_kind = clang::OO_AmpEqual; break;
-                    case '&': op_kind = clang::OO_AmpAmp; break;
-                }
-            }
-            break;
-            
-        case '|':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Pipe;
-            else if (post_op_name[2] == '\0')
-            {
-                switch (post_op_name[1])
-                {
-                    case '=': op_kind = clang::OO_PipeEqual; break;
-                    case '|': op_kind = clang::OO_PipePipe; break;
-                }
-            }
-            break;
-            
-        case '~':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Tilde;
-            break;
-            
-        case '!':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Exclaim;
-            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
-                op_kind = clang::OO_ExclaimEqual;
-            break;
-            
-        case '=':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Equal;
-            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
-                op_kind = clang::OO_EqualEqual;
-            break;
-            
-        case '<':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Less;
-            else if (post_op_name[2] == '\0')
-            {
-                switch (post_op_name[1])
-                {
-                    case '<': op_kind = clang::OO_LessLess; break;
-                    case '=': op_kind = clang::OO_LessEqual; break;
-                }
-            }
-            else if (post_op_name[3] == '\0')
-            {
-                if (post_op_name[2] == '=')
-                    op_kind = clang::OO_LessLessEqual;
-            }
-            break;
-            
-        case '>':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Greater;
-            else if (post_op_name[2] == '\0')
-            {
-                switch (post_op_name[1])
-                {
-                    case '>': op_kind = clang::OO_GreaterGreater; break;
-                    case '=': op_kind = clang::OO_GreaterEqual; break;
-                }
-            }
-            else if (post_op_name[1] == '>' &&
-                     post_op_name[2] == '=' &&
-                     post_op_name[3] == '\0')
-            {
-                op_kind = clang::OO_GreaterGreaterEqual;
-            }
-            break;
-            
-        case ',':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Comma;
-            break;
-            
-        case '(':
-            if (post_op_name[1] == ')' && post_op_name[2] == '\0')
-                op_kind = clang::OO_Call;
-            break;
-            
-        case '[':
-            if (post_op_name[1] == ']' && post_op_name[2] == '\0')
-                op_kind = clang::OO_Subscript;
-            break;
-    }
-    
-    return true;
-}
-
-clang::EnumDecl *
-ClangASTType::GetAsEnumDecl () const
-{
-    const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType());
-    if (enum_type)
-        return enum_type->getDecl();
-    return NULL;
-}
-
-clang::RecordDecl *
-ClangASTType::GetAsRecordDecl () const
-{
-    const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(GetCanonicalQualType());
-    if (record_type)
-        return record_type->getDecl();
-    return nullptr;
-}
-
-clang::CXXRecordDecl *
-ClangASTType::GetAsCXXRecordDecl () const
-{
-    return GetCanonicalQualType()->getAsCXXRecordDecl();
-}
-
-clang::ObjCInterfaceDecl *
-ClangASTType::GetAsObjCInterfaceDecl () const
-{
-    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(GetCanonicalQualType());
-    if (objc_class_type)
-        return objc_class_type->getInterface();
-    return nullptr;
-}
-
-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 nullptr;
-    
-    clang::FieldDecl *field = nullptr;
-
-    clang::Expr *bit_width = nullptr;
-    if (bitfield_bit_size != 0)
-    {
-        llvm::APInt bitfield_bit_size_apint(m_ast->getTypeSize(m_ast->IntTy), bitfield_bit_size);
-        bit_width = new (*m_ast)clang::IntegerLiteral (*m_ast, bitfield_bit_size_apint, m_ast->IntTy, clang::SourceLocation());
-    }
-
-    clang::RecordDecl *record_decl = GetAsRecordDecl ();
-    if (record_decl)
-    {
-        field = clang::FieldDecl::Create (*m_ast,
-                                          record_decl,
-                                          clang::SourceLocation(),
-                                          clang::SourceLocation(),
-                                          name ? &m_ast->Idents.get(name) : nullptr,  // Identifier
-                                          field_clang_type.GetQualType(),             // Field type
-                                          nullptr,                                    // TInfo *
-                                          bit_width,                                  // BitWidth
-                                          false,                                      // Mutable
-                                          clang::ICIS_NoInit);                        // HasInit
-        
-        if (!name)
-        {
-            // Determine whether this field corresponds to an anonymous
-            // struct or union.
-            if (const clang::TagType *TagT = field->getType()->getAs<clang::TagType>()) {
-                if (clang::RecordDecl *Rec = llvm::dyn_cast<clang::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
-    {
-        clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
-        
-        if (class_interface_decl)
-        {
-            const bool is_synthesized = false;
-            
-            field_clang_type.GetCompleteType();
-
-            field = clang::ObjCIvarDecl::Create (*m_ast,
-                                          class_interface_decl,
-                                          clang::SourceLocation(),
-                                          clang::SourceLocation(),
-                                          name ? &m_ast->Idents.get(name) : nullptr,   // Identifier
-                                          field_clang_type.GetQualType(),           // Field type
-                                          nullptr,                                     // 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::BuildIndirectFields ()
-{
-    clang::RecordDecl *record_decl = GetAsRecordDecl();
-    
-    if (!record_decl)
-        return;
-    
-    typedef llvm::SmallVector <clang::IndirectFieldDecl *, 1> IndirectFieldVector;
-    
-    IndirectFieldVector indirect_fields;
-    clang::RecordDecl::field_iterator field_pos;
-    clang::RecordDecl::field_iterator field_end_pos = record_decl->field_end();
-    clang::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())
-        {
-            clang::QualType field_qual_type = field_pos->getType();
-            
-            const clang::RecordType *field_record_type = field_qual_type->getAs<clang::RecordType>();
-            
-            if (!field_record_type)
-                continue;
-            
-            clang::RecordDecl *field_record_decl = field_record_type->getDecl();
-            
-            if (!field_record_decl)
-                continue;
-            
-            for (clang::RecordDecl::decl_iterator di = field_record_decl->decls_begin(), de = field_record_decl->decls_end();
-                 di != de;
-                 ++di)
-            {
-                if (clang::FieldDecl *nested_field_decl = llvm::dyn_cast<clang::FieldDecl>(*di))
-                {
-                    clang::NamedDecl **chain = new (*m_ast) clang::NamedDecl*[2];
-                    chain[0] = *field_pos;
-                    chain[1] = nested_field_decl;
-                    clang::IndirectFieldDecl *indirect_field = clang::IndirectFieldDecl::Create(*m_ast,
-                                                                                                record_decl,
-                                                                                                clang::SourceLocation(),
-                                                                                                nested_field_decl->getIdentifier(),
-                                                                                                nested_field_decl->getType(),
-                                                                                                chain,
-                                                                                                2);
-                    
-                    indirect_field->setImplicit();
-                    
-                    indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(field_pos->getAccess(),
-                                                                                     nested_field_decl->getAccess()));
-                    
-                    indirect_fields.push_back(indirect_field);
-                }
-                else if (clang::IndirectFieldDecl *nested_indirect_field_decl = llvm::dyn_cast<clang::IndirectFieldDecl>(*di))
-                {
-                    int nested_chain_size = nested_indirect_field_decl->getChainingSize();
-                    clang::NamedDecl **chain = new (*m_ast) clang::NamedDecl*[nested_chain_size + 1];
-                    chain[0] = *field_pos;
-                    
-                    int chain_index = 1;
-                    for (clang::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++;
-                    }
-                    
-                    clang::IndirectFieldDecl *indirect_field = clang::IndirectFieldDecl::Create(*m_ast,
-                                                                                                record_decl,
-                                                                                                clang::SourceLocation(),
-                                                                                                nested_indirect_field_decl->getIdentifier(),
-                                                                                                nested_indirect_field_decl->getType(),
-                                                                                                chain,
-                                                                                                nested_chain_size + 1);
-                    
-                    indirect_field->setImplicit();
-                    
-                    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);
-    }
-}
-
-void
-ClangASTType::SetIsPacked ()
-{
-    clang::RecordDecl *record_decl = GetAsRecordDecl();
-    
-    if (!record_decl)
-        return;
-    
-    record_decl->addAttr(clang::PackedAttr::CreateImplicit(*m_ast));
-}
-
-clang::VarDecl *
-ClangASTType::AddVariableToRecordType (const char *name,
-                                       const ClangASTType &var_type,
-                                       AccessType access)
-{
-    clang::VarDecl *var_decl = nullptr;
-    
-    if (!IsValid() || !var_type.IsValid())
-        return nullptr;
-    
-    clang::RecordDecl *record_decl = GetAsRecordDecl ();
-    if (record_decl)
-    {        
-        var_decl = clang::VarDecl::Create (*m_ast,                                     // ASTContext &
-                                           record_decl,                                // DeclContext *
-                                           clang::SourceLocation(),                    // clang::SourceLocation StartLoc
-                                           clang::SourceLocation(),                    // clang::SourceLocation IdLoc
-                                           name ? &m_ast->Idents.get(name) : nullptr,  // clang::IdentifierInfo *
-                                           var_type.GetQualType(),                     // Variable clang::QualType
-                                           nullptr,                                    // TypeSourceInfo *
-                                           clang::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;
-}
-
-
-clang::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 == nullptr || name[0] == '\0')
-        return nullptr;
-    
-    clang::QualType record_qual_type(GetCanonicalQualType());
-    
-    clang::CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
-    
-    if (cxx_record_decl == nullptr)
-        return nullptr;
-    
-    clang::QualType method_qual_type (method_clang_type.GetQualType());
-    
-    clang::CXXMethodDecl *cxx_method_decl = nullptr;
-    
-    clang::DeclarationName decl_name (&m_ast->Idents.get(name));
-    
-    const clang::FunctionType *function_type = llvm::dyn_cast<clang::FunctionType>(method_qual_type.getTypePtr());
-    
-    if (function_type == nullptr)
-        return nullptr;
-    
-    const clang::FunctionProtoType *method_function_prototype (llvm::dyn_cast<clang::FunctionProtoType>(function_type));
-    
-    if (!method_function_prototype)
-        return nullptr;
-    
-    unsigned int num_params = method_function_prototype->getNumParams();
-    
-    clang::CXXDestructorDecl *cxx_dtor_decl(nullptr);
-    clang::CXXConstructorDecl *cxx_ctor_decl(nullptr);
-    
-    if (is_artificial)
-        return nullptr; // skip everything artificial
-    
-    if (name[0] == '~')
-    {
-        cxx_dtor_decl = clang::CXXDestructorDecl::Create (*m_ast,
-                                                          cxx_record_decl,
-                                                          clang::SourceLocation(),
-                                                          clang::DeclarationNameInfo (m_ast->DeclarationNames.getCXXDestructorName (m_ast->getCanonicalType (record_qual_type)), clang::SourceLocation()),
-                                                          method_qual_type,
-                                                          nullptr,
-                                                          is_inline,
-                                                          is_artificial);
-        cxx_method_decl = cxx_dtor_decl;
-    }
-    else if (decl_name == cxx_record_decl->getDeclName())
-    {
-        cxx_ctor_decl = clang::CXXConstructorDecl::Create (*m_ast,
-                                                           cxx_record_decl,
-                                                           clang::SourceLocation(),
-                                                           clang::DeclarationNameInfo (m_ast->DeclarationNames.getCXXConstructorName (m_ast->getCanonicalType (record_qual_type)), clang::SourceLocation()),
-                                                           method_qual_type,
-                                                           nullptr, // TypeSourceInfo *
-                                                           is_explicit,
-                                                           is_inline,
-                                                           is_artificial,
-                                                           false /*is_constexpr*/);
-        cxx_method_decl = cxx_ctor_decl;
-    }
-    else
-    {
-        clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None;
-        clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
-        
-        if (IsOperator (name, op_kind))
-        {
-            if (op_kind != clang::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 nullptr;
-                cxx_method_decl = clang::CXXMethodDecl::Create (*m_ast,
-                                                                cxx_record_decl,
-                                                                clang::SourceLocation(),
-                                                                clang::DeclarationNameInfo (m_ast->DeclarationNames.getCXXOperatorName (op_kind), clang::SourceLocation()),
-                                                                method_qual_type,
-                                                                nullptr, // TypeSourceInfo *
-                                                                SC,
-                                                                is_inline,
-                                                                false /*is_constexpr*/,
-                                                                clang::SourceLocation());
-            }
-            else if (num_params == 0)
-            {
-                // Conversion operators don't take params...
-                cxx_method_decl = clang::CXXConversionDecl::Create (*m_ast,
-                                                                    cxx_record_decl,
-                                                                    clang::SourceLocation(),
-                                                                    clang::DeclarationNameInfo (m_ast->DeclarationNames.getCXXConversionFunctionName (m_ast->getCanonicalType (function_type->getReturnType())), clang::SourceLocation()),
-                                                                    method_qual_type,
-                                                                    nullptr, // TypeSourceInfo *
-                                                                    is_inline,
-                                                                    is_explicit,
-                                                                    false /*is_constexpr*/,
-                                                                    clang::SourceLocation());
-            }
-        }
-        
-        if (cxx_method_decl == nullptr)
-        {
-            cxx_method_decl = clang::CXXMethodDecl::Create (*m_ast,
-                                                            cxx_record_decl,
-                                                            clang::SourceLocation(),
-                                                            clang::DeclarationNameInfo (decl_name, clang::SourceLocation()),
-                                                            method_qual_type,
-                                                            nullptr, // TypeSourceInfo *
-                                                            SC,
-                                                            is_inline,
-                                                            false /*is_constexpr*/,
-                                                            clang::SourceLocation());
-        }
-    }
-    
-    clang::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(clang::UsedAttr::CreateImplicit(*m_ast));
-    
-    // Populate the method decl with parameter decls
-    
-    llvm::SmallVector<clang::ParmVarDecl *, 12> params;
-    
-    for (unsigned param_index = 0;
-         param_index < num_params;
-         ++param_index)
-    {
-        params.push_back (clang::ParmVarDecl::Create (*m_ast,
-                                                      cxx_method_decl,
-                                                      clang::SourceLocation(),
-                                                      clang::SourceLocation(),
-                                                      nullptr, // anonymous
-                                                      method_function_prototype->getParamType(param_index),
-                                                      nullptr,
-                                                      clang::SC_None,
-                                                      nullptr));
-    }
-    
-    cxx_method_decl->setParams (llvm::ArrayRef<clang::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
-
-clang::CXXBaseSpecifier *
-ClangASTType::CreateBaseClassSpecifier (AccessType access, bool is_virtual, bool base_of_class)
-{
-    if (IsValid())
-        return new clang::CXXBaseSpecifier (clang::SourceRange(),
-                                            is_virtual,
-                                            base_of_class,
-                                            ClangASTContext::ConvertAccessTypeToAccessSpecifier (access),
-                                            m_ast->getTrivialTypeSourceInfo (GetQualType()),
-                                            clang::SourceLocation());
-    return nullptr;
-}
-
-void
-ClangASTType::DeleteBaseClassSpecifiers (clang::CXXBaseSpecifier **base_classes, unsigned num_base_classes)
-{
-    for (unsigned i=0; i<num_base_classes; ++i)
-    {
-        delete base_classes[i];
-        base_classes[i] = nullptr;
-    }
-}
-
-bool
-ClangASTType::SetBaseClassesForClassType (clang::CXXBaseSpecifier const * const *base_classes,
-                                          unsigned num_base_classes)
-{
-    if (IsValid())
-    {
-        clang::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())
-    {
-        clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
-        clang::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,
-                                    clang::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 == nullptr || property_name[0] == '\0')
-        return false;
-        
-    clang::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());
-            
-            clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create (*m_ast,
-                                                                                      class_interface_decl,
-                                                                                      clang::SourceLocation(), // Source Location
-                                                                                      &m_ast->Idents.get(property_name),
-                                                                                      clang::SourceLocation(), //Source Location for AT
-                                                                                      clang::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);
-                
-                clang::Selector setter_sel, getter_sel;
-                
-                if (property_setter_name != nullptr)
-                {
-                    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 != nullptr)
-                {
-                    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 clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None;
-                    const bool HasRelatedResultType = false;
-                    
-                    clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create (*m_ast,
-                                                                                   clang::SourceLocation(),
-                                                                                   clang::SourceLocation(),
-                                                                                   getter_sel,
-                                                                                   property_clang_type_to_access.GetQualType(),
-                                                                                   nullptr,
-                                                                                   class_interface_decl,
-                                                                                   isInstance,
-                                                                                   isVariadic,
-                                                                                   isSynthesized,
-                                                                                   isImplicitlyDeclared,
-                                                                                   isDefined,
-                                                                                   impControl,
-                                                                                   HasRelatedResultType);
-                    
-                    if (getter && metadata)
-                        ClangASTContext::SetMetadata(m_ast, getter, *metadata);
-                    
-                    if (getter)
-                    {
-                        getter->setMethodParams(*m_ast, llvm::ArrayRef<clang::ParmVarDecl*>(), llvm::ArrayRef<clang::SourceLocation>());
-                    
-                        class_interface_decl->addDecl(getter);
-                    }
-                }
-                
-                if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel))
-                {
-                    clang::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 clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None;
-                    const bool HasRelatedResultType = false;
-                    
-                    clang::ObjCMethodDecl *setter = clang::ObjCMethodDecl::Create (*m_ast,
-                                                                                   clang::SourceLocation(),
-                                                                                   clang::SourceLocation(),
-                                                                                   setter_sel,
-                                                                                   result_type,
-                                                                                   nullptr,
-                                                                                   class_interface_decl,
-                                                                                   isInstance,
-                                                                                   isVariadic,
-                                                                                   isSynthesized,
-                                                                                   isImplicitlyDeclared,
-                                                                                   isDefined,
-                                                                                   impControl,
-                                                                                   HasRelatedResultType);
-                    
-                    if (setter && metadata)
-                        ClangASTContext::SetMetadata(m_ast, setter, *metadata);
-                    
-                    llvm::SmallVector<clang::ParmVarDecl *, 1> params;
-                    
-                    params.push_back (clang::ParmVarDecl::Create (*m_ast,
-                                                                  setter,
-                                                                  clang::SourceLocation(),
-                                                                  clang::SourceLocation(),
-                                                                  nullptr, // anonymous
-                                                                  property_clang_type_to_access.GetQualType(),
-                                                                  nullptr,
-                                                                  clang::SC_Auto,
-                                                                  nullptr));
-                    
-                    if (setter)
-                    {
-                        setter->setMethodParams(*m_ast, llvm::ArrayRef<clang::ParmVarDecl*>(params), llvm::ArrayRef<clang::SourceLocation>());
-                    
-                        class_interface_decl->addDecl(setter);
-                    }
-                }
-                
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-bool
-ClangASTType::IsObjCClassTypeAndHasIVars (bool check_superclass) const
-{
-    clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
-    if (class_interface_decl)
-        return ObjCDeclHasIVars (class_interface_decl, check_superclass);
-    return false;
-}
-
-
-clang::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 nullptr;
-
-    clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl();
-    
-    if (class_interface_decl == nullptr)
-        return nullptr;
-    
-    const char *selector_start = ::strchr (name, ' ');
-    if (selector_start == nullptr)
-        return nullptr;
-    
-    selector_start++;
-    llvm::SmallVector<clang::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 (llvm::StringRef (start, len)));
-        if (has_arg)
-            len += 1;
-    }
-    
-    
-    if (selector_idents.size() == 0)
-        return nullptr;
-    
-    clang::Selector method_selector = m_ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
-                                                                    selector_idents.data());
-    
-    clang::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 == nullptr)
-        return nullptr;
-    
-    const clang::FunctionProtoType *method_function_prototype (llvm::dyn_cast<clang::FunctionProtoType>(method_type));
-    
-    if (!method_function_prototype)
-        return nullptr;
-    
-    
-    bool is_variadic = false;
-    bool is_synthesized = false;
-    bool is_defined = false;
-    clang::ObjCMethodDecl::ImplementationControl imp_control = clang::ObjCMethodDecl::None;
-    
-    const unsigned num_args = method_function_prototype->getNumParams();
-    
-    if (num_args != num_selectors_with_args)
-        return nullptr; // some debug information is corrupt.  We are not going to deal with it.
-    
-    clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create (*m_ast,
-                                                                             clang::SourceLocation(), // beginLoc,
-                                                                             clang::SourceLocation(), // endLoc,
-                                                                             method_selector,
-                                                                             method_function_prototype->getReturnType(),
-                                                                             nullptr, // 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 == nullptr)
-        return nullptr;
-    
-    if (num_args > 0)
-    {
-        llvm::SmallVector<clang::ParmVarDecl *, 12> params;
-        
-        for (unsigned param_index = 0; param_index < num_args; ++param_index)
-        {
-            params.push_back (clang::ParmVarDecl::Create (*m_ast,
-                                                          objc_method_decl,
-                                                          clang::SourceLocation(),
-                                                          clang::SourceLocation(),
-                                                          nullptr, // anonymous
-                                                          method_function_prototype->getParamType(param_index),
-                                                          nullptr,
-                                                          clang::SC_Auto,
-                                                          nullptr));
-        }
-        
-        objc_method_decl->setMethodParams(*m_ast, llvm::ArrayRef<clang::ParmVarDecl*>(params), llvm::ArrayRef<clang::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 nullptr;
-    
-    clang::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 llvm::cast<clang::ObjCObjectType>(qual_type.getTypePtr())->getInterface();
-        case clang::Type::ObjCObjectPointer:        return ClangASTType (m_ast, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType()).GetDeclContextForType();
-        case clang::Type::Record:                   return llvm::cast<clang::RecordType>(qual_type)->getDecl();
-        case clang::Type::Enum:                     return llvm::cast<clang::EnumType>(qual_type)->getDecl();
-        case clang::Type::Typedef:                  return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetDeclContextForType();
-        case clang::Type::Elaborated:               return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetDeclContextForType();
-        case clang::Type::Paren:                    return ClangASTType (m_ast, llvm::cast<clang::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;
-        case clang::Type::Adjusted:                 break;
-
-        // pointer type decayed from an array or function type.
-        case clang::Type::Decayed:                  break;
-    }
-    // No DeclContext in this type...
-    return nullptr;
-}
-
-bool
-ClangASTType::SetDefaultAccessForRecordFields (int default_accessibility,
-                                               int *assigned_accessibilities,
-                                               size_t num_assigned_accessibilities)
-{
-    if (IsValid())
-    {
-        clang::RecordDecl *record_decl = GetAsRecordDecl();
-        if (record_decl)
-        {
-            uint32_t field_idx;
-            clang::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 ((clang::AccessSpecifier)default_accessibility);
-            }
-            return true;
-        }
-    }
-    return false;
-}
-
-
-bool
-ClangASTType::SetHasExternalStorage (bool has_extern)
-{
-    if (!IsValid())
-        return false;
-    
-    clang::QualType qual_type (GetCanonicalQualType());
-    
-    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-    switch (type_class)
-    {
-        case clang::Type::Record:
-        {
-            clang::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:
-        {
-            clang::EnumDecl *enum_decl = llvm::cast<clang::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 clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
-            assert (objc_class_type);
-            if (objc_class_type)
-            {
-                clang::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, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).SetHasExternalStorage (has_extern);
-            
-        case clang::Type::Elaborated:
-            return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).SetHasExternalStorage (has_extern);
-            
-        case clang::Type::Paren:
-            return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).SetHasExternalStorage (has_extern);
-            
-        default:
-            break;
-    }
-    return false;
-}
-
-bool
-ClangASTType::SetTagTypeKind (int kind) const
-{
-    if (IsValid())
-    {
-        clang::QualType tag_qual_type(GetQualType());
-        const clang::Type *clang_type = tag_qual_type.getTypePtr();
-        if (clang_type)
-        {
-            const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
-            if (tag_type)
-            {
-                clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
-                if (tag_decl)
-                {
-                    tag_decl->setTagKind ((clang::TagDecl::TagKind)kind);
-                    return true;
-                }
-            }
-        }
-    }
-    return false;
-}
-
-
 #pragma mark TagDecl
 
-bool
-ClangASTType::StartTagDeclarationDefinition ()
-{
-    if (IsValid())
-    {
-        clang::QualType qual_type (GetQualType());
-        const clang::Type *t = qual_type.getTypePtr();
-        if (t)
-        {
-            const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(t);
-            if (tag_type)
-            {
-                clang::TagDecl *tag_decl = tag_type->getDecl();
-                if (tag_decl)
-                {
-                    tag_decl->startDefinition();
-                    return true;
-                }
-            }
-            
-            const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(t);
-            if (object_type)
-            {
-                clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface();
-                if (interface_decl)
-                {
-                    interface_decl->startDefinition();
-                    return true;
-                }
-            }
-        }
-    }
-    return false;
-}
-
-bool
-ClangASTType::CompleteTagDeclarationDefinition ()
-{
-    if (IsValid())
-    {
-        clang::QualType qual_type (GetQualType());
-        
-        clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-        
-        if (cxx_record_decl)
-        {
-            cxx_record_decl->completeDefinition();
-            
-            return true;
-        }
-        
-        const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(qual_type.getTypePtr());
-        
-        if (enum_type)
-        {
-            clang::EnumDecl *enum_decl = enum_type->getDecl();
-            
-            if (enum_decl)
-            {
-                /// TODO This really needs to be fixed.
-                
-                unsigned NumPositiveBits = 1;
-                unsigned NumNegativeBits = 0;
-                                
-                clang::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])
-    {
-        clang::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 clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(clang_type);
-            
-            if (enum_type)
-            {
-                llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed);
-                enum_llvm_apsint = enum_value;
-                clang::EnumConstantDecl *enumerator_decl =
-                clang::EnumConstantDecl::Create (*m_ast,
-                                                 enum_type->getDecl(),
-                                                 clang::SourceLocation(),
-                                                 name ? &m_ast->Idents.get(name) : nullptr,    // Identifier
-                                                 enumerator_clang_type.GetQualType(),
-                                                 nullptr,
-                                                 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
-{
-    clang::QualType enum_qual_type (GetCanonicalQualType());
-    const clang::Type *clang_type = enum_qual_type.getTypePtr();
-    if (clang_type)
-    {
-        const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(clang_type);
-        if (enum_type)
-        {
-            clang::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())
-    {
-        clang::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;
-            
-            llvm::StringRef s_sref(s);
-            llvm::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 m_type_system->ConvertStringToFloatValue(m_type, s, dst, dst_size);
     return 0;
 }
 
@@ -6055,7 +748,6 @@
 //----------------------------------------------------------------------
 // Dumping types
 //----------------------------------------------------------------------
-#define DEPTH_INCREMENT 2
 
 void
 ClangASTType::DumpValue (ExecutionContext *exe_ctx,
@@ -6073,315 +765,7 @@
 {
     if (!IsValid())
         return;
-
-    clang::QualType qual_type(GetQualType());
-    switch (qual_type->getTypeClass())
-    {
-    case clang::Type::Record:
-        if (GetCompleteType ())
-        {
-            const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
-            const clang::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 = m_ast->getASTRecordLayout(record_decl);
-            uint32_t child_idx = 0;
-
-            const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::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;
-                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());
-
-                    // Skip empty base classes
-                    if (verbose == false && ClangASTContext::RecordHasFields(base_class_decl) == false)
-                        continue;
-
-                    if (base_class->isVirtual())
-                        field_bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
-                    else
-                        field_bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
-                    field_byte_offset = field_bit_offset / 8;
-                    assert (field_bit_offset % 8 == 0);
-                    if (child_idx == 0)
-                        s->PutChar('{');
-                    else
-                        s->PutChar(',');
-
-                    clang::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());
-
-                    clang::TypeInfo base_class_type_info = m_ast->getTypeInfo(base_class_qual_type);
-
-                    // Dump the value of the member
-                    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.Width / 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;
-            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
-                // first member) or comman (for member 2 and beyong) for
-                // the struct/union/class member.
-                if (child_idx == 0)
-                    s->PutChar('{');
-                else
-                    s->PutChar(',');
-
-                // Indent
-                s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
-
-                clang::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.
-                clang::TypeInfo 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 (m_ast, *field, field_bitfield_bit_size))
-                    field_bitfield_bit_offset = field_bit_offset % 8;
-
-                if (show_types)
-                {
-                    std::string field_type_name(field_type.getAsString());
-                    if (field_bitfield_bit_size > 0)
-                        s->Printf("(%s:%u) ", field_type_name.c_str(), field_bitfield_bit_size);
-                    else
-                        s->Printf("(%s) ", field_type_name.c_str());
-                }
-                // Print the member name and equal sign
-                s->Printf("%s = ", field->getNameAsString().c_str());
-
-
-                // Dump the value of the member
-                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.Width / 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
-            if (child_idx > 0)
-                s->Printf("\n%*s}", depth, "");
-        }
-        return;
-
-    case clang::Type::Enum:
-        if (GetCompleteType ())
-        {
-            const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
-            const clang::EnumDecl *enum_decl = enum_type->getDecl();
-            assert(enum_decl);
-            clang::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)
-            {
-                if (enum_pos->getInitVal() == enum_value)
-                {
-                    s->Printf("%s", enum_pos->getNameAsString().c_str());
-                    return;
-                }
-            }
-            // If we have gotten here we didn't get find the enumerator in the
-            // enum decl, so just print the integer.
-            s->Printf("%" PRIi64, enum_value);
-        }
-        return;
-
-    case clang::Type::ConstantArray:
-        {
-            const clang::ConstantArrayType *array = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
-            bool is_array_of_characters = false;
-            clang::QualType element_qual_type = array->getElementType();
-
-            const clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
-            if (canonical_type)
-                is_array_of_characters = canonical_type->isCharType();
-
-            const uint64_t element_count = array->getSize().getLimitedValue();
-
-            clang::TypeInfo field_type_info = m_ast->getTypeInfo(element_qual_type);
-
-            uint32_t element_idx = 0;
-            uint32_t element_offset = 0;
-            uint64_t element_byte_size = field_type_info.Width / 8;
-            uint32_t element_stride = element_byte_size;
-
-            if (is_array_of_characters)
-            {
-                s->PutChar('"');
-                data.Dump(s, data_byte_offset, lldb::eFormatChar, element_byte_size, element_count, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
-                s->PutChar('"');
-                return;
-            }
-            else
-            {
-                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)
-                {
-                    // Print the starting squiggly bracket (if this is the
-                    // first member) or comman (for member 2 and beyong) for
-                    // the struct/union/class member.
-                    if (element_idx == 0)
-                        s->PutChar('{');
-                    else
-                        s->PutChar(',');
-
-                    // Indent and print the index
-                    s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx);
-
-                    // Figure out the field offset within the current struct/union/class type
-                    element_offset = element_idx * element_stride;
-
-                    // Dump the value of the member
-                    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
-                if (element_idx > 0)
-                    s->Printf("\n%*s}", depth, "");
-            }
-        }
-        return;
-
-    case clang::Type::Typedef:
-        {
-            clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType();
-            
-            ClangASTType typedef_clang_type (m_ast, typedef_qual_type);
-            lldb::Format typedef_format = typedef_clang_type.GetFormat();
-            clang::TypeInfo typedef_type_info = m_ast->getTypeInfo(typedef_qual_type);
-            uint64_t typedef_byte_size = typedef_type_info.Width / 8;
-
-            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();
-            ClangASTType elaborated_clang_type (m_ast, elaborated_qual_type);
-            lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
-            clang::TypeInfo elaborated_type_info = m_ast->getTypeInfo(elaborated_qual_type);
-            uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
-
-            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();
-            ClangASTType desugar_clang_type (m_ast, desugar_qual_type);
-
-            lldb::Format desugar_format = desugar_clang_type.GetFormat();
-            clang::TypeInfo desugar_type_info = m_ast->getTypeInfo(desugar_qual_type);
-            uint64_t desugar_byte_size = desugar_type_info.Width / 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);
-
-        if (show_summary)
-            DumpSummary (exe_ctx, s, data, data_byte_offset, data_byte_size);
-        break;
-    }
+    m_type_system->DumpValue(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);
 }
 
 
@@ -6399,152 +783,7 @@
 {
     if (!IsValid())
         return false;
-    if (IsAggregateType())
-    {
-        return false;
-    }
-    else
-    {
-        clang::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();
-                ClangASTType typedef_clang_type (m_ast, typedef_qual_type);
-                if (format == eFormatDefault)
-                    format = typedef_clang_type.GetFormat();
-                clang::TypeInfo typedef_type_info = m_ast->getTypeInfo(typedef_qual_type);
-                uint64_t typedef_byte_size = typedef_type_info.Width / 8;
-
-                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) && GetCompleteType ())
-            {
-                const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
-                const clang::EnumDecl *enum_decl = enum_type->getDecl();
-                assert(enum_decl);
-                clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
-                const bool is_signed = qual_type->isSignedIntegerOrEnumerationType();
-                lldb::offset_t offset = byte_offset;
-                if (is_signed)
-                {
-                    const int64_t enum_svalue = data.GetMaxS64Bitfield (&offset, 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)
-                    {
-                        if (enum_pos->getInitVal().getSExtValue() == enum_svalue)
-                        {
-                            s->PutCString (enum_pos->getNameAsString().c_str());
-                            return true;
-                        }
-                    }
-                    // If we have gotten here we didn't get find the enumerator in the
-                    // enum decl, so just print the integer.                    
-                    s->Printf("%" PRIi64, enum_svalue);
-                }
-                else
-                {
-                    const uint64_t enum_uvalue = data.GetMaxU64Bitfield (&offset, 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)
-                    {
-                        if (enum_pos->getInitVal().getZExtValue() == enum_uvalue)
-                        {
-                            s->PutCString (enum_pos->getNameAsString().c_str());
-                            return true;
-                        }
-                    }
-                    // If we have gotten here we didn't get find the enumerator in the
-                    // enum decl, so just print the integer.
-                    s->Printf("%" PRIu64, enum_uvalue);
-                }
-                return true;
-            }
-            // format was not enum, just fall through and dump the value as requested....
-                
-        default:
-            // We are down the a scalar type that we just need to display.
-            {
-                uint32_t item_count = 1;
-                // A few formats, we might need to modify our size and count for depending
-                // on how we are trying to display the value...
-                switch (format)
-                {
-                    default:
-                    case eFormatBoolean:
-                    case eFormatBinary:
-                    case eFormatComplex:
-                    case eFormatCString:         // NULL terminated C strings
-                    case eFormatDecimal:
-                    case eFormatEnum:
-                    case eFormatHex:
-                    case eFormatHexUppercase:
-                    case eFormatFloat:
-                    case eFormatOctal:
-                    case eFormatOSType:
-                    case eFormatUnsigned:
-                    case eFormatPointer:
-                    case eFormatVectorOfChar:
-                    case eFormatVectorOfSInt8:
-                    case eFormatVectorOfUInt8:
-                    case eFormatVectorOfSInt16:
-                    case eFormatVectorOfUInt16:
-                    case eFormatVectorOfSInt32:
-                    case eFormatVectorOfUInt32:
-                    case eFormatVectorOfSInt64:
-                    case eFormatVectorOfUInt64:
-                    case eFormatVectorOfFloat32:
-                    case eFormatVectorOfFloat64:
-                    case eFormatVectorOfUInt128:
-                        break;
-
-                    case eFormatChar: 
-                    case eFormatCharPrintable:  
-                    case eFormatCharArray:
-                    case eFormatBytes:
-                    case eFormatBytesWithASCII:
-                        item_count = byte_size;
-                        byte_size = 1; 
-                        break;
-
-                    case eFormatUnicode16:
-                        item_count = byte_size / 2; 
-                        byte_size = 2; 
-                        break;
-
-                    case eFormatUnicode32:
-                        item_count = byte_size / 4; 
-                        byte_size = 4; 
-                        break;
-                }
-                return data.Dump (s,
-                                  byte_offset,
-                                  format,
-                                  byte_size,
-                                  item_count,
-                                  UINT32_MAX,
-                                  LLDB_INVALID_ADDRESS,
-                                  bitfield_bit_size,
-                                  bitfield_bit_offset,
-                                  exe_scope);
-            }
-            break;
-        }
-    }
-    return 0;
+    return m_type_system->DumpTypeValue(m_type, s, format, data, byte_offset, byte_size, bitfield_bit_size, bitfield_bit_offset, exe_scope);
 }
 
 
@@ -6556,57 +795,15 @@
                            lldb::offset_t data_byte_offset,
                            size_t data_byte_size)
 {
-    uint32_t length = 0;
-    if (IsCStringType (length))
-    {
-        if (exe_ctx)
-        {
-            Process *process = exe_ctx->GetProcessPtr();
-            if (process)
-            {
-                lldb::offset_t offset = data_byte_offset;
-                lldb::addr_t pointer_address = data.GetMaxU64(&offset, data_byte_size);
-                std::vector<uint8_t> buf;
-                if (length > 0)
-                    buf.resize (length);
-                else
-                    buf.resize (256);
-
-                lldb_private::DataExtractor cstr_data(&buf.front(), buf.size(), process->GetByteOrder(), 4);
-                buf.back() = '\0';
-                size_t bytes_read;
-                size_t total_cstr_len = 0;
-                Error error;
-                while ((bytes_read = process->ReadMemory (pointer_address, &buf.front(), buf.size(), error)) > 0)
-                {
-                    const size_t len = strlen((const char *)&buf.front());
-                    if (len == 0)
-                        break;
-                    if (total_cstr_len == 0)
-                        s->PutCString (" \"");
-                    cstr_data.Dump(s, 0, lldb::eFormatChar, 1, len, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
-                    total_cstr_len += len;
-                    if (len < buf.size())
-                        break;
-                    pointer_address += total_cstr_len;
-                }
-                if (total_cstr_len > 0)
-                    s->PutChar ('"');
-            }
-        }
-    }
+    if (IsValid())
+        m_type_system->DumpSummary(m_type, exe_ctx, s, data, data_byte_offset, data_byte_size);
 }
 
 void
 ClangASTType::DumpTypeDescription () const
 {
-    StreamFile s (stdout, false);
-    DumpTypeDescription (&s);
-    ClangASTMetadata *metadata = ClangASTContext::GetMetadata (m_ast, m_type);
-    if (metadata)
-    {
-        metadata->Dump (&s);
-    }
+    if (IsValid())
+        m_type_system->DumpTypeDescription(m_type);
 }
 
 void
@@ -6614,95 +811,7 @@
 {
     if (IsValid())
     {
-        clang::QualType qual_type(GetQualType());
-
-        llvm::SmallVector<char, 1024> buf;
-        llvm::raw_svector_ostream llvm_ostrm (buf);
-
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-        case clang::Type::ObjCObject:
-        case clang::Type::ObjCInterface:
-            {
-                GetCompleteType ();
-                
-                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
-                assert (objc_class_type);
-                if (objc_class_type)
-                {
-                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                    if (class_interface_decl)
-                    {
-                        clang::PrintingPolicy policy = m_ast->getPrintingPolicy();
-                        class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
-                    }
-                }
-            }
-            break;
-        
-        case clang::Type::Typedef:
-            {
-                const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
-                if (typedef_type)
-                {
-                    const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
-                    std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString());
-                    if (!clang_typedef_name.empty())
-                    {
-                        s->PutCString ("typedef ");
-                        s->PutCString (clang_typedef_name.c_str());
-                    }
-                }
-            }
-            break;
-
-        case clang::Type::Elaborated:
-            ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).DumpTypeDescription(s);
-            return;
-
-        case clang::Type::Paren:
-            ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).DumpTypeDescription(s);
-            return;
-
-        case clang::Type::Record:
-            {
-                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);
-
-                if (cxx_record_decl)
-                    cxx_record_decl->print(llvm_ostrm, m_ast->getPrintingPolicy(), s->GetIndentLevel());
-                else
-                    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());
-                if (tag_type)
-                {
-                    clang::TagDecl *tag_decl = tag_type->getDecl();
-                    if (tag_decl)
-                        tag_decl->print(llvm_ostrm, 0);
-                }
-                else
-                {
-                    std::string clang_type_name(qual_type.getAsString());
-                    if (!clang_type_name.empty())
-                        s->PutCString (clang_type_name.c_str());
-                }
-            }
-        }
-        
-        llvm_ostrm.flush();
-        if (buf.size() > 0)
-        {
-            s->Write (buf.data(), buf.size());
-        }
+        m_type_system->DumpTypeDescription(m_type, s);
     }
 }
 
@@ -6714,7 +823,7 @@
 {
     if (!IsValid())
         return false;
-
+    
     if (IsAggregateType ())
     {
         return false;   // Aggregate types don't have scalar values
@@ -6723,120 +832,120 @@
     {
         uint64_t count = 0;
         lldb::Encoding encoding = GetEncoding (count);
-
+        
         if (encoding == lldb::eEncodingInvalid || count != 1)
             return false;
-
+        
         const uint64_t byte_size = GetByteSize(nullptr);
         lldb::offset_t offset = data_byte_offset;
         switch (encoding)
         {
-        case lldb::eEncodingInvalid:
-            break;
-        case lldb::eEncodingVector:
-            break;
-        case lldb::eEncodingUint:
-            if (byte_size <= sizeof(unsigned long long))
-            {
-                uint64_t uval64 = data.GetMaxU64 (&offset, byte_size);
-                if (byte_size <= sizeof(unsigned int))
+            case lldb::eEncodingInvalid:
+                break;
+            case lldb::eEncodingVector:
+                break;
+            case lldb::eEncodingUint:
+                if (byte_size <= sizeof(unsigned long long))
                 {
-                    value = (unsigned int)uval64;
-                    return true;
-                }
-                else if (byte_size <= sizeof(unsigned long))
-                {
-                    value = (unsigned long)uval64;
-                    return true;
-                }
-                else if (byte_size <= sizeof(unsigned long long))
-                {
-                    value = (unsigned long long )uval64;
-                    return true;
-                }
-                else
-                    value.Clear();
-            }
-            break;
-
-        case lldb::eEncodingSint:
-            if (byte_size <= sizeof(long long))
-            {
-                int64_t sval64 = data.GetMaxS64 (&offset, byte_size);
-                if (byte_size <= sizeof(int))
-                {
-                    value = (int)sval64;
-                    return true;
-                }
-                else if (byte_size <= sizeof(long))
-                {
-                    value = (long)sval64;
-                    return true;
-                }
-                else if (byte_size <= sizeof(long long))
-                {
-                    value = (long long )sval64;
-                    return true;
-                }
-                else
-                    value.Clear();
-            }
-            break;
-
-        case lldb::eEncodingIEEE754:
-            if (byte_size <= sizeof(long double))
-            {
-                uint32_t u32;
-                uint64_t u64;
-                if (byte_size == sizeof(float))
-                {
-                    if (sizeof(float) == sizeof(uint32_t))
+                    uint64_t uval64 = data.GetMaxU64 (&offset, byte_size);
+                    if (byte_size <= sizeof(unsigned int))
                     {
-                        u32 = data.GetU32(&offset);
-                        value = *((float *)&u32);
+                        value = (unsigned int)uval64;
                         return true;
                     }
-                    else if (sizeof(float) == sizeof(uint64_t))
+                    else if (byte_size <= sizeof(unsigned long))
                     {
-                        u64 = data.GetU64(&offset);
-                        value = *((float *)&u64);
+                        value = (unsigned long)uval64;
                         return true;
                     }
+                    else if (byte_size <= sizeof(unsigned long long))
+                    {
+                        value = (unsigned long long )uval64;
+                        return true;
+                    }
+                    else
+                        value.Clear();
                 }
-                else
-                if (byte_size == sizeof(double))
+                break;
+                
+            case lldb::eEncodingSint:
+                if (byte_size <= sizeof(long long))
                 {
-                    if (sizeof(double) == sizeof(uint32_t))
+                    int64_t sval64 = data.GetMaxS64 (&offset, byte_size);
+                    if (byte_size <= sizeof(int))
                     {
-                        u32 = data.GetU32(&offset);
-                        value = *((double *)&u32);
+                        value = (int)sval64;
                         return true;
                     }
-                    else if (sizeof(double) == sizeof(uint64_t))
+                    else if (byte_size <= sizeof(long))
                     {
-                        u64 = data.GetU64(&offset);
-                        value = *((double *)&u64);
+                        value = (long)sval64;
                         return true;
                     }
+                    else if (byte_size <= sizeof(long long))
+                    {
+                        value = (long long )sval64;
+                        return true;
+                    }
+                    else
+                        value.Clear();
                 }
-                else
-                if (byte_size == sizeof(long double))
+                break;
+                
+            case lldb::eEncodingIEEE754:
+                if (byte_size <= sizeof(long double))
                 {
-                    if (sizeof(long double) == sizeof(uint32_t))
+                    uint32_t u32;
+                    uint64_t u64;
+                    if (byte_size == sizeof(float))
                     {
-                        u32 = data.GetU32(&offset);
-                        value = *((long double *)&u32);
-                        return true;
+                        if (sizeof(float) == sizeof(uint32_t))
+                        {
+                            u32 = data.GetU32(&offset);
+                            value = *((float *)&u32);
+                            return true;
+                        }
+                        else if (sizeof(float) == sizeof(uint64_t))
+                        {
+                            u64 = data.GetU64(&offset);
+                            value = *((float *)&u64);
+                            return true;
+                        }
                     }
-                    else if (sizeof(long double) == sizeof(uint64_t))
-                    {
-                        u64 = data.GetU64(&offset);
-                        value = *((long double *)&u64);
-                        return true;
-                    }
+                    else
+                        if (byte_size == sizeof(double))
+                        {
+                            if (sizeof(double) == sizeof(uint32_t))
+                            {
+                                u32 = data.GetU32(&offset);
+                                value = *((double *)&u32);
+                                return true;
+                            }
+                            else if (sizeof(double) == sizeof(uint64_t))
+                            {
+                                u64 = data.GetU64(&offset);
+                                value = *((double *)&u64);
+                                return true;
+                            }
+                        }
+                        else
+                            if (byte_size == sizeof(long double))
+                            {
+                                if (sizeof(long double) == sizeof(uint32_t))
+                                {
+                                    u32 = data.GetU32(&offset);
+                                    value = *((long double *)&u32);
+                                    return true;
+                                }
+                                else if (sizeof(long double) == sizeof(uint64_t))
+                                {
+                                    u64 = data.GetU64(&offset);
+                                    value = *((long double *)&u64);
+                                    return true;
+                                }
+                            }
                 }
-            }
-            break;
+                break;
         }
     }
     return false;
@@ -6845,74 +954,77 @@
 bool
 ClangASTType::SetValueFromScalar (const Scalar &value, Stream &strm)
 {
+    if (!IsValid())
+        return false;
+
     // Aggregate types don't have scalar values
     if (!IsAggregateType ())
     {
         strm.GetFlags().Set(Stream::eBinary);
         uint64_t count = 0;
         lldb::Encoding encoding = GetEncoding (count);
-
+        
         if (encoding == lldb::eEncodingInvalid || count != 1)
             return false;
-
+        
         const uint64_t bit_width = GetBitSize(nullptr);
         // This function doesn't currently handle non-byte aligned assignments
         if ((bit_width % 8) != 0)
             return false;
-
+        
         const uint64_t byte_size = (bit_width + 7 ) / 8;
         switch (encoding)
         {
-        case lldb::eEncodingInvalid:
-            break;
-        case lldb::eEncodingVector:
-            break;
-        case lldb::eEncodingUint:
-            switch (byte_size)
-            {
-            case 1: strm.PutHex8(value.UInt()); return true;
-            case 2: strm.PutHex16(value.UInt()); return true;
-            case 4: strm.PutHex32(value.UInt()); return true;
-            case 8: strm.PutHex64(value.ULongLong()); return true;
-            default:
+            case lldb::eEncodingInvalid:
                 break;
-            }
-            break;
-
-        case lldb::eEncodingSint:
-            switch (byte_size)
-            {
-            case 1: strm.PutHex8(value.SInt()); return true;
-            case 2: strm.PutHex16(value.SInt()); return true;
-            case 4: strm.PutHex32(value.SInt()); return true;
-            case 8: strm.PutHex64(value.SLongLong()); return true;
-            default:
+            case lldb::eEncodingVector:
                 break;
-            }
-            break;
-
-        case lldb::eEncodingIEEE754:
-            if (byte_size <= sizeof(long double))
+            case lldb::eEncodingUint:
+                switch (byte_size)
             {
-                if (byte_size == sizeof(float))
-                {
-                    strm.PutFloat(value.Float());
-                    return true;
-                }
-                else
-                if (byte_size == sizeof(double))
-                {
-                    strm.PutDouble(value.Double());
-                    return true;
-                }
-                else
-                if (byte_size == sizeof(long double))
-                {
-                    strm.PutDouble(value.LongDouble());
-                    return true;
-                }
+                case 1: strm.PutHex8(value.UInt()); return true;
+                case 2: strm.PutHex16(value.UInt()); return true;
+                case 4: strm.PutHex32(value.UInt()); return true;
+                case 8: strm.PutHex64(value.ULongLong()); return true;
+                default:
+                    break;
             }
-            break;
+                break;
+                
+            case lldb::eEncodingSint:
+                switch (byte_size)
+            {
+                case 1: strm.PutHex8(value.SInt()); return true;
+                case 2: strm.PutHex16(value.SInt()); return true;
+                case 4: strm.PutHex32(value.SInt()); return true;
+                case 8: strm.PutHex64(value.SLongLong()); return true;
+                default:
+                    break;
+            }
+                break;
+                
+            case lldb::eEncodingIEEE754:
+                if (byte_size <= sizeof(long double))
+                {
+                    if (byte_size == sizeof(float))
+                    {
+                        strm.PutFloat(value.Float());
+                        return true;
+                    }
+                    else
+                        if (byte_size == sizeof(double))
+                        {
+                            strm.PutDouble(value.Double());
+                            return true;
+                        }
+                        else
+                            if (byte_size == sizeof(long double))
+                            {
+                                strm.PutDouble(value.LongDouble());
+                                return true;
+                            }
+                }
+                break;
         }
     }
     return false;
@@ -6926,7 +1038,7 @@
 {
     if (!IsValid())
         return false;
-
+    
     // Can't convert a file address to anything valid without more
     // context (which Module it came from)
     if (address_type == eAddressTypeFile)
@@ -6976,17 +1088,17 @@
 {
     if (!IsValid())
         return false;
-
+    
     // 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(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
-
+    
     if (byte_size > 0)
     {
         if (address_type == eAddressTypeHost)
@@ -7010,7 +1122,6 @@
     return false;
 }
 
-
 //clang::CXXRecordDecl *
 //ClangASTType::GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type)
 //{
@@ -7022,14 +1133,14 @@
 bool
 lldb_private::operator == (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs)
 {
-    return lhs.GetASTContext() == rhs.GetASTContext() && lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
+    return lhs.GetTypeSystem() == rhs.GetTypeSystem() && lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
 }
 
 
 bool
 lldb_private::operator != (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs)
 {
-    return lhs.GetASTContext() != rhs.GetASTContext() || lhs.GetOpaqueQualType() != rhs.GetOpaqueQualType();
+    return lhs.GetTypeSystem() != rhs.GetTypeSystem() || lhs.GetOpaqueQualType() != rhs.GetOpaqueQualType();
 }
 
 
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 6e67f46..06de0bd 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -491,6 +491,7 @@
 bool
 Type::ResolveClangType (ResolveState clang_type_resolve_state)
 {
+    // TODO: This needs to consider the correct type system to use.
     Type *encoding_type = nullptr;
     if (!m_clang_type.IsValid())
     {
@@ -511,20 +512,21 @@
                 break;
 
             case eEncodingIsConstUID:
-                m_clang_type = encoding_type->GetClangForwardType().AddConstModifier();
+                m_clang_type = ClangASTContext::AddConstModifier(encoding_type->GetClangForwardType());
                 break;
 
             case eEncodingIsRestrictUID:
-                m_clang_type = encoding_type->GetClangForwardType().AddRestrictModifier();
+                m_clang_type = ClangASTContext::AddRestrictModifier(encoding_type->GetClangForwardType());
                 break;
 
             case eEncodingIsVolatileUID:
-                m_clang_type = encoding_type->GetClangForwardType().AddVolatileModifier();
+                m_clang_type = ClangASTContext::AddVolatileModifier(encoding_type->GetClangForwardType());
                 break;
 
             case eEncodingIsTypedefUID:
-                m_clang_type = encoding_type->GetClangForwardType().CreateTypedefType (GetName().AsCString(),
-                                                                                       GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID()));
+                m_clang_type = ClangASTContext::CreateTypedefType (encoding_type->GetClangForwardType(),
+                                                                   GetName().AsCString(),
+                                                                   GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID()));
                 m_name.Clear();
                 break;
 
@@ -533,11 +535,11 @@
                 break;
 
             case eEncodingIsLValueReferenceUID:
-                m_clang_type = encoding_type->GetClangForwardType().GetLValueReferenceType();
+                m_clang_type = ClangASTContext::GetLValueReferenceType(encoding_type->GetClangForwardType());
                 break;
 
             case eEncodingIsRValueReferenceUID:
-                m_clang_type = encoding_type->GetClangForwardType().GetRValueReferenceType();
+                m_clang_type = ClangASTContext::GetRValueReferenceType(encoding_type->GetClangForwardType());
                 break;
 
             default:
@@ -556,20 +558,21 @@
                 break;
 
             case eEncodingIsConstUID:
-                m_clang_type = void_clang_type.AddConstModifier ();
+                m_clang_type = ClangASTContext::AddConstModifier (void_clang_type);
                 break;
 
             case eEncodingIsRestrictUID:
-                m_clang_type = void_clang_type.AddRestrictModifier ();
+                m_clang_type = ClangASTContext::AddRestrictModifier (void_clang_type);
                 break;
 
             case eEncodingIsVolatileUID:
-                m_clang_type = void_clang_type.AddVolatileModifier ();
+                m_clang_type = ClangASTContext::AddVolatileModifier (void_clang_type);
                 break;
 
             case eEncodingIsTypedefUID:
-                m_clang_type = void_clang_type.CreateTypedefType (GetName().AsCString(),
-                                                                  GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID()));
+                m_clang_type = ClangASTContext::CreateTypedefType (void_clang_type,
+                                                                   GetName().AsCString(),
+                                                                   GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID()));
                 break;
 
             case eEncodingIsPointerUID:
@@ -577,11 +580,11 @@
                 break;
 
             case eEncodingIsLValueReferenceUID:
-                m_clang_type = void_clang_type.GetLValueReferenceType ();
+                m_clang_type = ClangASTContext::GetLValueReferenceType(void_clang_type);
                 break;
 
             case eEncodingIsRValueReferenceUID:
-                m_clang_type = void_clang_type.GetRValueReferenceType ();
+                m_clang_type = ClangASTContext::GetRValueReferenceType(void_clang_type);
                 break;
 
             default:
@@ -724,7 +727,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 (m_clang_type.IsObjCObjectOrInterfaceType() && GetByteSize() != 0)
+    if (ClangASTContext::IsObjCObjectOrInterfaceType(m_clang_type) && GetByteSize() != 0)
         return true;
     else
         return false;
@@ -1171,7 +1174,7 @@
     {
         if (m_dynamic_type.IsValid())
         {
-            return TypeImpl(m_static_type.GetReferenceType(), m_dynamic_type.GetLValueReferenceType());
+            return TypeImpl(m_static_type.GetReferenceType(), ClangASTContext::GetLValueReferenceType(m_dynamic_type));
         }
         return TypeImpl(m_static_type.GetReferenceType());
     }
@@ -1254,8 +1257,8 @@
     return ClangASTType();
 }
 
-clang::ASTContext *
-TypeImpl::GetClangASTContext (bool prefer_dynamic)
+TypeSystem *
+TypeImpl::GetTypeSystem (bool prefer_dynamic)
 {
     ModuleSP module_sp;
     if (CheckModule (module_sp))
@@ -1263,9 +1266,9 @@
         if (prefer_dynamic)
         {
             if (m_dynamic_type.IsValid())
-                return m_dynamic_type.GetASTContext();
+                return m_dynamic_type.GetTypeSystem();
         }
-        return m_static_type.GetClangASTContext();
+        return m_static_type.GetClangASTType().GetTypeSystem();
     }
     return NULL;
 }
@@ -1376,7 +1379,7 @@
     if (m_type)
         return m_type.GetFunctionReturnType();
     if (m_objc_method_decl)
-        return ClangASTType(&m_objc_method_decl->getASTContext(),m_objc_method_decl->getReturnType().getAsOpaquePtr());
+        return ClangASTType(&m_objc_method_decl->getASTContext(), m_objc_method_decl->getReturnType());
     return ClangASTType();
 }
 
@@ -1398,7 +1401,7 @@
     if (m_objc_method_decl)
     {
         if (idx < m_objc_method_decl->param_size())
-            return ClangASTType(&m_objc_method_decl->getASTContext(), m_objc_method_decl->parameters()[idx]->getOriginalType().getAsOpaquePtr());
+            return ClangASTType(&m_objc_method_decl->getASTContext(), m_objc_method_decl->parameters()[idx]->getOriginalType());
     }
     return ClangASTType();
 }
diff --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp
new file mode 100644
index 0000000..1e72c54
--- /dev/null
+++ b/lldb/source/Symbol/TypeSystem.cpp
@@ -0,0 +1,20 @@
+//
+//  TypeSystem.cpp
+//  lldb
+//
+//  Created by Ryan Brown on 3/29/15.
+//
+//
+
+#include "lldb/Symbol/TypeSystem.h"
+
+using namespace lldb_private;
+
+TypeSystem::TypeSystem()
+{
+}
+
+TypeSystem::~TypeSystem()
+{
+    
+}
diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp
index 5665e47..b6b3f5a 100644
--- a/lldb/source/Symbol/Variable.cpp
+++ b/lldb/source/Symbol/Variable.cpp
@@ -555,13 +555,13 @@
 {
 
     // We are in a type parsing child members
-    const uint32_t num_bases = clang_type.GetNumDirectBaseClasses();
+    const uint32_t num_bases = ClangASTContext::GetNumDirectBaseClasses(clang_type);
     
     if (num_bases > 0)
     {
         for (uint32_t i = 0; i < num_bases; ++i)
         {
-            ClangASTType base_class_type (clang_type.GetDirectBaseClassAtIndex (i, nullptr));
+            ClangASTType base_class_type (ClangASTContext::GetDirectBaseClassAtIndex(clang_type, i, nullptr));
             
             PrivateAutoCompleteMembers (frame,
                                         partial_member_name,
@@ -573,13 +573,13 @@
         }
     }
 
-    const uint32_t num_vbases = clang_type.GetNumVirtualBaseClasses();
+    const uint32_t num_vbases = ClangASTContext::GetNumVirtualBaseClasses(clang_type);
     
     if (num_vbases > 0)
     {
         for (uint32_t i = 0; i < num_vbases; ++i)
         {
-            ClangASTType vbase_class_type (clang_type.GetVirtualBaseClassAtIndex(i,nullptr));
+            ClangASTType vbase_class_type (ClangASTContext::GetVirtualBaseClassAtIndex(clang_type, i,nullptr));
             
             PrivateAutoCompleteMembers (frame,
                                         partial_member_name,
diff --git a/lldb/source/Target/ObjCLanguageRuntime.cpp b/lldb/source/Target/ObjCLanguageRuntime.cpp
index e54dd5b..73d7899 100644
--- a/lldb/source/Target/ObjCLanguageRuntime.cpp
+++ b/lldb/source/Target/ObjCLanguageRuntime.cpp
@@ -136,7 +136,7 @@
             {
                 TypeSP type_sp (types.GetTypeAtIndex(i));
                 
-                if (type_sp->GetClangForwardType().IsObjCObjectOrInterfaceType())
+                if (ClangASTContext::IsObjCObjectOrInterfaceType(type_sp->GetClangForwardType()))
                 {
                     if (type_sp->IsCompleteObjCClass())
                     {
@@ -648,7 +648,7 @@
 ObjCLanguageRuntime::GetTypeBitSize (const ClangASTType& clang_type,
                                      uint64_t &size)
 {
-    void *opaque_ptr = clang_type.GetQualType().getAsOpaquePtr();
+    void *opaque_ptr = clang_type.GetOpaqueQualType();
     size = m_type_size_cache.Lookup(opaque_ptr);
     // an ObjC object will at least have an ISA, so 0 is definitely not OK
     if (size > 0)
