zturner updated this revision to Diff 51476.
zturner added a comment.

This patch has gotten both bigger and smaller.  Smaller in the sense that after 
taking into consideration the most recent comments, there was really only one 
piece left of my patch.  It is the piece that abstracted out `CanComplete`, 
`CompleteType`, and `LayoutRecord` into a new class called 
`ClangTypeImportHelper` so that the same code could be re-used by 
`PDBASTParser`.

But upon closer inspection, this code ultimately just contained multiple levels 
of indirection to do what seems to be better housed inside of 
`ClangASTImporter`.  I mean, `ClangASTImporter::Import()`, makes sense right?  
Physically, there's no real different in doing it this way versus the other 
way.  In both cases the `DWARFASTParserClang` had an instance of the thing.  
Both the `ClangASTImporter` and the `ClangTypeImportHelper` with my first 
patch, and just a `ClangASTImporter` with my second patch.  But the code is 
much cleaner and more straightforward now, with fewer ping-ponging of API calls 
to get to the right place now that those 3 functions live directly isnide of 
`ClangASTImporter`.

In doing so though, I had some difficulty with the circular dependency 
relationship between `ClangASTImporter` and `ClangASTContext`.  They were each 
calling into each other in some cases, and this was leaking into header files 
causing compiler errors.  To address this I identified the code that needed to 
be shared (a couple of static methods in `ClangASTContext`) and moved them into 
a new file called `ClangUtil`.

Unfortunately this dirties up the CL and makes it look really large, even 
though a lot of the changes are just namespace fixes.

There are still many many instances of this kind of thing remaining in 
`ClangASTContext` which i did not address (because it quickly would have made 
the CL un-reviewable), but I would like to continue cleaning this up in 
subsequent patches.  `ClangASTContext.cpp` is a massive file, and anything we 
can do to split this code up will help people maintain this code (not to 
mention help new people grok it).  Plus removing circular dependencies is 
always a win.


http://reviews.llvm.org/D18381

Files:
  include/lldb/Symbol/ClangASTContext.h
  include/lldb/Symbol/ClangASTImporter.h
  include/lldb/Symbol/ClangUtil.h
  include/lldb/Symbol/TypeSystem.h
  source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
  source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
  source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
  source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
  
source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Symbol/CMakeLists.txt
  source/Symbol/ClangASTContext.cpp
  source/Symbol/ClangASTImporter.cpp
  source/Symbol/ClangUtil.cpp

Index: source/Symbol/ClangUtil.cpp
===================================================================
--- /dev/null
+++ source/Symbol/ClangUtil.cpp
@@ -0,0 +1,58 @@
+//===-- ClangUtil.cpp -------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+// A collection of helper methods and data structures for manipulating clang
+// types and decls.
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/ClangUtil.h"
+#include "lldb/Symbol/ClangASTContext.h"
+
+using namespace clang;
+using namespace lldb_private;
+
+bool
+ClangUtil::IsClangType(const CompilerType &ct)
+{
+    if (llvm::dyn_cast_or_null<ClangASTContext>(ct.GetTypeSystem()) == nullptr)
+        return false;
+
+    if (!ct.GetOpaqueQualType())
+        return false;
+
+    return true;
+}
+
+QualType
+ClangUtil::GetQualType(const CompilerType &ct)
+{
+    // Make sure we have a clang type before making a clang::QualType
+    if (!IsClangType(ct))
+        return QualType();
+
+    return QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
+}
+
+QualType
+ClangUtil::GetCanonicalQualType(const CompilerType &ct)
+{
+    if (!IsClangType(ct))
+        return QualType();
+
+    return GetQualType(ct).getCanonicalType();
+}
+
+CompilerType
+ClangUtil::RemoveFastQualifiers(const CompilerType &ct)
+{
+    if (!IsClangType(ct))
+        return ct;
+
+    QualType qual_type(GetQualType(ct));
+    qual_type.getQualifiers().removeFastQualifiers();
+    return CompilerType(ct.GetTypeSystem(), qual_type.getAsOpaquePtr());
+}
Index: source/Symbol/ClangASTImporter.cpp
===================================================================
--- source/Symbol/ClangASTImporter.cpp
+++ source/Symbol/ClangASTImporter.cpp
@@ -7,16 +7,17 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "llvm/Support/raw_ostream.h"
+#include "lldb/Symbol/ClangASTImporter.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
 #include "lldb/Utility/LLDBAssert.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "llvm/Support/raw_ostream.h"
 
 using namespace lldb_private;
 using namespace clang;
@@ -347,6 +348,211 @@
     return result;
 }
 
+bool
+ClangASTImporter::CanImport(const CompilerType &type)
+{
+    if (!ClangUtil::IsClangType(type))
+        return false;
+
+    // TODO: remove external completion BOOL
+    // CompleteAndFetchChildren should get the Decl out and check for the
+
+    clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+        {
+            const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+            if (cxx_record_decl)
+            {
+                if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL))
+                    return true;
+            }
+        }
+        break;
+
+        case clang::Type::Enum:
+        {
+            clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
+            if (enum_decl)
+            {
+                if (ResolveDeclOrigin(enum_decl, NULL, NULL))
+                    return true;
+            }
+        }
+        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 (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
+                        return true;
+                }
+            }
+        }
+        break;
+
+        case clang::Type::Typedef:
+            return CanImport(CompilerType(
+                type.GetTypeSystem(),
+                llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
+
+        case clang::Type::Auto:
+            return CanImport(CompilerType(type.GetTypeSystem(),
+                                          llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()));
+
+        case clang::Type::Elaborated:
+            return CanImport(CompilerType(
+                type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
+
+        case clang::Type::Paren:
+            return CanImport(CompilerType(type.GetTypeSystem(),
+                                          llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+        default:
+            break;
+    }
+
+    return false;
+}
+
+bool
+ClangASTImporter::Import(const CompilerType &type)
+{
+    if (!ClangUtil::IsClangType(type))
+        return false;
+    // TODO: remove external completion BOOL
+    // CompleteAndFetchChildren should get the Decl out and check for the
+
+    clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+        {
+            const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+            if (cxx_record_decl)
+            {
+                if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL))
+                    return CompleteAndFetchChildren(qual_type);
+            }
+        }
+        break;
+
+        case clang::Type::Enum:
+        {
+            clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
+            if (enum_decl)
+            {
+                if (ResolveDeclOrigin(enum_decl, NULL, NULL))
+                    return CompleteAndFetchChildren(qual_type);
+            }
+        }
+        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 (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
+                        return CompleteAndFetchChildren(qual_type);
+                }
+            }
+        }
+        break;
+
+        case clang::Type::Typedef:
+            return Import(CompilerType(
+                type.GetTypeSystem(),
+                llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
+
+        case clang::Type::Auto:
+            return Import(CompilerType(type.GetTypeSystem(),
+                                       llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()));
+
+        case clang::Type::Elaborated:
+            return Import(CompilerType(type.GetTypeSystem(),
+                                       llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
+
+        case clang::Type::Paren:
+            return Import(CompilerType(type.GetTypeSystem(),
+                                       llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+        default:
+            break;
+    }
+    return false;
+}
+
+bool
+ClangASTImporter::CompleteType(const CompilerType &compiler_type)
+{
+    if (!CanImport(compiler_type))
+        return false;
+
+    if (Import(compiler_type))
+    {
+        ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
+        return true;
+    }
+
+    ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), false);
+    return false;
+}
+
+bool
+ClangASTImporter::LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment,
+                                   llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
+                                   llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
+                                   llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
+{
+    RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find(record_decl);
+    bool success = false;
+    base_offsets.clear();
+    vbase_offsets.clear();
+    if (pos != m_record_decl_to_layout_map.end())
+    {
+        bit_size = pos->second.bit_size;
+        alignment = pos->second.alignment;
+        field_offsets.swap(pos->second.field_offsets);
+        base_offsets.swap(pos->second.base_offsets);
+        vbase_offsets.swap(pos->second.vbase_offsets);
+        m_record_decl_to_layout_map.erase(pos);
+        success = true;
+    }
+    else
+    {
+        bit_size = 0;
+        alignment = 0;
+        field_offsets.clear();
+    }
+    return success;
+}
+
+void
+ClangASTImporter::InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout)
+{
+    m_record_decl_to_layout_map.insert(std::make_pair(decl, layout));
+}
+
 void
 ClangASTImporter::CompleteDecl (clang::Decl *decl)
 {
Index: source/Symbol/ClangASTContext.cpp
===================================================================
--- source/Symbol/ClangASTContext.cpp
+++ source/Symbol/ClangASTContext.cpp
@@ -63,6 +63,9 @@
 
 #include "llvm/Support/Signals.h"
 
+#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
+#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/Flags.h"
 #include "lldb/Core/Log.h"
@@ -72,12 +75,11 @@
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/ThreadSafeDenseMap.h"
 #include "lldb/Core/UniqueCStringMap.h"
-#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
-#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
-#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
 #include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangASTImporter.h"
 #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/VerifyDecl.h"
@@ -1057,7 +1059,7 @@
                     if (::strstr(type_name, "complex"))
                     {
                         CompilerType complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
-                        return CompilerType (ast, ast->getComplexType (GetQualType(complex_int_clang_type)));
+                        return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(complex_int_clang_type)));
                     }
                 }
                 break;
