1 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s 2 #include <typeinfo> 3 4 // vtables. 5 extern "C" { 6 const void *_ZTVN10__cxxabiv123__fundamental_type_infoE; 7 const void *_ZTVN10__cxxabiv117__class_type_infoE; 8 const void *_ZTVN10__cxxabiv120__si_class_type_infoE; 9 const void *_ZTVN10__cxxabiv121__vmi_class_type_infoE; 10 const void *_ZTVN10__cxxabiv119__pointer_type_infoE; 11 const void *_ZTVN10__cxxabiv129__pointer_to_member_type_infoE; 12 }; 13 #define fundamental_type_info_vtable _ZTVN10__cxxabiv123__fundamental_type_infoE 14 #define class_type_info_vtable _ZTVN10__cxxabiv117__class_type_infoE 15 #define si_class_type_info_vtable _ZTVN10__cxxabiv120__si_class_type_infoE 16 #define vmi_class_type_info_vtable _ZTVN10__cxxabiv121__vmi_class_type_infoE 17 #define pointer_type_info_vtable _ZTVN10__cxxabiv119__pointer_type_infoE 18 #define pointer_to_member_type_info_vtable _ZTVN10__cxxabiv129__pointer_to_member_type_infoE 19 20 class __pbase_type_info : public std::type_info { 21 public: 22 unsigned int __flags; 23 const std::type_info *__pointee; 24 25 enum __masks { 26 __const_mask = 0x1, 27 __volatile_mask = 0x2, 28 __restrict_mask = 0x4, 29 __incomplete_mask = 0x8, 30 __incomplete_class_mask = 0x10 31 }; 32 }; 33 34 class __class_type_info : public std::type_info { }; 35 36 class __si_class_type_info : public __class_type_info { 37 public: 38 const __class_type_info *__base_type; 39 }; 40 41 template<typename T> const T& to(const std::type_info &info) { 42 return static_cast<const T&>(info); 43 } 44 struct Incomplete; 45 46 struct A { int a; }; 47 struct Empty { }; 48 49 struct SI1 : A { }; 50 struct SI2 : Empty { }; 51 struct SI3 : Empty { virtual void f() { } }; 52 53 struct VMI1 : private A { }; 54 struct VMI2 : virtual A { }; 55 struct VMI3 : A { virtual void f() { } }; 56 struct VMI4 : A, Empty { }; 57 58 #define CHECK(x) if (!(x)) return __LINE__ 59 #define CHECK_VTABLE(type, vtable) if (&vtable##_type_info_vtable + 2 != (((void **)&(typeid(type)))[0])) return __LINE__ 60 61 // CHECK: define i32 @_Z1fv() 62 int f() { 63 // Vectors should be treated as fundamental types. 64 typedef short __v4hi __attribute__ ((__vector_size__ (8))); 65 CHECK_VTABLE(__v4hi, fundamental); 66 67 // A does not have any bases. 68 CHECK_VTABLE(A, class); 69 70 // SI1 has a single public base. 71 CHECK_VTABLE(SI1, si_class); 72 73 // SI2 has a single public empty base. 74 CHECK_VTABLE(SI2, si_class); 75 76 // SI3 has a single public empty base. SI3 is dynamic whereas Empty is not, but since Empty is 77 // an empty class, it will still be at offset zero. 78 CHECK_VTABLE(SI3, si_class); 79 80 // VMI1 has a single base, but it is private. 81 CHECK_VTABLE(VMI1, vmi_class); 82 83 // VMI2 has a single base, but it is virtual. 84 CHECK_VTABLE(VMI2, vmi_class); 85 86 // VMI3 has a single base, but VMI3 is dynamic whereas A is not, and A is not empty. 87 CHECK_VTABLE(VMI3, vmi_class); 88 89 // VMI4 has two bases. 90 CHECK_VTABLE(VMI4, vmi_class); 91 92 CHECK(to<__si_class_type_info>(typeid(SI1)).__base_type == &typeid(A)); 93 CHECK(to<__si_class_type_info>(typeid(SI2)).__base_type == &typeid(Empty)); 94 CHECK(to<__si_class_type_info>(typeid(SI3)).__base_type == &typeid(Empty)); 95 96 // Pointers to incomplete classes. 97 CHECK_VTABLE(Incomplete *, pointer); 98 CHECK(to<__pbase_type_info>(typeid(Incomplete *)).__flags == __pbase_type_info::__incomplete_mask); 99 CHECK(to<__pbase_type_info>(typeid(Incomplete **)).__flags == __pbase_type_info::__incomplete_mask); 100 CHECK(to<__pbase_type_info>(typeid(Incomplete ***)).__flags == __pbase_type_info::__incomplete_mask); 101 102 // Member pointers. 103 CHECK_VTABLE(int Incomplete::*, pointer_to_member); 104 CHECK(to<__pbase_type_info>(typeid(int Incomplete::*)).__flags == __pbase_type_info::__incomplete_class_mask); 105 CHECK(to<__pbase_type_info>(typeid(Incomplete Incomplete::*)).__flags == (__pbase_type_info::__incomplete_class_mask | __pbase_type_info::__incomplete_mask)); 106 CHECK(to<__pbase_type_info>(typeid(Incomplete A::*)).__flags == (__pbase_type_info::__incomplete_mask)); 107 108 // Success! 109 // CHECK: ret i32 0 110 return 0; 111 } 112 113 #ifdef HARNESS 114 extern "C" void printf(const char *, ...); 115 116 int main() { 117 int result = f(); 118 119 if (result == 0) 120 printf("success!\n"); 121 else 122 printf("test on line %d failed!\n", result); 123 124 return result; 125 } 126 #endif 127 128 129