blob: 8ff95d2566a77f7f5d88db03fc6a0302cfed8289 [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 Trieu1c71d512017-07-15 02:55:13 +0000536namespace Constructor {
537#if defined(FIRST)
538struct S1 {
539 S1() {}
540 void foo() {}
541};
542#elif defined(SECOND)
543struct S1 {
544 void foo() {}
545 S1() {}
546};
547#else
548S1 s1;
549// expected-error@second.h:* {{'Constructor::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo'}}
550// expected-note@first.h:* {{but in 'FirstModule' found constructor}}
551#endif
552
553#if defined(FIRST)
554struct S2 {
555 S2(int) {}
556 S2(int, int) {}
557};
558#elif defined(SECOND)
559struct S2 {
560 S2(int, int) {}
561 S2(int) {}
562};
563#else
564S2* s2;
565// expected-error@second.h:* {{'Constructor::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found constructor that has 2 parameters}}
566// expected-note@first.h:* {{but in 'FirstModule' found constructor that has 1 parameter}}
567#endif
568} // namespace Constructor
569
570namespace Destructor {
571#if defined(FIRST)
572struct S1 {
573 ~S1() {}
574 S1() {}
575};
576#elif defined(SECOND)
577struct S1 {
578 S1() {}
579 ~S1() {}
580};
581#else
582S1 s1;
583// expected-error@second.h:* {{'Destructor::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found constructor}}
584// expected-note@first.h:* {{but in 'FirstModule' found destructor}}
585#endif
586
587#if defined(FIRST)
588struct S2 {
589 virtual ~S2() {}
590 void foo() {}
591};
592#elif defined(SECOND)
593struct S2 {
594 ~S2() {}
595 virtual void foo() {}
596};
597#else
598S2 s2;
599// expected-error@second.h:* {{'Destructor::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found destructor is not virtual}}
600// expected-note@first.h:* {{but in 'FirstModule' found destructor is virtual}}
601#endif
602
603} // namespace Destructor
604
Richard Trieue7f7ed22017-02-22 01:11:25 +0000605// Naive parsing of AST can lead to cycles in processing. Ensure
606// self-references don't trigger an endless cycles of AST node processing.
607namespace SelfReference {
608#if defined(FIRST)
609template <template <int> class T> class Wrapper {};
610
611template <int N> class S {
612 S(Wrapper<::SelfReference::S> &Ref) {}
613};
614
615struct Xx {
616 struct Yy {
617 };
618};
619
620Xx::Xx::Xx::Yy yy;
621
622namespace NNS {
623template <typename> struct Foo;
624template <template <class> class T = NNS::Foo>
625struct NestedNamespaceSpecifier {};
626}
627#endif
628} // namespace SelfReference
629
Richard Trieu33562c22017-03-08 00:13:19 +0000630namespace TypeDef {
631#if defined(FIRST)
632struct S1 {
633 typedef int a;
634};
635#elif defined(SECOND)
636struct S1 {
637 typedef double a;
638};
639#else
640S1 s1;
641// expected-error@first.h:* {{'TypeDef::S1::a' from module 'FirstModule' is not present in definition of 'TypeDef::S1' in module 'SecondModule'}}
642// expected-note@second.h:* {{declaration of 'a' does not match}}
643#endif
644
645#if defined(FIRST)
646struct S2 {
647 typedef int a;
648};
649#elif defined(SECOND)
650struct S2 {
651 typedef int b;
652};
653#else
654S2 s2;
655// expected-error@first.h:* {{'TypeDef::S2::a' from module 'FirstModule' is not present in definition of 'TypeDef::S2' in module 'SecondModule'}}
656// expected-note@second.h:* {{definition has no member 'a'}}
657#endif
658
659#if defined(FIRST)
660typedef int T;
661struct S3 {
662 typedef T a;
663};
664#elif defined(SECOND)
665typedef double T;
666struct S3 {
667 typedef T a;
668};
669#else
670S3 s3;
671// expected-error@first.h:* {{'TypeDef::S3::a' from module 'FirstModule' is not present in definition of 'TypeDef::S3' in module 'SecondModule'}}
672// expected-note@second.h:* {{declaration of 'a' does not match}}
673#endif
Richard Trieu11d566a2017-06-12 21:58:22 +0000674
675#if defined(FIRST)
676struct S4 {
677 typedef int a;
678 typedef int b;
679};
680#elif defined(SECOND)
681struct S4 {
682 typedef int b;
683 typedef int a;
684};
685#else
686S4 s4;
687// expected-error@second.h:* {{'TypeDef::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef name 'b'}}
688// expected-note@first.h:* {{but in 'FirstModule' found typedef name 'a'}}
689#endif
690
691#if defined(FIRST)
692struct S5 {
693 typedef int a;
694 typedef int b;
695 int x;
696};
697#elif defined(SECOND)
698struct S5 {
699 int x;
700 typedef int b;
701 typedef int a;
702};
703#else
704S5 s5;
705// expected-error@second.h:* {{'TypeDef::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
706// expected-note@first.h:* {{but in 'FirstModule' found typedef}}
707#endif
708
709#if defined(FIRST)
710typedef float F;
711struct S6 {
712 typedef int a;
713 typedef F b;
714};
715#elif defined(SECOND)
716struct S6 {
717 typedef int a;
718 typedef float b;
719};
720#else
721S6 s6;
722// 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'}}
723// expected-note@first.h:* {{but in 'FirstModule' found typedef 'b' with different underlying type 'TypeDef::F' (aka 'float')}}
724#endif
Richard Trieu33562c22017-03-08 00:13:19 +0000725} // namespace TypeDef
726
727namespace Using {
728#if defined(FIRST)
729struct S1 {
730 using a = int;
731};
732#elif defined(SECOND)
733struct S1 {
734 using a = double;
735};
736#else
737S1 s1;
738// expected-error@first.h:* {{'Using::S1::a' from module 'FirstModule' is not present in definition of 'Using::S1' in module 'SecondModule'}}
739// expected-note@second.h:* {{declaration of 'a' does not match}}
740#endif
741
742#if defined(FIRST)
743struct S2 {
744 using a = int;
745};
746#elif defined(SECOND)
747struct S2 {
748 using b = int;
749};
750#else
751S2 s2;
752// expected-error@first.h:* {{'Using::S2::a' from module 'FirstModule' is not present in definition of 'Using::S2' in module 'SecondModule'}}
753// expected-note@second.h:* {{definition has no member 'a'}}
754#endif
755
756#if defined(FIRST)
757typedef int T;
758struct S3 {
759 using a = T;
760};
761#elif defined(SECOND)
762typedef double T;
763struct S3 {
764 using a = T;
765};
766#else
767S3 s3;
768// expected-error@first.h:* {{'Using::S3::a' from module 'FirstModule' is not present in definition of 'Using::S3' in module 'SecondModule'}}
769// expected-note@second.h:* {{declaration of 'a' does not match}}
770#endif
Richard Trieu11d566a2017-06-12 21:58:22 +0000771
772#if defined(FIRST)
773struct S4 {
774 using a = int;
775 using b = int;
776};
777#elif defined(SECOND)
778struct S4 {
779 using b = int;
780 using a = int;
781};
782#else
783S4 s4;
784// expected-error@second.h:* {{'Using::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias name 'b'}}
785// expected-note@first.h:* {{but in 'FirstModule' found type alias name 'a'}}
786#endif
787
788#if defined(FIRST)
789struct S5 {
790 using a = int;
791 using b = int;
792 int x;
793};
794#elif defined(SECOND)
795struct S5 {
796 int x;
797 using b = int;
798 using a = int;
799};
800#else
801S5 s5;
802// expected-error@second.h:* {{'Using::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
803// expected-note@first.h:* {{but in 'FirstModule' found type alias}}
804#endif
805
806#if defined(FIRST)
807typedef float F;
808struct S6 {
809 using a = int;
810 using b = F;
811};
812#elif defined(SECOND)
813struct S6 {
814 using a = int;
815 using b = float;
816};
817#else
818S6 s6;
819// 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'}}
820// expected-note@first.h:* {{but in 'FirstModule' found type alias 'b' with different underlying type 'Using::F' (aka 'float')}}
821#endif
Richard Trieu33562c22017-03-08 00:13:19 +0000822} // namespace Using
823
Richard Trieu58bb7bd2017-05-17 02:29:02 +0000824namespace RecordType {
825#if defined(FIRST)
826struct B1 {};
827struct S1 {
828 B1 x;
829};
830#elif defined(SECOND)
831struct A1 {};
832struct S1 {
833 A1 x;
834};
835#else
836S1 s1;
837// expected-error@first.h:* {{'RecordType::S1::x' from module 'FirstModule' is not present in definition of 'RecordType::S1' in module 'SecondModule'}}
838// expected-note@second.h:* {{declaration of 'x' does not match}}
839#endif
840}
841
842namespace DependentType {
843#if defined(FIRST)
844template <class T>
845class S1 {
846 typename T::typeA x;
847};
848#elif defined(SECOND)
849template <class T>
850class S1 {
851 typename T::typeB x;
852};
853#else
854template<class T>
855using U1 = S1<T>;
856// expected-error@first.h:* {{'DependentType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T>' in module 'SecondModule'}}
857// expected-note@second.h:* {{declaration of 'x' does not match}}
858#endif
859}
860
861namespace ElaboratedType {
862#if defined(FIRST)
863namespace N1 { using type = double; }
864struct S1 {
865 N1::type x;
866};
867#elif defined(SECOND)
868namespace N1 { using type = int; }
869struct S1 {
870 N1::type x;
871};
872#else
873S1 s1;
874// expected-error@first.h:* {{'ElaboratedType::S1::x' from module 'FirstModule' is not present in definition of 'ElaboratedType::S1' in module 'SecondModule'}}
875// expected-note@second.h:* {{declaration of 'x' does not match}}
876#endif
877}
878
879namespace Enum {
880#if defined(FIRST)
881enum A1 {};
882struct S1 {
883 A1 x;
884};
885#elif defined(SECOND)
886enum A2 {};
887struct S1 {
888 A2 x;
889};
890#else
891S1 s1;
892// expected-error@first.h:* {{'Enum::S1::x' from module 'FirstModule' is not present in definition of 'Enum::S1' in module 'SecondModule'}}
893// expected-note@second.h:* {{declaration of 'x' does not match}}
894#endif
895}
Hans Wennborg22707762017-04-12 16:40:26 +0000896
Richard Trieuce81b192017-05-17 03:23:35 +0000897namespace NestedNamespaceSpecifier {
898#if defined(FIRST)
899namespace LevelA1 {
900using Type = int;
901}
902
903struct S1 {
904 LevelA1::Type x;
905};
906# elif defined(SECOND)
907namespace LevelB1 {
908namespace LevelC1 {
909using Type = int;
910}
911}
912
913struct S1 {
914 LevelB1::LevelC1::Type x;
915};
916#else
917S1 s1;
918// 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')}}
919// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA1::Type' (aka 'int')}}
920#endif
921
922#if defined(FIRST)
923namespace LevelA2 { using Type = int; }
924struct S2 {
925 LevelA2::Type x;
926};
927# elif defined(SECOND)
928struct S2 {
929 int x;
930};
931#else
932S2 s2;
933// 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'}}
934// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA2::Type' (aka 'int')}}
935#endif
936
937namespace LevelA3 { using Type = int; }
938namespace LevelB3 { using Type = int; }
939#if defined(FIRST)
940struct S3 {
941 LevelA3::Type x;
942};
943# elif defined(SECOND)
944struct S3 {
945 LevelB3::Type x;
946};
947#else
948S3 s3;
949// 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')}}
950// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA3::Type' (aka 'int')}}
951#endif
952
953#if defined(FIRST)
954struct TA4 { using Type = int; };
955struct S4 {
956 TA4::Type x;
957};
958# elif defined(SECOND)
959struct TB4 { using Type = int; };
960struct S4 {
961 TB4::Type x;
962};
963#else
964S4 s4;
965// 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')}}
966// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'TA4::Type' (aka 'int')}}
967#endif
968
969#if defined(FIRST)
970struct T5 { using Type = int; };
971struct S5 {
972 T5::Type x;
973};
974# elif defined(SECOND)
975namespace T5 { using Type = int; };
976struct S5 {
977 T5::Type x;
978};
979#else
980S5 s5;
981// 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')}}
982// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'T5::Type' (aka 'int')}}
983#endif
984
985#if defined(FIRST)
986namespace N6 {using I = int;}
987struct S6 {
988 NestedNamespaceSpecifier::N6::I x;
989};
990# elif defined(SECOND)
991using I = int;
992struct S6 {
993 ::NestedNamespaceSpecifier::I x;
994};
995#else
996S6 s6;
997// 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')}}
998// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'NestedNamespaceSpecifier::N6::I' (aka 'int')}}
999#endif
1000
1001#if defined(FIRST)
1002template <class T, class U>
1003class S7 {
1004 typename T::type *x = {};
1005 int z = x->T::foo();
1006};
1007#elif defined(SECOND)
1008template <class T, class U>
1009class S7 {
1010 typename T::type *x = {};
1011 int z = x->U::foo();
1012};
1013#else
1014template <class T, class U>
1015using U7 = S7<T, U>;
1016// 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}}
1017// expected-note@first.h:* {{but in 'FirstModule' found field 'z' with a different initializer}}
1018#endif
1019
1020#if defined(FIRST)
1021template <class T>
1022class S8 {
1023 int x = T::template X<int>::value;
1024};
1025#elif defined(SECOND)
1026template <class T>
1027class S8 {
1028 int x = T::template Y<int>::value;
1029};
1030#else
1031template <class T>
1032using U8 = S8<T>;
1033// 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}}
1034// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}}
1035#endif
1036
1037#if defined(FIRST)
1038namespace N9 { using I = int; }
1039namespace O9 = N9;
1040struct S9 {
1041 O9::I x;
1042};
1043#elif defined(SECOND)
1044namespace N9 { using I = int; }
1045namespace P9 = N9;
1046struct S9 {
1047 P9::I x;
1048};
1049#else
1050S9 s9;
1051// 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')}}
1052// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'O9::I' (aka 'int')}}
1053#endif
Richard Trieu96b41642017-07-01 02:00:05 +00001054
1055namespace N10 {
1056#if defined(FIRST)
1057inline namespace A { struct X {}; }
1058struct S10 {
1059 A::X x;
1060};
1061#elif defined(SECOND)
1062inline namespace B { struct X {}; }
1063struct S10 {
1064 B::X x;
1065};
1066#else
1067S10 s10;
1068// expected-error@second.h:* {{'NestedNamespaceSpecifier::N10::S10::x' from module 'SecondModule' is not present in definition of 'NestedNamespaceSpecifier::N10::S10' in module 'FirstModule'}}
1069// expected-note@first.h:* {{declaration of 'x' does not match}}
1070#endif
1071}
Richard Trieuce81b192017-05-17 03:23:35 +00001072}
1073
Richard Trieu96b49622017-05-31 00:31:58 +00001074namespace TemplateSpecializationType {
1075#if defined(FIRST)
1076template <class T1> struct U1 {};
1077struct S1 {
1078 U1<int> u;
1079};
1080#elif defined(SECOND)
1081template <class T1, class T2> struct U1 {};
1082struct S1 {
1083 U1<int, int> u;
1084};
1085#else
1086S1 s1;
1087// expected-error@first.h:* {{'TemplateSpecializationType::S1::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S1' in module 'SecondModule'}}
1088// expected-note@second.h:* {{declaration of 'u' does not match}}
1089#endif
1090
1091#if defined(FIRST)
1092template <class T1> struct U2 {};
1093struct S2 {
1094 U2<int> u;
1095};
1096#elif defined(SECOND)
1097template <class T1> struct V1 {};
1098struct S2 {
1099 V1<int> u;
1100};
1101#else
1102S2 s2;
1103// expected-error@first.h:* {{'TemplateSpecializationType::S2::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S2' in module 'SecondModule'}}
1104// expected-note@second.h:* {{declaration of 'u' does not match}}
1105#endif
1106}
1107
Richard Trieu3b261bb72017-06-13 22:21:18 +00001108namespace TemplateArgument {
1109#if defined(FIRST)
1110template <class> struct U1{};
1111struct S1 {
1112 U1<int> x;
1113};
1114#elif defined(SECOND)
1115template <int> struct U1{};
1116struct S1 {
1117 U1<1> x;
1118};
1119#else
1120S1 s1;
1121// expected-error@first.h:* {{'TemplateArgument::S1::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S1' in module 'SecondModule'}}
1122// expected-note@second.h:* {{declaration of 'x' does not match}}
1123#endif
Richard Trieu1dcb4052017-06-14 01:28:00 +00001124
1125#if defined(FIRST)
1126template <int> struct U2{};
1127struct S2 {
1128 using T = U2<2>;
1129};
1130#elif defined(SECOND)
1131template <int> struct U2{};
1132struct S2 {
1133 using T = U2<(2)>;
1134};
1135#else
1136S2 s2;
1137// 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)>'}}
1138// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U2<2>'}}
1139#endif
1140
1141#if defined(FIRST)
1142template <int> struct U3{};
1143struct S3 {
1144 using T = U3<2>;
1145};
1146#elif defined(SECOND)
1147template <int> struct U3{};
1148struct S3 {
1149 using T = U3<1 + 1>;
1150};
1151#else
1152S3 s3;
1153// 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>'}}
1154// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U3<2>'}}
1155#endif
1156
Richard Trieuee132d62017-06-14 03:17:26 +00001157#if defined(FIRST)
1158template<class> struct T4a {};
1159template <template <class> class T> struct U4 {};
1160struct S4 {
1161 U4<T4a> x;
1162};
1163#elif defined(SECOND)
1164template<class> struct T4b {};
1165template <template <class> class T> struct U4 {};
1166struct S4 {
1167 U4<T4b> x;
1168};
1169#else
1170S4 s4;
1171// expected-error@first.h:* {{'TemplateArgument::S4::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S4' in module 'SecondModule'}}
1172// expected-note@second.h:* {{declaration of 'x' does not match}}
1173#endif
Richard Trieu8844c522017-06-30 22:40:33 +00001174
1175#if defined(FIRST)
1176template <class T> struct U5 {};
1177struct S5 {
1178 U5<int> x;
1179};
1180#elif defined(SECOND)
1181template <class T> struct U5 {};
1182struct S5 {
1183 U5<short> x;
1184};
1185#else
1186S5 s5;
1187// expected-error@first.h:* {{'TemplateArgument::S5::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S5' in module 'SecondModule'}}
1188// expected-note@second.h:* {{declaration of 'x' does not match}}
1189#endif
1190
1191#if defined(FIRST)
1192template <class T> struct U6 {};
1193struct S6 {
1194 U6<int> x;
1195 U6<short> y;
1196};
1197#elif defined(SECOND)
1198template <class T> struct U6 {};
1199struct S6 {
1200 U6<short> y;
1201 U6<int> x;
1202};
1203#else
1204S6 s6;
1205// expected-error@second.h:* {{'TemplateArgument::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}}
1206// expected-note@first.h:* {{but in 'FirstModule' found field 'x'}}
1207#endif
Richard Trieud9201d02017-06-15 01:35:06 +00001208}
Richard Trieuee132d62017-06-14 03:17:26 +00001209
Richard Trieud9201d02017-06-15 01:35:06 +00001210namespace TemplateTypeParmType {
1211#if defined(FIRST)
1212template <class T1, class T2>
1213struct S1 {
1214 T1 x;
1215};
1216#elif defined(SECOND)
1217template <class T1, class T2>
1218struct S1 {
1219 T2 x;
1220};
1221#else
1222using TemplateTypeParmType::S1;
1223// expected-error@first.h:* {{'TemplateTypeParmType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T1, T2>' in module 'SecondModule'}}
1224// expected-note@second.h:* {{declaration of 'x' does not match}}
1225#endif
1226
1227#if defined(FIRST)
1228template <int ...Ts>
1229struct U2 {};
1230template <int T, int U>
1231class S2 {
1232 typedef U2<U, T> type;
1233 type x;
1234};
1235#elif defined(SECOND)
1236template <int ...Ts>
1237struct U2 {};
1238template <int T, int U>
1239class S2 {
1240 typedef U2<T, U> type;
1241 type x;
1242};
1243#else
1244using TemplateTypeParmType::S2;
1245// expected-error@first.h:* {{'TemplateTypeParmType::S2::x' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}}
1246// expected-note@second.h:* {{declaration of 'x' does not match}}
1247// expected-error@first.h:* {{'TemplateTypeParmType::S2::type' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}}
1248// expected-note@second.h:* {{declaration of 'type' does not match}}
1249#endif
Richard Trieu3b261bb72017-06-13 22:21:18 +00001250}
1251
Richard Trieu6e13ff32017-06-16 02:44:29 +00001252namespace VarDecl {
1253#if defined(FIRST)
1254struct S1 {
1255 static int x;
1256 static int y;
1257};
1258#elif defined(SECOND)
1259struct S1 {
1260 static int y;
1261 static int x;
1262};
1263#else
1264S1 s1;
1265// 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'}}
1266// expected-note@first.h:* {{but in 'FirstModule' found data member with name 'x'}}
1267#endif
1268
1269#if defined(FIRST)
1270struct S2 {
1271 static int x;
1272};
1273#elif defined(SECOND)
1274using I = int;
1275struct S2 {
1276 static I x;
1277};
1278#else
1279S2 s2;
1280// 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')}}
1281// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' with different type 'int'}}
1282#endif
1283
1284#if defined(FIRST)
1285struct S3 {
1286 static const int x = 1;
1287};
1288#elif defined(SECOND)
1289struct S3 {
1290 static const int x;
1291};
1292#else
1293S3 s3;
1294// 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}}
1295// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' without an initializer}}
1296#endif
1297
1298#if defined(FIRST)
1299struct S4 {
1300 static const int x = 1;
1301};
1302#elif defined(SECOND)
1303struct S4 {
1304 static const int x = 2;
1305};
1306#else
1307S4 s4;
1308// 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}}
1309// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' with a different initializer}}
1310#endif
1311
1312#if defined(FIRST)
1313struct S5 {
1314 static const int x = 1;
1315};
1316#elif defined(SECOND)
1317struct S5 {
1318 static constexpr int x = 1;
1319};
1320#else
1321S5 s5;
1322// 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}}
1323// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' is constexpr}}
1324#endif
1325
1326#if defined(FIRST)
1327struct S6 {
1328 static const int x = 1;
1329};
1330#elif defined(SECOND)
1331struct S6 {
1332 static const int y = 1;
1333};
1334#else
1335S6 s6;
1336// expected-error@first.h:* {{'VarDecl::S6::x' from module 'FirstModule' is not present in definition of 'VarDecl::S6' in module 'SecondModule'}}
1337// expected-note@second.h:* {{definition has no member 'x'}}
1338#endif
1339
1340#if defined(FIRST)
1341struct S7 {
1342 static const int x = 1;
1343};
1344#elif defined(SECOND)
1345struct S7 {
1346 static const unsigned x = 1;
1347};
1348#else
1349S7 s7;
1350// expected-error@first.h:* {{'VarDecl::S7::x' from module 'FirstModule' is not present in definition of 'VarDecl::S7' in module 'SecondModule'}}
1351// expected-note@second.h:* {{declaration of 'x' does not match}}
1352#endif
1353
1354#if defined(FIRST)
1355struct S8 {
1356public:
1357 static const int x = 1;
1358};
1359#elif defined(SECOND)
1360struct S8 {
1361 static const int x = 1;
1362public:
1363};
1364#else
1365S8 s8;
1366// expected-error@second.h:* {{'VarDecl::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member}}
1367// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
1368#endif
1369
1370#if defined(FIRST)
1371struct S9 {
1372 static const int x = 1;
1373};
1374#elif defined(SECOND)
1375struct S9 {
1376 static int x;
1377};
1378#else
1379S9 s9;
1380// expected-error@first.h:* {{'VarDecl::S9::x' from module 'FirstModule' is not present in definition of 'VarDecl::S9' in module 'SecondModule'}}
1381// expected-note@second.h:* {{declaration of 'x' does not match}}
1382#endif
1383
1384#if defined(FIRST)
1385template <typename T>
1386struct S {
1387 struct R {
1388 void foo(T x = 0) {}
1389 };
1390};
1391#elif defined(SECOND)
1392template <typename T>
1393struct S {
1394 struct R {
1395 void foo(T x = 1) {}
1396 };
1397};
1398#else
1399void run() {
1400 S<int>::R().foo();
1401}
1402// 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}}
1403// expected-note@first.h:* {{but in 'FirstModule' found method 'foo' with 1st parameter with a different default argument}}
1404#endif
1405
1406#if defined(FIRST)
1407template <typename alpha> struct Bravo {
1408 void charlie(bool delta = false) {}
1409};
1410typedef Bravo<char> echo;
1411echo foxtrot;
1412#elif defined(SECOND)
1413template <typename alpha> struct Bravo {
1414 void charlie(bool delta = (false)) {}
1415};
1416typedef Bravo<char> echo;
1417echo foxtrot;
1418#else
1419Bravo<char> golf;
1420// 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}}
1421// expected-note@first.h:* {{but in 'FirstModule' found method 'charlie' with 1st parameter with a different default argument}}
1422#endif
1423}
1424
Richard Trieuac6a1b62017-07-08 02:04:42 +00001425namespace Friend {
1426#if defined(FIRST)
1427struct T1 {};
1428struct S1 {
1429 friend class T1;
1430};
1431#elif defined(SECOND)
1432struct T1 {};
1433struct S1 {
1434 friend T1;
1435};
1436#else
1437S1 s1;
1438// expected-error@second.h:* {{'Friend::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend 'Friend::T1'}}
1439// expected-note@first.h:* {{but in 'FirstModule' found friend 'class T1'}}
1440#endif
1441
1442#if defined(FIRST)
1443struct T2 {};
1444struct S2 {
1445 friend class T2;
1446};
1447#elif defined(SECOND)
1448struct T2 {};
1449struct S2 {
1450 friend struct T2;
1451};
1452#else
1453S2 s2;
1454// expected-error@second.h:* {{'Friend::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend 'struct T2'}}
1455// expected-note@first.h:* {{but in 'FirstModule' found friend 'class T2'}}
1456#endif
1457
1458#if defined(FIRST)
1459struct T3 {};
1460struct S3 {
1461 friend const T3;
1462};
1463#elif defined(SECOND)
1464struct T3 {};
1465struct S3 {
1466 friend T3;
1467};
1468#else
1469S3 s3;
1470// expected-error@second.h:* {{'Friend::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend 'Friend::T3'}}
1471// expected-note@first.h:* {{but in 'FirstModule' found friend 'const Friend::T3'}}
1472#endif
1473
1474#if defined(FIRST)
1475struct T4 {};
1476struct S4 {
1477 friend T4;
1478};
1479#elif defined(SECOND)
1480struct S4 {
1481 friend void T4();
1482};
1483#else
1484S4 s4;
1485// expected-error@second.h:* {{'Friend::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend function}}
1486// expected-note@first.h:* {{but in 'FirstModule' found friend class}}
1487#endif
1488
1489#if defined(FIRST)
1490struct S5 {
1491 friend void T5a();
1492};
1493#elif defined(SECOND)
1494struct S5 {
1495 friend void T5b();
1496};
1497#else
1498S5 s5;
1499// expected-error@second.h:* {{'Friend::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend function 'T5b'}}
1500// expected-note@first.h:* {{but in 'FirstModule' found friend function 'T5a'}}
1501#endif
1502}
Richard Trieu498117b2017-08-23 02:43:59 +00001503
1504namespace TemplateParameters {
1505#if defined(FIRST)
1506template <class A>
1507struct S1 {};
1508#elif defined(SECOND)
1509template <class B>
1510struct S1 {};
1511#else
1512using TemplateParameters::S1;
1513// expected-error@second.h:* {{'TemplateParameters::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter 'B'}}
1514// expected-note@first.h:* {{but in 'FirstModule' found template parameter 'A'}}
1515#endif
1516
1517#if defined(FIRST)
1518template <class A = double>
1519struct S2 {};
1520#elif defined(SECOND)
1521template <class A = int>
1522struct S2 {};
1523#else
1524using TemplateParameters::S2;
1525// expected-error@second.h:* {{'TemplateParameters::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with default argument}}
1526// expected-note@first.h:* {{but in 'FirstModule' found template parameter with different default argument}}
1527#endif
1528
1529#if defined(FIRST)
1530template <class A = int>
1531struct S3 {};
1532#elif defined(SECOND)
1533template <class A>
1534struct S3 {};
1535#else
1536using TemplateParameters::S3;
1537// expected-error@second.h:* {{'TemplateParameters::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with no default argument}}
1538// expected-note@first.h:* {{but in 'FirstModule' found template parameter with default argument}}
1539#endif
1540
1541#if defined(FIRST)
1542template <int A>
1543struct S4 {};
1544#elif defined(SECOND)
1545template <int A = 2>
1546struct S4 {};
1547#else
1548using TemplateParameters::S4;
1549// expected-error@second.h:* {{'TemplateParameters::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with default argument}}
1550// expected-note@first.h:* {{but in 'FirstModule' found template parameter with no default argument}}
1551#endif
1552
1553#if defined(FIRST)
1554template <int> class S5_first {};
1555template <template<int> class A = S5_first>
1556struct S5 {};
1557#elif defined(SECOND)
1558template <int> class S5_second {};
1559template <template<int> class A = S5_second>
1560struct S5 {};
1561#else
1562using TemplateParameters::S5;
1563// expected-error@second.h:* {{'TemplateParameters::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found template parameter with default argument}}
1564// expected-note@first.h:* {{but in 'FirstModule' found template parameter with different default argument}}
1565#endif
1566
1567#if defined(FIRST)
1568template <class A>
1569struct S6 {};
1570#elif defined(SECOND)
1571template <class>
1572struct S6 {};
1573#else
1574using TemplateParameters::S6;
1575// expected-error@second.h:* {{'TemplateParameters::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found unnamed template parameter}}
1576// expected-note@first.h:* {{but in 'FirstModule' found template parameter 'A'}}
1577#endif
1578} // namespace TemplateParameters
1579
Richard Trieue13eabe2017-09-30 02:19:17 +00001580namespace BaseClass {
1581#if defined(FIRST)
1582struct B1 {};
1583struct S1 : B1 {};
1584#elif defined(SECOND)
1585struct S1 {};
1586#else
1587S1 s1;
1588// expected-error@second.h:* {{'BaseClass::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found 0 base classes}}
1589// expected-note@first.h:* {{but in 'FirstModule' found 1 base class}}
1590#endif
1591
1592#if defined(FIRST)
1593struct S2 {};
1594#elif defined(SECOND)
1595struct B2 {};
1596struct S2 : virtual B2 {};
1597#else
1598S2 s2;
1599// expected-error@second.h:* {{'BaseClass::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1 base class}}
1600// expected-note@first.h:* {{but in 'FirstModule' found 0 base classes}}
1601#endif
1602
1603#if defined(FIRST)
1604struct B3a {};
1605struct S3 : B3a {};
1606#elif defined(SECOND)
1607struct B3b {};
1608struct S3 : virtual B3b {};
1609#else
1610S3 s3;
1611// expected-error@second.h:* {{'BaseClass::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1 virtual base class}}
1612// expected-note@first.h:* {{but in 'FirstModule' found 0 virtual base classes}}
1613#endif
1614
1615#if defined(FIRST)
1616struct B4a {};
1617struct S4 : B4a {};
1618#elif defined(SECOND)
1619struct B4b {};
1620struct S4 : B4b {};
1621#else
1622S4 s4;
1623// expected-error@second.h:* {{'BaseClass::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class with type 'BaseClass::B4b'}}
1624// expected-note@first.h:* {{but in 'FirstModule' found 1st base class with different type 'BaseClass::B4a'}}
1625#endif
1626
1627#if defined(FIRST)
1628struct B5a {};
1629struct S5 : virtual B5a {};
1630#elif defined(SECOND)
1631struct B5a {};
1632struct S5 : B5a {};
1633#else
1634S5 s5;
1635// expected-error@second.h:* {{'BaseClass::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found 0 virtual base classes}}
1636// expected-note@first.h:* {{but in 'FirstModule' found 1 virtual base class}}
1637#endif
1638
1639#if defined(FIRST)
1640struct B6a {};
1641struct S6 : B6a {};
1642#elif defined(SECOND)
1643struct B6a {};
1644struct S6 : virtual B6a {};
1645#else
1646S6 s6;
1647// expected-error@second.h:* {{'BaseClass::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1 virtual base class}}
1648// expected-note@first.h:* {{but in 'FirstModule' found 0 virtual base classes}}
1649#endif
1650
1651#if defined(FIRST)
1652struct B7a {};
1653struct S7 : protected B7a {};
1654#elif defined(SECOND)
1655struct B7a {};
1656struct S7 : B7a {};
1657#else
1658S7 s7;
1659// expected-error@second.h:* {{'BaseClass::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'BaseClass::B7a' with no access specifier}}
1660// expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'BaseClass::B7a' with protected access specifier}}
1661#endif
1662
1663#if defined(FIRST)
1664struct B8a {};
1665struct S8 : public B8a {};
1666#elif defined(SECOND)
1667struct B8a {};
1668struct S8 : private B8a {};
1669#else
1670S8 s8;
1671// expected-error@second.h:* {{'BaseClass::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'BaseClass::B8a' with private access specifier}}
1672// expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'BaseClass::B8a' with public access specifier}}
1673#endif
1674
1675#if defined(FIRST)
1676struct B9a {};
1677struct S9 : private B9a {};
1678#elif defined(SECOND)
1679struct B9a {};
1680struct S9 : public B9a {};
1681#else
1682S9 s9;
1683// expected-error@second.h:* {{'BaseClass::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'BaseClass::B9a' with public access specifier}}
1684// expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'BaseClass::B9a' with private access specifier}}
1685#endif
1686
1687#if defined(FIRST)
1688struct B10a {};
1689struct S10 : B10a {};
1690#elif defined(SECOND)
1691struct B10a {};
1692struct S10 : protected B10a {};
1693#else
1694S10 s10;
1695// expected-error@second.h:* {{'BaseClass::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'BaseClass::B10a' with protected access specifier}}
1696// expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'BaseClass::B10a' with no access specifier}}
1697#endif
1698} // namespace BaseClass
1699
Richard Trieue7f7ed22017-02-22 01:11:25 +00001700// Interesting cases that should not cause errors. struct S should not error
1701// while struct T should error at the access specifier mismatch at the end.
1702namespace AllDecls {
Richard Trieu02552272017-05-02 23:58:52 +00001703#define CREATE_ALL_DECL_STRUCT(NAME, ACCESS) \
1704 typedef int INT; \
1705 struct NAME { \
1706 public: \
1707 private: \
1708 protected: \
1709 static_assert(1 == 1, "Message"); \
1710 static_assert(2 == 2); \
1711 \
1712 int x; \
1713 double y; \
1714 \
1715 INT z; \
1716 \
1717 unsigned a : 1; \
1718 unsigned b : 2 * 2 + 5 / 2; \
1719 \
1720 mutable int c = sizeof(x + y); \
1721 \
1722 void method() {} \
1723 static void static_method() {} \
1724 virtual void virtual_method() {} \
1725 virtual void pure_virtual_method() = 0; \
1726 inline void inline_method() {} \
1727 void volatile_method() volatile {} \
1728 void const_method() const {} \
1729 \
1730 typedef int typedef_int; \
1731 using using_int = int; \
1732 \
1733 void method_one_arg(int x) {} \
1734 void method_one_arg_default_argument(int x = 5 + 5) {} \
1735 void method_decayed_type(int x[5]) {} \
1736 \
1737 int constant_arr[5]; \
1738 \
1739 ACCESS: \
Richard Trieufe564052017-04-20 02:53:53 +00001740 };
1741
Richard Trieue7f7ed22017-02-22 01:11:25 +00001742#if defined(FIRST)
Richard Trieufe564052017-04-20 02:53:53 +00001743CREATE_ALL_DECL_STRUCT(S, public)
Richard Trieue7f7ed22017-02-22 01:11:25 +00001744#elif defined(SECOND)
Richard Trieufe564052017-04-20 02:53:53 +00001745CREATE_ALL_DECL_STRUCT(S, public)
Richard Trieue7f7ed22017-02-22 01:11:25 +00001746#else
Richard Trieu583e2c12017-03-04 00:08:58 +00001747S *s;
Richard Trieue7f7ed22017-02-22 01:11:25 +00001748#endif
1749
1750#if defined(FIRST)
Richard Trieufe564052017-04-20 02:53:53 +00001751CREATE_ALL_DECL_STRUCT(T, private)
Richard Trieue7f7ed22017-02-22 01:11:25 +00001752#elif defined(SECOND)
Richard Trieufe564052017-04-20 02:53:53 +00001753CREATE_ALL_DECL_STRUCT(T, public)
Richard Trieue7f7ed22017-02-22 01:11:25 +00001754#else
Richard Trieu583e2c12017-03-04 00:08:58 +00001755T *t;
Richard Trieue7f7ed22017-02-22 01:11:25 +00001756// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
1757// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
1758#endif
1759}
1760
1761namespace FriendFunction {
1762#if defined(FIRST)
1763void F(int = 0);
1764struct S { friend void F(int); };
1765#elif defined(SECOND)
1766void F(int);
1767struct S { friend void F(int); };
1768#else
1769S s;
1770#endif
1771
1772#if defined(FIRST)
1773void G(int = 0);
1774struct T {
1775 friend void G(int);
1776
1777 private:
1778};
1779#elif defined(SECOND)
1780void G(int);
1781struct T {
1782 friend void G(int);
1783
1784 public:
1785};
1786#else
1787T t;
1788// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
1789// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
1790#endif
1791} // namespace FriendFunction
1792
1793namespace ImplicitDecl {
1794#if defined(FIRST)
1795struct S { };
1796void S_Constructors() {
1797 // Trigger creation of implicit contructors
1798 S foo;
1799 S bar = foo;
1800 S baz(bar);
1801}
1802#elif defined(SECOND)
1803struct S { };
1804#else
1805S s;
1806#endif
1807
1808#if defined(FIRST)
1809struct T {
1810 private:
1811};
1812void T_Constructors() {
1813 // Trigger creation of implicit contructors
1814 T foo;
1815 T bar = foo;
1816 T baz(bar);
1817}
1818#elif defined(SECOND)
1819struct T {
1820 public:
1821};
1822#else
1823T t;
1824// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}
1825// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
1826#endif
1827
1828} // namespace ImplicitDelc
1829
1830namespace TemplatedClass {
1831#if defined(FIRST)
1832template <class>
1833struct S {};
1834#elif defined(SECOND)
1835template <class>
1836struct S {};
1837#else
1838S<int> s;
1839#endif
1840
1841#if defined(FIRST)
1842template <class>
1843struct T {
1844 private:
1845};
1846#elif defined(SECOND)
1847template <class>
1848struct T {
1849 public:
1850};
1851#else
1852T<int> t;
1853// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
1854// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
1855#endif
1856} // namespace TemplatedClass
1857
1858namespace TemplateClassWithField {
1859#if defined(FIRST)
1860template <class A>
1861struct S {
1862 A a;
1863};
1864#elif defined(SECOND)
1865template <class A>
1866struct S {
1867 A a;
1868};
1869#else
1870S<int> s;
1871#endif
1872
1873#if defined(FIRST)
1874template <class A>
1875struct T {
1876 A a;
1877
1878 private:
1879};
1880#elif defined(SECOND)
1881template <class A>
1882struct T {
1883 A a;
1884
1885 public:
1886};
1887#else
1888T<int> t;
1889// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
1890// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
1891#endif
1892} // namespace TemplateClassWithField
1893
1894namespace TemplateClassWithTemplateField {
1895#if defined(FIRST)
1896template <class A>
1897class WrapperS;
1898template <class A>
1899struct S {
1900 WrapperS<A> a;
1901};
1902#elif defined(SECOND)
1903template <class A>
1904class WrapperS;
1905template <class A>
1906struct S {
1907 WrapperS<A> a;
1908};
1909#else
1910template <class A>
1911class WrapperS{};
1912S<int> s;
1913#endif
1914
1915#if defined(FIRST)
1916template <class A>
1917class WrapperT;
1918template <class A>
1919struct T {
1920 WrapperT<A> a;
1921
1922 public:
1923};
1924#elif defined(SECOND)
1925template <class A>
1926class WrapperT;
1927template <class A>
1928struct T {
1929 WrapperT<A> a;
1930
1931 private:
1932};
1933#else
1934template <class A>
1935class WrapperT{};
1936T<int> t;
1937// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
1938// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
1939#endif
1940} // namespace TemplateClassWithTemplateField
1941
1942namespace EnumWithForwardDeclaration {
1943#if defined(FIRST)
1944enum E : int;
1945struct S {
1946 void get(E) {}
1947};
1948#elif defined(SECOND)
1949enum E : int { A, B };
1950struct S {
1951 void get(E) {}
1952};
1953#else
1954S s;
1955#endif
1956
1957#if defined(FIRST)
1958struct T {
1959 void get(E) {}
1960 public:
1961};
1962#elif defined(SECOND)
1963struct T {
1964 void get(E) {}
1965 private:
1966};
1967#else
1968T t;
1969// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
1970// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
1971#endif
1972} // namespace EnumWithForwardDeclaration
1973
1974namespace StructWithForwardDeclaration {
1975#if defined(FIRST)
1976struct P {};
1977struct S {
1978 struct P *ptr;
1979};
1980#elif defined(SECOND)
1981struct S {
1982 struct P *ptr;
1983};
1984#else
1985S s;
1986#endif
1987
1988#if defined(FIRST)
1989struct Q {};
1990struct T {
1991 struct Q *ptr;
1992 public:
1993};
1994#elif defined(SECOND)
1995struct T {
1996 struct Q *ptr;
1997 private:
1998};
1999#else
2000T t;
2001// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
2002// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
2003#endif
2004} // namespace StructWithForwardDeclaration
2005
2006namespace StructWithForwardDeclarationNoDefinition {
2007#if defined(FIRST)
2008struct P;
2009struct S {
2010 struct P *ptr;
2011};
2012#elif defined(SECOND)
2013struct S {
2014 struct P *ptr;
2015};
2016#else
2017S s;
2018#endif
2019
2020#if defined(FIRST)
2021struct Q;
2022struct T {
2023 struct Q *ptr;
2024
2025 public:
2026};
2027#elif defined(SECOND)
2028struct T {
2029 struct Q *ptr;
2030
2031 private:
2032};
2033#else
2034T t;
2035// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
2036// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
2037#endif
2038} // namespace StructWithForwardDeclarationNoDefinition
2039
Richard Trieufe564052017-04-20 02:53:53 +00002040namespace LateParsedDefaultArgument {
2041#if defined(FIRST)
2042template <typename T>
2043struct S {
2044 struct R {
2045 void foo(T x = 0) {}
2046 };
2047};
2048#elif defined(SECOND)
2049#else
2050void run() {
2051 S<int>::R().foo();
2052}
2053#endif
2054}
2055
2056namespace LateParsedDefaultArgument {
2057#if defined(FIRST)
2058template <typename alpha> struct Bravo {
2059 void charlie(bool delta = false) {}
2060};
2061typedef Bravo<char> echo;
2062echo foxtrot;
2063
2064Bravo<char> golf;
2065#elif defined(SECOND)
2066#else
2067#endif
2068}
2069
Richard Trieu157ed942017-04-28 22:03:28 +00002070namespace DifferentParameterNameInTemplate {
2071#if defined(FIRST) || defined(SECOND)
2072template <typename T>
2073struct S {
2074 typedef T Type;
2075
2076 static void Run(const Type *name_one);
2077};
2078
2079template <typename T>
2080void S<T>::Run(const T *name_two) {}
2081
2082template <typename T>
2083struct Foo {
2084 ~Foo() { Handler::Run(nullptr); }
2085 Foo() {}
2086
2087 class Handler : public S<T> {};
2088
2089 void Get(typename Handler::Type *x = nullptr) {}
2090 void Add() { Handler::Run(nullptr); }
2091};
2092#endif
2093
2094#if defined(FIRST)
2095struct Beta;
2096
2097struct Alpha {
2098 Alpha();
2099 void Go() { betas.Get(); }
2100 Foo<Beta> betas;
2101};
2102
2103#elif defined(SECOND)
2104struct Beta {};
2105
2106struct BetaHelper {
2107 void add_Beta() { betas.Add(); }
2108 Foo<Beta> betas;
2109};
2110
2111#else
2112Alpha::Alpha() {}
2113#endif
2114}
2115
Richard Trieu02552272017-05-02 23:58:52 +00002116namespace ParameterTest {
2117#if defined(FIRST)
2118class X {};
2119template <typename G>
2120class S {
2121 public:
2122 typedef G Type;
2123 static inline G *Foo(const G *a, int * = nullptr);
2124};
2125
2126template<typename G>
2127G* S<G>::Foo(const G* aaaa, int*) {}
2128#elif defined(SECOND)
2129template <typename G>
2130class S {
2131 public:
2132 typedef G Type;
2133 static inline G *Foo(const G *a, int * = nullptr);
2134};
2135
2136template<typename G>
2137G* S<G>::Foo(const G* asdf, int*) {}
2138#else
2139S<X> s;
2140#endif
2141}
2142
Richard Trieub35ef2a2017-05-09 03:24:34 +00002143namespace MultipleTypedefs {
2144#if defined(FIRST)
2145typedef int B1;
2146typedef B1 A1;
2147struct S1 {
2148 A1 x;
2149};
2150#elif defined(SECOND)
2151typedef int A1;
2152struct S1 {
2153 A1 x;
2154};
2155#else
2156S1 s1;
2157#endif
2158
2159#if defined(FIRST)
2160struct T2 { int x; };
2161typedef T2 B2;
2162typedef B2 A2;
2163struct S2 {
2164 T2 x;
2165};
2166#elif defined(SECOND)
2167struct T2 { int x; };
2168typedef T2 A2;
2169struct S2 {
2170 T2 x;
2171};
2172#else
2173S2 s2;
2174#endif
Richard Trieu3e03d3e2017-06-29 22:53:04 +00002175
2176#if defined(FIRST)
2177using A3 = const int;
2178using B3 = volatile A3;
2179struct S3 {
2180 B3 x = 1;
2181};
2182#elif defined(SECOND)
2183using A3 = volatile const int;
2184using B3 = A3;
2185struct S3 {
2186 B3 x = 1;
2187};
2188#else
2189S3 s3;
2190#endif
Richard Trieub35ef2a2017-05-09 03:24:34 +00002191}
Richard Trieu02552272017-05-02 23:58:52 +00002192
Richard Trieue7f7ed22017-02-22 01:11:25 +00002193// Keep macros contained to one file.
2194#ifdef FIRST
2195#undef FIRST
2196#endif
2197#ifdef SECOND
2198#undef SECOND
2199#endif