parent
cc06621280
commit
583ef62149
|
@ -707,6 +707,7 @@ class ABIBuilder {
|
|||
std::vector<llvm::Constant *> &methods;
|
||||
llvm::Type *Ptr8Ty;
|
||||
const CXXRecordDecl *Class;
|
||||
const ASTRecordLayout &BLayout;
|
||||
llvm::Constant *rtti;
|
||||
llvm::LLVMContext &VMContext;
|
||||
CodeGenModule &CGM; // Per-module state.
|
||||
|
@ -716,21 +717,34 @@ public:
|
|||
ABIBuilder(std::vector<llvm::Constant *> &meth,
|
||||
const CXXRecordDecl *c,
|
||||
CodeGenModule &cgm)
|
||||
: methods(meth), Class(c), rtti(cgm.GenerateRtti(c)),
|
||||
VMContext(cgm.getModule().getContext()), CGM(cgm) {
|
||||
: methods(meth), Class(c), BLayout(cgm.getContext().getASTRecordLayout(c)),
|
||||
rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()),
|
||||
CGM(cgm) {
|
||||
Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
|
||||
}
|
||||
|
||||
void GenerateVcalls(const CXXRecordDecl *RD) {
|
||||
llvm::Constant *GenerateVcall(const CXXMethodDecl *MD,
|
||||
const CXXRecordDecl *RD,
|
||||
bool VBoundary,
|
||||
bool SecondaryVirtual) {
|
||||
llvm::Constant *m = 0;
|
||||
|
||||
// FIXME: vcall: offset for virtual base for this function
|
||||
if (SecondaryVirtual || VBoundary)
|
||||
m = llvm::Constant::getNullValue(Ptr8Ty);
|
||||
return m;
|
||||
}
|
||||
|
||||
void GenerateVcalls(const CXXRecordDecl *RD, bool VBoundary,
|
||||
bool SecondaryVirtual) {
|
||||
llvm::Constant *m;
|
||||
|
||||
// FIXME: audit order
|
||||
for (method_iter mi = RD->method_begin(),
|
||||
me = RD->method_end(); mi != me; ++mi) {
|
||||
if (mi->isVirtual()) {
|
||||
// FIXME: vcall: offset for virtual base for this function
|
||||
m = llvm::Constant::getNullValue(Ptr8Ty);
|
||||
methods.push_back(m);
|
||||
m = GenerateVcall(*mi, RD, VBoundary, SecondaryVirtual);
|
||||
if (m)
|
||||
methods.push_back(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -750,8 +764,8 @@ public:
|
|||
|
||||
void GenerateVtableForBase(const CXXRecordDecl *RD,
|
||||
bool forPrimary,
|
||||
bool VBoundary,
|
||||
int64_t Offset,
|
||||
const CXXRecordDecl *Class,
|
||||
bool ForVirtualBase,
|
||||
llvm::SmallSet<const CXXRecordDecl *, 32> &IndirectPrimary) {
|
||||
llvm::Constant *m = llvm::Constant::getNullValue(Ptr8Ty);
|
||||
|
@ -763,6 +777,11 @@ public:
|
|||
const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
|
||||
const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
|
||||
|
||||
if (VBoundary || forPrimary || ForVirtualBase) {
|
||||
// then comes the the vcall offsets for all our functions...
|
||||
GenerateVcalls(RD, VBoundary, !forPrimary && ForVirtualBase);
|
||||
}
|
||||
|
||||
// The virtual base offsets come first...
|
||||
// FIXME: Audit, is this right?
|
||||
if (forPrimary || !PrimaryBaseWasVirtual) {
|
||||
|
@ -774,11 +793,6 @@ public:
|
|||
methods.push_back(*i);
|
||||
}
|
||||
|
||||
if (forPrimary || ForVirtualBase) {
|
||||
// then comes the the vcall offsets for all our functions...
|
||||
GenerateVcalls(RD);
|
||||
}
|
||||
|
||||
bool Top = true;
|
||||
|
||||
// vtables are composed from the chain of primaries.
|
||||
|
@ -786,15 +800,13 @@ public:
|
|||
if (PrimaryBaseWasVirtual)
|
||||
IndirectPrimary.insert(PrimaryBase);
|
||||
Top = false;
|
||||
GenerateVtableForBase(PrimaryBase, true, Offset, Class,
|
||||
PrimaryBaseWasVirtual, IndirectPrimary);
|
||||
GenerateVtableForBase(PrimaryBase, true, PrimaryBaseWasVirtual|VBoundary,
|
||||
Offset, PrimaryBaseWasVirtual, IndirectPrimary);
|
||||
}
|
||||
|
||||
if (Top) {
|
||||
int64_t BaseOffset;
|
||||
if (ForVirtualBase) {
|
||||
const ASTRecordLayout &BLayout = CGM.getContext()
|
||||
.getASTRecordLayout(Class);
|
||||
BaseOffset = -(BLayout.getVBaseClassOffset(RD) / 8);
|
||||
} else
|
||||
BaseOffset = -Offset/8;
|
||||
|
@ -816,7 +828,7 @@ public:
|
|||
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
|
||||
if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
|
||||
uint64_t o = Offset + Layout.getBaseClassOffset(Base);
|
||||
GenerateVtableForBase(Base, true, o, Class, false, IndirectPrimary);
|
||||
GenerateVtableForBase(Base, true, false, o, false, IndirectPrimary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -831,7 +843,7 @@ public:
|
|||
if (i->isVirtual() && !IndirectPrimary.count(Base)) {
|
||||
// Mark it so we don't output it twice.
|
||||
IndirectPrimary.insert(Base);
|
||||
GenerateVtableForBase(Base, true, 0, Class, true, IndirectPrimary);
|
||||
GenerateVtableForBase(Base, false, true, 0, true, IndirectPrimary);
|
||||
}
|
||||
if (Base->getNumVBases())
|
||||
GenerateVtableForVBases(Base, Class, IndirectPrimary);
|
||||
|
@ -880,7 +892,7 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
|
|||
ABIBuilder b(methods, RD, CGM);
|
||||
|
||||
// First comes the vtables for all the non-virtual bases...
|
||||
b.GenerateVtableForBase(RD, true, 0, RD, false, IndirectPrimary);
|
||||
b.GenerateVtableForBase(RD, true, false, 0, false, IndirectPrimary);
|
||||
|
||||
// then the vtables for all the virtual bases.
|
||||
b.GenerateVtableForVBases(RD, RD, IndirectPrimary);
|
||||
|
|
|
@ -228,16 +228,16 @@ struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 {
|
|||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32-NEXT .space 4 FIXME
|
||||
// CHECK-LP32: .long 4294967292
|
||||
// CHECK-LP32-NEXT: .long __ZTI7test5_D
|
||||
// CHECK-LP32-NEXT: .long __ZN9test5_B237funcB23Ev
|
||||
// CHECK-LP32-NEXT: .long __ZN9test5_B227funcB22Ev
|
||||
// CHECK-LP32-NEXT: .long __ZN9test5_B217funcB21Ev
|
||||
// CHECK-LP32 .space 4
|
||||
// CHECK-LP32: .long 8
|
||||
// CHECK-LP32 .long 8 FIXME
|
||||
// CHECK-LP32: .space 4
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32-NEXT .space 4 FIXME
|
||||
// CHECK-LP32: .long 4
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
|
@ -280,16 +280,16 @@ struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 {
|
|||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT .space 8 FIXME
|
||||
// CHECK-LP64: .quad 18446744073709551608
|
||||
// CHECK-LP64-NEXT: .quad __ZTI7test5_D
|
||||
// CHECK-LP64-NEXT: .quad __ZN9test5_B237funcB23Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZN9test5_B227funcB22Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZN9test5_B217funcB21Ev
|
||||
// CHECK-LP64 .space 8
|
||||
// CHECK-LP64: .quad 16
|
||||
// CHECK-LP64 .quad 16 FIXME
|
||||
// CHECK-LP64: .space 8
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT .space 8 FIXME
|
||||
// CHECK-LP64: .quad 8
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
|
@ -337,7 +337,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
|
|||
// CHECK-LP32-NEXT: .long 24
|
||||
// CHECK-LP32-NEXT: .long 16
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32: .long __ZTI7test8_D
|
||||
// CHECK-LP32-NEXT: .long __ZTI7test8_D
|
||||
// CHECK-LP32-NEXT: .long __ZN8test8_B19ftest8_B1Ev
|
||||
// CHECK-LP32-NEXT: .long 20
|
||||
// CHECK-LP32-NEXT: .long 12
|
||||
|
@ -345,10 +345,10 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
|
|||
// CHECK-LP32-NEXT: .long __ZTI7test8_D
|
||||
// CHECK-LP32-NEXT: .long __ZN9test8_B2a10ftest8_B2aEv
|
||||
// CHECK-LP32-NEXT: .long __ZN8test8_B29ftest8_B2Ev
|
||||
// CHECK-LP32: .long 4294967288
|
||||
// CHECK-LP32-NEXT: .long 4294967288
|
||||
// CHECK-LP32-NEXT: .long __ZTI7test8_D
|
||||
// CHECK-LP32-NEXT: .long __ZN9test8_B2b10ftest8_B2bEv
|
||||
// CHECK-LP32: .long 4294967284
|
||||
// CHECK-LP32-NEXT: .long 4294967284
|
||||
// CHECK-LP32-NEXT: .long __ZTI7test8_D
|
||||
// CHECK-LP32-NEXT: .long __ZN8test8_B39ftest8_B3Ev
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
|
@ -364,7 +364,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
|
|||
// CHECK-LP64-NEXT: .quad 48
|
||||
// CHECK-LP64-NEXT: .quad 32
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64: .quad __ZTI7test8_D
|
||||
// CHECK-LP64-NEXT: .quad __ZTI7test8_D
|
||||
// CHECK-LP64-NEXT: .quad __ZN8test8_B19ftest8_B1Ev
|
||||
// CHECK-LP64-NEXT: .quad 40
|
||||
// CHECK-LP64-NEXT: .quad 24
|
||||
|
@ -372,10 +372,10 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
|
|||
// CHECK-LP64-NEXT: .quad __ZTI7test8_D
|
||||
// CHECK-LP64-NEXT: .quad __ZN9test8_B2a10ftest8_B2aEv
|
||||
// CHECK-LP64-NEXT: .quad __ZN8test8_B29ftest8_B2Ev
|
||||
// CHECK-LP64: .quad 18446744073709551600
|
||||
// CHECK-LP64-NEXT: .quad 18446744073709551600
|
||||
// CHECK-LP64-NEXT: .quad __ZTI7test8_D
|
||||
// CHECK-LP64-NEXT: .quad __ZN9test8_B2b10ftest8_B2bEv
|
||||
// CHECK-LP64: .quad 18446744073709551592
|
||||
// CHECK-LP64-NEXT: .quad 18446744073709551592
|
||||
// CHECK-LP64-NEXT: .quad __ZTI7test8_D
|
||||
// CHECK-LP64-NEXT: .quad __ZN8test8_B39ftest8_B3Ev
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
|
@ -390,37 +390,37 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
|
|||
|
||||
|
||||
// CHECK-LP64: __ZTV1B:
|
||||
// CHECK-LP64: .space 8
|
||||
// CHECK-LP64: .quad __ZTI1B
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT: .quad __ZTI1B
|
||||
// CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev
|
||||
|
||||
// CHECK-LP32: __ZTV1B:
|
||||
// CHECK-LP32: .space 4
|
||||
// CHECK-LP32: .long __ZTI1B
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32-NEXT: .long __ZTI1B
|
||||
// CHECK-LP32-NEXT: .long __ZN1B4bar1Ev
|
||||
// CHECK-LP32-NEXT: .long __ZN1B4bar2Ev
|
||||
|
||||
// CHECK-LP64: __ZTV1A:
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64: .quad __ZTI1A
|
||||
// CHECK-LP64-NEXT: .quad __ZTI1A
|
||||
// CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZN1A4foo1Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZN1A4foo2Ev
|
||||
// CHECK-LP64: .quad 18446744073709551600
|
||||
// CHECK-LP64-NEXT: .quad 18446744073709551600
|
||||
// CHECK-LP64-NEXT: .quad __ZTI1A
|
||||
// CHECK-LP64-NEXT: .quad __ZN1C4bee1Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZN1C4bee2Ev
|
||||
|
||||
// CHECK-LP32: __ZTV1A:
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32: .long __ZTI1A
|
||||
// CHECK-LP32-NEXT: .long __ZTI1A
|
||||
// CHECK-LP32-NEXT: .long __ZN1B4bar1Ev
|
||||
// CHECK-LP32-NEXT: .long __ZN1B4bar2Ev
|
||||
// CHECK-LP32-NEXT: .long __ZN1A4foo1Ev
|
||||
// CHECK-LP32-NEXT: .long __ZN1A4foo2Ev
|
||||
// CHECK-LP32: .long 4294967284
|
||||
// CHECK-LP32-NEXT: .long 4294967284
|
||||
// CHECK-LP32-NEXT: .long __ZTI1A
|
||||
// CHECK-LP32-NEXT: .long __ZN1C4bee1Ev
|
||||
// CHECK-LP32-NEXT: .long __ZN1C4bee2Ev
|
||||
|
@ -430,7 +430,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
|
|||
// CHECK-LP32-NEXT: .long 8
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32: .long __ZTI1F
|
||||
// CHECK-LP32-NEXT: .long __ZTI1F
|
||||
// CHECK-LP32-NEXT: .long __ZN1D3booEv
|
||||
// CHECK-LP32-NEXT: .long __ZN1F3fooEv
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
|
@ -451,7 +451,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
|
|||
// CHECK-LP64-NEXT: .quad 16
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64: .quad __ZTI1F
|
||||
// CHECK-LP64-NEXT: .quad __ZTI1F
|
||||
// CHECK-LP64-NEXT: .quad __ZN1D3booEv
|
||||
// CHECK-LP64-NEXT: .quad __ZN1F3fooEv
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
|
|
Loading…
Reference in New Issue