1// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime=macosx-fragile-10.5 -verify -Wno-objc-root-class %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
14typedef struct { int x; } ivar;
15
16@interface I2 {
17  id ivar;
18}
19- (int*)method;
20+ (void)method;
21@end
22
23struct I2_holder {
24  I2_holder();
25
26  I2 *get();
27};
28
29I2 *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
54template<typename T>
55struct 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
79struct String {
80  String(const char *);
81};
82
83struct 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
91void 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
99struct X { };
100
101+ (A *)create:(void (*)(void *x, X r, void *data))callback
102	      callbackData:(void *)callback_data;
103
104@end
105
106
107void 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>
117template<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
124void f() {
125  [B blah]; // expected-error{{implicit instantiation of undefined template 'X1<int>'}}
126  [B blarg];
127}
128