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