[cfe-commits] r78308 - in /cfe/trunk: lib/AST/RecordLayoutBuilder.cpp lib/AST/RecordLayoutBuilder.h lib/CodeGen/CGCXX.cpp test/CodeGenCXX/virt.cpp

Mike Stump mrs at apple.com
Thu Aug 6 06:41:24 PDT 2009


Author: mrs
Date: Thu Aug  6 08:41:24 2009
New Revision: 78308

URL: http://llvm.org/viewvc/llvm-project?rev=78308&view=rev
Log:
Layout virtual bases.  Work in progress.

Modified:
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.h
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/test/CodeGenCXX/virt.cpp

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

==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Thu Aug  6 08:41:24 2009
@@ -52,7 +52,7 @@
         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
       // Skip the PrimaryBase here, as it is laid down first.
       if (Base != PrimaryBase)
-        LayoutNonVirtualBase(Base);
+        LayoutBaseNonVirtually(Base);
     }
   }
 }
@@ -155,7 +155,22 @@
   return;
 }
 
-void ASTRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *RD) {
+void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
+  LayoutBaseNonVirtually(RD);
+}
+
+void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD) {
+  // FIXME: audit indirect virtual bases
+  for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
+         e = RD->vbases_end(); i != e; ++i) {
+    const CXXRecordDecl *Base = 
+      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+    if (Base != PrimaryBase)
+      LayoutVirtualBase(Base);
+  }
+}
+
+void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD) {
   const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD);
     assert(BaseInfo.getDataSize() > 0 && 
            "FIXME: Handle empty classes.");
@@ -190,11 +205,12 @@
     UpdateAlignment(AA->getAlignment());
 
   // If this is a C++ class, lay out the nonvirtual bases.
-  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
+  const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
+  if (RD) {
     LayoutVtable(RD);
     // PrimaryBase goes first.
     if (PrimaryBase)
-      LayoutNonVirtualBase(PrimaryBase);
+      LayoutBaseNonVirtually(PrimaryBase);
     LayoutNonVirtualBases(RD);
   }
 
@@ -203,6 +219,9 @@
   NonVirtualSize = Size;
   NonVirtualAlignment = Alignment;
 
+  if (RD)
+    LayoutVirtualBases(RD);
+
   // Finally, round the size of the total struct up to the alignment of the
   // struct itself.
   FinishLayout();

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

==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Thu Aug  6 08:41:24 2009
@@ -58,7 +58,9 @@
   bool IsNearlyEmpty(const CXXRecordDecl *RD);
   void LayoutVtable(const CXXRecordDecl *RD);
   void LayoutNonVirtualBases(const CXXRecordDecl *RD);
-  void LayoutNonVirtualBase(const CXXRecordDecl *RD);
+  void LayoutBaseNonVirtually(const CXXRecordDecl *RD);
+  void LayoutVirtualBase(const CXXRecordDecl *RD);
+  void LayoutVirtualBases(const CXXRecordDecl *RD);
   
   /// FinishLayout - Finalize record layout. Adjust record size based on the
   /// alignment.

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Thu Aug  6 08:41:24 2009
@@ -623,10 +623,8 @@
 /// base classes and non-static data members belonging to this constructor.
 void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
   const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
-  assert(ClassDecl->getNumVBases() == 0
-         && "FIXME: virtual base initialization unsupported");
+  // FIXME: Add vbase initialization
   llvm::Value *LoadOfThis = 0;
-
   
   for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
        E = CD->init_end();

Modified: cfe/trunk/test/CodeGenCXX/virt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/virt.cpp?rev=78308&r1=78307&r2=78308&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/virt.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/virt.cpp Thu Aug  6 08:41:24 2009
@@ -30,7 +30,7 @@
 
 static_assert (sizeof (C) == (sizeof(void *)), "vtable pointer layout");
 
-class A : public E, public B, public C, /* virtual */ public D {
+class A : public E, public B, public C {
 public:
   virtual void foo1();
   virtual void foo2();
@@ -90,3 +90,23 @@
 // CHECK-LP32: .space 4
 // CHECK-LP32: .long __ZN1C4bee1Ev
 // CHECK-LP32: .long __ZN1C4bee2Ev
+
+struct D1 {
+  virtual void bar();
+  void *d1;
+};
+void D1::bar() { }
+
+class F : virtual public D1, virtual public D {
+public:
+  virtual void foo();
+  void *f;
+};
+void F::foo() { }
+
+void test2() {
+  F f;
+  f.f = 0;
+}
+  
+static_assert(sizeof(F) == sizeof(void*)*4, "invalid vbase size");





More information about the cfe-commits mailing list