blob: 91230c52c8e0364a5870d0daf2df74c47a4bebab [file] [log] [blame]
Richard Trieue7f7ed22017-02-22 01:11:25 +00001// 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// Build module map file
16// RUN: echo "module FirstModule {" >> %t/Inputs/module.map
17// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map
18// RUN: echo "}" >> %t/Inputs/module.map
19// RUN: echo "module SecondModule {" >> %t/Inputs/module.map
20// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map
21// RUN: echo "}" >> %t/Inputs/module.map
22
23// Run test
Richard Trieu639d7b62017-02-22 22:22:42 +000024// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=c++1z
Richard Trieue7f7ed22017-02-22 01:11:25 +000025
26#if !defined(FIRST) && !defined(SECOND)
27#include "first.h"
28#include "second.h"
29#endif
30
31namespace AccessSpecifiers {
32#if defined(FIRST)
33struct S1 {
34};
35#elif defined(SECOND)
36struct S1 {
37 private:
38};
39#else
40S1 s1;
41// expected-error@second.h:* {{'AccessSpecifiers::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
42// expected-note@first.h:* {{but in 'FirstModule' found end of class}}
43#endif
44
45#if defined(FIRST)
46struct S2 {
47 public:
48};
49#elif defined(SECOND)
50struct S2 {
51 protected:
52};
53#else
54S2 s2;
55// expected-error@second.h:* {{'AccessSpecifiers::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found protected access specifier}}
56// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
57#endif
58} // namespace AccessSpecifiers
59
Richard Trieu639d7b62017-02-22 22:22:42 +000060namespace StaticAssert {
61#if defined(FIRST)
62struct S1 {
63 static_assert(1 == 1, "First");
64};
65#elif defined(SECOND)
66struct S1 {
67 static_assert(1 == 1, "Second");
68};
69#else
70S1 s1;
71// expected-error@second.h:* {{'StaticAssert::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with message}}
72// expected-note@first.h:* {{but in 'FirstModule' found static assert with different message}}
73#endif
74
75#if defined(FIRST)
76struct S2 {
77 static_assert(2 == 2, "Message");
78};
79#elif defined(SECOND)
80struct S2 {
81 static_assert(2 == 2);
82};
83#else
84S2 s2;
85// expected-error@second.h:* {{'StaticAssert::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with no message}}
86// expected-note@first.h:* {{but in 'FirstModule' found static assert with message}}
87#endif
88
89#if defined(FIRST)
90struct S3 {
91 static_assert(3 == 3, "Message");
92};
93#elif defined(SECOND)
94struct S3 {
95 static_assert(3 != 4, "Message");
96};
97#else
98S3 s3;
99// expected-error@second.h:* {{'StaticAssert::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with condition}}
100// expected-note@first.h:* {{but in 'FirstModule' found static assert with different condition}}
101#endif
102
103#if defined(FIRST)
104struct S4 {
105 static_assert(4 == 4, "Message");
106};
107#elif defined(SECOND)
108struct S4 {
109 public:
110};
111#else
112S4 s4;
113// expected-error@second.h:* {{'StaticAssert::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
114// expected-note@first.h:* {{but in 'FirstModule' found static assert}}
115#endif
116}
117
Richard Trieud0786092017-02-23 00:23:01 +0000118namespace Field {
119#if defined(FIRST)
120struct S1 {
121 int x;
122 private:
123 int y;
124};
125#elif defined(SECOND)
126struct S1 {
127 int x;
128 int y;
129};
130#else
131S1 s1;
132// expected-error@second.h:* {{'Field::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
133// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
134#endif
135
136#if defined(FIRST)
137struct S2 {
138 int x;
139 int y;
140};
141#elif defined(SECOND)
142struct S2 {
143 int y;
144 int x;
145};
146#else
147S2 s2;
148// expected-error@second.h:* {{'Field::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}}
149// expected-note@first.h:* {{but in 'FirstModule' found field 'x'}}
150#endif
Richard Trieubcaaf962017-02-23 03:25:57 +0000151
152#if defined(FIRST)
153struct S3 {
154 double x;
155};
156#elif defined(SECOND)
157struct S3 {
158 int x;
159};
160#else
161S3 s3;
162// expected-error@first.h:* {{'Field::S3::x' from module 'FirstModule' is not present in definition of 'Field::S3' in module 'SecondModule'}}
163// expected-note@second.h:* {{declaration of 'x' does not match}}
164#endif
Richard Trieu8459ddf2017-02-24 02:59:12 +0000165
166#if defined(FIRST)
167typedef int A;
168struct S4 {
169 A x;
170};
171
172struct S5 {
173 A x;
174};
175#elif defined(SECOND)
176typedef int B;
177struct S4 {
178 B x;
179};
180
181struct S5 {
182 int x;
183};
184#else
185S4 s4;
Alex Lorenz76377dc2017-03-10 15:04:58 +0000186// expected-error@second.h:* {{'Field::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'Field::B' (aka 'int')}}
187// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'Field::A' (aka 'int')}}
Richard Trieu8459ddf2017-02-24 02:59:12 +0000188
189S5 s5;
190// expected-error@second.h:* {{'Field::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'int'}}
Alex Lorenz76377dc2017-03-10 15:04:58 +0000191// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'Field::A' (aka 'int')}}
Richard Trieu8459ddf2017-02-24 02:59:12 +0000192#endif
193
Richard Trieu93772fc2017-02-24 20:59:28 +0000194#if defined(FIRST)
195struct S6 {
196 unsigned x;
197};
198#elif defined(SECOND)
199struct S6 {
200 unsigned x : 1;
201};
202#else
203S6 s6;
204// expected-error@second.h:* {{'Field::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x'}}
205// expected-note@first.h:* {{but in 'FirstModule' found non-bitfield 'x'}}
206#endif
207
208#if defined(FIRST)
209struct S7 {
210 unsigned x : 2;
211};
212#elif defined(SECOND)
213struct S7 {
214 unsigned x : 1;
215};
216#else
217S7 s7;
218// expected-error@second.h:* {{'Field::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x' with one width expression}}
219// expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}}
220#endif
221
222#if defined(FIRST)
223struct S8 {
224 unsigned x : 2;
225};
226#elif defined(SECOND)
227struct S8 {
228 unsigned x : 1 + 1;
229};
230#else
231S8 s8;
232// expected-error@second.h:* {{'Field::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x' with one width expression}}
233// expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}}
234#endif
Richard Trieu8459ddf2017-02-24 02:59:12 +0000235
Richard Trieu8d543e22017-02-24 23:35:37 +0000236#if defined(FIRST)
237struct S9 {
238 mutable int x;
239};
240#elif defined(SECOND)
241struct S9 {
242 int x;
243};
244#else
245S9 s9;
246// expected-error@second.h:* {{'Field::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found non-mutable field 'x'}}
247// expected-note@first.h:* {{but in 'FirstModule' found mutable field 'x'}}
248#endif
249
250#if defined(FIRST)
251struct S10 {
252 unsigned x = 5;
253};
254#elif defined(SECOND)
255struct S10 {
256 unsigned x;
257};
258#else
259S10 s10;
260// expected-error@second.h:* {{'Field::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with no initalizer}}
261// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with an initializer}}
262#endif
263
264#if defined(FIRST)
265struct S11 {
266 unsigned x = 5;
267};
268#elif defined(SECOND)
269struct S11 {
270 unsigned x = 7;
271};
272#else
273S11 s11;
274// expected-error@second.h:* {{'Field::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with an initializer}}
275// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}}
276#endif
277
Richard Trieu02552272017-05-02 23:58:52 +0000278#if defined(FIRST)
279struct S12 {
280 unsigned x[5];
281};
282#elif defined(SECOND)
283struct S12 {
284 unsigned x[7];
285};
286#else
287S12 s12;
288// expected-error@first.h:* {{'Field::S12::x' from module 'FirstModule' is not present in definition of 'Field::S12' in module 'SecondModule'}}
289// expected-note@second.h:* {{declaration of 'x' does not match}}
290#endif
291
292#if defined(FIRST)
293struct S13 {
294 unsigned x[7];
295};
296#elif defined(SECOND)
297struct S13 {
298 double x[7];
299};
300#else
301S13 s13;
302// expected-error@first.h:* {{'Field::S13::x' from module 'FirstModule' is not present in definition of 'Field::S13' in module 'SecondModule'}}
303// expected-note@second.h:* {{declaration of 'x' does not match}}
304#endif
Richard Trieud0786092017-02-23 00:23:01 +0000305} // namespace Field
306
Richard Trieu48143742017-02-28 21:24:38 +0000307namespace Method {
308#if defined(FIRST)
309struct S1 {
310 void A() {}
311};
312#elif defined(SECOND)
313struct S1 {
314 private:
315 void A() {}
316};
317#else
318S1 s1;
319// expected-error@second.h:* {{'Method::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
320// expected-note@first.h:* {{but in 'FirstModule' found method}}
321#endif
322
323#if defined(FIRST)
324struct S2 {
325 void A() {}
326 void B() {}
327};
328#elif defined(SECOND)
329struct S2 {
330 void B() {}
331 void A() {}
332};
333#else
334S2 s2;
335// expected-error@second.h:* {{'Method::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'B'}}
336// expected-note@first.h:* {{but in 'FirstModule' found method 'A'}}
337#endif
Richard Trieu583e2c12017-03-04 00:08:58 +0000338
339#if defined(FIRST)
340struct S3 {
341 static void A() {}
Richard Trieuf4b54fe2017-03-04 03:04:15 +0000342 void A(int) {}
Richard Trieu583e2c12017-03-04 00:08:58 +0000343};
344#elif defined(SECOND)
345struct S3 {
Richard Trieuf4b54fe2017-03-04 03:04:15 +0000346 void A(int) {}
347 static void A() {}
Richard Trieu583e2c12017-03-04 00:08:58 +0000348};
349#else
350S3 s3;
351// expected-error@second.h:* {{'Method::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not static}}
352// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is static}}
353#endif
354
355#if defined(FIRST)
356struct S4 {
357 virtual void A() {}
358 void B() {}
359};
360#elif defined(SECOND)
361struct S4 {
362 void A() {}
363 virtual void B() {}
364};
365#else
366S4 s4;
367// expected-error@second.h:* {{'Method::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not virtual}}
368// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is virtual}}
369#endif
370
371#if defined(FIRST)
372struct S5 {
373 virtual void A() = 0;
374 virtual void B() {};
375};
376#elif defined(SECOND)
377struct S5 {
378 virtual void A() {}
379 virtual void B() = 0;
380};
381#else
382S5 *s5;
383// expected-error@second.h:* {{'Method::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is virtual}}
384// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is pure virtual}}
385#endif
386
387#if defined(FIRST)
388struct S6 {
389 inline void A() {}
390};
391#elif defined(SECOND)
392struct S6 {
393 void A() {}
394};
395#else
396S6 s6;
397// expected-error@second.h:* {{'Method::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not inline}}
398// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is inline}}
399#endif
400
401#if defined(FIRST)
402struct S7 {
403 void A() volatile {}
404 void A() {}
405};
406#elif defined(SECOND)
407struct S7 {
408 void A() {}
409 void A() volatile {}
410};
411#else
412S7 s7;
413// expected-error@second.h:* {{'Method::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not volatile}}
414// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is volatile}}
415#endif
416
417#if defined(FIRST)
418struct S8 {
419 void A() const {}
420 void A() {}
421};
422#elif defined(SECOND)
423struct S8 {
424 void A() {}
425 void A() const {}
426};
427#else
428S8 s8;
429// expected-error@second.h:* {{'Method::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not const}}
430// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is const}}
431#endif
432
Richard Trieu02552272017-05-02 23:58:52 +0000433#if defined(FIRST)
434struct S9 {
435 void A(int x) {}
436 void A(int x, int y) {}
437};
438#elif defined(SECOND)
439struct S9 {
440 void A(int x, int y) {}
441 void A(int x) {}
442};
443#else
444S9 s9;
445// expected-error@second.h:* {{'Method::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' that has 2 parameters}}
446// expected-note@first.h:* {{but in 'FirstModule' found method 'A' that has 1 parameter}}
447#endif
448
449#if defined(FIRST)
450struct S10 {
451 void A(int x) {}
452 void A(float x) {}
453};
454#elif defined(SECOND)
455struct S10 {
456 void A(float x) {}
457 void A(int x) {}
458};
459#else
460S10 s10;
461// expected-error@second.h:* {{'Method::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter of type 'float'}}
462// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter of type 'int'}}
463#endif
464
465#if defined(FIRST)
466struct S11 {
467 void A(int x) {}
468};
469#elif defined(SECOND)
470struct S11 {
471 void A(int y) {}
472};
473#else
474S11 s11;
475// expected-error@second.h:* {{'Method::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter named 'y'}}
476// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter named 'x'}}
477#endif
478
479#if defined(FIRST)
480struct S12 {
481 void A(int x) {}
482};
483#elif defined(SECOND)
484struct S12 {
485 void A(int x = 1) {}
486};
487#else
488S12 s12;
Richard Trieu6e13ff32017-06-16 02:44:29 +0000489// expected-error@second.h:* {{'Method::S12' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter without a default argument}}
490// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter with a default argument}}
Richard Trieu02552272017-05-02 23:58:52 +0000491#endif
492
493#if defined(FIRST)
494struct S13 {
495 void A(int x = 1 + 0) {}
496};
497#elif defined(SECOND)
498struct S13 {
499 void A(int x = 1) {}
500};
501#else
502S13 s13;
Richard Trieu6e13ff32017-06-16 02:44:29 +0000503// expected-error@second.h:* {{'Method::S13' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter with a default argument}}
504// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter with a different default argument}}
Richard Trieu02552272017-05-02 23:58:52 +0000505#endif
506
507#if defined(FIRST)
508struct S14 {
509 void A(int x[2]) {}
510};
511#elif defined(SECOND)
512struct S14 {
513 void A(int x[3]) {}
514};
515#else
516S14 s14;
517// expected-error@second.h:* {{'Method::S14' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter of type 'int *' decayed from 'int [3]'}}
518// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter of type 'int *' decayed from 'int [2]'}}
519#endif
Richard Trieu9747a7c2017-07-14 01:36:41 +0000520
521#if defined(FIRST)
522struct S15 {
523 int A() { return 0; }
524};
525#elif defined(SECOND)
526struct S15 {
527 long A() { return 0; }
528};
529#else
530S15 s15;
531// expected-error@first.h:* {{'Method::S15::A' from module 'FirstModule' is not present in definition of 'Method::S15' in module 'SecondModule'}}
532// expected-note@second.h:* {{declaration of 'A' does not match}}
533#endif
Richard Trieu48143742017-02-28 21:24:38 +0000534} // namespace Method
535
Richard Trieue7f7ed22017-02-22 01:11:25 +0000536// Naive parsing of AST can lead to cycles in processing. Ensure
537// self-references don't trigger an endless cycles of AST node processing.
538namespace SelfReference {
539#if defined(FIRST)
540template <template <int> class T> class Wrapper {};
541
542template <int N> class S {
543 S(Wrapper<::SelfReference::S> &Ref) {}
544};
545
546struct Xx {
547 struct Yy {
548 };
549};
550
551Xx::Xx::Xx::Yy yy;
552
553namespace NNS {
554template <typename> struct Foo;
555template <template <class> class T = NNS::Foo>
556struct NestedNamespaceSpecifier {};
557}
558#endif
559} // namespace SelfReference
560
Richard Trieu33562c22017-03-08 00:13:19 +0000561namespace TypeDef {
562#if defined(FIRST)
563struct S1 {
564 typedef int a;
565};
566#elif defined(SECOND)
567struct S1 {
568 typedef double a;
569};
570#else
571S1 s1;
572// expected-error@first.h:* {{'TypeDef::S1::a' from module 'FirstModule' is not present in definition of 'TypeDef::S1' in module 'SecondModule'}}
573// expected-note@second.h:* {{declaration of 'a' does not match}}
574#endif
575
576#if defined(FIRST)
577struct S2 {
578 typedef int a;
579};
580#elif defined(SECOND)
581struct S2 {
582 typedef int b;
583};
584#else
585S2 s2;
586// expected-error@first.h:* {{'TypeDef::S2::a' from module 'FirstModule' is not present in definition of 'TypeDef::S2' in module 'SecondModule'}}
587// expected-note@second.h:* {{definition has no member 'a'}}
588#endif
589
590#if defined(FIRST)
591typedef int T;
592struct S3 {
593 typedef T a;
594};
595#elif defined(SECOND)
596typedef double T;
597struct S3 {
598 typedef T a;
599};
600#else
601S3 s3;
602// expected-error@first.h:* {{'TypeDef::S3::a' from module 'FirstModule' is not present in definition of 'TypeDef::S3' in module 'SecondModule'}}
603// expected-note@second.h:* {{declaration of 'a' does not match}}
604#endif
Richard Trieu11d566a2017-06-12 21:58:22 +0000605
606#if defined(FIRST)
607struct S4 {
608 typedef int a;
609 typedef int b;
610};
611#elif defined(SECOND)
612struct S4 {
613 typedef int b;
614 typedef int a;
615};
616#else
617S4 s4;
618// expected-error@second.h:* {{'TypeDef::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef name 'b'}}
619// expected-note@first.h:* {{but in 'FirstModule' found typedef name 'a'}}
620#endif
621
622#if defined(FIRST)
623struct S5 {
624 typedef int a;
625 typedef int b;
626 int x;
627};
628#elif defined(SECOND)
629struct S5 {
630 int x;
631 typedef int b;
632 typedef int a;
633};
634#else
635S5 s5;
636// expected-error@second.h:* {{'TypeDef::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
637// expected-note@first.h:* {{but in 'FirstModule' found typedef}}
638#endif
639
640#if defined(FIRST)
641typedef float F;
642struct S6 {
643 typedef int a;
644 typedef F b;
645};
646#elif defined(SECOND)
647struct S6 {
648 typedef int a;
649 typedef float b;
650};
651#else
652S6 s6;
653// expected-error@second.h:* {{'TypeDef::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef 'b' with underlying type 'float'}}
654// expected-note@first.h:* {{but in 'FirstModule' found typedef 'b' with different underlying type 'TypeDef::F' (aka 'float')}}
655#endif
Richard Trieu33562c22017-03-08 00:13:19 +0000656} // namespace TypeDef
657
658namespace Using {
659#if defined(FIRST)
660struct S1 {
661 using a = int;
662};
663#elif defined(SECOND)
664struct S1 {
665 using a = double;
666};
667#else
668S1 s1;
669// expected-error@first.h:* {{'Using::S1::a' from module 'FirstModule' is not present in definition of 'Using::S1' in module 'SecondModule'}}
670// expected-note@second.h:* {{declaration of 'a' does not match}}
671#endif
672
673#if defined(FIRST)
674struct S2 {
675 using a = int;
676};
677#elif defined(SECOND)
678struct S2 {
679 using b = int;
680};
681#else
682S2 s2;
683// expected-error@first.h:* {{'Using::S2::a' from module 'FirstModule' is not present in definition of 'Using::S2' in module 'SecondModule'}}
684// expected-note@second.h:* {{definition has no member 'a'}}
685#endif
686
687#if defined(FIRST)
688typedef int T;
689struct S3 {
690 using a = T;
691};
692#elif defined(SECOND)
693typedef double T;
694struct S3 {
695 using a = T;
696};
697#else
698S3 s3;
699// expected-error@first.h:* {{'Using::S3::a' from module 'FirstModule' is not present in definition of 'Using::S3' in module 'SecondModule'}}
700// expected-note@second.h:* {{declaration of 'a' does not match}}
701#endif
Richard Trieu11d566a2017-06-12 21:58:22 +0000702
703#if defined(FIRST)
704struct S4 {
705 using a = int;
706 using b = int;
707};
708#elif defined(SECOND)
709struct S4 {
710 using b = int;
711 using a = int;
712};
713#else
714S4 s4;
715// expected-error@second.h:* {{'Using::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias name 'b'}}
716// expected-note@first.h:* {{but in 'FirstModule' found type alias name 'a'}}
717#endif
718
719#if defined(FIRST)
720struct S5 {
721 using a = int;
722 using b = int;
723 int x;
724};
725#elif defined(SECOND)
726struct S5 {
727 int x;
728 using b = int;
729 using a = int;
730};
731#else
732S5 s5;
733// expected-error@second.h:* {{'Using::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
734// expected-note@first.h:* {{but in 'FirstModule' found type alias}}
735#endif
736
737#if defined(FIRST)
738typedef float F;
739struct S6 {
740 using a = int;
741 using b = F;
742};
743#elif defined(SECOND)
744struct S6 {
745 using a = int;
746 using b = float;
747};
748#else
749S6 s6;
750// expected-error@second.h:* {{'Using::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'b' with underlying type 'float'}}
751// expected-note@first.h:* {{but in 'FirstModule' found type alias 'b' with different underlying type 'Using::F' (aka 'float')}}
752#endif
Richard Trieu33562c22017-03-08 00:13:19 +0000753} // namespace Using
754
Richard Trieu58bb7bd2017-05-17 02:29:02 +0000755namespace RecordType {
756#if defined(FIRST)
757struct B1 {};
758struct S1 {
759 B1 x;
760};
761#elif defined(SECOND)
762struct A1 {};
763struct S1 {
764 A1 x;
765};
766#else
767S1 s1;
768// expected-error@first.h:* {{'RecordType::S1::x' from module 'FirstModule' is not present in definition of 'RecordType::S1' in module 'SecondModule'}}
769// expected-note@second.h:* {{declaration of 'x' does not match}}
770#endif
771}
772
773namespace DependentType {
774#if defined(FIRST)
775template <class T>
776class S1 {
777 typename T::typeA x;
778};
779#elif defined(SECOND)
780template <class T>
781class S1 {
782 typename T::typeB x;
783};
784#else
785template<class T>
786using U1 = S1<T>;
787// expected-error@first.h:* {{'DependentType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T>' in module 'SecondModule'}}
788// expected-note@second.h:* {{declaration of 'x' does not match}}
789#endif
790}
791
792namespace ElaboratedType {
793#if defined(FIRST)
794namespace N1 { using type = double; }
795struct S1 {
796 N1::type x;
797};
798#elif defined(SECOND)
799namespace N1 { using type = int; }
800struct S1 {
801 N1::type x;
802};
803#else
804S1 s1;
805// expected-error@first.h:* {{'ElaboratedType::S1::x' from module 'FirstModule' is not present in definition of 'ElaboratedType::S1' in module 'SecondModule'}}
806// expected-note@second.h:* {{declaration of 'x' does not match}}
807#endif
808}
809
810namespace Enum {
811#if defined(FIRST)
812enum A1 {};
813struct S1 {
814 A1 x;
815};
816#elif defined(SECOND)
817enum A2 {};
818struct S1 {
819 A2 x;
820};
821#else
822S1 s1;
823// expected-error@first.h:* {{'Enum::S1::x' from module 'FirstModule' is not present in definition of 'Enum::S1' in module 'SecondModule'}}
824// expected-note@second.h:* {{declaration of 'x' does not match}}
825#endif
826}
Hans Wennborg22707762017-04-12 16:40:26 +0000827
Richard Trieuce81b192017-05-17 03:23:35 +0000828namespace NestedNamespaceSpecifier {
829#if defined(FIRST)
830namespace LevelA1 {
831using Type = int;
832}
833
834struct S1 {
835 LevelA1::Type x;
836};
837# elif defined(SECOND)
838namespace LevelB1 {
839namespace LevelC1 {
840using Type = int;
841}
842}
843
844struct S1 {
845 LevelB1::LevelC1::Type x;
846};
847#else
848S1 s1;
849// expected-error@second.h:* {{'NestedNamespaceSpecifier::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'LevelB1::LevelC1::Type' (aka 'int')}}
850// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA1::Type' (aka 'int')}}
851#endif
852
853#if defined(FIRST)
854namespace LevelA2 { using Type = int; }
855struct S2 {
856 LevelA2::Type x;
857};
858# elif defined(SECOND)
859struct S2 {
860 int x;
861};
862#else
863S2 s2;
864// expected-error@second.h:* {{'NestedNamespaceSpecifier::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'int'}}
865// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA2::Type' (aka 'int')}}
866#endif
867
868namespace LevelA3 { using Type = int; }
869namespace LevelB3 { using Type = int; }
870#if defined(FIRST)
871struct S3 {
872 LevelA3::Type x;
873};
874# elif defined(SECOND)
875struct S3 {
876 LevelB3::Type x;
877};
878#else
879S3 s3;
880// expected-error@second.h:* {{'NestedNamespaceSpecifier::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'LevelB3::Type' (aka 'int')}}
881// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA3::Type' (aka 'int')}}
882#endif
883
884#if defined(FIRST)
885struct TA4 { using Type = int; };
886struct S4 {
887 TA4::Type x;
888};
889# elif defined(SECOND)
890struct TB4 { using Type = int; };
891struct S4 {
892 TB4::Type x;
893};
894#else
895S4 s4;
896// expected-error@second.h:* {{'NestedNamespaceSpecifier::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'TB4::Type' (aka 'int')}}
897// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'TA4::Type' (aka 'int')}}
898#endif
899
900#if defined(FIRST)
901struct T5 { using Type = int; };
902struct S5 {
903 T5::Type x;
904};
905# elif defined(SECOND)
906namespace T5 { using Type = int; };
907struct S5 {
908 T5::Type x;
909};
910#else
911S5 s5;
912// expected-error@second.h:* {{'NestedNamespaceSpecifier::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'T5::Type' (aka 'int')}}
913// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'T5::Type' (aka 'int')}}
914#endif
915
916#if defined(FIRST)
917namespace N6 {using I = int;}
918struct S6 {
919 NestedNamespaceSpecifier::N6::I x;
920};
921# elif defined(SECOND)
922using I = int;
923struct S6 {
924 ::NestedNamespaceSpecifier::I x;
925};
926#else
927S6 s6;
928// expected-error@second.h:* {{'NestedNamespaceSpecifier::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type '::NestedNamespaceSpecifier::I' (aka 'int')}}
929// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'NestedNamespaceSpecifier::N6::I' (aka 'int')}}
930#endif
931
932#if defined(FIRST)
933template <class T, class U>
934class S7 {
935 typename T::type *x = {};
936 int z = x->T::foo();
937};
938#elif defined(SECOND)
939template <class T, class U>
940class S7 {
941 typename T::type *x = {};
942 int z = x->U::foo();
943};
944#else
945template <class T, class U>
946using U7 = S7<T, U>;
947// expected-error@second.h:* {{'NestedNamespaceSpecifier::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'z' with an initializer}}
948// expected-note@first.h:* {{but in 'FirstModule' found field 'z' with a different initializer}}
949#endif
950
951#if defined(FIRST)
952template <class T>
953class S8 {
954 int x = T::template X<int>::value;
955};
956#elif defined(SECOND)
957template <class T>
958class S8 {
959 int x = T::template Y<int>::value;
960};
961#else
962template <class T>
963using U8 = S8<T>;
964// expected-error@second.h:* {{'NestedNamespaceSpecifier::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with an initializer}}
965// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}}
966#endif
967
968#if defined(FIRST)
969namespace N9 { using I = int; }
970namespace O9 = N9;
971struct S9 {
972 O9::I x;
973};
974#elif defined(SECOND)
975namespace N9 { using I = int; }
976namespace P9 = N9;
977struct S9 {
978 P9::I x;
979};
980#else
981S9 s9;
982// expected-error@second.h:* {{'NestedNamespaceSpecifier::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'P9::I' (aka 'int')}}
983// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'O9::I' (aka 'int')}}
984#endif
Richard Trieu96b41642017-07-01 02:00:05 +0000985
986namespace N10 {
987#if defined(FIRST)
988inline namespace A { struct X {}; }
989struct S10 {
990 A::X x;
991};
992#elif defined(SECOND)
993inline namespace B { struct X {}; }
994struct S10 {
995 B::X x;
996};
997#else
998S10 s10;
999// expected-error@second.h:* {{'NestedNamespaceSpecifier::N10::S10::x' from module 'SecondModule' is not present in definition of 'NestedNamespaceSpecifier::N10::S10' in module 'FirstModule'}}
1000// expected-note@first.h:* {{declaration of 'x' does not match}}
1001#endif
1002}
Richard Trieuce81b192017-05-17 03:23:35 +00001003}
1004
Richard Trieu96b49622017-05-31 00:31:58 +00001005namespace TemplateSpecializationType {
1006#if defined(FIRST)
1007template <class T1> struct U1 {};
1008struct S1 {
1009 U1<int> u;
1010};
1011#elif defined(SECOND)
1012template <class T1, class T2> struct U1 {};
1013struct S1 {
1014 U1<int, int> u;
1015};
1016#else
1017S1 s1;
1018// expected-error@first.h:* {{'TemplateSpecializationType::S1::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S1' in module 'SecondModule'}}
1019// expected-note@second.h:* {{declaration of 'u' does not match}}
1020#endif
1021
1022#if defined(FIRST)
1023template <class T1> struct U2 {};
1024struct S2 {
1025 U2<int> u;
1026};
1027#elif defined(SECOND)
1028template <class T1> struct V1 {};
1029struct S2 {
1030 V1<int> u;
1031};
1032#else
1033S2 s2;
1034// expected-error@first.h:* {{'TemplateSpecializationType::S2::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S2' in module 'SecondModule'}}
1035// expected-note@second.h:* {{declaration of 'u' does not match}}
1036#endif
1037}
1038
Richard Trieu3b261bb72017-06-13 22:21:18 +00001039namespace TemplateArgument {
1040#if defined(FIRST)
1041template <class> struct U1{};
1042struct S1 {
1043 U1<int> x;
1044};
1045#elif defined(SECOND)
1046template <int> struct U1{};
1047struct S1 {
1048 U1<1> x;
1049};
1050#else
1051S1 s1;
1052// expected-error@first.h:* {{'TemplateArgument::S1::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S1' in module 'SecondModule'}}
1053// expected-note@second.h:* {{declaration of 'x' does not match}}
1054#endif
Richard Trieu1dcb4052017-06-14 01:28:00 +00001055
1056#if defined(FIRST)
1057template <int> struct U2{};
1058struct S2 {
1059 using T = U2<2>;
1060};
1061#elif defined(SECOND)
1062template <int> struct U2{};
1063struct S2 {
1064 using T = U2<(2)>;
1065};
1066#else
1067S2 s2;
1068// expected-error@second.h:* {{'TemplateArgument::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'T' with underlying type 'U2<(2)>'}}
1069// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U2<2>'}}
1070#endif
1071
1072#if defined(FIRST)
1073template <int> struct U3{};
1074struct S3 {
1075 using T = U3<2>;
1076};
1077#elif defined(SECOND)
1078template <int> struct U3{};
1079struct S3 {
1080 using T = U3<1 + 1>;
1081};
1082#else
1083S3 s3;
1084// expected-error@second.h:* {{'TemplateArgument::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'T' with underlying type 'U3<1 + 1>'}}
1085// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U3<2>'}}
1086#endif
1087
Richard Trieuee132d62017-06-14 03:17:26 +00001088#if defined(FIRST)
1089template<class> struct T4a {};
1090template <template <class> class T> struct U4 {};
1091struct S4 {
1092 U4<T4a> x;
1093};
1094#elif defined(SECOND)
1095template<class> struct T4b {};
1096template <template <class> class T> struct U4 {};
1097struct S4 {
1098 U4<T4b> x;
1099};
1100#else
1101S4 s4;
1102// expected-error@first.h:* {{'TemplateArgument::S4::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S4' in module 'SecondModule'}}
1103// expected-note@second.h:* {{declaration of 'x' does not match}}
1104#endif
Richard Trieu8844c522017-06-30 22:40:33 +00001105
1106#if defined(FIRST)
1107template <class T> struct U5 {};
1108struct S5 {
1109 U5<int> x;
1110};
1111#elif defined(SECOND)
1112template <class T> struct U5 {};
1113struct S5 {
1114 U5<short> x;
1115};
1116#else
1117S5 s5;
1118// expected-error@first.h:* {{'TemplateArgument::S5::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S5' in module 'SecondModule'}}
1119// expected-note@second.h:* {{declaration of 'x' does not match}}
1120#endif
1121
1122#if defined(FIRST)
1123template <class T> struct U6 {};
1124struct S6 {
1125 U6<int> x;
1126 U6<short> y;
1127};
1128#elif defined(SECOND)
1129template <class T> struct U6 {};
1130struct S6 {
1131 U6<short> y;
1132 U6<int> x;
1133};
1134#else
1135S6 s6;
1136// expected-error@second.h:* {{'TemplateArgument::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}}
1137// expected-note@first.h:* {{but in 'FirstModule' found field 'x'}}
1138#endif
Richard Trieud9201d02017-06-15 01:35:06 +00001139}
Richard Trieuee132d62017-06-14 03:17:26 +00001140
Richard Trieud9201d02017-06-15 01:35:06 +00001141namespace TemplateTypeParmType {
1142#if defined(FIRST)
1143template <class T1, class T2>
1144struct S1 {
1145 T1 x;
1146};
1147#elif defined(SECOND)
1148template <class T1, class T2>
1149struct S1 {
1150 T2 x;
1151};
1152#else
1153using TemplateTypeParmType::S1;
1154// expected-error@first.h:* {{'TemplateTypeParmType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T1, T2>' in module 'SecondModule'}}
1155// expected-note@second.h:* {{declaration of 'x' does not match}}
1156#endif
1157
1158#if defined(FIRST)
1159template <int ...Ts>
1160struct U2 {};
1161template <int T, int U>
1162class S2 {
1163 typedef U2<U, T> type;
1164 type x;
1165};
1166#elif defined(SECOND)
1167template <int ...Ts>
1168struct U2 {};
1169template <int T, int U>
1170class S2 {
1171 typedef U2<T, U> type;
1172 type x;
1173};
1174#else
1175using TemplateTypeParmType::S2;
1176// expected-error@first.h:* {{'TemplateTypeParmType::S2::x' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}}
1177// expected-note@second.h:* {{declaration of 'x' does not match}}
1178// expected-error@first.h:* {{'TemplateTypeParmType::S2::type' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}}
1179// expected-note@second.h:* {{declaration of 'type' does not match}}
1180#endif
Richard Trieu3b261bb72017-06-13 22:21:18 +00001181}
1182
Richard Trieu6e13ff32017-06-16 02:44:29 +00001183namespace VarDecl {
1184#if defined(FIRST)
1185struct S1 {
1186 static int x;
1187 static int y;
1188};
1189#elif defined(SECOND)
1190struct S1 {
1191 static int y;
1192 static int x;
1193};
1194#else
1195S1 s1;
1196// expected-error@second.h:* {{'VarDecl::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member with name 'y'}}
1197// expected-note@first.h:* {{but in 'FirstModule' found data member with name 'x'}}
1198#endif
1199
1200#if defined(FIRST)
1201struct S2 {
1202 static int x;
1203};
1204#elif defined(SECOND)
1205using I = int;
1206struct S2 {
1207 static I x;
1208};
1209#else
1210S2 s2;
1211// expected-error@second.h:* {{'VarDecl::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member 'x' with type 'VarDecl::I' (aka 'int')}}
1212// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' with different type 'int'}}
1213#endif
1214
1215#if defined(FIRST)
1216struct S3 {
1217 static const int x = 1;
1218};
1219#elif defined(SECOND)
1220struct S3 {
1221 static const int x;
1222};
1223#else
1224S3 s3;
1225// expected-error@second.h:* {{'VarDecl::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member 'x' with an initializer}}
1226// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' without an initializer}}
1227#endif
1228
1229#if defined(FIRST)
1230struct S4 {
1231 static const int x = 1;
1232};
1233#elif defined(SECOND)
1234struct S4 {
1235 static const int x = 2;
1236};
1237#else
1238S4 s4;
1239// expected-error@second.h:* {{'VarDecl::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member 'x' with an initializer}}
1240// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' with a different initializer}}
1241#endif
1242
1243#if defined(FIRST)
1244struct S5 {
1245 static const int x = 1;
1246};
1247#elif defined(SECOND)
1248struct S5 {
1249 static constexpr int x = 1;
1250};
1251#else
1252S5 s5;
1253// expected-error@second.h:* {{'VarDecl::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member 'x' is not constexpr}}
1254// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' is constexpr}}
1255#endif
1256
1257#if defined(FIRST)
1258struct S6 {
1259 static const int x = 1;
1260};
1261#elif defined(SECOND)
1262struct S6 {
1263 static const int y = 1;
1264};
1265#else
1266S6 s6;
1267// expected-error@first.h:* {{'VarDecl::S6::x' from module 'FirstModule' is not present in definition of 'VarDecl::S6' in module 'SecondModule'}}
1268// expected-note@second.h:* {{definition has no member 'x'}}
1269#endif
1270
1271#if defined(FIRST)
1272struct S7 {
1273 static const int x = 1;
1274};
1275#elif defined(SECOND)
1276struct S7 {
1277 static const unsigned x = 1;
1278};
1279#else
1280S7 s7;
1281// expected-error@first.h:* {{'VarDecl::S7::x' from module 'FirstModule' is not present in definition of 'VarDecl::S7' in module 'SecondModule'}}
1282// expected-note@second.h:* {{declaration of 'x' does not match}}
1283#endif
1284
1285#if defined(FIRST)
1286struct S8 {
1287public:
1288 static const int x = 1;
1289};
1290#elif defined(SECOND)
1291struct S8 {
1292 static const int x = 1;
1293public:
1294};
1295#else
1296S8 s8;
1297// expected-error@second.h:* {{'VarDecl::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member}}
1298// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
1299#endif
1300
1301#if defined(FIRST)
1302struct S9 {
1303 static const int x = 1;
1304};
1305#elif defined(SECOND)
1306struct S9 {
1307 static int x;
1308};
1309#else
1310S9 s9;
1311// expected-error@first.h:* {{'VarDecl::S9::x' from module 'FirstModule' is not present in definition of 'VarDecl::S9' in module 'SecondModule'}}
1312// expected-note@second.h:* {{declaration of 'x' does not match}}
1313#endif
1314
1315#if defined(FIRST)
1316template <typename T>
1317struct S {
1318 struct R {
1319 void foo(T x = 0) {}
1320 };
1321};
1322#elif defined(SECOND)
1323template <typename T>
1324struct S {
1325 struct R {
1326 void foo(T x = 1) {}
1327 };
1328};
1329#else
1330void run() {
1331 S<int>::R().foo();
1332}
1333// expected-error@second.h:* {{'VarDecl::S::R' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo' with 1st parameter with a default argument}}
1334// expected-note@first.h:* {{but in 'FirstModule' found method 'foo' with 1st parameter with a different default argument}}
1335#endif
1336
1337#if defined(FIRST)
1338template <typename alpha> struct Bravo {
1339 void charlie(bool delta = false) {}
1340};
1341typedef Bravo<char> echo;
1342echo foxtrot;
1343#elif defined(SECOND)
1344template <typename alpha> struct Bravo {
1345 void charlie(bool delta = (false)) {}
1346};
1347typedef Bravo<char> echo;
1348echo foxtrot;
1349#else
1350Bravo<char> golf;
1351// expected-error@second.h:* {{'VarDecl::Bravo' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'charlie' with 1st parameter with a default argument}}
1352// expected-note@first.h:* {{but in 'FirstModule' found method 'charlie' with 1st parameter with a different default argument}}
1353#endif
1354}
1355
Richard Trieuac6a1b62017-07-08 02:04:42 +00001356namespace Friend {
1357#if defined(FIRST)
1358struct T1 {};
1359struct S1 {
1360 friend class T1;
1361};
1362#elif defined(SECOND)
1363struct T1 {};
1364struct S1 {
1365 friend T1;
1366};
1367#else
1368S1 s1;
1369// expected-error@second.h:* {{'Friend::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend 'Friend::T1'}}
1370// expected-note@first.h:* {{but in 'FirstModule' found friend 'class T1'}}
1371#endif
1372
1373#if defined(FIRST)
1374struct T2 {};
1375struct S2 {
1376 friend class T2;
1377};
1378#elif defined(SECOND)
1379struct T2 {};
1380struct S2 {
1381 friend struct T2;
1382};
1383#else
1384S2 s2;
1385// expected-error@second.h:* {{'Friend::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend 'struct T2'}}
1386// expected-note@first.h:* {{but in 'FirstModule' found friend 'class T2'}}
1387#endif
1388
1389#if defined(FIRST)
1390struct T3 {};
1391struct S3 {
1392 friend const T3;
1393};
1394#elif defined(SECOND)
1395struct T3 {};
1396struct S3 {
1397 friend T3;
1398};
1399#else
1400S3 s3;
1401// expected-error@second.h:* {{'Friend::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend 'Friend::T3'}}
1402// expected-note@first.h:* {{but in 'FirstModule' found friend 'const Friend::T3'}}
1403#endif
1404
1405#if defined(FIRST)
1406struct T4 {};
1407struct S4 {
1408 friend T4;
1409};
1410#elif defined(SECOND)
1411struct S4 {
1412 friend void T4();
1413};
1414#else
1415S4 s4;
1416// expected-error@second.h:* {{'Friend::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend function}}
1417// expected-note@first.h:* {{but in 'FirstModule' found friend class}}
1418#endif
1419
1420#if defined(FIRST)
1421struct S5 {
1422 friend void T5a();
1423};
1424#elif defined(SECOND)
1425struct S5 {
1426 friend void T5b();
1427};
1428#else
1429S5 s5;
1430// expected-error@second.h:* {{'Friend::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend function 'T5b'}}
1431// expected-note@first.h:* {{but in 'FirstModule' found friend function 'T5a'}}
1432#endif
1433}
Richard Trieue7f7ed22017-02-22 01:11:25 +00001434// Interesting cases that should not cause errors. struct S should not error
1435// while struct T should error at the access specifier mismatch at the end.
1436namespace AllDecls {
Richard Trieu02552272017-05-02 23:58:52 +00001437#define CREATE_ALL_DECL_STRUCT(NAME, ACCESS) \
1438 typedef int INT; \
1439 struct NAME { \
1440 public: \
1441 private: \
1442 protected: \
1443 static_assert(1 == 1, "Message"); \
1444 static_assert(2 == 2); \
1445 \
1446 int x; \
1447 double y; \
1448 \
1449 INT z; \
1450 \
1451 unsigned a : 1; \
1452 unsigned b : 2 * 2 + 5 / 2; \
1453 \
1454 mutable int c = sizeof(x + y); \
1455 \
1456 void method() {} \
1457 static void static_method() {} \
1458 virtual void virtual_method() {} \
1459 virtual void pure_virtual_method() = 0; \
1460 inline void inline_method() {} \
1461 void volatile_method() volatile {} \
1462 void const_method() const {} \
1463 \
1464 typedef int typedef_int; \
1465 using using_int = int; \
1466 \
1467 void method_one_arg(int x) {} \
1468 void method_one_arg_default_argument(int x = 5 + 5) {} \
1469 void method_decayed_type(int x[5]) {} \
1470 \
1471 int constant_arr[5]; \
1472 \
1473 ACCESS: \
Richard Trieufe564052017-04-20 02:53:53 +00001474 };
1475
Richard Trieue7f7ed22017-02-22 01:11:25 +00001476#if defined(FIRST)
Richard Trieufe564052017-04-20 02:53:53 +00001477CREATE_ALL_DECL_STRUCT(S, public)
Richard Trieue7f7ed22017-02-22 01:11:25 +00001478#elif defined(SECOND)
Richard Trieufe564052017-04-20 02:53:53 +00001479CREATE_ALL_DECL_STRUCT(S, public)
Richard Trieue7f7ed22017-02-22 01:11:25 +00001480#else
Richard Trieu583e2c12017-03-04 00:08:58 +00001481S *s;
Richard Trieue7f7ed22017-02-22 01:11:25 +00001482#endif
1483
1484#if defined(FIRST)
Richard Trieufe564052017-04-20 02:53:53 +00001485CREATE_ALL_DECL_STRUCT(T, private)
Richard Trieue7f7ed22017-02-22 01:11:25 +00001486#elif defined(SECOND)
Richard Trieufe564052017-04-20 02:53:53 +00001487CREATE_ALL_DECL_STRUCT(T, public)
Richard Trieue7f7ed22017-02-22 01:11:25 +00001488#else
Richard Trieu583e2c12017-03-04 00:08:58 +00001489T *t;
Richard Trieue7f7ed22017-02-22 01:11:25 +00001490// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
1491// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
1492#endif
1493}
1494
1495namespace FriendFunction {
1496#if defined(FIRST)
1497void F(int = 0);
1498struct S { friend void F(int); };
1499#elif defined(SECOND)
1500void F(int);
1501struct S { friend void F(int); };
1502#else
1503S s;
1504#endif
1505
1506#if defined(FIRST)
1507void G(int = 0);
1508struct T {
1509 friend void G(int);
1510
1511 private:
1512};
1513#elif defined(SECOND)
1514void G(int);
1515struct T {
1516 friend void G(int);
1517
1518 public:
1519};
1520#else
1521T t;
1522// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
1523// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
1524#endif
1525} // namespace FriendFunction
1526
1527namespace ImplicitDecl {
1528#if defined(FIRST)
1529struct S { };
1530void S_Constructors() {
1531 // Trigger creation of implicit contructors
1532 S foo;
1533 S bar = foo;
1534 S baz(bar);
1535}
1536#elif defined(SECOND)
1537struct S { };
1538#else
1539S s;
1540#endif
1541
1542#if defined(FIRST)
1543struct T {
1544 private:
1545};
1546void T_Constructors() {
1547 // Trigger creation of implicit contructors
1548 T foo;
1549 T bar = foo;
1550 T baz(bar);
1551}
1552#elif defined(SECOND)
1553struct T {
1554 public:
1555};
1556#else
1557T t;
1558// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}
1559// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
1560#endif
1561
1562} // namespace ImplicitDelc
1563
1564namespace TemplatedClass {
1565#if defined(FIRST)
1566template <class>
1567struct S {};
1568#elif defined(SECOND)
1569template <class>
1570struct S {};
1571#else
1572S<int> s;
1573#endif
1574
1575#if defined(FIRST)
1576template <class>
1577struct T {
1578 private:
1579};
1580#elif defined(SECOND)
1581template <class>
1582struct T {
1583 public:
1584};
1585#else
1586T<int> t;
1587// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
1588// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
1589#endif
1590} // namespace TemplatedClass
1591
1592namespace TemplateClassWithField {
1593#if defined(FIRST)
1594template <class A>
1595struct S {
1596 A a;
1597};
1598#elif defined(SECOND)
1599template <class A>
1600struct S {
1601 A a;
1602};
1603#else
1604S<int> s;
1605#endif
1606
1607#if defined(FIRST)
1608template <class A>
1609struct T {
1610 A a;
1611
1612 private:
1613};
1614#elif defined(SECOND)
1615template <class A>
1616struct T {
1617 A a;
1618
1619 public:
1620};
1621#else
1622T<int> t;
1623// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
1624// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
1625#endif
1626} // namespace TemplateClassWithField
1627
1628namespace TemplateClassWithTemplateField {
1629#if defined(FIRST)
1630template <class A>
1631class WrapperS;
1632template <class A>
1633struct S {
1634 WrapperS<A> a;
1635};
1636#elif defined(SECOND)
1637template <class A>
1638class WrapperS;
1639template <class A>
1640struct S {
1641 WrapperS<A> a;
1642};
1643#else
1644template <class A>
1645class WrapperS{};
1646S<int> s;
1647#endif
1648
1649#if defined(FIRST)
1650template <class A>
1651class WrapperT;
1652template <class A>
1653struct T {
1654 WrapperT<A> a;
1655
1656 public:
1657};
1658#elif defined(SECOND)
1659template <class A>
1660class WrapperT;
1661template <class A>
1662struct T {
1663 WrapperT<A> a;
1664
1665 private:
1666};
1667#else
1668template <class A>
1669class WrapperT{};
1670T<int> t;
1671// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
1672// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
1673#endif
1674} // namespace TemplateClassWithTemplateField
1675
1676namespace EnumWithForwardDeclaration {
1677#if defined(FIRST)
1678enum E : int;
1679struct S {
1680 void get(E) {}
1681};
1682#elif defined(SECOND)
1683enum E : int { A, B };
1684struct S {
1685 void get(E) {}
1686};
1687#else
1688S s;
1689#endif
1690
1691#if defined(FIRST)
1692struct T {
1693 void get(E) {}
1694 public:
1695};
1696#elif defined(SECOND)
1697struct T {
1698 void get(E) {}
1699 private:
1700};
1701#else
1702T t;
1703// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
1704// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
1705#endif
1706} // namespace EnumWithForwardDeclaration
1707
1708namespace StructWithForwardDeclaration {
1709#if defined(FIRST)
1710struct P {};
1711struct S {
1712 struct P *ptr;
1713};
1714#elif defined(SECOND)
1715struct S {
1716 struct P *ptr;
1717};
1718#else
1719S s;
1720#endif
1721
1722#if defined(FIRST)
1723struct Q {};
1724struct T {
1725 struct Q *ptr;
1726 public:
1727};
1728#elif defined(SECOND)
1729struct T {
1730 struct Q *ptr;
1731 private:
1732};
1733#else
1734T t;
1735// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
1736// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
1737#endif
1738} // namespace StructWithForwardDeclaration
1739
1740namespace StructWithForwardDeclarationNoDefinition {
1741#if defined(FIRST)
1742struct P;
1743struct S {
1744 struct P *ptr;
1745};
1746#elif defined(SECOND)
1747struct S {
1748 struct P *ptr;
1749};
1750#else
1751S s;
1752#endif
1753
1754#if defined(FIRST)
1755struct Q;
1756struct T {
1757 struct Q *ptr;
1758
1759 public:
1760};
1761#elif defined(SECOND)
1762struct T {
1763 struct Q *ptr;
1764
1765 private:
1766};
1767#else
1768T t;
1769// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
1770// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
1771#endif
1772} // namespace StructWithForwardDeclarationNoDefinition
1773
Richard Trieufe564052017-04-20 02:53:53 +00001774namespace LateParsedDefaultArgument {
1775#if defined(FIRST)
1776template <typename T>
1777struct S {
1778 struct R {
1779 void foo(T x = 0) {}
1780 };
1781};
1782#elif defined(SECOND)
1783#else
1784void run() {
1785 S<int>::R().foo();
1786}
1787#endif
1788}
1789
1790namespace LateParsedDefaultArgument {
1791#if defined(FIRST)
1792template <typename alpha> struct Bravo {
1793 void charlie(bool delta = false) {}
1794};
1795typedef Bravo<char> echo;
1796echo foxtrot;
1797
1798Bravo<char> golf;
1799#elif defined(SECOND)
1800#else
1801#endif
1802}
1803
Richard Trieu157ed942017-04-28 22:03:28 +00001804namespace DifferentParameterNameInTemplate {
1805#if defined(FIRST) || defined(SECOND)
1806template <typename T>
1807struct S {
1808 typedef T Type;
1809
1810 static void Run(const Type *name_one);
1811};
1812
1813template <typename T>
1814void S<T>::Run(const T *name_two) {}
1815
1816template <typename T>
1817struct Foo {
1818 ~Foo() { Handler::Run(nullptr); }
1819 Foo() {}
1820
1821 class Handler : public S<T> {};
1822
1823 void Get(typename Handler::Type *x = nullptr) {}
1824 void Add() { Handler::Run(nullptr); }
1825};
1826#endif
1827
1828#if defined(FIRST)
1829struct Beta;
1830
1831struct Alpha {
1832 Alpha();
1833 void Go() { betas.Get(); }
1834 Foo<Beta> betas;
1835};
1836
1837#elif defined(SECOND)
1838struct Beta {};
1839
1840struct BetaHelper {
1841 void add_Beta() { betas.Add(); }
1842 Foo<Beta> betas;
1843};
1844
1845#else
1846Alpha::Alpha() {}
1847#endif
1848}
1849
Richard Trieu02552272017-05-02 23:58:52 +00001850namespace ParameterTest {
1851#if defined(FIRST)
1852class X {};
1853template <typename G>
1854class S {
1855 public:
1856 typedef G Type;
1857 static inline G *Foo(const G *a, int * = nullptr);
1858};
1859
1860template<typename G>
1861G* S<G>::Foo(const G* aaaa, int*) {}
1862#elif defined(SECOND)
1863template <typename G>
1864class S {
1865 public:
1866 typedef G Type;
1867 static inline G *Foo(const G *a, int * = nullptr);
1868};
1869
1870template<typename G>
1871G* S<G>::Foo(const G* asdf, int*) {}
1872#else
1873S<X> s;
1874#endif
1875}
1876
Richard Trieub35ef2a2017-05-09 03:24:34 +00001877namespace MultipleTypedefs {
1878#if defined(FIRST)
1879typedef int B1;
1880typedef B1 A1;
1881struct S1 {
1882 A1 x;
1883};
1884#elif defined(SECOND)
1885typedef int A1;
1886struct S1 {
1887 A1 x;
1888};
1889#else
1890S1 s1;
1891#endif
1892
1893#if defined(FIRST)
1894struct T2 { int x; };
1895typedef T2 B2;
1896typedef B2 A2;
1897struct S2 {
1898 T2 x;
1899};
1900#elif defined(SECOND)
1901struct T2 { int x; };
1902typedef T2 A2;
1903struct S2 {
1904 T2 x;
1905};
1906#else
1907S2 s2;
1908#endif
Richard Trieu3e03d3e2017-06-29 22:53:04 +00001909
1910#if defined(FIRST)
1911using A3 = const int;
1912using B3 = volatile A3;
1913struct S3 {
1914 B3 x = 1;
1915};
1916#elif defined(SECOND)
1917using A3 = volatile const int;
1918using B3 = A3;
1919struct S3 {
1920 B3 x = 1;
1921};
1922#else
1923S3 s3;
1924#endif
Richard Trieub35ef2a2017-05-09 03:24:34 +00001925}
Richard Trieu02552272017-05-02 23:58:52 +00001926
Richard Trieue7f7ed22017-02-22 01:11:25 +00001927// Keep macros contained to one file.
1928#ifdef FIRST
1929#undef FIRST
1930#endif
1931#ifdef SECOND
1932#undef SECOND
1933#endif