blob: 9063cd1ea769a80b761089297c5b2406ae0d6376 [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() {}
Richard Trieuf4b54fe2017-03-04 03:04:15 +0000315 void A(int) {}
Richard Trieu583e2c12017-03-04 00:08:58 +0000316};
317#elif defined(SECOND)
318struct S3 {
Richard Trieuf4b54fe2017-03-04 03:04:15 +0000319 void A(int) {}
320 static void A() {}
Richard Trieu583e2c12017-03-04 00:08:58 +0000321};
322#else
323S3 s3;
324// 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}}
325// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is static}}
326#endif
327
328#if defined(FIRST)
329struct S4 {
330 virtual void A() {}
331 void B() {}
332};
333#elif defined(SECOND)
334struct S4 {
335 void A() {}
336 virtual void B() {}
337};
338#else
339S4 s4;
340// 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}}
341// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is virtual}}
342#endif
343
344#if defined(FIRST)
345struct S5 {
346 virtual void A() = 0;
347 virtual void B() {};
348};
349#elif defined(SECOND)
350struct S5 {
351 virtual void A() {}
352 virtual void B() = 0;
353};
354#else
355S5 *s5;
356// expected-error@second.h:* {{'Method::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is virtual}}
357// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is pure virtual}}
358#endif
359
360#if defined(FIRST)
361struct S6 {
362 inline void A() {}
363};
364#elif defined(SECOND)
365struct S6 {
366 void A() {}
367};
368#else
369S6 s6;
370// 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}}
371// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is inline}}
372#endif
373
374#if defined(FIRST)
375struct S7 {
376 void A() volatile {}
377 void A() {}
378};
379#elif defined(SECOND)
380struct S7 {
381 void A() {}
382 void A() volatile {}
383};
384#else
385S7 s7;
386// 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}}
387// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is volatile}}
388#endif
389
390#if defined(FIRST)
391struct S8 {
392 void A() const {}
393 void A() {}
394};
395#elif defined(SECOND)
396struct S8 {
397 void A() {}
398 void A() const {}
399};
400#else
401S8 s8;
402// 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}}
403// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is const}}
404#endif
405
Richard Trieu48143742017-02-28 21:24:38 +0000406} // namespace Method
407
Richard Trieue7f7ed22017-02-22 01:11:25 +0000408// Naive parsing of AST can lead to cycles in processing. Ensure
409// self-references don't trigger an endless cycles of AST node processing.
410namespace SelfReference {
411#if defined(FIRST)
412template <template <int> class T> class Wrapper {};
413
414template <int N> class S {
415 S(Wrapper<::SelfReference::S> &Ref) {}
416};
417
418struct Xx {
419 struct Yy {
420 };
421};
422
423Xx::Xx::Xx::Yy yy;
424
425namespace NNS {
426template <typename> struct Foo;
427template <template <class> class T = NNS::Foo>
428struct NestedNamespaceSpecifier {};
429}
430#endif
431} // namespace SelfReference
432
433// Interesting cases that should not cause errors. struct S should not error
434// while struct T should error at the access specifier mismatch at the end.
435namespace AllDecls {
436#if defined(FIRST)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000437typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000438struct S {
439 public:
440 private:
441 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000442
443 static_assert(1 == 1, "Message");
444 static_assert(2 == 2);
Richard Trieud0786092017-02-23 00:23:01 +0000445
446 int x;
447 double y;
Richard Trieu8459ddf2017-02-24 02:59:12 +0000448
449 INT z;
Richard Trieu93772fc2017-02-24 20:59:28 +0000450
451 unsigned a : 1;
452 unsigned b : 2*2 + 5/2;
Richard Trieu8d543e22017-02-24 23:35:37 +0000453
454 mutable int c = sizeof(x + y);
Richard Trieu48143742017-02-28 21:24:38 +0000455
456 void method() {}
Richard Trieu583e2c12017-03-04 00:08:58 +0000457 static void static_method() {}
458 virtual void virtual_method() {}
459 virtual void pure_virtual_method() = 0;
460 inline void inline_method() {}
461 void volatile_method() volatile {}
462 void const_method() const {}
Richard Trieue7f7ed22017-02-22 01:11:25 +0000463};
464#elif defined(SECOND)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000465typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000466struct S {
467 public:
468 private:
469 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000470
471 static_assert(1 == 1, "Message");
472 static_assert(2 == 2);
Richard Trieud0786092017-02-23 00:23:01 +0000473
474 int x;
475 double y;
Richard Trieu8459ddf2017-02-24 02:59:12 +0000476
477 INT z;
Richard Trieu93772fc2017-02-24 20:59:28 +0000478
479 unsigned a : 1;
480 unsigned b : 2 * 2 + 5 / 2;
Richard Trieu8d543e22017-02-24 23:35:37 +0000481
482 mutable int c = sizeof(x + y);
Richard Trieu48143742017-02-28 21:24:38 +0000483
484 void method() {}
Richard Trieu583e2c12017-03-04 00:08:58 +0000485 static void static_method() {}
486 virtual void virtual_method() {}
487 virtual void pure_virtual_method() = 0;
488 inline void inline_method() {}
489 void volatile_method() volatile {}
490 void const_method() const {}
Richard Trieue7f7ed22017-02-22 01:11:25 +0000491};
492#else
Richard Trieu583e2c12017-03-04 00:08:58 +0000493S *s;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000494#endif
495
496#if defined(FIRST)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000497typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000498struct T {
499 public:
500 private:
501 protected:
502
Richard Trieu639d7b62017-02-22 22:22:42 +0000503 static_assert(1 == 1, "Message");
504 static_assert(2 == 2);
505
Richard Trieud0786092017-02-23 00:23:01 +0000506 int x;
507 double y;
508
Richard Trieu8459ddf2017-02-24 02:59:12 +0000509 INT z;
510
Richard Trieu93772fc2017-02-24 20:59:28 +0000511 unsigned a : 1;
512 unsigned b : 2 * 2 + 5 / 2;
513
Richard Trieu8d543e22017-02-24 23:35:37 +0000514 mutable int c = sizeof(x + y);
515
Richard Trieu48143742017-02-28 21:24:38 +0000516 void method() {}
Richard Trieu583e2c12017-03-04 00:08:58 +0000517 static void static_method() {}
518 virtual void virtual_method() {}
519 virtual void pure_virtual_method() = 0;
520 inline void inline_method() {}
521 void volatile_method() volatile {}
522 void const_method() const {}
Richard Trieu48143742017-02-28 21:24:38 +0000523
Richard Trieue7f7ed22017-02-22 01:11:25 +0000524 private:
525};
526#elif defined(SECOND)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000527typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000528struct T {
529 public:
530 private:
531 protected:
532
Richard Trieu639d7b62017-02-22 22:22:42 +0000533 static_assert(1 == 1, "Message");
534 static_assert(2 == 2);
535
Richard Trieud0786092017-02-23 00:23:01 +0000536 int x;
537 double y;
538
Richard Trieu8459ddf2017-02-24 02:59:12 +0000539 INT z;
540
Richard Trieu93772fc2017-02-24 20:59:28 +0000541 unsigned a : 1;
542 unsigned b : 2 * 2 + 5 / 2;
543
Richard Trieu8d543e22017-02-24 23:35:37 +0000544 mutable int c = sizeof(x + y);
545
Richard Trieu48143742017-02-28 21:24:38 +0000546 void method() {}
Richard Trieu583e2c12017-03-04 00:08:58 +0000547 static void static_method() {}
548 virtual void virtual_method() {}
549 virtual void pure_virtual_method() = 0;
550 inline void inline_method() {}
551 void volatile_method() volatile {}
552 void const_method() const {}
Richard Trieu48143742017-02-28 21:24:38 +0000553
Richard Trieue7f7ed22017-02-22 01:11:25 +0000554 public:
555};
556#else
Richard Trieu583e2c12017-03-04 00:08:58 +0000557T *t;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000558// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
559// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
560#endif
561}
562
563namespace FriendFunction {
564#if defined(FIRST)
565void F(int = 0);
566struct S { friend void F(int); };
567#elif defined(SECOND)
568void F(int);
569struct S { friend void F(int); };
570#else
571S s;
572#endif
573
574#if defined(FIRST)
575void G(int = 0);
576struct T {
577 friend void G(int);
578
579 private:
580};
581#elif defined(SECOND)
582void G(int);
583struct T {
584 friend void G(int);
585
586 public:
587};
588#else
589T t;
590// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
591// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
592#endif
593} // namespace FriendFunction
594
595namespace ImplicitDecl {
596#if defined(FIRST)
597struct S { };
598void S_Constructors() {
599 // Trigger creation of implicit contructors
600 S foo;
601 S bar = foo;
602 S baz(bar);
603}
604#elif defined(SECOND)
605struct S { };
606#else
607S s;
608#endif
609
610#if defined(FIRST)
611struct T {
612 private:
613};
614void T_Constructors() {
615 // Trigger creation of implicit contructors
616 T foo;
617 T bar = foo;
618 T baz(bar);
619}
620#elif defined(SECOND)
621struct T {
622 public:
623};
624#else
625T t;
626// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}
627// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
628#endif
629
630} // namespace ImplicitDelc
631
632namespace TemplatedClass {
633#if defined(FIRST)
634template <class>
635struct S {};
636#elif defined(SECOND)
637template <class>
638struct S {};
639#else
640S<int> s;
641#endif
642
643#if defined(FIRST)
644template <class>
645struct T {
646 private:
647};
648#elif defined(SECOND)
649template <class>
650struct T {
651 public:
652};
653#else
654T<int> t;
655// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
656// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
657#endif
658} // namespace TemplatedClass
659
660namespace TemplateClassWithField {
661#if defined(FIRST)
662template <class A>
663struct S {
664 A a;
665};
666#elif defined(SECOND)
667template <class A>
668struct S {
669 A a;
670};
671#else
672S<int> s;
673#endif
674
675#if defined(FIRST)
676template <class A>
677struct T {
678 A a;
679
680 private:
681};
682#elif defined(SECOND)
683template <class A>
684struct T {
685 A a;
686
687 public:
688};
689#else
690T<int> t;
691// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
692// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
693#endif
694} // namespace TemplateClassWithField
695
696namespace TemplateClassWithTemplateField {
697#if defined(FIRST)
698template <class A>
699class WrapperS;
700template <class A>
701struct S {
702 WrapperS<A> a;
703};
704#elif defined(SECOND)
705template <class A>
706class WrapperS;
707template <class A>
708struct S {
709 WrapperS<A> a;
710};
711#else
712template <class A>
713class WrapperS{};
714S<int> s;
715#endif
716
717#if defined(FIRST)
718template <class A>
719class WrapperT;
720template <class A>
721struct T {
722 WrapperT<A> a;
723
724 public:
725};
726#elif defined(SECOND)
727template <class A>
728class WrapperT;
729template <class A>
730struct T {
731 WrapperT<A> a;
732
733 private:
734};
735#else
736template <class A>
737class WrapperT{};
738T<int> t;
739// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
740// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
741#endif
742} // namespace TemplateClassWithTemplateField
743
744namespace EnumWithForwardDeclaration {
745#if defined(FIRST)
746enum E : int;
747struct S {
748 void get(E) {}
749};
750#elif defined(SECOND)
751enum E : int { A, B };
752struct S {
753 void get(E) {}
754};
755#else
756S s;
757#endif
758
759#if defined(FIRST)
760struct T {
761 void get(E) {}
762 public:
763};
764#elif defined(SECOND)
765struct T {
766 void get(E) {}
767 private:
768};
769#else
770T t;
771// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
772// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
773#endif
774} // namespace EnumWithForwardDeclaration
775
776namespace StructWithForwardDeclaration {
777#if defined(FIRST)
778struct P {};
779struct S {
780 struct P *ptr;
781};
782#elif defined(SECOND)
783struct S {
784 struct P *ptr;
785};
786#else
787S s;
788#endif
789
790#if defined(FIRST)
791struct Q {};
792struct T {
793 struct Q *ptr;
794 public:
795};
796#elif defined(SECOND)
797struct T {
798 struct Q *ptr;
799 private:
800};
801#else
802T t;
803// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
804// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
805#endif
806} // namespace StructWithForwardDeclaration
807
808namespace StructWithForwardDeclarationNoDefinition {
809#if defined(FIRST)
810struct P;
811struct S {
812 struct P *ptr;
813};
814#elif defined(SECOND)
815struct S {
816 struct P *ptr;
817};
818#else
819S s;
820#endif
821
822#if defined(FIRST)
823struct Q;
824struct T {
825 struct Q *ptr;
826
827 public:
828};
829#elif defined(SECOND)
830struct T {
831 struct Q *ptr;
832
833 private:
834};
835#else
836T t;
837// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
838// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
839#endif
840} // namespace StructWithForwardDeclarationNoDefinition
841
842// Keep macros contained to one file.
843#ifdef FIRST
844#undef FIRST
845#endif
846#ifdef SECOND
847#undef SECOND
848#endif