blob: 28b05a53564454ead5c1a652ceebb711439eaeec [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;
489// TODO: This should produce an error.
490#endif
491
492#if defined(FIRST)
493struct S13 {
494 void A(int x = 1 + 0) {}
495};
496#elif defined(SECOND)
497struct S13 {
498 void A(int x = 1) {}
499};
500#else
501S13 s13;
502// TODO: This should produce an error.
503#endif
504
505#if defined(FIRST)
506struct S14 {
507 void A(int x[2]) {}
508};
509#elif defined(SECOND)
510struct S14 {
511 void A(int x[3]) {}
512};
513#else
514S14 s14;
515// 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]'}}
516// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter of type 'int *' decayed from 'int [2]'}}
517#endif
Richard Trieu48143742017-02-28 21:24:38 +0000518} // namespace Method
519
Richard Trieue7f7ed22017-02-22 01:11:25 +0000520// Naive parsing of AST can lead to cycles in processing. Ensure
521// self-references don't trigger an endless cycles of AST node processing.
522namespace SelfReference {
523#if defined(FIRST)
524template <template <int> class T> class Wrapper {};
525
526template <int N> class S {
527 S(Wrapper<::SelfReference::S> &Ref) {}
528};
529
530struct Xx {
531 struct Yy {
532 };
533};
534
535Xx::Xx::Xx::Yy yy;
536
537namespace NNS {
538template <typename> struct Foo;
539template <template <class> class T = NNS::Foo>
540struct NestedNamespaceSpecifier {};
541}
542#endif
543} // namespace SelfReference
544
Richard Trieu33562c22017-03-08 00:13:19 +0000545namespace TypeDef {
546#if defined(FIRST)
547struct S1 {
548 typedef int a;
549};
550#elif defined(SECOND)
551struct S1 {
552 typedef double a;
553};
554#else
555S1 s1;
556// expected-error@first.h:* {{'TypeDef::S1::a' from module 'FirstModule' is not present in definition of 'TypeDef::S1' in module 'SecondModule'}}
557// expected-note@second.h:* {{declaration of 'a' does not match}}
558#endif
559
560#if defined(FIRST)
561struct S2 {
562 typedef int a;
563};
564#elif defined(SECOND)
565struct S2 {
566 typedef int b;
567};
568#else
569S2 s2;
570// expected-error@first.h:* {{'TypeDef::S2::a' from module 'FirstModule' is not present in definition of 'TypeDef::S2' in module 'SecondModule'}}
571// expected-note@second.h:* {{definition has no member 'a'}}
572#endif
573
574#if defined(FIRST)
575typedef int T;
576struct S3 {
577 typedef T a;
578};
579#elif defined(SECOND)
580typedef double T;
581struct S3 {
582 typedef T a;
583};
584#else
585S3 s3;
586// expected-error@first.h:* {{'TypeDef::S3::a' from module 'FirstModule' is not present in definition of 'TypeDef::S3' in module 'SecondModule'}}
587// expected-note@second.h:* {{declaration of 'a' does not match}}
588#endif
Richard Trieu11d566a2017-06-12 21:58:22 +0000589
590#if defined(FIRST)
591struct S4 {
592 typedef int a;
593 typedef int b;
594};
595#elif defined(SECOND)
596struct S4 {
597 typedef int b;
598 typedef int a;
599};
600#else
601S4 s4;
602// expected-error@second.h:* {{'TypeDef::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef name 'b'}}
603// expected-note@first.h:* {{but in 'FirstModule' found typedef name 'a'}}
604#endif
605
606#if defined(FIRST)
607struct S5 {
608 typedef int a;
609 typedef int b;
610 int x;
611};
612#elif defined(SECOND)
613struct S5 {
614 int x;
615 typedef int b;
616 typedef int a;
617};
618#else
619S5 s5;
620// expected-error@second.h:* {{'TypeDef::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
621// expected-note@first.h:* {{but in 'FirstModule' found typedef}}
622#endif
623
624#if defined(FIRST)
625typedef float F;
626struct S6 {
627 typedef int a;
628 typedef F b;
629};
630#elif defined(SECOND)
631struct S6 {
632 typedef int a;
633 typedef float b;
634};
635#else
636S6 s6;
637// 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'}}
638// expected-note@first.h:* {{but in 'FirstModule' found typedef 'b' with different underlying type 'TypeDef::F' (aka 'float')}}
639#endif
Richard Trieu33562c22017-03-08 00:13:19 +0000640} // namespace TypeDef
641
642namespace Using {
643#if defined(FIRST)
644struct S1 {
645 using a = int;
646};
647#elif defined(SECOND)
648struct S1 {
649 using a = double;
650};
651#else
652S1 s1;
653// expected-error@first.h:* {{'Using::S1::a' from module 'FirstModule' is not present in definition of 'Using::S1' in module 'SecondModule'}}
654// expected-note@second.h:* {{declaration of 'a' does not match}}
655#endif
656
657#if defined(FIRST)
658struct S2 {
659 using a = int;
660};
661#elif defined(SECOND)
662struct S2 {
663 using b = int;
664};
665#else
666S2 s2;
667// expected-error@first.h:* {{'Using::S2::a' from module 'FirstModule' is not present in definition of 'Using::S2' in module 'SecondModule'}}
668// expected-note@second.h:* {{definition has no member 'a'}}
669#endif
670
671#if defined(FIRST)
672typedef int T;
673struct S3 {
674 using a = T;
675};
676#elif defined(SECOND)
677typedef double T;
678struct S3 {
679 using a = T;
680};
681#else
682S3 s3;
683// expected-error@first.h:* {{'Using::S3::a' from module 'FirstModule' is not present in definition of 'Using::S3' in module 'SecondModule'}}
684// expected-note@second.h:* {{declaration of 'a' does not match}}
685#endif
Richard Trieu11d566a2017-06-12 21:58:22 +0000686
687#if defined(FIRST)
688struct S4 {
689 using a = int;
690 using b = int;
691};
692#elif defined(SECOND)
693struct S4 {
694 using b = int;
695 using a = int;
696};
697#else
698S4 s4;
699// expected-error@second.h:* {{'Using::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias name 'b'}}
700// expected-note@first.h:* {{but in 'FirstModule' found type alias name 'a'}}
701#endif
702
703#if defined(FIRST)
704struct S5 {
705 using a = int;
706 using b = int;
707 int x;
708};
709#elif defined(SECOND)
710struct S5 {
711 int x;
712 using b = int;
713 using a = int;
714};
715#else
716S5 s5;
717// expected-error@second.h:* {{'Using::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
718// expected-note@first.h:* {{but in 'FirstModule' found type alias}}
719#endif
720
721#if defined(FIRST)
722typedef float F;
723struct S6 {
724 using a = int;
725 using b = F;
726};
727#elif defined(SECOND)
728struct S6 {
729 using a = int;
730 using b = float;
731};
732#else
733S6 s6;
734// 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'}}
735// expected-note@first.h:* {{but in 'FirstModule' found type alias 'b' with different underlying type 'Using::F' (aka 'float')}}
736#endif
Richard Trieu33562c22017-03-08 00:13:19 +0000737} // namespace Using
738
Richard Trieu58bb7bd2017-05-17 02:29:02 +0000739namespace RecordType {
740#if defined(FIRST)
741struct B1 {};
742struct S1 {
743 B1 x;
744};
745#elif defined(SECOND)
746struct A1 {};
747struct S1 {
748 A1 x;
749};
750#else
751S1 s1;
752// expected-error@first.h:* {{'RecordType::S1::x' from module 'FirstModule' is not present in definition of 'RecordType::S1' in module 'SecondModule'}}
753// expected-note@second.h:* {{declaration of 'x' does not match}}
754#endif
755}
756
757namespace DependentType {
758#if defined(FIRST)
759template <class T>
760class S1 {
761 typename T::typeA x;
762};
763#elif defined(SECOND)
764template <class T>
765class S1 {
766 typename T::typeB x;
767};
768#else
769template<class T>
770using U1 = S1<T>;
771// expected-error@first.h:* {{'DependentType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T>' in module 'SecondModule'}}
772// expected-note@second.h:* {{declaration of 'x' does not match}}
773#endif
774}
775
776namespace ElaboratedType {
777#if defined(FIRST)
778namespace N1 { using type = double; }
779struct S1 {
780 N1::type x;
781};
782#elif defined(SECOND)
783namespace N1 { using type = int; }
784struct S1 {
785 N1::type x;
786};
787#else
788S1 s1;
789// expected-error@first.h:* {{'ElaboratedType::S1::x' from module 'FirstModule' is not present in definition of 'ElaboratedType::S1' in module 'SecondModule'}}
790// expected-note@second.h:* {{declaration of 'x' does not match}}
791#endif
792}
793
794namespace Enum {
795#if defined(FIRST)
796enum A1 {};
797struct S1 {
798 A1 x;
799};
800#elif defined(SECOND)
801enum A2 {};
802struct S1 {
803 A2 x;
804};
805#else
806S1 s1;
807// expected-error@first.h:* {{'Enum::S1::x' from module 'FirstModule' is not present in definition of 'Enum::S1' in module 'SecondModule'}}
808// expected-note@second.h:* {{declaration of 'x' does not match}}
809#endif
810}
Hans Wennborg22707762017-04-12 16:40:26 +0000811
Richard Trieuce81b192017-05-17 03:23:35 +0000812namespace NestedNamespaceSpecifier {
813#if defined(FIRST)
814namespace LevelA1 {
815using Type = int;
816}
817
818struct S1 {
819 LevelA1::Type x;
820};
821# elif defined(SECOND)
822namespace LevelB1 {
823namespace LevelC1 {
824using Type = int;
825}
826}
827
828struct S1 {
829 LevelB1::LevelC1::Type x;
830};
831#else
832S1 s1;
833// 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')}}
834// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA1::Type' (aka 'int')}}
835#endif
836
837#if defined(FIRST)
838namespace LevelA2 { using Type = int; }
839struct S2 {
840 LevelA2::Type x;
841};
842# elif defined(SECOND)
843struct S2 {
844 int x;
845};
846#else
847S2 s2;
848// 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'}}
849// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA2::Type' (aka 'int')}}
850#endif
851
852namespace LevelA3 { using Type = int; }
853namespace LevelB3 { using Type = int; }
854#if defined(FIRST)
855struct S3 {
856 LevelA3::Type x;
857};
858# elif defined(SECOND)
859struct S3 {
860 LevelB3::Type x;
861};
862#else
863S3 s3;
864// 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')}}
865// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA3::Type' (aka 'int')}}
866#endif
867
868#if defined(FIRST)
869struct TA4 { using Type = int; };
870struct S4 {
871 TA4::Type x;
872};
873# elif defined(SECOND)
874struct TB4 { using Type = int; };
875struct S4 {
876 TB4::Type x;
877};
878#else
879S4 s4;
880// 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')}}
881// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'TA4::Type' (aka 'int')}}
882#endif
883
884#if defined(FIRST)
885struct T5 { using Type = int; };
886struct S5 {
887 T5::Type x;
888};
889# elif defined(SECOND)
890namespace T5 { using Type = int; };
891struct S5 {
892 T5::Type x;
893};
894#else
895S5 s5;
896// 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')}}
897// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'T5::Type' (aka 'int')}}
898#endif
899
900#if defined(FIRST)
901namespace N6 {using I = int;}
902struct S6 {
903 NestedNamespaceSpecifier::N6::I x;
904};
905# elif defined(SECOND)
906using I = int;
907struct S6 {
908 ::NestedNamespaceSpecifier::I x;
909};
910#else
911S6 s6;
912// 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')}}
913// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'NestedNamespaceSpecifier::N6::I' (aka 'int')}}
914#endif
915
916#if defined(FIRST)
917template <class T, class U>
918class S7 {
919 typename T::type *x = {};
920 int z = x->T::foo();
921};
922#elif defined(SECOND)
923template <class T, class U>
924class S7 {
925 typename T::type *x = {};
926 int z = x->U::foo();
927};
928#else
929template <class T, class U>
930using U7 = S7<T, U>;
931// 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}}
932// expected-note@first.h:* {{but in 'FirstModule' found field 'z' with a different initializer}}
933#endif
934
935#if defined(FIRST)
936template <class T>
937class S8 {
938 int x = T::template X<int>::value;
939};
940#elif defined(SECOND)
941template <class T>
942class S8 {
943 int x = T::template Y<int>::value;
944};
945#else
946template <class T>
947using U8 = S8<T>;
948// 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}}
949// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}}
950#endif
951
952#if defined(FIRST)
953namespace N9 { using I = int; }
954namespace O9 = N9;
955struct S9 {
956 O9::I x;
957};
958#elif defined(SECOND)
959namespace N9 { using I = int; }
960namespace P9 = N9;
961struct S9 {
962 P9::I x;
963};
964#else
965S9 s9;
966// 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')}}
967// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'O9::I' (aka 'int')}}
968#endif
969}
970
Richard Trieu96b49622017-05-31 00:31:58 +0000971namespace TemplateSpecializationType {
972#if defined(FIRST)
973template <class T1> struct U1 {};
974struct S1 {
975 U1<int> u;
976};
977#elif defined(SECOND)
978template <class T1, class T2> struct U1 {};
979struct S1 {
980 U1<int, int> u;
981};
982#else
983S1 s1;
984// expected-error@first.h:* {{'TemplateSpecializationType::S1::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S1' in module 'SecondModule'}}
985// expected-note@second.h:* {{declaration of 'u' does not match}}
986#endif
987
988#if defined(FIRST)
989template <class T1> struct U2 {};
990struct S2 {
991 U2<int> u;
992};
993#elif defined(SECOND)
994template <class T1> struct V1 {};
995struct S2 {
996 V1<int> u;
997};
998#else
999S2 s2;
1000// expected-error@first.h:* {{'TemplateSpecializationType::S2::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S2' in module 'SecondModule'}}
1001// expected-note@second.h:* {{declaration of 'u' does not match}}
1002#endif
1003}
1004
Richard Trieu3b261bb72017-06-13 22:21:18 +00001005namespace TemplateArgument {
1006#if defined(FIRST)
1007template <class> struct U1{};
1008struct S1 {
1009 U1<int> x;
1010};
1011#elif defined(SECOND)
1012template <int> struct U1{};
1013struct S1 {
1014 U1<1> x;
1015};
1016#else
1017S1 s1;
1018// expected-error@first.h:* {{'TemplateArgument::S1::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S1' in module 'SecondModule'}}
1019// expected-note@second.h:* {{declaration of 'x' does not match}}
1020#endif
Richard Trieu1dcb4052017-06-14 01:28:00 +00001021
1022#if defined(FIRST)
1023template <int> struct U2{};
1024struct S2 {
1025 using T = U2<2>;
1026};
1027#elif defined(SECOND)
1028template <int> struct U2{};
1029struct S2 {
1030 using T = U2<(2)>;
1031};
1032#else
1033S2 s2;
1034// 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)>'}}
1035// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U2<2>'}}
1036#endif
1037
1038#if defined(FIRST)
1039template <int> struct U3{};
1040struct S3 {
1041 using T = U3<2>;
1042};
1043#elif defined(SECOND)
1044template <int> struct U3{};
1045struct S3 {
1046 using T = U3<1 + 1>;
1047};
1048#else
1049S3 s3;
1050// 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>'}}
1051// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U3<2>'}}
1052#endif
1053
Richard Trieuee132d62017-06-14 03:17:26 +00001054#if defined(FIRST)
1055template<class> struct T4a {};
1056template <template <class> class T> struct U4 {};
1057struct S4 {
1058 U4<T4a> x;
1059};
1060#elif defined(SECOND)
1061template<class> struct T4b {};
1062template <template <class> class T> struct U4 {};
1063struct S4 {
1064 U4<T4b> x;
1065};
1066#else
1067S4 s4;
1068// expected-error@first.h:* {{'TemplateArgument::S4::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S4' in module 'SecondModule'}}
1069// expected-note@second.h:* {{declaration of 'x' does not match}}
1070#endif
Richard Trieud9201d02017-06-15 01:35:06 +00001071}
Richard Trieuee132d62017-06-14 03:17:26 +00001072
Richard Trieud9201d02017-06-15 01:35:06 +00001073namespace TemplateTypeParmType {
1074#if defined(FIRST)
1075template <class T1, class T2>
1076struct S1 {
1077 T1 x;
1078};
1079#elif defined(SECOND)
1080template <class T1, class T2>
1081struct S1 {
1082 T2 x;
1083};
1084#else
1085using TemplateTypeParmType::S1;
1086// expected-error@first.h:* {{'TemplateTypeParmType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T1, T2>' in module 'SecondModule'}}
1087// expected-note@second.h:* {{declaration of 'x' does not match}}
1088#endif
1089
1090#if defined(FIRST)
1091template <int ...Ts>
1092struct U2 {};
1093template <int T, int U>
1094class S2 {
1095 typedef U2<U, T> type;
1096 type x;
1097};
1098#elif defined(SECOND)
1099template <int ...Ts>
1100struct U2 {};
1101template <int T, int U>
1102class S2 {
1103 typedef U2<T, U> type;
1104 type x;
1105};
1106#else
1107using TemplateTypeParmType::S2;
1108// expected-error@first.h:* {{'TemplateTypeParmType::S2::x' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}}
1109// expected-note@second.h:* {{declaration of 'x' does not match}}
1110// expected-error@first.h:* {{'TemplateTypeParmType::S2::type' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}}
1111// expected-note@second.h:* {{declaration of 'type' does not match}}
1112#endif
Richard Trieu3b261bb72017-06-13 22:21:18 +00001113}
1114
Richard Trieue7f7ed22017-02-22 01:11:25 +00001115// Interesting cases that should not cause errors. struct S should not error
1116// while struct T should error at the access specifier mismatch at the end.
1117namespace AllDecls {
Richard Trieu02552272017-05-02 23:58:52 +00001118#define CREATE_ALL_DECL_STRUCT(NAME, ACCESS) \
1119 typedef int INT; \
1120 struct NAME { \
1121 public: \
1122 private: \
1123 protected: \
1124 static_assert(1 == 1, "Message"); \
1125 static_assert(2 == 2); \
1126 \
1127 int x; \
1128 double y; \
1129 \
1130 INT z; \
1131 \
1132 unsigned a : 1; \
1133 unsigned b : 2 * 2 + 5 / 2; \
1134 \
1135 mutable int c = sizeof(x + y); \
1136 \
1137 void method() {} \
1138 static void static_method() {} \
1139 virtual void virtual_method() {} \
1140 virtual void pure_virtual_method() = 0; \
1141 inline void inline_method() {} \
1142 void volatile_method() volatile {} \
1143 void const_method() const {} \
1144 \
1145 typedef int typedef_int; \
1146 using using_int = int; \
1147 \
1148 void method_one_arg(int x) {} \
1149 void method_one_arg_default_argument(int x = 5 + 5) {} \
1150 void method_decayed_type(int x[5]) {} \
1151 \
1152 int constant_arr[5]; \
1153 \
1154 ACCESS: \
Richard Trieufe564052017-04-20 02:53:53 +00001155 };
1156
Richard Trieue7f7ed22017-02-22 01:11:25 +00001157#if defined(FIRST)
Richard Trieufe564052017-04-20 02:53:53 +00001158CREATE_ALL_DECL_STRUCT(S, public)
Richard Trieue7f7ed22017-02-22 01:11:25 +00001159#elif defined(SECOND)
Richard Trieufe564052017-04-20 02:53:53 +00001160CREATE_ALL_DECL_STRUCT(S, public)
Richard Trieue7f7ed22017-02-22 01:11:25 +00001161#else
Richard Trieu583e2c12017-03-04 00:08:58 +00001162S *s;
Richard Trieue7f7ed22017-02-22 01:11:25 +00001163#endif
1164
1165#if defined(FIRST)
Richard Trieufe564052017-04-20 02:53:53 +00001166CREATE_ALL_DECL_STRUCT(T, private)
Richard Trieue7f7ed22017-02-22 01:11:25 +00001167#elif defined(SECOND)
Richard Trieufe564052017-04-20 02:53:53 +00001168CREATE_ALL_DECL_STRUCT(T, public)
Richard Trieue7f7ed22017-02-22 01:11:25 +00001169#else
Richard Trieu583e2c12017-03-04 00:08:58 +00001170T *t;
Richard Trieue7f7ed22017-02-22 01:11:25 +00001171// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
1172// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
1173#endif
1174}
1175
1176namespace FriendFunction {
1177#if defined(FIRST)
1178void F(int = 0);
1179struct S { friend void F(int); };
1180#elif defined(SECOND)
1181void F(int);
1182struct S { friend void F(int); };
1183#else
1184S s;
1185#endif
1186
1187#if defined(FIRST)
1188void G(int = 0);
1189struct T {
1190 friend void G(int);
1191
1192 private:
1193};
1194#elif defined(SECOND)
1195void G(int);
1196struct T {
1197 friend void G(int);
1198
1199 public:
1200};
1201#else
1202T t;
1203// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
1204// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
1205#endif
1206} // namespace FriendFunction
1207
1208namespace ImplicitDecl {
1209#if defined(FIRST)
1210struct S { };
1211void S_Constructors() {
1212 // Trigger creation of implicit contructors
1213 S foo;
1214 S bar = foo;
1215 S baz(bar);
1216}
1217#elif defined(SECOND)
1218struct S { };
1219#else
1220S s;
1221#endif
1222
1223#if defined(FIRST)
1224struct T {
1225 private:
1226};
1227void T_Constructors() {
1228 // Trigger creation of implicit contructors
1229 T foo;
1230 T bar = foo;
1231 T baz(bar);
1232}
1233#elif defined(SECOND)
1234struct T {
1235 public:
1236};
1237#else
1238T t;
1239// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}
1240// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
1241#endif
1242
1243} // namespace ImplicitDelc
1244
1245namespace TemplatedClass {
1246#if defined(FIRST)
1247template <class>
1248struct S {};
1249#elif defined(SECOND)
1250template <class>
1251struct S {};
1252#else
1253S<int> s;
1254#endif
1255
1256#if defined(FIRST)
1257template <class>
1258struct T {
1259 private:
1260};
1261#elif defined(SECOND)
1262template <class>
1263struct T {
1264 public:
1265};
1266#else
1267T<int> t;
1268// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
1269// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
1270#endif
1271} // namespace TemplatedClass
1272
1273namespace TemplateClassWithField {
1274#if defined(FIRST)
1275template <class A>
1276struct S {
1277 A a;
1278};
1279#elif defined(SECOND)
1280template <class A>
1281struct S {
1282 A a;
1283};
1284#else
1285S<int> s;
1286#endif
1287
1288#if defined(FIRST)
1289template <class A>
1290struct T {
1291 A a;
1292
1293 private:
1294};
1295#elif defined(SECOND)
1296template <class A>
1297struct T {
1298 A a;
1299
1300 public:
1301};
1302#else
1303T<int> t;
1304// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
1305// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
1306#endif
1307} // namespace TemplateClassWithField
1308
1309namespace TemplateClassWithTemplateField {
1310#if defined(FIRST)
1311template <class A>
1312class WrapperS;
1313template <class A>
1314struct S {
1315 WrapperS<A> a;
1316};
1317#elif defined(SECOND)
1318template <class A>
1319class WrapperS;
1320template <class A>
1321struct S {
1322 WrapperS<A> a;
1323};
1324#else
1325template <class A>
1326class WrapperS{};
1327S<int> s;
1328#endif
1329
1330#if defined(FIRST)
1331template <class A>
1332class WrapperT;
1333template <class A>
1334struct T {
1335 WrapperT<A> a;
1336
1337 public:
1338};
1339#elif defined(SECOND)
1340template <class A>
1341class WrapperT;
1342template <class A>
1343struct T {
1344 WrapperT<A> a;
1345
1346 private:
1347};
1348#else
1349template <class A>
1350class WrapperT{};
1351T<int> t;
1352// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
1353// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
1354#endif
1355} // namespace TemplateClassWithTemplateField
1356
1357namespace EnumWithForwardDeclaration {
1358#if defined(FIRST)
1359enum E : int;
1360struct S {
1361 void get(E) {}
1362};
1363#elif defined(SECOND)
1364enum E : int { A, B };
1365struct S {
1366 void get(E) {}
1367};
1368#else
1369S s;
1370#endif
1371
1372#if defined(FIRST)
1373struct T {
1374 void get(E) {}
1375 public:
1376};
1377#elif defined(SECOND)
1378struct T {
1379 void get(E) {}
1380 private:
1381};
1382#else
1383T t;
1384// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
1385// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
1386#endif
1387} // namespace EnumWithForwardDeclaration
1388
1389namespace StructWithForwardDeclaration {
1390#if defined(FIRST)
1391struct P {};
1392struct S {
1393 struct P *ptr;
1394};
1395#elif defined(SECOND)
1396struct S {
1397 struct P *ptr;
1398};
1399#else
1400S s;
1401#endif
1402
1403#if defined(FIRST)
1404struct Q {};
1405struct T {
1406 struct Q *ptr;
1407 public:
1408};
1409#elif defined(SECOND)
1410struct T {
1411 struct Q *ptr;
1412 private:
1413};
1414#else
1415T t;
1416// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
1417// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
1418#endif
1419} // namespace StructWithForwardDeclaration
1420
1421namespace StructWithForwardDeclarationNoDefinition {
1422#if defined(FIRST)
1423struct P;
1424struct S {
1425 struct P *ptr;
1426};
1427#elif defined(SECOND)
1428struct S {
1429 struct P *ptr;
1430};
1431#else
1432S s;
1433#endif
1434
1435#if defined(FIRST)
1436struct Q;
1437struct T {
1438 struct Q *ptr;
1439
1440 public:
1441};
1442#elif defined(SECOND)
1443struct T {
1444 struct Q *ptr;
1445
1446 private:
1447};
1448#else
1449T t;
1450// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
1451// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
1452#endif
1453} // namespace StructWithForwardDeclarationNoDefinition
1454
Richard Trieufe564052017-04-20 02:53:53 +00001455namespace LateParsedDefaultArgument {
1456#if defined(FIRST)
1457template <typename T>
1458struct S {
1459 struct R {
1460 void foo(T x = 0) {}
1461 };
1462};
1463#elif defined(SECOND)
1464#else
1465void run() {
1466 S<int>::R().foo();
1467}
1468#endif
1469}
1470
1471namespace LateParsedDefaultArgument {
1472#if defined(FIRST)
1473template <typename alpha> struct Bravo {
1474 void charlie(bool delta = false) {}
1475};
1476typedef Bravo<char> echo;
1477echo foxtrot;
1478
1479Bravo<char> golf;
1480#elif defined(SECOND)
1481#else
1482#endif
1483}
1484
Richard Trieu157ed942017-04-28 22:03:28 +00001485namespace DifferentParameterNameInTemplate {
1486#if defined(FIRST) || defined(SECOND)
1487template <typename T>
1488struct S {
1489 typedef T Type;
1490
1491 static void Run(const Type *name_one);
1492};
1493
1494template <typename T>
1495void S<T>::Run(const T *name_two) {}
1496
1497template <typename T>
1498struct Foo {
1499 ~Foo() { Handler::Run(nullptr); }
1500 Foo() {}
1501
1502 class Handler : public S<T> {};
1503
1504 void Get(typename Handler::Type *x = nullptr) {}
1505 void Add() { Handler::Run(nullptr); }
1506};
1507#endif
1508
1509#if defined(FIRST)
1510struct Beta;
1511
1512struct Alpha {
1513 Alpha();
1514 void Go() { betas.Get(); }
1515 Foo<Beta> betas;
1516};
1517
1518#elif defined(SECOND)
1519struct Beta {};
1520
1521struct BetaHelper {
1522 void add_Beta() { betas.Add(); }
1523 Foo<Beta> betas;
1524};
1525
1526#else
1527Alpha::Alpha() {}
1528#endif
1529}
1530
Richard Trieu02552272017-05-02 23:58:52 +00001531namespace ParameterTest {
1532#if defined(FIRST)
1533class X {};
1534template <typename G>
1535class S {
1536 public:
1537 typedef G Type;
1538 static inline G *Foo(const G *a, int * = nullptr);
1539};
1540
1541template<typename G>
1542G* S<G>::Foo(const G* aaaa, int*) {}
1543#elif defined(SECOND)
1544template <typename G>
1545class S {
1546 public:
1547 typedef G Type;
1548 static inline G *Foo(const G *a, int * = nullptr);
1549};
1550
1551template<typename G>
1552G* S<G>::Foo(const G* asdf, int*) {}
1553#else
1554S<X> s;
1555#endif
1556}
1557
Richard Trieub35ef2a2017-05-09 03:24:34 +00001558namespace MultipleTypedefs {
1559#if defined(FIRST)
1560typedef int B1;
1561typedef B1 A1;
1562struct S1 {
1563 A1 x;
1564};
1565#elif defined(SECOND)
1566typedef int A1;
1567struct S1 {
1568 A1 x;
1569};
1570#else
1571S1 s1;
1572#endif
1573
1574#if defined(FIRST)
1575struct T2 { int x; };
1576typedef T2 B2;
1577typedef B2 A2;
1578struct S2 {
1579 T2 x;
1580};
1581#elif defined(SECOND)
1582struct T2 { int x; };
1583typedef T2 A2;
1584struct S2 {
1585 T2 x;
1586};
1587#else
1588S2 s2;
1589#endif
1590}
Richard Trieu02552272017-05-02 23:58:52 +00001591
Richard Trieue7f7ed22017-02-22 01:11:25 +00001592// Keep macros contained to one file.
1593#ifdef FIRST
1594#undef FIRST
1595#endif
1596#ifdef SECOND
1597#undef SECOND
1598#endif