[cfe-commits] r93709 - in /cfe/trunk: lib/CodeGen/CGVtable.cpp test/CodeGenCXX/virt.cpp test/CodeGenCXX/vtt-layout.cpp

Anders Carlsson andersca at mac.com
Sun Jan 17 20:25:19 PST 2010


Author: andersca
Date: Sun Jan 17 22:25:18 2010
New Revision: 93709

URL: http://llvm.org/viewvc/llvm-project?rev=93709&view=rev
Log:
Fix a bunch of VTT layout bugs, add simple tests for VTT layout.

Added:
    cfe/trunk/test/CodeGenCXX/vtt-layout.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGVtable.cpp
    cfe/trunk/test/CodeGenCXX/virt.cpp

Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=93709&r1=93708&r2=93709&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Sun Jan 17 22:25:18 2010
@@ -1314,6 +1314,17 @@
            e = RD->bases_end(); i != e; ++i) {
       const CXXRecordDecl *Base =
         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+      
+      // Itanium C++ ABI 2.6.2:
+      //   Secondary virtual pointers are present for all bases with either
+      //   virtual bases or virtual function declarations overridden along a 
+      //   virtual path.
+      //
+      // If the base class is not dynamic, we don't want to add it, nor any
+      // of its base classes.
+      if (!Base->isDynamicClass())
+        continue;
+
       const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
       const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
       const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
@@ -1330,10 +1341,9 @@
       const CXXRecordDecl *subVtblClass = VtblClass;
       if ((Base->getNumVBases() || BaseMorallyVirtual)
           && !NonVirtualPrimaryBase) {
-        // FIXME: Slightly too many of these for __ZTT8test8_B2
         llvm::Constant *init;
-        if (BaseMorallyVirtual)
-          init = BuildVtablePtr(vtbl, VtblClass, RD, Offset);
+        if (BaseMorallyVirtual || VtblClass == Class)
+          init = BuildVtablePtr(vtbl, VtblClass, Base, BaseOffset);
         else {
           init = getCtorVtable(BaseSubobject(Base, BaseOffset));
           
@@ -1351,7 +1361,10 @@
   /// BuiltVTT - Add the VTT to Inits.  Offset is the offset in bits to the
   /// currnet object we're working on.
   void BuildVTT(const CXXRecordDecl *RD, uint64_t Offset, bool MorallyVirtual) {
-    if (RD->getNumVBases() == 0 && !MorallyVirtual)
+    // Itanium C++ ABI 2.6.2:
+    //   An array of virtual table addresses, called the VTT, is declared for 
+    //   each class type that has indirect or direct virtual base classes.
+    if (RD->getNumVBases() == 0)
       return;
 
     llvm::Constant *Vtable;

Modified: cfe/trunk/test/CodeGenCXX/virt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/virt.cpp?rev=93709&r1=93708&r2=93709&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/virt.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/virt.cpp Sun Jan 17 22:25:18 2010
@@ -375,13 +375,13 @@
 // CHECK-LP64-NEXT: .quad   (__ZTV7test8_D) + 32
 // CHECK-LP64-NEXT: .quad   (__ZTC7test8_D8_8test8_B2) + 32
 // CHECK-LP64-NEXT: .quad   (__ZTC7test8_D8_9test8_B2a) + 32
-// CHECK-LP64-NEXT  .quad   (__ZTC7test8_D8_9test8_B2a) + 64
-// CHECK-LP64-NEXT  .quad   (__ZTC7test8_D8_9test8_B2a) + 96
-// CHECK-LP64-NEXT  .quad   (__ZTC7test8_D8_8test8_B2) + 72
-// CHECK-LP64-NEXT  .quad   (__ZTC7test8_D8_8test8_B2) + 104
-// CHECK-LP64-NEXT  .quad   (__ZTV7test8_D) + 72
-// CHECK-LP64: .quad   (__ZTV7test8_D) + 160
-// CHECK-LP64: .quad   (__ZTV7test8_D) + 192
+// CHECK-LP64-NEXT: .quad   (__ZTC7test8_D8_9test8_B2a) + 64
+// CHECK-LP64-NEXT: .quad   (__ZTC7test8_D8_9test8_B2a) + 96
+// CHECK-LP64-NEXT: .quad   (__ZTC7test8_D8_8test8_B2) + 72
+// CHECK-LP64-NEXT: .quad   (__ZTC7test8_D8_8test8_B2) + 104
+// CHECK-LP64-NEXT: .quad   (__ZTV7test8_D) + 72
+// CHECK-LP64-NEXT: .quad   (__ZTV7test8_D) + 160
+// CHECK-LP64-NEXT: .quad   (__ZTV7test8_D) + 192
 
 
 struct test9_B3 { virtual void funcB3(); int i; };

Added: cfe/trunk/test/CodeGenCXX/vtt-layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtt-layout.cpp?rev=93709&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtt-layout.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/vtt-layout.cpp Sun Jan 17 22:25:18 2010
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+namespace Test1 {
+struct A { };
+
+struct B : virtual A { 
+  virtual void f();
+};
+
+void B::f() { } 
+}
+
+// Test1::B should just have a single entry in its VTT, which points to the vtable.
+// CHECK: @_ZTTN5Test11BE = constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTVN5Test11BE, i64 0, i64 3) to i8*)]
+
+namespace Test2 {
+  struct A { };
+
+  struct B : A { virtual void f(); };
+  struct C : virtual B { };
+
+  C c;
+}
+
+// Check that we don't add a secondary virtual pointer for Test2::A, since Test2::A doesn't have any virtual member functions or bases.
+// CHECK: @_ZTTN5Test21CE = weak_odr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*)] ; <[2 x i8*]*> [#uses=0]





More information about the cfe-commits mailing list