blob: 652e74f95695e9a9173bd9e04c6dce0fbd672896 [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 Trieue7f7ed22017-02-22 01:11:25 +0000118// Naive parsing of AST can lead to cycles in processing. Ensure
119// self-references don't trigger an endless cycles of AST node processing.
120namespace SelfReference {
121#if defined(FIRST)
122template <template <int> class T> class Wrapper {};
123
124template <int N> class S {
125 S(Wrapper<::SelfReference::S> &Ref) {}
126};
127
128struct Xx {
129 struct Yy {
130 };
131};
132
133Xx::Xx::Xx::Yy yy;
134
135namespace NNS {
136template <typename> struct Foo;
137template <template <class> class T = NNS::Foo>
138struct NestedNamespaceSpecifier {};
139}
140#endif
141} // namespace SelfReference
142
143// Interesting cases that should not cause errors. struct S should not error
144// while struct T should error at the access specifier mismatch at the end.
145namespace AllDecls {
146#if defined(FIRST)
147struct S {
148 public:
149 private:
150 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000151
152 static_assert(1 == 1, "Message");
153 static_assert(2 == 2);
Richard Trieue7f7ed22017-02-22 01:11:25 +0000154};
155#elif defined(SECOND)
156struct S {
157 public:
158 private:
159 protected:
Richard Trieu639d7b62017-02-22 22:22:42 +0000160
161 static_assert(1 == 1, "Message");
162 static_assert(2 == 2);
Richard Trieue7f7ed22017-02-22 01:11:25 +0000163};
164#else
165S s;
166#endif
167
168#if defined(FIRST)
169struct T {
170 public:
171 private:
172 protected:
173
Richard Trieu639d7b62017-02-22 22:22:42 +0000174 static_assert(1 == 1, "Message");
175 static_assert(2 == 2);
176
Richard Trieue7f7ed22017-02-22 01:11:25 +0000177 private:
178};
179#elif defined(SECOND)
180struct T {
181 public:
182 private:
183 protected:
184
Richard Trieu639d7b62017-02-22 22:22:42 +0000185 static_assert(1 == 1, "Message");
186 static_assert(2 == 2);
187
Richard Trieue7f7ed22017-02-22 01:11:25 +0000188 public:
189};
190#else
191T t;
192// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
193// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
194#endif
195}
196
197namespace FriendFunction {
198#if defined(FIRST)
199void F(int = 0);
200struct S { friend void F(int); };
201#elif defined(SECOND)
202void F(int);
203struct S { friend void F(int); };
204#else
205S s;
206#endif
207
208#if defined(FIRST)
209void G(int = 0);
210struct T {
211 friend void G(int);
212
213 private:
214};
215#elif defined(SECOND)
216void G(int);
217struct T {
218 friend void G(int);
219
220 public:
221};
222#else
223T t;
224// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
225// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
226#endif
227} // namespace FriendFunction
228
229namespace ImplicitDecl {
230#if defined(FIRST)
231struct S { };
232void S_Constructors() {
233 // Trigger creation of implicit contructors
234 S foo;
235 S bar = foo;
236 S baz(bar);
237}
238#elif defined(SECOND)
239struct S { };
240#else
241S s;
242#endif
243
244#if defined(FIRST)
245struct T {
246 private:
247};
248void T_Constructors() {
249 // Trigger creation of implicit contructors
250 T foo;
251 T bar = foo;
252 T baz(bar);
253}
254#elif defined(SECOND)
255struct T {
256 public:
257};
258#else
259T t;
260// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}}
261// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}}
262#endif
263
264} // namespace ImplicitDelc
265
266namespace TemplatedClass {
267#if defined(FIRST)
268template <class>
269struct S {};
270#elif defined(SECOND)
271template <class>
272struct S {};
273#else
274S<int> s;
275#endif
276
277#if defined(FIRST)
278template <class>
279struct T {
280 private:
281};
282#elif defined(SECOND)
283template <class>
284struct T {
285 public:
286};
287#else
288T<int> t;
289// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
290// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
291#endif
292} // namespace TemplatedClass
293
294namespace TemplateClassWithField {
295#if defined(FIRST)
296template <class A>
297struct S {
298 A a;
299};
300#elif defined(SECOND)
301template <class A>
302struct S {
303 A a;
304};
305#else
306S<int> s;
307#endif
308
309#if defined(FIRST)
310template <class A>
311struct T {
312 A a;
313
314 private:
315};
316#elif defined(SECOND)
317template <class A>
318struct T {
319 A a;
320
321 public:
322};
323#else
324T<int> t;
325// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}}
326// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
327#endif
328} // namespace TemplateClassWithField
329
330namespace TemplateClassWithTemplateField {
331#if defined(FIRST)
332template <class A>
333class WrapperS;
334template <class A>
335struct S {
336 WrapperS<A> a;
337};
338#elif defined(SECOND)
339template <class A>
340class WrapperS;
341template <class A>
342struct S {
343 WrapperS<A> a;
344};
345#else
346template <class A>
347class WrapperS{};
348S<int> s;
349#endif
350
351#if defined(FIRST)
352template <class A>
353class WrapperT;
354template <class A>
355struct T {
356 WrapperT<A> a;
357
358 public:
359};
360#elif defined(SECOND)
361template <class A>
362class WrapperT;
363template <class A>
364struct T {
365 WrapperT<A> a;
366
367 private:
368};
369#else
370template <class A>
371class WrapperT{};
372T<int> t;
373// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
374// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
375#endif
376} // namespace TemplateClassWithTemplateField
377
378namespace EnumWithForwardDeclaration {
379#if defined(FIRST)
380enum E : int;
381struct S {
382 void get(E) {}
383};
384#elif defined(SECOND)
385enum E : int { A, B };
386struct S {
387 void get(E) {}
388};
389#else
390S s;
391#endif
392
393#if defined(FIRST)
394struct T {
395 void get(E) {}
396 public:
397};
398#elif defined(SECOND)
399struct T {
400 void get(E) {}
401 private:
402};
403#else
404T t;
405// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
406// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
407#endif
408} // namespace EnumWithForwardDeclaration
409
410namespace StructWithForwardDeclaration {
411#if defined(FIRST)
412struct P {};
413struct S {
414 struct P *ptr;
415};
416#elif defined(SECOND)
417struct S {
418 struct P *ptr;
419};
420#else
421S s;
422#endif
423
424#if defined(FIRST)
425struct Q {};
426struct T {
427 struct Q *ptr;
428 public:
429};
430#elif defined(SECOND)
431struct T {
432 struct Q *ptr;
433 private:
434};
435#else
436T t;
437// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
438// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
439#endif
440} // namespace StructWithForwardDeclaration
441
442namespace StructWithForwardDeclarationNoDefinition {
443#if defined(FIRST)
444struct P;
445struct S {
446 struct P *ptr;
447};
448#elif defined(SECOND)
449struct S {
450 struct P *ptr;
451};
452#else
453S s;
454#endif
455
456#if defined(FIRST)
457struct Q;
458struct T {
459 struct Q *ptr;
460
461 public:
462};
463#elif defined(SECOND)
464struct T {
465 struct Q *ptr;
466
467 private:
468};
469#else
470T t;
471// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
472// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}}
473#endif
474} // namespace StructWithForwardDeclarationNoDefinition
475
476// Keep macros contained to one file.
477#ifdef FIRST
478#undef FIRST
479#endif
480#ifdef SECOND
481#undef SECOND
482#endif