blob: c1ea3b034ff8a63ed6053e88a7defb077c6ff899 [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
311} // namespace Method
312
Richard Trieue7f7ed22017-02-22 01:11:25 +0000313// Naive parsing of AST can lead to cycles in processing. Ensure
314// self-references don't trigger an endless cycles of AST node processing.
315namespace SelfReference {
316#if defined(FIRST)
317template <template <int> class T> class Wrapper {};
318
319template <int N> class S {
320 S(Wrapper<::SelfReference::S> &Ref) {}
321};
322
323struct Xx {
324 struct Yy {
325 };
326};
327
328Xx::Xx::Xx::Yy yy;
329
330namespace NNS {
331template <typename> struct Foo;
332template <template <class> class T = NNS::Foo>
333struct NestedNamespaceSpecifier {};
334}
335#endif
336} // namespace SelfReference
337
338// Interesting cases that should not cause errors. struct S should not error
339// while struct T should error at the access specifier mismatch at the end.
340namespace AllDecls {
341#if defined(FIRST)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000342typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000343struct S {
344 public:
345 private:
346 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000347
348 static_assert(1 == 1, "Message");
349 static_assert(2 == 2);
Richard Trieud0786092017-02-23 00:23:01 +0000350
351 int x;
352 double y;
Richard Trieu8459ddf2017-02-24 02:59:12 +0000353
354 INT z;
Richard Trieu93772fc2017-02-24 20:59:28 +0000355
356 unsigned a : 1;
357 unsigned b : 2*2 + 5/2;
Richard Trieu8d543e22017-02-24 23:35:37 +0000358
359 mutable int c = sizeof(x + y);
Richard Trieu48143742017-02-28 21:24:38 +0000360
361 void method() {}
Richard Trieue7f7ed22017-02-22 01:11:25 +0000362};
363#elif defined(SECOND)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000364typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000365struct S {
366 public:
367 private:
368 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000369
370 static_assert(1 == 1, "Message");
371 static_assert(2 == 2);
Richard Trieud0786092017-02-23 00:23:01 +0000372
373 int x;
374 double y;
Richard Trieu8459ddf2017-02-24 02:59:12 +0000375
376 INT z;
Richard Trieu93772fc2017-02-24 20:59:28 +0000377
378 unsigned a : 1;
379 unsigned b : 2 * 2 + 5 / 2;
Richard Trieu8d543e22017-02-24 23:35:37 +0000380
381 mutable int c = sizeof(x + y);
Richard Trieu48143742017-02-28 21:24:38 +0000382
383 void method() {}
Richard Trieue7f7ed22017-02-22 01:11:25 +0000384};
385#else
386S s;
387#endif
388
389#if defined(FIRST)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000390typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000391struct T {
392 public:
393 private:
394 protected:
395
Richard Trieu639d7b62017-02-22 22:22:42 +0000396 static_assert(1 == 1, "Message");
397 static_assert(2 == 2);
398
Richard Trieud0786092017-02-23 00:23:01 +0000399 int x;
400 double y;
401
Richard Trieu8459ddf2017-02-24 02:59:12 +0000402 INT z;
403
Richard Trieu93772fc2017-02-24 20:59:28 +0000404 unsigned a : 1;
405 unsigned b : 2 * 2 + 5 / 2;
406
Richard Trieu8d543e22017-02-24 23:35:37 +0000407 mutable int c = sizeof(x + y);
408
Richard Trieu48143742017-02-28 21:24:38 +0000409 void method() {}
410
Richard Trieue7f7ed22017-02-22 01:11:25 +0000411 private:
412};
413#elif defined(SECOND)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000414typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000415struct T {
416 public:
417 private:
418 protected:
419
Richard Trieu639d7b62017-02-22 22:22:42 +0000420 static_assert(1 == 1, "Message");
421 static_assert(2 == 2);
422
Richard Trieud0786092017-02-23 00:23:01 +0000423 int x;
424 double y;
425
Richard Trieu8459ddf2017-02-24 02:59:12 +0000426 INT z;
427
Richard Trieu93772fc2017-02-24 20:59:28 +0000428 unsigned a : 1;
429 unsigned b : 2 * 2 + 5 / 2;
430
Richard Trieu8d543e22017-02-24 23:35:37 +0000431 mutable int c = sizeof(x + y);
432
Richard Trieu48143742017-02-28 21:24:38 +0000433 void method() {}
434
Richard Trieue7f7ed22017-02-22 01:11:25 +0000435 public:
436};
437#else
438T t;
439// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
440// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
441#endif
442}
443
444namespace FriendFunction {
445#if defined(FIRST)
446void F(int = 0);
447struct S { friend void F(int); };
448#elif defined(SECOND)
449void F(int);
450struct S { friend void F(int); };
451#else
452S s;
453#endif
454
455#if defined(FIRST)
456void G(int = 0);
457struct T {
458 friend void G(int);
459
460 private:
461};
462#elif defined(SECOND)
463void G(int);
464struct T {
465 friend void G(int);
466
467 public:
468};
469#else
470T t;
471// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
472// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
473#endif
474} // namespace FriendFunction
475
476namespace ImplicitDecl {
477#if defined(FIRST)
478struct S { };
479void S_Constructors() {
480 // Trigger creation of implicit contructors
481 S foo;
482 S bar = foo;
483 S baz(bar);
484}
485#elif defined(SECOND)
486struct S { };
487#else
488S s;
489#endif
490
491#if defined(FIRST)
492struct T {
493 private:
494};
495void T_Constructors() {
496 // Trigger creation of implicit contructors
497 T foo;
498 T bar = foo;
499 T baz(bar);
500}
501#elif defined(SECOND)
502struct T {
503 public:
504};
505#else
506T t;
507// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}
508// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
509#endif
510
511} // namespace ImplicitDelc
512
513namespace TemplatedClass {
514#if defined(FIRST)
515template <class>
516struct S {};
517#elif defined(SECOND)
518template <class>
519struct S {};
520#else
521S<int> s;
522#endif
523
524#if defined(FIRST)
525template <class>
526struct T {
527 private:
528};
529#elif defined(SECOND)
530template <class>
531struct T {
532 public:
533};
534#else
535T<int> t;
536// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
537// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
538#endif
539} // namespace TemplatedClass
540
541namespace TemplateClassWithField {
542#if defined(FIRST)
543template <class A>
544struct S {
545 A a;
546};
547#elif defined(SECOND)
548template <class A>
549struct S {
550 A a;
551};
552#else
553S<int> s;
554#endif
555
556#if defined(FIRST)
557template <class A>
558struct T {
559 A a;
560
561 private:
562};
563#elif defined(SECOND)
564template <class A>
565struct T {
566 A a;
567
568 public:
569};
570#else
571T<int> t;
572// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
573// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
574#endif
575} // namespace TemplateClassWithField
576
577namespace TemplateClassWithTemplateField {
578#if defined(FIRST)
579template <class A>
580class WrapperS;
581template <class A>
582struct S {
583 WrapperS<A> a;
584};
585#elif defined(SECOND)
586template <class A>
587class WrapperS;
588template <class A>
589struct S {
590 WrapperS<A> a;
591};
592#else
593template <class A>
594class WrapperS{};
595S<int> s;
596#endif
597
598#if defined(FIRST)
599template <class A>
600class WrapperT;
601template <class A>
602struct T {
603 WrapperT<A> a;
604
605 public:
606};
607#elif defined(SECOND)
608template <class A>
609class WrapperT;
610template <class A>
611struct T {
612 WrapperT<A> a;
613
614 private:
615};
616#else
617template <class A>
618class WrapperT{};
619T<int> t;
620// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
621// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
622#endif
623} // namespace TemplateClassWithTemplateField
624
625namespace EnumWithForwardDeclaration {
626#if defined(FIRST)
627enum E : int;
628struct S {
629 void get(E) {}
630};
631#elif defined(SECOND)
632enum E : int { A, B };
633struct S {
634 void get(E) {}
635};
636#else
637S s;
638#endif
639
640#if defined(FIRST)
641struct T {
642 void get(E) {}
643 public:
644};
645#elif defined(SECOND)
646struct T {
647 void get(E) {}
648 private:
649};
650#else
651T t;
652// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
653// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
654#endif
655} // namespace EnumWithForwardDeclaration
656
657namespace StructWithForwardDeclaration {
658#if defined(FIRST)
659struct P {};
660struct S {
661 struct P *ptr;
662};
663#elif defined(SECOND)
664struct S {
665 struct P *ptr;
666};
667#else
668S s;
669#endif
670
671#if defined(FIRST)
672struct Q {};
673struct T {
674 struct Q *ptr;
675 public:
676};
677#elif defined(SECOND)
678struct T {
679 struct Q *ptr;
680 private:
681};
682#else
683T t;
684// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
685// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
686#endif
687} // namespace StructWithForwardDeclaration
688
689namespace StructWithForwardDeclarationNoDefinition {
690#if defined(FIRST)
691struct P;
692struct S {
693 struct P *ptr;
694};
695#elif defined(SECOND)
696struct S {
697 struct P *ptr;
698};
699#else
700S s;
701#endif
702
703#if defined(FIRST)
704struct Q;
705struct T {
706 struct Q *ptr;
707
708 public:
709};
710#elif defined(SECOND)
711struct T {
712 struct Q *ptr;
713
714 private:
715};
716#else
717T t;
718// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
719// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
720#endif
721} // namespace StructWithForwardDeclarationNoDefinition
722
723// Keep macros contained to one file.
724#ifdef FIRST
725#undef FIRST
726#endif
727#ifdef SECOND
728#undef SECOND
729#endif