]> granicus.if.org Git - clang/commitdiff
When building construction vtables, we need to check if a primary virtual base is...
authorAnders Carlsson <andersca@mac.com>
Wed, 10 Mar 2010 03:02:01 +0000 (03:02 +0000)
committerAnders Carlsson <andersca@mac.com>
Wed, 10 Mar 2010 03:02:01 +0000 (03:02 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98131 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGVtable.cpp

index fbd0ed8fbef7d2cdb849cf2c88c7d1ef50612703..8b239f2614f7a36c233c4083643c61c1306d1e49 100644 (file)
@@ -1238,6 +1238,7 @@ private:
   /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this
   /// class hierarchy.
   void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 
+                                    uint64_t OffsetInLayoutClass,
                                     VisitedVirtualBasesSetTy &VBases);
 
   /// LayoutVtablesForVirtualBases - Layout vtables for all virtual bases of the
@@ -1699,7 +1700,8 @@ void VtableBuilder::LayoutVtable() {
   VisitedVirtualBasesSetTy VBases;
   
   // Determine the primary virtual bases.
-  DeterminePrimaryVirtualBases(MostDerivedClass, VBases);
+  DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset,
+                               VBases);
   VBases.clear();
   
   LayoutVtablesForVirtualBases(MostDerivedClass, VBases);
@@ -1808,7 +1810,8 @@ void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base,
 }
 
 void
-VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 
+VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
+                                            uint64_t OffsetInLayoutClass,
                                             VisitedVirtualBasesSetTy &VBases) {
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
   
@@ -1822,8 +1825,15 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
       if (isBuildingConstructorVtable()) {
         // Check if the base is actually a primary base in the class we use for
         // layout.
-        // FIXME: Is this check enough?
-        if (MostDerivedClassOffset != 0)
+        const ASTRecordLayout &LayoutClassLayout =
+          Context.getASTRecordLayout(LayoutClass);
+
+        uint64_t PrimaryBaseOffsetInLayoutClass =
+          LayoutClassLayout.getVBaseClassOffset(PrimaryBase);
+        
+        // We know that the base is not a primary base in the layout class if 
+        // the base offsets are different.
+        if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass)
           IsPrimaryVirtualBase = false;
       }
         
@@ -1838,10 +1848,22 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
     const CXXRecordDecl *BaseDecl = 
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
 
-    if (I->isVirtual() && !VBases.insert(BaseDecl))
-      continue;
+    uint64_t BaseOffsetInLayoutClass;
+    
+    if (I->isVirtual()) {
+      if (!VBases.insert(BaseDecl))
+        continue;
+      
+      const ASTRecordLayout &LayoutClassLayout =
+        Context.getASTRecordLayout(LayoutClass);
+
+      BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl);
+    } else {
+      BaseOffsetInLayoutClass = 
+        OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl);
+    }
 
-    DeterminePrimaryVirtualBases(BaseDecl, VBases);
+    DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases);
   }
 }