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 i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0) 33 // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 1) 34 pa = 0; 35 36 // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 0) 37 // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 1) 38 vpa = 0; 39 40 // CHECK: store i64 {{.*}}, i64* getelementptr inbounds (%0* @pc, i32 0, i32 0) 41 // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 {{.*}}, 16 42 // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pc, i32 0, i32 1) 43 pc = pa; 44 45 // CHECK: store i64 {{.*}}, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0) 46 // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub i64 {{.*}}, 16 47 // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pa, i32 0, i32 1) 48 pa = static_cast<void (A::*)()>(pc); 49 } 50 51 void f2() { 52 // CHECK: [[pa2ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 0 53 // CHECK: store i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64* [[pa2ptr]] 54 // CHECK: [[pa2adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 1 55 // CHECK: store i64 0, i64* [[pa2adj]] 56 void (A::*pa2)() = &A::f; 57 58 // CHECK: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0 59 // CHECK: store i64 1, i64* [[pa3ptr]] 60 // CHECK: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1 61 // CHECK: store i64 0, i64* [[pa3adj]] 62 // CHECK-LP32: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0 63 // CHECK-LP32: store i32 1, i32* [[pa3ptr]] 64 // CHECK-LP32: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1 65 // CHECK-LP32: store i32 0, i32* [[pa3adj]] 66 void (A::*pa3)() = &A::vf1; 67 68 // CHECK: [[pa4ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 0 69 // CHECK: store i64 9, i64* [[pa4ptr]] 70 // CHECK: [[pa4adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 1 71 // CHECK: store i64 0, i64* [[pa4adj]] 72 // CHECK-LP32: [[pa4ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 0 73 // CHECK-LP32: store i32 5, i32* [[pa4ptr]] 74 // CHECK-LP32: [[pa4adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 1 75 // CHECK-LP32: store i32 0, i32* [[pa4adj]] 76 void (A::*pa4)() = &A::vf2; 77 } 78 79 void f3(A *a, A &ar) { 80 (a->*pa)(); 81 (ar.*pa)(); 82 } 83 84 bool f4() { 85 return pa; 86 } 87 88 // PR5177 89 namespace PR5177 { 90 struct A { 91 bool foo(int*) const; 92 } a; 93 94 struct B1 { 95 bool (A::*pmf)(int*) const; 96 const A* pa; 97 98 B1() : pmf(&A::foo), pa(&a) {} 99 bool operator()() const { return (pa->*pmf)(new int); } 100 }; 101 102 void bar(B1 b2) { while (b2()) ; } 103 } 104 105 // PR5138 106 namespace PR5138 { 107 struct foo { 108 virtual void bar(foo *); 109 }; 110 111 extern "C" { 112 void baz(foo *); 113 } 114 115 void (foo::*ptr1)(void *) = (void (foo::*)(void *))&foo::bar; 116 void (*ptr2)(void *) = (void (*)(void *))&baz; 117 118 void (foo::*ptr3)(void) = (void (foo::*)(void))&foo::bar; 119 } 120 121 // PR5593 122 namespace PR5593 { 123 struct A { }; 124 125 bool f(void (A::*f)()) { 126 return f && f; 127 } 128 } 129 130 namespace PR5718 { 131 struct A { }; 132 133 bool f(void (A::*f)(), void (A::*g)()) { 134 return f == g; 135 } 136 } 137 138 namespace BoolMemberPointer { 139 struct A { }; 140 141 bool f(void (A::*f)()) { 142 return !f; 143 } 144 145 bool g(void (A::*f)()) { 146 if (!!f) 147 return true; 148 return false; 149 } 150 } 151 152 // PR5940 153 namespace PR5940 { 154 class foo { 155 public: 156 virtual void baz(void); 157 }; 158 159 void foo::baz(void) { 160 void (foo::*ptr)(void) = &foo::baz; 161 } 162 } 163 164 namespace MemberPointerImpCast { 165 struct A { 166 int x; 167 }; 168 struct B : public A { 169 }; 170 void f(B* obj, void (A::*method)()) { 171 (obj->*method)(); 172 } 173 } 174 175 // PR6258 176 namespace PR6258 { 177 178 struct A { 179 void f(bool); 180 }; 181 182 void (A::*pf)(bool) = &A::f; 183 184 void f() { 185 void (A::*pf)(bool) = &A::f; 186 } 187 } 188 189 // PR7027 190 namespace PR7027 { 191 struct X { void test( ); }; 192 void testX() { &X::test; } 193 } 194 195 namespace test7 { 196 struct A { void foo(); virtual void vfoo(); }; 197 struct B { void foo(); virtual void vfoo(); }; 198 struct C : A, B { void foo(); virtual void vfoo(); }; 199 200 // CHECK-ARM: @_ZN5test74ptr0E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71A3fooEv to i32), i32 0 } 201 // CHECK-ARM: @_ZN5test74ptr1E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71B3fooEv to i32), i32 8 } 202 // CHECK-ARM: @_ZN5test74ptr2E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71C3fooEv to i32), i32 0 } 203 // CHECK-ARM: @_ZN5test74ptr3E = global {{.*}} { i32 0, i32 1 } 204 // CHECK-ARM: @_ZN5test74ptr4E = global {{.*}} { i32 0, i32 9 } 205 // CHECK-ARM: @_ZN5test74ptr5E = global {{.*}} { i32 0, i32 1 } 206 void (C::*ptr0)() = &A::foo; 207 void (C::*ptr1)() = &B::foo; 208 void (C::*ptr2)() = &C::foo; 209 void (C::*ptr3)() = &A::vfoo; 210 void (C::*ptr4)() = &B::vfoo; 211 void (C::*ptr5)() = &C::vfoo; 212 } 213