@@ -1072,7 +1074,7 @@
                 else 
                 {
                     CompilerType complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
-                    return CompilerType (ast, ast->getComplexType (GetQualType(complex_float_clang_type)));
+                    return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(complex_float_clang_type)));
                 }
                 break;
                 
@@ -1302,9 +1304,9 @@
     if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
         return true;
 
-    QualType type1_qual = GetQualType(type1);
-    QualType type2_qual = GetQualType(type2);
-    
+    QualType type1_qual = ClangUtil::GetQualType(type1);
+    QualType type2_qual = ClangUtil::GetQualType(type2);
+
     if (ignore_qualifiers)
     {
         type1_qual = type1_qual.getUnqualifiedType();
@@ -2016,31 +2018,17 @@
 
     if (name && name[0])
     {
-        func_decl = FunctionDecl::Create (*ast,
-                                          decl_ctx,
-                                          SourceLocation(),
-                                          SourceLocation(),
-                                          DeclarationName (&ast->Idents.get(name)),
-                                          GetQualType(function_clang_type),
-                                          nullptr,
-                                          (clang::StorageClass)storage,
-                                          is_inline,
-                                          hasWrittenPrototype,
-                                          isConstexprSpecified);
+        func_decl = FunctionDecl::Create(
+            *ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(&ast->Idents.get(name)),
+            ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, is_inline,
+            hasWrittenPrototype, isConstexprSpecified);
     }
     else
     {
-        func_decl = FunctionDecl::Create (*ast,
-                                          decl_ctx,
-                                          SourceLocation(),
-                                          SourceLocation(),
-                                          DeclarationName (),
-                                          GetQualType(function_clang_type),
-                                          nullptr,
-                                          (clang::StorageClass)storage,
-                                          is_inline,
-                                          hasWrittenPrototype,
-                                          isConstexprSpecified);
+        func_decl =
+            FunctionDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(),
+                                 ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage,
+                                 is_inline, hasWrittenPrototype, isConstexprSpecified);
     }
     if (func_decl)
         decl_ctx->addDecl (func_decl);
@@ -2063,7 +2051,7 @@
     assert (ast != nullptr);
     std::vector<QualType> qual_type_args;
     for (unsigned i=0; i<num_args; ++i)
-        qual_type_args.push_back (GetQualType(args[i]));
+        qual_type_args.push_back(ClangUtil::GetQualType(args[i]));
 
     // TODO: Detect calling convention in DWARF?
     FunctionProtoType::ExtProtoInfo proto_info;
@@ -2072,9 +2060,7 @@
     proto_info.TypeQuals = type_quals;
     proto_info.RefQualifier = RQ_None;
 
-    return CompilerType (ast, ast->getFunctionType (GetQualType(result_type),
-                                                    qual_type_args,
-                                                    proto_info));
+    return CompilerType(ast, ast->getFunctionType(ClangUtil::GetQualType(result_type), qual_type_args, proto_info));
 }
 
 ParmVarDecl *
@@ -2082,15 +2068,9 @@
 {
     ASTContext *ast = getASTContext();
     assert (ast != nullptr);
-    return ParmVarDecl::Create(*ast,
-                                ast->getTranslationUnitDecl(),
-                                SourceLocation(),
-                                SourceLocation(),
-                                name && name[0] ? &ast->Idents.get(name) : nullptr,
-                                GetQualType(param_type),
-                                nullptr,
-                                (clang::StorageClass)storage,
-                                nullptr);
+    return ParmVarDecl::Create(*ast, ast->getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
+                               name && name[0] ? &ast->Idents.get(name) : nullptr, ClangUtil::GetQualType(param_type),
+                               nullptr, (clang::StorageClass)storage, nullptr);
 }
 
 void
@@ -2115,7 +2095,7 @@
 
         if (is_vector)
         {
-            return CompilerType (ast, ast->getExtVectorType(GetQualType(element_type), element_count));
+            return CompilerType(ast, ast->getExtVectorType(ClangUtil::GetQualType(element_type), element_count));
         }
         else
         {
@@ -2123,16 +2103,13 @@
             llvm::APInt ap_element_count (64, element_count);
             if (element_count == 0)
             {
-                return CompilerType (ast, ast->getIncompleteArrayType (GetQualType(element_type),
-                                                                       clang::ArrayType::Normal,
-                                                                       0));
+                return CompilerType(ast, ast->getIncompleteArrayType(ClangUtil::GetQualType(element_type),
+                                                                     clang::ArrayType::Normal, 0));
             }
             else
             {
-                return CompilerType (ast, ast->getConstantArrayType (GetQualType(element_type),
-                                                                     ap_element_count,
-                                                                     clang::ArrayType::Normal,
-                                                                     0));
+                return CompilerType(ast, ast->getConstantArrayType(ClangUtil::GetQualType(element_type),
+                                                                   ap_element_count, clang::ArrayType::Normal, 0));
             }
         }
     }
@@ -2190,8 +2167,8 @@
     if (enum_decl)
     {
         // TODO: check if we should be setting the promotion type too?
-        enum_decl->setIntegerType(GetQualType(integer_clang_type));
-        
+        enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));
+
         enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
         
         return CompilerType (ast, ast->getTagDeclType(enum_decl));
@@ -2584,7 +2561,7 @@
 clang::DeclContext *
 ClangASTContext::GetDeclContextForType (const CompilerType& type)
 {
-    return GetDeclContextForType(GetQualType(type));
+    return GetDeclContextForType(ClangUtil::GetQualType(type));
 }
 
 clang::DeclContext *
