1 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s
2 #include <typeinfo>
3 
4 class __pbase_type_info : public std::type_info {
5 public:
6   unsigned int __flags;
7   const std::type_info *__pointee;
8 
9   enum __masks {
10     __const_mask = 0x1,
11     __volatile_mask = 0x2,
12     __restrict_mask = 0x4,
13     __incomplete_mask = 0x8,
14     __incomplete_class_mask = 0x10
15   };
16 };
17 
18 template<typename T> const T& to(const std::type_info &info) {
19 return static_cast<const T&>(info);
20 }
21 struct Incomplete;
22 
23 struct A { };
24 
25 #define CHECK(x) if (!(x)) return __LINE__;
26 
27 // CHECK: define i32 @_Z1fv()
28 int f() {
29   // Pointers to incomplete classes.
30   CHECK(to<__pbase_type_info>(typeid(Incomplete *)).__flags == __pbase_type_info::__incomplete_mask);
31   CHECK(to<__pbase_type_info>(typeid(Incomplete **)).__flags == __pbase_type_info::__incomplete_mask);
32   CHECK(to<__pbase_type_info>(typeid(Incomplete ***)).__flags == __pbase_type_info::__incomplete_mask);
33 
34   // Member pointers.
35   CHECK(to<__pbase_type_info>(typeid(int Incomplete::*)).__flags == __pbase_type_info::__incomplete_class_mask);
36   CHECK(to<__pbase_type_info>(typeid(Incomplete Incomplete::*)).__flags == (__pbase_type_info::__incomplete_class_mask | __pbase_type_info::__incomplete_mask));
37   CHECK(to<__pbase_type_info>(typeid(Incomplete A::*)).__flags == (__pbase_type_info::__incomplete_mask));
38 
39   // Success!
40   // CHECK: ret i32 0
41   return 0;
42 }
43 
44 #ifdef HARNESS
45 extern "C" void printf(const char *, ...);
46 
47 int main() {
48   int result = f();
49 
50   if (result == 0)
51     printf("success!\n");
52   else
53     printf("test on line %d failed!\n", result);
54 
55   return result;
56 }
57 #endif
58 
59 
60