1// RUN: %clang_cc1 -fsyntax-only -verify %s
2// expected-no-diagnostics
3@protocol P1
4@end
5
6@interface A <P1>
7@end
8
9@interface B : A
10@end
11
12@interface C : B
13@end
14
15template<typename T>
16struct ConvertsTo {
17  operator T() const;
18};
19
20
21// conversion of C* to B* is better than conversion of C* to A*.
22int &f0(A*);
23float &f0(B*);
24
25void test_f0(C *c) {
26  float &fr1 = f0(c);
27}
28
29// conversion of B* to A* is better than conversion of C* to A*
30void f1(A*);
31
32struct ConvertsToBoth {
33private:
34  operator C*() const;
35
36public:
37  operator B*() const;
38};
39
40void test_f1(ConvertsTo<B*> toB, ConvertsTo<C*> toC, ConvertsToBoth toBoth) {
41  f1(toB);
42  f1(toC);
43  f1(toBoth);
44};
45
46// A conversion to an a non-id object pointer type is better than a
47// conversion to 'id'.
48int &f2(A*);
49float &f2(id);
50
51void test_f2(B *b) {
52  int &ir = f2(b);
53}
54
55// A conversion to an a non-Class object pointer type is better than a
56// conversion to 'Class'.
57int &f3(A*);
58float &f3(Class);
59
60void test_f3(B *b) {
61  int &ir = f3(b);
62}
63
64// When both conversions convert to 'id' or 'Class', pick the most
65// specific type to convert from.
66void f4(id);
67
68void test_f4(ConvertsTo<B*> toB, ConvertsTo<C*> toC, ConvertsToBoth toBoth) {
69  f4(toB);
70  f4(toC);
71  f4(toBoth);
72}
73
74void f5(id<P1>);
75
76void test_f5(ConvertsTo<B*> toB, ConvertsTo<C*> toC, ConvertsToBoth toBoth) {
77  f5(toB);
78  f5(toC);
79  f5(toBoth);
80}
81
82
83// A conversion to an a non-id object pointer type is better than a
84// conversion to qualified 'id'.
85int &f6(A*);
86float &f6(id<P1>);
87
88void test_f6(B *b) {
89  int &ir = f6(b);
90}
91