@@ -3486,8 +3463,8 @@
 {
     if (type)
     {
-        clang::QualType qual_type (GetCanonicalQualType(type));
-        
+        clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+
         const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
         
         if (obj_pointer_type)
@@ -3499,8 +3476,8 @@
 bool
 ClangASTContext::IsObjCObjectOrInterfaceType (const CompilerType& type)
 {
-    if (IsClangType(type))
-        return GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
+    if (ClangUtil::IsClangType(type))
+        return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
     return false;
 }
 
@@ -3716,7 +3693,7 @@
 {
     if (type)
     {
-        clang::QualType qual_type (GetCanonicalQualType(type));
+        clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
         if (!qual_type.isNull())
         {
             clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
@@ -3737,8 +3714,8 @@
 {
     if (!type)
         return false;
-    
-    clang::QualType qual_type (GetCanonicalQualType(type));
+
+    clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
     if (!qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr)
         return true;
     return false;
@@ -3762,7 +3739,7 @@
     if (!type)
         return false;
 
-    clang::QualType qual_type (GetCanonicalQualType(type));
+    clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
 
     if (!qual_type.isNull() && qual_type->isObjCObjectPointerType())
     {
@@ -3790,9 +3767,9 @@
 {
     if (!type)
         return false;
-    
-    clang::QualType qual_type (GetCanonicalQualType(type));
-    
+
+    clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+
     const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
     if (object_type)
     {
@@ -4511,7 +4488,7 @@
         if (!ast)
             return CompilerType();
         clang::ASTContext* clang_ast = ast->getASTContext();
-        clang::QualType qual_type (GetQualType(type));
+        clang::QualType qual_type(ClangUtil::GetQualType(type));
 
         clang::DeclContext *decl_ctx = ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
         if (decl_ctx == nullptr)
@@ -4677,18 +4654,6 @@
     return CompilerType();
 }
 
-CompilerType
-ClangASTContext::RemoveFastQualifiers (const CompilerType& type)
-{
-    if (IsClangType(type))
-    {
-        clang::QualType qual_type(GetQualType(type));
-        qual_type.getQualifiers().removeFastQualifiers();
-        return CompilerType (type.GetTypeSystem(), qual_type.getAsOpaquePtr());
-    }
-    return type;
-}
-
 
 //----------------------------------------------------------------------
 // Create related types using the current type's AST
@@ -7250,7 +7215,7 @@
 ClangASTContext::GetTypeForFormatters (void* type)
 {
     if (type)
-        return RemoveFastQualifiers(CompilerType(this, type));
+        return ClangUtil::RemoveFastQualifiers(CompilerType(this, type));
     return CompilerType();
 }
 
@@ -7473,7 +7438,7 @@
 clang::EnumDecl *
 ClangASTContext::GetAsEnumDecl (const CompilerType& type)
 {
-    const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type));
+    const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type));
     if (enutype)
         return enutype->getDecl();
     return NULL;
@@ -7482,7 +7447,7 @@
 clang::RecordDecl *
 ClangASTContext::GetAsRecordDecl (const CompilerType& type)
 {
-    const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(GetCanonicalQualType(type));
+    const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(ClangUtil::GetCanonicalQualType(type));
     if (record_type)
         return record_type->getDecl();
     return nullptr;
@@ -7491,7 +7456,7 @@
 clang::TagDecl *
 ClangASTContext::GetAsTagDecl (const CompilerType& type)
 {
-    clang::QualType qual_type = GetCanonicalQualType(type);
+    clang::QualType qual_type = ClangUtil::GetCanonicalQualType(type);
     if (qual_type.isNull())
         return nullptr;
     else
@@ -7507,7 +7472,8 @@
 clang::ObjCInterfaceDecl *
 ClangASTContext::GetAsObjCInterfaceDecl (const CompilerType& type)
 {
-    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(GetCanonicalQualType(type));
+    const clang::ObjCObjectType *objc_class_type =
+        llvm::dyn_cast<clang::ObjCObjectType>(ClangUtil::GetCanonicalQualType(type));
     if (objc_class_type)
         return objc_class_type->getInterface();
     return nullptr;
@@ -7538,17 +7504,14 @@
     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
-        
+        field = clang::FieldDecl::Create(*clang_ast, record_decl, clang::SourceLocation(), clang::SourceLocation(),
+                                         name ? &clang_ast->Idents.get(name) : nullptr, // Identifier
+                                         ClangUtil::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
@@ -7583,18 +7546,14 @@
             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);
-            
+
+            field = clang::ObjCIvarDecl::Create(
+                *clang_ast, class_interface_decl, clang::SourceLocation(), clang::SourceLocation(),
+                name ? &clang_ast->Idents.get(name) : nullptr, // Identifier
+                ClangUtil::GetQualType(field_clang_type),      // Field type
+                nullptr,                                       // TypeSourceInfo *
+                ConvertAccessTypeToObjCIvarAccessControl(access), bit_width, is_synthesized);
+
             if (field)
             {
                 class_interface_decl->addDecl(field);
@@ -7754,14 +7713,15 @@
     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
+        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 *
+                                   ClangUtil::GetQualType(var_type),                         // Variable clang::QualType
+                                   nullptr,                                                  // TypeSourceInfo *
+                                   clang::SC_Static);                                        // StorageClass
         if (var_decl)
         {
             var_decl->setAccess(ClangASTContext::ConvertAccessTypeToAccessSpecifier (access));
@@ -7796,9 +7756,9 @@
     
     if (cxx_record_decl == nullptr)
         return nullptr;
-    
-    clang::QualType method_qual_type (GetQualType(method_clang_type));
-    
+
+    clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
+
     clang::CXXMethodDecl *cxx_method_decl = nullptr;
     
     clang::DeclarationName decl_name (&getASTContext()->Idents.get(name));
@@ -8082,17 +8042,16 @@
             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 (
-                                                                                      ivar_decl ? ivar_decl->getType() : ClangASTContext::GetQualType(property_clang_type),
-                                                                                      prop_type_source);
-            
+                prop_type_source = clang_ast->getTrivialTypeSourceInfo(ClangUtil::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 (
+                ivar_decl ? ivar_decl->getType() : ClangUtil::GetQualType(property_clang_type), prop_type_source);
+
             if (property_decl)
             {
                 if (metadata)
@@ -8157,22 +8116,13 @@
                     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);
-                    
+
+                    clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create(
+                        *clang_ast, clang::SourceLocation(), clang::SourceLocation(), getter_sel,
+                        ClangUtil::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);
                     
@@ -8215,17 +8165,12 @@
                         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));
-                    
+
+                    params.push_back(clang::ParmVarDecl::Create(
+                        *clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(),
+                        nullptr, // anonymous
+                        ClangUtil::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>());
@@ -8301,9 +8246,9 @@
     
     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));
-    
+
+    clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
+
     // Populate the method decl with parameter decls
     const clang::Type *method_type(method_qual_type.getTypePtr());
     
@@ -8325,23 +8270,18 @@
     
     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*/);
-    
-    
+
+    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(ClangUtil::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;
     
@@ -8377,10 +8317,10 @@
 bool
 ClangASTContext::GetHasExternalStorage (const CompilerType &type)
 {
-    if (IsClangType(type))
+    if (ClangUtil::IsClangType(type))
         return false;
 
-    clang::QualType qual_type (GetCanonicalQualType(type));
+    clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
 
     const clang::Type::TypeClass type_class = qual_type->getTypeClass();
     switch (type_class)
@@ -8508,158 +8448,12 @@
 }
 
 
-bool
-ClangASTContext::CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer)
-{
-    if (IsClangType(type))
-    {
-        // TODO: remove external completion BOOL
-        // CompleteAndFetchChildren should get the Decl out and check for the
-
-        clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type)));
-
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-            case clang::Type::Record:
-            {
-                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                if (cxx_record_decl)
-                {
-                    if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL))
-                        return true;
-                }
-            }
-                break;
-
-            case clang::Type::Enum:
-            {
-                clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
-                if (enum_decl)
-                {
-                    if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL))
-                        return true;
-                }
-            }
-                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 (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL))
-                            return true;
-                    }
-                }
-            }
-                break;
-
-
-            case clang::Type::Typedef:
-                return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer);
-
-            case clang::Type::Auto:
-                return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()), importer);
-                
-            case clang::Type::Elaborated:
-                return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer);
-
-            case clang::Type::Paren:
-                return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer);
-
-            default:
-                break;
-        }
-    }
-    return false;
-}
-bool
-ClangASTContext::Import (const CompilerType &type, lldb_private::ClangASTImporter &importer)
-{
-    if (IsClangType(type))
-    {
-        // TODO: remove external completion BOOL
-        // CompleteAndFetchChildren should get the Decl out and check for the
-
-        clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type)));
-
-        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-        switch (type_class)
-        {
-            case clang::Type::Record:
-            {
-                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-                if (cxx_record_decl)
-                {
-                    if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL))
-                        return importer.CompleteAndFetchChildren(qual_type);
-                }
-            }
-                break;
-
-            case clang::Type::Enum:
-            {
-                clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
-                if (enum_decl)
-                {
-                    if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL))
-                        return importer.CompleteAndFetchChildren(qual_type);
-                }
-            }
-                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 (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL))
-                            return importer.CompleteAndFetchChildren(qual_type);
-                    }
-                }
-            }
-                break;
-
-
-            case clang::Type::Typedef:
-                return Import (CompilerType(type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer);
-
-            case clang::Type::Auto:
-                return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()), importer);
-                
-            case clang::Type::Elaborated:
-                return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer);
-
-            case clang::Type::Paren:
-                return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer);
-                
-            default:
-                break;
-        }
-    }
-    return false;
-}
-
-
 #pragma mark TagDecl
 
 bool
 ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type)
 {
-    clang::QualType qual_type (ClangASTContext::GetQualType(type));
+    clang::QualType qual_type(ClangUtil::GetQualType(type));
     if (!qual_type.isNull())
     {
         const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
@@ -8690,7 +8484,7 @@
 bool
 ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type)
 {
-    clang::QualType qual_type (ClangASTContext::GetQualType(type));
+    clang::QualType qual_type(ClangUtil::GetQualType(type));
     if (!qual_type.isNull())
     {
         clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
@@ -8770,15 +8564,11 @@
             {
                 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);
-                
+                clang::EnumConstantDecl *enumerator_decl = clang::EnumConstantDecl::Create(
+                    *getASTContext(), enutype->getDecl(), clang::SourceLocation(),
+                    name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier
+                    ClangUtil::GetQualType(enumerator_clang_type), nullptr, enum_llvm_apsint);
+
                 if (enumerator_decl)
                 {
                     enutype->getDecl()->addDecl(enumerator_decl);
@@ -8821,9 +8611,9 @@
         ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
         if (!ast)
             return CompilerType();
-        return CompilerType (ast->getASTContext(),
-                             ast->getASTContext()->getMemberPointerType (GetQualType(pointee_type),
-                                                                         GetQualType(type).getTypePtr()));
+        return CompilerType(ast->getASTContext(),
+                            ast->getASTContext()->getMemberPointerType(ClangUtil::GetQualType(pointee_type),
+                                                                       ClangUtil::GetQualType(type).getTypePtr()));
     }
     return CompilerType();
 }
@@ -9554,9 +9344,9 @@
 void
 ClangASTContext::DumpTypeName (const CompilerType &type)
 {
-    if (IsClangType(type))
+    if (ClangUtil::IsClangType(type))
     {
-        clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type)));
+        clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
 
         const clang::Type::TypeClass type_class = qual_type->getTypeClass();
         switch (type_class)
@@ -9668,9 +9458,8 @@
     }
 }
 
