blob: 572d24a077fadc105ae3ec825292448ef27de31b [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;
186// expected-error@second.h:* {{'Field::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'B' (aka 'int')}}
187// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'A' (aka 'int')}}
188
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'}}
191// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'A' (aka 'int')}}
192#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 Trieud0786092017-02-23 00:23:01 +0000278} // namespace Field
279
Richard Trieu48143742017-02-28 21:24:38 +0000280namespace Method {
281#if defined(FIRST)
282struct S1 {
283 void A() {}
284};
285#elif defined(SECOND)
286struct S1 {
287 private:
288 void A() {}
289};
290#else
291S1 s1;
292// expected-error@second.h:* {{'Method::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
293// expected-note@first.h:* {{but in 'FirstModule' found method}}
294#endif
295
296#if defined(FIRST)
297struct S2 {
298 void A() {}
299 void B() {}
300};
301#elif defined(SECOND)
302struct S2 {
303 void B() {}
304 void A() {}
305};
306#else
307S2 s2;
308// expected-error@second.h:* {{'Method::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'B'}}
309// expected-note@first.h:* {{but in 'FirstModule' found method 'A'}}
310#endif
Richard Trieu583e2c12017-03-04 00:08:58 +0000311
312#if defined(FIRST)
313struct S3 {
314 static void A() {}
315};
316#elif defined(SECOND)
317struct S3 {
318 void A() {}
319};
320#else
321S3 s3;
322// 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}}
323// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is static}}
324#endif
325
326#if defined(FIRST)
327struct S4 {
328 virtual void A() {}
329 void B() {}
330};
331#elif defined(SECOND)
332struct S4 {
333 void A() {}
334 virtual void B() {}
335};
336#else
337S4 s4;
338// 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}}
339// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is virtual}}
340#endif
341
342#if defined(FIRST)
343struct S5 {
344 virtual void A() = 0;
345 virtual void B() {};
346};
347#elif defined(SECOND)
348struct S5 {
349 virtual void A() {}
350 virtual void B() = 0;
351};
352#else
353S5 *s5;
354// expected-error@second.h:* {{'Method::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is virtual}}
355// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is pure virtual}}
356#endif
357
358#if defined(FIRST)
359struct S6 {
360 inline void A() {}
361};
362#elif defined(SECOND)
363struct S6 {
364 void A() {}
365};
366#else
367S6 s6;
368// 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}}
369// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is inline}}
370#endif
371
372#if defined(FIRST)
373struct S7 {
374 void A() volatile {}
375 void A() {}
376};
377#elif defined(SECOND)
378struct S7 {
379 void A() {}
380 void A() volatile {}
381};
382#else
383S7 s7;
384// 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}}
385// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is volatile}}
386#endif
387
388#if defined(FIRST)
389struct S8 {
390 void A() const {}
391 void A() {}
392};
393#elif defined(SECOND)
394struct S8 {
395 void A() {}
396 void A() const {}
397};
398#else
399S8 s8;
400// 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}}
401// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is const}}
402#endif
403
Richard Trieu48143742017-02-28 21:24:38 +0000404} // namespace Method
405
Richard Trieue7f7ed22017-02-22 01:11:25 +0000406// Naive parsing of AST can lead to cycles in processing. Ensure
407// self-references don't trigger an endless cycles of AST node processing.
408namespace SelfReference {
409#if defined(FIRST)
410template <template <int> class T> class Wrapper {};
411
412template <int N> class S {
413 S(Wrapper<::SelfReference::S> &Ref) {}
414};
415
416struct Xx {
417 struct Yy {
418 };
419};
420
421Xx::Xx::Xx::Yy yy;
422
423namespace NNS {
424template <typename> struct Foo;
425template <template <class> class T = NNS::Foo>
426struct NestedNamespaceSpecifier {};
427}
428#endif
429} // namespace SelfReference
430
431// Interesting cases that should not cause errors. struct S should not error
432// while struct T should error at the access specifier mismatch at the end.
433namespace AllDecls {
434#if defined(FIRST)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000435typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000436struct S {
437 public:
438 private:
439 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000440
441 static_assert(1 == 1, "Message");
442 static_assert(2 == 2);
Richard Trieud0786092017-02-23 00:23:01 +0000443
444 int x;
445 double y;
Richard Trieu8459ddf2017-02-24 02:59:12 +0000446
447 INT z;
Richard Trieu93772fc2017-02-24 20:59:28 +0000448
449 unsigned a : 1;
450 unsigned b : 2*2 + 5/2;
Richard Trieu8d543e22017-02-24 23:35:37 +0000451
452 mutable int c = sizeof(x + y);
Richard Trieu48143742017-02-28 21:24:38 +0000453
454 void method() {}
Richard Trieu583e2c12017-03-04 00:08:58 +0000455 static void static_method() {}
456 virtual void virtual_method() {}
457 virtual void pure_virtual_method() = 0;
458 inline void inline_method() {}
459 void volatile_method() volatile {}
460 void const_method() const {}
Richard Trieue7f7ed22017-02-22 01:11:25 +0000461};
462#elif defined(SECOND)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000463typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000464struct S {
465 public:
466 private:
467 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000468
469 static_assert(1 == 1, "Message");
470 static_assert(2 == 2);
Richard Trieud0786092017-02-23 00:23:01 +0000471
472 int x;
473 double y;
Richard Trieu8459ddf2017-02-24 02:59:12 +0000474
475 INT z;
Richard Trieu93772fc2017-02-24 20:59:28 +0000476
477 unsigned a : 1;
478 unsigned b : 2 * 2 + 5 / 2;
Richard Trieu8d543e22017-02-24 23:35:37 +0000479
480 mutable int c = sizeof(x + y);
Richard Trieu48143742017-02-28 21:24:38 +0000481
482 void method() {}
Richard Trieu583e2c12017-03-04 00:08:58 +0000483 static void static_method() {}
484 virtual void virtual_method() {}
485 virtual void pure_virtual_method() = 0;
486 inline void inline_method() {}
487 void volatile_method() volatile {}
488 void const_method() const {}
Richard Trieue7f7ed22017-02-22 01:11:25 +0000489};
490#else
Richard Trieu583e2c12017-03-04 00:08:58 +0000491S *s;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000492#endif
493
494#if defined(FIRST)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000495typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000496struct T {
497 public:
498 private:
499 protected:
500
Richard Trieu639d7b62017-02-22 22:22:42 +0000501 static_assert(1 == 1, "Message");
502 static_assert(2 == 2);
503
Richard Trieud0786092017-02-23 00:23:01 +0000504 int x;
505 double y;
506
Richard Trieu8459ddf2017-02-24 02:59:12 +0000507 INT z;
508
Richard Trieu93772fc2017-02-24 20:59:28 +0000509 unsigned a : 1;
510 unsigned b : 2 * 2 + 5 / 2;
511
Richard Trieu8d543e22017-02-24 23:35:37 +0000512 mutable int c = sizeof(x + y);
513
Richard Trieu48143742017-02-28 21:24:38 +0000514 void method() {}
Richard Trieu583e2c12017-03-04 00:08:58 +0000515 static void static_method() {}
516 virtual void virtual_method() {}
517 virtual void pure_virtual_method() = 0;
518 inline void inline_method() {}
519 void volatile_method() volatile {}
520 void const_method() const {}
Richard Trieu48143742017-02-28 21:24:38 +0000521
Richard Trieue7f7ed22017-02-22 01:11:25 +0000522 private:
523};
524#elif defined(SECOND)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000525typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000526struct T {
527 public:
528 private:
529 protected:
530
Richard Trieu639d7b62017-02-22 22:22:42 +0000531 static_assert(1 == 1, "Message");
532 static_assert(2 == 2);
533
Richard Trieud0786092017-02-23 00:23:01 +0000534 int x;
535 double y;
536
Richard Trieu8459ddf2017-02-24 02:59:12 +0000537 INT z;
538
Richard Trieu93772fc2017-02-24 20:59:28 +0000539 unsigned a : 1;
540 unsigned b : 2 * 2 + 5 / 2;
541
Richard Trieu8d543e22017-02-24 23:35:37 +0000542 mutable int c = sizeof(x + y);
543
Richard Trieu48143742017-02-28 21:24:38 +0000544 void method() {}
Richard Trieu583e2c12017-03-04 00:08:58 +0000545 static void static_method() {}
546 virtual void virtual_method() {}
547 virtual void pure_virtual_method() = 0;
548 inline void inline_method() {}
549 void volatile_method() volatile {}
550 void const_method() const {}
Richard Trieu48143742017-02-28 21:24:38 +0000551
Richard Trieue7f7ed22017-02-22 01:11:25 +0000552 public:
553};
554#else
Richard Trieu583e2c12017-03-04 00:08:58 +0000555T *t;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000556// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
557// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
558#endif
559}
560
561namespace FriendFunction {
562#if defined(FIRST)
563void F(int = 0);
564struct S { friend void F(int); };
565#elif defined(SECOND)
566void F(int);
567struct S { friend void F(int); };
568#else
569S s;
570#endif
571
572#if defined(FIRST)
573void G(int = 0);
574struct T {
575 friend void G(int);
576
577 private:
578};
579#elif defined(SECOND)
580void G(int);
581struct T {
582 friend void G(int);
583
584 public:
585};
586#else
587T t;
588// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
589// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
590#endif
591} // namespace FriendFunction
592
593namespace ImplicitDecl {
594#if defined(FIRST)
595struct S { };
596void S_Constructors() {
597 // Trigger creation of implicit contructors
598 S foo;
599 S bar = foo;
600 S baz(bar);
601}
602#elif defined(SECOND)
603struct S { };
604#else
605S s;
606#endif
607
608#if defined(FIRST)
609struct T {
610 private:
611};
612void T_Constructors() {
613 // Trigger creation of implicit contructors
614 T foo;
615 T bar = foo;
616 T baz(bar);
617}
618#elif defined(SECOND)
619struct T {
620 public:
621};
622#else
623T t;
624// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}
625// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
626#endif
627
628} // namespace ImplicitDelc
629
630namespace TemplatedClass {
631#if defined(FIRST)
632template <class>
633struct S {};
634#elif defined(SECOND)
635template <class>
636struct S {};
637#else
638S<int> s;
639#endif
640
641#if defined(FIRST)
642template <class>
643struct T {
644 private:
645};
646#elif defined(SECOND)
647template <class>
648struct T {
649 public:
650};
651#else
652T<int> t;
653// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
654// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
655#endif
656} // namespace TemplatedClass
657
658namespace TemplateClassWithField {
659#if defined(FIRST)
660template <class A>
661struct S {
662 A a;
663};
664#elif defined(SECOND)
665template <class A>
666struct S {
667 A a;
668};
669#else
670S<int> s;
671#endif
672
673#if defined(FIRST)
674template <class A>
675struct T {
676 A a;
677
678 private:
679};
680#elif defined(SECOND)
681template <class A>
682struct T {
683 A a;
684
685 public:
686};
687#else
688T<int> t;
689// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
690// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
691#endif
692} // namespace TemplateClassWithField
693
694namespace TemplateClassWithTemplateField {
695#if defined(FIRST)
696template <class A>
697class WrapperS;
698template <class A>
699struct S {
700 WrapperS<A> a;
701};
702#elif defined(SECOND)
703template <class A>
704class WrapperS;
705template <class A>
706struct S {
707 WrapperS<A> a;
708};
709#else
710template <class A>
711class WrapperS{};
712S<int> s;
713#endif
714
715#if defined(FIRST)
716template <class A>
717class WrapperT;
718template <class A>
719struct T {
720 WrapperT<A> a;
721
722 public:
723};
724#elif defined(SECOND)
725template <class A>
726class WrapperT;
727template <class A>
728struct T {
729 WrapperT<A> a;
730
731 private:
732};
733#else
734template <class A>
735class WrapperT{};
736T<int> t;
737// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
738// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
739#endif
740} // namespace TemplateClassWithTemplateField
741
742namespace EnumWithForwardDeclaration {
743#if defined(FIRST)
744enum E : int;
745struct S {
746 void get(E) {}
747};
748#elif defined(SECOND)
749enum E : int { A, B };
750struct S {
751 void get(E) {}
752};
753#else
754S s;
755#endif
756
757#if defined(FIRST)
758struct T {
759 void get(E) {}
760 public:
761};
762#elif defined(SECOND)
763struct T {
764 void get(E) {}
765 private:
766};
767#else
768T t;
769// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
770// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
771#endif
772} // namespace EnumWithForwardDeclaration
773
774namespace StructWithForwardDeclaration {
775#if defined(FIRST)
776struct P {};
777struct S {
778 struct P *ptr;
779};
780#elif defined(SECOND)
781struct S {
782 struct P *ptr;
783};
784#else
785S s;
786#endif
787
788#if defined(FIRST)
789struct Q {};
790struct T {
791 struct Q *ptr;
792 public:
793};
794#elif defined(SECOND)
795struct T {
796 struct Q *ptr;
797 private:
798};
799#else
800T t;
801// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
802// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
803#endif
804} // namespace StructWithForwardDeclaration
805
806namespace StructWithForwardDeclarationNoDefinition {
807#if defined(FIRST)
808struct P;
809struct S {
810 struct P *ptr;
811};
812#elif defined(SECOND)
813struct S {
814 struct P *ptr;
815};
816#else
817S s;
818#endif
819
820#if defined(FIRST)
821struct Q;
822struct T {
823 struct Q *ptr;
824
825 public:
826};
827#elif defined(SECOND)
828struct T {
829 struct Q *ptr;
830
831 private:
832};
833#else
834T t;
835// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
836// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
837#endif
838} // namespace StructWithForwardDeclarationNoDefinition
839
840// Keep macros contained to one file.
841#ifdef FIRST
842#undef FIRST
843#endif
844#ifdef SECOND
845#undef SECOND
846#endif