1 | // Clear and create directories |
2 | // RUN: rm -rf %t |
3 | // RUN: mkdir %t |
4 | // RUN: mkdir %t/cache |
5 | // RUN: mkdir %t/Inputs |
6 | |
7 | // Build first header file |
8 | // RUN: echo "#define FIRST" >> %t/Inputs/first.h |
9 | // RUN: cat %s >> %t/Inputs/first.h |
10 | |
11 | // Build second header file |
12 | // RUN: echo "#define SECOND" >> %t/Inputs/second.h |
13 | // RUN: cat %s >> %t/Inputs/second.h |
14 | |
15 | // Test that each header can compile |
16 | // RUN: %clang_cc1 -fsyntax-only -x objective-c++ %t/Inputs/first.h -fblocks -fobjc-arc |
17 | // RUN: %clang_cc1 -fsyntax-only -x objective-c++ %t/Inputs/second.h -fblocks -fobjc-arc |
18 | |
19 | // Build module map file |
20 | // RUN: echo "module FirstModule {" >> %t/Inputs/module.map |
21 | // RUN: echo " header \"first.h\"" >> %t/Inputs/module.map |
22 | // RUN: echo "}" >> %t/Inputs/module.map |
23 | // RUN: echo "module SecondModule {" >> %t/Inputs/module.map |
24 | // RUN: echo " header \"second.h\"" >> %t/Inputs/module.map |
25 | // RUN: echo "}" >> %t/Inputs/module.map |
26 | |
27 | // Run test |
28 | // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c++ -I%t/Inputs -verify %s -fblocks -fobjc-arc |
29 | |
30 | #if !defined(FIRST) && !defined(SECOND) |
31 | #include "first.h" |
32 | #include "second.h" |
33 | #endif |
34 | |
35 | #if defined(FIRST) || defined(SECOND) |
36 | @protocol P1 |
37 | @end |
38 | |
39 | @protocol P2 |
40 | @end |
41 | |
42 | @interface I1 |
43 | @end |
44 | |
45 | @interface I2 : I1 |
46 | @end |
47 | |
48 | @interface Interface1 <T : I1 *> { |
49 | @public |
50 | T<P1> x; |
51 | } |
52 | @end |
53 | |
54 | @interface Interface2 <T : I1 *> |
55 | @end |
56 | |
57 | @interface Interface3 <T : I1 *> |
58 | @end |
59 | |
60 | #endif |
61 | |
62 | #if defined(FIRST) |
63 | struct S { |
64 | Interface1 *I; |
65 | decltype(I->x) x; |
66 | int y; |
67 | }; |
68 | #elif defined(SECOND) |
69 | struct S { |
70 | Interface1 *I; |
71 | decltype(I->x) x; |
72 | bool y; |
73 | }; |
74 | #else |
75 | S s; |
76 | // expected-error@second.h:* {{'S::y' from module 'SecondModule' is not present in definition of 'S' in module 'FirstModule'}} |
77 | // expected-note@first.h:* {{declaration of 'y' does not match}} |
78 | #endif |
79 | |
80 | namespace Types { |
81 | namespace Attributed { |
82 | #if defined(FIRST) |
83 | void invalid1() { |
84 | static double __attribute((objc_gc(strong))) *x; |
85 | } |
86 | void invalid2() { |
87 | static int __attribute((objc_gc(strong))) *x; |
88 | } |
89 | void valid() { |
90 | static int __attribute((objc_gc(strong))) *x; |
91 | } |
92 | #elif defined(SECOND) |
93 | void invalid1() { |
94 | static int __attribute((objc_gc(strong))) *x; |
95 | } |
96 | void invalid2() { |
97 | static int __attribute((objc_gc(weak))) *x; |
98 | } |
99 | void valid() { |
100 | static int __attribute((objc_gc(strong))) *x; |
101 | } |
102 | #else |
103 | auto function1 = invalid1; |
104 | // expected-error@second.h:* {{Types::Attributed::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} |
105 | // expected-note@first.h:* {{but in 'FirstModule' found a different body}} |
106 | auto function2 = invalid2; |
107 | // expected-error@second.h:* {{'Types::Attributed::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} |
108 | // expected-note@first.h:* {{but in 'FirstModule' found a different body}} |
109 | auto function3 = valid; |
110 | #endif |
111 | } // namespace Attributed |
112 | |
113 | namespace BlockPointer { |
114 | #if defined(FIRST) |
115 | void invalid1() { |
116 | void (^x)(int); |
117 | } |
118 | void invalid2() { |
119 | void (^x)(int); |
120 | } |
121 | void invalid3() { |
122 | void (^x)(int); |
123 | } |
124 | void invalid4() { |
125 | void (^x)(int); |
126 | } |
127 | void valid() { |
128 | void (^x1)(int); |
129 | int (^x2)(int); |
130 | void (^x3)(int, int); |
131 | void (^x4)(short); |
132 | } |
133 | #elif defined(SECOND) |
134 | void invalid1() { |
135 | void (^x)(); |
136 | } |
137 | void invalid2() { |
138 | void (^x)(int, int); |
139 | } |
140 | void invalid3() { |
141 | int (^x)(int); |
142 | } |
143 | void invalid4() { |
144 | void (^x)(float); |
145 | } |
146 | void valid() { |
147 | void (^x1)(int); |
148 | int (^x2)(int); |
149 | void (^x3)(int, int); |
150 | void (^x4)(short); |
151 | } |
152 | #else |
153 | auto function1 = invalid1; |
154 | // expected-error@second.h:* {{'Types::BlockPointer::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} |
155 | // expected-note@first.h:* {{but in 'FirstModule' found a different body}} |
156 | auto function2 = invalid2; |
157 | // expected-error@second.h:* {{'Types::BlockPointer::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} |
158 | // expected-note@first.h:* {{but in 'FirstModule' found a different body}} |
159 | auto function3 = invalid3; |
160 | // expected-error@second.h:* {{'Types::BlockPointer::invalid3' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} |
161 | // expected-note@first.h:* {{but in 'FirstModule' found a different body}} |
162 | auto function4 = invalid4; |
163 | // expected-error@second.h:* {{'Types::BlockPointer::invalid4' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} |
164 | // expected-note@first.h:* {{but in 'FirstModule' found a different body}} |
165 | auto function5 = valid; |
166 | #endif |
167 | } // namespace BlockPointer |
168 | |
169 | namespace ObjCObject { |
170 | #if defined(FIRST) |
171 | struct Invalid1 { |
172 | using T = Interface2<I1*>; |
173 | }; |
174 | struct Invalid2 { |
175 | using T = Interface2<I1*>; |
176 | }; |
177 | struct Invalid3 { |
178 | using T = Interface2<P1, P1>; |
179 | }; |
180 | struct Invalid4 { |
181 | using T = Interface2<P1>; |
182 | }; |
183 | struct Valid { |
184 | using T1 = Interface2<I1*>; |
185 | using T2 = Interface3<I1*>; |
186 | using T3 = Interface2<P1>; |
187 | using T4 = Interface3<P1, P2>; |
188 | using T5 = __kindof Interface2; |
189 | }; |
190 | #elif defined(SECOND) |
191 | struct Invalid1 { |
192 | using T = Interface3<I1*>; |
193 | }; |
194 | struct Invalid2 { |
195 | using T = Interface2<I2*>; |
196 | }; |
197 | struct Invalid3 { |
198 | using T = Interface2<P1>; |
199 | }; |
200 | struct Invalid4 { |
201 | using T = Interface2<P2>; |
202 | }; |
203 | struct Valid { |
204 | using T1 = Interface2<I1*>; |
205 | using T2 = Interface3<I1*>; |
206 | using T3 = Interface2<P1>; |
207 | using T4 = Interface3<P1, P2>; |
208 | using T5 = __kindof Interface2; |
209 | }; |
210 | #else |
211 | Invalid1 i1; |
212 | // expected-error@first.h:* {{'Types::ObjCObject::Invalid1::T' from module 'FirstModule' is not present in definition of 'Types::ObjCObject::Invalid1' in module 'SecondModule'}} |
213 | // expected-note@second.h:* {{declaration of 'T' does not match}} |
214 | Invalid2 i2; |
215 | // expected-error@first.h:* {{'Types::ObjCObject::Invalid2::T' from module 'FirstModule' is not present in definition of 'Types::ObjCObject::Invalid2' in module 'SecondModule'}} |
216 | // expected-note@second.h:* {{declaration of 'T' does not match}} |
217 | Invalid3 i3; |
218 | // expected-error@second.h:* {{'Types::ObjCObject::Invalid3' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'T' with underlying type 'Interface2<P1>'}} |
219 | // expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'Interface2<P1,P1>'}} |
220 | Invalid4 i4; |
221 | // expected-error@first.h:* {{'Types::ObjCObject::Invalid4::T' from module 'FirstModule' is not present in definition of 'Types::ObjCObject::Invalid4' in module 'SecondModule'}} |
222 | // expected-note@second.h:* {{declaration of 'T' does not match}} |
223 | Valid v; |
224 | #endif |
225 | } // namespace VisitObjCObject |
226 | } // namespace Types |
227 | |
228 | #if defined(FIRST) |
229 | @interface Interface4 <T : I1 *> { |
230 | @public |
231 | T<P1> x; |
232 | } |
233 | @end |
234 | @interface Interface5 <T : I1 *> { |
235 | @public |
236 | T<P1> x; |
237 | } |
238 | @end |
239 | @interface Interface6 <T1 : I1 *, T2 : I2 *> { |
240 | @public |
241 | T1 x; |
242 | } |
243 | @end |
244 | #elif defined(SECOND) |
245 | @interface Interface4 <T : I1 *> { |
246 | @public |
247 | T<P2> x; |
248 | } |
249 | @end |
250 | @interface Interface5 <T : I1 *> { |
251 | @public |
252 | T<P1, P2> x; |
253 | } |
254 | @end |
255 | @interface Interface6 <T1 : I1 *, T2 : I2 *> { |
256 | @public |
257 | T2 x; |
258 | } |
259 | @end |
260 | #endif |
261 | |
262 | namespace Types { |
263 | namespace ObjCTypeParam { |
264 | #if defined(FIRST) || defined(SECOND) |
265 | struct Invalid1 { |
266 | Interface4 *I; |
267 | decltype(I->x) x; |
268 | }; |
269 | struct Invalid2 { |
270 | Interface5 *I; |
271 | decltype(I->x) x; |
272 | }; |
273 | struct Invalid3 { |
274 | Interface6 *I; |
275 | decltype(I->x) x; |
276 | }; |
277 | #else |
278 | Invalid1 i1; |
279 | // expected-error@first.h:* {{'Types::ObjCTypeParam::Invalid1::x' from module 'FirstModule' is not present in definition of 'Types::ObjCTypeParam::Invalid1' in module 'SecondModule'}} |
280 | // expected-note@second.h:* {{declaration of 'x' does not match}} |
281 | Invalid2 i2; |
282 | // expected-error@first.h:* {{'Types::ObjCTypeParam::Invalid2::x' from module 'FirstModule' is not present in definition of 'Types::ObjCTypeParam::Invalid2' in module 'SecondModule'}} |
283 | // expected-note@second.h:* {{declaration of 'x' does not match}} |
284 | Invalid3 i3; |
285 | // expected-error@first.h:* {{'Types::ObjCTypeParam::Invalid3::x' from module 'FirstModule' is not present in definition of 'Types::ObjCTypeParam::Invalid3' in module 'SecondModule'}} |
286 | // expected-note@second.h:* {{declaration of 'x' does not match}} |
287 | #endif |
288 | |
289 | } // namespace ObjCTypeParam |
290 | } // namespace Types |
291 | |
292 | // Keep macros contained to one file. |
293 | #ifdef FIRST |
294 | #undef FIRST |
295 | #endif |
296 | |
297 | #ifdef SECOND |
298 | #undef SECOND |
299 | #endif |
300 | |