blob: 7b696346be306e0918f3c9f99aa4117610555cfd [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 Trieud0786092017-02-23 00:23:01 +0000165} // namespace Field
166
Richard Trieue7f7ed22017-02-22 01:11:25 +0000167// Naive parsing of AST can lead to cycles in processing. Ensure
168// self-references don't trigger an endless cycles of AST node processing.
169namespace SelfReference {
170#if defined(FIRST)
171template <template <int> class T> class Wrapper {};
172
173template <int N> class S {
174 S(Wrapper<::SelfReference::S> &Ref) {}
175};
176
177struct Xx {
178 struct Yy {
179 };
180};
181
182Xx::Xx::Xx::Yy yy;
183
184namespace NNS {
185template <typename> struct Foo;
186template <template <class> class T = NNS::Foo>
187struct NestedNamespaceSpecifier {};
188}
189#endif
190} // namespace SelfReference
191
192// Interesting cases that should not cause errors. struct S should not error
193// while struct T should error at the access specifier mismatch at the end.
194namespace AllDecls {
195#if defined(FIRST)
196struct S {
197 public:
198 private:
199 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000200
201 static_assert(1 == 1, "Message");
202 static_assert(2 == 2);
Richard Trieud0786092017-02-23 00:23:01 +0000203
204 int x;
205 double y;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000206};
207#elif defined(SECOND)
208struct S {
209 public:
210 private:
211 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000212
213 static_assert(1 == 1, "Message");
214 static_assert(2 == 2);
Richard Trieud0786092017-02-23 00:23:01 +0000215
216 int x;
217 double y;
Richard Trieue7f7ed22017-02-22 01:11:25 +0000218};
219#else
220S s;
221#endif
222
223#if defined(FIRST)
224struct T {
225 public:
226 private:
227 protected:
228
Richard Trieu639d7b62017-02-22 22:22:42 +0000229 static_assert(1 == 1, "Message");
230 static_assert(2 == 2);
231
Richard Trieud0786092017-02-23 00:23:01 +0000232 int x;
233 double y;
234
Richard Trieue7f7ed22017-02-22 01:11:25 +0000235 private:
236};
237#elif defined(SECOND)
238struct T {
239 public:
240 private:
241 protected:
242
Richard Trieu639d7b62017-02-22 22:22:42 +0000243 static_assert(1 == 1, "Message");
244 static_assert(2 == 2);
245
Richard Trieud0786092017-02-23 00:23:01 +0000246 int x;
247 double y;
248
Richard Trieue7f7ed22017-02-22 01:11:25 +0000249 public:
250};
251#else
252T t;
253// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
254// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
255#endif
256}
257
258namespace FriendFunction {
259#if defined(FIRST)
260void F(int = 0);
261struct S { friend void F(int); };
262#elif defined(SECOND)
263void F(int);
264struct S { friend void F(int); };
265#else
266S s;
267#endif
268
269#if defined(FIRST)
270void G(int = 0);
271struct T {
272 friend void G(int);
273
274 private:
275};
276#elif defined(SECOND)
277void G(int);
278struct T {
279 friend void G(int);
280
281 public:
282};
283#else
284T t;
285// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
286// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
287#endif
288} // namespace FriendFunction
289
290namespace ImplicitDecl {
291#if defined(FIRST)
292struct S { };
293void S_Constructors() {
294 // Trigger creation of implicit contructors
295 S foo;
296 S bar = foo;
297 S baz(bar);
298}
299#elif defined(SECOND)
300struct S { };
301#else
302S s;
303#endif
304
305#if defined(FIRST)
306struct T {
307 private:
308};
309void T_Constructors() {
310 // Trigger creation of implicit contructors
311 T foo;
312 T bar = foo;
313 T baz(bar);
314}
315#elif defined(SECOND)
316struct T {
317 public:
318};
319#else
320T t;
321// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}
322// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
323#endif
324
325} // namespace ImplicitDelc
326
327namespace TemplatedClass {
328#if defined(FIRST)
329template <class>
330struct S {};
331#elif defined(SECOND)
332template <class>
333struct S {};
334#else
335S<int> s;
336#endif
337
338#if defined(FIRST)
339template <class>
340struct T {
341 private:
342};
343#elif defined(SECOND)
344template <class>
345struct T {
346 public:
347};
348#else
349T<int> t;
350// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
351// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
352#endif
353} // namespace TemplatedClass
354
355namespace TemplateClassWithField {
356#if defined(FIRST)
357template <class A>
358struct S {
359 A a;
360};
361#elif defined(SECOND)
362template <class A>
363struct S {
364 A a;
365};
366#else
367S<int> s;
368#endif
369
370#if defined(FIRST)
371template <class A>
372struct T {
373 A a;
374
375 private:
376};
377#elif defined(SECOND)
378template <class A>
379struct T {
380 A a;
381
382 public:
383};
384#else
385T<int> t;
386// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
387// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
388#endif
389} // namespace TemplateClassWithField
390
391namespace TemplateClassWithTemplateField {
392#if defined(FIRST)
393template <class A>
394class WrapperS;
395template <class A>
396struct S {
397 WrapperS<A> a;
398};
399#elif defined(SECOND)
400template <class A>
401class WrapperS;
402template <class A>
403struct S {
404 WrapperS<A> a;
405};
406#else
407template <class A>
408class WrapperS{};
409S<int> s;
410#endif
411
412#if defined(FIRST)
413template <class A>
414class WrapperT;
415template <class A>
416struct T {
417 WrapperT<A> a;
418
419 public:
420};
421#elif defined(SECOND)
422template <class A>
423class WrapperT;
424template <class A>
425struct T {
426 WrapperT<A> a;
427
428 private:
429};
430#else
431template <class A>
432class WrapperT{};
433T<int> t;
434// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
435// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
436#endif
437} // namespace TemplateClassWithTemplateField
438
439namespace EnumWithForwardDeclaration {
440#if defined(FIRST)
441enum E : int;
442struct S {
443 void get(E) {}
444};
445#elif defined(SECOND)
446enum E : int { A, B };
447struct S {
448 void get(E) {}
449};
450#else
451S s;
452#endif
453
454#if defined(FIRST)
455struct T {
456 void get(E) {}
457 public:
458};
459#elif defined(SECOND)
460struct T {
461 void get(E) {}
462 private:
463};
464#else
465T t;
466// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
467// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
468#endif
469} // namespace EnumWithForwardDeclaration
470
471namespace StructWithForwardDeclaration {
472#if defined(FIRST)
473struct P {};
474struct S {
475 struct P *ptr;
476};
477#elif defined(SECOND)
478struct S {
479 struct P *ptr;
480};
481#else
482S s;
483#endif
484
485#if defined(FIRST)
486struct Q {};
487struct T {
488 struct Q *ptr;
489 public:
490};
491#elif defined(SECOND)
492struct T {
493 struct Q *ptr;
494 private:
495};
496#else
497T t;
498// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
499// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
500#endif
501} // namespace StructWithForwardDeclaration
502
503namespace StructWithForwardDeclarationNoDefinition {
504#if defined(FIRST)
505struct P;
506struct S {
507 struct P *ptr;
508};
509#elif defined(SECOND)
510struct S {
511 struct P *ptr;
512};
513#else
514S s;
515#endif
516
517#if defined(FIRST)
518struct Q;
519struct T {
520 struct Q *ptr;
521
522 public:
523};
524#elif defined(SECOND)
525struct T {
526 struct Q *ptr;
527
528 private:
529};
530#else
531T t;
532// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
533// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
534#endif
535} // namespace StructWithForwardDeclarationNoDefinition
536
537// Keep macros contained to one file.
538#ifdef FIRST
539#undef FIRST
540#endif
541#ifdef SECOND
542#undef SECOND
543#endif