xref: /llvm-project/clang/test/CodeGenCXX/RelativeVTablesABI/type-info.cpp (revision 6bb63002fca8a7cfa9ff8ffd86da4c2ca3d98a3b)
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