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.
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);
}
}
}
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);
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) {
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.
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;
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);
}
}
}
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);
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);
// 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
// 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
// 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
// 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
// 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
// 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
// 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
// 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
// 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