1 | // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \ |
2 | // RUN: FileCheck -check-prefix CHECK-LP64 %s |
3 | // RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \ |
4 | // RUN: FileCheck -check-prefix CHECK-LP32 %s |
5 | // 13.3.3.2 Ranking implicit conversion sequences |
6 | |
7 | extern "C" int printf(...); |
8 | |
9 | struct A { |
10 | int Ai; |
11 | bool foo(int* arg) const; |
12 | }; |
13 | |
14 | bool A::foo(int* arg) const { |
15 | printf("A::foo(%d)\n", *arg); |
16 | return true; |
17 | } |
18 | |
19 | struct B : public A { |
20 | void bf() { printf("B::bf called\n"); } |
21 | }; |
22 | |
23 | struct C : public B { }; |
24 | |
25 | // conversion of B::* to C::* is better than conversion of A::* to C::* |
26 | typedef void (A::*pmfa)(); |
27 | typedef void (B::*pmfb)(); |
28 | typedef void (C::*pmfc)(); |
29 | |
30 | struct X { |
31 | operator pmfa(); |
32 | operator pmfb() { |
33 | return &B::bf; |
34 | } |
35 | }; |
36 | |
37 | |
38 | void g(pmfc pm) { |
39 | C c; |
40 | (c.*pm)(); |
41 | } |
42 | |
43 | void test2(X x) |
44 | { |
45 | g(x); |
46 | } |
47 | |
48 | struct B1 { |
49 | bool (A::*pmf)(int*) const; |
50 | |
51 | B1(int i) : pmf(&A::foo), im(i) { |
52 | ((A*)this->*pmf)(&im); |
53 | } |
54 | |
55 | int im; |
56 | }; |
57 | |
58 | int main() |
59 | { |
60 | X x; |
61 | test2(x); |
62 | B1 b = B1(1); |
63 | B1 c = B1(2); |
64 | } |
65 | |
66 | // CHECK-LP64: call { i64, i64 } @_ZN1XcvM1BFvvEEv |
67 | // CHECK-LP64: call void @_Z1gM1CFvvE |
68 | |
69 | // CHECK-LP32: call i64 @_ZN1XcvM1BFvvEEv |
70 | // CHECK-LP32: call void @_Z1gM1CFvvE |
71 | |