[cfe-commits] r78971 - in /cfe/trunk: include/clang/AST/RecordLayout.h lib/AST/RecordLayoutBuilder.cpp lib/AST/RecordLayoutBuilder.h lib/CodeGen/CGCXX.cpp

Mike Stump mrs at apple.com
Thu Aug 13 18:44:03 PDT 2009


Author: mrs
Date: Thu Aug 13 20:44:03 2009
New Revision: 78971

URL: http://llvm.org/viewvc/llvm-project?rev=78971&view=rev
Log:
Deconflate virtual base offsets from non-virtual base offsets.
Deconflate a virtual base primary from a non-virtual base.

Modified:
    cfe/trunk/include/clang/AST/RecordLayout.h
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.h
    cfe/trunk/lib/CodeGen/CGCXX.cpp

Modified: cfe/trunk/include/clang/AST/RecordLayout.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecordLayout.h?rev=78971&r1=78970&r2=78971&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/RecordLayout.h (original)
+++ cfe/trunk/include/clang/AST/RecordLayout.h Thu Aug 13 20:44:03 2009
@@ -60,10 +60,12 @@
     bool PrimaryBaseWasVirtual;
 
     /// BaseOffsets - Contains a map from base classes to their offset.
-    /// FIXME: Does it make sense to store offsets for virtual base classes
-    /// here?
     /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
     llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsets;
+
+    /// VBaseOffsets - Contains a map from vbase classes to their offset.
+    /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
+    llvm::DenseMap<const CXXRecordDecl *, uint64_t> VBaseOffsets;
   };
   
   /// CXXInfo - If the record layout is for a C++ record, this will have 
@@ -90,7 +92,8 @@
                   uint64_t nonvirtualsize, unsigned nonvirtualalign,
                   const CXXRecordDecl *PB, bool PBVirtual,
                   const CXXRecordDecl **bases, const uint64_t *baseoffsets,
-                  unsigned basecount)
+                  unsigned basecount, const CXXRecordDecl **vbases,
+                  const uint64_t *vbaseoffsets,unsigned vbasecount)
   : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
   FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) {
     if (FieldCount > 0)  {
@@ -105,6 +108,8 @@
     CXXInfo->NonVirtualAlign = nonvirtualalign;
     for (unsigned i = 0; i != basecount; ++i)
       CXXInfo->BaseOffsets[bases[i]] = baseoffsets[i];
+    for (unsigned i = 0; i != vbasecount; ++i)
+      CXXInfo->VBaseOffsets[vbases[i]] = vbaseoffsets[i];
   }
   
   ~ASTRecordLayout() {
@@ -174,6 +179,14 @@
     
     return CXXInfo->BaseOffsets[Base];
   }
+
+  /// getVBaseClassOffset - Get the offset, in bits, for the given base class.
+  uint64_t getVBaseClassOffset(const CXXRecordDecl *VBase) const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
+    
+    return CXXInfo->VBaseOffsets[VBase];
+  }
 };
 
 }  // end namespace clang

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=78971&r1=78970&r2=78971&view=diff

==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Thu Aug 13 20:44:03 2009
@@ -51,8 +51,8 @@
       const CXXRecordDecl *Base = 
         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
       // Skip the PrimaryBase here, as it is laid down first.
-      if (Base != PrimaryBase)
-        LayoutBaseNonVirtually(Base);
+      if (Base != PrimaryBase || PrimaryBaseWasVirtual)
+        LayoutBaseNonVirtually(Base, false);
     }
   }
 }
@@ -77,9 +77,10 @@
   const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
   const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
   const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
-  if (PrimaryBaseWasVirtual) {
+
+  if (PrimaryBaseWasVirtual)
     IndirectPrimary.insert(PrimaryBase);
-  }
+
   for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
        e = RD->bases_end(); i != e; ++i) {
     const CXXRecordDecl *Base = 
@@ -163,7 +164,7 @@
 }
 
 void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
-  LayoutBaseNonVirtually(RD);
+  LayoutBaseNonVirtually(RD, true);
 }
 
 void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
@@ -182,7 +183,8 @@
   }
 }
 
-void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD) {
+void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD,
+  bool IsVirtualBase) {
   const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD);
     assert(BaseInfo.getDataSize() > 0 && 
            "FIXME: Handle empty classes.");
@@ -193,9 +195,14 @@
   // Round up the current record size to the base's alignment boundary.
   Size = (Size + (BaseAlign-1)) & ~(BaseAlign-1);
 
