diff options
-rw-r--r-- | clang/lib/CodeGen/CGCXXExpr.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGRtti.cpp | 9 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/rtti.cpp | 29 |
3 files changed, 36 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CGCXXExpr.cpp b/clang/lib/CodeGen/CGCXXExpr.cpp index 153effe9076..a93210904d1 100644 --- a/clang/lib/CodeGen/CGCXXExpr.cpp +++ b/clang/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<RecordType>()) { const CXXRecordDecl *RD = cast<CXXRecordDecl>(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/clang/lib/CodeGen/CGRtti.cpp b/clang/lib/CodeGen/CGRtti.cpp index c7044e59873..901c34a2812 100644 --- a/clang/lib/CodeGen/CGRtti.cpp +++ b/clang/lib/CodeGen/CGRtti.cpp @@ -263,10 +263,13 @@ public: std::vector<llvm::Constant *> info; QualType PTy = Ty->getPointeeType(); - // FIXME: ptr-mem data QualType BTy; - // FIXME: ptr-mem data bool PtrMem = false; + if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(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/clang/test/CodeGenCXX/rtti.cpp b/clang/test/CodeGenCXX/rtti.cpp index c761bdf46f3..3d8f116fc13 100644 --- a/clang/test/CodeGenCXX/rtti.cpp +++ b/clang/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; } |