From 02cf1e264719b4dada4377cc8a43888cb66f8815 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Thu, 6 Aug 2009 23:48:32 +0000 Subject: [PATCH] Add support for vcall generation for vtables for virtual bases. WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78357 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCXX.cpp | 28 ++++++++++++++++++++++++---- lib/CodeGen/CodeGenFunction.h | 3 ++- test/CodeGenCXX/virt.cpp | 24 ++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index d60f13019f..f1a5e1cca4 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -534,7 +534,8 @@ void CodeGenFunction::GenerateVtableForBase(const CXXRecordDecl *RD, const CXXRecordDecl *Class, llvm::Constant *rtti, std::vector &methods, - bool isPrimary) { + bool isPrimary, + bool ForVirtualBase) { typedef CXXRecordDecl::method_iterator meth_iter; llvm::Type *Ptr8Ty; Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0); @@ -542,6 +543,26 @@ void CodeGenFunction::GenerateVtableForBase(const CXXRecordDecl *RD, if (RD && !RD->isDynamicClass()) return; + + if (RD && ForVirtualBase) + for (meth_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); + } + } + if (isPrimary && ForVirtualBase) + for (meth_iter mi = Class->method_begin(), + me = Class->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); + } + } + if (RD) { const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Class); int64_t BaseOffset = -(Layout.getBaseClassOffset(RD) / 8); @@ -564,8 +585,7 @@ void CodeGenFunction::GenerateVtableForBase(const CXXRecordDecl *RD, return; // And add the virtuals for the class to the primary vtable. - RD = Class; - for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; + for (meth_iter mi = Class->method_begin(), me = Class->method_end(); mi != me; ++mi) { if (mi->isVirtual()) { m = CGM.GetAddrOfFunction(GlobalDecl(*mi)); @@ -619,7 +639,7 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { const CXXRecordDecl *Base = cast(i->getType()->getAs()->getDecl()); if (Base != PrimaryBase) - GenerateVtableForBase(Base, RD, rtti, methods); + GenerateVtableForBase(Base, RD, rtti, methods, false, true); } llvm::Constant *C; diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index fe52e99662..63632f5f40 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -363,7 +363,8 @@ public: const CXXRecordDecl *Class, llvm::Constant *rtti, std::vector &methods, - bool isPrimary = false); + bool isPrimary = false, + bool ForVirtualBase = false); llvm::Value *GenerateVtable(const CXXRecordDecl *RD); void EmitCtorPrologue(const CXXConstructorDecl *CD); diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp index 5c6c919e42..aa1bca156c 100644 --- a/test/CodeGenCXX/virt.cpp +++ b/test/CodeGenCXX/virt.cpp @@ -26,6 +26,10 @@ void D::boo() { } struct D1 { virtual void bar(); + virtual void bar2(); + virtual void bar3(); + virtual void bar4(); + virtual void bar5(); void *d1; }; void D1::bar() { } @@ -125,10 +129,18 @@ int main() { // CHECK-LP32: .long __ZTI1F // CHECK-LP32: .long __ZN1D3booEv // CHECK-LP32: .long __ZN1F3fooEv -// CHECK-LP32 .space 4 +// CHECK-LP32: .space 4 +// CHECK-LP32: .space 4 +// CHECK-LP32: .space 4 +// CHECK-LP32: .space 4 +// CHECK-LP32: .space 4 // CHECK-LP32: .long 4294967288 // CHECK-LP32: .long __ZTI1F // CHECK-LP32: .long __ZN2D13barEv +// CHECK-LP32: .long __ZN2D14bar2Ev +// CHECK-LP32: .long __ZN2D14bar3Ev +// CHECK-LP32: .long __ZN2D14bar4Ev +// CHECK-LP32: .long __ZN2D14bar5Ev // CHECK-LP64: __ZTV1F: // CHECK-LP64 .space 8 @@ -138,7 +150,15 @@ int main() { // CHECK-LP64: .quad __ZTI1F // CHECK-LP64: .quad __ZN1D3booEv // CHECK-LP64: .quad __ZN1F3fooEv -// CHECK-LP64 .space 8 +// CHECK-LP64: .space 8 +// CHECK-LP64: .space 8 +// CHECK-LP64: .space 8 +// CHECK-LP64: .space 8 +// CHECK-LP64: .space 8 // CHECK-LP64: .quad 18446744073709551600 // CHECK-LP64: .quad __ZTI1F // CHECK-LP64: .quad __ZN2D13barEv +// CHECK-LP64: .quad __ZN2D14bar2Ev +// CHECK-LP64: .quad __ZN2D14bar3Ev +// CHECK-LP64: .quad __ZN2D14bar4Ev +// CHECK-LP64: .quad __ZN2D14bar5Ev -- 2.40.0