[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / Modules / odr_hash.mm
blob512c8adc15924a17ce197da450d4ddcb6c8adcdd
1 // Clear and create directories
2 // RUN: rm -rf %t
3 // RUN: mkdir %t
4 // RUN: mkdir %t/cache
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
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
30 #if !defined(FIRST) && !defined(SECOND)
31 #include "first.h"
32 #include "second.h"
33 #endif
35 #if defined(FIRST) || defined(SECOND)
36 @protocol P1
37 @end
39 @protocol P2
40 @end
42 @interface I1
43 @end
45 @interface I2 : I1
46 @end
48 @interface Interface1 <T : I1 *> {
49 @public
50   T<P1> x;
52 @end
54 @interface Interface2 <T : I1 *>
55 @end
57 @interface Interface3 <T : I1 *>
58 @end
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;
66 @end
68 #endif
70 #if defined(FIRST)
71 struct S {
72   Interface1 *I;
73   decltype(I->x) x;
74   int y;
76 #elif defined(SECOND)
77 struct S {
78   Interface1 *I;
79   decltype(I->x) x;
80   bool y;
82 #else
83 S 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
88 namespace Types {
89 namespace Attributed {
90 #if defined(FIRST)
91 void invalid1() {
92   static double __attribute((objc_gc(strong))) *x;
94 void invalid2() {
95   static int __attribute((objc_gc(strong))) *x;
97 void valid() {
98   static int __attribute((objc_gc(strong))) *x;
100 #elif defined(SECOND)
101 void invalid1() {
102   static int __attribute((objc_gc(strong))) *x;
104 void invalid2() {
105   static int __attribute((objc_gc(weak))) *x;
107 void valid() {
108   static int __attribute((objc_gc(strong))) *x;
110 #else
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;
117 #endif
118 }  // namespace Attributed
120 namespace BlockPointer {
121 #if defined(FIRST)
122 void invalid1() {
123   void (^x)(int);
125 void invalid2() {
126   void (^x)(int);
128 void invalid3() {
129   void (^x)(int);
131 void invalid4() {
132   void (^x)(int);
134 void valid() {
135   void (^x1)(int);
136   int (^x2)(int);
137   void (^x3)(int, int);
138   void (^x4)(short);
140 #elif defined(SECOND)
141 void invalid1() {
142   void (^x)();
144 void invalid2() {
145   void (^x)(int, int);
147 void invalid3() {
148   int (^x)(int);
150 void invalid4() {
151   void (^x)(float);
153 void valid() {
154   void (^x1)(int);
155   int (^x2)(int);
156   void (^x3)(int, int);
157   void (^x4)(short);
159 #else
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;
173 #endif
174 }  // namespace BlockPointer
176 namespace ObjCObject {
177 #if defined(FIRST)
178 struct Invalid1 {
179   using T = Interface2<I1*>;
181 struct Invalid2 {
182   using T = Interface2<I1*>;
184 struct Invalid3 {
185   using T = Interface2<P1, P1>;
187 struct Invalid4 {
188   using T = Interface2<P1>;
190 struct 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;
197 #elif defined(SECOND)
198 struct Invalid1 {
199   using T = Interface3<I1*>;
201 struct Invalid2 {
202   using T = Interface2<I2*>;
204 struct Invalid3 {
205   using T = Interface2<P1>;
207 struct Invalid4 {
208   using T = Interface2<P2>;
210 struct 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;
217 #else
218 Invalid1 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}}
221 Invalid2 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}}
224 Invalid3 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>'}}
227 Invalid4 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}}
230 Valid v;
231 #endif
232 }  // namespace VisitObjCObject
233 }  // namespace Types
235 #if defined(FIRST)
236 @interface Interface4 <T : I1 *> {
237 @public
238   T<P1> x;
240 @end
241 @interface Interface5 <T : I1 *> {
242 @public
243   T<P1> y;
245 @end
246 @interface Interface6 <T1 : I1 *, T2 : I2 *> {
247 @public
248   T1 z;
250 @end
251 #elif defined(SECOND)
252 @interface Interface4 <T : I1 *> {
253 @public
254   T<P2> x;
256 @end
257 @interface Interface5 <T : I1 *> {
258 @public
259   T<P1, P2> y;
261 @end
262 @interface Interface6 <T1 : I1 *, T2 : I2 *> {
263 @public
264   T2 z;
266 @end
267 #else
269 #endif
271 namespace Types {
272 namespace ObjCTypeParam {
273 #if defined(FIRST) || defined(SECOND)
274 struct Invalid1 {
275   Interface4 *I;
276   decltype(I->x) x;
278 struct Invalid2 {
279   Interface5 *I;
280   decltype(I->y) y;
282 struct Invalid3 {
283   Interface6 *I;
284   decltype(I->z) z;
286 #else
287 Invalid1 i1;
289 Invalid2 i2;
291 Invalid3 i3;
293 // FIXME: We should reject to merge these structs and diagnose for the
294 // different definitions for Interface4/Interface5/Interface6.
296 #endif
298 }  // namespace ObjCTypeParam
299 }  // namespace Types
301 namespace CallMethods {
302 #if defined(FIRST)
303 void invalid1(EmptySelectorSlot *obj) {
304   [obj method:0];
306 void invalid2(EmptySelectorSlot *obj) {
307   [obj multiple:0 args:0 :0];
309 #elif defined(SECOND)
310 void invalid1(EmptySelectorSlot *obj) {
311   [obj method:0 :0];
313 void invalid2(EmptySelectorSlot *obj) {
314   [obj multiple:0 :0 args:0];
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}}
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.
325 #ifdef FIRST
326 #undef FIRST
327 #endif
329 #ifdef SECOND
330 #undef SECOND
331 #endif