1// RUN: rm -rf %t
2// RUN: mkdir %t
3// RUN: split-file %s %t
4//
5// RUN: %clang_cc1 -std=c++20 -emit-module-interface -I%t %t/A.cppm -o %t/A.pcm
6// RUN: %clang_cc1 -std=c++20 -emit-module-interface -I%t %t/B.cppm -o %t/B.pcm
7// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use.cpp -verify -fsyntax-only
8// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use2.cpp -verify -fsyntax-only
9// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use3.cpp -verify -fsyntax-only
10// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/Use4.cpp -verify -fsyntax-only
11// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/C.cppm -verify -fsyntax-only
12// RUN: %clang_cc1 -std=c++20 -I%t %t/D.cppm -verify -fsyntax-only
13// RUN: %clang_cc1 -std=c++20 -I%t %t/E.cppm -verify -fsyntax-only
14// RUN: %clang_cc1 -std=c++20 -I%t %t/F.cppm -verify -fsyntax-only
15//
16// Testing header units for coverity.
17// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header %t/foo.h -o %t/foo.pcm
18// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -fmodule-file=%t/foo.pcm %t/Use5.cpp -verify -fsyntax-only
19// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -fmodule-file=%t/foo.pcm %t/Use6.cpp -verify -fsyntax-only
20//
21// Testing with module map modules. It is unclear about the relation ship between Clang modules and
22// C++20 Named Modules. Will they coexist? Or will they be mutually exclusive?
23// The test here is for primarily coverity.
24//
25// RUN: rm -f %t/foo.pcm
26// RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fprebuilt-module-path=%t \
27// RUN:   -fmodule-map-file=%t/module.map %t/Use7.cpp -verify -fsyntax-only
28// RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fprebuilt-module-path=%t \
29// RUN:   -fmodule-map-file=%t/module.map %t/Use7.cpp -verify -fsyntax-only
30// Testing module map modules with named modules.
31// RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%t/module.map \
32// RUN:   %t/A.cppm -o %t/A.pcm
33// RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fprebuilt-module-path=%t \
34// RUN:   -fmodule-map-file=%t/module.map %t/Use7.cpp -verify -fsyntax-only
35// RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fprebuilt-module-path=%t \
36// RUN:   -fmodule-map-file=%t/module.map %t/Use7.cpp -verify -fsyntax-only
37
38//
39//--- foo.h
40#ifndef FOO_H
41#define FOO_H
42template <class T, class U>
43concept same_as = __is_same(T, U);
44#endif
45
46// The compiler would warn if we include foo_h twice without guard.
47//--- redecl.h
48#ifndef REDECL_H
49#define REDECL_H
50template <class T, class U>
51concept same_as = __is_same(T, U);
52#endif
53
54//--- A.cppm
55module;
56#include "foo.h"
57export module A;
58export using ::same_as;
59
60//--- B.cppm
61module;
62#include "foo.h"
63export module B;
64export using ::same_as;
65
66//--- Use.cpp
67// expected-no-diagnostics
68import A;
69import B;
70
71template <class T> void foo()
72  requires same_as<T, int>
73{}
74
75//--- Use2.cpp
76// expected-no-diagnostics
77#include "foo.h"
78import A;
79
80template <class T> void foo()
81  requires same_as<T, int>
82{}
83
84//--- Use3.cpp
85// expected-no-diagnostics
86import A;
87#include "foo.h"
88
89template <class T> void foo()
90  requires same_as<T, int>
91{}
92
93//--- Use4.cpp
94// expected-no-diagnostics
95import A;
96import B;
97#include "foo.h"
98
99template <class T> void foo()
100  requires same_as<T, int>
101{}
102
103//--- C.cppm
104// expected-no-diagnostics
105module;
106#include "foo.h"
107export module C;
108import A;
109import B;
110
111template <class T> void foo()
112  requires same_as<T, int>
113{}
114
115//--- D.cppm
116module;
117#include "foo.h"
118#include "redecl.h"
119export module D;
120export using ::same_as;
121
122// expected-error@* {{redefinition of 'same_as'}}
123// expected-note@* 1+{{previous definition is here}}
124
125//--- E.cppm
126module;
127#include "foo.h"
128export module E;
129export template <class T, class U>
130concept same_as = __is_same(T, U);
131
132// expected-error@* {{redefinition of 'same_as'}}
133// expected-note@* 1+{{previous definition is here}}
134
135//--- F.cppm
136export module F;
137template <class T, class U>
138concept same_as = __is_same(T, U);
139template <class T, class U>
140concept same_as = __is_same(T, U);
141
142// expected-error@* {{redefinition of 'same_as'}}
143// expected-note@* 1+{{previous definition is here}}
144
145//--- Use5.cpp
146// expected-no-diagnostics
147import "foo.h";
148import A;
149
150template <class T> void foo()
151  requires same_as<T, int>
152{}
153
154//--- Use6.cpp
155// expected-no-diagnostics
156import A;
157import "foo.h";
158
159template <class T> void foo()
160  requires same_as<T, int>
161{}
162
163//--- module.map
164module "foo" {
165  export *
166  header "foo.h"
167}
168
169//--- Use7.cpp
170// expected-no-diagnostics
171#include "foo.h"
172import A;
173
174template <class T> void foo()
175  requires same_as<T, int>
176{}
177
178//--- Use8.cpp
179// expected-no-diagnostics
180import A;
181#include "foo.h"
182
183template <class T> void foo()
184  requires same_as<T, int>
185{}
186