1 // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin9 | FileCheck %s
2 // RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-apple-darwin9 | FileCheck -check-prefix LP32 %s
3 // RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-unknown-unknown | FileCheck -check-prefix ARM %s
4 
5 struct A { int a; void f(); virtual void vf1(); virtual void vf2(); };
6 struct B { int b; virtual void g(); };
7 struct C : B, A { };
8 
9 void (A::*pa)();
10 void (A::*volatile vpa)();
11 void (B::*pb)();
12 void (C::*pc)();
13 
14 // CHECK: @pa2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }, align 8
15 void (A::*pa2)() = &A::f;
16 
17 // CHECK:      @pa3 = global %0 { i64 1, i64 0 }, align 8
18 // CHECK-LP32: @pa3 = global %0 { i32 1, i32 0 }, align 4
19 void (A::*pa3)() = &A::vf1;
20 
21 // CHECK:      @pa4 = global %0 { i64 9, i64 0 }, align 8
22 // CHECK-LP32: @pa4 = global %0 { i32 5, i32 0 }, align 4
23 void (A::*pa4)() = &A::vf2;
24 
25 // CHECK: @pc2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 16 }, align 8
26 void (C::*pc2)() = &C::f;
27 
28 // CHECK: @pc3 = global %0 { i64 1, i64 0 }, align 8
29 void (A::*pc3)() = &A::vf1;
30 
31 void f() {
32   // CHECK: store %0 zeroinitializer, %0* @pa
33   pa = 0;
34 
35   // Is this okay?  What are LLVM's volatile semantics for structs?
36   // CHECK: volatile store %0 zeroinitializer, %0* @vpa
37   vpa = 0;
38 
39   // CHECK: [[TMP:%.*]] = load %0* @pa, align 8
40   // CHECK: [[TMPPTR:%.*]] = extractvalue %0 [[TMP]], 0
41   // CHECK: [[TMPADJ:%.*]] = extractvalue %0 [[TMP]], 1
42   // CHECK: [[RES0:%.*]] = insertvalue %0 undef, i64 [[TMPPTR]], 0
43   // CHECK: [[ADJ:%.*]] = add i64 [[TMPADJ]], 16
44   // CHECK: [[RES1:%.*]] = insertvalue %0 [[RES0]], i64 [[ADJ]], 1
45   // CHECK: store %0 [[RES1]], %0* @pc, align 8
46   pc = pa;
47 
48   // CHECK: [[TMP:%.*]] = load %0* @pc, align 8
49   // CHECK: [[TMPPTR:%.*]] = extractvalue %0 [[TMP]], 0
50   // CHECK: [[TMPADJ:%.*]] = extractvalue %0 [[TMP]], 1
51   // CHECK: [[RES0:%.*]] = insertvalue %0 undef, i64 [[TMPPTR]], 0
52   // CHECK: [[ADJ:%.*]] = sub i64 [[TMPADJ]], 16
53   // CHECK: [[RES1:%.*]] = insertvalue %0 [[RES0]], i64 [[ADJ]], 1
54   // CHECK: store %0 [[RES1]], %0* @pa, align 8
55   pa = static_cast<void (A::*)()>(pc);
56 }
57 
58 void f2() {
59   // CHECK:      store %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }
60   void (A::*pa2)() = &A::f;
61 
62   // CHECK:      store %0 { i64 1, i64 0 }
63   // CHECK-LP32: store %0 { i32 1, i32 0 }
64   void (A::*pa3)() = &A::vf1;
65 
66   // CHECK:      store %0 { i64 9, i64 0 }
67   // CHECK-LP32: store %0 { i32 5, i32 0 }
68   void (A::*pa4)() = &A::vf2;
69 }
70 
71 void f3(A *a, A &ar) {
72   (a->*pa)();
73   (ar.*pa)();
74 }
75 
76 bool f4() {
77   return pa;
78 }
79 
80 // PR5177
81 namespace PR5177 {
82   struct A {
83    bool foo(int*) const;
84   } a;
85 
86   struct B1 {
87    bool (A::*pmf)(int*) const;
88    const A* pa;
89 
90    B1() : pmf(&A::foo), pa(&a) {}
91    bool operator()() const { return (pa->*pmf)(new int); }
92   };
93 
94   void bar(B1 b2) { while (b2()) ; }
95 }
96 
97 // PR5138
98 namespace PR5138 {
99   struct foo {
100       virtual void bar(foo *);
101   };
102 
103   extern "C" {
104     void baz(foo *);
105   }
106 
107   void (foo::*ptr1)(void *) = (void (foo::*)(void *))&foo::bar;
108   void (*ptr2)(void *) = (void (*)(void *))&baz;
109 
110   void (foo::*ptr3)(void) = (void (foo::*)(void))&foo::bar;
111 }
112 
113 // PR5593
114 namespace PR5593 {
115   struct A { };
116 
117   bool f(void (A::*f)()) {
118     return f && f;
119   }
120 }
121 
122 namespace PR5718 {
123   struct A { };
124 
125   bool f(void (A::*f)(), void (A::*g)()) {
126     return f == g;
127   }
128 }
129 
130 namespace BoolMemberPointer {
131   struct A { };
132 
133   bool f(void (A::*f)()) {
134     return !f;
135   }
136 
137   bool g(void (A::*f)()) {
138     if (!!f)
139       return true;
140     return false;
141   }
142 }
143 
144 // PR5940
145 namespace PR5940 {
146   class foo {
147   public:
148     virtual void baz(void);
149   };
150 
151   void foo::baz(void) {
152        void (foo::*ptr)(void) = &foo::baz;
153   }
154 }
155 
156 namespace MemberPointerImpCast {
157   struct A {
158     int x;
159   };
160   struct B : public A {
161   };
162   void f(B* obj, void (A::*method)()) {
163     (obj->*method)();
164   }
165 }
166 
167 // PR6258
168 namespace PR6258 {
169 
170   struct A {
171     void f(bool);
172   };
173 
174   void (A::*pf)(bool) = &A::f;
175 
176   void f() {
177     void (A::*pf)(bool) = &A::f;
178   }
179 }
180 
181 // PR7027
182 namespace PR7027 {
183   struct X { void test( ); };
184   void testX() { &X::test; }
185 }
186 
187 namespace test7 {
188   struct A { void foo(); virtual void vfoo(); };
189   struct B { void foo(); virtual void vfoo(); };
190   struct C : A, B { void foo(); virtual void vfoo(); };
191 
192   // CHECK-ARM: @_ZN5test74ptr0E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71A3fooEv to i32), i32 0 }
193   // CHECK-ARM: @_ZN5test74ptr1E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71B3fooEv to i32), i32 8 }
194   // CHECK-ARM: @_ZN5test74ptr2E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71C3fooEv to i32), i32 0 }
195   // CHECK-ARM: @_ZN5test74ptr3E = global {{.*}} { i32 0, i32 1 }
196   // CHECK-ARM: @_ZN5test74ptr4E = global {{.*}} { i32 0, i32 9 }
197   // CHECK-ARM: @_ZN5test74ptr5E = global {{.*}} { i32 0, i32 1 }
198   void (C::*ptr0)() = &A::foo;
199   void (C::*ptr1)() = &B::foo;
200   void (C::*ptr2)() = &C::foo;
201   void (C::*ptr3)() = &A::vfoo;
202   void (C::*ptr4)() = &B::vfoo;
203   void (C::*ptr5)() = &C::vfoo;
204 }
205