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