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 15 template<typename T> 16 struct ConvertsTo { 17 operator T() const; 18 }; 19 20 21 // conversion of C* to B* is better than conversion of C* to A*. 22 int &f0(A*); 23 float &f0(B*); 24 25 void 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* 30 void f1(A*); 31 32 struct ConvertsToBoth { 33 private: 34 operator C*() const; 35 36 public: 37 operator B*() const; 38 }; 39 40 void 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'. 48 int &f2(A*); 49 float &f2(id); 50 51 void 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'. 57 int &f3(A*); 58 float &f3(Class); 59 60 void 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. 66 void f4(id); 67 68 void test_f4(ConvertsTo<B*> toB, ConvertsTo<C*> toC, ConvertsToBoth toBoth) { 69 f4(toB); 70 f4(toC); 71 f4(toBoth); 72 } 73 74 void f5(id<P1>); 75 76 void 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'. 85 int &f6(A*); 86 float &f6(id<P1>); 87 88 void test_f6(B *b) { 89 int &ir = f6(b); 90 } 91