-  // Add base class offsets.
-  Bases.push_back(RD);
-  BaseOffsets.push_back(Size);
+    // Add base class offsets.
+  if (IsVirtualBase) {
+    VBases.push_back(RD);
+    VBaseOffsets.push_back(Size);
+  } else {
+    Bases.push_back(RD);
+    BaseOffsets.push_back(Size);
+  }
 
   // Reserve space for this base.
   Size += BaseSize;
@@ -229,7 +236,7 @@
     if (PrimaryBase) {
       if (PrimaryBaseWasVirtual)
         IndirectPrimary.insert(PrimaryBase);
-      LayoutBaseNonVirtually(PrimaryBase);
+      LayoutBaseNonVirtually(PrimaryBase, PrimaryBaseWasVirtual);
     }
     LayoutNonVirtualBases(RD);
   }
@@ -406,6 +413,8 @@
   
   assert(Builder.Bases.size() == Builder.BaseOffsets.size() && 
          "Base offsets vector must be same size as bases vector!");
+  assert(Builder.VBases.size() == Builder.VBaseOffsets.size() && 
+         "Base offsets vector must be same size as bases vector!");
 
   // FIXME: This should be done in FinalizeLayout.
   uint64_t DataSize = 
@@ -422,7 +431,10 @@
                              Builder.PrimaryBaseWasVirtual,
                              Builder.Bases.data(),
                              Builder.BaseOffsets.data(),
-                             Builder.Bases.size());
+                             Builder.Bases.size(),
+                             Builder.VBases.data(),
+                             Builder.VBaseOffsets.data(),
+                             Builder.VBases.size());
 }
 
 const ASTRecordLayout *

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=78971&r1=78970&r2=78971&view=diff

==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Thu Aug 13 20:44:03 2009
@@ -42,6 +42,9 @@
 
   llvm::SmallVector<const CXXRecordDecl *, 4> Bases;
   llvm::SmallVector<uint64_t, 4> BaseOffsets;
+
+  llvm::SmallVector<const CXXRecordDecl *, 4> VBases;
+  llvm::SmallVector<uint64_t, 4> VBaseOffsets;
   
   ASTRecordLayoutBuilder(ASTContext &Ctx);
   
@@ -68,7 +71,7 @@
   void LayoutVtable(const CXXRecordDecl *RD,
                      llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
   void LayoutNonVirtualBases(const CXXRecordDecl *RD);
-  void LayoutBaseNonVirtually(const CXXRecordDecl *RD);
+  void LayoutBaseNonVirtually(const CXXRecordDecl *RD, bool IsVBase);
   void LayoutVirtualBase(const CXXRecordDecl *RD);
   void LayoutVirtualBases(const CXXRecordDecl *RD,
                      llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Thu Aug 13 20:44:03 2009
@@ -703,6 +703,7 @@
 
   if (isPrimary) {
     // The virtual base offsets come first...
+    // FIXME: audit
     for (CXXRecordDecl::reverse_base_class_const_iterator i
            = Class->bases_rbegin(),
            e = Class->bases_rend(); i != e; ++i) {
@@ -710,7 +711,7 @@
         continue;
       const CXXRecordDecl *Base = 
         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
-      int64_t BaseOffset = Layout.getBaseClassOffset(Base) / 8;
+      int64_t BaseOffset = Layout.getVBaseClassOffset(Base) / 8;
       llvm::Constant *m;
       m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), BaseOffset);
       m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
@@ -741,7 +742,11 @@
 
   if (TopPrimary) {
     if (RD) {
-      int64_t BaseOffset = -(Layout.getBaseClassOffset(RD) / 8);
+      int64_t BaseOffset;
+      if (ForVirtualBase)
+        BaseOffset = -(Layout.getVBaseClassOffset(RD) / 8);
+      else
+        BaseOffset = -(Layout.getBaseClassOffset(RD) / 8);
       m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), BaseOffset);
       m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
     }
@@ -784,13 +789,15 @@
   // The primary base comes first.
   GenerateVtableForBase(PrimaryBase, RD, rtti, methods, true,
                         PrimaryBaseWasVirtual, IndirectPrimary);
+
+  // Then come the non-virtual bases.
   for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
          e = RD->bases_end(); i != e; ++i) {
     if (i->isVirtual())
       continue;
     const CXXRecordDecl *Base = 
       cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
-    if (Base != PrimaryBase)
+    if (Base != PrimaryBase || PrimaryBaseWasVirtual)
       GenerateVtableForBase(Base, RD, rtti, methods, false, false,
                             IndirectPrimary);
   }





More information about the cfe-commits mailing list