[cfe-commits] r97361 - in /cfe/trunk: clang.xcodeproj/project.pbxproj lib/CodeGen/CGVtable.cpp test/CodeGenCXX/vtable-layout.cpp

Anders Carlsson andersca at mac.com
Sat Feb 27 17:43:58 PST 2010


Author: andersca
Date: Sat Feb 27 19:43:58 2010
New Revision: 97361

URL: http://llvm.org/viewvc/llvm-project?rev=97361&view=rev
Log:
More improvements to construction vtables; we know handle vbase offsets correctly (I hope).

Modified:
    cfe/trunk/clang.xcodeproj/project.pbxproj
    cfe/trunk/lib/CodeGen/CGVtable.cpp
    cfe/trunk/test/CodeGenCXX/vtable-layout.cpp

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=97361&r1=97360&r2=97361&view=diff
==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Sat Feb 27 19:43:58 2010
@@ -420,7 +420,7 @@
 		1A81AA5D108278A20094E50B /* CGVtable.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGVtable.h; path = lib/CodeGen/CGVtable.h; sourceTree = "<group>"; tabWidth = 2; };
 		1A869A6E0BA2164C008DA07A /* LiteralSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiteralSupport.h; sourceTree = "<group>"; };
 		1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = "<group>"; };
-		1A97825A1108BA18002B98FC /* CGVTT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGVTT.cpp; path = lib/CodeGen/CGVTT.cpp; sourceTree = "<group>"; };
+		1A97825A1108BA18002B98FC /* CGVTT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGVTT.cpp; path = lib/CodeGen/CGVTT.cpp; sourceTree = "<group>"; tabWidth = 2; };
 		1A986AB610D0746D00A8EA9E /* CGDeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGDeclCXX.cpp; path = lib/CodeGen/CGDeclCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
 		1AA1D91610125DE30078DEBC /* RecordLayoutBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = RecordLayoutBuilder.cpp; path = lib/AST/RecordLayoutBuilder.cpp; sourceTree = "<group>"; tabWidth = 2; };
 		1AA1D91710125DE30078DEBC /* RecordLayoutBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = RecordLayoutBuilder.h; path = lib/AST/RecordLayoutBuilder.h; sourceTree = "<group>"; tabWidth = 2; };

Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=97361&r1=97360&r2=97361&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Sat Feb 27 19:43:58 2010
@@ -824,14 +824,10 @@
 
 /// VCallAndVBaseOffsetBuilder - Class for building vcall and vbase offsets.
 class VCallAndVBaseOffsetBuilder {
-  /// MostDerivedClass - The most derived class for which we're building this
-  /// vtable.
+  /// MostDerivedClass - The most derived class for which we're building vcall
+  /// and vbase offsets.
   const CXXRecordDecl *MostDerivedClass;
   
-  /// MostDerivedClassOffset - If we're building a construction vtable, this
-  /// holds the offset from the layout class to the most derived class.
-  const uint64_t MostDerivedClassOffset;
-  
   /// LayoutClass - The class we're using for layout information. Will be 
   /// different than the most derived class if we're building a construction
   /// vtable.
@@ -867,16 +863,15 @@
   
 public:
   VCallAndVBaseOffsetBuilder(const CXXRecordDecl *MostDerivedClass,
-                             uint64_t MostDerivedClassOffset,
                              const CXXRecordDecl *LayoutClass,
                              const FinalOverriders *Overriders,
-                             BaseSubobject Base, bool BaseIsVirtual)
-    : MostDerivedClass(MostDerivedClass),
-    MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass), 
+                             BaseSubobject Base, bool BaseIsVirtual,
+                             uint64_t OffsetInLayoutClass)
+    : MostDerivedClass(MostDerivedClass), LayoutClass(LayoutClass), 
     Context(MostDerivedClass->getASTContext()), Overriders(Overriders) {
       
     // Add vcall and vbase offsets.
-    AddVCallAndVBaseOffsets(Base, BaseIsVirtual, Base.getBaseOffset());
+    AddVCallAndVBaseOffsets(Base, BaseIsVirtual, OffsetInLayoutClass);
   }
   
   /// Methods for iterating over the components.
@@ -1045,9 +1040,6 @@
       uint64_t Offset = 
         OffsetToTop + LayoutClassLayout.getVBaseClassOffset(BaseDecl) / 8;
     
-      // The offset should be relative to the most derived class offset.
-      Offset -= MostDerivedClassOffset / 8;
-
       Components.push_back(VtableComponent::MakeVBaseOffset(Offset));
     }
     
@@ -1222,14 +1214,15 @@
   // secondary vtables and any vtables for virtual bases.
   void LayoutVtable();
 
-  /// LayoutPrimaryAndAndSecondaryVtables - Layout the primary vtable for the
+  /// LayoutPrimaryAndSecondaryVtables - Layout the primary vtable for the
   /// given base subobject, as well as all its secondary vtables.
-  void LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base, 
-                                           bool BaseIsVirtual);
+  void LayoutPrimaryAndSecondaryVtables(BaseSubobject Base,
+                                        bool BaseIsVirtual,
+                                        uint64_t OffsetInLayoutClass);
   
   /// LayoutSecondaryVtables - Layout the secondary vtables for the given base
   /// subobject.
-  void LayoutSecondaryVtables(BaseSubobject Base);
+  void LayoutSecondaryVtables(BaseSubobject Base, uint64_t OffsetInLayoutClass);
 
   /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this
   /// class hierarchy.
@@ -1434,10 +1427,11 @@
       if (VCallOffsets.empty()) {
         // We don't have vcall offsets for this virtual base, go ahead and
         // build them.
-        VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, 0,
-                                           MostDerivedClass, 0,
-                                           BaseSubobject(Offset.VirtualBase, 0),
-                                           /*BaseIsVirtual=*/true);
+        VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass,
+                                           /*FinalOverriders=*/0,
+                                           BaseSubobject(Offset.VirtualBase, 0),                                           
+                                           /*BaseIsVirtual=*/true,
+                                           /*OffsetInLayoutClass=*/0);
         
         VCallOffsets = Builder.getVCallOffsets();
       }
