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

Mike Stump mrs at apple.com
Thu Jan 21 22:45:05 PST 2010


Author: mrs
Date: Fri Jan 22 00:45:05 2010
New Revision: 94163

URL: http://llvm.org/viewvc/llvm-project?rev=94163&view=rev
Log:
Ensure we output all non-virtual base vtables.  Fixes PR5890.

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=94163&r1=94162&r2=94163&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Fri Jan 22 00:45:05 2010
@@ -431,12 +431,11 @@
         continue;
       const CXXRecordDecl *Base =
         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
-      if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
-        uint64_t o = Offset + Layout.getBaseClassOffset(Base);
-        StartNewTable();
-        GenerateVtableForBase(Base, o, MorallyVirtual, false,
-                              CurrentVBaseOffset, Path);
-      }
+      uint64_t o = Offset + Layout.getBaseClassOffset(Base);
+      StartNewTable();
+      GenerateVtableForBase(Base, o, MorallyVirtual, false,
+                            true, Base == PrimaryBase && !PrimaryBaseWasVirtual,
+                            CurrentVBaseOffset, Path);
     }
     Path->pop_back();
   }
@@ -493,6 +492,7 @@
   void FinishGenerateVtable(const CXXRecordDecl *RD,
                             const ASTRecordLayout &Layout,
                             const CXXRecordDecl *PrimaryBase,
+                            bool ForNPNVBases, bool WasPrimaryBase,
                             bool PrimaryBaseWasVirtual,
                             bool MorallyVirtual, int64_t Offset,
                             bool ForVirtualBase, int64_t CurrentVBaseOffset,
@@ -505,23 +505,27 @@
 
     StartNewTable();
     extra = 0;
-    bool DeferVCalls = MorallyVirtual || ForVirtualBase;
-    int VCallInsertionPoint = VtableComponents.size();
-    if (!DeferVCalls) {
-      insertVCalls(VCallInsertionPoint);
-    } else
-      // FIXME: just for extra, or for all uses of VCalls.size post this?
-      extra = -VCalls.size();
-
-    // Add the offset to top.
-    VtableComponents.push_back(BuildVtable ? wrap(-((Offset-LayoutOffset)/8)) : 0);
+    Index_t AddressPoint = 0;
+    int VCallInsertionPoint = 0;
+    if (!ForNPNVBases || !WasPrimaryBase) {
+      bool DeferVCalls = MorallyVirtual || ForVirtualBase;
+      VCallInsertionPoint = VtableComponents.size();
+      if (!DeferVCalls) {
+        insertVCalls(VCallInsertionPoint);
+      } else
+        // FIXME: just for extra, or for all uses of VCalls.size post this?
+        extra = -VCalls.size();
+
+      // Add the offset to top.
+      VtableComponents.push_back(BuildVtable ? wrap(-((Offset-LayoutOffset)/8)) : 0);
     
-    // Add the RTTI information.
-    VtableComponents.push_back(rtti);
+      // Add the RTTI information.
+      VtableComponents.push_back(rtti);
     
-    Index_t AddressPoint = VtableComponents.size();
+      AddressPoint = VtableComponents.size();
 
-    AppendMethodsToVtable();
+      AppendMethodsToVtable();
+    }
 
     // and then the non-virtual bases.
     NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual,
@@ -539,7 +543,8 @@
       insertVCalls(VCallInsertionPoint);
     }
     
-    AddAddressPoints(RD, Offset, AddressPoint);
+    if (!ForNPNVBases || !WasPrimaryBase)
+      AddAddressPoints(RD, Offset, AddressPoint);
 
     if (alloc) {
       delete Path;
@@ -611,6 +616,8 @@
   void GenerateVtableForBase(const CXXRecordDecl *RD, int64_t Offset = 0,
                              bool MorallyVirtual = false, 
                              bool ForVirtualBase = false,
+                             bool ForNPNVBases = false,
+                             bool WasPrimaryBase = true,
                              int CurrentVBaseOffset = 0,
                              Path_t *Path = 0) {
     if (!RD->isDynamicClass())
@@ -633,15 +640,17 @@
     if (ForVirtualBase)
       extra = VCalls.size();
 
-    VBPrimaries(RD, MorallyVirtual, Offset, !ForVirtualBase, 0, ForVirtualBase,
-                CurrentVBaseOffset, true);
+    if (!ForNPNVBases || !WasPrimaryBase) {
+      VBPrimaries(RD, MorallyVirtual, Offset, !ForVirtualBase, 0,
+                  ForVirtualBase, CurrentVBaseOffset, true);
 
-    if (Path)
-      OverrideMethods(Path, MorallyVirtual, Offset, CurrentVBaseOffset);
+      if (Path)
+        OverrideMethods(Path, MorallyVirtual, Offset, CurrentVBaseOffset);
+    }
 
-    FinishGenerateVtable(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual,
-                         MorallyVirtual, Offset, ForVirtualBase,
-                         CurrentVBaseOffset, Path);
+    FinishGenerateVtable(RD, Layout, PrimaryBase, ForNPNVBases, WasPrimaryBase,
+                         PrimaryBaseWasVirtual, MorallyVirtual, Offset,
+                         ForVirtualBase, CurrentVBaseOffset, Path);
   }
 
   void GenerateVtableForVBases(const CXXRecordDecl *RD,
@@ -668,8 +677,8 @@
         int64_t CurrentVBaseOffset = BaseOffset;
         D1(printf("vtable %s virtual base %s\n",
                   MostDerivedClass->getNameAsCString(), Base->getNameAsCString()));
-        GenerateVtableForBase(Base, BaseOffset, true, true, CurrentVBaseOffset,
-                              Path);
+        GenerateVtableForBase(Base, BaseOffset, true, true, false,
+                              true, CurrentVBaseOffset, Path);
       }
       int64_t BaseOffset;
       if (i->isVirtual())

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

==============================================================================
--- cfe/trunk/test/CodeGenCXX/virt.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/virt.cpp Fri Jan 22 00:45:05 2010
@@ -1077,7 +1077,21 @@
 // CHECK-LP64-NEXT .quad   (__ZTV8test21_D) + 80
 
 
+struct test22_s1 { virtual void dtor() { } }; 
+struct test22_s2 { virtual void dtor() { } }; 
+struct test22_s3 : test22_s1, test22_s2 { virtual void dtor() { } }; 
+struct test22_D : test22_s3 { virtual void dtor() { } }; 
 
+// CHECK-LP64:     __ZTV8test22_D:
+// CHECK-LP64-NEXT:        .quad   0
+// CHECK-LP64-NEXT:        .quad   __ZTI8test22_D
+// CHECK-LP64-NEXT:        .quad   __ZN8test22_D4dtorEv
+// CHECK-LP64-NEXT:        .quad   18446744073709551608
+// CHECK-LP64-NEXT:        .quad   __ZTI8test22_D
+// CHECK-LP64-NEXT:        .quad   __ZThn8_N8test22_D4dtorEv
+
+
+test22_D d22;
 test21_D d21;
 test20_D d20;
 test19_D d19;





More information about the cfe-commits mailing list