-
 DWARFASTParser *
-ClangASTContext::GetDWARFParser ()
+ClangASTContext::GetDWARFParser()
 {
     if (!m_dwarf_ast_parser_ap)
         m_dwarf_ast_parser_ap.reset(new DWARFASTParserClang(*this));
@@ -9689,7 +9478,8 @@
 {
     ClangASTContext *ast = (ClangASTContext *)baton;
     DWARFASTParserClang *dwarf_ast_parser = (DWARFASTParserClang *)ast->GetDWARFParser();
-    return dwarf_ast_parser->LayoutRecordType(record_decl, bit_size, alignment, field_offsets, base_offsets, vbase_offsets);
+    return dwarf_ast_parser->GetClangASTImporter().LayoutRecordType(record_decl, bit_size, alignment, field_offsets,
+                                                                    base_offsets, vbase_offsets);
 }
 
 //----------------------------------------------------------------------
Index: source/Symbol/CMakeLists.txt
===================================================================
--- source/Symbol/CMakeLists.txt
+++ source/Symbol/CMakeLists.txt
@@ -5,6 +5,7 @@
   ClangASTImporter.cpp
   ClangExternalASTSourceCallbacks.cpp
   ClangExternalASTSourceCommon.cpp
+  ClangUtil.cpp
   CompilerDecl.cpp
   CompilerDeclContext.cpp
   CompilerType.cpp
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -35,16 +35,17 @@
 
 #include "lldb/Symbol/Block.h"
 #include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
+#include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/CompilerDecl.h"
 #include "lldb/Symbol/CompilerDeclContext.h"
-#include "lldb/Symbol/CompileUnit.h"
-#include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/DebugMacros.h"
+#include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/TypeMap.h"
 #include "lldb/Symbol/TypeSystem.h"
 #include "lldb/Symbol/VariableList.h"
-#include "lldb/Symbol/TypeMap.h"
 
 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
 #include "Plugins/Language/ObjC/ObjCLanguage.h"
@@ -54,7 +55,9 @@
 #include "lldb/Utility/TaskPool.h"
 
 #include "DWARFASTParser.h"
+#include "DWARFASTParserClang.h"
 #include "DWARFCompileUnit.h"
+#include "DWARFDIECollection.h"
 #include "DWARFDebugAbbrev.h"
 #include "DWARFDebugAranges.h"
 #include "DWARFDebugInfo.h"
@@ -63,11 +66,10 @@
 #include "DWARFDebugPubnames.h"
 #include "DWARFDebugRanges.h"
 #include "DWARFDeclContext.h"
-#include "DWARFDIECollection.h"
 #include "DWARFFormValue.h"
 #include "LogChannelDWARF.h"
-#include "SymbolFileDWARFDwo.h"
 #include "SymbolFileDWARFDebugMap.h"
+#include "SymbolFileDWARFDwo.h"
 
 #include <map>
 
@@ -1603,19 +1605,21 @@
 bool
 SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type)
 {
-    CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
+    CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type);
     if (GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType()))
     {
         return true;
     }
     TypeSystem *type_system = compiler_type.GetTypeSystem();
