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
34class __class_type_info : public std::type_info { };
35
36class __si_class_type_info : public __class_type_info {
37public:
38  const __class_type_info *__base_type;
39};
40
41struct __base_class_type_info {
42public:
43 const __class_type_info *__base_type;
44 long __offset_flags;
45
46 enum __offset_flags_masks {
47   __virtual_mask = 0x1,
48   __public_mask = 0x2,
49   __offset_shift = 8
50 };
51};
52
53class __vmi_class_type_info : public __class_type_info {
54public:
55  unsigned int __flags;
56  unsigned int __base_count;
57  __base_class_type_info __base_info[1];
58
59  enum __flags_masks {
60    __non_diamond_repeat_mask = 0x1,
61    __diamond_shaped_mask = 0x2
62  };
63};
64
65template<typename T> const T& to(const std::type_info &info) {
66return static_cast<const T&>(info);
67}
68struct Incomplete;
69
70struct A { int a; };
71struct Empty { };
72
73struct SI1 : A { };
74struct SI2 : Empty { };
75struct SI3 : Empty { virtual void f() { } };
76
77struct VMI1 : private A { };
78struct VMI2 : virtual A { };
79struct VMI3 : A { virtual void f() { } };
80struct VMI4 : A, Empty { };
81
82struct VMIBase1 { int a; };
83struct VMIBase2 : VMIBase1 { int a; };
84struct VMI5 : VMIBase1, VMIBase2 { int a; };
85
86struct VMIBase3 : virtual VMIBase1 { int a; };
87struct VMI6 : virtual VMIBase1, VMIBase3 { int a; };
88
89struct VMI7 : VMIBase1, VMI5, private VMI6 { };
90
91#define CHECK(x) if (!(x)) return __LINE__
92#define CHECK_VTABLE(type, vtable) CHECK(&vtable##_type_info_vtable + 2 == (((void **)&(typeid(type)))[0]))
93#define CHECK_BASE_INFO_TYPE(type, index, base) CHECK(to<__vmi_class_type_info>(typeid(type)).__base_info[(index)].__base_type == &typeid(base))
94#define CHECK_BASE_INFO_OFFSET_FLAGS(type, index, offset, flags) CHECK(to<__vmi_class_type_info>(typeid(type)).__base_info[(index)].__offset_flags == (((offset) << 8) | (flags)))
95
96struct B {
97  static int const volatile (*a)[10];
98  static int (*b)[10];
99
100  static int const volatile (B::*c)[10];
101  static int (B::*d)[10];
102};
103
104// CHECK-LABEL: define i32 @_Z1fv()
105int f() {
106  // Vectors should be treated as fundamental types.
107  typedef short __v4hi __attribute__ ((__vector_size__ (8)));
108  CHECK_VTABLE(__v4hi, fundamental);
109
110  // A does not have any bases.
111  CHECK_VTABLE(A, class);
112
113  // SI1 has a single public base.
114  CHECK_VTABLE(SI1, si_class);
115  CHECK(to<__si_class_type_info>(typeid(SI1)).__base_type == &typeid(A));
116
117  // SI2 has a single public empty base.
118  CHECK_VTABLE(SI2, si_class);
119  CHECK(to<__si_class_type_info>(typeid(SI2)).__base_type == &typeid(Empty));
120
121  // SI3 has a single public empty base. SI3 is dynamic whereas Empty is not, but since Empty is
122  // an empty class, it will still be at offset zero.
123  CHECK_VTABLE(SI3, si_class);
124  CHECK(to<__si_class_type_info>(typeid(SI3)).__base_type == &typeid(Empty));
125
126  // VMI1 has a single base, but it is private.
127  CHECK_VTABLE(VMI1, vmi_class);
128
129  // VMI2 has a single base, but it is virtual.
130  CHECK_VTABLE(VMI2, vmi_class);
131
132  // VMI3 has a single base, but VMI3 is dynamic whereas A is not, and A is not empty.
133  CHECK_VTABLE(VMI3, vmi_class);
134
135  // VMI4 has two bases.
136  CHECK_VTABLE(VMI4, vmi_class);
137
138  // VMI5 has non-diamond shaped inheritance.
139  CHECK_VTABLE(VMI5, vmi_class);
140  CHECK(to<__vmi_class_type_info>(typeid(VMI5)).__flags == __vmi_class_type_info::__non_diamond_repeat_mask);
141  CHECK(to<__vmi_class_type_info>(typeid(VMI5)).__base_count == 2);
142  CHECK_BASE_INFO_TYPE(VMI5, 0, VMIBase1);
143  CHECK_BASE_INFO_OFFSET_FLAGS(VMI5, 0, 0, __base_class_type_info::__public_mask);
144  CHECK_BASE_INFO_TYPE(VMI5, 1, VMIBase2);
145  CHECK_BASE_INFO_OFFSET_FLAGS(VMI5, 1, 4, __base_class_type_info::__public_mask);
146
147  // VMI6 has diamond shaped inheritance.
148  CHECK_VTABLE(VMI6, vmi_class);
149  CHECK(to<__vmi_class_type_info>(typeid(VMI6)).__flags == __vmi_class_type_info::__diamond_shaped_mask);
150  CHECK(to<__vmi_class_type_info>(typeid(VMI6)).__base_count == 2);
151  CHECK_BASE_INFO_TYPE(VMI6, 0, VMIBase1);
152  CHECK_BASE_INFO_OFFSET_FLAGS(VMI6, 0, -24, __base_class_type_info::__public_mask | __base_class_type_info::__virtual_mask);
153  CHECK_BASE_INFO_TYPE(VMI6, 1, VMIBase3);
154  CHECK_BASE_INFO_OFFSET_FLAGS(VMI6, 1, 0, __base_class_type_info::__public_mask);
155
156  // VMI7 has both non-diamond and diamond shaped inheritance.
157  CHECK_VTABLE(VMI7, vmi_class);
158  CHECK(to<__vmi_class_type_info>(typeid(VMI7)).__flags == (__vmi_class_type_info::__non_diamond_repeat_mask | __vmi_class_type_info::__diamond_shaped_mask));
159  CHECK(to<__vmi_class_type_info>(typeid(VMI7)).__base_count == 3);
160  CHECK_BASE_INFO_TYPE(VMI7, 0, VMIBase1);
161  CHECK_BASE_INFO_OFFSET_FLAGS(VMI7, 0, 16, __base_class_type_info::__public_mask);
162  CHECK_BASE_INFO_TYPE(VMI7, 1, VMI5);
163  CHECK_BASE_INFO_OFFSET_FLAGS(VMI7, 1, 20, __base_class_type_info::__public_mask);
164  CHECK_BASE_INFO_TYPE(VMI7, 2, VMI6);
165  CHECK_BASE_INFO_OFFSET_FLAGS(VMI7, 2, 0, 0);
166
167  // Pointers to incomplete classes.
168  CHECK_VTABLE(Incomplete *, pointer);
169  CHECK(to<__pbase_type_info>(typeid(Incomplete *)).__flags == __pbase_type_info::__incomplete_mask);
170  CHECK(to<__pbase_type_info>(typeid(Incomplete **)).__flags == __pbase_type_info::__incomplete_mask);
171  CHECK(to<__pbase_type_info>(typeid(Incomplete ***)).__flags == __pbase_type_info::__incomplete_mask);
172
173  // Member pointers.
174  CHECK_VTABLE(int Incomplete::*, pointer_to_member);
175  CHECK(to<__pbase_type_info>(typeid(int Incomplete::*)).__flags == __pbase_type_info::__incomplete_class_mask);
176  CHECK(to<__pbase_type_info>(typeid(Incomplete Incomplete::*)).__flags == (__pbase_type_info::__incomplete_class_mask | __pbase_type_info::__incomplete_mask));
177  CHECK(to<__pbase_type_info>(typeid(Incomplete A::*)).__flags == (__pbase_type_info::__incomplete_mask));
178
179  // Check that when stripping qualifiers off the pointee type, we correctly handle arrays.
180  CHECK(to<__pbase_type_info>(typeid(B::a)).__flags == (__pbase_type_info::__const_mask | __pbase_type_info::__volatile_mask));
181  CHECK(to<__pbase_type_info>(typeid(B::a)).__pointee == to<__pbase_type_info>(typeid(B::b)).__pointee);
182  CHECK(to<__pbase_type_info>(typeid(B::c)).__flags == (__pbase_type_info::__const_mask | __pbase_type_info::__volatile_mask));
183  CHECK(to<__pbase_type_info>(typeid(B::c)).__pointee == to<__pbase_type_info>(typeid(B::d)).__pointee);
184
185  // Success!
186  // CHECK: ret i32 0
187  return 0;
188}
189
190#ifdef HARNESS
191extern "C" void printf(const char *, ...);
192
193int main() {
194  int result = f();
195
196  if (result == 0)
197    printf("success!\n");
198  else
199    printf("test on line %d failed!\n", result);
200
201  return result;
202}
203#endif
204
205
206