1 // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin9 | FileCheck %s 2 3 struct A { int a; void f(); virtual void vf1(); virtual void vf2(); }; 4 struct B { int b; virtual void g(); }; 5 struct C : B, A { }; 6 7 void (A::*pa)(); 8 void (A::*volatile vpa)(); 9 void (B::*pb)(); 10 void (C::*pc)(); 11 12 // CHECK: @pa2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }, align 8 13 void (A::*pa2)() = &A::f; 14 15 // CHECK: @pa3 = global %0 { i64 1, i64 0 }, align 8 16 void (A::*pa3)() = &A::vf1; 17 18 // CHECK: @pa4 = global %0 { i64 9, i64 0 }, align 8 19 void (A::*pa4)() = &A::vf2; 20 21 // CHECK: @pc2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 16 }, align 8 22 void (C::*pc2)() = &C::f; 23 24 // CHECK: @pc3 = global %0 { i64 1, i64 0 }, align 8 25 void (A::*pc3)() = &A::vf1; 26 27 void f() { 28 // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0) 29 // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 1) 30 pa = 0; 31 32 // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 0) 33 // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 1) 34 vpa = 0; 35 36 // CHECK: store i64 {{.*}}, i64* getelementptr inbounds (%0* @pc, i32 0, i32 0) 37 // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 {{.*}}, 16 38 // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pc, i32 0, i32 1) 39 pc = pa; 40 41 // CHECK: store i64 {{.*}}, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0) 42 // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub i64 {{.*}}, 16 43 // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pa, i32 0, i32 1) 44 pa = static_cast<void (A::*)()>(pc); 45 } 46 47 void f2() { 48 // CHECK: [[pa2ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 0 49 // CHECK: store i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64* [[pa2ptr]] 50 // CHECK: [[pa2adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 1 51 // CHECK: store i64 0, i64* [[pa2adj]] 52 void (A::*pa2)() = &A::f; 53 54 // CHECK: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0 55 // CHECK: store i64 1, i64* [[pa3ptr]] 56 // CHECK: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1 57 // CHECK: store i64 0, i64* [[pa3adj]] 58 void (A::*pa3)() = &A::vf1; 59 60 // CHECK: [[pa4ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 0 61 // CHECK: store i64 9, i64* [[pa4ptr]] 62 // CHECK: [[pa4adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 1 63 // CHECK: store i64 0, i64* [[pa4adj]] 64 void (A::*pa4)() = &A::vf2; 65 } 66 67 void f3(A *a, A &ar) { 68 (a->*pa)(); 69 (ar.*pa)(); 70 } 71 72 bool f4() { 73 return pa; 74 } 75 76 // PR5177 77 namespace PR5177 { 78 struct A { 79 bool foo(int*) const; 80 } a; 81 82 struct B1 { 83 bool (A::*pmf)(int*) const; 84 const A* pa; 85 86 B1() : pmf(&A::foo), pa(&a) {} 87 bool operator()() const { return (pa->*pmf)(new int); } 88 }; 89 90 void bar(B1 b2) { while (b2()) ; } 91 } 92 93 // PR5138 94 namespace PR5138 { 95 struct foo { 96 virtual void bar(foo *); 97 }; 98 99 extern "C" { 100 void baz(foo *); 101 } 102 103 void (foo::*ptr1)(void *) = (void (foo::*)(void *))&foo::bar; 104 void (*ptr2)(void *) = (void (*)(void *))&baz; 105 106 void (foo::*ptr3)(void) = (void (foo::*)(void))&foo::bar; 107 } 108 109 // PR5593 110 namespace PR5593 { 111 struct A { }; 112 113 bool f(void (A::*f)()) { 114 return f && f; 115 } 116 } 117 118 namespace PR5718 { 119 struct A { }; 120 121 bool f(void (A::*f)(), void (A::*g)()) { 122 return f == g; 123 } 124 } 125 126 namespace BoolMemberPointer { 127 struct A { }; 128 129 bool f(void (A::*f)()) { 130 return !f; 131 } 132 133 bool g(void (A::*f)()) { 134 if (!!f) 135 return true; 136 return false; 137 } 138 } 139 140 // PR5940 141 namespace PR5940 { 142 class foo { 143 public: 144 virtual void baz(void); 145 }; 146 147 void foo::baz(void) { 148 void (foo::*ptr)(void) = &foo::baz; 149 } 150 } 151 152 namespace MemberPointerImpCast { 153 struct A { 154 int x; 155 }; 156 struct B : public A { 157 }; 158 void f(B* obj, void (A::*method)()) { 159 (obj->*method)(); 160 } 161 } 162 163 // PR6258 164 namespace PR6258 { 165 166 struct A { 167 void f(bool); 168 }; 169 170 void (A::*pf)(bool) = &A::f; 171 172 void f() { 173 void (A::*pf)(bool) = &A::f; 174 } 175 } 176