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

Anders Carlsson andersca at mac.com
Wed Mar 10 11:39:11 PST 2010


Author: andersca
Date: Wed Mar 10 13:39:11 2010
New Revision: 98180

URL: http://llvm.org/viewvc/llvm-project?rev=98180&view=rev
Log:
We were mistakenly marking morally virtual bases as being uninteresting. Fix this.

Modified:
    cfe/trunk/lib/CodeGen/CGVtable.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=98180&r1=98179&r2=98180&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Wed Mar 10 13:39:11 2010
@@ -1235,7 +1235,11 @@
   
   /// LayoutSecondaryVtables - Layout the secondary vtables for the given base
   /// subobject.
-  void LayoutSecondaryVtables(BaseSubobject Base, uint64_t OffsetInLayoutClass);
+  ///
+  /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
+  /// or a direct or indirect base of a virtual base.
+  void LayoutSecondaryVtables(BaseSubobject Base, bool BaseIsMorallyVirtual,
+                              uint64_t OffsetInLayoutClass);
 
   /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this
   /// class hierarchy.
@@ -1772,11 +1776,16 @@
     AddressPoints.insert(std::make_pair(PrimaryBase, AddressPoint));
   }
 
+  bool BaseIsMorallyVirtual = BaseIsVirtual;
+  if (isBuildingConstructorVtable() && Base.getBase() == MostDerivedClass)
+    BaseIsMorallyVirtual = false;
+  
   // Layout secondary vtables.
-  LayoutSecondaryVtables(Base, OffsetInLayoutClass);
+  LayoutSecondaryVtables(Base, BaseIsMorallyVirtual, OffsetInLayoutClass);
 }
 
 void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base,
+                                           bool BaseIsMorallyVirtual,
                                            uint64_t OffsetInLayoutClass) {
   // Itanium C++ ABI 2.5.2:
   //   Following the primary virtual table of a derived class are secondary 
@@ -1806,9 +1815,8 @@
       //   tables, which will therefore not be present in the construction
       //   virtual table group, even though the subobject virtual tables are
       //   present in the main virtual table group for the complete object.
-      if (!BaseDecl->getNumVBases()) {
+      if (!BaseIsMorallyVirtual && !BaseDecl->getNumVBases())
         continue;
-      }
     }
 
     // Get the base offset of this base.
@@ -1821,7 +1829,7 @@
     // to emit secondary vtables for other bases of this base.
     if (BaseDecl == PrimaryBase) {
       LayoutSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset),
-                             BaseOffsetInLayoutClass);
+                             BaseIsMorallyVirtual, BaseOffsetInLayoutClass);
       continue;
     }
 

Modified: cfe/trunk/test/CodeGenCXX/vtable-layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-layout.cpp?rev=98180&r1=98179&r2=98180&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-layout.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-layout.cpp Wed Mar 10 13:39:11 2010
@@ -1150,4 +1150,71 @@
   virtual void e();
 };
 void E::e() { }
+
+}
+
+namespace Test28 {
+
+// Check that we do include the vtable for B in the D-in-E construction vtable, since
+// B is a base class of a virtual base (C).
+
+struct A {
+  virtual void a();
+};
+
+struct B {
+  virtual void b();
+};
+
+struct C : A, B {
+  virtual void c();
+};
+
+struct D : virtual C {
+};
+
+// CHECK:      Vtable for 'Test28::E' (14 entries).
+// CHECK-NEXT:    0 | vbase_offset (8)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test28::E RTTI
+// CHECK-NEXT:        -- (Test28::D, 0) vtable address --
+// CHECK-NEXT:        -- (Test28::E, 0) vtable address --
+// CHECK-NEXT:    3 | void Test28::E::e()
+// CHECK-NEXT:    4 | vcall_offset (8)
+// CHECK-NEXT:    5 | vcall_offset (0)
+// CHECK-NEXT:    6 | vcall_offset (0)
+// CHECK-NEXT:    7 | offset_to_top (-8)
+// CHECK-NEXT:    8 | Test28::E RTTI
+// CHECK-NEXT:        -- (Test28::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test28::C, 8) vtable address --
+// CHECK-NEXT:    9 | void Test28::A::a()
+// CHECK-NEXT:   10 | void Test28::C::c()
+// CHECK-NEXT:   11 | offset_to_top (-16)
+// CHECK-NEXT:   12 | Test28::E RTTI
+// CHECK-NEXT:        -- (Test28::B, 16) vtable address --
+// CHECK-NEXT:   13 | void Test28::B::b()
+
+// CHECK:      Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries).
+// CHECK-NEXT:    0 | vbase_offset (8)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test28::D RTTI
+// CHECK-NEXT:        -- (Test28::D, 0) vtable address --
+// CHECK-NEXT:    3 | vcall_offset (8)
+// CHECK-NEXT:    4 | vcall_offset (0)
+// CHECK-NEXT:    5 | vcall_offset (0)
+// CHECK-NEXT:    6 | offset_to_top (-8)
+// CHECK-NEXT:    7 | Test28::D RTTI
+// CHECK-NEXT:        -- (Test28::A, 8) vtable address --
+// CHECK-NEXT:        -- (Test28::C, 8) vtable address --
+// CHECK-NEXT:    8 | void Test28::A::a()
+// CHECK-NEXT:    9 | void Test28::C::c()
+// CHECK-NEXT:   10 | offset_to_top (-16)
+// CHECK-NEXT:   11 | Test28::D RTTI
+// CHECK-NEXT:        -- (Test28::B, 16) vtable address --
+// CHECK-NEXT:   12 | void Test28::B::b()
+struct E : D {
+  virtual void e();
+};
+void E::e() { }
+
 }





More information about the cfe-commits mailing list