blob: 8e51a2dc70178e0789d79aa2963e554e9ba1472d [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
194
Richard Trieud0786092017-02-23 00:23:01 +0000195} // namespace Field
196
Richard Trieue7f7ed22017-02-22 01:11:25 +0000197// Naive parsing of AST can lead to cycles in processing. Ensure
198// self-references don't trigger an endless cycles of AST node processing.
199namespace SelfReference {
200#if defined(FIRST)
201template <template <int> class T> class Wrapper {};
202
203template <int N> class S {
204 S(Wrapper<::SelfReference::S> &Ref) {}
205};
206
207struct Xx {
208 struct Yy {
209 };
210};
211
212Xx::Xx::Xx::Yy yy;
213
214namespace NNS {
215template <typename> struct Foo;
216template <template <class> class T = NNS::Foo>
217struct NestedNamespaceSpecifier {};
218}
219#endif
220} // namespace SelfReference
221
222// Interesting cases that should not cause errors. struct S should not error
223// while struct T should error at the access specifier mismatch at the end.
224namespace AllDecls {
225#if defined(FIRST)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000226typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000227struct S {
228 public:
229 private:
230 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000231
232 static_assert(1 == 1, "Message");
233 static_assert(2 == 2);
Richard Trieud0786092017-02-23 00:23:01 +0000234
235 int x;
236 double y;
Richard Trieu8459ddf2017-02-24 02:59:12 +0000237
238 INT z;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000239};
240#elif defined(SECOND)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000241typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000242struct S {
243 public:
244 private:
245 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000246
247 static_assert(1 == 1, "Message");
248 static_assert(2 == 2);
Richard Trieud0786092017-02-23 00:23:01 +0000249
250 int x;
251 double y;
Richard Trieu8459ddf2017-02-24 02:59:12 +0000252
253 INT z;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000254};
255#else
256S s;
257#endif
258
259#if defined(FIRST)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000260typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000261struct T {
262 public:
263 private:
264 protected:
265
Richard Trieu639d7b62017-02-22 22:22:42 +0000266 static_assert(1 == 1, "Message");
267 static_assert(2 == 2);
268
Richard Trieud0786092017-02-23 00:23:01 +0000269 int x;
270 double y;
271
Richard Trieu8459ddf2017-02-24 02:59:12 +0000272 INT z;
273
Richard Trieue7f7ed22017-02-22 01:11:25 +0000274 private:
275};
276#elif defined(SECOND)
Richard Trieu8459ddf2017-02-24 02:59:12 +0000277typedef int INT;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000278struct T {
279 public:
280 private:
281 protected:
282
Richard Trieu639d7b62017-02-22 22:22:42 +0000283 static_assert(1 == 1, "Message");
284 static_assert(2 == 2);
285
Richard Trieud0786092017-02-23 00:23:01 +0000286 int x;
287 double y;
288
Richard Trieu8459ddf2017-02-24 02:59:12 +0000289 INT z;
290
Richard Trieue7f7ed22017-02-22 01:11:25 +0000291 public:
292};
293#else
294T t;
295// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
296// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
297#endif
298}
299
300namespace FriendFunction {
301#if defined(FIRST)
302void F(int = 0);
303struct S { friend void F(int); };
304#elif defined(SECOND)
305void F(int);
306struct S { friend void F(int); };
307#else
308S s;
309#endif
310
311#if defined(FIRST)
312void G(int = 0);
313struct T {
314 friend void G(int);
315
316 private:
317};
318#elif defined(SECOND)
319void G(int);
320struct T {
321 friend void G(int);
322
323 public:
324};
325#else
326T t;
327// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
328// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
329#endif
330} // namespace FriendFunction
331
332namespace ImplicitDecl {
333#if defined(FIRST)
334struct S { };
335void S_Constructors() {
336 // Trigger creation of implicit contructors
337 S foo;
338 S bar = foo;
339 S baz(bar);
340}
341#elif defined(SECOND)
342struct S { };
343#else
344S s;
345#endif
346
347#if defined(FIRST)
348struct T {
349 private:
350};
351void T_Constructors() {
352 // Trigger creation of implicit contructors
353 T foo;
354 T bar = foo;
355 T baz(bar);
356}
357#elif defined(SECOND)
358struct T {
359 public:
360};
361#else
362T t;
363// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}
364// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
365#endif
366
367} // namespace ImplicitDelc
368
369namespace TemplatedClass {
370#if defined(FIRST)
371template <class>
372struct S {};
373#elif defined(SECOND)
374template <class>
375struct S {};
376#else
377S<int> s;
378#endif
379
380#if defined(FIRST)
381template <class>
382struct T {
383 private:
384};
385#elif defined(SECOND)
386template <class>
387struct T {
388 public:
389};
390#else
391T<int> t;
392// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
393// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
394#endif
395} // namespace TemplatedClass
396
397namespace TemplateClassWithField {
398#if defined(FIRST)
399template <class A>
400struct S {
401 A a;
402};
403#elif defined(SECOND)
404template <class A>
405struct S {
406 A a;
407};
408#else
409S<int> s;
410#endif
411
412#if defined(FIRST)
413template <class A>
414struct T {
415 A a;
416
417 private:
418};
419#elif defined(SECOND)
420template <class A>
421struct T {
422 A a;
423
424 public:
425};
426#else
427T<int> t;
428// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
429// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
430#endif
431} // namespace TemplateClassWithField
432
433namespace TemplateClassWithTemplateField {
434#if defined(FIRST)
435template <class A>
436class WrapperS;
437template <class A>
438struct S {
439 WrapperS<A> a;
440};
441#elif defined(SECOND)
442template <class A>
443class WrapperS;
444template <class A>
445struct S {
446 WrapperS<A> a;
447};
448#else
449template <class A>
450class WrapperS{};
451S<int> s;
452#endif
453
454#if defined(FIRST)
455template <class A>
456class WrapperT;
457template <class A>
458struct T {
459 WrapperT<A> a;
460
461 public:
462};
463#elif defined(SECOND)
464template <class A>
465class WrapperT;
466template <class A>
467struct T {
468 WrapperT<A> a;
469
470 private:
471};
472#else
473template <class A>
474class WrapperT{};
475T<int> t;
476// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
477// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
478#endif
479} // namespace TemplateClassWithTemplateField
480
481namespace EnumWithForwardDeclaration {
482#if defined(FIRST)
483enum E : int;
484struct S {
485 void get(E) {}
486};
487#elif defined(SECOND)
488enum E : int { A, B };
489struct S {
490 void get(E) {}
491};
492#else
493S s;
494#endif
495
496#if defined(FIRST)
497struct T {
498 void get(E) {}
499 public:
500};
501#elif defined(SECOND)
502struct T {
503 void get(E) {}
504 private:
505};
506#else
507T t;
508// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
509// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
510#endif
511} // namespace EnumWithForwardDeclaration
512
513namespace StructWithForwardDeclaration {
514#if defined(FIRST)
515struct P {};
516struct S {
517 struct P *ptr;
518};
519#elif defined(SECOND)
520struct S {
521 struct P *ptr;
522};
523#else
524S s;
525#endif
526
527#if defined(FIRST)
528struct Q {};
529struct T {
530 struct Q *ptr;
531 public:
532};
533#elif defined(SECOND)
534struct T {
535 struct Q *ptr;
536 private:
537};
538#else
539T t;
540// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
541// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
542#endif
543} // namespace StructWithForwardDeclaration
544
545namespace StructWithForwardDeclarationNoDefinition {
546#if defined(FIRST)
547struct P;
548struct S {
549 struct P *ptr;
550};
551#elif defined(SECOND)
552struct S {
553 struct P *ptr;
554};
555#else
556S s;
557#endif
558
559#if defined(FIRST)
560struct Q;
561struct T {
562 struct Q *ptr;
563
564 public:
565};
566#elif defined(SECOND)
567struct T {
568 struct Q *ptr;
569
570 private:
571};
572#else
573T t;
574// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
575// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
576#endif
577} // namespace StructWithForwardDeclarationNoDefinition
578
579// Keep macros contained to one file.
580#ifdef FIRST
581#undef FIRST
582#endif
583#ifdef SECOND
584#undef SECOND
585#endif