-    if (type_system)
-    {
-        DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
-        if (dwarf_ast)
-            return dwarf_ast->CanCompleteType(compiler_type);
-    }
-    return false;
+    ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+    if (!clang_type_system)
+        return false;
+
+    DWARFASTParser *ast_parser = clang_type_system->GetDWARFParser();
+    if (!ast_parser)
+        return false;
+
+    return ast_parser->CanCompleteType(compiler_type);
 }
 
 
@@ -1633,7 +1637,7 @@
     }
 
     // We have a struct/union/class/enum that needs to be fully resolved.
-    CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
+    CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type);
     auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType());
     if (die_it == GetForwardDeclClangTypeToDie().end())
     {
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -19,11 +19,12 @@
 #include "clang/AST/CharUnits.h"
 
 // Project includes
+#include "DWARFASTParser.h"
+#include "DWARFDefines.h"
 #include "lldb/Core/ClangForward.h"
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/Symbol/ClangASTContext.h"
-#include "DWARFDefines.h"
-#include "DWARFASTParser.h"
+#include "lldb/Symbol/ClangASTImporter.h"
 
 class DWARFDebugInfoEntry;
 class DWARFDIECollection;
@@ -35,6 +36,7 @@
 
     ~DWARFASTParserClang() override;
 
+    // DWARFASTParser interface.
     lldb::TypeSP
     ParseTypeFromDWARF (const lldb_private::SymbolContext& sc,
                         const DWARFDIE &die,
@@ -47,12 +49,6 @@
                             const DWARFDIE &die) override;
 
     bool
-    CanCompleteType (const lldb_private::CompilerType &compiler_type) override;
-
-    bool
-    CompleteType (const lldb_private::CompilerType &compiler_type) override;
-
-    bool
     CompleteTypeFromDWARF (const DWARFDIE &die,
                            lldb_private::Type *type,
                            lldb_private::CompilerType &compiler_type) override;
@@ -69,43 +65,19 @@
     lldb_private::CompilerDeclContext
     GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) override;
 
-    bool
-    LayoutRecordType(const clang::RecordDecl *record_decl,
-                     uint64_t &bit_size,
-                     uint64_t &alignment,
-                     llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
-                     llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
-                     llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets);
+    lldb_private::ClangASTImporter &
+    GetClangASTImporter();
 
 protected:
     class DelayedAddObjCClassProperty;
     typedef std::vector <DelayedAddObjCClassProperty> DelayedPropertyList;
 
-    struct LayoutInfo
-    {
-        LayoutInfo () :
-        bit_size(0),
-        alignment(0),
-        field_offsets(),
-        base_offsets(),
-        vbase_offsets()
-        {
-        }
-        uint64_t bit_size;
-        uint64_t alignment;
-        llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets;
-        llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
-        llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets;
-    };
-
     clang::BlockDecl *
     ResolveBlockDIE (const DWARFDIE &die);
 
     clang::NamespaceDecl *
     ResolveNamespaceDIE (const DWARFDIE &die);
 
-    typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo> RecordDeclToLayoutMap;
-
     bool
     ParseTemplateDIE (const DWARFDIE &die,
                       lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
@@ -114,17 +86,12 @@
                                  lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
 
     bool
-    ParseChildMembers (const lldb_private::SymbolContext& sc,
-                       const DWARFDIE &die,
-                       lldb_private::CompilerType &class_compiler_type,
-                       const lldb::LanguageType class_language,
-                       std::vector<clang::CXXBaseSpecifier *>& base_classes,
-                       std::vector<int>& member_accessibilities,
-                       DWARFDIECollection& member_function_dies,
-                       DelayedPropertyList& delayed_properties,
-                       lldb::AccessType &default_accessibility,
-                       bool &is_a_class,
-                       LayoutInfo &layout_info);
+    ParseChildMembers(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+                      lldb_private::CompilerType &class_compiler_type, const lldb::LanguageType class_language,
+                      std::vector<clang::CXXBaseSpecifier *> &base_classes, std::vector<int> &member_accessibilities,
+                      DWARFDIECollection &member_function_dies, DelayedPropertyList &delayed_properties,
+                      lldb::AccessType &default_accessibility, bool &is_a_class,
+                      lldb_private::ClangASTImporter::LayoutInfo &layout_info);
 
     size_t
     ParseChildParameters (const lldb_private::SymbolContext& sc,
@@ -182,9 +149,6 @@
     void
     LinkDeclToDIE (clang::Decl *decl, const DWARFDIE &die);
 
-    lldb_private::ClangASTImporter &
-    GetClangASTImporter();
-
     lldb::TypeSP
     ParseTypeFromDWO (const DWARFDIE &die, lldb_private::Log *log);
 
@@ -207,7 +171,6 @@
     DeclToDIEMap m_decl_to_die;
     DIEToDeclContextMap m_die_to_decl_ctx;
     DeclContextToDIEMap m_decl_ctx_to_die;
-    RecordDeclToLayoutMap m_record_decl_to_layout_map;
     std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap;
 };
 
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -18,14 +18,16 @@
 #include "SymbolFileDWARFDebugMap.h"
 #include "UniqueDWARFASTType.h"
 
-#include "lldb/Interpreter/Args.h"
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Value.h"
 #include "lldb/Host/Host.h"
+#include "lldb/Interpreter/Args.h"
 #include "lldb/Symbol/ClangASTImporter.h"
 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -34,7 +36,6 @@
 #include "lldb/Symbol/TypeMap.h"
 #include "lldb/Target/Language.h"
 #include "lldb/Utility/LLDBAssert.h"
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
 
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
@@ -865,7 +866,9 @@
                                 clang::RecordDecl *record_decl = ClangASTContext::GetAsRecordDecl(clang_type);
 
                                 if (record_decl)
-                                    m_record_decl_to_layout_map.insert(std::make_pair(record_decl, LayoutInfo()));
+                                {
+                                    GetClangASTImporter().InsertRecordDecl(record_decl, ClangASTImporter::LayoutInfo());
+                                }
                             }
                         }
                         else if (clang_type_was_created)
@@ -887,14 +890,16 @@
                             // will automatically call the SymbolFile virtual function
                             // "SymbolFileDWARF::CompleteType(Type *)"
                             // When the definition needs to be defined.
-                            assert(!dwarf->GetForwardDeclClangTypeToDie().count(ClangASTContext::RemoveFastQualifiers(clang_type).GetOpaqueQualType()) &&
+                            assert(!dwarf->GetForwardDeclClangTypeToDie().count(
+                                       ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()) &&
                                    "Type already in the forward declaration map!");
                             // Can't assume m_ast.GetSymbolFile() is actually a SymbolFileDWARF, it can be a
                             // SymbolFileDWARFDebugMap for Apple binaries.
                             //assert(((SymbolFileDWARF*)m_ast.GetSymbolFile())->UserIDMatches(die.GetDIERef().GetUID()) &&
                             //       "Adding incorrect type to forward declaration map");
                             dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = clang_type.GetOpaqueQualType();
-                            dwarf->GetForwardDeclClangTypeToDie()[ClangASTContext::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] = die.GetDIERef();
+                            dwarf->GetForwardDeclClangTypeToDie()[ClangUtil::RemoveFastQualifiers(clang_type)
+                                                                      .GetOpaqueQualType()] = die.GetDIERef();
                             m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), true);
                         }
                     }
