1//===- unittests/Lex/DependencyDirectivesScannerTest.cpp ------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "clang/Lex/DependencyDirectivesScanner.h"
10#include "llvm/ADT/SmallString.h"
11#include "gtest/gtest.h"
12
13using namespace llvm;
14using namespace clang;
15using namespace clang::dependency_directives_scan;
16
17static bool minimizeSourceToDependencyDirectives(
18 StringRef Input, SmallVectorImpl<char> &Out,
19 SmallVectorImpl<dependency_directives_scan::Token> &Tokens,
20 SmallVectorImpl<Directive> &Directives) {
21 Out.clear();
22 Tokens.clear();
23 Directives.clear();
24 if (scanSourceForDependencyDirectives(Input, Tokens, Directives))
25 return true;
26
27 raw_svector_ostream OS(Out);
28 printDependencyDirectivesAsSource(Source: Input, Directives, OS);
29 if (!Out.empty() && Out.back() != '\n')
30 Out.push_back(Elt: '\n');
31 Out.push_back(Elt: '\0');
32 Out.pop_back();
33
34 return false;
35}
36
37static bool minimizeSourceToDependencyDirectives(StringRef Input,
38 SmallVectorImpl<char> &Out) {
39 SmallVector<dependency_directives_scan::Token, 16> Tokens;
40 SmallVector<Directive, 32> Directives;
41 return minimizeSourceToDependencyDirectives(Input, Out, Tokens, Directives);
42}
43
44namespace {
45
46TEST(MinimizeSourceToDependencyDirectivesTest, Empty) {
47 SmallVector<char, 128> Out;
48 SmallVector<dependency_directives_scan::Token, 4> Tokens;
49 SmallVector<Directive, 4> Directives;
50
51 ASSERT_FALSE(
52 minimizeSourceToDependencyDirectives("", Out, Tokens, Directives));
53 EXPECT_TRUE(Out.empty());
54 EXPECT_TRUE(Tokens.empty());
55 ASSERT_EQ(1u, Directives.size());
56 ASSERT_EQ(pp_eof, Directives.back().Kind);
57
58 ASSERT_FALSE(minimizeSourceToDependencyDirectives("abc def\nxyz", Out, Tokens,
59 Directives));
60 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
61 EXPECT_TRUE(Tokens.empty());
62 ASSERT_EQ(2u, Directives.size());
63 EXPECT_EQ(tokens_present_before_eof, Directives[0].Kind);
64 EXPECT_EQ(pp_eof, Directives[1].Kind);
65}
66
67TEST(MinimizeSourceToDependencyDirectivesTest, AllTokens) {
68 SmallVector<char, 128> Out;
69 SmallVector<dependency_directives_scan::Token, 4> Tokens;
70 SmallVector<Directive, 4> Directives;
71
72 ASSERT_FALSE(
73 minimizeSourceToDependencyDirectives("#define A\n"
74 "#undef A\n"
75 "#endif\n"
76 "#if A\n"
77 "#ifdef A\n"
78 "#ifndef A\n"
79 "#elifdef A\n"
80 "#elifndef A\n"
81 "#elif A\n"
82 "#else\n"
83 "#include <A>\n"
84 "#include_next <A>\n"
85 "#__include_macros <A>\n"
86 "#import <A>\n"
87 "@import A;\n"
88 "#pragma clang module import A\n"
89 "#pragma push_macro(A)\n"
90 "#pragma pop_macro(A)\n"
91 "#pragma include_alias(<A>, <B>)\n"
92 "export module m;\n"
93 "import m;\n"
94 "#pragma clang system_header\n",
95 Out, Tokens, Directives));
96 EXPECT_EQ(pp_define, Directives[0].Kind);
97 EXPECT_EQ(pp_undef, Directives[1].Kind);
98 EXPECT_EQ(pp_endif, Directives[2].Kind);
99 EXPECT_EQ(pp_if, Directives[3].Kind);
100 EXPECT_EQ(pp_ifdef, Directives[4].Kind);
101 EXPECT_EQ(pp_ifndef, Directives[5].Kind);
102 EXPECT_EQ(pp_elifdef, Directives[6].Kind);
103 EXPECT_EQ(pp_elifndef, Directives[7].Kind);
104 EXPECT_EQ(pp_elif, Directives[8].Kind);
105 EXPECT_EQ(pp_else, Directives[9].Kind);
106 EXPECT_EQ(pp_include, Directives[10].Kind);
107 EXPECT_EQ(pp_include_next, Directives[11].Kind);
108 EXPECT_EQ(pp___include_macros, Directives[12].Kind);
109 EXPECT_EQ(pp_import, Directives[13].Kind);
110 EXPECT_EQ(decl_at_import, Directives[14].Kind);
111 EXPECT_EQ(pp_pragma_import, Directives[15].Kind);
112 EXPECT_EQ(pp_pragma_push_macro, Directives[16].Kind);
113 EXPECT_EQ(pp_pragma_pop_macro, Directives[17].Kind);
114 EXPECT_EQ(pp_pragma_include_alias, Directives[18].Kind);
115 EXPECT_EQ(cxx_export_module_decl, Directives[19].Kind);
116 EXPECT_EQ(cxx_import_decl, Directives[20].Kind);
117 EXPECT_EQ(pp_pragma_system_header, Directives[21].Kind);
118 EXPECT_EQ(pp_eof, Directives[22].Kind);
119}
120
121TEST(MinimizeSourceToDependencyDirectivesTest, EmptyHash) {
122 SmallVector<char, 128> Out;
123
124 ASSERT_FALSE(
125 minimizeSourceToDependencyDirectives("#\n#define MACRO a\n", Out));
126 EXPECT_STREQ("#define MACRO a\n", Out.data());
127}
128
129TEST(MinimizeSourceToDependencyDirectivesTest, HashHash) {
130 SmallVector<char, 128> Out;
131
132 StringRef Source = R"(
133 #define S
134 #if 0
135 ##pragma cool
136 ##include "t.h"
137 #endif
138 #define E
139 )";
140 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
141 EXPECT_STREQ("#define S\n#if 0\n#endif\n#define E\n", Out.data());
142}
143
144TEST(MinimizeSourceToDependencyDirectivesTest, Define) {
145 SmallVector<char, 128> Out;
146 SmallVector<dependency_directives_scan::Token, 4> Tokens;
147 SmallVector<Directive, 4> Directives;
148
149 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO", Out,
150 Tokens, Directives));
151 EXPECT_STREQ("#define MACRO\n", Out.data());
152 ASSERT_EQ(4u, Tokens.size());
153 ASSERT_EQ(2u, Directives.size());
154 ASSERT_EQ(pp_define, Directives.front().Kind);
155}
156
157TEST(MinimizeSourceToDependencyDirectivesTest, DefineSpacing) {
158 SmallVector<char, 128> Out;
159
160 ASSERT_FALSE(
161 minimizeSourceToDependencyDirectives("#define MACRO\n\n\n", Out));
162 EXPECT_STREQ("#define MACRO\n", Out.data());
163
164 ASSERT_FALSE(
165 minimizeSourceToDependencyDirectives("#define MACRO \n\n\n", Out));
166 EXPECT_STREQ("#define MACRO\n", Out.data());
167
168 ASSERT_FALSE(
169 minimizeSourceToDependencyDirectives("#define MACRO a \n\n\n", Out));
170 EXPECT_STREQ("#define MACRO a\n", Out.data());
171
172 ASSERT_FALSE(
173 minimizeSourceToDependencyDirectives("#define MACRO\n\n\n", Out));
174 EXPECT_STREQ("#define MACRO\n", Out.data());
175}
176
177TEST(MinimizeSourceToDependencyDirectivesTest, DefineMacroArguments) {
178 SmallVector<char, 128> Out;
179
180 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO()", Out));
181 EXPECT_STREQ("#define MACRO()\n", Out.data());
182
183 ASSERT_FALSE(
184 minimizeSourceToDependencyDirectives("#define MACRO(a, b...)", Out));
185 EXPECT_STREQ("#define MACRO(a,b...)\n", Out.data());
186
187 ASSERT_FALSE(
188 minimizeSourceToDependencyDirectives("#define MACRO content", Out));
189 EXPECT_STREQ("#define MACRO content\n", Out.data());
190
191 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
192 "#define MACRO con tent ", Out));
193 EXPECT_STREQ("#define MACRO con tent\n", Out.data());
194
195 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
196 "#define MACRO() con tent ", Out));
197 EXPECT_STREQ("#define MACRO() con tent\n", Out.data());
198}
199
200TEST(MinimizeSourceToDependencyDirectivesTest, DefineInvalidMacroArguments) {
201 SmallVector<char, 128> Out;
202
203 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO((a))", Out));
204 EXPECT_STREQ("#define MACRO((a))\n", Out.data());
205
206 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO(", Out));
207 EXPECT_STREQ("#define MACRO(\n", Out.data());
208
209 ASSERT_FALSE(
210 minimizeSourceToDependencyDirectives("#define MACRO(a * b)", Out));
211 EXPECT_STREQ("#define MACRO(a*b)\n", Out.data());
212}
213
214TEST(MinimizeSourceToDependencyDirectivesTest, DefineHorizontalWhitespace) {
215 SmallVector<char, 128> Out;
216
217 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
218 "#define MACRO(\t)\tcon \t tent\t", Out));
219 EXPECT_STREQ("#define MACRO() con tent\n", Out.data());
220
221 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
222 "#define MACRO(\f)\fcon \f tent\f", Out));
223 EXPECT_STREQ("#define MACRO() con tent\n", Out.data());
224
225 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
226 "#define MACRO(\v)\vcon \v tent\v", Out));
227 EXPECT_STREQ("#define MACRO() con tent\n", Out.data());
228
229 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
230 "#define MACRO \t\v\f\v\t con\f\t\vtent\v\f \v", Out));
231 EXPECT_STREQ("#define MACRO con tent\n", Out.data());
232}
233
234TEST(MinimizeSourceToDependencyDirectivesTest, DefineMultilineArgs) {
235 SmallVector<char, 128> Out;
236
237 ASSERT_FALSE(
238 minimizeSourceToDependencyDirectives("#define MACRO(a \\\n"
239 " )",
240 Out));
241 EXPECT_STREQ("#define MACRO(a)\n", Out.data());
242
243 ASSERT_FALSE(
244 minimizeSourceToDependencyDirectives("#define MACRO(a, \\\n"
245 " b) \\\n"
246 " call((a), \\\n"
247 " (b))",
248 Out));
249 EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out.data());
250}
251
252TEST(MinimizeSourceToDependencyDirectivesTest,
253 DefineMultilineArgsCarriageReturn) {
254 SmallVector<char, 128> Out;
255
256 ASSERT_FALSE(
257 minimizeSourceToDependencyDirectives("#define MACRO(a, \\\r"
258 " b) \\\r"
259 " call((a), \\\r"
260 " (b))",
261 Out));
262 EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out.data());
263}
264
265TEST(MinimizeSourceToDependencyDirectivesTest, DefineMultilineArgsStringize) {
266 SmallVector<char, 128> Out;
267
268 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO(a,b) \\\n"
269 " #a \\\n"
270 " #b",
271 Out));
272 EXPECT_STREQ("#define MACRO(a,b) #a #b\n", Out.data());
273}
274
275TEST(MinimizeSourceToDependencyDirectivesTest,
276 DefineMultilineArgsCarriageReturnNewline) {
277 SmallVector<char, 128> Out;
278
279 ASSERT_FALSE(
280 minimizeSourceToDependencyDirectives("#define MACRO(a, \\\r\n"
281 " b) \\\r\n"
282 " call((a), \\\r\n"
283 " (b))",
284 Out));
285 EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out.data());
286}
287
288TEST(MinimizeSourceToDependencyDirectivesTest,
289 DefineMultilineArgsNewlineCarriageReturn) {
290 SmallVector<char, 128> Out;
291
292 ASSERT_FALSE(
293 minimizeSourceToDependencyDirectives("#define MACRO(a, \\\n\r"
294 " b) \\\n\r"
295 " call((a), \\\n\r"
296 " (b))",
297 Out));
298 EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out.data());
299}
300
301TEST(MinimizeSourceToDependencyDirectivesTest, DefineNumber) {
302 SmallVector<char, 128> Out;
303
304 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define 0\n", Out));
305}
306
307TEST(MinimizeSourceToDependencyDirectivesTest, DefineNoName) {
308 SmallVector<char, 128> Out;
309
310 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define &\n", Out));
311}
312
313TEST(MinimizeSourceToDependencyDirectivesTest, DefineNoWhitespace) {
314 SmallVector<char, 128> Out;
315
316 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define AND&\n", Out));
317 EXPECT_STREQ("#define AND&\n", Out.data());
318
319 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define AND\\\n"
320 "&\n",
321 Out));
322 EXPECT_STREQ("#define AND\\\n"
323 "&\n",
324 Out.data());
325}
326
327TEST(MinimizeSourceToDependencyDirectivesTest, MultilineComment) {
328 SmallVector<char, 128> Out;
329
330 ASSERT_FALSE(
331 minimizeSourceToDependencyDirectives("#define MACRO a/*\n"
332 " /*\n"
333 "#define MISSING abc\n"
334 " /*\n"
335 " /* something */ \n"
336 "#include /* \"def\" */ <abc> \n",
337 Out));
338 EXPECT_STREQ("#define MACRO a\n"
339 "#include <abc>\n",
340 Out.data());
341}
342
343TEST(MinimizeSourceToDependencyDirectivesTest, MultilineCommentInStrings) {
344 SmallVector<char, 128> Out;
345
346 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO1 \"/*\"\n"
347 "#define MACRO2 \"*/\"\n",
348 Out));
349 EXPECT_STREQ("#define MACRO1 \"/*\"\n"
350 "#define MACRO2 \"*/\"\n",
351 Out.data());
352}
353
354TEST(MinimizeSourceToDependencyDirectivesTest, CommentSlashSlashStar) {
355 SmallVector<char, 128> Out;
356
357 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
358 "#define MACRO 1 //* blah */\n", Out));
359 EXPECT_STREQ("#define MACRO 1\n", Out.data());
360}
361
362TEST(MinimizeSourceToDependencyDirectivesTest, Ifdef) {
363 SmallVector<char, 128> Out;
364
365 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
366 "#define B\n"
367 "#endif\n",
368 Out));
369 EXPECT_STREQ("#ifdef A\n"
370 "#define B\n"
371 "#endif\n",
372 Out.data());
373
374 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
375 "#define B\n"
376 "#elif B\n"
377 "#define C\n"
378 "#elif C\n"
379 "#define D\n"
380 "#else\n"
381 "#define E\n"
382 "#endif\n",
383 Out));
384 EXPECT_STREQ("#ifdef A\n"
385 "#define B\n"
386 "#elif B\n"
387 "#define C\n"
388 "#elif C\n"
389 "#define D\n"
390 "#else\n"
391 "#define E\n"
392 "#endif\n",
393 Out.data());
394}
395
396TEST(MinimizeSourceToDependencyDirectivesTest, Elifdef) {
397 SmallVector<char, 128> Out;
398
399 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
400 "#define B\n"
401 "#elifdef C\n"
402 "#define D\n"
403 "#endif\n",
404 Out));
405 EXPECT_STREQ("#ifdef A\n"
406 "#define B\n"
407 "#elifdef C\n"
408 "#define D\n"
409 "#endif\n",
410 Out.data());
411
412 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
413 "#define B\n"
414 "#elifdef B\n"
415 "#define C\n"
416 "#elifndef C\n"
417 "#define D\n"
418 "#else\n"
419 "#define E\n"
420 "#endif\n",
421 Out));
422 EXPECT_STREQ("#ifdef A\n"
423 "#define B\n"
424 "#elifdef B\n"
425 "#define C\n"
426 "#elifndef C\n"
427 "#define D\n"
428 "#else\n"
429 "#define E\n"
430 "#endif\n",
431 Out.data());
432}
433
434TEST(MinimizeSourceToDependencyDirectivesTest, EmptyIfdef) {
435 SmallVector<char, 128> Out;
436
437 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
438 "void skip();\n"
439 "#elif B\n"
440 "#elif C\n"
441 "#else D\n"
442 "#endif\n",
443 Out));
444 EXPECT_STREQ("#ifdef A\n"
445 "#elif B\n"
446 "#elif C\n"
447 "#endif\n",
448 Out.data());
449}
450
451TEST(MinimizeSourceToDependencyDirectivesTest, EmptyElifdef) {
452 SmallVector<char, 128> Out;
453
454 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
455 "void skip();\n"
456 "#elifdef B\n"
457 "#elifndef C\n"
458 "#else D\n"
459 "#endif\n",
460 Out));
461 EXPECT_STREQ("#ifdef A\n"
462 "#elifdef B\n"
463 "#elifndef C\n"
464 "#endif\n",
465 Out.data());
466}
467
468TEST(MinimizeSourceToDependencyDirectivesTest, Pragma) {
469 SmallVector<char, 128> Out;
470
471 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#pragma A\n", Out));
472 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
473
474 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
475 "#pragma push_macro(\"MACRO\")\n", Out));
476 EXPECT_STREQ("#pragma push_macro(\"MACRO\")\n", Out.data());
477
478 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
479 "#pragma pop_macro(\"MACRO\")\n", Out));
480 EXPECT_STREQ("#pragma pop_macro(\"MACRO\")\n", Out.data());
481
482 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
483 "#pragma include_alias(\"A\", \"B\")\n", Out));
484 EXPECT_STREQ("#pragma include_alias(\"A\", \"B\")\n", Out.data());
485
486 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
487 "#pragma include_alias(<A>, <B>)\n", Out));
488 EXPECT_STREQ("#pragma include_alias(<A>, <B>)\n", Out.data());
489
490 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#pragma clang\n", Out));
491 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
492
493 ASSERT_FALSE(
494 minimizeSourceToDependencyDirectives("#pragma clang module\n", Out));
495 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
496
497 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
498 "#pragma clang module impor\n", Out));
499 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
500
501 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
502 "#pragma clang module import\n", Out));
503 EXPECT_STREQ("#pragma clang module import\n", Out.data());
504}
505
506TEST(MinimizeSourceToDependencyDirectivesTest, UnderscorePragma) {
507 SmallVector<char, 128> Out;
508
509 ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_)", Out));
510 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
511 ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma)", Out));
512 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
513 ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma()", Out));
514 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
515 ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma())", Out));
516 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
517 ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma(")", Out));
518 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
519 ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma("A"))", Out));
520 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
521
522 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
523 R"x(_Pragma("push_macro(\"MACRO\")"))x", Out));
524 EXPECT_STREQ(R"x(_Pragma("push_macro(\"MACRO\")"))x"
525 "\n",
526 Out.data());
527
528 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
529 R"x(_Pragma("pop_macro(\"MACRO\")"))x", Out));
530 EXPECT_STREQ(R"x(_Pragma("pop_macro(\"MACRO\")"))x"
531 "\n",
532 Out.data());
533
534 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
535 R"x(_Pragma("include_alias(\"A\", \"B\")"))x", Out));
536 EXPECT_STREQ(R"x(_Pragma("include_alias(\"A\", \"B\")"))x"
537 "\n",
538 Out.data());
539
540 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
541 R"x(_Pragma("include_alias(<A>, <B>)"))x", Out));
542 EXPECT_STREQ(R"x(_Pragma("include_alias(<A>, <B>)"))x"
543 "\n",
544 Out.data());
545
546 ASSERT_FALSE(
547 minimizeSourceToDependencyDirectives(R"(_Pragma("clang"))", Out));
548 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
549
550 ASSERT_FALSE(
551 minimizeSourceToDependencyDirectives(R"(_Pragma("clang module"))", Out));
552 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
553
554 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
555 R"(_Pragma("clang module impor"))", Out));
556 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
557
558 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
559 R"(_Pragma("clang module import"))", Out));
560 EXPECT_STREQ(R"(_Pragma("clang module import"))"
561 "\n",
562 Out.data());
563
564 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
565 R"(_Pragma("clang \
566 module \
567 import"))",
568 Out));
569 EXPECT_STREQ(R"(_Pragma("clang \
570 module \
571 import"))"
572 "\n",
573 Out.data());
574
575 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
576 R"(_Pragma(L"clang module import"))", Out));
577 EXPECT_STREQ(R"(_Pragma(L"clang module import"))"
578 "\n",
579 Out.data());
580
581 // FIXME: u"" strings depend on using C11 language mode
582 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
583 R"(_Pragma(u"clang module import"))", Out));
584 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
585
586 // R"()" strings are enabled by default.
587 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
588 R"(_Pragma(R"abc(clang module import)abc"))", Out));
589 EXPECT_STREQ(R"(_Pragma(R"abc(clang module import)abc"))"
590 "\n",
591 Out.data());
592}
593
594TEST(MinimizeSourceToDependencyDirectivesTest, Include) {
595 SmallVector<char, 128> Out;
596
597 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include \"A\"\n", Out));
598 EXPECT_STREQ("#include \"A\"\n", Out.data());
599
600 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include <A>\n", Out));
601 EXPECT_STREQ("#include <A>\n", Out.data());
602
603 ASSERT_FALSE(
604 minimizeSourceToDependencyDirectives("#include <A//A.h>\n", Out));
605 EXPECT_STREQ("#include <A//A.h>\n", Out.data());
606
607 ASSERT_FALSE(
608 minimizeSourceToDependencyDirectives("#include \"A//A.h\"\n", Out));
609 EXPECT_STREQ("#include \"A//A.h\"\n", Out.data());
610
611 ASSERT_FALSE(
612 minimizeSourceToDependencyDirectives("#include_next <A>\n", Out));
613 EXPECT_STREQ("#include_next <A>\n", Out.data());
614
615 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#import <A>\n", Out));
616 EXPECT_STREQ("#import <A>\n", Out.data());
617
618 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#import <A//A.h>\n", Out));
619 EXPECT_STREQ("#import <A//A.h>\n", Out.data());
620
621 ASSERT_FALSE(
622 minimizeSourceToDependencyDirectives("#import \"A//A.h\"\n", Out));
623 EXPECT_STREQ("#import \"A//A.h\"\n", Out.data());
624
625 ASSERT_FALSE(
626 minimizeSourceToDependencyDirectives("#__include_macros <A>\n", Out));
627 EXPECT_STREQ("#__include_macros <A>\n", Out.data());
628
629 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include MACRO\n", Out));
630 EXPECT_STREQ("#include MACRO\n", Out.data());
631}
632
633TEST(MinimizeSourceToDependencyDirectivesTest, AtImport) {
634 SmallVector<char, 128> Out;
635
636 ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A;\n", Out));
637 EXPECT_STREQ("@import A;\n", Out.data());
638
639 ASSERT_FALSE(minimizeSourceToDependencyDirectives(" @ import A;\n", Out));
640 EXPECT_STREQ("@import A;\n", Out.data());
641
642 ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A\n;", Out));
643 EXPECT_STREQ("@import A;\n", Out.data());
644
645 ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A.B;\n", Out));
646 EXPECT_STREQ("@import A.B;\n", Out.data());
647
648 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
649 "@import /*x*/ A /*x*/ . /*x*/ B /*x*/ \n /*x*/ ; /*x*/", Out));
650 EXPECT_STREQ("@import A.B;\n", Out.data());
651}
652
653TEST(MinimizeSourceToDependencyDirectivesTest, EmptyIncludesAndImports) {
654 SmallVector<char, 128> Out;
655
656 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#import\n", Out));
657 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
658
659 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include\n", Out));
660 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
661
662 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
663 "#import \n"
664 "#endif\n",
665 Out));
666 // The ifdef block is removed because it's "empty".
667 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
668
669 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
670 "#import \n"
671 "#define B\n"
672 "#endif\n",
673 Out));
674 EXPECT_STREQ("#ifdef A\n"
675 "#define B\n"
676 "#endif\n",
677 Out.data());
678}
679
680TEST(MinimizeSourceToDependencyDirectivesTest, ImportFailures) {
681 SmallVector<char, 128> Out;
682
683 ASSERT_TRUE(minimizeSourceToDependencyDirectives("@import A\n", Out));
684 ASSERT_FALSE(
685 minimizeSourceToDependencyDirectives("@import MACRO(A);\n", Out));
686 ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import \" \";\n", Out));
687
688 ASSERT_FALSE(minimizeSourceToDependencyDirectives("import <Foo.h>\n"
689 "@import Foo;",
690 Out));
691 EXPECT_STREQ("@import Foo;\n", Out.data());
692
693 ASSERT_FALSE(
694 minimizeSourceToDependencyDirectives("import <Foo.h>\n"
695 "#import <Foo.h>\n"
696 "@;\n"
697 "#pragma clang module import Foo",
698 Out));
699 EXPECT_STREQ("#import <Foo.h>\n"
700 "#pragma clang module import Foo\n",
701 Out.data());
702}
703
704TEST(MinimizeSourceToDependencyDirectivesTest, RawStringLiteral) {
705 SmallVector<char, 128> Out;
706
707 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifndef GUARD\n"
708 "#define GUARD\n"
709 "R\"()\"\n"
710 "#endif\n",
711 Out));
712 EXPECT_STREQ("#ifndef GUARD\n"
713 "#define GUARD\n"
714 "#endif\n",
715 Out.data());
716
717 bool RawStringLiteralResult = minimizeSourceToDependencyDirectives(
718 Input: "#ifndef GUARD\n"
719 "#define GUARD\n"
720 R"raw(static constexpr char bytes[] = R"(-?:\,[]{}#&*!|>'"%@`)";)raw"
721 "\n"
722 "#endif\n",
723 Out);
724 ASSERT_FALSE(RawStringLiteralResult);
725 EXPECT_STREQ("#ifndef GUARD\n"
726 "#define GUARD\n"
727 "#endif\n",
728 Out.data());
729
730 bool RawStringLiteralResult2 = minimizeSourceToDependencyDirectives(
731 Input: "#ifndef GUARD\n"
732 "#define GUARD\n"
733 R"raw(static constexpr char bytes[] = R"abc(-?:\,[]{}#&*!|>'"%@`)abc";)raw"
734 "\n"
735 "#endif\n",
736 Out);
737 ASSERT_FALSE(RawStringLiteralResult2);
738 EXPECT_STREQ("#ifndef GUARD\n"
739 "#define GUARD\n"
740 "#endif\n",
741 Out.data());
742}
743
744TEST(MinimizeSourceToDependencyDirectivesTest, SplitIdentifier) {
745 SmallVector<char, 128> Out;
746
747 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#if\\\n"
748 "ndef GUARD\n"
749 "#define GUARD\n"
750 "#endif\n",
751 Out));
752 EXPECT_STREQ("#if\\\n"
753 "ndef GUARD\n"
754 "#define GUARD\n"
755 "#endif\n",
756 Out.data());
757
758 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\n"
759 "RD\n",
760 Out));
761 EXPECT_STREQ("#define GUA\\\n"
762 "RD\n",
763 Out.data());
764
765 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\r"
766 "RD\n",
767 Out));
768 EXPECT_STREQ("#define GUA\\\r"
769 "RD\n",
770 Out.data());
771
772 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\n"
773 " RD\n",
774 Out));
775 EXPECT_STREQ("#define GUA RD\n", Out.data());
776}
777
778TEST(MinimizeSourceToDependencyDirectivesTest,
779 WhitespaceAfterLineContinuationSlash) {
780 SmallVector<char, 128> Out;
781
782 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define A 1 + \\ \n"
783 "2 + \\\t\n"
784 "3\n",
785 Out));
786 EXPECT_STREQ("#define A 1+\\ \n"
787 "2+\\\t\n"
788 "3\n",
789 Out.data());
790}
791
792TEST(MinimizeSourceToDependencyDirectivesTest,
793 WhitespaceAfterLineContinuationSlashLineComment) {
794 SmallVector<char, 128> Out;
795
796 ASSERT_FALSE(minimizeSourceToDependencyDirectives("// some comment \\ \n"
797 "module A;\n",
798 Out));
799 EXPECT_STREQ("", Out.data());
800}
801
802TEST(MinimizeSourceToDependencyDirectivesTest,
803 WhitespaceAfterLineContinuationSlashAllDirectives) {
804 SmallVector<char, 512> Out;
805 SmallVector<dependency_directives_scan::Token, 16> Tokens;
806 SmallVector<Directive, 16> Directives;
807
808 StringRef Input = "#define \\ \n"
809 "A\n"
810 "#undef\t\\ \n"
811 "A\n"
812 "#endif \\\t\t\n"
813 "\n"
814 "#if \\ \t\n"
815 "A\n"
816 "#ifdef\t\\ \n"
817 "A\n"
818 "#ifndef \\ \t\n"
819 "A\n"
820 "#elifdef \\ \n"
821 "A\n"
822 "#elifndef \\ \n"
823 "A\n"
824 "#elif \\\t\t \n"
825 "A\n"
826 "#else \\\t \t\n"
827 "\n"
828 "#include \\ \n"
829 "<A>\n"
830 "#include_next \\ \n"
831 "<A>\n"
832 "#__include_macros\\ \n"
833 "<A>\n"
834 "#import \\ \t\n"
835 "<A>\n"
836 "@import \\\t \n"
837 "A;\n"
838 "#pragma clang \\ \n"
839 "module \\ \n"
840 "import A\n"
841 "#pragma \\ \n"
842 "push_macro(A)\n"
843 "#pragma \\\t \n"
844 "pop_macro(A)\n"
845 "#pragma \\ \n"
846 "include_alias(<A>,\\ \n"
847 "<B>)\n"
848 "export \\ \n"
849 "module m;\n"
850 "import\t\\\t \n"
851 "m;\n"
852 "#pragma\t\\ \n"
853 "clang\t\\ \t\n"
854 "system_header\n";
855 ASSERT_FALSE(
856 minimizeSourceToDependencyDirectives(Input, Out, Tokens, Directives));
857
858 EXPECT_EQ(pp_define, Directives[0].Kind);
859 EXPECT_EQ(pp_undef, Directives[1].Kind);
860 EXPECT_EQ(pp_endif, Directives[2].Kind);
861 EXPECT_EQ(pp_if, Directives[3].Kind);
862 EXPECT_EQ(pp_ifdef, Directives[4].Kind);
863 EXPECT_EQ(pp_ifndef, Directives[5].Kind);
864 EXPECT_EQ(pp_elifdef, Directives[6].Kind);
865 EXPECT_EQ(pp_elifndef, Directives[7].Kind);
866 EXPECT_EQ(pp_elif, Directives[8].Kind);
867 EXPECT_EQ(pp_else, Directives[9].Kind);
868 EXPECT_EQ(pp_include, Directives[10].Kind);
869 EXPECT_EQ(pp_include_next, Directives[11].Kind);
870 EXPECT_EQ(pp___include_macros, Directives[12].Kind);
871 EXPECT_EQ(pp_import, Directives[13].Kind);
872 EXPECT_EQ(decl_at_import, Directives[14].Kind);
873 EXPECT_EQ(pp_pragma_import, Directives[15].Kind);
874 EXPECT_EQ(pp_pragma_push_macro, Directives[16].Kind);
875 EXPECT_EQ(pp_pragma_pop_macro, Directives[17].Kind);
876 EXPECT_EQ(pp_pragma_include_alias, Directives[18].Kind);
877 EXPECT_EQ(cxx_export_module_decl, Directives[19].Kind);
878 EXPECT_EQ(cxx_import_decl, Directives[20].Kind);
879 EXPECT_EQ(pp_pragma_system_header, Directives[21].Kind);
880 EXPECT_EQ(pp_eof, Directives[22].Kind);
881}
882
883TEST(MinimizeSourceToDependencyDirectivesTest,
884 TestFixedBugThatReportUnterminatedDirectiveFalsely) {
885 SmallVector<char, 512> Out;
886 SmallVector<dependency_directives_scan::Token, 16> Tokens;
887 SmallVector<Directive, 16> Directives;
888
889 StringRef Input = "#ifndef __TEST \n"
890 "#define __TEST \n"
891 "#if defined(__TEST_DUMMY) \n"
892 "#if defined(__TEST_DUMMY2) \n"
893 "#pragma GCC warning \\ \n"
894 "\"hello!\"\n"
895 "#else\n"
896 "#pragma GCC error \\ \n"
897 "\"world!\" \n"
898 "#endif // defined(__TEST_DUMMY2) \n"
899 "#endif // defined(__TEST_DUMMY) \n"
900 "#endif // #ifndef __TEST \n";
901 ASSERT_FALSE( // False on no error:
902 minimizeSourceToDependencyDirectives(Input, Out, Tokens, Directives));
903 ASSERT_TRUE(Directives.size() == 8);
904 EXPECT_EQ(pp_ifndef, Directives[0].Kind);
905 EXPECT_EQ(pp_define, Directives[1].Kind);
906 EXPECT_EQ(pp_if, Directives[2].Kind);
907 EXPECT_EQ(pp_if, Directives[3].Kind);
908 EXPECT_EQ(pp_endif, Directives[4].Kind);
909 EXPECT_EQ(pp_endif, Directives[5].Kind);
910 EXPECT_EQ(pp_endif, Directives[6].Kind);
911 EXPECT_EQ(pp_eof, Directives[7].Kind);
912}
913
914TEST(MinimizeSourceToDependencyDirectivesTest, PoundWarningAndError) {
915 SmallVector<char, 128> Out;
916
917 for (auto Source : {
918 "#warning '\n#include <t.h>\n",
919 "#warning \"\n#include <t.h>\n",
920 "#warning /*\n#include <t.h>\n",
921 "#warning \\\n#include <t.h>\n#include <t.h>\n",
922 "#error '\n#include <t.h>\n",
923 "#error \"\n#include <t.h>\n",
924 "#error /*\n#include <t.h>\n",
925 "#error \\\n#include <t.h>\n#include <t.h>\n",
926 }) {
927 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
928 EXPECT_STREQ("#include <t.h>\n", Out.data());
929 }
930
931 for (auto Source : {
932 "#warning \\\n#include <t.h>\n",
933 "#error \\\n#include <t.h>\n",
934 }) {
935 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
936 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
937 }
938
939 for (auto Source : {
940 "#if MACRO\n#warning '\n#endif\n",
941 "#if MACRO\n#warning \"\n#endif\n",
942 "#if MACRO\n#warning /*\n#endif\n",
943 "#if MACRO\n#error '\n#endif\n",
944 "#if MACRO\n#error \"\n#endif\n",
945 "#if MACRO\n#error /*\n#endif\n",
946 }) {
947 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
948 EXPECT_STREQ("#if MACRO\n#endif\n", Out.data());
949 }
950}
951
952TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteral) {
953 SmallVector<char, 128> Out;
954
955 StringRef Source = R"(
956#include <bob>
957int a = 0'1;
958int b = 0xfa'af'fa;
959int c = 12 ' ';
960#include <foo>
961)";
962 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
963 EXPECT_STREQ("#include <bob>\n#include <foo>\n", Out.data());
964}
965
966TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixL) {
967 SmallVector<char, 128> Out;
968
969 StringRef Source = R"(L'P'
970#if DEBUG
971// '
972#endif
973#include <test.h>
974)";
975 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
976 EXPECT_STREQ("#if DEBUG\n#endif\n#include <test.h>\n", Out.data());
977}
978
979TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixU) {
980 SmallVector<char, 128> Out;
981
982 StringRef Source = R"(int x = U'P';
983#include <test.h>
984// '
985)";
986 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
987 EXPECT_STREQ("#include <test.h>\n", Out.data());
988}
989
990TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixu) {
991 SmallVector<char, 128> Out;
992
993 StringRef Source = R"(int x = u'b';
994int y = u8'a';
995int z = 128'78;
996#include <test.h>
997// '
998)";
999 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1000 EXPECT_STREQ("#include <test.h>\n", Out.data());
1001}
1002
1003TEST(MinimizeSourceToDependencyDirectivesTest, PragmaOnce) {
1004 SmallVector<char, 128> Out;
1005 SmallVector<dependency_directives_scan::Token, 4> Tokens;
1006 SmallVector<Directive, 4> Directives;
1007
1008 StringRef Source = R"(// comment
1009#pragma once
1010// another comment
1011#include <test.h>
1012_Pragma("once")
1013)";
1014 ASSERT_FALSE(
1015 minimizeSourceToDependencyDirectives(Source, Out, Tokens, Directives));
1016 EXPECT_STREQ("#pragma once\n#include <test.h>\n_Pragma(\"once\")\n",
1017 Out.data());
1018 ASSERT_EQ(Directives.size(), 4u);
1019 EXPECT_EQ(Directives[0].Kind, dependency_directives_scan::pp_pragma_once);
1020 EXPECT_EQ(Directives[2].Kind, dependency_directives_scan::pp_pragma_once);
1021
1022 Source = R"(// comment
1023 #pragma once extra tokens
1024 // another comment
1025 #include <test.h>
1026 _Pragma("once") extra tokens
1027 )";
1028 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1029 EXPECT_STREQ("#pragma once extra tokens\n#include "
1030 "<test.h>\n_Pragma(\"once\")<TokBeforeEOF>\n",
1031 Out.data());
1032}
1033
1034TEST(MinimizeSourceToDependencyDirectivesTest,
1035 SkipLineStringCharLiteralsUntilNewline) {
1036 SmallVector<char, 128> Out;
1037
1038 StringRef Source = R"(#if NEVER_ENABLED
1039 #define why(fmt, ...) #error don't try me
1040 #endif
1041
1042 void foo();
1043)";
1044 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1045 EXPECT_STREQ(
1046 "#if NEVER_ENABLED\n#define why(fmt,...) #error don't try me\n#endif\n"
1047 "<TokBeforeEOF>\n",
1048 Out.data());
1049
1050 Source = R"(#if NEVER_ENABLED
1051 #define why(fmt, ...) "quote dropped
1052 #endif
1053
1054 void foo();
1055 )";
1056 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1057 EXPECT_STREQ(
1058 "#if NEVER_ENABLED\n#define why(fmt,...) \"quote dropped\n#endif\n"
1059 "<TokBeforeEOF>\n",
1060 Out.data());
1061}
1062
1063TEST(MinimizeSourceToDependencyDirectivesTest,
1064 SupportWhitespaceBeforeLineContinuation) {
1065 SmallVector<char, 128> Out;
1066
1067 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define FOO(BAR) \\\n"
1068 " #BAR\\\n"
1069 " baz\n",
1070 Out));
1071 EXPECT_STREQ("#define FOO(BAR) #BAR baz\n", Out.data());
1072}
1073
1074TEST(MinimizeSourceToDependencyDirectivesTest,
1075 SupportWhitespaceBeforeLineContinuationInStringSkipping) {
1076 SmallVector<char, 128> Out;
1077
1078 StringRef Source = "#define X '\\ \t\nx'\nvoid foo() {}";
1079 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1080 EXPECT_STREQ("#define X '\\ \t\nx'\n<TokBeforeEOF>\n", Out.data());
1081
1082 Source = "#define X \"\\ \r\nx\"\nvoid foo() {}";
1083 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1084 EXPECT_STREQ("#define X \"\\ \r\nx\"\n<TokBeforeEOF>\n", Out.data());
1085
1086 Source = "#define X \"\\ \r\nx\n#include <x>\n";
1087 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1088 EXPECT_STREQ("#define X\"\\ \r\nx\n#include <x>\n", Out.data());
1089}
1090
1091TEST(MinimizeSourceToDependencyDirectivesTest, CxxModules) {
1092 SmallVector<char, 128> Out;
1093 SmallVector<dependency_directives_scan::Token, 4> Tokens;
1094 SmallVector<Directive, 4> Directives;
1095
1096 StringRef Source = R"(
1097 module;
1098 #include "textual-header.h"
1099
1100 export module m;
1101 exp\
1102ort \
1103 import \
1104 :l [[rename]];
1105
1106 export void f();
1107
1108 void h() {
1109 import.a = 3;
1110 import = 3;
1111 import <<= 3;
1112 import->a = 3;
1113 import();
1114 import . a();
1115
1116 import a b d e d e f e;
1117 import foo [[no_unique_address]];
1118 import foo();
1119 import f(:sefse);
1120 import f(->a = 3);
1121 }
1122 )";
1123 ASSERT_FALSE(
1124 minimizeSourceToDependencyDirectives(Source, Out, Tokens, Directives));
1125 EXPECT_STREQ("#include \"textual-header.h\"\nexport module m;"
1126 "exp\\\nort import:l[[rename]];"
1127 "import<<=3;import a b d e d e f e;"
1128 "import foo[[no_unique_address]];import foo();"
1129 "import f(:sefse);import f(->a=3);"
1130 "<TokBeforeEOF>\n",
1131 Out.data());
1132 ASSERT_EQ(Directives.size(), 11u);
1133 EXPECT_EQ(Directives[0].Kind, pp_include);
1134 EXPECT_EQ(Directives[1].Kind, cxx_export_module_decl);
1135}
1136
1137TEST(MinimizeSourceToDependencyDirectivesTest, ObjCMethodArgs) {
1138 SmallVector<char, 128> Out;
1139
1140 StringRef Source = R"(
1141 @interface SomeObjcClass
1142 - (void)func:(int)otherData
1143 module:(int)module
1144 import:(int)import;
1145 @end
1146 )";
1147
1148 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1149 // `module :` and `import :` not followed by an identifier are not treated as
1150 // directive lines because they can be method argument decls.
1151 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
1152}
1153
1154TEST(MinimizeSourceToDependencyDirectivesTest,
1155 CxxModulesImportScopeResolution) {
1156 SmallString<16> Out;
1157 SmallVector<dependency_directives_scan::Token, 2> Tokens;
1158 SmallVector<Directive, 1> Directives;
1159
1160 StringRef Source = "import::inner xi = {};'\n"
1161 "module::inner yi = {};";
1162 ASSERT_FALSE(
1163 minimizeSourceToDependencyDirectives(Source, Out, Tokens, Directives));
1164 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
1165}
1166
1167TEST(MinimizeSourceToDependencyDirectivesTest, TokensBeforeEOF) {
1168 SmallString<128> Out;
1169
1170 StringRef Source = R"(
1171 #define A
1172 #ifdef B
1173 int x;
1174 #endif
1175 )";
1176 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1177 EXPECT_STREQ("#define A\n<TokBeforeEOF>\n", Out.data());
1178
1179 Source = R"(
1180 #ifndef A
1181 #define A
1182 #endif // some comment
1183
1184 // other comment
1185 )";
1186 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1187 EXPECT_STREQ("#ifndef A\n#define A\n#endif\n", Out.data());
1188
1189 Source = R"(
1190 #ifndef A
1191 #define A
1192 #endif /* some comment
1193
1194 */
1195 )";
1196 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1197 EXPECT_STREQ("#ifndef A\n#define A\n#endif\n", Out.data());
1198
1199 Source = R"(
1200 #ifndef A
1201 #define A
1202 #endif /* some comment
1203
1204 */
1205 int x;
1206 )";
1207 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1208 EXPECT_STREQ("#ifndef A\n#define A\n#endif\n<TokBeforeEOF>\n", Out.data());
1209}
1210
1211} // end anonymous namespace
1212

source code of clang/unittests/Lex/DependencyDirectivesScannerTest.cpp