[cfe-commits] r98245 - /cfe/trunk/lib/CodeGen/CGVtable.cpp

Anders Carlsson andersca at mac.com
Wed Mar 10 22:43:12 PST 2010


Author: andersca
Date: Thu Mar 11 00:43:12 2010
New Revision: 98245

URL: http://llvm.org/viewvc/llvm-project?rev=98245&view=rev
Log:
Keep track of, and dump, vbase offset offsets.

Modified:
    cfe/trunk/lib/CodeGen/CGVtable.cpp

Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=98245&r1=98244&r2=98245&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Thu Mar 11 00:43:12 2010
@@ -856,6 +856,13 @@
   /// VCallOffsets - Keeps track of vcall offsets.
   VCallOffsetMap VCallOffsets;
 
+  typedef llvm::DenseMap<const CXXRecordDecl *, int64_t> 
+    VBaseOffsetOffsetsMapTy;
+
+  /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets,
+  /// relative to the address point.
+  VBaseOffsetOffsetsMapTy VBaseOffsetOffsets;
+  
   /// FinalOverriders - The final overriders of the most derived class.
   /// (Can be null when we're not building a vtable of the most derived class).
   const FinalOverriders *Overriders;
@@ -871,6 +878,10 @@
   /// AddVBaseOffsets - Add vbase offsets for the given class.
   void AddVBaseOffsets(const CXXRecordDecl *Base, uint64_t OffsetInLayoutClass);
   
+  /// getCurrentOffsetOffset - Get the current vcall or vbase offset offset in
+  /// bytes, relative to the vtable address point.
+  int64_t getCurrentOffsetOffset() const;
+  
 public:
   VCallAndVBaseOffsetBuilder(const CXXRecordDecl *MostDerivedClass,
                              const CXXRecordDecl *LayoutClass,
@@ -890,6 +901,9 @@
   const_iterator components_end() const { return Components.rend(); }
   
   const VCallOffsetMap& getVCallOffsets() const { return VCallOffsets; }
+  const VBaseOffsetOffsetsMapTy getVBaseOffsetOffsets() const {
+    return VBaseOffsetOffsets;
+  }
 };
   
 void 
@@ -940,6 +954,20 @@
     AddVCallOffsets(Base, RealBaseOffset);
 }
 
+int64_t VCallAndVBaseOffsetBuilder::getCurrentOffsetOffset() const {
+  // OffsetIndex is the index of this vcall or vbase offset, relative to the 
+  // vtable address point. (We subtract 3 to account for the information just
+  // above the address point, the RTTI info, the offset to top, and the
+  // vcall offset itself).
+  int64_t OffsetIndex = -(int64_t)(3 + Components.size());
+    
+  // FIXME: We shouldn't use / 8 here.
+  int64_t OffsetOffset = OffsetIndex * 
+    (int64_t)Context.Target.getPointerWidth(0) / 8;
+
+  return OffsetOffset;
+}
+
 void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, 
                                                  uint64_t VBaseOffset) {
   const CXXRecordDecl *RD = Base.getBase();
@@ -980,15 +1008,7 @@
     if (!MD->isVirtual())
       continue;
 
-    // OffsetIndex is the index of this vcall offset, relative to the vtable
-    // address point. (We subtract 3 to account for the information just
-    // above the address point, the RTTI info, the offset to top, and the
-    // vcall offset itself).
-    int64_t OffsetIndex = -(int64_t)(3 + Components.size());
-    
-    // FIXME: We shouldn't use / 8 here.
-    int64_t OffsetOffset = OffsetIndex * 
-      (int64_t)Context.Target.getPointerWidth(0) / 8;
+    int64_t OffsetOffset = getCurrentOffsetOffset();
     
     // Don't add a vcall offset if we already have one for this member function
     // signature.
@@ -1048,10 +1068,17 @@
       int64_t Offset = 
         (int64_t)(LayoutClassLayout.getVBaseClassOffset(BaseDecl) - 
                   OffsetInLayoutClass) / 8;
-    
+
+      // Add the vbase offset offset.
+      assert(!VBaseOffsetOffsets.count(BaseDecl) &&
+             "vbase offset offset already exists!");
+
+      int64_t VBaseOffsetOffset = getCurrentOffsetOffset();
+      VBaseOffsetOffsets.insert(std::make_pair(BaseDecl, VBaseOffsetOffset));
+
       Components.push_back(VtableComponent::MakeVBaseOffset(Offset));
     }
-    
+
     // Check the base class looking for more vbase offsets.
     AddVBaseOffsets(BaseDecl, OffsetInLayoutClass);
   }
@@ -1096,6 +1123,13 @@
   /// bases in this vtable.
   llvm::DenseMap<const CXXRecordDecl *, VCallOffsetMap> VCallOffsetsForVBases;
 
+  typedef llvm::DenseMap<const CXXRecordDecl *, int64_t> 
+    VBaseOffsetOffsetsMapTy;
+  
+  /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets for
+  /// the most derived class.
+  VBaseOffsetOffsetsMapTy VBaseOffsetOffsets;
+  
   /// Components - The components of the vtable being built.
   llvm::SmallVector<VtableComponent, 64> Components;
 
@@ -1751,6 +1785,11 @@
       VCallOffsets = Builder.getVCallOffsets();
   }
 
+  // If we're laying out the most derived class we want to keep track of the
+  // virtual base class offset offsets.
+  if (Base.getBase() == MostDerivedClass)
+    VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets();
+
   // Add the offset to top.
   // FIXME: We should not use / 8 here.
   int64_t OffsetToTop = -(int64_t)(OffsetInLayoutClass -
@@ -1949,15 +1988,15 @@
 /// dumpLayout - Dump the vtable layout.
 void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) {
 
-  if (MostDerivedClass == LayoutClass) {
-    Out << "Vtable for '";
-    Out << MostDerivedClass->getQualifiedNameAsString();
-  } else {
+  if (isBuildingConstructorVtable()) {
     Out << "Construction vtable for ('";
     Out << MostDerivedClass->getQualifiedNameAsString() << "', ";
     // FIXME: Don't use / 8 .
     Out << MostDerivedClassOffset / 8 << ") in '";
     Out << LayoutClass->getQualifiedNameAsString();
+  } else {
+    Out << "Vtable for '";
+    Out << MostDerivedClass->getQualifiedNameAsString();
   }
   Out << "' (" << Components.size() << " entries).\n";
 
@@ -2137,6 +2176,29 @@
   }
 
   Out << '\n';
+  
+  if (!isBuildingConstructorVtable()) {
+    Out << "Virtual base offset offsets for '";
+    Out << MostDerivedClass->getQualifiedNameAsString() << "'.\n";
+    
+    // We store the virtual base class names and their offsets in a map to get
+    // a stable order.
+    std::map<std::string, int64_t> ClassNamesAndOffsets;
+
+    for (VBaseOffsetOffsetsMapTy::const_iterator I = VBaseOffsetOffsets.begin(),
+         E = VBaseOffsetOffsets.end(); I != E; ++I) {
+      std::string ClassName = I->first->getQualifiedNameAsString();
+      int64_t OffsetOffset = I->second;
+      ClassNamesAndOffsets.insert(std::make_pair(ClassName, OffsetOffset));
+    }
+
+    for (std::map<std::string, int64_t>::const_iterator I =
+         ClassNamesAndOffsets.begin(), E = ClassNamesAndOffsets.end(); 
+         I != E; ++I)
+      Out << "   " << I->first << " | " << I->second << '\n';
+
+    Out << "\n";
+  }
 }
   
 }





More information about the cfe-commits mailing list