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

Anders Carlsson andersca at mac.com
Sat Feb 13 13:07:32 PST 2010


Author: andersca
Date: Sat Feb 13 15:07:32 2010
New Revision: 96119

URL: http://llvm.org/viewvc/llvm-project?rev=96119&view=rev
Log:
Handle virtual bases in return adjustment types.

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=96119&r1=96118&r2=96119&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Sat Feb 13 15:07:32 2010
@@ -124,6 +124,9 @@
   /// BaseOffset - Represents an offset from a derived class to a direct or
   /// indirect base class.
   struct BaseOffset {
+    /// DerivedClass - The derived class.
+    const CXXRecordDecl *DerivedClass;
+    
     /// VirtualBase - If the path from the derived class to the base class
     /// involves a virtual base class, this holds its declaration.
     const CXXRecordDecl *VirtualBase;
@@ -133,9 +136,11 @@
     /// from the derived class to the base class involves a virtual base class.
     uint64_t NonVirtualOffset;
     
-    BaseOffset() : VirtualBase(0), NonVirtualOffset(0) { }
-    BaseOffset(const CXXRecordDecl *VirtualBase, uint64_t NonVirtualOffset)
-      : VirtualBase(VirtualBase), NonVirtualOffset(NonVirtualOffset) { }
+    BaseOffset() : DerivedClass(0), VirtualBase(0), NonVirtualOffset(0) { }
+    BaseOffset(const CXXRecordDecl *DerivedClass,
+               const CXXRecordDecl *VirtualBase, uint64_t NonVirtualOffset)
+      : DerivedClass(DerivedClass), VirtualBase(VirtualBase), 
+      NonVirtualOffset(NonVirtualOffset) { }
 
     bool isEmpty() const { return !NonVirtualOffset && !VirtualBase; }
   };
@@ -333,7 +338,8 @@
   // FIXME: This should probably use CharUnits or something. Maybe we should
   // even change the base offsets in ASTRecordLayout to be specified in 
   // CharUnits.
-  return FinalOverriders::BaseOffset(VirtualBase, NonVirtualOffset / 8);
+  return FinalOverriders::BaseOffset(DerivedRD, VirtualBase, 
+                                     NonVirtualOffset / 8);
 }
 
 static FinalOverriders::BaseOffset
@@ -663,6 +669,9 @@
   typedef llvm::SmallPtrSet<const CXXRecordDecl *, 8> PrimaryBasesSetTy;
 
 private:
+  /// VtableInfo - Global vtable information.
+  CGVtableInfo &VtableInfo;
+  
   /// MostDerivedClass - The most derived class for which we're building this
   /// vtable.
   const CXXRecordDecl *MostDerivedClass;
@@ -685,20 +694,20 @@
     /// nearest virtual base.
     int64_t NonVirtual;
     
-    /// VBaseOffsetIndex - The index relative to the address point of the
-    /// virtual base class offset.
-    int64_t VBaseOffsetIndex;
+    /// VBaseOffsetOffset - The offset, in bytes, relative to the address point 
+    /// of the virtual base class offset.
+    int64_t VBaseOffsetOffset;
     
-    ReturnAdjustment() : NonVirtual(0), VBaseOffsetIndex(0) { }
+    ReturnAdjustment() : NonVirtual(0), VBaseOffsetOffset(0) { }
     
-    bool isEmpty() const { return !NonVirtual && !VBaseOffsetIndex; }
+    bool isEmpty() const { return !NonVirtual && !VBaseOffsetOffset; }
   };
   
   /// ReturnAdjustments - The return adjustments needed in this vtable.
   llvm::SmallVector<std::pair<uint64_t, ReturnAdjustment>, 16> 
     ReturnAdjustments;
 
-  /// ComputeReturnAdjustment - Compute the return adjustment given return
+  /// ComputeReturnAdjustment - Compute the return adjustment given a return
   /// adjustment base offset.
   ReturnAdjustment ComputeReturnAdjustment(FinalOverriders::BaseOffset Offset);
   
@@ -715,8 +724,8 @@
   void layoutSimpleVtable(BaseSubobject Base);
   
 public:
