498 lines · plain
1// RUN: rm -rf %t2// RUN: split-file %s %t3 4// Build first header file5// RUN: echo "#define FIRST" >> %t/include/first.h6// RUN: cat %t/test.m >> %t/include/first.h7// RUN: echo "#undef FIRST" >> %t/include/first.h8 9// Build second header file10// RUN: echo "#define SECOND" >> %t/include/second.h11// RUN: cat %t/test.m >> %t/include/second.h12// RUN: echo "#undef SECOND" >> %t/include/second.h13 14// Test that each header can compile15// RUN: %clang_cc1 -fsyntax-only -x objective-c %t/include/first.h -fblocks -fobjc-arc16// RUN: %clang_cc1 -fsyntax-only -x objective-c %t/include/second.h -fblocks -fobjc-arc17 18// Run test19// RUN: %clang_cc1 -I%t/include -verify %t/test.m -fblocks -fobjc-arc \20// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache21 22// Run the same test with second.h being modular23// RUN: cat %t/include/second.modulemap >> %t/include/module.modulemap24// 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.cache26 27// Test that we don't accept different class definitions with the same name28// from multiple modules but detect mismatches and provide actionable29// diagnostic.30 31//--- include/common.h32#ifndef COMMON_H33#define COMMON_H34@interface NSObject @end35@protocol CommonProtocol @end36@protocol ExtraProtocol @end37#endif38 39//--- include/first-empty.h40//--- include/module.modulemap41module First {42 module Empty {43 header "first-empty.h"44 }45 module Hidden {46 header "first.h"47 export *48 }49}50 51//--- include/second.modulemap52module Second {53 header "second.h"54 export *55}56 57//--- test.m58#if defined(FIRST) || defined(SECOND)59# include "common.h"60#endif61 62#if !defined(FIRST) && !defined(SECOND)63# include "first-empty.h"64# include "second.h"65#endif66 67#if defined(FIRST)68@class CompareForwardDeclaration1;69@interface CompareForwardDeclaration2: NSObject @end70#elif defined(SECOND)71@interface CompareForwardDeclaration1: NSObject @end72@class CompareForwardDeclaration2;73#else74CompareForwardDeclaration1 *compareForwardDeclaration1;75CompareForwardDeclaration2 *compareForwardDeclaration2;76#endif77 78#if defined(FIRST)79@interface CompareMatchingSuperclass: NSObject @end80 81@interface CompareSuperclassPresence1: NSObject @end82@interface CompareSuperclassPresence2 @end83 84@interface CompareDifferentSuperclass: NSObject @end85#elif defined(SECOND)86@interface CompareMatchingSuperclass: NSObject @end87 88@interface CompareSuperclassPresence1 @end89@interface CompareSuperclassPresence2: NSObject @end90 91@interface DifferentSuperclass: NSObject @end92@interface CompareDifferentSuperclass: DifferentSuperclass @end93#else94CompareMatchingSuperclass *compareMatchingSuperclass;95CompareSuperclassPresence1 *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}}98CompareSuperclassPresence2 *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'}}101CompareDifferentSuperclass *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'}}104#endif105 106#if defined(FIRST)107@interface CompareMatchingConformingProtocols: NSObject<CommonProtocol> @end108@protocol ForwardProtocol;109@interface CompareMatchingConformingForwardProtocols: NSObject<ForwardProtocol> @end110 111@interface CompareProtocolPresence1: NSObject<CommonProtocol> @end112@interface CompareProtocolPresence2: NSObject @end113 114@interface CompareDifferentProtocols: NSObject<CommonProtocol> @end115@interface CompareProtocolOrder: NSObject<CommonProtocol, ExtraProtocol> @end116#elif defined(SECOND)117@interface CompareMatchingConformingProtocols: NSObject<CommonProtocol> @end118@protocol ForwardProtocol @end119@interface CompareMatchingConformingForwardProtocols: NSObject<ForwardProtocol> @end120 121@interface CompareProtocolPresence1: NSObject @end122@interface CompareProtocolPresence2: NSObject<CommonProtocol> @end123 124@interface CompareDifferentProtocols: NSObject<ExtraProtocol> @end125@interface CompareProtocolOrder: NSObject<ExtraProtocol, CommonProtocol> @end126#else127CompareMatchingConformingProtocols *compareMatchingConformingProtocols;128CompareMatchingConformingForwardProtocols *compareMatchingConformingForwardProtocols;129 130CompareProtocolPresence1 *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}}133CompareProtocolPresence2 *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}}136 137CompareDifferentProtocols *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'}}140CompareProtocolOrder *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'}}143#endif144 145#if defined(FIRST)146@interface CompareMatchingIVars: NSObject { int ivarName; } @end147 148@interface CompareIVarPresence1: NSObject @end149@interface CompareIVarPresence2: NSObject { int ivarPresence2; } @end150 151@interface CompareIVarName: NSObject { int ivarName; } @end152@interface CompareIVarType: NSObject { int ivarType; } @end153@interface CompareIVarOrder: NSObject {154 int ivarNameInt;155 float ivarNameFloat;156}157@end158 159@interface CompareIVarVisibilityExplicit: NSObject {160@public161 int ivarVisibility;162}163@end164@interface CompareIVarVisibilityDefault: NSObject {165 int ivarVisibilityDefault;166}167@end168#elif defined(SECOND)169@interface CompareMatchingIVars: NSObject { int ivarName; } @end170 171@interface CompareIVarPresence1: NSObject { int ivarPresence1; } @end172@interface CompareIVarPresence2: NSObject @end173 174@interface CompareIVarName: NSObject { int differentIvarName; } @end175@interface CompareIVarType: NSObject { float ivarType; } @end176@interface CompareIVarOrder: NSObject {177 float ivarNameFloat;178 int ivarNameInt;179}180@end181 182@interface CompareIVarVisibilityExplicit: NSObject {183@private184 int ivarVisibility;185}186@end187@interface CompareIVarVisibilityDefault: NSObject {188@public189 int ivarVisibilityDefault;190}191@end192#else193CompareMatchingIVars *compareMatchingIVars;194 195CompareIVarPresence1 *compareIVarPresence1;196#ifdef TEST_MODULAR197// 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'}}199#else200// 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}}202#endif203CompareIVarPresence2 *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}}206 207CompareIVarName *compareIVarName;208#ifdef TEST_MODULAR209// 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'}}211#else212// 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'}}214#endif215CompareIVarType *compareIVarType;216#ifdef TEST_MODULAR217// 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}}219#else220// 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'}}222#endif223CompareIVarOrder *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'}}226 227CompareIVarVisibilityExplicit *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}}230CompareIVarVisibilityDefault *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}}233#endif234 235#if defined(FIRST)236@interface CompareMatchingMethods: NSObject237- (float)matchingMethod:(int)arg;238@end239 240@interface CompareMethodPresence1: NSObject241- (void)presenceMethod1;242@end243@interface CompareMethodPresence2: NSObject244@end245 246@interface CompareMethodName: NSObject247- (void)methodNameA;248@end249 250@interface CompareMethodArgCount: NSObject251- (void)methodArgCount:(int)arg0 :(int)arg1;252@end253@interface CompareMethodArgName: NSObject254- (void)methodArgName:(int)argNameA;255@end256@interface CompareMethodArgType: NSObject257- (void)methodArgType:(int)argType;258@end259 260@interface CompareMethodReturnType: NSObject261- (int)methodReturnType;262@end263 264@interface CompareMethodOrder: NSObject265- (void)methodOrderFirst;266- (void)methodOrderSecond;267@end268 269@interface CompareMethodClassInstance: NSObject270+ (void)methodClassInstance;271@end272#elif defined(SECOND)273@interface CompareMatchingMethods: NSObject274- (float)matchingMethod:(int)arg;275@end276 277@interface CompareMethodPresence1: NSObject278@end279@interface CompareMethodPresence2: NSObject280- (void)presenceMethod2;281@end282 283@interface CompareMethodName: NSObject284- (void)methodNameB;285@end286 287@interface CompareMethodArgCount: NSObject288- (void)methodArgCount:(int)arg0;289@end290@interface CompareMethodArgName: NSObject291- (void)methodArgName:(int)argNameB;292@end293@interface CompareMethodArgType: NSObject294- (void)methodArgType:(float)argType;295@end296 297@interface CompareMethodReturnType: NSObject298- (float)methodReturnType;299@end300 301@interface CompareMethodOrder: NSObject302- (void)methodOrderSecond;303- (void)methodOrderFirst;304@end305 306@interface CompareMethodClassInstance: NSObject307- (void)methodClassInstance;308@end309#else310CompareMatchingMethods *compareMatchingMethods;311CompareMethodPresence1 *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}}314CompareMethodPresence2 *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}}317CompareMethodName *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'}}320 321CompareMethodArgCount *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}}324CompareMethodArgName *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'}}327CompareMethodArgType *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'}}330 331CompareMethodReturnType *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'}}334 335CompareMethodOrder *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'}}338CompareMethodClassInstance *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}}341#endif342 343#if defined(FIRST)344@interface CompareMatchingProperties: NSObject345@property int matchingPropName;346@end347 348@interface ComparePropertyPresence1: NSObject349@property int propPresence1;350@end351@interface ComparePropertyPresence2: NSObject352@end353 354@interface ComparePropertyName: NSObject355@property int propNameA;356@end357 358@interface ComparePropertyType: NSObject359@property int propType;360@end361 362@interface ComparePropertyOrder: NSObject363@property int propOrderX;364@property int propOrderY;365@end366 367@interface CompareMatchingPropertyAttributes: NSObject368@property (nonatomic, assign) int matchingProp;369@end370@interface ComparePropertyAttributes: NSObject371@property (readonly) int propAttributes;372@end373// Edge cases.374@interface CompareFirstImplAttribute: NSObject375@property int firstImplAttribute;376@end377@interface CompareLastImplAttribute: NSObject378@property (direct) int lastImplAttribute;379@end380#elif defined(SECOND)381@interface CompareMatchingProperties: NSObject382@property int matchingPropName;383@end384 385@interface ComparePropertyPresence1: NSObject386@end387@interface ComparePropertyPresence2: NSObject388@property int propPresence2;389@end390 391@interface ComparePropertyName: NSObject392@property int propNameB;393@end394 395@interface ComparePropertyType: NSObject396@property float propType;397@end398 399@interface ComparePropertyOrder: NSObject400@property int propOrderY;401@property int propOrderX;402@end403 404@interface CompareMatchingPropertyAttributes: NSObject405@property (assign, nonatomic) int matchingProp;406@end407@interface ComparePropertyAttributes: NSObject408@property (readwrite) int propAttributes;409@end410// Edge cases.411@interface CompareFirstImplAttribute: NSObject412@property (readonly) int firstImplAttribute;413@end414@interface CompareLastImplAttribute: NSObject415@property int lastImplAttribute;416@end417#else418CompareMatchingProperties *compareMatchingProperties;419ComparePropertyPresence1 *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}}422ComparePropertyPresence2 *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}}425 426ComparePropertyName *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'}}429ComparePropertyType *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'}}432ComparePropertyOrder *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'}}435 436CompareMatchingPropertyAttributes *compareMatchingPropertyAttributes;437ComparePropertyAttributes *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}}440CompareFirstImplAttribute *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}}443CompareLastImplAttribute *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}}446#endif447 448#if defined(FIRST)449@interface CompareMatchingCategories: NSObject @end450@interface CompareMatchingCategories(Matching)451- (int)testMethod;452@end453 454@interface CompareMismatchingCategories1: NSObject @end455@interface CompareMismatchingCategories1(Category1)456- (void)presentMethod;457@end458@interface CompareMismatchingCategories2: NSObject @end459@interface CompareMismatchingCategories2(Category2)460@end461 462@interface CompareDifferentCategoryNames: NSObject @end463@interface CompareDifferentCategoryNames(CategoryFirst)464- (void)firstMethod:(int)x;465@end466#elif defined(SECOND)467@interface CompareMatchingCategories: NSObject @end468@interface CompareMatchingCategories(Matching)469- (int)testMethod;470@end471 472@interface CompareMismatchingCategories1: NSObject @end473@interface CompareMismatchingCategories1(Category1)474@end475@interface CompareMismatchingCategories2: NSObject @end476@interface CompareMismatchingCategories2(Category2)477- (void)presentMethod;478@end479 480@interface CompareDifferentCategoryNames: NSObject @end481@interface CompareDifferentCategoryNames(CategorySecond)482- (void)secondMethod;483@end484#else485CompareMatchingCategories *compareMatchingCategories; // no diagnostic486CompareMismatchingCategories1 *compareMismatchingCategories1;487#ifdef TEST_MODULAR488// expected-warning@second.h:* {{duplicate definition of category 'Category1' on interface 'CompareMismatchingCategories1'}}489// expected-note@first.h:* {{previous definition is here}}490#endif491CompareMismatchingCategories2 *compareMismatchingCategories2;492#ifdef TEST_MODULAR493// expected-warning@second.h:* {{duplicate definition of category 'Category2' on interface 'CompareMismatchingCategories2'}}494// expected-note@first.h:* {{previous definition is here}}495#endif496CompareDifferentCategoryNames *compareDifferentCategoryNames; // no diagnostic497#endif498