[cfe-commits] r99555 - in /cfe/trunk: lib/CodeGen/CGVtable.cpp test/CodeGenCXX/vtable-layout-abi-examples.cpp test/CodeGenCXX/vtable-layout.cpp

Anders Carlsson andersca at mac.com
Thu Mar 25 14:45:14 PDT 2010


Author: andersca
Date: Thu Mar 25 16:45:14 2010
New Revision: 99555

URL: http://llvm.org/viewvc/llvm-project?rev=99555&view=rev
Log:
Don't add address points for virtual primary bases that aren't primary bases in the complete class.

Modified:
    cfe/trunk/lib/CodeGen/CGVtable.cpp
    cfe/trunk/test/CodeGenCXX/vtable-layout-abi-examples.cpp
    cfe/trunk/test/CodeGenCXX/vtable-layout.cpp

Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=99555&r1=99554&r2=99555&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Thu Mar 25 16:45:14 2010
@@ -1900,20 +1900,32 @@
   // Compute 'this' pointer adjustments.
   ComputeThisAdjustments();
 
-  // Record the address point.
-  AddressPoints.insert(std::make_pair(BaseSubobject(Base.getBase(),
-                                                    OffsetInLayoutClass),
-                                      AddressPoint));
-  
-  // Record the address points for all primary bases.
-  for (PrimaryBasesSetVectorTy::const_iterator I = PrimaryBases.begin(),
-       E = PrimaryBases.end(); I != E; ++I) {
-    const CXXRecordDecl *BaseDecl = *I;
-    
-    // We know that all the primary bases have the same offset as the base
-    // subobject.
-    BaseSubobject PrimaryBase(BaseDecl, OffsetInLayoutClass);
-    AddressPoints.insert(std::make_pair(PrimaryBase, AddressPoint));
+  // Add all address points.
+  const CXXRecordDecl *RD = Base.getBase();
+  while (true) {
+    AddressPoints.insert(std::make_pair(BaseSubobject(RD, OffsetInLayoutClass),
+                                        AddressPoint));
+
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+    
+    if (!PrimaryBase)
+      break;
+    
+    if (Layout.getPrimaryBaseWasVirtual()) {
+      // Check if this virtual primary base is a primary base in the layout
+      // class. If it's not, we don't want to add it.
+      const ASTRecordLayout &LayoutClassLayout =
+        Context.getASTRecordLayout(LayoutClass);
+
+      if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) !=
+          OffsetInLayoutClass) {
+        // We don't want to add this class (or any of its primary bases).
+        break;
+      }
+    }
+
+    RD = PrimaryBase;
   }
 
   bool BaseIsMorallyVirtual = BaseIsVirtual;

Modified: cfe/trunk/test/CodeGenCXX/vtable-layout-abi-examples.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-layout-abi-examples.cpp?rev=99555&r1=99554&r2=99555&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-layout-abi-examples.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-layout-abi-examples.cpp Thu Mar 25 16:45:14 2010
@@ -178,7 +178,6 @@
 // CHECK-NEXT:    7 | vcall_offset (-16)
 // CHECK-NEXT:    8 | offset_to_top (-16)
 // CHECK-NEXT:    9 | Test2::D RTTI
