[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / Modules / compare-objc-protocol.m
blob6dec2965487c5f0f3f449e3170fdc68984454e5e
1 // RUN: rm -rf %t
2 // RUN: split-file %s %t
4 // Build first header file
5 // RUN: echo "#define FIRST" >> %t/include/first.h
6 // RUN: cat %t/test.m        >> %t/include/first.h
7 // RUN: echo "#undef FIRST"  >> %t/include/first.h
9 // Build second header file
10 // RUN: echo "#define SECOND" >> %t/include/second.h
11 // RUN: cat %t/test.m         >> %t/include/second.h
12 // RUN: echo "#undef SECOND"  >> %t/include/second.h
14 // Test that each header can compile
15 // RUN: %clang_cc1 -fsyntax-only -x objective-c %t/include/first.h -fblocks -fobjc-arc
16 // RUN: %clang_cc1 -fsyntax-only -x objective-c %t/include/second.h -fblocks -fobjc-arc
18 // Run test
19 // RUN: %clang_cc1 -I%t/include -verify %t/test.m -fblocks -fobjc-arc \
20 // RUN:            -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache
22 // Run the same test with second.h being modular
23 // RUN: cat %t/include/second.modulemap >> %t/include/module.modulemap
24 // RUN: %clang_cc1 -I%t/include -verify %t/test.m -fblocks -fobjc-arc -DTEST_MODULAR=1 \
25 // RUN:            -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache
27 // In non-modular case we ignore protocol redefinitions. But with modules
28 // previous definition can come from a hidden [sub]module. And in this case we
29 // allow a new definition if it is equivalent to the hidden one.
31 // This test case is to verify equivalence checks.
33 //--- include/common.h
34 #ifndef COMMON_H
35 #define COMMON_H
36 @protocol CommonProtocol @end
37 @protocol ExtraProtocol @end
38 #endif
40 //--- include/first-empty.h
41 //--- include/module.modulemap
42 module Common {
43   header "common.h"
44   export *
46 module First {
47   module Empty {
48     header "first-empty.h"
49   }
50   module Hidden {
51     header "first.h"
52     export *
53   }
55 //--- include/second.modulemap
56 module Second {
57   header "second.h"
58   export *
61 //--- test.m
62 #if defined(FIRST) || defined(SECOND)
63 # include "common.h"
64 #endif
66 #if !defined(FIRST) && !defined(SECOND)
67 # include "first-empty.h"
68 # include "second.h"
69 #endif
71 #if defined(FIRST)
72 @protocol CompareForwardDeclaration1;
73 @protocol CompareForwardDeclaration2<CommonProtocol> @end
74 #elif defined(SECOND)
75 @protocol CompareForwardDeclaration1<CommonProtocol> @end
76 @protocol CompareForwardDeclaration2;
77 #else
78 id<CompareForwardDeclaration1> compareForwardDeclaration1;
79 id<CompareForwardDeclaration2> compareForwardDeclaration2;
80 #endif
82 #if defined(FIRST)
83 @protocol CompareMatchingConformingProtocols<CommonProtocol> @end
84 @protocol ForwardProtocol;
85 @protocol CompareMatchingConformingForwardProtocols<ForwardProtocol> @end
87 @protocol CompareProtocolPresence1<CommonProtocol> @end
88 @protocol CompareProtocolPresence2 @end
90 @protocol CompareDifferentProtocols<CommonProtocol> @end
91 @protocol CompareProtocolOrder<CommonProtocol, ExtraProtocol> @end
92 #elif defined(SECOND)
93 @protocol CompareMatchingConformingProtocols<CommonProtocol> @end
94 @protocol ForwardProtocol @end
95 @protocol CompareMatchingConformingForwardProtocols<ForwardProtocol> @end
97 @protocol CompareProtocolPresence1 @end
98 @protocol CompareProtocolPresence2<CommonProtocol> @end
100 @protocol CompareDifferentProtocols<ExtraProtocol> @end
101 @protocol CompareProtocolOrder<ExtraProtocol, CommonProtocol> @end
102 #else
103 id<CompareMatchingConformingProtocols> compareMatchingConformingProtocols;
104 id<CompareMatchingConformingForwardProtocols> compareMatchingConformingForwardProtocols;
106 id<CompareProtocolPresence1> compareProtocolPresence1;
107 // expected-error@first.h:* {{'CompareProtocolPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found 1 referenced protocol}}
108 #ifdef TEST_MODULAR
109 // expected-note@second.h:* {{but in 'Second' found 0 referenced protocols}}
110 #else
111 // expected-note@second.h:* {{but in definition here found 0 referenced protocols}}
112 #endif
113 id<CompareProtocolPresence2> compareProtocolPresence2;
114 // expected-error@first.h:* {{'CompareProtocolPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found 0 referenced protocols}}
115 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 1 referenced protocol}}
117 id<CompareDifferentProtocols> compareDifferentProtocols;
118 // expected-error@first.h:* {{'CompareDifferentProtocols' has different definitions in different modules; first difference is definition in module 'First.Hidden' found 1st referenced protocol with name 'CommonProtocol'}}
119 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 1st referenced protocol with different name 'ExtraProtocol'}}
120 id<CompareProtocolOrder> compareProtocolOrder;
121 // expected-error@first.h:* {{'CompareProtocolOrder' has different definitions in different modules; first difference is definition in module 'First.Hidden' found 1st referenced protocol with name 'CommonProtocol'}}
122 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 1st referenced protocol with different name 'ExtraProtocol'}}
123 #endif
125 #if defined(FIRST)
126 @protocol CompareMatchingMethods
127 - (float)matchingMethod:(int)arg;
128 @end
130 @protocol CompareMethodPresence1
131 - (void)presenceMethod1;
132 @end
133 @protocol CompareMethodPresence2
134 @end
136 @protocol CompareMethodName
137 - (void)methodNameA;
138 @end
140 @protocol CompareMethodArgCount
141 - (void)methodArgCount:(int)arg0 :(int)arg1;
142 @end
143 @protocol CompareMethodArgName
144 - (void)methodArgName:(int)argNameA;
145 @end
146 @protocol CompareMethodArgType
147 - (void)methodArgType:(int)argType;
148 @end
150 @protocol CompareMethodReturnType
151 - (int)methodReturnType;
152 @end
154 @protocol CompareMethodOrder
155 - (void)methodOrderFirst;
156 - (void)methodOrderSecond;
157 @end
159 @protocol CompareMethodClassInstance
160 - (void)methodClassInstance;
161 @end
163 @protocol CompareMethodRequirednessExplicit
164 @optional
165 - (void)methodRequiredness;
166 @end
167 @protocol CompareMethodRequirednessDefault
168 // @required is default
169 - (void)methodRequiredness;
170 @end
171 #elif defined(SECOND)
172 @protocol CompareMatchingMethods
173 - (float)matchingMethod:(int)arg;
174 @end
176 @protocol CompareMethodPresence1
177 @end
178 @protocol CompareMethodPresence2
179 - (void)presenceMethod2;
180 @end
182 @protocol CompareMethodName
183 - (void)methodNameB;
184 @end
186 @protocol CompareMethodArgCount
187 - (void)methodArgCount:(int)arg0;
188 @end
189 @protocol CompareMethodArgName
190 - (void)methodArgName:(int)argNameB;
191 @end
192 @protocol CompareMethodArgType
193 - (void)methodArgType:(float)argType;
194 @end
196 @protocol CompareMethodReturnType
197 - (float)methodReturnType;
198 @end
200 @protocol CompareMethodOrder
201 - (void)methodOrderSecond;
202 - (void)methodOrderFirst;
203 @end
205 @protocol CompareMethodClassInstance
206 + (void)methodClassInstance;
207 @end
209 @protocol CompareMethodRequirednessExplicit
210 @required
211 - (void)methodRequiredness;
212 @end
213 @protocol CompareMethodRequirednessDefault
214 @required
215 - (void)methodRequiredness;
216 @end
217 #else
218 id<CompareMatchingMethods> compareMatchingMethods; // no error
219 id<CompareMethodPresence1> compareMethodPresence1;
220 // expected-error@first.h:* {{'CompareMethodPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method}}
221 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found end of class}}
222 id<CompareMethodPresence2> compareMethodPresence2;
223 // expected-error@first.h:* {{'CompareMethodPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found end of class}}
224 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method}}
225 id<CompareMethodName> compareMethodName;
226 // expected-error@first.h:* {{'CompareMethodName' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method 'methodNameA'}}
227 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found different method 'methodNameB'}}
229 id<CompareMethodArgCount> compareMethodArgCount;
230 // expected-error@first.h:* {{'CompareMethodArgCount' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method 'methodArgCount::' that has 2 parameters}}
231 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodArgCount:' that has 1 parameter}}
232 id<CompareMethodArgName> compareMethodArgName;
233 // expected-error@first.h:* {{'CompareMethodArgName' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method 'methodArgName:' with 1st parameter named 'argNameA'}}
234 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodArgName:' with 1st parameter named 'argNameB'}}
235 id<CompareMethodArgType> compareMethodArgType;
236 // expected-error@first.h:* {{'CompareMethodArgType' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method 'methodArgType:' with 1st parameter of type 'int'}}
237 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodArgType:' with 1st parameter of type 'float'}}
239 id<CompareMethodReturnType> compareMethodReturnType;
240 // expected-error@first.h:* {{'CompareMethodReturnType' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method 'methodReturnType' with return type 'int'}}
241 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodReturnType' with different return type 'float'}}
243 id<CompareMethodOrder> compareMethodOrder;
244 // expected-error@first.h:* {{'CompareMethodOrder' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method 'methodOrderFirst'}}
245 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found different method 'methodOrderSecond'}}
246 id<CompareMethodClassInstance> compareMethodClassInstance;
247 // expected-error@first.h:* {{'CompareMethodClassInstance' has different definitions in different modules; first difference is definition in module 'First.Hidden' found instance method 'methodClassInstance'}}
248 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodClassInstance' as class method}}
250 id<CompareMethodRequirednessExplicit> compareMethodRequirednessExplicit;
251 // expected-error@first.h:* {{'CompareMethodRequirednessExplicit' has different definitions in different modules; first difference is definition in module 'First.Hidden' found 'optional' method control}}
252 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 'required' method control}}
253 id<CompareMethodRequirednessDefault> compareMethodRequirednessDefault; // no error
254 #endif
256 #if defined(FIRST)
257 @protocol CompareMatchingProperties
258 @property int matchingPropName;
259 @end
261 @protocol ComparePropertyPresence1
262 @property int propPresence1;
263 @end
264 @protocol ComparePropertyPresence2
265 @end
267 @protocol ComparePropertyName
268 @property int propNameA;
269 @end
271 @protocol ComparePropertyType
272 @property int propType;
273 @end
275 @protocol ComparePropertyOrder
276 @property int propOrderX;
277 @property int propOrderY;
278 @end
280 @protocol CompareMatchingPropertyAttributes
281 @property (nonatomic, assign) int matchingProp;
282 @end
283 @protocol ComparePropertyAttributes
284 @property (nonatomic) int propAttributes;
285 @end
286 // Edge cases.
287 @protocol CompareFirstImplAttribute
288 @property int firstImplAttribute;
289 @end
290 @protocol CompareLastImplAttribute
291 // Cannot test with protocols 'direct' attribute because it's not allowed.
292 @property (class) int lastImplAttribute;
293 @end
294 #elif defined(SECOND)
295 @protocol CompareMatchingProperties
296 @property int matchingPropName;
297 @end
299 @protocol ComparePropertyPresence1
300 @end
301 @protocol ComparePropertyPresence2
302 @property int propPresence2;
303 @end
305 @protocol ComparePropertyName
306 @property int propNameB;
307 @end
309 @protocol ComparePropertyType
310 @property float propType;
311 @end
313 @protocol ComparePropertyOrder
314 @property int propOrderY;
315 @property int propOrderX;
316 @end
318 @protocol CompareMatchingPropertyAttributes
319 @property (assign, nonatomic) int matchingProp;
320 @end
321 @protocol ComparePropertyAttributes
322 @property (atomic) int propAttributes;
323 @end
324 // Edge cases.
325 @protocol CompareFirstImplAttribute
326 @property (readonly) int firstImplAttribute;
327 @end
328 @protocol CompareLastImplAttribute
329 @property int lastImplAttribute;
330 @end
331 #else
332 id<CompareMatchingProperties> compareMatchingProperties;
333 id<ComparePropertyPresence1> comparePropertyPresence1;
334 // expected-error@first.h:* {{'ComparePropertyPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property}}
335 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found end of class}}
336 id<ComparePropertyPresence2> comparePropertyPresence2;
337 // expected-error@first.h:* {{'ComparePropertyPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found end of class}}
338 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property}}
339 id<ComparePropertyName> comparePropertyName;
340 // expected-error@first.h:* {{'ComparePropertyName' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property 'propNameA'}}
341 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'propNameB'}}
342 id<ComparePropertyType> comparePropertyType;
343 // expected-error@first.h:* {{'ComparePropertyType' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property 'propType' with type 'int'}}
344 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'propType' with type 'float'}}
345 id<ComparePropertyOrder> comparePropertyOrder;
346 // expected-error@first.h:* {{'ComparePropertyOrder' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property 'propOrderX'}}
347 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'propOrderY'}}
349 id<CompareMatchingPropertyAttributes> compareMatchingPropertyAttributes;
350 id<ComparePropertyAttributes> comparePropertyAttributes;
351 // expected-error@first.h:* {{'ComparePropertyAttributes' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property 'propAttributes' with 'nonatomic' attribute}}
352 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'propAttributes' with different 'nonatomic' attribute}}
353 id<CompareFirstImplAttribute> compareFirstImplAttribute;
354 // expected-error@first.h:* {{'CompareFirstImplAttribute' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property 'firstImplAttribute' with default 'readonly' attribute}}
355 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'firstImplAttribute' with different 'readonly' attribute}}
356 id<CompareLastImplAttribute> compareLastImplAttribute;
357 // expected-error@first.h:* {{'CompareLastImplAttribute' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property 'lastImplAttribute' with 'class' attribute}}
358 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'lastImplAttribute' with different 'class' attribute}}
359 #endif