@@ -1412,7 +1417,8 @@
                                                                 clang::CXXMethodDecl *method_decl = *method_iter;
                                                                 if (method_decl->getNameInfo().getAsString() == std::string(type_name_cstr))
                                                                 {
-                                                                    if (method_decl->getType() == ClangASTContext::GetQualType(clang_type))
+                                                                    if (method_decl->getType() ==
+                                                                        ClangUtil::GetQualType(clang_type))
                                                                     {
                                                                         add_method = false;
                                                                         LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(method_decl), die);
@@ -1932,13 +1938,13 @@
                         uval64_valid)
                     {
                         llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
-                        template_param_infos.args.push_back (clang::TemplateArgument (*ast,
-                                                                                      llvm::APSInt(apint),
-                                                                                      ClangASTContext::GetQualType(clang_type)));
+                        template_param_infos.args.push_back(
+                            clang::TemplateArgument(*ast, llvm::APSInt(apint), ClangUtil::GetQualType(clang_type)));
                     }
                     else
                     {
-                        template_param_infos.args.push_back (clang::TemplateArgument (ClangASTContext::GetQualType(clang_type)));
+                        template_param_infos.args.push_back(
+                            clang::TemplateArgument(ClangUtil::GetQualType(clang_type)));
                     }
                 }
                 else
@@ -1988,36 +1994,7 @@
 }
 
 bool
-DWARFASTParserClang::CanCompleteType (const lldb_private::CompilerType &compiler_type)
-{
-    if (m_clang_ast_importer_ap)
-        return ClangASTContext::CanImport(compiler_type, GetClangASTImporter());
-    else
-        return false;
-}
-
-bool
-DWARFASTParserClang::CompleteType (const lldb_private::CompilerType &compiler_type)
-{
-    if (CanCompleteType(compiler_type))
-    {
-        if (ClangASTContext::Import(compiler_type, GetClangASTImporter()))
-        {
-            ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
-            return true;
-        }
-        else
-        {
-            ClangASTContext::SetHasExternalStorage (compiler_type.GetOpaqueQualType(), false);
-        }
-    }
-    return false;
-}
-
-bool
-DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
-                                            lldb_private::Type *type,
-                                            CompilerType &clang_type)
+DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type)
 {
     SymbolFileDWARF *dwarf = die.GetDWARF();
 
@@ -2047,7 +2024,7 @@
         case DW_TAG_union_type:
         case DW_TAG_class_type:
         {
-            LayoutInfo layout_info;
+            ClangASTImporter::LayoutInfo layout_info;
 
             {
                 if (die.HasChildren())
@@ -2144,7 +2121,7 @@
                     if (class_language != eLanguageTypeObjC)
                     {
                         if (is_a_class && tag_decl_kind != clang::TTK_Class)
-                            m_ast.SetTagTypeKind (ClangASTContext::GetQualType(clang_type), clang::TTK_Class);
+                            m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type), clang::TTK_Class);
                     }
 
                     // Since DW_TAG_structure_type gets used for both classes
@@ -2283,7 +2260,7 @@
 
                         }
                     }
-                    m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
+                    GetClangASTImporter().InsertRecordDecl(record_decl, layout_info);
                 }
             }
         }
@@ -2623,19 +2600,14 @@
     return NULL;
 }
 
-
 bool
-DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
-                                        const DWARFDIE &parent_die,
-                                        CompilerType &class_clang_type,
-                                        const LanguageType class_language,
-                                        std::vector<clang::CXXBaseSpecifier *>& base_classes,
-                                        std::vector<int>& member_accessibilities,
-                                        DWARFDIECollection& member_function_dies,
-                                        DelayedPropertyList& delayed_properties,
-                                        AccessType& default_accessibility,
-                                        bool &is_a_class,
-                                        LayoutInfo &layout_info)
+DWARFASTParserClang::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &parent_die,
+                                       CompilerType &class_clang_type, const LanguageType class_language,
+                                       std::vector<clang::CXXBaseSpecifier *> &base_classes,
+                                       std::vector<int> &member_accessibilities,
+                                       DWARFDIECollection &member_function_dies,
+                                       DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
+                                       bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info)
 {
     if (!parent_die)
         return 0;
@@ -3559,10 +3531,8 @@
             Type *type = GetTypeForDIE(die);
             const char *name = die.GetName();
             clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
-            decl = m_ast.CreateVariableDeclaration(
-                decl_context,
-                name,
-                ClangASTContext::GetQualType(type->GetForwardCompilerType()));
+            decl = m_ast.CreateVariableDeclaration(decl_context, name,
+                                                   ClangUtil::GetQualType(type->GetForwardCompilerType()));
             break;
         }
         case DW_TAG_imported_declaration:
@@ -4071,34 +4041,3 @@
     return (failures.Size() != 0);
 }
 
-
-bool
-DWARFASTParserClang::LayoutRecordType(const clang::RecordDecl *record_decl,
-                                      uint64_t &bit_size,
-                                      uint64_t &alignment,
-                                      llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
-                                      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
-                                      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
-{
-    RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl);
-    bool success = false;
-    base_offsets.clear();
-    vbase_offsets.clear();
-    if (pos != m_record_decl_to_layout_map.end())
-    {
-        bit_size = pos->second.bit_size;
-        alignment = pos->second.alignment;
-        field_offsets.swap(pos->second.field_offsets);
-        base_offsets.swap (pos->second.base_offsets);
-        vbase_offsets.swap (pos->second.vbase_offsets);
-        m_record_decl_to_layout_map.erase(pos);
-        success = true;
-    }
-    else
-    {
-        bit_size = 0;
-        alignment = 0;
-        field_offsets.clear();
-    }
-    return success;
-}
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -33,13 +33,13 @@
                             const DWARFDIE &die) = 0;
 
     virtual bool
-    CanCompleteType (const lldb_private::CompilerType &compiler_type)
+    CanCompleteType(const lldb_private::CompilerType &compiler_type)
     {
         return false;
     }
 
     virtual bool
-    CompleteType (const lldb_private::CompilerType &compiler_type)
+    CompleteType(const lldb_private::CompilerType &compiler_type)
     {
         return false;
     }
Index: source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
===================================================================
--- source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -10,6 +10,7 @@
 #include "AppleObjCTypeEncodingParser.h"
 
 #include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
 #include "lldb/Symbol/CompilerType.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
@@ -155,7 +156,7 @@
         }
         ClangASTContext::CompleteTagDeclarationDefinition(union_type);
     }
-    return ClangASTContext::GetQualType(union_type);
+    return ClangUtil::GetQualType(union_type);
 }
 
 clang::QualType
@@ -171,7 +172,7 @@
     if (!lldb_ctx)
         return clang::QualType();
     CompilerType array_type(lldb_ctx->CreateArrayType(CompilerType(&ast_ctx, element_type), size, false));
-    return ClangASTContext::GetQualType(array_type);
+    return ClangUtil::GetQualType(array_type);
 }
 
 // the runtime can emit these in the form of @"SomeType", giving more specifics
@@ -261,8 +262,8 @@
         if (!num_types)
             return ast_ctx.getObjCIdType();
 #endif
