blob: 2a7a65c2ec682feef2c3f681cf1cecb96f1142c1 [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 Trieud0786092017-02-23 00:23:01 +0000236} // namespace Field
237
Richard Trieue7f7ed22017-02-22 01:11:25 +0000238// Naive parsing of AST can lead to cycles in processing. Ensure
239// self-references don't trigger an endless cycles of AST node processing.
240namespace SelfReference {
241#if defined(FIRST)
242template <template <int> class T> class Wrapper {};
243
244template <int N> class S {
245 S(Wrapper<::SelfReference::S> &Ref) {}
246};
247
248struct Xx {
249 struct Yy {
250 };
251};
252
253Xx::Xx::Xx::Yy yy;
254
255namespace NNS {
256template <typename> struct Foo;
257template <template <class> class T = NNS::Foo>
258struct NestedNamespaceSpecifier {};
259}
260#endif
261} // namespace SelfReference
262
263// Interesting cases that should not cause errors. struct S should not error
264// while struct T should error at the access specifier mismatch at the end.
265namespace AllDecls {
266#if defined(FIRST)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000267typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000268struct S {
269 public:
270 private:
271 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000272
273 static_assert(1 == 1, "Message");
274 static_assert(2 == 2);
Richard Trieud0786092017-02-23 00:23:01 +0000275
276 int x;
277 double y;
Richard Trieu8459ddf2017-02-24 02:59:12 +0000278
279 INT z;
Richard Trieu93772fc2017-02-24 20:59:28 +0000280
281 unsigned a : 1;
282 unsigned b : 2*2 + 5/2;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000283};
284#elif defined(SECOND)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000285typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000286struct S {
287 public:
288 private:
289 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000290
291 static_assert(1 == 1, "Message");
292 static_assert(2 == 2);
Richard Trieud0786092017-02-23 00:23:01 +0000293
294 int x;
295 double y;
Richard Trieu8459ddf2017-02-24 02:59:12 +0000296
297 INT z;
Richard Trieu93772fc2017-02-24 20:59:28 +0000298
299 unsigned a : 1;
300 unsigned b : 2 * 2 + 5 / 2;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000301};
302#else
303S s;
304#endif
305
306#if defined(FIRST)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000307typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000308struct T {
309 public:
310 private:
311 protected:
312
Richard Trieu639d7b62017-02-22 22:22:42 +0000313 static_assert(1 == 1, "Message");
314 static_assert(2 == 2);
315
Richard Trieud0786092017-02-23 00:23:01 +0000316 int x;
317 double y;
318
Richard Trieu8459ddf2017-02-24 02:59:12 +0000319 INT z;
320
Richard Trieu93772fc2017-02-24 20:59:28 +0000321 unsigned a : 1;
322 unsigned b : 2 * 2 + 5 / 2;
323
Richard Trieue7f7ed22017-02-22 01:11:25 +0000324 private:
325};
326#elif defined(SECOND)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000327typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000328struct T {
329 public:
330 private:
331 protected:
332
Richard Trieu639d7b62017-02-22 22:22:42 +0000333 static_assert(1 == 1, "Message");
334 static_assert(2 == 2);
335
Richard Trieud0786092017-02-23 00:23:01 +0000336 int x;
337 double y;
338
Richard Trieu8459ddf2017-02-24 02:59:12 +0000339 INT z;
340
Richard Trieu93772fc2017-02-24 20:59:28 +0000341 unsigned a : 1;
342 unsigned b : 2 * 2 + 5 / 2;
343
Richard Trieue7f7ed22017-02-22 01:11:25 +0000344 public:
345};
346#else
347T t;
348// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
349// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
350#endif
351}
352
353namespace FriendFunction {
354#if defined(FIRST)
355void F(int = 0);
356struct S { friend void F(int); };
357#elif defined(SECOND)
358void F(int);
359struct S { friend void F(int); };
360#else
361S s;
362#endif
363
364#if defined(FIRST)
365void G(int = 0);
366struct T {
367 friend void G(int);
368
369 private:
370};
371#elif defined(SECOND)
372void G(int);
373struct T {
374 friend void G(int);
375
376 public:
377};
378#else
379T t;
380// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
381// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
382#endif
383} // namespace FriendFunction
384
385namespace ImplicitDecl {
386#if defined(FIRST)
387struct S { };
388void S_Constructors() {
389 // Trigger creation of implicit contructors
390 S foo;
391 S bar = foo;
392 S baz(bar);
393}
394#elif defined(SECOND)
395struct S { };
396#else
397S s;
398#endif
399
400#if defined(FIRST)
401struct T {
402 private:
403};
404void T_Constructors() {
405 // Trigger creation of implicit contructors
406 T foo;
407 T bar = foo;
408 T baz(bar);
409}
410#elif defined(SECOND)
411struct T {
412 public:
413};
414#else
415T t;
416// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}
417// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
418#endif
419
420} // namespace ImplicitDelc
421
422namespace TemplatedClass {
423#if defined(FIRST)
424template <class>
425struct S {};
426#elif defined(SECOND)
427template <class>
428struct S {};
429#else
430S<int> s;
431#endif
432
433#if defined(FIRST)
434template <class>
435struct T {
436 private:
437};
438#elif defined(SECOND)
439template <class>
440struct T {
441 public:
442};
443#else
444T<int> t;
445// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
446// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
447#endif
448} // namespace TemplatedClass
449
450namespace TemplateClassWithField {
451#if defined(FIRST)
452template <class A>
453struct S {
454 A a;
455};
456#elif defined(SECOND)
457template <class A>
458struct S {
459 A a;
460};
461#else
462S<int> s;
463#endif
464
465#if defined(FIRST)
466template <class A>
467struct T {
468 A a;
469
470 private:
471};
472#elif defined(SECOND)
473template <class A>
474struct T {
475 A a;
476
477 public:
478};
479#else
480T<int> t;
481// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
482// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
483#endif
484} // namespace TemplateClassWithField
485
486namespace TemplateClassWithTemplateField {
487#if defined(FIRST)
488template <class A>
489class WrapperS;
490template <class A>
491struct S {
492 WrapperS<A> a;
493};
494#elif defined(SECOND)
495template <class A>
496class WrapperS;
497template <class A>
498struct S {
499 WrapperS<A> a;
500};
501#else
502template <class A>
503class WrapperS{};
504S<int> s;
505#endif
506
507#if defined(FIRST)
508template <class A>
509class WrapperT;
510template <class A>
511struct T {
512 WrapperT<A> a;
513
514 public:
515};
516#elif defined(SECOND)
517template <class A>
518class WrapperT;
519template <class A>
520struct T {
521 WrapperT<A> a;
522
523 private:
524};
525#else
526template <class A>
527class WrapperT{};
528T<int> t;
529// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
530// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
531#endif
532} // namespace TemplateClassWithTemplateField
533
534namespace EnumWithForwardDeclaration {
535#if defined(FIRST)
536enum E : int;
537struct S {
538 void get(E) {}
539};
540#elif defined(SECOND)
541enum E : int { A, B };
542struct S {
543 void get(E) {}
544};
545#else
546S s;
547#endif
548
549#if defined(FIRST)
550struct T {
551 void get(E) {}
552 public:
553};
554#elif defined(SECOND)
555struct T {
556 void get(E) {}
557 private:
558};
559#else
560T t;
561// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
562// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
563#endif
564} // namespace EnumWithForwardDeclaration
565
566namespace StructWithForwardDeclaration {
567#if defined(FIRST)
568struct P {};
569struct S {
570 struct P *ptr;
571};
572#elif defined(SECOND)
573struct S {
574 struct P *ptr;
575};
576#else
577S s;
578#endif
579
580#if defined(FIRST)
581struct Q {};
582struct T {
583 struct Q *ptr;
584 public:
585};
586#elif defined(SECOND)
587struct T {
588 struct Q *ptr;
589 private:
590};
591#else
592T t;
593// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
594// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
595#endif
596} // namespace StructWithForwardDeclaration
597
598namespace StructWithForwardDeclarationNoDefinition {
599#if defined(FIRST)
600struct P;
601struct S {
602 struct P *ptr;
603};
604#elif defined(SECOND)
605struct S {
606 struct P *ptr;
607};
608#else
609S s;
610#endif
611
612#if defined(FIRST)
613struct Q;
614struct T {
615 struct Q *ptr;
616
617 public:
618};
619#elif defined(SECOND)
620struct T {
621 struct Q *ptr;
622
623 private:
624};
625#else
626T t;
627// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
628// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
629#endif
630} // namespace StructWithForwardDeclarationNoDefinition
631
632// Keep macros contained to one file.
633#ifdef FIRST
634#undef FIRST
635#endif
636#ifdef SECOND
637#undef SECOND
638#endif