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