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

Anders Carlsson andersca at mac.com
Mon May 17 22:12:20 PDT 2010


Author: andersca
Date: Tue May 18 00:12:20 2010
New Revision: 104012

URL: http://llvm.org/viewvc/llvm-project?rev=104012&view=rev
Log:
Start laying out bases as individual fields. We still use ugly i8 arrays but this is a step in the right direction.

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=104012&r1=104011&r2=104012&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Tue May 18 00:12:20 2010
@@ -81,8 +81,13 @@
   /// Returns false if the operation failed because the struct is not packed.
   bool LayoutFields(const RecordDecl *D);
 
-  /// LayoutBases - layout the bases and vtable pointer of a record decl.
-  void LayoutBases(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.
+  void LayoutNonVirtualBases(const CXXRecordDecl *RD, 
+                             const ASTRecordLayout &Layout);
 
   /// LayoutField - layout a single field. Returns false if the operation failed
   /// because the current struct is not packed.
@@ -435,18 +440,60 @@
     AppendPadding(Layout.getSize() / 8, Align);
 }
 
-void CGRecordLayoutBuilder::LayoutBases(const CXXRecordDecl *RD,
-                                        const ASTRecordLayout &Layout) {
+void CGRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *BaseDecl,
+                                                 uint64_t BaseOffset) {
+  const ASTRecordLayout &Layout = 
+    Types.getContext().getASTRecordLayout(BaseDecl);
+
+  uint64_t NonVirtualSize = Layout.getNonVirtualSize();
+
+  if (BaseDecl->isEmpty()) {
+    // FIXME: Lay out empty bases.
+    return;
+  }
+
+  // FIXME: Actually use a better type than [sizeof(BaseDecl) x i8] when we can.
+  AppendPadding(BaseOffset / 8, 1);
+  AppendBytes(NonVirtualSize / 8);
+}
+
+void
+CGRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD,
+                                             const ASTRecordLayout &Layout) {
+  const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+
   // Check if we need to add a vtable pointer.
-  if (RD->isDynamicClass() && !Layout.getPrimaryBase()) {
-    const llvm::Type *FunctionType =
-      llvm::FunctionType::get(llvm::Type::getInt32Ty(Types.getLLVMContext()),
-                              /*isVarArg=*/true);
-    const llvm::Type *VTableTy = FunctionType->getPointerTo();
-
-    assert(NextFieldOffsetInBytes == 0 &&
-           "VTable pointer must come first!");
-    AppendField(NextFieldOffsetInBytes, VTableTy->getPointerTo());
+  if (RD->isDynamicClass()) {
+    if (!PrimaryBase) {
+      const llvm::Type *FunctionType =
+        llvm::FunctionType::get(llvm::Type::getInt32Ty(Types.getLLVMContext()),
+                                /*isVarArg=*/true);
+      const llvm::Type *VTableTy = FunctionType->getPointerTo();
+
+      assert(NextFieldOffsetInBytes == 0 &&
+             "VTable pointer must come first!");
+      AppendField(NextFieldOffsetInBytes, VTableTy->getPointerTo());
+    } else {
+      // FIXME: Handle a virtual primary base.
+      if (!Layout.getPrimaryBaseWasVirtual())
+        LayoutNonVirtualBase(PrimaryBase, 0);
+    }
+  }
+
+  // Layout 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 *BaseDecl = 
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    // We've already laid out the primary base.
+    if (BaseDecl == PrimaryBase && !Layout.getPrimaryBaseWasVirtual())
+      continue;
+
+    LayoutNonVirtualBase(BaseDecl, Layout.getBaseClassOffset(BaseDecl));
   }
 }
 
@@ -457,7 +504,7 @@
   const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D);
 
   if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
-    LayoutBases(RD, Layout);
+    LayoutNonVirtualBases(RD, Layout);
 
   unsigned FieldNo = 0;
 





More information about the cfe-commits mailing list