-// CHECK-NEXT:        -- (Test2::A, 16) vtable address --
 // CHECK-NEXT:        -- (Test2::C, 16) vtable address --
 // CHECK-NEXT:   10 | [unused] void Test2::A::f()
 struct D : public B, public C {

Modified: cfe/trunk/test/CodeGenCXX/vtable-layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-layout.cpp?rev=99555&r1=99554&r2=99555&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-layout.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-layout.cpp Thu Mar 25 16:45:14 2010
@@ -635,7 +635,6 @@
 // CHECK-NEXT:    9 | vcall_offset (-8)
 // CHECK-NEXT:   10 | offset_to_top (-8)
 // CHECK-NEXT:   11 | Test17::E RTTI
-// CHECK-NEXT:        -- (Test17::A, 8) vtable address --
 // CHECK-NEXT:        -- (Test17::C, 8) vtable address --
 // CHECK-NEXT:   12 | void Test17::E::f()
 // CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
@@ -693,7 +692,6 @@
 // CHECK-NEXT:   19 | vcall_offset (-16)
 // CHECK-NEXT:   20 | offset_to_top (-16)
 // CHECK-NEXT:   21 | Test18::D RTTI
-// CHECK-NEXT:        -- (Test18::A, 16) vtable address --
 // CHECK-NEXT:        -- (Test18::B, 16) vtable address --
 // CHECK-NEXT:   22 | void Test18::D::f()
 // CHECK-NEXT:        [this adjustment: -8 non-virtual, -32 vcall offset offset]
@@ -725,7 +723,6 @@
 // CHECK-NEXT:    9 | vcall_offset (0)
 // CHECK-NEXT:   10 | offset_to_top (-8)
 // CHECK-NEXT:   11 | Test18::C RTTI
-// CHECK-NEXT:        -- (Test18::A, 16) vtable address --
 // CHECK-NEXT:        -- (Test18::B, 16) vtable address --
 // CHECK-NEXT:   12 | void Test18::B::f()
 // CHECK-NEXT:   13 | [unused] void Test18::C::g()
@@ -745,7 +742,6 @@
 // CHECK-NEXT:    2 | vcall_offset (0)
 // CHECK-NEXT:    3 | offset_to_top (0)
 // CHECK-NEXT:    4 | Test18::B RTTI
-// CHECK-NEXT:        -- (Test18::A, 16) vtable address --
 // CHECK-NEXT:        -- (Test18::B, 16) vtable address --
 // CHECK-NEXT:    5 | void Test18::B::f()
 // CHECK-NEXT:    6 | [unused] void Test18::A::g()
@@ -881,9 +877,6 @@
 // CHECK-NEXT:   12 | vcall_offset (-8)
 // CHECK-NEXT:   13 | offset_to_top (-8)
 // CHECK-NEXT:   14 | Test21::F RTTI
-// CHECK-NEXT:        -- (Test21::A, 8) vtable address --
-// CHECK-NEXT:        -- (Test21::B, 8) vtable address --
-// CHECK-NEXT:        -- (Test21::C, 8) vtable address --
 // CHECK-NEXT:        -- (Test21::E, 8) vtable address --
 // CHECK-NEXT:   15 | [unused] void Test21::F::f()
 //
@@ -1012,7 +1005,6 @@
 // CHECK-NEXT:    6 | vcall_offset (-8)
 // CHECK-NEXT:    7 | offset_to_top (-8)
 // CHECK-NEXT:    8 | Test24::D RTTI
-// CHECK-NEXT:        -- (Test24::A, 8) vtable address --
 // CHECK-NEXT:        -- (Test24::C, 8) vtable address --
 // CHECK-NEXT:    9 | [unused] void Test24::D::f()
 
@@ -1030,14 +1022,13 @@
 // CHECK-NEXT:    1 | vcall_offset (-8)
 // CHECK-NEXT:    2 | offset_to_top (0)
 // CHECK-NEXT:    3 | Test24::C RTTI
-// CHECK-NEXT:        -- (Test24::A, 8) vtable address --
 // CHECK-NEXT:        -- (Test24::C, 8) vtable address --
 // CHECK-NEXT:    4 | [unused] void Test24::A::f()
 // CHECK-NEXT:    5 | vcall_offset (0)
-// CHECK-NEXT: 6 | offset_to_top (8)
-// CHECK-NEXT: 7 | Test24::C RTTI
-// CHECK-NEXT:     -- (Test24::A, 0) vtable address --
-// CHECK-NEXT: 8 | void Test24::A::f()
+// CHECK-NEXT:    6 | offset_to_top (8)
+// CHECK-NEXT:    7 | Test24::C RTTI
+// CHECK-NEXT:        -- (Test24::A, 0) vtable address --
+// CHECK-NEXT:    8 | void Test24::A::f()
 struct D : B, C {
   virtual void f();
 };
@@ -1071,7 +1062,6 @@
 // CHECK-NEXT:    8 | offset_to_top (-8)
 // CHECK-NEXT:    9 | Test25::C RTTI
 // CHECK-NEXT:        -- (Test25::B, 8) vtable address --
-// CHECK-NEXT:        -- (Test25::V, 8) vtable address --
 // CHECK-NEXT:   10 | [unused] void Test25::V::f()
 
 // CHECK:      Construction vtable for ('Test25::A', 0) in 'Test25::C' (5 entries).
@@ -1089,7 +1079,6 @@
 // CHECK-NEXT:    2 | offset_to_top (0)
 // CHECK-NEXT:    3 | Test25::B RTTI
 // CHECK-NEXT:        -- (Test25::B, 8) vtable address --
-// CHECK-NEXT:        -- (Test25::V, 8) vtable address --
 // CHECK-NEXT:    4 | [unused] void Test25::V::f()
 // CHECK-NEXT:    5 | vcall_offset (0)
 // CHECK-NEXT:    6 | offset_to_top (8)





More information about the cfe-commits mailing list