-  VtableBuilder(const CXXRecordDecl *MostDerivedClass)
-    : MostDerivedClass(MostDerivedClass), 
+  VtableBuilder(CGVtableInfo &VtableInfo, const CXXRecordDecl *MostDerivedClass)
+    : VtableInfo(VtableInfo), MostDerivedClass(MostDerivedClass), 
     Context(MostDerivedClass->getASTContext()), Overriders(MostDerivedClass) { 
 
     layoutSimpleVtable(BaseSubobject(MostDerivedClass, 0));
@@ -751,7 +760,16 @@
   ReturnAdjustment Adjustment;
   
   if (!Offset.isEmpty()) {
-    assert(!Offset.VirtualBase && "FIXME: Handle virtual bases!");
+    if (Offset.VirtualBase) {
+      // Get the virtual base offset offset.
+      Adjustment.VBaseOffsetOffset = 
+        VtableInfo.getVirtualBaseOffsetIndex(Offset.DerivedClass,
+                                             Offset.VirtualBase);
+      // FIXME: Once the assert in getVirtualBaseOffsetIndex is back again,
+      // we can get rid of this assert.
+      assert(Adjustment.VBaseOffsetOffset != 0 && 
+             "Invalid base offset offset!");
+    }
 
     Adjustment.NonVirtual = Offset.NonVirtualOffset;
   }
@@ -967,10 +985,12 @@
         const ReturnAdjustment Adjustment = 
           ReturnAdjustments[NextReturnAdjustmentIndex].second;
         
-        assert(!Adjustment.VBaseOffsetIndex && "FIXME: Handle virtual bases!");
-        
         Out << "\n       [return adjustment: ";
-        Out << Adjustment.NonVirtual << " non-virtual]";
+        Out << Adjustment.NonVirtual << " non-virtual";
+        
+        if (Adjustment.VBaseOffsetOffset)
+          Out << ", " << Adjustment.VBaseOffsetOffset << " vbase offset offset";
+        Out << ']';
 
         NextReturnAdjustmentIndex++;
       }
@@ -2291,7 +2311,7 @@
                              const CXXRecordDecl *RD, uint64_t Offset,
                              AddressPointsMapTy& AddressPoints) {
   if (GenerateDefinition && CGM.getLangOptions().DumpVtableLayouts) {
-    VtableBuilder Builder(RD);
+    VtableBuilder Builder(*this, RD);
     
     Builder.dumpLayout(llvm::errs());
   }

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

==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-layout.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-layout.cpp Sat Feb 13 15:07:32 2010
@@ -120,7 +120,7 @@
 
 namespace Test4 {
 
-// Test simple non-virtual result adjustments.
+// Test non-virtual result adjustments.
 
 struct R1 { int r1; };
 struct R2 { int r2; };
@@ -142,9 +142,46 @@
 struct B : A {
   virtual R3 *f();
 };
-
 R3 *B::f() { return 0; }
-  
+
+// Test virtual result adjustments.
+struct V1 { int v1; };
+struct V2 : virtual V1 { int v1; };
+
+struct C {
+  virtual V1 *f(); 
+};
+
+// CHECK:     Vtable for 'Test4::D' (4 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test4::D RTTI
+// CHECK-NEXT:       -- (Test4::C, 0) vtable address --
+// CHECK-NEXT:       -- (Test4::D, 0) vtable address --
+// CHECK-NEXT:   2 | Test4::V2 *Test4::D::f()
+// CHECK-NEXT:       [return adjustment: 0 non-virtual, -24 vbase offset offset]
+// CHECK-NEXT:   3 | Test4::V2 *Test4::D::f()
+struct D : C {
+  virtual V2 *f();
+};
+V2 *D::f() { return 0; };
+
+// Virtual result adjustments with an additional non-virtual adjustment.
+struct V3 : virtual R3 { int r3; };
+
+// CHECK:     Vtable for 'Test4::E' (4 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test4::E RTTI
+// CHECK-NEXT:       -- (Test4::A, 0) vtable address --
+// CHECK-NEXT:       -- (Test4::E, 0) vtable address --
+// CHECK-NEXT:   2 | Test4::V3 *Test4::E::f()
+// CHECK-NEXT:       [return adjustment: 4 non-virtual, -24 vbase offset offset]
+// CHECK-NEXT:   3 | Test4::V3 *Test4::E::f()
+
+struct E : A {
+  virtual V3 *f();
+};
+V3 *E::f() { return 0;}
+
 }
 
 // For now, just verify this doesn't crash.





More information about the cfe-commits mailing list