12a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-unknown-unknown | FileCheck -check-prefix CODE-LP64 %s
22a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-unknown-unknown | FileCheck -check-prefix CODE-LP32 %s
32a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-unknown-unknown | FileCheck -check-prefix GLOBAL-LP64 %s
42a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-unknown-unknown | FileCheck -check-prefix GLOBAL-LP32 %s
52a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-unknown-unknown | FileCheck -check-prefix GLOBAL-ARM %s
621fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn
721fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn// PNaCl uses the same representation of method pointers as ARM.
821fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn// RUN: %clang_cc1 %s -emit-llvm -o - -triple=le32-unknown-nacl | FileCheck -check-prefix GLOBAL-ARM %s
97b69956387785006244e7868f8dab09b371dbb6dAnders Carlsson
10e8a81f7e8e26275d91c073bf908a7d6d246106c5Anders Carlssonstruct A { int a; void f(); virtual void vf1(); virtual void vf2(); };
11f57b4e44d03266f2ec1b427645555ed8952bc830Anders Carlssonstruct B { int b; virtual void g(); };
127b69956387785006244e7868f8dab09b371dbb6dAnders Carlssonstruct C : B, A { };
137b69956387785006244e7868f8dab09b371dbb6dAnders Carlsson
147b69956387785006244e7868f8dab09b371dbb6dAnders Carlssonvoid (A::*pa)();
157b69956387785006244e7868f8dab09b371dbb6dAnders Carlssonvoid (A::*volatile vpa)();
167b69956387785006244e7868f8dab09b371dbb6dAnders Carlssonvoid (B::*pb)();
177b69956387785006244e7868f8dab09b371dbb6dAnders Carlssonvoid (C::*pc)();
187b69956387785006244e7868f8dab09b371dbb6dAnders Carlsson
192a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP64: @pa2 = global { i64, i64 } { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }, align 8
20f57b4e44d03266f2ec1b427645555ed8952bc830Anders Carlssonvoid (A::*pa2)() = &A::f;
21f57b4e44d03266f2ec1b427645555ed8952bc830Anders Carlsson
222a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP64: @pa3 = global { i64, i64 } { i64 1, i64 0 }, align 8
232a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP32: @pa3 = global { i32, i32 } { i32 1, i32 0 }, align 4
24e8a81f7e8e26275d91c073bf908a7d6d246106c5Anders Carlssonvoid (A::*pa3)() = &A::vf1;
25e8a81f7e8e26275d91c073bf908a7d6d246106c5Anders Carlsson
262a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP64: @pa4 = global { i64, i64 } { i64 9, i64 0 }, align 8
272a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP32: @pa4 = global { i32, i32 } { i32 5, i32 0 }, align 4
28e8a81f7e8e26275d91c073bf908a7d6d246106c5Anders Carlssonvoid (A::*pa4)() = &A::vf2;
29f57b4e44d03266f2ec1b427645555ed8952bc830Anders Carlsson
302a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP64: @pc2 = global { i64, i64 } { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 16 }, align 8
312c51f092e4d75550f51b4dd6f831aa5e5e6ae928Anders Carlssonvoid (C::*pc2)() = &C::f;
322c51f092e4d75550f51b4dd6f831aa5e5e6ae928Anders Carlsson
332a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP64: @pc3 = global { i64, i64 } { i64 1, i64 0 }, align 8
34e8a81f7e8e26275d91c073bf908a7d6d246106c5Anders Carlssonvoid (A::*pc3)() = &A::vf1;
352c51f092e4d75550f51b4dd6f831aa5e5e6ae928Anders Carlsson
367b69956387785006244e7868f8dab09b371dbb6dAnders Carlssonvoid f() {
372a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: store { i64, i64 } zeroinitializer, { i64, i64 }* @pa
387b69956387785006244e7868f8dab09b371dbb6dAnders Carlsson  pa = 0;
39ee383163a656a7e8d99efa4e5ee98c705c7fdf89Anders Carlsson
40d608cdb7c044365cf4e8764ade1e11e99c176078John McCall  // Is this okay?  What are LLVM's volatile semantics for structs?
412a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: store volatile { i64, i64 } zeroinitializer, { i64, i64 }* @vpa
427b69956387785006244e7868f8dab09b371dbb6dAnders Carlsson  vpa = 0;
43ee383163a656a7e8d99efa4e5ee98c705c7fdf89Anders Carlsson
442a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: [[TMP:%.*]] = load { i64, i64 }* @pa, align 8
452a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: [[TMPADJ:%.*]] = extractvalue { i64, i64 } [[TMP]], 1
462a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: [[ADJ:%.*]] = add nsw i64 [[TMPADJ]], 16
472a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: [[RES:%.*]] = insertvalue { i64, i64 } [[TMP]], i64 [[ADJ]], 1
482a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: store { i64, i64 } [[RES]], { i64, i64 }* @pc, align 8
49f57b4e44d03266f2ec1b427645555ed8952bc830Anders Carlsson  pc = pa;
509b3727457d1f779da81569c2ca42ff6cd5f5b03dEli Friedman
512a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: [[TMP:%.*]] = load { i64, i64 }* @pc, align 8
522a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: [[TMPADJ:%.*]] = extractvalue { i64, i64 } [[TMP]], 1
532a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: [[ADJ:%.*]] = sub nsw i64 [[TMPADJ]], 16
542a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: [[RES:%.*]] = insertvalue { i64, i64 } [[TMP]], i64 [[ADJ]], 1
552a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: store { i64, i64 } [[RES]], { i64, i64 }* @pa, align 8
569b3727457d1f779da81569c2ca42ff6cd5f5b03dEli Friedman  pa = static_cast<void (A::*)()>(pc);
577b69956387785006244e7868f8dab09b371dbb6dAnders Carlsson}
58a024d17048cd7fb71bfaee3876993ef2c27057beAnders Carlsson
59a024d17048cd7fb71bfaee3876993ef2c27057beAnders Carlssonvoid f2() {
602a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: store { i64, i64 } { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }
61a024d17048cd7fb71bfaee3876993ef2c27057beAnders Carlsson  void (A::*pa2)() = &A::f;
62a024d17048cd7fb71bfaee3876993ef2c27057beAnders Carlsson
632a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: store { i64, i64 } { i64 1, i64 0 }
642a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP32: store { i32, i32 } { i32 1, i32 0 }
65e8a81f7e8e26275d91c073bf908a7d6d246106c5Anders Carlsson  void (A::*pa3)() = &A::vf1;
66e8a81f7e8e26275d91c073bf908a7d6d246106c5Anders Carlsson
672a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64: store { i64, i64 } { i64 9, i64 0 }
682a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP32: store { i32, i32 } { i32 5, i32 0 }
69e8a81f7e8e26275d91c073bf908a7d6d246106c5Anders Carlsson  void (A::*pa4)() = &A::vf2;
70a024d17048cd7fb71bfaee3876993ef2c27057beAnders Carlsson}
71375c31c4673f83f925de221752cf801c2fbbb246Anders Carlsson
72375c31c4673f83f925de221752cf801c2fbbb246Anders Carlssonvoid f3(A *a, A &ar) {
73375c31c4673f83f925de221752cf801c2fbbb246Anders Carlsson  (a->*pa)();
74375c31c4673f83f925de221752cf801c2fbbb246Anders Carlsson  (ar.*pa)();
75375c31c4673f83f925de221752cf801c2fbbb246Anders Carlsson}
763eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson
77bc0e0781da778bd5eb41a810419912893ae20448Anders Carlssonbool f4() {
78bc0e0781da778bd5eb41a810419912893ae20448Anders Carlsson  return pa;
79bc0e0781da778bd5eb41a810419912893ae20448Anders Carlsson}
80bc0e0781da778bd5eb41a810419912893ae20448Anders Carlsson
813eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson// PR5177
823eea6350412eb7db13f0e2791c118920b36130a4Anders Carlssonnamespace PR5177 {
833eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson  struct A {
843eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson   bool foo(int*) const;
853eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson  } a;
863eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson
873eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson  struct B1 {
883eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson   bool (A::*pmf)(int*) const;
893eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson   const A* pa;
903eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson
913eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson   B1() : pmf(&A::foo), pa(&a) {}
923eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson   bool operator()() const { return (pa->*pmf)(new int); }
933eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson  };
943eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson
953eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson  void bar(B1 b2) { while (b2()) ; }
963eea6350412eb7db13f0e2791c118920b36130a4Anders Carlsson}
97bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson
98bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson// PR5138
99bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlssonnamespace PR5138 {
100bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson  struct foo {
101bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson      virtual void bar(foo *);
102bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson  };
103bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson
104bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson  extern "C" {
105bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson    void baz(foo *);
106bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson  }
107bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson
108bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson  void (foo::*ptr1)(void *) = (void (foo::*)(void *))&foo::bar;
109bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson  void (*ptr2)(void *) = (void (*)(void *))&baz;
110bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson
111bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson  void (foo::*ptr3)(void) = (void (foo::*)(void))&foo::bar;
112bb378cbf04e343fb15ae3611a153dde60671b514Anders Carlsson}
113a4c98cd60e7151ea6eccfc677742bdbcf58d2a55Anders Carlsson
114a4c98cd60e7151ea6eccfc677742bdbcf58d2a55Anders Carlsson// PR5593
115a4c98cd60e7151ea6eccfc677742bdbcf58d2a55Anders Carlssonnamespace PR5593 {
116a4c98cd60e7151ea6eccfc677742bdbcf58d2a55Anders Carlsson  struct A { };
117a4c98cd60e7151ea6eccfc677742bdbcf58d2a55Anders Carlsson
118a4c98cd60e7151ea6eccfc677742bdbcf58d2a55Anders Carlsson  bool f(void (A::*f)()) {
119a4c98cd60e7151ea6eccfc677742bdbcf58d2a55Anders Carlsson    return f && f;
120a4c98cd60e7151ea6eccfc677742bdbcf58d2a55Anders Carlsson  }
121a4c98cd60e7151ea6eccfc677742bdbcf58d2a55Anders Carlsson}
122b81c786de58ce484230dc04f9a7c78bc48990106Eli Friedman
123b81c786de58ce484230dc04f9a7c78bc48990106Eli Friedmannamespace PR5718 {
124b81c786de58ce484230dc04f9a7c78bc48990106Eli Friedman  struct A { };
125b81c786de58ce484230dc04f9a7c78bc48990106Eli Friedman
126b81c786de58ce484230dc04f9a7c78bc48990106Eli Friedman  bool f(void (A::*f)(), void (A::*g)()) {
127b81c786de58ce484230dc04f9a7c78bc48990106Eli Friedman    return f == g;
128b81c786de58ce484230dc04f9a7c78bc48990106Eli Friedman  }
129b81c786de58ce484230dc04f9a7c78bc48990106Eli Friedman}
1303a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman
1313a1737030e3c8d209987325c61dacb8e4a65123bEli Friedmannamespace BoolMemberPointer {
1323a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman  struct A { };
1333a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman
1343a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman  bool f(void (A::*f)()) {
1353a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman    return !f;
1363a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman  }
1373a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman
1383a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman  bool g(void (A::*f)()) {
1393a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman    if (!!f)
1403a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman      return true;
1413a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman    return false;
1423a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman  }
1433a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman}
1443a1737030e3c8d209987325c61dacb8e4a65123bEli Friedman
1457af4ec744e30d573482aef7a37089d0d32cc07efAnders Carlsson// PR5940
1467af4ec744e30d573482aef7a37089d0d32cc07efAnders Carlssonnamespace PR5940 {
1477af4ec744e30d573482aef7a37089d0d32cc07efAnders Carlsson  class foo {
1487af4ec744e30d573482aef7a37089d0d32cc07efAnders Carlsson  public:
1497af4ec744e30d573482aef7a37089d0d32cc07efAnders Carlsson    virtual void baz(void);
1507af4ec744e30d573482aef7a37089d0d32cc07efAnders Carlsson  };
1517af4ec744e30d573482aef7a37089d0d32cc07efAnders Carlsson
1527af4ec744e30d573482aef7a37089d0d32cc07efAnders Carlsson  void foo::baz(void) {
1537af4ec744e30d573482aef7a37089d0d32cc07efAnders Carlsson       void (foo::*ptr)(void) = &foo::baz;
1547af4ec744e30d573482aef7a37089d0d32cc07efAnders Carlsson  }
1557af4ec744e30d573482aef7a37089d0d32cc07efAnders Carlsson}
1563005efeb131ccddcda9c332c83e49c32349e2aedEli Friedman
1573005efeb131ccddcda9c332c83e49c32349e2aedEli Friedmannamespace MemberPointerImpCast {
1583005efeb131ccddcda9c332c83e49c32349e2aedEli Friedman  struct A {
1593005efeb131ccddcda9c332c83e49c32349e2aedEli Friedman    int x;
1603005efeb131ccddcda9c332c83e49c32349e2aedEli Friedman  };
1613005efeb131ccddcda9c332c83e49c32349e2aedEli Friedman  struct B : public A {
1623005efeb131ccddcda9c332c83e49c32349e2aedEli Friedman  };
1633005efeb131ccddcda9c332c83e49c32349e2aedEli Friedman  void f(B* obj, void (A::*method)()) {
1643005efeb131ccddcda9c332c83e49c32349e2aedEli Friedman    (obj->*method)();
1653005efeb131ccddcda9c332c83e49c32349e2aedEli Friedman  }
1663005efeb131ccddcda9c332c83e49c32349e2aedEli Friedman}
167585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson
168585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson// PR6258
169585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlssonnamespace PR6258 {
170585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson
171585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson  struct A {
172585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson    void f(bool);
173585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson  };
174585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson
175585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson  void (A::*pf)(bool) = &A::f;
176585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson
177585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson  void f() {
178585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson    void (A::*pf)(bool) = &A::f;
179585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson  }
180585fa68ca00421af6c8289866a7bde27a8e8c0ceAnders Carlsson}
181e174bd05ca9991e705f51afcfab27933b537dc63Douglas Gregor
182e174bd05ca9991e705f51afcfab27933b537dc63Douglas Gregor// PR7027
183e174bd05ca9991e705f51afcfab27933b537dc63Douglas Gregornamespace PR7027 {
184e174bd05ca9991e705f51afcfab27933b537dc63Douglas Gregor  struct X { void test( ); };
185e174bd05ca9991e705f51afcfab27933b537dc63Douglas Gregor  void testX() { &X::test; }
186e174bd05ca9991e705f51afcfab27933b537dc63Douglas Gregor}
187875ab10245d3bf37252dd822aa1616bb0a391095John McCall
188875ab10245d3bf37252dd822aa1616bb0a391095John McCallnamespace test7 {
189875ab10245d3bf37252dd822aa1616bb0a391095John McCall  struct A { void foo(); virtual void vfoo(); };
190875ab10245d3bf37252dd822aa1616bb0a391095John McCall  struct B { void foo(); virtual void vfoo(); };
191875ab10245d3bf37252dd822aa1616bb0a391095John McCall  struct C : A, B { void foo(); virtual void vfoo(); };
192875ab10245d3bf37252dd822aa1616bb0a391095John McCall
1932a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // GLOBAL-ARM: @_ZN5test74ptr0E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71A3fooEv to i32), i32 0 }
1942a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // GLOBAL-ARM: @_ZN5test74ptr1E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71B3fooEv to i32), i32 8 }
1952a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // GLOBAL-ARM: @_ZN5test74ptr2E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71C3fooEv to i32), i32 0 }
1962a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // GLOBAL-ARM: @_ZN5test74ptr3E = global {{.*}} { i32 0, i32 1 }
1972a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // GLOBAL-ARM: @_ZN5test74ptr4E = global {{.*}} { i32 0, i32 9 }
1982a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // GLOBAL-ARM: @_ZN5test74ptr5E = global {{.*}} { i32 0, i32 1 }
199875ab10245d3bf37252dd822aa1616bb0a391095John McCall  void (C::*ptr0)() = &A::foo;
200875ab10245d3bf37252dd822aa1616bb0a391095John McCall  void (C::*ptr1)() = &B::foo;
201875ab10245d3bf37252dd822aa1616bb0a391095John McCall  void (C::*ptr2)() = &C::foo;
202875ab10245d3bf37252dd822aa1616bb0a391095John McCall  void (C::*ptr3)() = &A::vfoo;
203875ab10245d3bf37252dd822aa1616bb0a391095John McCall  void (C::*ptr4)() = &B::vfoo;
204875ab10245d3bf37252dd822aa1616bb0a391095John McCall  void (C::*ptr5)() = &C::vfoo;
205875ab10245d3bf37252dd822aa1616bb0a391095John McCall}
206db68e28c05a67735211e688009890cf834c22e75Douglas Gregor
207db68e28c05a67735211e688009890cf834c22e75Douglas Gregornamespace test8 {
208db68e28c05a67735211e688009890cf834c22e75Douglas Gregor  struct X { };
209db68e28c05a67735211e688009890cf834c22e75Douglas Gregor  typedef int (X::*pmf)(int);
210db68e28c05a67735211e688009890cf834c22e75Douglas Gregor
211db68e28c05a67735211e688009890cf834c22e75Douglas Gregor  // CHECK: {{define.*_ZN5test81fEv}}
212db68e28c05a67735211e688009890cf834c22e75Douglas Gregor  pmf f() {
213db68e28c05a67735211e688009890cf834c22e75Douglas Gregor    // CHECK: {{ret.*zeroinitializer}}
214db68e28c05a67735211e688009890cf834c22e75Douglas Gregor    return pmf();
215db68e28c05a67735211e688009890cf834c22e75Douglas Gregor  }
216db68e28c05a67735211e688009890cf834c22e75Douglas Gregor}
2178bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall
2188bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCallnamespace test9 {
2198bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall  struct A {
2208bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall    void foo();
2218bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall  };
2228bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall  struct B : A {
2238bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall    void foo();
2248bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall  };
2258bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall
2268bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall  typedef void (A::*fooptr)();
2278bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall
2288bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall  struct S {
2298bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall    fooptr p;
2308bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall  };
2318bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall
23293ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin  // CODE-LP64-LABEL:    define void @_ZN5test94testEv(
2332a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64:      alloca i32
2342a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // CODE-LP64-NEXT: ret void
2358bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall  void test() {
2368bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall    int x;
2378bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall    static S array[] = { (fooptr) &B::foo };
2388bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall  }
2398bba1f4ab1f06864fec627befdf7cf8e1ad017beJohn McCall}
2404d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall
2414d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall// rdar://problem/10815683 - Verify that we can emit reinterprets of
2424d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall// member pointers as constant initializers.  For added trickiness,
2434d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall// we also add some non-trivial adjustments.
2444d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCallnamespace test10 {
2454d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall  struct A {
2464d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall    int nonEmpty;
2474d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall    void foo();
2484d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall  };
2494d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall  struct B : public A {
2504d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall    virtual void requireNonZeroAdjustment();
2514d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall  };
2524d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall  struct C {
2534d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall    int nonEmpty;
2544d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall  };
2554d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall  struct D : public C {
2564d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall    virtual void requireNonZeroAdjustment();
2574d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall  };
2584d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall
2592a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall
2602a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// It's not that the offsets are doubled on ARM, it's that they're left-shifted by 1.
2612a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall
2622a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP64: @_ZN6test101aE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 0 }, align 8
2632a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP32: @_ZN6test101aE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 0 }, align 4
2642a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-ARM:  @_ZN6test101aE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 0 }, align 4
2654d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall  void (A::*a)() = &A::foo;
2662a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall
2672a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP64: @_ZN6test101bE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 8 }, align 8
2682a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP32: @_ZN6test101bE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 4 }, align 4
2692a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-ARM:  @_ZN6test101bE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 8 }, align 4
2704d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall  void (B::*b)() = (void (B::*)()) &A::foo;
2712a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall
2722a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP64: @_ZN6test101cE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 8 }, align 8
2732a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP32: @_ZN6test101cE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 4 }, align 4
2742a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-ARM:  @_ZN6test101cE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 8 }, align 4
2754d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall  void (C::*c)() = (void (C::*)()) (void (B::*)()) &A::foo;
2762a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall
2772a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP64: @_ZN6test101dE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 16 }, align 8
2782a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-LP32: @_ZN6test101dE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 8 }, align 4
2792a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall// GLOBAL-ARM:  @_ZN6test101dE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 16 }, align 4
2804d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall  void (D::*d)() = (void (C::*)()) (void (B::*)()) &A::foo;
2814d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall}
2822a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall
2832a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCallnamespace test11 {
2842a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  struct A { virtual void a(); };
2852a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  struct B : A {};
2862a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  struct C : B { virtual void a(); };
2872a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  void (C::*x)() = &C::a;
2882a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall
2892a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // GLOBAL-LP64: @_ZN6test111xE = global { i64, i64 } { i64 1, i64 0 }
2902a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // GLOBAL-LP32: @_ZN6test111xE = global { i32, i32 } { i32 1, i32 0 }
2912a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall  // GLOBAL-ARM:  @_ZN6test111xE = global { i32, i32 } { i32 0, i32 1 }
2922a7b09db93ed57f97cc9d9e7ec1b1d11934d0841John McCall}
293