From e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Thu, 6 Aug 2009 21:49:36 +0000 Subject: [PATCH] Also generate the rtti field for virtual bases for vtables. Turn on rtti so we can properly test it. Refactor code a little. Still a work in progress. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78343 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCXX.cpp | 69 ++++++++++++++++++++--------------- lib/CodeGen/CodeGenFunction.h | 5 ++- test/CodeGenCXX/virt.cpp | 24 ++++++------ 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 0d51c03bab..d60f13019f 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -514,10 +514,10 @@ llvm::Constant *CodeGenFunction::GenerateRtti(const CXXRecordDecl *RD) { llvm::GlobalVariable::LinkageTypes linktype; linktype = llvm::GlobalValue::WeakAnyLinkage; std::vector info; - assert (0 && "FIXME: implement rtti descriptor"); + // assert (0 && "FIXME: implement rtti descriptor"); // FIXME: descriptor info.push_back(llvm::Constant::getNullValue(Ptr8Ty)); - assert (0 && "FIXME: implement rtti ts"); + // assert (0 && "FIXME: implement rtti ts"); // FIXME: TS info.push_back(llvm::Constant::getNullValue(Ptr8Ty)); @@ -531,14 +531,43 @@ llvm::Constant *CodeGenFunction::GenerateRtti(const CXXRecordDecl *RD) { } void CodeGenFunction::GenerateVtableForBase(const CXXRecordDecl *RD, - std::vector &methods) { + const CXXRecordDecl *Class, + llvm::Constant *rtti, + std::vector &methods, + bool isPrimary) { typedef CXXRecordDecl::method_iterator meth_iter; llvm::Type *Ptr8Ty; Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0); + llvm::Constant *m = llvm::Constant::getNullValue(Ptr8Ty); + + if (RD && !RD->isDynamicClass()) + return; + if (RD) { + const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Class); + int64_t BaseOffset = -(Layout.getBaseClassOffset(RD) / 8); + m = llvm::ConstantInt::get(llvm::Type::Int64Ty, BaseOffset); + m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty); + } + methods.push_back(m); + methods.push_back(rtti); + + if (RD) + for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; + ++mi) { + if (mi->isVirtual()) { + m = CGM.GetAddrOfFunction(GlobalDecl(*mi)); + m = llvm::ConstantExpr::getBitCast(m, Ptr8Ty); + methods.push_back(m); + } + } + if (!isPrimary) + 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; ++mi) { if (mi->isVirtual()) { - llvm::Constant *m; m = CGM.GetAddrOfFunction(GlobalDecl(*mi)); m = llvm::ConstantExpr::getBitCast(m, Ptr8Ty); methods.push_back(m); @@ -559,29 +588,19 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { linktype = llvm::GlobalValue::WeakAnyLinkage; std::vector methods; typedef CXXRecordDecl::method_iterator meth_iter; - llvm::Constant *m; llvm::Type *Ptr8Ty; Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0); - m = llvm::Constant::getNullValue(Ptr8Ty); int64_t Offset = 0; - methods.push_back(m); Offset += LLVMPointerWidth; - methods.push_back(GenerateRtti(RD)); Offset += LLVMPointerWidth; + llvm::Constant *rtti = GenerateRtti(RD); + + Offset += LLVMPointerWidth; + Offset += LLVMPointerWidth; const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); // The primary base comes first. - if (PrimaryBase) - GenerateVtableForBase(PrimaryBase, methods); - for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; - ++mi) { - if (mi->isVirtual()) { - m = CGM.GetAddrOfFunction(GlobalDecl(*mi)); - m = llvm::ConstantExpr::getBitCast(m, Ptr8Ty); - methods.push_back(m); - } - } - + GenerateVtableForBase(PrimaryBase, RD, rtti, methods, true); for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), e = RD->bases_end(); i != e; ++i) { if (i->isVirtual()) @@ -589,15 +608,7 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { const CXXRecordDecl *Base = cast(i->getType()->getAs()->getDecl()); if (PrimaryBase != Base) { - const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); - int64_t BaseOffset = -(Layout.getBaseClassOffset(Base) / 8); - m = llvm::ConstantInt::get(llvm::Type::Int64Ty, BaseOffset); - m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty); - methods.push_back(m); - // FIXME: GenerateRtti for Base in RD. - m = llvm::Constant::getNullValue(Ptr8Ty); - methods.push_back(m); - GenerateVtableForBase(Base, methods); + GenerateVtableForBase(Base, RD, rtti, methods); } } @@ -608,7 +619,7 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { const CXXRecordDecl *Base = cast(i->getType()->getAs()->getDecl()); if (Base != PrimaryBase) - GenerateVtableForBase(Base, methods); + GenerateVtableForBase(Base, RD, rtti, methods); } llvm::Constant *C; diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 1f0fad609f..fe52e99662 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -360,7 +360,10 @@ public: llvm::Constant *GenerateRtti(const CXXRecordDecl *RD); void GenerateVtableForBase(const CXXRecordDecl *RD, - std::vector &methods); + const CXXRecordDecl *Class, + llvm::Constant *rtti, + std::vector &methods, + bool isPrimary = 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 4ba52bc7ff..1096e5d530 100644 --- a/test/CodeGenCXX/virt.cpp +++ b/test/CodeGenCXX/virt.cpp @@ -1,6 +1,6 @@ -// RUN: clang-cc -triple x86_64-apple-darwin -frtti=0 -std=c++0x -O3 -S %s -o %t-64.s && +// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -O3 -S %s -o %t-64.s && // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && -// RUN: clang-cc -triple i386-apple-darwin -frtti=0 -std=c++0x -O3 -S %s -o %t-32.s && +// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -O3 -S %s -o %t-32.s && // RUN: FileCheck -check-prefix LP32 -input-file=%t-32.s %s && // RUN: true @@ -83,37 +83,37 @@ int main() { // CHECK-LP64: __ZTV1B: // CHECK-LP64: .space 8 -// CHECK-LP64: .space 8 +// CHECK-LP64: .quad __ZTI1B // CHECK-LP64: .quad __ZN1B4bar1Ev // CHECK-LP64: .quad __ZN1B4bar2Ev // CHECK-LP32: __ZTV1B: // CHECK-LP32: .space 4 -// CHECK-LP32: .space 4 +// CHECK-LP32: .long __ZTI1B // CHECK-LP32: .long __ZN1B4bar1Ev // CHECK-LP32: .long __ZN1B4bar2Ev // CHECK-LP64: __ZTV1A: // CHECK-LP64: .space 8 -// CHECK-LP64: .space 8 +// CHECK-LP64: .quad __ZTI1A // CHECK-LP64: .quad __ZN1B4bar1Ev // CHECK-LP64: .quad __ZN1B4bar2Ev // CHECK-LP64: .quad __ZN1A4foo1Ev // CHECK-LP64: .quad __ZN1A4foo2Ev // CHECK-LP64: .quad 18446744073709551600 -// CHECK-LP64: .space 8 +// CHECK-LP64: .quad __ZTI1A // CHECK-LP64: .quad __ZN1C4bee1Ev // CHECK-LP64: .quad __ZN1C4bee2Ev // CHECK-LP32: __ZTV1A: // CHECK-LP32: .space 4 -// CHECK-LP32: .space 4 +// CHECK-LP32: .long __ZTI1A // CHECK-LP32: .long __ZN1B4bar1Ev // CHECK-LP32: .long __ZN1B4bar2Ev // CHECK-LP32: .long __ZN1A4foo1Ev // CHECK-LP32: .long __ZN1A4foo2Ev // CHECK-LP32: .long 4294967284 -// CHECK-LP32: .space 4 +// CHECK-LP32: .long __ZTI1A // CHECK-LP32: .long __ZN1C4bee1Ev // CHECK-LP32: .long __ZN1C4bee2Ev @@ -122,12 +122,12 @@ int main() { // CHECK-LP32 .long 8 // CHECK-LP32 .space 4 // CHECK-LP32: .space 4 -// CHECK-LP32: .space 4 +// CHECK-LP32: .long __ZTI1F // CHECK-LP32: .long __ZN1D3booEv // CHECK-LP32: .long __ZN1F3fooEv // CHECK-LP32 .space 4 // CHECK-LP32 .long -8 -// CHECK-LP32 .space 4 +// CHECK-LP32: .long __ZTI1F // CHECK-LP32: .long __ZN2D13barEv // CHECK-LP64: __ZTV1F: @@ -135,10 +135,10 @@ int main() { // CHECK-LP64 .quad 16 // CHECK-LP64 .space 8 // CHECK-LP64: .space 8 -// CHECK-LP64: .space 8 +// CHECK-LP64: .quad __ZTI1F // CHECK-LP64: .quad __ZN1D3booEv // CHECK-LP64: .quad __ZN1F3fooEv // CHECK-LP64 .space 8 // CHECK-LP64 .space -16 -// CHECK-LP64 .space 8 +// CHECK-LP64:.quad __ZTI1F // CHECK-LP64: .quad __ZN2D13barEv -- 2.40.0