Move some functions from DWARFASTParserClang to ClangASTImporter.
This allows these functions to be re-used by a forthcoming
PDBASTParser.  The functions in question are CanCompleteType,
CompleteType, and CanImport.  Conceptually, these functions belong
on ClangASTImporter anyway, and previously they were just ping
ponging around through a few levels of indirection to end up there
as well, so this patch actually makes the code somewhat simpler.
A few methods were moved to a new file called ClangUtil, so that
they can be shared between ClangASTImporter and ClangASTContext
without creating a circular dependency between those two cpp
files.
Differential Revision: http://reviews.llvm.org/D18381
llvm-svn: 264685
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index ab20844..2fb3604 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -33,18 +33,6 @@
                             const DWARFDIE &die) = 0;
 
     virtual bool
-    CanCompleteType (const lldb_private::CompilerType &compiler_type)
-    {
-        return false;
-    }
-
-    virtual bool
-    CompleteType (const lldb_private::CompilerType &compiler_type)
-    {
-        return false;
-    }
-
-    virtual bool
     CompleteTypeFromDWARF (const DWARFDIE &die,
                            lldb_private::Type *type,
                            lldb_private::CompilerType &compiler_type) = 0;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 8293415..0af10c7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/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;
-}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index bd83250..0826423 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/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;
 };
 
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 842575f..66e3e72 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/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,18 @@
 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;
+    DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
+    return ast_parser->GetClangASTImporter().CanImport(compiler_type);
 }
 
 
@@ -1624,16 +1625,16 @@
 {
     lldb_private::Mutex::Locker locker(GetObjectFile()->GetModule()->GetMutex());
 
-    TypeSystem *type_system = compiler_type.GetTypeSystem();
-    if (type_system)
+    ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem());
+    if (clang_type_system)
     {
-        DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
-        if (dwarf_ast && dwarf_ast->CanCompleteType(compiler_type))
-            return dwarf_ast->CompleteType(compiler_type);
+        DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
+        if (ast_parser && ast_parser->GetClangASTImporter().CanImport(compiler_type))
+            return ast_parser->GetClangASTImporter().CompleteType(compiler_type);
     }
 
     // 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())
     {