-        
-        return ClangASTContext::GetQualType(ClangASTContext::GetTypeForDecl(decls[0]).GetPointerType());
+
+        return ClangUtil::GetQualType(ClangASTContext::GetTypeForDecl(decls[0]).GetPointerType());
     }
     else
     {
Index: source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
===================================================================
--- source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -9,10 +9,11 @@
 
 #include "AppleObjCDeclVendor.h"
 
+#include "Plugins/ExpressionParser/Clang/ASTDumper.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
-#include "Plugins/ExpressionParser/Clang/ASTDumper.h"
 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
@@ -356,9 +357,10 @@
         }
         
         clang::Selector sel = ast_ctx.Selectors.getSelector(is_zero_argument ? 0 : selector_components.size(), selector_components.data());
-        
-        clang::QualType ret_type = ClangASTContext::GetQualType(type_realizer_sp->RealizeType(interface_decl->getASTContext(), m_type_vector[0].c_str(), for_expression));
-        
+
+        clang::QualType ret_type = ClangUtil::GetQualType(
+            type_realizer_sp->RealizeType(interface_decl->getASTContext(), m_type_vector[0].c_str(), for_expression));
+
         if (ret_type.isNull())
             return NULL;
         
@@ -384,8 +386,9 @@
              ++ai)
         {
             const bool for_expression = true;
-            clang::QualType arg_type = ClangASTContext::GetQualType(type_realizer_sp->RealizeType(ast_ctx, m_type_vector[ai].c_str(), for_expression));
-            
+            clang::QualType arg_type = ClangUtil::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!
 
@@ -502,17 +505,12 @@
         {
             clang::TypeSourceInfo * const type_source_info = nullptr;
             const bool is_synthesized = false;
-            clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create (*m_ast_ctx.getASTContext(),
-                                                                          interface_decl,
-                                                                          clang::SourceLocation(),
-                                                                          clang::SourceLocation(),
-                                                                          &m_ast_ctx.getASTContext()->Idents.get(name),
-                                                                          ClangASTContext::GetQualType(ivar_type),
-                                                                          type_source_info,                      // TypeSourceInfo *
-                                                                          clang::ObjCIvarDecl::Public,
-                                                                          0,
-                                                                          is_synthesized);
-            
+            clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create(
+                *m_ast_ctx.getASTContext(), interface_decl, clang::SourceLocation(), clang::SourceLocation(),
+                &m_ast_ctx.getASTContext()->Idents.get(name), ClangUtil::GetQualType(ivar_type),
+                type_source_info, // TypeSourceInfo *
+                clang::ObjCIvarDecl::Public, 0, is_synthesized);
+
             if (ivar_decl)
             {
                 interface_decl->addDecl(ivar_decl);
Index: source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
===================================================================
--- source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -25,16 +25,17 @@
 
 #include "clang/AST/ASTContext.h"
 
-#include "lldb/Core/dwarf.h"
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Scalar.h"
 #include "lldb/Core/StreamString.h"
+#include "lldb/Core/dwarf.h"
 #include "lldb/Expression/IRExecutionUnit.h"
 #include "lldb/Expression/IRInterpreter.h"
 #include "lldb/Host/Endian.h"
 #include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
 #include "lldb/Symbol/CompilerType.h"
 
 #include <map>
@@ -1235,11 +1236,8 @@
         if (log)
         {
             log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRIu64 "]",
-                        name.c_str(),
-                        lldb_private::ClangASTContext::GetQualType(compiler_type).getAsString().c_str(),
-                        PrintType(value_type).c_str(),
-                        value_size,
-                        value_alignment);
+                        name.c_str(), lldb_private::ClangUtil::GetQualType(compiler_type).getAsString().c_str(),
+                        PrintType(value_type).c_str(), value_size, value_alignment);
         }
 
 
Index: source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
===================================================================
--- source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -12,12 +12,11 @@
 #include "ASTDumper.h"
 #include "ClangModulesDeclVendor.h"
 
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/RecordLayout.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
 #include "lldb/Symbol/CompilerDeclContext.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/SymbolFile.h"
@@ -25,6 +24,8 @@
 #include "lldb/Symbol/TaggedASTType.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Target.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
 
 #include <vector>
 
@@ -277,7 +278,7 @@
                     if (!clang_type)
                         continue;
 
-                    const TagType *tag_type = ClangASTContext::GetQualType(clang_type)->getAs<TagType>();
+                    const TagType *tag_type = ClangUtil::GetQualType(clang_type)->getAs<TagType>();
 
                     if (!tag_type)
                         continue;
@@ -317,7 +318,7 @@
                 if (!clang_type)
                     continue;
 
-                const TagType *tag_type = ClangASTContext::GetQualType(clang_type)->getAs<TagType>();
+                const TagType *tag_type = ClangUtil::GetQualType(clang_type)->getAs<TagType>();
 
                 if (!tag_type)
                     continue;
@@ -1905,7 +1906,8 @@
 
     SetImportInProgress(true);
 
-    QualType copied_qual_type = m_ast_importer_sp->CopyType (m_ast_context, src_ast->getASTContext(), ClangASTContext::GetQualType(src_type));
+    QualType copied_qual_type =
+        m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(), ClangUtil::GetQualType(src_type));
 
     SetImportInProgress(false);
 
@@ -1933,14 +1935,8 @@
 
     clang::ASTContext *ast = lldb_ast->getASTContext();
 
-    clang::NamedDecl *Decl = VarDecl::Create(*ast,
-                                             const_cast<DeclContext*>(m_decl_context),
-                                             SourceLocation(),
-                                             SourceLocation(),
-                                             ii,
-                                             ClangASTContext::GetQualType(type),
-                                             0,
-                                             SC_Static);
+    clang::NamedDecl *Decl = VarDecl::Create(*ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
+                                             SourceLocation(), ii, ClangUtil::GetQualType(type), 0, SC_Static);
     m_decls.push_back(Decl);
 
     return Decl;
@@ -1963,7 +1959,7 @@
 
     m_function_types.insert(type);
 
-    QualType qual_type (ClangASTContext::GetQualType(type));
+    QualType qual_type(ClangUtil::GetQualType(type));
 
     clang::ASTContext *ast = lldb_ast->getASTContext();
 
