[cfe-commits] r120257 - /cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp

Anders Carlsson andersca at mac.com
Sun Nov 28 11:18:44 PST 2010


Author: andersca
Date: Sun Nov 28 13:18:44 2010
New Revision: 120257

URL: http://llvm.org/viewvc/llvm-project?rev=120257&view=rev
Log:
More work on laying out virtual bases.

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

Modified: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp?rev=120257&r1=120256&r2=120257&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Sun Nov 28 13:18:44 2010
@@ -69,6 +69,10 @@
   /// primary base classes for some other direct or indirect base class.
   CXXIndirectPrimaryBaseSet IndirectPrimaryBases;
 
+  /// LaidOutVirtualBases - A set of all laid out virtual bases, used to avoid
+  /// avoid laying out virtual bases more than once.
+  llvm::SmallPtrSet<const CXXRecordDecl *, 4> LaidOutVirtualBases;
+  
   /// IsZeroInitializable - Whether this struct can be C++
   /// zero-initialized with an LLVM zeroinitializer.
   bool IsZeroInitializable;
@@ -110,11 +114,15 @@
   /// LayoutVirtualBase - layout a single virtual base.
   void LayoutVirtualBase(const CXXRecordDecl *BaseDecl, uint64_t BaseOffset);
 
+  /// LayoutVirtualBases - layout the virtual bases of a record decl.
+  void LayoutVirtualBases(const CXXRecordDecl *RD,
+                          const ASTRecordLayout &Layout);
+  
   /// LayoutNonVirtualBase - layout a single non-virtual base.
   void LayoutNonVirtualBase(const CXXRecordDecl *BaseDecl,
                             uint64_t BaseOffset);
   
-  /// LayoutNonVirtualBases - layout the non-virtual bases of a record decl.
+  /// LayoutNonVirtualBases - layout the virtual bases of a record decl.
   void LayoutNonVirtualBases(const CXXRecordDecl *RD, 
                              const ASTRecordLayout &Layout);
 
@@ -513,6 +521,35 @@
 
 }
 
+/// LayoutVirtualBases - layout the non-virtual bases of a record decl.
+void
+CGRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
+                                          const ASTRecordLayout &Layout) {
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    // We only want to lay out virtual bases that aren't indirect primary bases
+    // of some other base.
+    if (I->isVirtual() && !IndirectPrimaryBases.count(BaseDecl)) {
+      // Only lay out the base once.
+      if (!LaidOutVirtualBases.insert(BaseDecl))
+        continue;
+
+      uint64_t VBaseOffset = Layout.getVBaseClassOffsetInBits(BaseDecl);
+      LayoutVirtualBase(BaseDecl, VBaseOffset);
+    }
+
+    if (!BaseDecl->getNumVBases()) {
+      // This base isn't interesting since it doesn't have any virtual bases.
+      continue;
+    }
+    
+    LayoutVirtualBases(BaseDecl, Layout);
+  }
+}
+
 void CGRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *BaseDecl,
                                                  uint64_t BaseOffset) {
   // Ignore empty bases.
@@ -630,17 +667,17 @@
     }
   }
 
-  // We've laid out the non-virtual bases and the fields, now compute the
-  // non-virtual base field types.
-  if (RD)
-    ComputeNonVirtualBaseType(RD);
-  
   if (RD) {
+    // We've laid out the non-virtual bases and the fields, now compute the
+    // non-virtual base field types.
+    ComputeNonVirtualBaseType(RD);
+
+    // And lay out the virtual bases.
     RD->getIndirectPrimaryBases(IndirectPrimaryBases);
+    if (Layout.isPrimaryBaseVirtual())
+      IndirectPrimaryBases.insert(Layout.getPrimaryBase());
+    LayoutVirtualBases(RD, Layout);
   }
-
-  // FIXME: Lay out the virtual bases instead of just treating them as tail
-  // padding.
   
   // Append tail padding if necessary.
   AppendTailPadding(Layout.getSize());





More information about the cfe-commits mailing list