@@ -1683,8 +1677,9 @@
 }
 
 void VtableBuilder::LayoutVtable() {
-  LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(MostDerivedClass, 0),
-                                      MostDerivedClassIsVirtual);
+  LayoutPrimaryAndSecondaryVtables(BaseSubobject(MostDerivedClass, 0),
+                                   MostDerivedClassIsVirtual,
+                                   MostDerivedClassOffset);
   
   VisitedVirtualBasesSetTy VBases;
   
@@ -1695,14 +1690,15 @@
   LayoutVtablesForVirtualBases(MostDerivedClass, VBases);
 }
   
-void VtableBuilder::LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base,
-                                                        bool BaseIsVirtual) {
+void
+VtableBuilder::LayoutPrimaryAndSecondaryVtables(BaseSubobject Base,
+                                                bool BaseIsVirtual,
+                                                uint64_t OffsetInLayoutClass) {
   assert(Base.getBase()->isDynamicClass() && "class does not have a vtable!");
 
   // Add vcall and vbase offsets for this vtable.
-  VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClassOffset,
-                                     LayoutClass, &Overriders,
-                                     Base, BaseIsVirtual);
+  VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, LayoutClass, &Overriders,
+                                     Base, BaseIsVirtual, OffsetInLayoutClass);
   Components.append(Builder.components_begin(), Builder.components_end());
   
   // Check if we need to add these vcall offsets.
@@ -1714,9 +1710,9 @@
   }
 
   // Add the offset to top.
-  // FIXME: This is not going to be right for construction vtables.
   // FIXME: We should not use / 8 here.
-  int64_t OffsetToTop = -(int64_t)Base.getBaseOffset() / 8;
+  int64_t OffsetToTop = -(int64_t)(OffsetInLayoutClass -
+                                   MostDerivedClassOffset) / 8;
   Components.push_back(VtableComponent::MakeOffsetToTop(OffsetToTop));
   
   // Next, add the RTTI.
@@ -1732,7 +1728,9 @@
   ComputeThisAdjustments();
 
   // Record the address point.
-  AddressPoints.insert(std::make_pair(Base, AddressPoint));
+  AddressPoints.insert(std::make_pair(BaseSubobject(Base.getBase(),
+                                                    OffsetInLayoutClass),
+                                      AddressPoint));
   
   // Record the address points for all primary bases.
   for (PrimaryBasesSetVectorTy::const_iterator I = PrimaryBases.begin(),
@@ -1741,15 +1739,16 @@
     
     // We know that all the primary bases have the same offset as the base
     // subobject.
-    BaseSubobject PrimaryBase(BaseDecl, Base.getBaseOffset());
+    BaseSubobject PrimaryBase(BaseDecl, OffsetInLayoutClass);
     AddressPoints.insert(std::make_pair(PrimaryBase, AddressPoint));
   }
 
   // Layout secondary vtables.
-  LayoutSecondaryVtables(Base);
+  LayoutSecondaryVtables(Base, OffsetInLayoutClass);
 }
 
