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

Anders Carlsson andersca at mac.com
Tue Feb 16 08:49:35 PST 2010


Author: andersca
Date: Tue Feb 16 10:49:35 2010
New Revision: 96355

URL: http://llvm.org/viewvc/llvm-project?rev=96355&view=rev
Log:
Handle layout of vtables for virtual bases.

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=96355&r1=96354&r2=96355&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Tue Feb 16 10:49:35 2010
@@ -831,6 +831,11 @@
   /// subobject.
   void LayoutSecondaryVtables(BaseSubobject Base);
   
+  /// LayoutVtablesForVirtualBases - Layout vtables for all virtual bases of the
+  /// given base (excluding any primary bases).
+  void LayoutVtablesForVirtualBases(const CXXRecordDecl *RD, 
+                                    VisitedVirtualBasesSetTy &VBases);
+
 public:
   VtableBuilder(CGVtableInfo &VtableInfo, const CXXRecordDecl *MostDerivedClass)
     : VtableInfo(VtableInfo), MostDerivedClass(MostDerivedClass), 
@@ -1039,7 +1044,8 @@
 void VtableBuilder::LayoutVtable() {
   LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(MostDerivedClass, 0));
   
-  // FIXME: Emit vtables for virtual bases here.
+  VisitedVirtualBasesSetTy VBases;
+  LayoutVtablesForVirtualBases(MostDerivedClass, VBases);
 }
   
 void VtableBuilder::LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base) {
@@ -1128,6 +1134,40 @@
   }
 }
 
+void
+VtableBuilder::LayoutVtablesForVirtualBases(const CXXRecordDecl *RD, 
+                                            VisitedVirtualBasesSetTy &VBases) {
+  // Itanium C++ ABI 2.5.2:
+  //   Then come the virtual base virtual tables, also in inheritance graph
+  //   order, and again excluding primary bases (which share virtual tables with
+  //   the classes for which they are primary).
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+  const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    // Check if this base needs a vtable. (If it's virtual, and we haven't
+    // visited it before).
+    if (I->isVirtual() && BaseDecl->isDynamicClass() && 
+        BaseDecl != PrimaryBase && VBases.insert(BaseDecl)) {
+      const ASTRecordLayout &MostDerivedClassLayout =
+        Context.getASTRecordLayout(MostDerivedClass);
+      uint64_t BaseOffset = 
+        MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
+      
+      LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset));
+    }
+    
+    // We only need to check the base for virtual base vtables if it actually
+    // has virtual bases.
+    if (BaseDecl->getNumVBases())
+      LayoutVtablesForVirtualBases(BaseDecl, VBases);
+  }
+}
+
 /// dumpLayout - Dump the vtable layout.
 void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) {
   

Modified: cfe/trunk/test/CodeGenCXX/vtable-layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-layout.cpp?rev=96355&r1=96354&r2=96355&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-layout.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-layout.cpp Tue Feb 16 10:49:35 2010
@@ -395,3 +395,30 @@
 void C::f() { }
 
 }
+
+namespace Test11 {
+
+// Very simple test of vtables for virtual bases.
+struct A1 { int a; };
+struct A2 { int b; };
+
+struct B : A1, virtual A2 {
+  int b;
+};
+
+// CHECK:     Vtable for 'Test11::C' (8 entries).
+// CHECK-NEXT:   0 | vbase_offset (24)
+// CHECK-NEXT:   1 | vbase_offset (8)
+// CHECK-NEXT:   2 | offset_to_top (0)
+// CHECK-NEXT:   3 | Test11::C RTTI
+// CHECK-NEXT:       -- (Test11::C, 0) vtable address --
+// CHECK-NEXT:   4 | void Test11::C::f()
+// CHECK-NEXT:   5 | vbase_offset (16)
+// CHECK-NEXT:   6 | offset_to_top (-8)
+// CHECK-NEXT:   7 | Test11::C RTTI
+struct C : virtual B {
+  virtual void f();
+};
+void C::f() { }
+
+}





More information about the cfe-commits mailing list