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__cxxabiv119__pointer_type_infoE; 10 const void *_ZTVN10__cxxabiv129__pointer_to_member_type_infoE; 11 }; 12 #define fundamental_type_info_vtable _ZTVN10__cxxabiv123__fundamental_type_infoE 13 #define class_type_info_vtable _ZTVN10__cxxabiv117__class_type_infoE 14 #define si_class_type_info_vtable _ZTVN10__cxxabiv120__si_class_type_infoE 15 #define pointer_type_info_vtable _ZTVN10__cxxabiv119__pointer_type_infoE 16 #define pointer_to_member_type_info_vtable _ZTVN10__cxxabiv129__pointer_to_member_type_infoE 17 18 class __pbase_type_info : public std::type_info { 19 public: 20 unsigned int __flags; 21 const std::type_info *__pointee; 22 23 enum __masks { 24 __const_mask = 0x1, 25 __volatile_mask = 0x2, 26 __restrict_mask = 0x4, 27 __incomplete_mask = 0x8, 28 __incomplete_class_mask = 0x10 29 }; 30 }; 31 32 template<typename T> const T& to(const std::type_info &info) { 33 return static_cast<const T&>(info); 34 } 35 struct Incomplete; 36 37 struct A { }; 38 39 #define CHECK(x) if (!(x)) return __LINE__ 40 #define CHECK_VTABLE(type, vtable) if (&vtable##_type_info_vtable + 2 != (((void **)&(typeid(type)))[0])) return __LINE__ 41 42 // CHECK: define i32 @_Z1fv() 43 int f() { 44 // Vectors should be treated as fundamental types. 45 typedef short __v4hi __attribute__ ((__vector_size__ (8))); 46 CHECK_VTABLE(__v4hi, fundamental); 47 48 // Pointers to incomplete classes. 49 CHECK_VTABLE(Incomplete *, pointer); 50 CHECK(to<__pbase_type_info>(typeid(Incomplete *)).__flags == __pbase_type_info::__incomplete_mask); 51 CHECK(to<__pbase_type_info>(typeid(Incomplete **)).__flags == __pbase_type_info::__incomplete_mask); 52 CHECK(to<__pbase_type_info>(typeid(Incomplete ***)).__flags == __pbase_type_info::__incomplete_mask); 53 54 // Member pointers. 55 CHECK_VTABLE(int Incomplete::*, pointer_to_member); 56 CHECK(to<__pbase_type_info>(typeid(int Incomplete::*)).__flags == __pbase_type_info::__incomplete_class_mask); 57 CHECK(to<__pbase_type_info>(typeid(Incomplete Incomplete::*)).__flags == (__pbase_type_info::__incomplete_class_mask | __pbase_type_info::__incomplete_mask)); 58 CHECK(to<__pbase_type_info>(typeid(Incomplete A::*)).__flags == (__pbase_type_info::__incomplete_mask)); 59 60 // Success! 61 // CHECK: ret i32 0 62 return 0; 63 } 64 65 #ifdef HARNESS 66 extern "C" void printf(const char *, ...); 67 68 int main() { 69 int result = f(); 70 71 if (result == 0) 72 printf("success!\n"); 73 else 74 printf("test on line %d failed!\n", result); 75 76 return result; 77 } 78 #endif 79 80 81