member-function-pointers.cpp revision 47d1e828674a2d9c020db9f9ec45f27025a39e35
1// RUN: clang-cc %s -emit-llvm -o - -triple=x86_64-apple-darwin9 | FileCheck %s
2
3struct A { int a; void f(); virtual void vf(); };
4struct B { int b; virtual void g(); };
5struct C : B, A { };
6
7void (A::*pa)();
8void (A::*volatile vpa)();
9void (B::*pb)();
10void (C::*pc)();
11
12// CHECK: @pa2 = global %0 { i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64 0 }, align 8
13void (A::*pa2)() = &A::f;
14
15// CHECK: @pa3 = global %0 { i64 1, i64 0 }, align 8
16void (A::*pa3)() = &A::vf;
17
18// CHECK: @pc2 = global %0 { i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64 16 }, align 8
19void (C::*pc2)() = &C::f;
20
21// CHECK: @pc3 = global %0 { i64 1, i64 0 }, align 8
22void (A::*pc3)() = &A::vf;
23
24void f() {
25  // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0)
26  // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 1)
27  pa = 0;
28
29  // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 0)
30  // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 1)
31  vpa = 0;
32
33  // CHECK: store i64 {{.*}}, i64* getelementptr inbounds (%0* @pc, i32 0, i32 0)
34  // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 {{.*}}, 16
35  // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pc, i32 0, i32 1)
36  pc = pa;
37}
38
39void f2() {
40  // CHECK: [[pa2ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 0
41  // CHECK: store i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64* [[pa2ptr]]
42  // CHECK: [[pa2adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 1
43  // CHECK: store i64 0, i64* [[pa2adj]]
44  void (A::*pa2)() = &A::f;
45
46  // CHECK: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0
47  // CHECK: store i64 1, i64* [[pa3ptr]]
48  // CHECK: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1
49  // CHECK: store i64 0, i64* [[pa3adj]]
50  void (A::*pa3)() = &A::vf;
51}
52
53void f3(A *a, A &ar) {
54  (a->*pa)();
55  (ar.*pa)();
56}
57
58// PR5177
59namespace PR5177 {
60  struct A {
61   bool foo(int*) const;
62  } a;
63
64  struct B1 {
65   bool (A::*pmf)(int*) const;
66   const A* pa;
67
68   B1() : pmf(&A::foo), pa(&a) {}
69   bool operator()() const { return (pa->*pmf)(new int); }
70  };
71
72  void bar(B1 b2) { while (b2()) ; }
73}
74
75// PR5138
76namespace PR5138 {
77  struct foo {
78      virtual void bar(foo *);
79  };
80
81  extern "C" {
82    void baz(foo *);
83  }
84
85  void (foo::*ptr1)(void *) = (void (foo::*)(void *))&foo::bar;
86  void (*ptr2)(void *) = (void (*)(void *))&baz;
87
88  void (foo::*ptr3)(void) = (void (foo::*)(void))&foo::bar;
89}
90