Home | History | Annotate | Download | only in SemaObjCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 
      3 @interface A {
      4 @public
      5   int ivar;
      6 }
      7 @property int prop;
      8 @end
      9 
     10 typedef struct objc_object {
     11     Class isa;
     12 } *id;
     13 
     14 // Test instantiation of value-dependent ObjCIvarRefExpr,
     15 // ObjCIsaRefExpr, and ObjCPropertyRefExpr nodes.
     16 A *get_an_A(unsigned);
     17 id get_an_id(unsigned);
     18 
     19 template<unsigned N, typename T, typename U, typename V>
     20 void f(U value, V value2) {
     21   get_an_A(N)->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
     22   get_an_A(N).prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}}
     23   T c = get_an_id(N)->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}} \
     24                            // expected-warning 3 {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
     25 }
     26 
     27 template void f<6, Class>(int, int); // expected-note{{in instantiation of}}
     28 template void f<7, Class>(int*, int); // expected-note{{in instantiation of}}
     29 template void f<8, Class>(int, double*); // expected-note{{in instantiation of}}
     30 template void f<9, int>(int, int); // expected-note{{in instantiation of}}
     31 
     32 // Test instantiation of unresolved member reference expressions to an
     33 // ivar reference.
     34 template<typename T, typename U, typename V>
     35 void f2(T ptr, U value, V value2) {
     36   ptr->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
     37   ptr.prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}}
     38 }
     39 
     40 template void f2(A*, int, int);
     41 template void f2(A*, int*, int); // expected-note{{instantiation of}}
     42 template void f2(A*, int, double*); // expected-note{{instantiation of}}
     43 
     44 // Test instantiation of unresolved member referfence expressions to
     45 // an isa.
     46 template<typename T, typename U>
     47 void f3(U ptr) {
     48   T c = ptr->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}} \
     49                   // expected-warning 1 {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
     50 }
     51 
     52 template void f3<Class>(id); // expected-note{{in instantiation of}}
     53 template void f3<int>(id); // expected-note{{instantiation of}}
     54 
     55 // Implicit setter/getter
     56 @interface B
     57 - (int)foo;
     58 - (void)setFoo:(int)value;
     59 @end
     60 
     61 template<typename T>
     62 void f4(B *b, T value) {
     63   b.foo = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
     64 }
     65 
     66 template void f4(B*, int);
     67 template void f4(B*, int*); // expected-note{{in instantiation of function template specialization 'f4<int *>' requested here}}
     68 
     69 template<typename T, typename U>
     70 void f5(T ptr, U value) {
     71   ptr.foo = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
     72 }
     73 
     74 template void f5(B*, int);
     75 template void f5(B*, int*); // expected-note{{in instantiation of function template specialization 'f5<B *, int *>' requested here}}
     76