File: type-info.cpp

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (69 lines) | stat: -rw-r--r-- 2,586 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// Check typeid() + type_info

// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O3 -o - -emit-llvm -fcxx-exceptions -fexceptions | FileCheck %s

// CHECK: $_ZTI1A.rtti_proxy = comdat any
// CHECK: $_ZTI1B.rtti_proxy = comdat any

// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
// CHECK: @_ZTS1A ={{.*}} constant [3 x i8] c"1A\00", align 1
// CHECK: @_ZTI1A ={{.*}} constant { ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i32 8), ptr @_ZTS1A }, align 8
// CHECK: @_ZTVN10__cxxabiv120__si_class_type_infoE = external global [0 x ptr]
// CHECK: @_ZTS1B ={{.*}} constant [3 x i8] c"1B\00", align 1
// 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
// CHECK: @_ZTI1A.rtti_proxy = linkonce_odr hidden unnamed_addr constant ptr @_ZTI1A, comdat
// CHECK: @_ZTI1B.rtti_proxy = linkonce_odr hidden unnamed_addr constant ptr @_ZTI1B, comdat

// CHECK:      define {{.*}}ptr @_Z11getTypeInfov() local_unnamed_addr
// CHECK-NEXT: entry:
// CHECK-NEXT:   ret ptr @_ZTI1A
// CHECK-NEXT: }

// CHECK:      define{{.*}} ptr @_Z7getNamev() local_unnamed_addr
// CHECK-NEXT: entry:
// CHECK-NEXT:   ret ptr @_ZTS1A
// CHECK-NEXT: }

// CHECK:      define{{.*}} i1 @_Z5equalP1A(ptr noundef readonly %a) local_unnamed_addr
// CHECK-NEXT: entry:
// CHECK-NEXT:   [[isnull:%[0-9]+]] = icmp eq ptr %a, null
// CHECK-NEXT:   br i1 [[isnull]], label %[[bad_typeid:[a-z0-9._]+]], label %[[end:[a-z0-9.+]+]]
// CHECK:      [[bad_typeid]]:
// CHECK-NEXT:   tail call void @__cxa_bad_typeid()
// CHECK-NEXT:   unreachable
// CHECK:      [[end]]:
// CHECK-NEXT:   [[vtable:%[a-z0-9]+]] = load ptr, ptr %a
// CHECK-NEXT:   [[type_info_ptr:%[0-9]+]] = tail call ptr @llvm.load.relative.i32(ptr [[vtable]], i32 -4)
// CHECK-NEXT:   [[type_info_ptr2:%[0-9]+]] = load ptr, ptr [[type_info_ptr]], align 8
// CHECK-NEXT:   [[name_ptr:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[type_info_ptr2]], i64 8
// CHECK-NEXT:   [[name:%[0-9]+]] = load ptr, ptr [[name_ptr]], align 8
// CHECK-NEXT:   [[eq:%[a-z0-9.]+]] = icmp eq ptr [[name]], @_ZTS1B
// CHECK-NEXT:   ret i1 [[eq]]
// CHECK-NEXT: }

#include "../typeinfo"

class A {
public:
  virtual void foo();
};

class B : public A {
public:
  void foo() override;
};

void A::foo() {}
void B::foo() {}

const auto &getTypeInfo() {
  return typeid(A);
}

const char *getName() {
  return typeid(A).name();
}

bool equal(A *a) {
  return typeid(B) == typeid(*a);
}