@@ -2059,7 +2055,7 @@
 {
     if (clang_type)
     {
-        QualType qual_type = ClangASTContext::GetQualType(clang_type);
+        QualType qual_type = ClangUtil::GetQualType(clang_type);
 
         if (const TypedefType *typedef_type = llvm::dyn_cast<TypedefType>(qual_type))
         {
Index: source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
===================================================================
--- source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
+++ source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
@@ -11,6 +11,7 @@
 
 #include "lldb/Core/Log.h"
 #include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
 #include "lldb/Symbol/CompilerType.h"
 
 #include "llvm/Support/raw_ostream.h"
@@ -83,7 +84,7 @@
 
 ASTDumper::ASTDumper (const CompilerType &compiler_type)
 {
-    m_dump = ClangASTContext::GetQualType(compiler_type).getAsString();
+    m_dump = ClangUtil::GetQualType(compiler_type).getAsString();
 }
 
 
Index: include/lldb/Symbol/TypeSystem.h
===================================================================
--- include/lldb/Symbol/TypeSystem.h
+++ include/lldb/Symbol/TypeSystem.h
@@ -100,7 +100,7 @@
     Finalize() {}
 
     virtual DWARFASTParser *
-    GetDWARFParser ()
+    GetDWARFParser()
     {
         return nullptr;
     }
Index: include/lldb/Symbol/ClangUtil.h
===================================================================
--- /dev/null
+++ include/lldb/Symbol/ClangUtil.h
@@ -0,0 +1,37 @@
+//===-- ClangUtil.h ---------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+// A collection of helper methods and data structures for manipulating clang
+// types and decls.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SYMBOL_CLANGUTIL_H
+#define LLDB_SYMBOL_CLANGUTIL_H
+
+#include "clang/AST/Type.h"
+
+#include "lldb/Symbol/CompilerType.h"
+
+namespace lldb_private
+{
+struct ClangUtil
+{
+    static bool
+    IsClangType(const CompilerType &ct);
+
+    static clang::QualType
+    GetQualType(const CompilerType &ct);
+
+    static clang::QualType
+    GetCanonicalQualType(const CompilerType &ct);
+
+    static CompilerType
+    RemoveFastQualifiers(const CompilerType &ct);
+};
+}
+
+#endif
Index: include/lldb/Symbol/ClangASTImporter.h
===================================================================
--- include/lldb/Symbol/ClangASTImporter.h
+++ include/lldb/Symbol/ClangASTImporter.h
@@ -19,6 +19,9 @@
 
 // Other libraries and framework includes
 #include "clang/AST/ASTImporter.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
 
@@ -26,6 +29,8 @@
 #include "lldb/lldb-types.h"
 #include "lldb/Symbol/CompilerDeclContext.h"
 
+#include "llvm/ADT/DenseMap.h"
+
 namespace lldb_private {
     
 class ClangASTMetrics
@@ -93,6 +98,16 @@
 class ClangASTImporter 
 {
 public:
+    struct LayoutInfo
+    {
+        LayoutInfo() : bit_size(0), alignment(0), field_offsets(), base_offsets(), vbase_offsets() {}
+        uint64_t bit_size;
+        uint64_t alignment;
+        llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets;
+        llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
+        llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets;
+    };
+
     ClangASTImporter () :
         m_file_manager(clang::FileSystemOptions())
     {
@@ -126,10 +141,28 @@
     DeportDecl (clang::ASTContext *dst_ctx,
                 clang::ASTContext *src_ctx,
                 clang::Decl *decl);
-    
+
     void
-    CompleteDecl (clang::Decl *decl);
-        
+    InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout);
+
+    bool
+    LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment,
+                     llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
+                     llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
+                     llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets);
+
+    bool
+    CanImport(const CompilerType &type);
+
+    bool
+    Import(const CompilerType &type);
+
+    bool
+    CompleteType(const CompilerType &compiler_type);
+
+    void
+    CompleteDecl(clang::Decl *decl);
+
     bool
     CompleteTagDecl (clang::TagDecl *decl);
     
@@ -381,6 +414,9 @@
     GetDeclOrigin (const clang::Decl *decl);
         
     clang::FileManager      m_file_manager;
+    typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo> RecordDeclToLayoutMap;
+
+    RecordDeclToLayoutMap m_record_decl_to_layout_map;
 };
     
 } // namespace lldb_private
Index: include/lldb/Symbol/ClangASTContext.h
===================================================================
--- include/lldb/Symbol/ClangASTContext.h
+++ include/lldb/Symbol/ClangASTContext.h
@@ -30,11 +30,13 @@
 
 // Project includes
 #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
-#include "lldb/lldb-enumerations.h"
 #include "lldb/Core/ClangForward.h"
 #include "lldb/Core/ConstString.h"
 #include "lldb/Symbol/CompilerType.h"
 #include "lldb/Symbol/TypeSystem.h"
+#include "lldb/lldb-enumerations.h"
+
+class DWARFASTParserClang;
 
 namespace lldb_private {
 
@@ -521,7 +523,7 @@
     // TypeSystem methods
     //------------------------------------------------------------------
     DWARFASTParser *
-    GetDWARFParser () override;
+    GetDWARFParser() override;
 
     //------------------------------------------------------------------
     // ClangASTContext callbacks for external source lookups.
@@ -593,16 +595,6 @@
                               ConstString *language_object_name_ptr) override;
 
     //----------------------------------------------------------------------
-    // Clang specific CompilerType predicates
-    //----------------------------------------------------------------------
-    
-    static bool
-    IsClangType (const CompilerType &ct)
-    {
-        return llvm::dyn_cast_or_null<ClangASTContext>(ct.GetTypeSystem()) != nullptr && ct.GetOpaqueQualType() != nullptr;
-    }
-
-    //----------------------------------------------------------------------
     // Clang specific clang::DeclContext functions
     //----------------------------------------------------------------------
 
@@ -834,9 +826,6 @@
     // If the current object represents a typedef type, get the underlying type
     CompilerType
     GetTypedefedType (lldb::opaque_compiler_type_t type) override;
-
-    static CompilerType
-    RemoveFastQualifiers (const CompilerType& type);
     
     //----------------------------------------------------------------------
     // Create related types using the current type's AST
@@ -1040,13 +1029,6 @@
     static bool
     SetHasExternalStorage (lldb::opaque_compiler_type_t type, bool has_extern);
     
-
-    static bool
-    CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer);
-
-    static bool
-    Import (const CompilerType &type, lldb_private::ClangASTImporter &importer);
-
     static bool
     GetHasExternalStorage (const CompilerType &type);
     //------------------------------------------------------------------
@@ -1149,29 +1131,6 @@
     
     static clang::ObjCInterfaceDecl *
     GetAsObjCInterfaceDecl (const CompilerType& type);
-    
-    static clang::QualType
-    GetQualType (const CompilerType& type)
-    {
-        // Make sure we have a clang type before making a clang::QualType
-        if (type.GetOpaqueQualType())
-        {
-            ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
-            if (ast)
-                return clang::QualType::getFromOpaquePtr(type.GetOpaqueQualType());
-        }
-        return clang::QualType();
-    }
-
-    static clang::QualType
-    GetCanonicalQualType (const CompilerType& type)
-    {
-        // Make sure we have a clang type before making a clang::QualType
-        ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
-        if (ast)
-            return clang::QualType::getFromOpaquePtr(type.GetOpaqueQualType()).getCanonicalType();
-        return clang::QualType();
-    }
 
     clang::ClassTemplateDecl *
     ParseClassTemplateDecl (clang::DeclContext *decl_ctx,
@@ -1212,6 +1171,7 @@
     //------------------------------------------------------------------
     // Classes that inherit from ClangASTContext can see and modify these
     //------------------------------------------------------------------
+    // clang-format off
     std::string                                     m_target_triple;
     std::unique_ptr<clang::ASTContext>              m_ast_ap;
     std::unique_ptr<clang::LangOptions>             m_language_options_ap;
@@ -1225,7 +1185,7 @@
     std::unique_ptr<clang::IdentifierTable>         m_identifier_table_ap;
     std::unique_ptr<clang::SelectorTable>           m_selector_table_ap;
     std::unique_ptr<clang::Builtin::Context>        m_builtins_ap;
-    std::unique_ptr<DWARFASTParser>                 m_dwarf_ast_parser_ap;
+    std::unique_ptr<DWARFASTParserClang>            m_dwarf_ast_parser_ap;
     std::unique_ptr<ClangASTSource>                 m_scratch_ast_source_ap;
     std::unique_ptr<clang::MangleContext>           m_mangle_ctx_ap;
     CompleteTagDeclCallback                         m_callback_tag_decl;
@@ -1235,7 +1195,7 @@
     bool                                            m_ast_owned;
     bool                                            m_can_evaluate_expressions;
     std::map<void *, std::shared_ptr<void>>         m_decl_objects;
-
+    // clang-format on
 private:
     //------------------------------------------------------------------
     // For ClangASTContext only
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to