-void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base) {
+void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base,
+                                           uint64_t OffsetInLayoutClass) {
   // Itanium C++ ABI 2.5.2:
   //   Following the primary virtual table of a derived class are secondary 
   //   virtual tables for each of its proper base classes, except any primary
@@ -1773,19 +1772,23 @@
       continue;
 
     // Get the base offset of this base.
-    uint64_t BaseOffset = Base.getBaseOffset() + 
-      Layout.getBaseClassOffset(BaseDecl);
+    uint64_t RelativeBaseOffset = Layout.getBaseClassOffset(BaseDecl);
+    uint64_t BaseOffset = Base.getBaseOffset() + RelativeBaseOffset;
+    
+    uint64_t BaseOffsetInLayoutClass = OffsetInLayoutClass + RelativeBaseOffset;
     
     // Don't emit a secondary vtable for a primary base. We might however want 
     // to emit secondary vtables for other bases of this base.
     if (BaseDecl == PrimaryBase) {
-      LayoutSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset));
+      LayoutSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset),
+                             BaseOffsetInLayoutClass);
       continue;
     }
 
     // Layout the primary vtable (and any secondary vtables) for this base.
-    LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset),
-                                        /*BaseIsVirtual=*/false);
+    LayoutPrimaryAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset),
+                                     /*BaseIsVirtual=*/false,
+                                     BaseOffsetInLayoutClass);
   }
 }
 
@@ -1835,8 +1838,14 @@
       uint64_t BaseOffset = 
         MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
       
-      LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset),
-                                          /*BaseIsVirtual=*/true);
+      const ASTRecordLayout &LayoutClassLayout =
+        Context.getASTRecordLayout(LayoutClass);
+      uint64_t BaseOffsetInLayoutClass = 
+        LayoutClassLayout.getVBaseClassOffset(BaseDecl);
+
+      LayoutPrimaryAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset),
+                                       /*BaseIsVirtual=*/true,
+                                       BaseOffsetInLayoutClass);
     }
     
     // We only need to check the base for virtual base vtables if it actually

Modified: cfe/trunk/test/CodeGenCXX/vtable-layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-layout.cpp?rev=97361&r1=97360&r2=97361&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-layout.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-layout.cpp Sat Feb 27 19:43:58 2010
@@ -855,6 +855,7 @@
 // CHECK-NEXT:    5 | vbase_offset (-4)
 // CHECK-NEXT:    6 | offset_to_top (-16)
 // CHECK-NEXT:    7 | Test22::C RTTI
+// CHECK-NEXT:        -- (Test22::V2, 16) vtable address --
 
 // CHECK:      Construction vtable for ('Test22::V2', 16) in 'Test22::C' (3 entries).
 // CHECK-NEXT:    0 | vbase_offset (-4)
@@ -868,3 +869,55 @@
 void C::f() { } 
 
 }
+
+namespace Test23 {
+
+struct A {
+  int a;
+};
+
+struct B : virtual A {
+  int b;
+};
+
+struct C : A, virtual B {
+  int c;
+};
+
+// CHECK:      Vtable for 'Test23::D' (7 entries).
+// CHECK-NEXT:    0 | vbase_offset (20)
+// CHECK-NEXT:    1 | vbase_offset (24)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test23::D RTTI
+// CHECK-NEXT:        -- (Test23::C, 0) vtable address --
+// CHECK-NEXT:        -- (Test23::D, 0) vtable address --
+// CHECK-NEXT:    4 | vbase_offset (-4)
+// CHECK-NEXT:    5 | offset_to_top (-24)
+// CHECK-NEXT:    6 | Test23::D RTTI
+// CHECK-NEXT:        -- (Test23::B, 24) vtable address --
+
+// CHECK:      Construction vtable for ('Test23::C', 0) in 'Test23::D' (7 entries).
+// CHECK-NEXT:    0 | vbase_offset (20)
+// CHECK-NEXT:    1 | vbase_offset (24)
+// CHECK-NEXT:    2 | offset_to_top (0)
+// CHECK-NEXT:    3 | Test23::C RTTI
+// CHECK-NEXT:        -- (Test23::C, 0) vtable address --
+// CHECK-NEXT:    4 | vbase_offset (-4)
+// CHECK-NEXT:    5 | offset_to_top (-24)
+// CHECK-NEXT:    6 | Test23::C RTTI
+// CHECK-NEXT:        -- (Test23::B, 24) vtable address --
+
+// CHECK:      Construction vtable for ('Test23::B', 24) in 'Test23::D' (3 entries).
+// CHECK-NEXT:    0 | vbase_offset (-4)
+// CHECK-NEXT:    1 | offset_to_top (0)
+// CHECK-NEXT:    2 | Test23::B RTTI
+// CHECK-NEXT:        -- (Test23::B, 24) vtable address --
+
+struct D : virtual A, virtual B, C {
+  int d;
+
+  void f();
+};
+void D::f() { } 
+
+}





More information about the cfe-commits mailing list