rtti-layout.cpp revision 2c0769e3e4ba4ad375421f0a6c6b110ed19a6dfe
1// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s 2#include <typeinfo> 3 4// vtables. 5extern "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 20class __pbase_type_info : public std::type_info { 21public: 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 34template<typename T> const T& to(const std::type_info &info) { 35return static_cast<const T&>(info); 36} 37struct Incomplete; 38 39struct A { int a; }; 40struct Empty { }; 41 42struct SI1 : A { }; 43struct SI2 : Empty { }; 44struct SI3 : Empty { virtual void f() { } }; 45 46struct VMI1 : private A { }; 47struct VMI2 : virtual A { }; 48struct VMI3 : A { virtual void f() { } }; 49struct VMI4 : A, Empty { }; 50 51#define CHECK(x) if (!(x)) return __LINE__ 52#define CHECK_VTABLE(type, vtable) if (&vtable##_type_info_vtable + 2 != (((void **)&(typeid(type)))[0])) return __LINE__ 53 54// CHECK: define i32 @_Z1fv() 55int f() { 56 // Vectors should be treated as fundamental types. 57 typedef short __v4hi __attribute__ ((__vector_size__ (8))); 58 CHECK_VTABLE(__v4hi, fundamental); 59 60 // A does not have any bases. 61 CHECK_VTABLE(A, class); 62 63 // SI1 has a single public base. 64 CHECK_VTABLE(SI1, si_class); 65 66 // SI2 has a single public empty base. 67 CHECK_VTABLE(SI2, si_class); 68 69 // SI3 has a single public empty base. SI3 is dynamic whereas Empty is not, but since Empty is 70 // an empty class, it will still be at offset zero. 71 CHECK_VTABLE(SI3, si_class); 72 73 // VMI1 has a single base, but it is private. 74 CHECK_VTABLE(VMI1, vmi_class); 75 76 // VMI2 has a single base, but it is virtual. 77 CHECK_VTABLE(VMI2, vmi_class); 78 79 // VMI3 has a single base, but VMI3 is dynamic whereas A is not, and A is not empty. 80 CHECK_VTABLE(VMI3, vmi_class); 81 82 // VMI4 has two bases. 83 CHECK_VTABLE(VMI4, vmi_class); 84 85 // Pointers to incomplete classes. 86 CHECK_VTABLE(Incomplete *, pointer); 87 CHECK(to<__pbase_type_info>(typeid(Incomplete *)).__flags == __pbase_type_info::__incomplete_mask); 88 CHECK(to<__pbase_type_info>(typeid(Incomplete **)).__flags == __pbase_type_info::__incomplete_mask); 89 CHECK(to<__pbase_type_info>(typeid(Incomplete ***)).__flags == __pbase_type_info::__incomplete_mask); 90 91 // Member pointers. 92 CHECK_VTABLE(int Incomplete::*, pointer_to_member); 93 CHECK(to<__pbase_type_info>(typeid(int Incomplete::*)).__flags == __pbase_type_info::__incomplete_class_mask); 94 CHECK(to<__pbase_type_info>(typeid(Incomplete Incomplete::*)).__flags == (__pbase_type_info::__incomplete_class_mask | __pbase_type_info::__incomplete_mask)); 95 CHECK(to<__pbase_type_info>(typeid(Incomplete A::*)).__flags == (__pbase_type_info::__incomplete_mask)); 96 97 // Success! 98 // CHECK: ret i32 0 99 return 0; 100} 101 102#ifdef HARNESS 103extern "C" void printf(const char *, ...); 104 105int main() { 106 int result = f(); 107 108 if (result == 0) 109 printf("success!\n"); 110 else 111 printf("test on line %d failed!\n", result); 112 113 return result; 114} 115#endif 116 117 118