1 // Clear and create directories
5 // RUN: mkdir %t/Inputs
7 // Build first header file
8 // RUN: echo "#define FIRST" >> %t/Inputs/first.h
9 // RUN: cat %s >> %t/Inputs/first.h
11 // Build second header file
12 // RUN: echo "#define SECOND" >> %t/Inputs/second.h
13 // RUN: cat %s >> %t/Inputs/second.h
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
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
28 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c++ -I%t/Inputs -verify %s -fblocks -fobjc-arc
30 #if !defined(FIRST) && !defined(SECOND)
35 #if defined(FIRST) || defined(SECOND)
48 @interface Interface1 <T : I1 *> {
54 @interface Interface2 <T : I1 *>
57 @interface Interface3 <T : I1 *>
60 @interface EmptySelectorSlot
61 - (void)method:(int)arg;
62 - (void)method:(int)arg :(int)empty;
64 - (void)multiple:(int)arg1 args:(int)arg2 :(int)arg3;
65 - (void)multiple:(int)arg1 :(int)arg2 args:(int)arg3;
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}}
89 namespace Attributed {
92 static double __attribute((objc_gc(strong))) *x;
95 static int __attribute((objc_gc(strong))) *x;
98 static int __attribute((objc_gc(strong))) *x;
100 #elif defined(SECOND)
102 static int __attribute((objc_gc(strong))) *x;
105 static int __attribute((objc_gc(weak))) *x;
108 static int __attribute((objc_gc(strong))) *x;
111 auto 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}}
114 auto function2 = invalid2;
116 auto function3 = valid;
118 } // namespace Attributed
120 namespace BlockPointer {
137 void (^x3)(int, int);
140 #elif defined(SECOND)
156 void (^x3)(int, int);
160 auto 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}}
163 auto 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}}
166 auto 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}}
169 auto 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}}
172 auto function5 = valid;
174 } // namespace BlockPointer
176 namespace ObjCObject {
179 using T = Interface2<I1*>;
182 using T = Interface2<I1*>;
185 using T = Interface2<P1, P1>;
188 using T = Interface2<P1>;
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;
197 #elif defined(SECOND)
199 using T = Interface3<I1*>;
202 using T = Interface2<I2*>;
205 using T = Interface2<P1>;
208 using T = Interface2<P2>;
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;
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}}
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}}
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>'}}
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}}
232 } // namespace VisitObjCObject
236 @interface Interface4 <T : I1 *> {
241 @interface Interface5 <T : I1 *> {
246 @interface Interface6 <T1 : I1 *, T2 : I2 *> {
251 #elif defined(SECOND)
252 @interface Interface4 <T : I1 *> {
257 @interface Interface5 <T : I1 *> {
262 @interface Interface6 <T1 : I1 *, T2 : I2 *> {
272 namespace ObjCTypeParam {
273 #if defined(FIRST) || defined(SECOND)
293 // FIXME: We should reject to merge these structs and diagnose for the
294 // different definitions for Interface4/Interface5/Interface6.
298 } // namespace ObjCTypeParam
301 namespace CallMethods {
303 void invalid1(EmptySelectorSlot *obj) {
306 void invalid2(EmptySelectorSlot *obj) {
307 [obj multiple:0 args:0 :0];
309 #elif defined(SECOND)
310 void invalid1(EmptySelectorSlot *obj) {
313 void invalid2(EmptySelectorSlot *obj) {
314 [obj multiple:0 :0 args:0];
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}}
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
324 // Keep macros contained to one file.