|  | // RUN: rm -rf %t | 
|  | // RUN: split-file %s %t | 
|  |  | 
|  | // Build first header file | 
|  | // RUN: echo "#define FIRST" >> %t/include/first.h | 
|  | // RUN: cat %t/test.m        >> %t/include/first.h | 
|  | // RUN: echo "#undef FIRST"  >> %t/include/first.h | 
|  |  | 
|  | // Build second header file | 
|  | // RUN: echo "#define SECOND" >> %t/include/second.h | 
|  | // RUN: cat %t/test.m         >> %t/include/second.h | 
|  | // RUN: echo "#undef SECOND"  >> %t/include/second.h | 
|  |  | 
|  | // Test that each header can compile | 
|  | // RUN: %clang_cc1 -fsyntax-only -x objective-c %t/include/first.h -fblocks -fobjc-arc | 
|  | // RUN: %clang_cc1 -fsyntax-only -x objective-c %t/include/second.h -fblocks -fobjc-arc | 
|  |  | 
|  | // Run test | 
|  | // RUN: %clang_cc1 -I%t/include -verify %t/test.m -fblocks -fobjc-arc \ | 
|  | // RUN:            -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache | 
|  |  | 
|  | // Run the same test with second.h being modular | 
|  | // RUN: cat %t/include/second.modulemap >> %t/include/module.modulemap | 
|  | // RUN: %clang_cc1 -I%t/include -verify %t/test.m -fblocks -fobjc-arc -DTEST_MODULAR=1 \ | 
|  | // RUN:            -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache | 
|  |  | 
|  | // Test that we don't accept different class definitions with the same name | 
|  | // from multiple modules but detect mismatches and provide actionable | 
|  | // diagnostic. | 
|  |  | 
|  | //--- include/common.h | 
|  | #ifndef COMMON_H | 
|  | #define COMMON_H | 
|  | @interface NSObject @end | 
|  | @protocol CommonProtocol @end | 
|  | @protocol ExtraProtocol @end | 
|  | #endif | 
|  |  | 
|  | //--- include/first-empty.h | 
|  | //--- include/module.modulemap | 
|  | module First { | 
|  | module Empty { | 
|  | header "first-empty.h" | 
|  | } | 
|  | module Hidden { | 
|  | header "first.h" | 
|  | export * | 
|  | } | 
|  | } | 
|  |  | 
|  | //--- include/second.modulemap | 
|  | module Second { | 
|  | header "second.h" | 
|  | export * | 
|  | } | 
|  |  | 
|  | //--- test.m | 
|  | #if defined(FIRST) || defined(SECOND) | 
|  | # include "common.h" | 
|  | #endif | 
|  |  | 
|  | #if !defined(FIRST) && !defined(SECOND) | 
|  | # include "first-empty.h" | 
|  | # include "second.h" | 
|  | #endif | 
|  |  | 
|  | #if defined(FIRST) | 
|  | @class CompareForwardDeclaration1; | 
|  | @interface CompareForwardDeclaration2: NSObject @end | 
|  | #elif defined(SECOND) | 
|  | @interface CompareForwardDeclaration1: NSObject @end | 
|  | @class CompareForwardDeclaration2; | 
|  | #else | 
|  | CompareForwardDeclaration1 *compareForwardDeclaration1; | 
|  | CompareForwardDeclaration2 *compareForwardDeclaration2; | 
|  | #endif | 
|  |  | 
|  | #if defined(FIRST) | 
|  | @interface CompareMatchingSuperclass: NSObject @end | 
|  |  | 
|  | @interface CompareSuperclassPresence1: NSObject @end | 
|  | @interface CompareSuperclassPresence2 @end | 
|  |  | 
|  | @interface CompareDifferentSuperclass: NSObject @end | 
|  | #elif defined(SECOND) | 
|  | @interface CompareMatchingSuperclass: NSObject @end | 
|  |  | 
|  | @interface CompareSuperclassPresence1 @end | 
|  | @interface CompareSuperclassPresence2: NSObject @end | 
|  |  | 
|  | @interface DifferentSuperclass: NSObject @end | 
|  | @interface CompareDifferentSuperclass: DifferentSuperclass @end | 
|  | #else | 
|  | CompareMatchingSuperclass *compareMatchingSuperclass; | 
|  | CompareSuperclassPresence1 *compareSuperclassPresence1; | 
|  | // 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'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found no super class}} | 
|  | CompareSuperclassPresence2 *compareSuperclassPresence2; | 
|  | // expected-error@first.h:* {{'CompareSuperclassPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found no super class}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found super class with type 'NSObject'}} | 
|  | CompareDifferentSuperclass *compareDifferentSuperclass; | 
|  | // 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'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found super class with type 'DifferentSuperclass'}} | 
|  | #endif | 
|  |  | 
|  | #if defined(FIRST) | 
|  | @interface CompareMatchingConformingProtocols: NSObject<CommonProtocol> @end | 
|  | @protocol ForwardProtocol; | 
|  | @interface CompareMatchingConformingForwardProtocols: NSObject<ForwardProtocol> @end | 
|  |  | 
|  | @interface CompareProtocolPresence1: NSObject<CommonProtocol> @end | 
|  | @interface CompareProtocolPresence2: NSObject @end | 
|  |  | 
|  | @interface CompareDifferentProtocols: NSObject<CommonProtocol> @end | 
|  | @interface CompareProtocolOrder: NSObject<CommonProtocol, ExtraProtocol> @end | 
|  | #elif defined(SECOND) | 
|  | @interface CompareMatchingConformingProtocols: NSObject<CommonProtocol> @end | 
|  | @protocol ForwardProtocol @end | 
|  | @interface CompareMatchingConformingForwardProtocols: NSObject<ForwardProtocol> @end | 
|  |  | 
|  | @interface CompareProtocolPresence1: NSObject @end | 
|  | @interface CompareProtocolPresence2: NSObject<CommonProtocol> @end | 
|  |  | 
|  | @interface CompareDifferentProtocols: NSObject<ExtraProtocol> @end | 
|  | @interface CompareProtocolOrder: NSObject<ExtraProtocol, CommonProtocol> @end | 
|  | #else | 
|  | CompareMatchingConformingProtocols *compareMatchingConformingProtocols; | 
|  | CompareMatchingConformingForwardProtocols *compareMatchingConformingForwardProtocols; | 
|  |  | 
|  | CompareProtocolPresence1 *compareProtocolPresence1; | 
|  | // expected-error@first.h:* {{'CompareProtocolPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found 1 referenced protocol}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 0 referenced protocols}} | 
|  | CompareProtocolPresence2 *compareProtocolPresence2; | 
|  | // expected-error@first.h:* {{'CompareProtocolPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found 0 referenced protocols}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 1 referenced protocol}} | 
|  |  | 
|  | CompareDifferentProtocols *compareDifferentProtocols; | 
|  | // 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'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 1st referenced protocol with different name 'ExtraProtocol'}} | 
|  | CompareProtocolOrder *compareProtocolOrder; | 
|  | // 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'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 1st referenced protocol with different name 'ExtraProtocol'}} | 
|  | #endif | 
|  |  | 
|  | #if defined(FIRST) | 
|  | @interface CompareMatchingIVars: NSObject { int ivarName; } @end | 
|  |  | 
|  | @interface CompareIVarPresence1: NSObject @end | 
|  | @interface CompareIVarPresence2: NSObject { int ivarPresence2; } @end | 
|  |  | 
|  | @interface CompareIVarName: NSObject { int ivarName; } @end | 
|  | @interface CompareIVarType: NSObject { int ivarType; } @end | 
|  | @interface CompareIVarOrder: NSObject { | 
|  | int ivarNameInt; | 
|  | float ivarNameFloat; | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface CompareIVarVisibilityExplicit: NSObject { | 
|  | @public | 
|  | int ivarVisibility; | 
|  | } | 
|  | @end | 
|  | @interface CompareIVarVisibilityDefault: NSObject { | 
|  | int ivarVisibilityDefault; | 
|  | } | 
|  | @end | 
|  | #elif defined(SECOND) | 
|  | @interface CompareMatchingIVars: NSObject { int ivarName; } @end | 
|  |  | 
|  | @interface CompareIVarPresence1: NSObject { int ivarPresence1; } @end | 
|  | @interface CompareIVarPresence2: NSObject @end | 
|  |  | 
|  | @interface CompareIVarName: NSObject { int differentIvarName; } @end | 
|  | @interface CompareIVarType: NSObject { float ivarType; } @end | 
|  | @interface CompareIVarOrder: NSObject { | 
|  | float ivarNameFloat; | 
|  | int ivarNameInt; | 
|  | } | 
|  | @end | 
|  |  | 
|  | @interface CompareIVarVisibilityExplicit: NSObject { | 
|  | @private | 
|  | int ivarVisibility; | 
|  | } | 
|  | @end | 
|  | @interface CompareIVarVisibilityDefault: NSObject { | 
|  | @public | 
|  | int ivarVisibilityDefault; | 
|  | } | 
|  | @end | 
|  | #else | 
|  | CompareMatchingIVars *compareMatchingIVars; | 
|  |  | 
|  | CompareIVarPresence1 *compareIVarPresence1; | 
|  | #ifdef TEST_MODULAR | 
|  | // expected-error@second.h:* {{'CompareIVarPresence1::ivarPresence1' from module 'Second' is not present in definition of 'CompareIVarPresence1' in module 'First.Hidden'}} | 
|  | // expected-note@first.h:* {{definition has no member 'ivarPresence1'}} | 
|  | #else | 
|  | // expected-error@first.h:* {{'CompareIVarPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found end of class}} | 
|  | // expected-note@second.h:* {{but in definition here found instance variable}} | 
|  | #endif | 
|  | CompareIVarPresence2 *compareIVarPresence2; | 
|  | // expected-error@first.h:* {{'CompareIVarPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found instance variable}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found end of class}} | 
|  |  | 
|  | CompareIVarName *compareIVarName; | 
|  | #ifdef TEST_MODULAR | 
|  | // expected-error@second.h:* {{'CompareIVarName::differentIvarName' from module 'Second' is not present in definition of 'CompareIVarName' in module 'First.Hidden'}} | 
|  | // expected-note@first.h:* {{definition has no member 'differentIvarName'}} | 
|  | #else | 
|  | // expected-error@first.h:* {{'CompareIVarName' has different definitions in different modules; first difference is definition in module 'First.Hidden' found field 'ivarName'}} | 
|  | // expected-note@second.h:* {{but in definition here found field 'differentIvarName'}} | 
|  | #endif | 
|  | CompareIVarType *compareIVarType; | 
|  | #ifdef TEST_MODULAR | 
|  | // expected-error@second.h:* {{'CompareIVarType::ivarType' from module 'Second' is not present in definition of 'CompareIVarType' in module 'First.Hidden'}} | 
|  | // expected-note@first.h:* {{declaration of 'ivarType' does not match}} | 
|  | #else | 
|  | // 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'}} | 
|  | // expected-note@second.h:* {{but in definition here found field 'ivarType' with type 'float'}} | 
|  | #endif | 
|  | CompareIVarOrder *compareIVarOrder; | 
|  | // expected-error@first.h:* {{'CompareIVarOrder' has different definitions in different modules; first difference is definition in module 'First.Hidden' found field 'ivarNameInt'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found field 'ivarNameFloat'}} | 
|  |  | 
|  | CompareIVarVisibilityExplicit *compareIVarVisibilityExplicit; | 
|  | // 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}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found instance variable 'ivarVisibility' access control is @private}} | 
|  | CompareIVarVisibilityDefault *compareIVarVisibilityDefault; | 
|  | // 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}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found instance variable 'ivarVisibilityDefault' access control is @public}} | 
|  | #endif | 
|  |  | 
|  | #if defined(FIRST) | 
|  | @interface CompareMatchingMethods: NSObject | 
|  | - (float)matchingMethod:(int)arg; | 
|  | @end | 
|  |  | 
|  | @interface CompareMethodPresence1: NSObject | 
|  | - (void)presenceMethod1; | 
|  | @end | 
|  | @interface CompareMethodPresence2: NSObject | 
|  | @end | 
|  |  | 
|  | @interface CompareMethodName: NSObject | 
|  | - (void)methodNameA; | 
|  | @end | 
|  |  | 
|  | @interface CompareMethodArgCount: NSObject | 
|  | - (void)methodArgCount:(int)arg0 :(int)arg1; | 
|  | @end | 
|  | @interface CompareMethodArgName: NSObject | 
|  | - (void)methodArgName:(int)argNameA; | 
|  | @end | 
|  | @interface CompareMethodArgType: NSObject | 
|  | - (void)methodArgType:(int)argType; | 
|  | @end | 
|  |  | 
|  | @interface CompareMethodReturnType: NSObject | 
|  | - (int)methodReturnType; | 
|  | @end | 
|  |  | 
|  | @interface CompareMethodOrder: NSObject | 
|  | - (void)methodOrderFirst; | 
|  | - (void)methodOrderSecond; | 
|  | @end | 
|  |  | 
|  | @interface CompareMethodClassInstance: NSObject | 
|  | + (void)methodClassInstance; | 
|  | @end | 
|  | #elif defined(SECOND) | 
|  | @interface CompareMatchingMethods: NSObject | 
|  | - (float)matchingMethod:(int)arg; | 
|  | @end | 
|  |  | 
|  | @interface CompareMethodPresence1: NSObject | 
|  | @end | 
|  | @interface CompareMethodPresence2: NSObject | 
|  | - (void)presenceMethod2; | 
|  | @end | 
|  |  | 
|  | @interface CompareMethodName: NSObject | 
|  | - (void)methodNameB; | 
|  | @end | 
|  |  | 
|  | @interface CompareMethodArgCount: NSObject | 
|  | - (void)methodArgCount:(int)arg0; | 
|  | @end | 
|  | @interface CompareMethodArgName: NSObject | 
|  | - (void)methodArgName:(int)argNameB; | 
|  | @end | 
|  | @interface CompareMethodArgType: NSObject | 
|  | - (void)methodArgType:(float)argType; | 
|  | @end | 
|  |  | 
|  | @interface CompareMethodReturnType: NSObject | 
|  | - (float)methodReturnType; | 
|  | @end | 
|  |  | 
|  | @interface CompareMethodOrder: NSObject | 
|  | - (void)methodOrderSecond; | 
|  | - (void)methodOrderFirst; | 
|  | @end | 
|  |  | 
|  | @interface CompareMethodClassInstance: NSObject | 
|  | - (void)methodClassInstance; | 
|  | @end | 
|  | #else | 
|  | CompareMatchingMethods *compareMatchingMethods; | 
|  | CompareMethodPresence1 *compareMethodPresence1; | 
|  | // expected-error@first.h:* {{'CompareMethodPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found end of class}} | 
|  | CompareMethodPresence2 *compareMethodPresence2; | 
|  | // expected-error@first.h:* {{'CompareMethodPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found end of class}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method}} | 
|  | CompareMethodName *compareMethodName; | 
|  | // expected-error@first.h:* {{'CompareMethodName' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method 'methodNameA'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found different method 'methodNameB'}} | 
|  |  | 
|  | CompareMethodArgCount *compareMethodArgCount; | 
|  | // 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}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodArgCount:' that has 1 parameter}} | 
|  | CompareMethodArgName *compareMethodArgName; | 
|  | // 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'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodArgName:' with 1st parameter named 'argNameB'}} | 
|  | CompareMethodArgType *compareMethodArgType; | 
|  | // 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'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodArgType:' with 1st parameter of type 'float'}} | 
|  |  | 
|  | CompareMethodReturnType *compareMethodReturnType; | 
|  | // 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'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodReturnType' with different return type 'float'}} | 
|  |  | 
|  | CompareMethodOrder *compareMethodOrder; | 
|  | // expected-error@first.h:* {{'CompareMethodOrder' has different definitions in different modules; first difference is definition in module 'First.Hidden' found method 'methodOrderFirst'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found different method 'methodOrderSecond'}} | 
|  | CompareMethodClassInstance *compareMethodClassInstance; | 
|  | // expected-error@first.h:* {{'CompareMethodClassInstance' has different definitions in different modules; first difference is definition in module 'First.Hidden' found class method 'methodClassInstance'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found method 'methodClassInstance' as instance method}} | 
|  | #endif | 
|  |  | 
|  | #if defined(FIRST) | 
|  | @interface CompareMatchingProperties: NSObject | 
|  | @property int matchingPropName; | 
|  | @end | 
|  |  | 
|  | @interface ComparePropertyPresence1: NSObject | 
|  | @property int propPresence1; | 
|  | @end | 
|  | @interface ComparePropertyPresence2: NSObject | 
|  | @end | 
|  |  | 
|  | @interface ComparePropertyName: NSObject | 
|  | @property int propNameA; | 
|  | @end | 
|  |  | 
|  | @interface ComparePropertyType: NSObject | 
|  | @property int propType; | 
|  | @end | 
|  |  | 
|  | @interface ComparePropertyOrder: NSObject | 
|  | @property int propOrderX; | 
|  | @property int propOrderY; | 
|  | @end | 
|  |  | 
|  | @interface CompareMatchingPropertyAttributes: NSObject | 
|  | @property (nonatomic, assign) int matchingProp; | 
|  | @end | 
|  | @interface ComparePropertyAttributes: NSObject | 
|  | @property (readonly) int propAttributes; | 
|  | @end | 
|  | // Edge cases. | 
|  | @interface CompareFirstImplAttribute: NSObject | 
|  | @property int firstImplAttribute; | 
|  | @end | 
|  | @interface CompareLastImplAttribute: NSObject | 
|  | @property (direct) int lastImplAttribute; | 
|  | @end | 
|  | #elif defined(SECOND) | 
|  | @interface CompareMatchingProperties: NSObject | 
|  | @property int matchingPropName; | 
|  | @end | 
|  |  | 
|  | @interface ComparePropertyPresence1: NSObject | 
|  | @end | 
|  | @interface ComparePropertyPresence2: NSObject | 
|  | @property int propPresence2; | 
|  | @end | 
|  |  | 
|  | @interface ComparePropertyName: NSObject | 
|  | @property int propNameB; | 
|  | @end | 
|  |  | 
|  | @interface ComparePropertyType: NSObject | 
|  | @property float propType; | 
|  | @end | 
|  |  | 
|  | @interface ComparePropertyOrder: NSObject | 
|  | @property int propOrderY; | 
|  | @property int propOrderX; | 
|  | @end | 
|  |  | 
|  | @interface CompareMatchingPropertyAttributes: NSObject | 
|  | @property (assign, nonatomic) int matchingProp; | 
|  | @end | 
|  | @interface ComparePropertyAttributes: NSObject | 
|  | @property (readwrite) int propAttributes; | 
|  | @end | 
|  | // Edge cases. | 
|  | @interface CompareFirstImplAttribute: NSObject | 
|  | @property (readonly) int firstImplAttribute; | 
|  | @end | 
|  | @interface CompareLastImplAttribute: NSObject | 
|  | @property int lastImplAttribute; | 
|  | @end | 
|  | #else | 
|  | CompareMatchingProperties *compareMatchingProperties; | 
|  | ComparePropertyPresence1 *comparePropertyPresence1; | 
|  | // expected-error@first.h:* {{'ComparePropertyPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found end of class}} | 
|  | ComparePropertyPresence2 *comparePropertyPresence2; | 
|  | // expected-error@first.h:* {{'ComparePropertyPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found end of class}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property}} | 
|  |  | 
|  | ComparePropertyName *comparePropertyName; | 
|  | // expected-error@first.h:* {{'ComparePropertyName' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property 'propNameA'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'propNameB'}} | 
|  | ComparePropertyType *comparePropertyType; | 
|  | // 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'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'propType' with type 'float'}} | 
|  | ComparePropertyOrder *comparePropertyOrder; | 
|  | // expected-error@first.h:* {{'ComparePropertyOrder' has different definitions in different modules; first difference is definition in module 'First.Hidden' found property 'propOrderX'}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'propOrderY'}} | 
|  |  | 
|  | CompareMatchingPropertyAttributes *compareMatchingPropertyAttributes; | 
|  | ComparePropertyAttributes *comparePropertyAttributes; | 
|  | // 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}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'propAttributes' with different 'readonly' attribute}} | 
|  | CompareFirstImplAttribute *compareFirstImplAttribute; | 
|  | // 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}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'firstImplAttribute' with different 'readonly' attribute}} | 
|  | CompareLastImplAttribute *compareLastImplAttribute; | 
|  | // 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}} | 
|  | // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found property 'lastImplAttribute' with different 'direct' attribute}} | 
|  | #endif | 
|  |  | 
|  | #if defined(FIRST) | 
|  | @interface CompareMatchingCategories: NSObject @end | 
|  | @interface CompareMatchingCategories(Matching) | 
|  | - (int)testMethod; | 
|  | @end | 
|  |  | 
|  | @interface CompareMismatchingCategories1: NSObject @end | 
|  | @interface CompareMismatchingCategories1(Category1) | 
|  | - (void)presentMethod; | 
|  | @end | 
|  | @interface CompareMismatchingCategories2: NSObject @end | 
|  | @interface CompareMismatchingCategories2(Category2) | 
|  | @end | 
|  |  | 
|  | @interface CompareDifferentCategoryNames: NSObject @end | 
|  | @interface CompareDifferentCategoryNames(CategoryFirst) | 
|  | - (void)firstMethod:(int)x; | 
|  | @end | 
|  | #elif defined(SECOND) | 
|  | @interface CompareMatchingCategories: NSObject @end | 
|  | @interface CompareMatchingCategories(Matching) | 
|  | - (int)testMethod; | 
|  | @end | 
|  |  | 
|  | @interface CompareMismatchingCategories1: NSObject @end | 
|  | @interface CompareMismatchingCategories1(Category1) | 
|  | @end | 
|  | @interface CompareMismatchingCategories2: NSObject @end | 
|  | @interface CompareMismatchingCategories2(Category2) | 
|  | - (void)presentMethod; | 
|  | @end | 
|  |  | 
|  | @interface CompareDifferentCategoryNames: NSObject @end | 
|  | @interface CompareDifferentCategoryNames(CategorySecond) | 
|  | - (void)secondMethod; | 
|  | @end | 
|  | #else | 
|  | CompareMatchingCategories *compareMatchingCategories; // no diagnostic | 
|  | CompareMismatchingCategories1 *compareMismatchingCategories1; | 
|  | #ifdef TEST_MODULAR | 
|  | // expected-warning@second.h:* {{duplicate definition of category 'Category1' on interface 'CompareMismatchingCategories1'}} | 
|  | // expected-note@first.h:* {{previous definition is here}} | 
|  | #endif | 
|  | CompareMismatchingCategories2 *compareMismatchingCategories2; | 
|  | #ifdef TEST_MODULAR | 
|  | // expected-warning@second.h:* {{duplicate definition of category 'Category2' on interface 'CompareMismatchingCategories2'}} | 
|  | // expected-note@first.h:* {{previous definition is here}} | 
|  | #endif | 
|  | CompareDifferentCategoryNames *compareDifferentCategoryNames; // no diagnostic | 
|  | #endif |