From 583ef6214924b668372e08a59f0cfb419f8a510e Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Wed, 19 Aug 2009 02:06:38 +0000 Subject: [PATCH] Refine vcalls a little. llvm-svn: 79400 --- clang/lib/CodeGen/CGCXX.cpp | 52 +++++++++++++++++++++------------- clang/test/CodeGenCXX/virt.cpp | 44 ++++++++++++++-------------- 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index ecde2ad19287..f95aa289a358 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -707,6 +707,7 @@ class ABIBuilder { std::vector &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 &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 &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(i->getType()->getAs()->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); diff --git a/clang/test/CodeGenCXX/virt.cpp b/clang/test/CodeGenCXX/virt.cpp index 25d47ccf8e70..95e98ac2fb35 100644 --- a/clang/test/CodeGenCXX/virt.cpp +++ b/clang/test/CodeGenCXX/virt.cpp @@ -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