[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / ClangScanDeps / P1689.cppm
blob4176a06ca3c34da9fc4d4bd689609f25fa729f50
1 // UNSUPPORTED: target={{.*}}-aix{{.*}}
2 //
3 // The slash direction in linux and windows are different.
4 // UNSUPPORTED: system-windows
5 //
6 // RUN: rm -fr %t
7 // RUN: mkdir -p %t
8 // RUN: split-file %s %t
9 //
10 // RUN: sed "s|DIR|%/t|g" %t/P1689.json.in > %t/P1689.json
11 // RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/Checks.cpp -DPREFIX=%/t
12 // RUN: clang-scan-deps --mode=preprocess-dependency-directives -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/Checks.cpp -DPREFIX=%/t
14 // Check the separated dependency format. This is required by CMake for the case
15 // that we have non-exist files in a fresh build and potentially out-of-date after that.
16 // So the build system need to wrtie a compilation database just for scanning purposes,
17 // which is not so good. So here is the per file mode for P1689.
18 // RUN: clang-scan-deps -format=p1689 \
19 // RUN:   -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/M.cppm -o %t/M.o \
20 // RUN:   | FileCheck %t/M.cppm -DPREFIX=%/t
21 // RUN: clang-scan-deps -format=p1689 \
22 // RUN:   -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/Impl.cpp -o %t/Impl.o \
23 // RUN:   | FileCheck %t/Impl.cpp -DPREFIX=%/t
24 // RUN: clang-scan-deps -format=p1689 \
25 // RUN:   -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/impl_part.cppm -o %t/impl_part.o \
26 // RUN:   | FileCheck %t/impl_part.cppm -DPREFIX=%/t
27 // RUN: clang-scan-deps -format=p1689 \
28 // RUN:   -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/interface_part.cppm -o %t/interface_part.o \
29 // RUN:   | FileCheck %t/interface_part.cppm -DPREFIX=%/t
30 // RUN: clang-scan-deps -format=p1689 \
31 // RUN:   -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/User.cpp -o %t/User.o \
32 // RUN:   | FileCheck %t/User.cpp -DPREFIX=%/t
34 // Check we can generate the make-style dependencies as expected.
35 // RUN: clang-scan-deps -format=p1689 \
36 // RUN:   -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/impl_part.cppm -o %t/impl_part.o \
37 // RUN:      -MT %t/impl_part.o.ddi -MD -MF %t/impl_part.dep
38 // RUN:   cat %t/impl_part.dep | FileCheck %t/impl_part.cppm -DPREFIX=%/t --check-prefix=CHECK-MAKE
40 // Check that we can generate multiple make-style dependency information with compilation database.
41 // RUN: cat %t/P1689.dep | FileCheck %t/Checks.cpp -DPREFIX=%/t --check-prefix=CHECK-MAKE
43 // Check that we can mix the use of -format=p1689 and -fmodules.
44 // RUN: clang-scan-deps -format=p1689 \
45 // RUN:   -- %clang++ -std=c++20 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -c %t/impl_part.cppm -o %t/impl_part.o \
46 // RUN:   | FileCheck %t/impl_part.cppm -DPREFIX=%/t
48 // Check the path in the make style dependencies are generated in relative path form
49 // RUN: cd %t
50 // RUN: clang-scan-deps -format=p1689 \
51 // RUN:   -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t impl_part.cppm -o impl_part.o \
52 // RUN:      -MT impl_part.o.ddi -MD -MF impl_part.dep
53 // RUN:   cat impl_part.dep | FileCheck impl_part.cppm -DPREFIX=%/t --check-prefix=CHECK-MAKE-RELATIVE
56 //--- P1689.json.in
59   "directory": "DIR",
60   "command": "clang++ -std=c++20 DIR/M.cppm -c -o DIR/M.o -MT DIR/M.o.ddi -MD -MF DIR/P1689.dep",
61   "file": "DIR/M.cppm",
62   "output": "DIR/M.o"
65   "directory": "DIR",
66   "command": "clang++ -std=c++20 DIR/Impl.cpp -c -o DIR/Impl.o -MT DIR/Impl.o.ddi -MD -MF DIR/P1689.dep",
67   "file": "DIR/Impl.cpp",
68   "output": "DIR/Impl.o"
71   "directory": "DIR",
72   "command": "clang++ -std=c++20 DIR/impl_part.cppm -c -o DIR/impl_part.o -MT DIR/impl_part.o.ddi -MD -MF DIR/P1689.dep",
73   "file": "DIR/impl_part.cppm",
74   "output": "DIR/impl_part.o"
77   "directory": "DIR",
78   "command": "clang++ -std=c++20 DIR/interface_part.cppm -c -o DIR/interface_part.o -MT DIR/interface_part.o.ddi -MD -MF DIR/P1689.dep",
79   "file": "DIR/interface_part.cppm",
80   "output": "DIR/interface_part.o"
83   "directory": "DIR",
84   "command": "clang++ -std=c++20 DIR/User.cpp -c -o DIR/User.o -MT DIR/User.o.ddi -MD -MF DIR/P1689.dep",
85   "file": "DIR/User.cpp",
86   "output": "DIR/User.o"
90 //--- M.cppm
91 export module M;
92 export import :interface_part;
93 import :impl_part;
94 export void Hello();
96 // CHECK: {
97 // CHECK-NEXT:   "revision": 0,
98 // CHECK-NEXT:   "rules": [
99 // CHECK-NEXT:     {
100 // CHECK-NEXT:       "primary-output": "[[PREFIX]]/M.o",
101 // CHECK-NEXT:       "provides": [
102 // CHECK-NEXT:         {
103 // CHECK-NEXT:           "is-interface": true,
104 // CHECK-NEXT:           "logical-name": "M",
105 // CHECK-NEXT:           "source-path": "[[PREFIX]]/M.cppm"
106 // CHECK-NEXT:         }
107 // CHECK-NEXT:       ],
108 // CHECK-NEXT:       "requires": [
109 // CHECK-NEXT:         {
110 // CHECK-NEXT:           "logical-name": "M:interface_part"
111 // CHECK-NEXT:         },
112 // CHECK-NEXT:         {
113 // CHECK-NEXT:           "logical-name": "M:impl_part"
114 // CHECK-NEXT:         }
115 // CHECK-NEXT:       ]
116 // CHECK-NEXT:     }
117 // CHECK-NEXT:   ],
118 // CHECK-NEXT:   "version": 1
119 // CHECK-NEXT: }
121 //--- Impl.cpp
122 module;
123 #include "header.mock"
124 module M;
125 void Hello() {
126     std::cout << "Hello ";
129 // CHECK: {
130 // CHECK-NEXT:   "revision": 0,
131 // CHECK-NEXT:   "rules": [
132 // CHECK-NEXT:     {
133 // CHECK-NEXT:       "primary-output": "[[PREFIX]]/Impl.o",
134 // CHECK-NEXT:       "requires": [
135 // CHECK-NEXT:         {
136 // CHECK-NEXT:           "logical-name": "M"
137 // CHECK-NEXT:         }
138 // CHECK-NEXT:       ]
139 // CHECK-NEXT:     }
140 // CHECK-NEXT:   ],
141 // CHECK-NEXT:   "version": 1
142 // CHECK-NEXT: }
144 //--- impl_part.cppm
145 module;
146 #include "header.mock"
147 module M:impl_part;
148 import :interface_part;
150 std::string W = "World.";
151 void World() {
152     std::cout << W << std::endl;
155 // CHECK: {
156 // CHECK-NEXT:   "revision": 0,
157 // CHECK-NEXT:   "rules": [
158 // CHECK-NEXT:     {
159 // CHECK-NEXT:       "primary-output": "[[PREFIX]]/impl_part.o",
160 // CHECK-NEXT:       "provides": [
161 // CHECK-NEXT:         {
162 // CHECK-NEXT:           "is-interface": false,
163 // CHECK-NEXT:           "logical-name": "M:impl_part",
164 // CHECK-NEXT:           "source-path": "[[PREFIX]]/impl_part.cppm"
165 // CHECK-NEXT:         }
166 // CHECK-NEXT:       ],
167 // CHECK-NEXT:       "requires": [
168 // CHECK-NEXT:         {
169 // CHECK-NEXT:           "logical-name": "M:interface_part"
170 // CHECK-NEXT:         }
171 // CHECK-NEXT:       ]
172 // CHECK-NEXT:     }
173 // CHECK-NEXT:   ],
174 // CHECK-NEXT:   "version": 1
175 // CHECK-NEXT: }
177 // CHECK-MAKE: [[PREFIX]]/impl_part.o.ddi:
178 // CHECK-MAKE:   [[PREFIX]]/impl_part.cppm
179 // CHECK-MAKE:   [[PREFIX]]/header.mock
181 // CHECK-MAKE-RELATIVE: impl_part.o.ddi: impl_part.cppm header.mock
183 //--- interface_part.cppm
184 export module M:interface_part;
185 export void World();
187 // CHECK: {
188 // CHECK-NEXT:   "revision": 0,
189 // CHECK-NEXT:   "rules": [
190 // CHECK-NEXT:     {
191 // CHECK-NEXT:       "primary-output": "[[PREFIX]]/interface_part.o",
192 // CHECK-NEXT:       "provides": [
193 // CHECK-NEXT:         {
194 // CHECK-NEXT:           "is-interface": true,
195 // CHECK-NEXT:           "logical-name": "M:interface_part",
196 // CHECK-NEXT:           "source-path": "[[PREFIX]]/interface_part.cppm"
197 // CHECK-NEXT:         }
198 // CHECK-NEXT:       ]
199 // CHECK-NEXT:     }
200 // CHECK-NEXT:   ],
201 // CHECK-NEXT:   "version": 1
202 // CHECK-NEXT: }
204 //--- User.cpp
205 import M;
206 import third_party_module;
207 int main() {
208     Hello();
209     World();
210     return 0;
213 // CHECK: {
214 // CHECK-NEXT:   "revision": 0,
215 // CHECK-NEXT:   "rules": [
216 // CHECK-NEXT:     {
217 // CHECK-NEXT:       "primary-output": "[[PREFIX]]/User.o",
218 // CHECK-NEXT:       "requires": [
219 // CHECK-NEXT:         {
220 // CHECK-NEXT:           "logical-name": "M"
221 // CHECK-NEXT:         },
222 // CHECK-NEXT:         {
223 // CHECK-NEXT:           "logical-name": "third_party_module"
224 // CHECK-NEXT:         }
225 // CHECK-NEXT:       ]
226 // CHECK-NEXT:     }
227 // CHECK-NEXT:   ],
228 // CHECK-NEXT:   "version": 1
229 // CHECK-NEXT: }
231 //--- Checks.cpp
232 // CHECK: {
233 // CHECK-NEXT:   "revision": 0,
234 // CHECK-NEXT:   "rules": [
235 // CHECK-NEXT:     {
236 // CHECK-NEXT:       "primary-output": "[[PREFIX]]/Impl.o",
237 // CHECK-NEXT:       "requires": [
238 // CHECK-NEXT:         {
239 // CHECK-NEXT:           "logical-name": "M",
240 // CHECK-NEXT:           "source-path": "[[PREFIX]]/M.cppm"
241 // CHECK-NEXT:         }
242 // CHECK-NEXT:       ]
243 // CHECK-NEXT:     },
244 // CHECK-NEXT:     {
245 // CHECK-NEXT:       "primary-output": "[[PREFIX]]/M.o",
246 // CHECK-NEXT:       "provides": [
247 // CHECK-NEXT:         {
248 // CHECK-NEXT:           "is-interface": true,
249 // CHECK-NEXT:           "logical-name": "M",
250 // CHECK-NEXT:           "source-path": "[[PREFIX]]/M.cppm"
251 // CHECK-NEXT:         }
252 // CHECK-NEXT:       ],
253 // CHECK-NEXT:       "requires": [
254 // CHECK-NEXT:         {
255 // CHECK-NEXT:           "logical-name": "M:interface_part",
256 // CHECK-NEXT:           "source-path": "[[PREFIX]]/interface_part.cppm"
257 // CHECK-NEXT:         },
258 // CHECK-NEXT:         {
259 // CHECK-NEXT:           "logical-name": "M:impl_part",
260 // CHECK-NEXT:           "source-path": "[[PREFIX]]/impl_part.cppm"
261 // CHECK-NEXT:         }
262 // CHECK-NEXT:       ]
263 // CHECK-NEXT:     },
264 // CHECK-NEXT:     {
265 // CHECK-NEXT:       "primary-output": "[[PREFIX]]/User.o",
266 // CHECK-NEXT:       "requires": [
267 // CHECK-NEXT:         {
268 // CHECK-NEXT:           "logical-name": "M",
269 // CHECK-NEXT:           "source-path": "[[PREFIX]]/M.cppm"
270 // CHECK-NEXT:         },
271 // CHECK-NEXT:         {
272 // CHECK-NEXT:           "logical-name": "third_party_module"
273 // CHECK-NEXT:         }
274 // CHECK-NEXT:       ]
275 // CHECK-NEXT:     },
276 // CHECK-NEXT:     {
277 // CHECK-NEXT:       "primary-output": "[[PREFIX]]/impl_part.o",
278 // CHECK-NEXT:       "provides": [
279 // CHECK-NEXT:         {
280 // CHECK-NEXT:           "is-interface": false,
281 // CHECK-NEXT:           "logical-name": "M:impl_part",
282 // CHECK-NEXT:           "source-path": "[[PREFIX]]/impl_part.cppm"
283 // CHECK-NEXT:         }
284 // CHECK-NEXT:       ],
285 // CHECK-NEXT:       "requires": [
286 // CHECK-NEXT:         {
287 // CHECK-NEXT:           "logical-name": "M:interface_part",
288 // CHECK-NEXT:           "source-path": "[[PREFIX]]/interface_part.cppm"
289 // CHECK-NEXT:         }
290 // CHECK-NEXT:       ]
291 // CHECK-NEXT:     },
292 // CHECK-NEXT:     {
293 // CHECK-NEXT:       "primary-output": "[[PREFIX]]/interface_part.o",
294 // CHECK-NEXT:       "provides": [
295 // CHECK-NEXT:         {
296 // CHECK-NEXT:           "is-interface": true,
297 // CHECK-NEXT:           "logical-name": "M:interface_part",
298 // CHECK-NEXT:           "source-path": "[[PREFIX]]/interface_part.cppm"
299 // CHECK-NEXT:         }
300 // CHECK-NEXT:       ]
301 // CHECK-NEXT:     }
302 // CHECK-NEXT:   ],
303 // CHECK-NEXT:   "version": 1
304 // CHECK-NEXT: }
306 // CHECK-MAKE-DAG: [[PREFIX]]/impl_part.o.ddi: \
307 // CHECK-MAKE-DAG-NEXT:   [[PREFIX]]/impl_part.cppm \
308 // CHECK-MAKE-DAG-NEXT:   [[PREFIX]]/header.mock
309 // CHECK-MAKE-DAG: [[PREFIX]]/interface_part.o.ddi: \
310 // CHECK-MAKE-DAG-NEXT:   [[PREFIX]]/interface_part.cppm
311 // CHECK-MAKE-DAG: [[PREFIX]]/M.o.ddi: \
312 // CHECK-MAKE-DAG-NEXT:   [[PREFIX]]/M.cppm
313 // CHECK-MAKE-DAG: [[PREFIX]]/User.o.ddi: \
314 // CHECK-MAKE-DAG-NEXT:   [[PREFIX]]/User.cpp
315 // CHECK-MAKE-DAG: [[PREFIX]]/Impl.o.ddi: \
316 // CHECK-MAKE-DAG-NEXT:   [[PREFIX]]/Impl.cpp \
317 // CHECK-MAKE-DAG-NEXT:   [[PREFIX]]/header.mock
319 //--- module.modulemap
320 module Mock { header "header.mock" }
322 //--- header.mock