1 // Check typeid() + type_info 2 3 // RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O3 -o - -emit-llvm -fcxx-exceptions -fexceptions | FileCheck %s 4 5 // CHECK: $_ZTI1A.rtti_proxy = comdat any 6 // CHECK: $_ZTI1B.rtti_proxy = comdat any 7 8 // CHECK: @_ZTI1A ={{.*}} constant { ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i32 8), ptr @_ZTS1A }, align 8 9 // CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] 10 // CHECK: @_ZTS1A ={{.*}} constant [3 x i8] c"1A\00", align 1 11 // CHECK: @_ZTI1B ={{.*}} constant { ptr, ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i32 8), ptr @_ZTS1B, ptr @_ZTI1A }, align 8 12 // CHECK: @_ZTVN10__cxxabiv120__si_class_type_infoE = external global [0 x ptr] 13 // CHECK: @_ZTS1B ={{.*}} constant [3 x i8] c"1B\00", align 1 14 // CHECK: @_ZTI1A.rtti_proxy = linkonce_odr hidden unnamed_addr constant ptr @_ZTI1A, comdat 15 // CHECK: @_ZTI1B.rtti_proxy = linkonce_odr hidden unnamed_addr constant ptr @_ZTI1B, comdat 16 17 // CHECK: define {{.*}}ptr @_Z11getTypeInfov() local_unnamed_addr 18 // CHECK-NEXT: entry: 19 // CHECK-NEXT: ret ptr @_ZTI1A 20 // CHECK-NEXT: } 21 22 // CHECK: define{{.*}} ptr @_Z7getNamev() local_unnamed_addr 23 // CHECK-NEXT: entry: 24 // CHECK-NEXT: ret ptr @_ZTS1A 25 // CHECK-NEXT: } 26 27 // CHECK: define{{.*}} i1 @_Z5equalP1A(ptr noundef readonly %a) local_unnamed_addr 28 // CHECK-NEXT: entry: 29 // CHECK-NEXT: [[isnull:%[0-9]+]] = icmp eq ptr %a, null 30 // CHECK-NEXT: br i1 [[isnull]], label %[[bad_typeid:[a-z0-9._]+]], label %[[end:[a-z0-9.+]+]] 31 // CHECK: [[bad_typeid]]: 32 // CHECK-NEXT: tail call void @__cxa_bad_typeid() 33 // CHECK-NEXT: unreachable 34 // CHECK: [[end]]: 35 // CHECK-NEXT: [[vtable:%[a-z0-9]+]] = load ptr, ptr %a 36 // CHECK-NEXT: [[type_info_ptr:%[0-9]+]] = tail call ptr @llvm.load.relative.i32(ptr [[vtable]], i32 -4) 37 // CHECK-NEXT: [[type_info_ptr2:%[0-9]+]] = load ptr, ptr [[type_info_ptr]], align 8 38 // CHECK-NEXT: [[name_ptr:%[a-z0-9._]+]] = getelementptr inbounds nuw i8, ptr [[type_info_ptr2]], i64 8 39 // CHECK-NEXT: [[name:%[0-9]+]] = load ptr, ptr [[name_ptr]], align 8 40 // CHECK-NEXT: [[eq:%[a-z0-9.]+]] = icmp eq ptr [[name]], @_ZTS1B 41 // CHECK-NEXT: ret i1 [[eq]] 42 // CHECK-NEXT: } 43 44 #include "../typeinfo" 45 46 class A { 47 public: 48 virtual void foo(); 49 }; 50 51 class B : public A { 52 public: 53 void foo() override; 54 }; 55 56 void A::foo() {} 57 void B::foo() {} 58 59 const auto &getTypeInfo() { 60 return typeid(A); 61 } 62 63 const char *getName() { 64 return typeid(A).name(); 65 } 66 67 bool equal(A *a) { 68 return typeid(B) == typeid(*a); 69 } 70