From 64989f04d13d9a4a62cc7ebee6351b7c4dbe2e74 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Tue, 17 Nov 2009 23:11:22 +0000 Subject: [PATCH] Add rtti info for function prototypes and refactor. This allows pointer to member functions to work. WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89161 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGRtti.cpp | 107 ++++++++++++++++++++++----------------- test/CodeGenCXX/rtti.cpp | 18 ++++++- 2 files changed, 77 insertions(+), 48 deletions(-) diff --git a/lib/CodeGen/CGRtti.cpp b/lib/CodeGen/CGRtti.cpp index 901c34a281..46d7b67efb 100644 --- a/lib/CodeGen/CGRtti.cpp +++ b/lib/CodeGen/CGRtti.cpp @@ -76,7 +76,6 @@ public: } llvm::Constant *BuildTypeRef(QualType Ty) { - const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); llvm::Constant *C; if (!CGM.getContext().getLangOptions().Rtti) @@ -143,13 +142,38 @@ public: return true; } - llvm::Constant *Buildclass_type_info(const CXXRecordDecl *RD) { - const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); + llvm::Constant *finish(std::vector &info, + llvm::GlobalVariable *GV, + llvm::StringRef Name) { + llvm::GlobalVariable::LinkageTypes linktype; + linktype = llvm::GlobalValue::LinkOnceODRLinkage; + llvm::Constant *C; + C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false); + + if (GV == 0) + GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, + linktype, C, Name); + else { + llvm::GlobalVariable *OGV = GV; + GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, + linktype, C, Name); + GV->takeName(OGV); + llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV, + OGV->getType()); + OGV->replaceAllUsesWith(NewPtr); + OGV->eraseFromParent(); + } + return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy); + } + + llvm::Constant *Buildclass_type_info(const CXXRecordDecl *RD) { if (!CGM.getContext().getLangOptions().Rtti) return llvm::Constant::getNullValue(Int8PtrTy); + llvm::Constant *C; + llvm::SmallString<256> OutName; llvm::raw_svector_ostream Out(OutName); mangleCXXRtti(CGM.getMangleContext(), CGM.getContext().getTagDeclType(RD), @@ -160,8 +184,6 @@ public: if (GV && !GV->isDeclaration()) return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy); - llvm::GlobalVariable::LinkageTypes linktype; - linktype = llvm::GlobalValue::LinkOnceODRLinkage; std::vector info; bool simple = false; @@ -206,31 +228,7 @@ public: } } - C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false); - - if (GV == 0) - GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype, - C, Out.str()); - else { - llvm::GlobalVariable *OGV = GV; - GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype, - C, Out.str()); - GV->takeName(OGV); - llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV, OGV->getType()); - OGV->replaceAllUsesWith(NewPtr); - OGV->eraseFromParent(); - } - return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy); - -#if 0 - llvm::ArrayType *type = llvm::ArrayType::get(Int8PtrTy, info.size()); - C = llvm::ConstantArray::get(type, info); - llvm::Constant *Rtti = - new llvm::GlobalVariable(CGM.getModule(), type, true, linktype, C, - Out.str()); - Rtti = llvm::ConstantExpr::getBitCast(Rtti, Int8PtrTy); - return Rtti; -#endif + return finish(info, GV, Out.str()); } /// - BuildFlags - Build a __flags value for __pbase_type_info. @@ -246,7 +244,6 @@ public: } llvm::Constant *BuildPointerType(QualType Ty) { - const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); llvm::Constant *C; llvm::SmallString<256> OutName; @@ -294,22 +291,37 @@ public: if (PtrMem) info.push_back(BuildType2(BTy)); - C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false); + return finish(info, GV, Out.str()); + } - if (GV == 0) - GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, - linktype, C, Out.str()); - else { - llvm::GlobalVariable *OGV = GV; - GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, - linktype, C, Out.str()); - GV->takeName(OGV); - llvm::Constant *NewPtr - = llvm::ConstantExpr::getBitCast(GV, OGV->getType()); - OGV->replaceAllUsesWith(NewPtr); - OGV->eraseFromParent(); + llvm::Constant *BuildFunctionType(QualType Ty) { + llvm::Constant *C; + + llvm::SmallString<256> OutName; + llvm::raw_svector_ostream Out(OutName); + mangleCXXRtti(CGM.getMangleContext(), Ty, Out); + + llvm::GlobalVariable *GV; + GV = CGM.getModule().getGlobalVariable(Out.str()); + if (GV && !GV->isDeclaration()) + return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy); + + std::vector info; + + QualType PTy = Ty->getPointeeType(); + QualType BTy; + bool PtrMem = false; + if (const MemberPointerType *MPT = dyn_cast(Ty)) { + PtrMem = true; + BTy = QualType(MPT->getClass(), 0); + PTy = MPT->getPointeeType(); } - return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy); + + C = BuildVtableRef("_ZTVN10__cxxabiv120__function_type_infoE"); + info.push_back(C); + info.push_back(BuildName(Ty)); + + return finish(info, GV, Out.str()); } llvm::Constant *BuildType(QualType Ty) { @@ -317,9 +329,8 @@ public: = *CGM.getContext().getCanonicalType(Ty).getTypePtr(); switch (Type.getTypeClass()) { default: { - // FIXME: Add all the missing types, such as pointer, array... + // FIXME: Add all the missing types, such as array... assert(0 && "typeid expression"); - const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); return llvm::Constant::getNullValue(Int8PtrTy); } @@ -340,6 +351,8 @@ public: } case Type::MemberPointer: return BuildPointerType(Ty); + case Type::FunctionProto: + return BuildFunctionType(Ty); } } }; diff --git a/test/CodeGenCXX/rtti.cpp b/test/CodeGenCXX/rtti.cpp index 3d8f116fc1..a673544ace 100644 --- a/test/CodeGenCXX/rtti.cpp +++ b/test/CodeGenCXX/rtti.cpp @@ -49,7 +49,7 @@ class test1_D : public test1_B7 { // CHECK-NEXT: .quad __ZTIi // CHECK-NEXT: .quad __ZTI7test3_A -// CHECK:__ZTIM7test3_Ii: +// CHECK: __ZTIM7test3_Ii: // CHECK-NEXT: .quad (__ZTVN10__cxxabiv129__pointer_to_member_type_infoE) + 16 // CHECK-NEXT: .quad __ZTSM7test3_Ii // CHECK-NEXT: .long 16 @@ -57,6 +57,19 @@ class test1_D : public test1_B7 { // CHECK-NEXT: .quad __ZTIi // CHECK-NEXT: .quad __ZTI7test3_I +// CHECK: __ZTIFvvE: +// CHECK-NEXT: .quad (__ZTVN10__cxxabiv120__function_type_infoE) + 16 +// CHECK-NEXT: .quad __ZTSFvvE + +// CHECK: __ZTIM7test3_AFvvE: +// CHECK-NEXT: .quad (__ZTVN10__cxxabiv129__pointer_to_member_type_infoE) + 16 +// CHECK-NEXT: .quad __ZTSM7test3_AFvvE +// CHECK-NEXT: .space 4 +// CHECK-NEXT: .space 4 +// CHECK-NEXT: .quad __ZTIFvvE +// CHECK-NEXT: .quad __ZTI7test3_A + + // CHECK:__ZTI7test1_D: // CHECK-NEXT: .quad (__ZTVN10__cxxabiv120__si_class_type_infoE) + 16 @@ -167,10 +180,13 @@ class test3_A { }; class test3_I; int (test3_A::*pmd); int (test3_I::*i_pmd); +void (test3_A::*pmf)(); int test3() { if (typeid(volatile int *) == typeid(int *)) return 1; if (typeid(pmd) == typeid(i_pmd)) return 1; + if (typeid(pmd) == typeid(pmf)) + return 1; return 0; } -- 2.40.0