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.modulemap 21// RUN: echo " header \"first.h\"" >> %t/Inputs/module.modulemap 22// RUN: echo "}" >> %t/Inputs/module.modulemap 23// RUN: echo "module SecondModule {" >> %t/Inputs/module.modulemap 24// RUN: echo " header \"second.h\"" >> %t/Inputs/module.modulemap 25// RUN: echo "}" >> %t/Inputs/module.modulemap 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@interface EmptySelectorSlot 61- (void)method:(int)arg; 62- (void)method:(int)arg :(int)empty; 63 64- (void)multiple:(int)arg1 args:(int)arg2 :(int)arg3; 65- (void)multiple:(int)arg1 :(int)arg2 args:(int)arg3; 66@end 67 68#endif 69 70#if defined(FIRST) 71struct S { 72 Interface1 *I; 73 decltype(I->x) x; 74 int y; 75}; 76#elif defined(SECOND) 77struct S { 78 Interface1 *I; 79 decltype(I->x) x; 80 bool y; 81}; 82#else 83S s; 84// expected-error@second.h:* {{'S::y' from module 'SecondModule' is not present in definition of 'S' in module 'FirstModule'}} 85// expected-note@first.h:* {{declaration of 'y' does not match}} 86#endif 87 88namespace Types { 89namespace Attributed { 90#if defined(FIRST) 91void invalid1() { 92 static double __attribute((objc_gc(strong))) *x; 93} 94void invalid2() { 95 static int __attribute((objc_gc(strong))) *x; 96} 97void valid() { 98 static int __attribute((objc_gc(strong))) *x; 99} 100#elif defined(SECOND) 101void invalid1() { 102 static int __attribute((objc_gc(strong))) *x; 103} 104void invalid2() { 105 static int __attribute((objc_gc(weak))) *x; 106} 107void valid() { 108 static int __attribute((objc_gc(strong))) *x; 109} 110#else 111auto function1 = invalid1; 112// expected-error@second.h:* {{Types::Attributed::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} 113// expected-note@first.h:* {{but in 'FirstModule' found a different body}} 114auto function2 = invalid2; 115 116auto function3 = valid; 117#endif 118} // namespace Attributed 119 120namespace BlockPointer { 121#if defined(FIRST) 122void invalid1() { 123 void (^x)(int); 124} 125void invalid2() { 126 void (^x)(int); 127} 128void invalid3() { 129 void (^x)(int); 130} 131void invalid4() { 132 void (^x)(int); 133} 134void valid() { 135 void (^x1)(int); 136 int (^x2)(int); 137 void (^x3)(int, int); 138 void (^x4)(short); 139} 140#elif defined(SECOND) 141void invalid1() { 142 void (^x)(); 143} 144void invalid2() { 145 void (^x)(int, int); 146} 147void invalid3() { 148 int (^x)(int); 149} 150void invalid4() { 151 void (^x)(float); 152} 153void valid() { 154 void (^x1)(int); 155 int (^x2)(int); 156 void (^x3)(int, int); 157 void (^x4)(short); 158} 159#else 160auto function1 = invalid1; 161// expected-error@second.h:* {{'Types::BlockPointer::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} 162// expected-note@first.h:* {{but in 'FirstModule' found a different body}} 163auto function2 = invalid2; 164// expected-error@second.h:* {{'Types::BlockPointer::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} 165// expected-note@first.h:* {{but in 'FirstModule' found a different body}} 166auto function3 = invalid3; 167// expected-error@second.h:* {{'Types::BlockPointer::invalid3' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} 168// expected-note@first.h:* {{but in 'FirstModule' found a different body}} 169auto function4 = invalid4; 170// expected-error@second.h:* {{'Types::BlockPointer::invalid4' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} 171// expected-note@first.h:* {{but in 'FirstModule' found a different body}} 172auto function5 = valid; 173#endif 174} // namespace BlockPointer 175 176namespace ObjCObject { 177#if defined(FIRST) 178struct Invalid1 { 179 using T = Interface2<I1*>; 180}; 181struct Invalid2 { 182 using T = Interface2<I1*>; 183}; 184struct Invalid3 { 185 using T = Interface2<P1, P1>; 186}; 187struct Invalid4 { 188 using T = Interface2<P1>; 189}; 190struct Valid { 191 using T1 = Interface2<I1*>; 192 using T2 = Interface3<I1*>; 193 using T3 = Interface2<P1>; 194 using T4 = Interface3<P1, P2>; 195 using T5 = __kindof Interface2; 196}; 197#elif defined(SECOND) 198struct Invalid1 { 199 using T = Interface3<I1*>; 200}; 201struct Invalid2 { 202 using T = Interface2<I2*>; 203}; 204struct Invalid3 { 205 using T = Interface2<P1>; 206}; 207struct Invalid4 { 208 using T = Interface2<P2>; 209}; 210struct Valid { 211 using T1 = Interface2<I1*>; 212 using T2 = Interface3<I1*>; 213 using T3 = Interface2<P1>; 214 using T4 = Interface3<P1, P2>; 215 using T5 = __kindof Interface2; 216}; 217#else 218Invalid1 i1; 219// expected-error@first.h:* {{'Types::ObjCObject::Invalid1::T' from module 'FirstModule' is not present in definition of 'Types::ObjCObject::Invalid1' in module 'SecondModule'}} 220// expected-note@second.h:* {{declaration of 'T' does not match}} 221Invalid2 i2; 222// expected-error@first.h:* {{'Types::ObjCObject::Invalid2::T' from module 'FirstModule' is not present in definition of 'Types::ObjCObject::Invalid2' in module 'SecondModule'}} 223// expected-note@second.h:* {{declaration of 'T' does not match}} 224Invalid3 i3; 225// 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>'}} 226// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'Interface2<P1,P1>'}} 227Invalid4 i4; 228// expected-error@first.h:* {{'Types::ObjCObject::Invalid4::T' from module 'FirstModule' is not present in definition of 'Types::ObjCObject::Invalid4' in module 'SecondModule'}} 229// expected-note@second.h:* {{declaration of 'T' does not match}} 230Valid v; 231#endif 232} // namespace VisitObjCObject 233} // namespace Types 234 235#if defined(FIRST) 236@interface Interface4 <T : I1 *> { 237@public 238 T<P1> x; 239} 240@end 241@interface Interface5 <T : I1 *> { 242@public 243 T<P1> y; 244} 245@end 246@interface Interface6 <T1 : I1 *, T2 : I2 *> { 247@public 248 T1 z; 249} 250@end 251#elif defined(SECOND) 252@interface Interface4 <T : I1 *> { 253@public 254 T<P2> x; 255} 256@end 257@interface Interface5 <T : I1 *> { 258@public 259 T<P1, P2> y; 260} 261@end 262@interface Interface6 <T1 : I1 *, T2 : I2 *> { 263@public 264 T2 z; 265} 266@end 267#else 268 269#endif 270 271namespace Types { 272namespace ObjCTypeParam { 273#if defined(FIRST) || defined(SECOND) 274struct Invalid1 { 275 Interface4 *I; 276 decltype(I->x) x; 277}; 278struct Invalid2 { 279 Interface5 *I; 280 decltype(I->y) y; 281}; 282struct Invalid3 { 283 Interface6 *I; 284 decltype(I->z) z; 285}; 286#else 287Invalid1 i1; 288 289Invalid2 i2; 290 291Invalid3 i3; 292 293// FIXME: We should reject to merge these structs and diagnose for the 294// different definitions for Interface4/Interface5/Interface6. 295 296#endif 297 298} // namespace ObjCTypeParam 299} // namespace Types 300 301namespace CallMethods { 302#if defined(FIRST) 303void invalid1(EmptySelectorSlot *obj) { 304 [obj method:0]; 305} 306void invalid2(EmptySelectorSlot *obj) { 307 [obj multiple:0 args:0 :0]; 308} 309#elif defined(SECOND) 310void invalid1(EmptySelectorSlot *obj) { 311 [obj method:0 :0]; 312} 313void invalid2(EmptySelectorSlot *obj) { 314 [obj multiple:0 :0 args:0]; 315} 316#endif 317// expected-error@second.h:* {{'CallMethods::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} 318// expected-note@first.h:* {{but in 'FirstModule' found a different body}} 319 320// expected-error@second.h:* {{'CallMethods::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} 321// expected-note@first.h:* {{but in 'FirstModule' found a different body}} 322} // namespace CallMethods 323 324// Keep macros contained to one file. 325#ifdef FIRST 326#undef FIRST 327#endif 328 329#ifdef SECOND 330#undef SECOND 331#endif 332