From: Mike Stump Date: Tue, 17 Nov 2009 22:33:00 +0000 (+0000) Subject: Add rtti support for pointer to data members. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5fae856de2520b63fd371c281a9d36c1547e17f3;p=clang Add rtti support for pointer to data members. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89155 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCXXExpr.cpp b/lib/CodeGen/CGCXXExpr.cpp index 153effe907..a93210904d 100644 --- a/lib/CodeGen/CGCXXExpr.cpp +++ b/lib/CodeGen/CGCXXExpr.cpp @@ -359,6 +359,9 @@ llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { return Builder.CreateBitCast(CGM.GenerateRttiNonClass(Ty), LTy); } Expr *subE = E->getExprOperand(); + Ty = subE->getType(); + CanQualType CanTy = CGM.getContext().getCanonicalType(Ty); + Ty = CanTy.getUnqualifiedType().getNonReferenceType(); if (const RecordType *RT = Ty->getAs()) { const CXXRecordDecl *RD = cast(RT->getDecl()); if (RD->isPolymorphic()) { @@ -397,9 +400,6 @@ llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { } return Builder.CreateBitCast(CGM.GenerateRtti(RD), LTy); } - Ty = subE->getType(); - CanQualType CanTy = CGM.getContext().getCanonicalType(Ty); - Ty = CanTy.getUnqualifiedType().getNonReferenceType(); return Builder.CreateBitCast(CGM.GenerateRttiNonClass(Ty), LTy); } diff --git a/lib/CodeGen/CGRtti.cpp b/lib/CodeGen/CGRtti.cpp index c7044e5987..901c34a281 100644 --- a/lib/CodeGen/CGRtti.cpp +++ b/lib/CodeGen/CGRtti.cpp @@ -263,10 +263,13 @@ public: std::vector info; QualType PTy = Ty->getPointeeType(); - // FIXME: ptr-mem data QualType BTy; - // FIXME: ptr-mem data bool PtrMem = false; + if (const MemberPointerType *MPT = dyn_cast(Ty)) { + PtrMem = true; + BTy = QualType(MPT->getClass(), 0); + PTy = MPT->getPointeeType(); + } if (PtrMem) C = BuildVtableRef("_ZTVN10__cxxabiv129__pointer_to_member_type_infoE"); @@ -335,6 +338,8 @@ public: return BuildPointerType(Ty); } + case Type::MemberPointer: + return BuildPointerType(Ty); } } }; diff --git a/test/CodeGenCXX/rtti.cpp b/test/CodeGenCXX/rtti.cpp index c761bdf46f..3d8f116fc1 100644 --- a/test/CodeGenCXX/rtti.cpp +++ b/test/CodeGenCXX/rtti.cpp @@ -41,6 +41,23 @@ class test1_D : public test1_B7 { // CHECK-NEXT: .space 4 // CHECK-NEXT: .quad __ZTIi +// CHECK: __ZTIM7test3_Ai: +// CHECK-NEXT: .quad (__ZTVN10__cxxabiv129__pointer_to_member_type_infoE) + 16 +// CHECK-NEXT: .quad __ZTSM7test3_Ai +// CHECK-NEXT: .space 4 +// CHECK-NEXT: .space 4 +// CHECK-NEXT: .quad __ZTIi +// CHECK-NEXT: .quad __ZTI7test3_A + +// CHECK:__ZTIM7test3_Ii: +// CHECK-NEXT: .quad (__ZTVN10__cxxabiv129__pointer_to_member_type_infoE) + 16 +// CHECK-NEXT: .quad __ZTSM7test3_Ii +// CHECK-NEXT: .long 16 +// CHECK-NEXT: .space 4 +// CHECK-NEXT: .quad __ZTIi +// CHECK-NEXT: .quad __ZTI7test3_I + + // CHECK:__ZTI7test1_D: // CHECK-NEXT: .quad (__ZTVN10__cxxabiv120__si_class_type_infoE) + 16 // CHECK-NEXT: .quad __ZTS7test1_D @@ -126,9 +143,9 @@ void test2_2(test1_D *dp) { // CHECK-LL-NEXT: %vtable = load %"class.std::type_info"*** %0 // CHECK-LL-NEXT: %1 = getelementptr inbounds %"class.std::type_info"** %vtable, i64 -1 // CHECK-LL-NEXT: %2 = load %"class.std::type_info"** %1 -// CHECK-LL-NEXT: %call = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* %2, %"class.std::type_info"* bitcast (%2* @_ZTI7test1_D to %"class.std::type_info"*)) +// CHECK-LL-NEXT: %call = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* %2, %"class.std::type_info"* bitcast (%{{[0-9]*}}* @_ZTI7test1_D to %"class.std::type_info"*)) -// CHECK-LL: %call2 = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* bitcast (%0* @_ZTI2NP to %"class.std::type_info"*), %"class.std::type_info"* bitcast (%2* @_ZTI7test1_D to %"class.std::type_info"*)) +// CHECK-LL: %call2 = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* bitcast (%0* @_ZTI2NP to %"class.std::type_info"*), %"class.std::type_info"* bitcast (%{{[0-9]*}}* @_ZTI7test1_D to %"class.std::type_info"*)) // CHECK-LL: %3 = bitcast %class.test1_B7* %tmp5 to %"class.std::type_info"*** // CHECK-LL-NEXT: %4 = icmp ne %"class.std::type_info"*** %3, null @@ -140,14 +157,20 @@ void test2_2(test1_D *dp) { // CHECK-LL-NEXT: %vtable6 = load %"class.std::type_info"*** %3 // CHECK-LL-NEXT: %7 = getelementptr inbounds %"class.std::type_info"** %vtable6, i64 -1 // CHECK-LL-NEXT: %8 = load %"class.std::type_info"** %7 -// CHECK-LL-NEXT: %call7 = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* %8, %"class.std::type_info"* bitcast (%2* @_ZTI7test1_D to %"class.std::type_info"*)) +// CHECK-LL-NEXT: %call7 = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* %8, %"class.std::type_info"* bitcast (%{{[0-9]*}}* @_ZTI7test1_D to %"class.std::type_info"*)) // CHECK-LL: %call10 = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* bitcast (i8** @_ZTIi to %"class.std::type_info"*), %"class.std::type_info"* bitcast (i8** @_ZTIf to %"class.std::type_info"*)) // CHECK-LL: %call13 = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* bitcast (i8** @_ZTIPi to %"class.std::type_info"*), %"class.std::type_info"* bitcast (i8** @_ZTIPKi to %"class.std::type_info"*)) +class test3_A { }; +class test3_I; +int (test3_A::*pmd); +int (test3_I::*i_pmd); int test3() { if (typeid(volatile int *) == typeid(int *)) return 1; + if (typeid(pmd) == typeid(i_pmd)) + return 1; return 0; }