Home | History | Annotate | Download | only in SemaObjCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 @interface I1
      3 - (int*)method;
      4 @end
      5 
      6 @implementation I1
      7 - (int*)method {
      8   struct x { };
      9   [x method]; // expected-error{{receiver type 'x' is not an Objective-C class}}
     10   return 0;
     11 }
     12 @end
     13 
     14 typedef struct { int x; } ivar;
     15 
     16 @interface I2 {
     17   id ivar;
     18 }
     19 - (int*)method;
     20 + (void)method;
     21 @end
     22 
     23 struct I2_holder {
     24   I2_holder();
     25 
     26   I2 *get();
     27 };
     28 
     29 I2 *operator+(I2_holder, int);
     30 
     31 @implementation I2
     32 - (int*)method {
     33   [ivar method];
     34 
     35   // Test instance messages that start with a simple-type-specifier.
     36   [I2_holder().get() method];
     37   [I2_holder().get() + 17 method];
     38   return 0;
     39 }
     40 + (void)method {
     41   [ivar method]; // expected-error{{receiver type 'ivar' is not an Objective-C class}}
     42 }
     43 @end
     44 
     45 // Class message sends
     46 @interface I3
     47 + (int*)method;
     48 @end
     49 
     50 @interface I4 : I3
     51 + (int*)otherMethod;
     52 @end
     53 
     54 template<typename T>
     55 struct identity {
     56   typedef T type;
     57 };
     58 
     59 @implementation I4
     60 + (int *)otherMethod {
     61   // Test class messages that use non-trivial simple-type-specifiers
     62   // or typename-specifiers.
     63   if (false) {
     64     if (true)
     65       return [typename identity<I3>::type method]; // expected-warning{{occurs outside of a template}}
     66 
     67     return [::I3 method];
     68   }
     69 
     70   int* ip1 = {[super method]};
     71   int* ip2 = {[::I3 method]};
     72   int* ip3 = {[typename identity<I3>::type method]}; // expected-warning{{occurs outside of a template}}
     73   int* ip4 = {[typename identity<I2_holder>::type().get() method]}; // expected-warning{{occurs outside of a template}}
     74   int array[5] = {[3] = 2};
     75   return [super method];
     76 }
     77 @end
     78 
     79 struct String {
     80   String(const char *);
     81 };
     82 
     83 struct MutableString : public String { };
     84 
     85 // C++-specific parameter types
     86 @interface I5
     87 - method:(const String&)str1 
     88    other:(String&)str2; // expected-note{{passing argument to parameter 'str2' here}}
     89 @end
     90 
     91 void test_I5(I5 *i5, String s) {
     92   [i5 method:"hello" other:s];
     93   [i5 method:s other:"world"]; // expected-error{{non-const lvalue reference to type 'String' cannot bind to a value of unrelated type 'const char [6]'}}
     94 }
     95 
     96 // <rdar://problem/8483253>
     97 @interface A
     98 
     99 struct X { };
    100 
    101 + (A *)create:(void (*)(void *x, X r, void *data))callback
    102 	      callbackData:(void *)callback_data;
    103 
    104 @end
    105 
    106 
    107 void foo(void)
    108 {
    109   void *fun;
    110   void *ptr;
    111   X r;
    112   A *im = [A create:(void (*)(void *cgl_ctx, X r, void *data)) fun
    113              callbackData:ptr];
    114 }
    115 
    116 // <rdar://problem/8807070>
    117 template<typename T> struct X1; // expected-note{{template is declared here}}
    118 
    119 @interface B
    120 + (X1<int>)blah;
    121 + (X1<float>&)blarg;
    122 @end
    123 
    124 void f() {
    125   [B blah]; // expected-error{{implicit instantiation of undefined template 'X1<int>'}}
    126   [B blarg];
    127 }
    128