forked from OSchip/llvm-project
parent
3ebc08b5bd
commit
6b2556f829
|
@ -52,7 +52,7 @@ ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
|
|||
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 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
|
|||
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 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
|
|||
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 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
|
|||
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();
|
||||
|
|
|
@ -58,7 +58,9 @@ class ASTRecordLayoutBuilder {
|
|||
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.
|
||||
|
|
|
@ -623,10 +623,8 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
|
|||
/// 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();
|
||||
|
|
|
@ -30,7 +30,7 @@ struct E {
|
|||
|
||||
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 @@ int main() {
|
|||
// 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");
|
||||
|
|
Loading…
Reference in New Issue