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
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 // Test that we don't accept different class definitions with the same name
28 // from multiple modules but detect mismatches and provide actionable
31 //--- include/common.h
34 @interface NSObject @end
35 @protocol CommonProtocol @end
36 @protocol ExtraProtocol @end
39 //--- include/first-empty.h
40 //--- include/module.modulemap
43 header "first-empty.h"
51 //--- include/second.modulemap
58 #if defined(FIRST) || defined(SECOND)
62 #if !defined(FIRST) && !defined(SECOND)
63 # include "first-empty.h"
68 @class CompareForwardDeclaration1;
69 @interface CompareForwardDeclaration2: NSObject @end
71 @interface CompareForwardDeclaration1: NSObject @end
72 @class CompareForwardDeclaration2;
74 CompareForwardDeclaration1 *compareForwardDeclaration1;
75 CompareForwardDeclaration2 *compareForwardDeclaration2;
79 @interface CompareMatchingSuperclass: NSObject @end
81 @interface CompareSuperclassPresence1: NSObject @end
82 @interface CompareSuperclassPresence2 @end
84 @interface CompareDifferentSuperclass: NSObject @end
86 @interface CompareMatchingSuperclass: NSObject @end
88 @interface CompareSuperclassPresence1 @end
89 @interface CompareSuperclassPresence2: NSObject @end
91 @interface DifferentSuperclass: NSObject @end
92 @interface CompareDifferentSuperclass: DifferentSuperclass @end
94 CompareMatchingSuperclass *compareMatchingSuperclass;
95 CompareSuperclassPresence1 *compareSuperclassPresence1;
96 // expected-error@first.h:* {{'CompareSuperclassPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found super class with type 'NSObject'}}
97 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found no super class}}
98 CompareSuperclassPresence2 *compareSuperclassPresence2;
99 // expected-error@first.h:* {{'CompareSuperclassPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found no super class}}
100 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found super class with type 'NSObject'}}
101 CompareDifferentSuperclass *compareDifferentSuperclass;
102 // expected-error@first.h:* {{'CompareDifferentSuperclass' has different definitions in different modules; first difference is definition in module 'First.Hidden' found super class with type 'NSObject'}}
103 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found super class with type 'DifferentSuperclass'}}
107 @interface CompareMatchingConformingProtocols: NSObject<CommonProtocol> @end
108 @protocol ForwardProtocol;
109 @interface CompareMatchingConformingForwardProtocols: NSObject<ForwardProtocol> @end
111 @interface CompareProtocolPresence1: NSObject<CommonProtocol> @end
112 @interface CompareProtocolPresence2: NSObject @end
114 @interface CompareDifferentProtocols: NSObject<CommonProtocol> @end
115 @interface CompareProtocolOrder: NSObject<CommonProtocol, ExtraProtocol> @end
116 #elif defined(SECOND)
117 @interface CompareMatchingConformingProtocols: NSObject<CommonProtocol> @end
118 @protocol ForwardProtocol @end
119 @interface CompareMatchingConformingForwardProtocols: NSObject<ForwardProtocol> @end
121 @interface CompareProtocolPresence1: NSObject @end
122 @interface CompareProtocolPresence2: NSObject<CommonProtocol> @end
124 @interface CompareDifferentProtocols: NSObject<ExtraProtocol> @end
125 @interface CompareProtocolOrder: NSObject<ExtraProtocol, CommonProtocol> @end
127 CompareMatchingConformingProtocols *compareMatchingConformingProtocols;
128 CompareMatchingConformingForwardProtocols *compareMatchingConformingForwardProtocols;
130 CompareProtocolPresence1 *compareProtocolPresence1;
131 // expected-error@first.h:* {{'CompareProtocolPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found 1 referenced protocol}}
132 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 0 referenced protocols}}
133 CompareProtocolPresence2 *compareProtocolPresence2;
134 // expected-error@first.h:* {{'CompareProtocolPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found 0 referenced protocols}}
135 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 1 referenced protocol}}
137 CompareDifferentProtocols *compareDifferentProtocols;
138 // 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'}}
139 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 1st referenced protocol with different name 'ExtraProtocol'}}
140 CompareProtocolOrder *compareProtocolOrder;
141 // 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'}}
142 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 1st referenced protocol with different name 'ExtraProtocol'}}
146 @interface CompareMatchingIVars: NSObject { int ivarName; } @end
148 @interface CompareIVarPresence1: NSObject @end
149 @interface CompareIVarPresence2: NSObject { int ivarPresence2; } @end
151 @interface CompareIVarName: NSObject { int ivarName; } @end
152 @interface CompareIVarType: NSObject { int ivarType; } @end
153 @interface CompareIVarOrder: NSObject {
159 @interface CompareIVarVisibilityExplicit: NSObject {
164 @interface CompareIVarVisibilityDefault: NSObject {
165 int ivarVisibilityDefault;
168 #elif defined(SECOND)
169 @interface CompareMatchingIVars: NSObject { int ivarName; } @end
171 @interface CompareIVarPresence1: NSObject { int ivarPresence1; } @end
172 @interface CompareIVarPresence2: NSObject @end
174 @interface CompareIVarName: NSObject { int differentIvarName; } @end
175 @interface CompareIVarType: NSObject { float ivarType; } @end
176 @interface CompareIVarOrder: NSObject {
182 @interface CompareIVarVisibilityExplicit: NSObject {
187 @interface CompareIVarVisibilityDefault: NSObject {
189 int ivarVisibilityDefault;
193 CompareMatchingIVars *compareMatchingIVars;
195 CompareIVarPresence1 *compareIVarPresence1;
197 // expected-error@second.h:* {{'CompareIVarPresence1::ivarPresence1' from module 'Second' is not present in definition of 'CompareIVarPresence1' in module 'First.Hidden'}}
198 // expected-note@first.h:* {{definition has no member 'ivarPresence1'}}
200 // expected-error@first.h:* {{'CompareIVarPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found end of class}}
201 // expected-note@second.h:* {{but in definition here found instance variable}}
203 CompareIVarPresence2 *compareIVarPresence2;
204 // expected-error@first.h:* {{'CompareIVarPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found instance variable}}
205 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found end of class}}
207 CompareIVarName *compareIVarName;
209 // expected-error@second.h:* {{'CompareIVarName::differentIvarName' from module 'Second' is not present in definition of 'CompareIVarName' in module 'First.Hidden'}}
210 // expected-note@first.h:* {{definition has no member 'differentIvarName'}}
212 // expected-error@first.h:* {{'CompareIVarName' has different definitions in different modules; first difference is definition in module 'First.Hidden' found field 'ivarName'}}
213 // expected-note@second.h:* {{but in definition here found field 'differentIvarName'}}
215 CompareIVarType *compareIVarType;
217 // expected-error@second.h:* {{'CompareIVarType::ivarType' from module 'Second' is not present in definition of 'CompareIVarType' in module 'First.Hidden'}}
218 // expected-note@first.h:* {{declaration of 'ivarType' does not match}}
220 // expected-error@first.h:* {{'CompareIVarType' has different definitions in different modules; first difference is definition in module 'First.Hidden' found field 'ivarType' with type 'int'}}
221 // expected-note@second.h:* {{but in definition here found field 'ivarType' with type 'float'}}
223 CompareIVarOrder *compareIVarOrder;
224 // expected-error@first.h:* {{'CompareIVarOrder' has different definitions in different modules; first difference is definition in module 'First.Hidden' found field 'ivarNameInt'}}
225 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found field 'ivarNameFloat'}}
227 CompareIVarVisibilityExplicit *compareIVarVisibilityExplicit;
228 // expected-error@first.h:* {{'CompareIVarVisibilityExplicit' has different definitions in different modules; first difference is definition in module 'First.Hidden' found instance variable 'ivarVisibility' access control is @public}}
229 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found instance variable 'ivarVisibility' access control is @private}}
230 CompareIVarVisibilityDefault *compareIVarVisibilityDefault;
231 // expected-error@first.h:* {{'CompareIVarVisibilityDefault' has different definitions in different modules; first difference is definition in module 'First.Hidden' found instance variable 'ivarVisibilityDefault' access control is @protected}}
232 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found instance variable 'ivarVisibilityDefault' access control is @public}}
236 @interface CompareMatchingMethods: NSObject
237 - (float)matchingMethod:(int)arg;
240 @interface CompareMethodPresence1: NSObject
241 - (void)presenceMethod1;
243 @interface CompareMethodPresence2: NSObject
246 @interface CompareMethodName: NSObject
250 @interface CompareMethodArgCount: NSObject
251 - (void)methodArgCount:(int)arg0 :(int)arg1;
253 @interface CompareMethodArgName: NSObject
254 - (void)methodArgName:(int)argNameA;
256 @interface CompareMethodArgType: NSObject
257 - (void)methodArgType:(int)argType;
260 @interface CompareMethodReturnType: NSObject
261 - (int)methodReturnType;
264 @interface CompareMethodOrder: NSObject
265 - (void)methodOrderFirst;
266 - (void)methodOrderSecond;
269 @interface CompareMethodClassInstance: NSObject
270 + (void)methodClassInstance;
272 #elif defined(SECOND)
273 @interface CompareMatchingMethods: NSObject
274 - (float)matchingMethod:(int)arg;
277 @interface CompareMethodPresence1: NSObject
279 @interface CompareMethodPresence2: NSObject
280 - (void)presenceMethod2;
283 @interface CompareMethodName: NSObject
287 @interface CompareMethodArgCount: NSObject
288 - (void)methodArgCount:(int)arg0;
290 @interface CompareMethodArgName: NSObject
291 - (void)methodArgName:(int)argNameB;
293 @interface CompareMethodArgType: NSObject
294 - (void)methodArgType:(float)argType;
297 @interface CompareMethodReturnType: NSObject
298 - (float)methodReturnType;
301 @interface CompareMethodOrder: NSObject
302 - (void)methodOrderSecond;
303 - (void)methodOrderFirst;
306 @interface CompareMethodClassInstance: NSObject
307 - (void)methodClassInstance;
310 CompareMatchingMethods *compareMatchingMethods;
311 CompareMethodPresence1 *compareMethodPresence1;
312 // expected-error@first.h:* {{'CompareMethodPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method}}
313 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found end of class}}
314 CompareMethodPresence2 *compareMethodPresence2;
315 // expected-error@first.h:* {{'CompareMethodPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found end of class}}
316 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method}}
317 CompareMethodName *compareMethodName;
318 // expected-error@first.h:* {{'CompareMethodName' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method 'methodNameA'}}
319 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found different method 'methodNameB'}}
321 CompareMethodArgCount *compareMethodArgCount;
322 // 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}}
323 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodArgCount:' that has 1 parameter}}
324 CompareMethodArgName *compareMethodArgName;
325 // 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'}}
326 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodArgName:' with 1st parameter named 'argNameB'}}
327 CompareMethodArgType *compareMethodArgType;
328 // 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'}}
329 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodArgType:' with 1st parameter of type 'float'}}
331 CompareMethodReturnType *compareMethodReturnType;
332 // 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'}}
333 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodReturnType' with different return type 'float'}}
335 CompareMethodOrder *compareMethodOrder;
336 // expected-error@first.h:* {{'CompareMethodOrder' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method 'methodOrderFirst'}}
337 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found different method 'methodOrderSecond'}}
338 CompareMethodClassInstance *compareMethodClassInstance;
339 // expected-error@first.h:* {{'CompareMethodClassInstance' has different definitions in different modules; first difference is definition in module 'First.Hidden' found class method 'methodClassInstance'}}
340 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodClassInstance' as instance method}}
344 @interface CompareMatchingProperties: NSObject
345 @property int matchingPropName;
348 @interface ComparePropertyPresence1: NSObject
349 @property int propPresence1;
351 @interface ComparePropertyPresence2: NSObject
354 @interface ComparePropertyName: NSObject
355 @property int propNameA;
358 @interface ComparePropertyType: NSObject
359 @property int propType;
362 @interface ComparePropertyOrder: NSObject
363 @property int propOrderX;
364 @property int propOrderY;
367 @interface CompareMatchingPropertyAttributes: NSObject
368 @property (nonatomic, assign) int matchingProp;
370 @interface ComparePropertyAttributes: NSObject
371 @property (readonly) int propAttributes;
374 @interface CompareFirstImplAttribute: NSObject
375 @property int firstImplAttribute;
377 @interface CompareLastImplAttribute: NSObject
378 @property (direct) int lastImplAttribute;
380 #elif defined(SECOND)
381 @interface CompareMatchingProperties: NSObject
382 @property int matchingPropName;
385 @interface ComparePropertyPresence1: NSObject
387 @interface ComparePropertyPresence2: NSObject
388 @property int propPresence2;
391 @interface ComparePropertyName: NSObject
392 @property int propNameB;
395 @interface ComparePropertyType: NSObject
396 @property float propType;
399 @interface ComparePropertyOrder: NSObject
400 @property int propOrderY;
401 @property int propOrderX;
404 @interface CompareMatchingPropertyAttributes: NSObject
405 @property (assign, nonatomic) int matchingProp;
407 @interface ComparePropertyAttributes: NSObject
408 @property (readwrite) int propAttributes;
411 @interface CompareFirstImplAttribute: NSObject
412 @property (readonly) int firstImplAttribute;
414 @interface CompareLastImplAttribute: NSObject
415 @property int lastImplAttribute;
418 CompareMatchingProperties *compareMatchingProperties;
419 ComparePropertyPresence1 *comparePropertyPresence1;
420 // expected-error@first.h:* {{'ComparePropertyPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property}}
421 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found end of class}}
422 ComparePropertyPresence2 *comparePropertyPresence2;
423 // expected-error@first.h:* {{'ComparePropertyPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found end of class}}
424 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property}}
426 ComparePropertyName *comparePropertyName;
427 // expected-error@first.h:* {{'ComparePropertyName' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property 'propNameA'}}
428 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'propNameB'}}
429 ComparePropertyType *comparePropertyType;
430 // 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'}}
431 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'propType' with type 'float'}}
432 ComparePropertyOrder *comparePropertyOrder;
433 // expected-error@first.h:* {{'ComparePropertyOrder' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property 'propOrderX'}}
434 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'propOrderY'}}
436 CompareMatchingPropertyAttributes *compareMatchingPropertyAttributes;
437 ComparePropertyAttributes *comparePropertyAttributes;
438 // expected-error@first.h:* {{'ComparePropertyAttributes' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property 'propAttributes' with 'readonly' attribute}}
439 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'propAttributes' with different 'readonly' attribute}}
440 CompareFirstImplAttribute *compareFirstImplAttribute;
441 // 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}}
442 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'firstImplAttribute' with different 'readonly' attribute}}
443 CompareLastImplAttribute *compareLastImplAttribute;
444 // expected-error@first.h:* {{'CompareLastImplAttribute' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property 'lastImplAttribute' with 'direct' attribute}}
445 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'lastImplAttribute' with different 'direct' attribute}}
449 @interface CompareMatchingCategories: NSObject @end
450 @interface CompareMatchingCategories(Matching)
454 @interface CompareMismatchingCategories1: NSObject @end
455 @interface CompareMismatchingCategories1(Category1)
456 - (void)presentMethod;
458 @interface CompareMismatchingCategories2: NSObject @end
459 @interface CompareMismatchingCategories2(Category2)
462 @interface CompareDifferentCategoryNames: NSObject @end
463 @interface CompareDifferentCategoryNames(CategoryFirst)
464 - (void)firstMethod:(int)x;
466 #elif defined(SECOND)
467 @interface CompareMatchingCategories: NSObject @end
468 @interface CompareMatchingCategories(Matching)
472 @interface CompareMismatchingCategories1: NSObject @end
473 @interface CompareMismatchingCategories1(Category1)
475 @interface CompareMismatchingCategories2: NSObject @end
476 @interface CompareMismatchingCategories2(Category2)
477 - (void)presentMethod;
480 @interface CompareDifferentCategoryNames: NSObject @end
481 @interface CompareDifferentCategoryNames(CategorySecond)
482 - (void)secondMethod;
485 CompareMatchingCategories *compareMatchingCategories; // no diagnostic
486 CompareMismatchingCategories1 *compareMismatchingCategories1;
488 // expected-warning@second.h:* {{duplicate definition of category 'Category1' on interface 'CompareMismatchingCategories1'}}
489 // expected-note@first.h:* {{previous definition is here}}
491 CompareMismatchingCategories2 *compareMismatchingCategories2;
493 // expected-warning@second.h:* {{duplicate definition of category 'Category2' on interface 'CompareMismatchingCategories2'}}
494 // expected-note@first.h:* {{previous definition is here}}
496 CompareDifferentCategoryNames *compareDifferentCategoryNames; // no diagnostic