Thread the info about vbptr sharing through ASTRecordLayout

Reviewed at http://llvm-reviews.chandlerc.com/D2120

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194256 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/RecordLayout.cpp b/lib/AST/RecordLayout.cpp
index 44af1f1..df5f79c 100644
--- a/lib/AST/RecordLayout.cpp
+++ b/lib/AST/RecordLayout.cpp
@@ -44,7 +44,6 @@
 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
                                  CharUnits size, CharUnits alignment,
                                  bool hasOwnVFPtr, bool hasVFPtr,
-                                 bool hasOwnVBPtr,
                                  CharUnits vbptroffset,
                                  CharUnits datasize,
                                  const uint64_t *fieldoffsets,
@@ -54,6 +53,7 @@
                                  CharUnits SizeOfLargestEmptySubobject,
                                  const CXXRecordDecl *PrimaryBase,
                                  bool IsPrimaryBaseVirtual,
+                                 const CXXRecordDecl *BaseSharingVBPtr,
                                  bool AlignAfterVBases,
                                  const BaseOffsetsMapTy& BaseOffsets,
                                  const VBaseOffsetsMapTy& VBaseOffsets)
@@ -75,7 +75,7 @@
   CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
   CXXInfo->VBPtrOffset = vbptroffset;
   CXXInfo->HasVFPtr = hasVFPtr;
-  CXXInfo->HasOwnVBPtr = hasOwnVBPtr;
+  CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
   CXXInfo->AlignAfterVBases = AlignAfterVBases;
 
 
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 08c9da3..d0426fa 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -2673,11 +2673,11 @@
     return new (*this) ASTRecordLayout(
         *this, Builder.Size, Builder.Alignment,
         Builder.HasVFPtr && !Builder.PrimaryBase, Builder.HasVFPtr,
-        Builder.HasVBPtr && !Builder.SharedVBPtrBase, Builder.VBPtrOffset,
-        Builder.DataSize, Builder.FieldOffsets.data(),
+        Builder.VBPtrOffset, Builder.DataSize, Builder.FieldOffsets.data(),
         Builder.FieldOffsets.size(), Builder.DataSize,
         Builder.NonVirtualAlignment, CharUnits::Zero(), Builder.PrimaryBase,
-        false, Builder.AlignAfterVBases, Builder.Bases, Builder.VBases);
+        false, Builder.SharedVBPtrBase, Builder.AlignAfterVBases, Builder.Bases,
+        Builder.VBases);
   } else {
     Builder.layout(D);
     return new (*this) ASTRecordLayout(
@@ -2735,7 +2735,6 @@
                                   Builder.Alignment,
                                   Builder.HasOwnVFPtr,
                                   RD->isDynamicClass(),
-                                  false,
                                   CharUnits::fromQuantity(-1),
                                   DataSize, 
                                   Builder.FieldOffsets.data(),
@@ -2745,7 +2744,7 @@
                                   EmptySubobjects.SizeOfLargestEmptySubobject,
                                   Builder.PrimaryBase,
                                   Builder.PrimaryBaseIsVirtual,
-                                  true,
+                                  0, true,
                                   Builder.Bases, Builder.VBases);
   } else {
     RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp
index 142f550..fd768d8 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/lib/AST/VTableBuilder.cpp
@@ -3363,30 +3363,17 @@
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
   BasesSetVectorTy VisitedBases;
 
-  // First, see if the Derived class shared the vbptr
-  // with the first non-virtual base.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    if (I->isVirtual())
-      continue;
-
-    const CXXRecordDecl *CurBase = I->getType()->getAsCXXRecordDecl();
-    CharUnits DerivedVBPtrOffset = Layout.getVBPtrOffset(),
-              BaseOffset = Layout.getBaseClassOffset(CurBase);
-    const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(CurBase);
-    if (!BaseLayout.hasVBPtr() ||
-        DerivedVBPtrOffset != BaseOffset + BaseLayout.getVBPtrOffset())
-      continue;
-
+  // First, see if the Derived class shared the vbptr with a non-virtual base.
+  if (const CXXRecordDecl *VBPtrBase = Layout.getBaseSharingVBPtr()) {
     // If the Derived class shares the vbptr with a non-virtual base,
     // it inherits its vbase indices.
-    computeVBTableRelatedInformation(CurBase);
-    for (CXXRecordDecl::base_class_const_iterator J = CurBase->vbases_begin(),
-         F = CurBase->vbases_end(); J != F; ++J) {
-      const CXXRecordDecl *SubVBase = J->getType()->getAsCXXRecordDecl();
-      assert(VBTableIndices.count(ClassPairTy(CurBase, SubVBase)));
+    computeVBTableRelatedInformation(VBPtrBase);
+    for (CXXRecordDecl::base_class_const_iterator I = VBPtrBase->vbases_begin(),
+         E = VBPtrBase->vbases_end(); I != E; ++I) {
+      const CXXRecordDecl *SubVBase = I->getType()->getAsCXXRecordDecl();
+      assert(VBTableIndices.count(ClassPairTy(VBPtrBase, SubVBase)));
       VBTableIndices[ClassPairTy(RD, SubVBase)] =
-          VBTableIndices[ClassPairTy(CurBase, SubVBase)];
+          VBTableIndices[ClassPairTy(VBPtrBase, SubVBase)];
       VisitedBases.insert(SubVBase);
     }
   }