[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