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