[SCCP] Avoid modifying AdditionalUsers while iterating over it
[llvm-project.git] / clang / unittests / Lex / DependencyDirectivesSourceMinimizerTest.cpp
blobb5bba30db78da592887f1d3c4340ddfaf7492ab9
1 //===- unittests/Lex/DependencyDirectivesSourceMinimizer.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 //===----------------------------------------------------------------------===//
9 #include "clang/Lex/DependencyDirectivesSourceMinimizer.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "gtest/gtest.h"
13 using namespace llvm;
14 using namespace clang;
15 using namespace clang::minimize_source_to_dependency_directives;
17 namespace clang {
19 bool minimizeSourceToDependencyDirectives(StringRef Input,
20 SmallVectorImpl<char> &Out) {
21 SmallVector<minimize_source_to_dependency_directives::Token, 32> Tokens;
22 return minimizeSourceToDependencyDirectives(Input, Out, Tokens);
25 } // end namespace clang
27 namespace {
29 TEST(MinimizeSourceToDependencyDirectivesTest, Empty) {
30 SmallVector<char, 128> Out;
31 SmallVector<Token, 4> Tokens;
33 ASSERT_FALSE(minimizeSourceToDependencyDirectives("", Out, Tokens));
34 EXPECT_TRUE(Out.empty());
35 ASSERT_EQ(1u, Tokens.size());
36 ASSERT_EQ(pp_eof, Tokens.back().K);
38 ASSERT_FALSE(
39 minimizeSourceToDependencyDirectives("abc def\nxyz", Out, Tokens));
40 EXPECT_TRUE(Out.empty());
41 ASSERT_EQ(1u, Tokens.size());
42 ASSERT_EQ(pp_eof, Tokens.back().K);
45 TEST(MinimizeSourceToDependencyDirectivesTest, AllTokens) {
46 SmallVector<char, 128> Out;
47 SmallVector<Token, 4> Tokens;
49 ASSERT_FALSE(
50 minimizeSourceToDependencyDirectives("#define A\n"
51 "#undef A\n"
52 "#endif\n"
53 "#if A\n"
54 "#ifdef A\n"
55 "#ifndef A\n"
56 "#elif A\n"
57 "#else\n"
58 "#include <A>\n"
59 "#include_next <A>\n"
60 "#__include_macros <A>\n"
61 "#import <A>\n"
62 "@import A;\n"
63 "#pragma clang module import A\n"
64 "export module m;\n"
65 "import m;\n",
66 Out, Tokens));
67 EXPECT_EQ(pp_define, Tokens[0].K);
68 EXPECT_EQ(pp_undef, Tokens[1].K);
69 EXPECT_EQ(pp_endif, Tokens[2].K);
70 EXPECT_EQ(pp_if, Tokens[3].K);
71 EXPECT_EQ(pp_ifdef, Tokens[4].K);
72 EXPECT_EQ(pp_ifndef, Tokens[5].K);
73 EXPECT_EQ(pp_elif, Tokens[6].K);
74 EXPECT_EQ(pp_else, Tokens[7].K);
75 EXPECT_EQ(pp_include, Tokens[8].K);
76 EXPECT_EQ(pp_include_next, Tokens[9].K);
77 EXPECT_EQ(pp___include_macros, Tokens[10].K);
78 EXPECT_EQ(pp_import, Tokens[11].K);
79 EXPECT_EQ(decl_at_import, Tokens[12].K);
80 EXPECT_EQ(pp_pragma_import, Tokens[13].K);
81 EXPECT_EQ(cxx_export_decl, Tokens[14].K);
82 EXPECT_EQ(cxx_module_decl, Tokens[15].K);
83 EXPECT_EQ(cxx_import_decl, Tokens[16].K);
84 EXPECT_EQ(pp_eof, Tokens[17].K);
87 TEST(MinimizeSourceToDependencyDirectivesTest, Define) {
88 SmallVector<char, 128> Out;
89 SmallVector<Token, 4> Tokens;
91 ASSERT_FALSE(
92 minimizeSourceToDependencyDirectives("#define MACRO", Out, Tokens));
93 EXPECT_STREQ("#define MACRO\n", Out.data());
94 ASSERT_EQ(2u, Tokens.size());
95 ASSERT_EQ(pp_define, Tokens.front().K);
98 TEST(MinimizeSourceToDependencyDirectivesTest, DefineSpacing) {
99 SmallVector<char, 128> Out;
101 ASSERT_FALSE(
102 minimizeSourceToDependencyDirectives("#define MACRO\n\n\n", Out));
103 EXPECT_STREQ("#define MACRO\n", Out.data());
105 ASSERT_FALSE(
106 minimizeSourceToDependencyDirectives("#define MACRO \n\n\n", Out));
107 EXPECT_STREQ("#define MACRO\n", Out.data());
109 ASSERT_FALSE(
110 minimizeSourceToDependencyDirectives("#define MACRO a \n\n\n", Out));
111 EXPECT_STREQ("#define MACRO a\n", Out.data());
113 ASSERT_FALSE(
114 minimizeSourceToDependencyDirectives("#define MACRO\n\n\n", Out));
115 EXPECT_STREQ("#define MACRO\n", Out.data());
118 TEST(MinimizeSourceToDependencyDirectivesTest, DefineMacroArguments) {
119 SmallVector<char, 128> Out;
121 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO()", Out));
122 EXPECT_STREQ("#define MACRO()\n", Out.data());
124 ASSERT_FALSE(
125 minimizeSourceToDependencyDirectives("#define MACRO(a, b...)", Out));
126 EXPECT_STREQ("#define MACRO(a,b...)\n", Out.data());
128 ASSERT_FALSE(
129 minimizeSourceToDependencyDirectives("#define MACRO content", Out));
130 EXPECT_STREQ("#define MACRO content\n", Out.data());
132 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
133 "#define MACRO con tent ", Out));
134 EXPECT_STREQ("#define MACRO con tent\n", Out.data());
136 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
137 "#define MACRO() con tent ", Out));
138 EXPECT_STREQ("#define MACRO() con tent\n", Out.data());
141 TEST(MinimizeSourceToDependencyDirectivesTest, DefineInvalidMacroArguments) {
142 SmallVector<char, 128> Out;
144 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO((a))", Out));
145 EXPECT_STREQ("#define MACRO(/* invalid */\n", Out.data());
147 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO(", Out));
148 EXPECT_STREQ("#define MACRO(/* invalid */\n", Out.data());
150 ASSERT_FALSE(
151 minimizeSourceToDependencyDirectives("#define MACRO(a * b)", Out));
152 EXPECT_STREQ("#define MACRO(/* invalid */\n", Out.data());
155 TEST(MinimizeSourceToDependencyDirectivesTest, DefineHorizontalWhitespace) {
156 SmallVector<char, 128> Out;
158 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
159 "#define MACRO(\t)\tcon \t tent\t", Out));
160 EXPECT_STREQ("#define MACRO() con \t tent\n", Out.data());
162 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
163 "#define MACRO(\f)\fcon \f tent\f", Out));
164 EXPECT_STREQ("#define MACRO() con \f tent\n", Out.data());
166 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
167 "#define MACRO(\v)\vcon \v tent\v", Out));
168 EXPECT_STREQ("#define MACRO() con \v tent\n", Out.data());
170 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
171 "#define MACRO \t\v\f\v\t con\f\t\vtent\v\f \v", Out));
172 EXPECT_STREQ("#define MACRO con\f\t\vtent\n", Out.data());
175 TEST(MinimizeSourceToDependencyDirectivesTest, DefineMultilineArgs) {
176 SmallVector<char, 128> Out;
178 ASSERT_FALSE(
179 minimizeSourceToDependencyDirectives("#define MACRO(a \\\n"
180 " )",
181 Out));
182 EXPECT_STREQ("#define MACRO(a)\n", Out.data());
184 ASSERT_FALSE(
185 minimizeSourceToDependencyDirectives("#define MACRO(a, \\\n"
186 " b) \\\n"
187 " call((a), \\\n"
188 " (b))",
189 Out));
190 EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out.data());
193 TEST(MinimizeSourceToDependencyDirectivesTest,
194 DefineMultilineArgsCarriageReturn) {
195 SmallVector<char, 128> Out;
197 ASSERT_FALSE(
198 minimizeSourceToDependencyDirectives("#define MACRO(a, \\\r"
199 " b) \\\r"
200 " call((a), \\\r"
201 " (b))",
202 Out));
203 EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out.data());
206 TEST(MinimizeSourceToDependencyDirectivesTest, DefineMultilineArgsStringize) {
207 SmallVector<char, 128> Out;
209 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO(a,b) \\\n"
210 " #a \\\n"
211 " #b",
212 Out));
213 EXPECT_STREQ("#define MACRO(a,b) #a #b\n", Out.data());
216 TEST(MinimizeSourceToDependencyDirectivesTest,
217 DefineMultilineArgsCarriageReturnNewline) {
218 SmallVector<char, 128> Out;
220 ASSERT_FALSE(
221 minimizeSourceToDependencyDirectives("#define MACRO(a, \\\r\n"
222 " b) \\\r\n"
223 " call((a), \\\r\n"
224 " (b))",
225 Out));
226 EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out.data());
229 TEST(MinimizeSourceToDependencyDirectivesTest,
230 DefineMultilineArgsNewlineCarriageReturn) {
231 SmallVector<char, 128> Out;
233 ASSERT_FALSE(
234 minimizeSourceToDependencyDirectives("#define MACRO(a, \\\n\r"
235 " b) \\\n\r"
236 " call((a), \\\n\r"
237 " (b))",
238 Out));
239 EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out.data());
242 TEST(MinimizeSourceToDependencyDirectivesTest, DefineNumber) {
243 SmallVector<char, 128> Out;
245 ASSERT_TRUE(minimizeSourceToDependencyDirectives("#define 0\n", Out));
248 TEST(MinimizeSourceToDependencyDirectivesTest, DefineNoName) {
249 SmallVector<char, 128> Out;
251 ASSERT_TRUE(minimizeSourceToDependencyDirectives("#define &\n", Out));
254 TEST(MinimizeSourceToDependencyDirectivesTest, DefineNoWhitespace) {
255 SmallVector<char, 128> Out;
257 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define AND&\n", Out));
258 EXPECT_STREQ("#define AND &\n", Out.data());
260 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define AND\\\n"
261 "&\n",
262 Out));
263 EXPECT_STREQ("#define AND &\n", Out.data());
266 TEST(MinimizeSourceToDependencyDirectivesTest, MultilineComment) {
267 SmallVector<char, 128> Out;
269 ASSERT_FALSE(
270 minimizeSourceToDependencyDirectives("#define MACRO a/*\n"
271 " /*\n"
272 "#define MISSING abc\n"
273 " /*\n"
274 " /* something */ \n"
275 "#include /* \"def\" */ <abc> \n",
276 Out));
277 EXPECT_STREQ("#define MACRO a\n"
278 "#include <abc>\n",
279 Out.data());
282 TEST(MinimizeSourceToDependencyDirectivesTest, MultilineCommentInStrings) {
283 SmallVector<char, 128> Out;
285 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO1 \"/*\"\n"
286 "#define MACRO2 \"*/\"\n",
287 Out));
288 EXPECT_STREQ("#define MACRO1 \"/*\"\n"
289 "#define MACRO2 \"*/\"\n",
290 Out.data());
293 TEST(MinimizeSourceToDependencyDirectivesTest, Ifdef) {
294 SmallVector<char, 128> Out;
296 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
297 "#define B\n"
298 "#endif\n",
299 Out));
300 EXPECT_STREQ("#ifdef A\n"
301 "#define B\n"
302 "#endif\n",
303 Out.data());
305 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
306 "#define B\n"
307 "#elif B\n"
308 "#define C\n"
309 "#elif C\n"
310 "#define D\n"
311 "#else\n"
312 "#define E\n"
313 "#endif\n",
314 Out));
315 EXPECT_STREQ("#ifdef A\n"
316 "#define B\n"
317 "#elif B\n"
318 "#define C\n"
319 "#elif C\n"
320 "#define D\n"
321 "#else\n"
322 "#define E\n"
323 "#endif\n",
324 Out.data());
327 TEST(MinimizeSourceToDependencyDirectivesTest, EmptyIfdef) {
328 SmallVector<char, 128> Out;
330 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
331 "void skip();\n"
332 "#elif B\n"
333 "#elif C\n"
334 "#else D\n"
335 "#endif\n",
336 Out));
337 EXPECT_STREQ("#ifdef A\n"
338 "#elif B\n"
339 "#elif C\n"
340 "#endif\n",
341 Out.data());
344 TEST(MinimizeSourceToDependencyDirectivesTest, Pragma) {
345 SmallVector<char, 128> Out;
347 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#pragma A\n", Out));
348 EXPECT_STREQ("", Out.data());
350 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#pragma clang\n", Out));
351 EXPECT_STREQ("", Out.data());
353 ASSERT_FALSE(
354 minimizeSourceToDependencyDirectives("#pragma clang module\n", Out));
355 EXPECT_STREQ("", Out.data());
357 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
358 "#pragma clang module impor\n", Out));
359 EXPECT_STREQ("", Out.data());
361 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
362 "#pragma clang module import\n", Out));
363 EXPECT_STREQ("#pragma clang module import\n", Out.data());
366 TEST(MinimizeSourceToDependencyDirectivesTest, Include) {
367 SmallVector<char, 128> Out;
369 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include \"A\"\n", Out));
370 EXPECT_STREQ("#include \"A\"\n", Out.data());
372 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include <A>\n", Out));
373 EXPECT_STREQ("#include <A>\n", Out.data());
375 ASSERT_FALSE(
376 minimizeSourceToDependencyDirectives("#include_next <A>\n", Out));
377 EXPECT_STREQ("#include_next <A>\n", Out.data());
379 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#import <A>\n", Out));
380 EXPECT_STREQ("#import <A>\n", Out.data());
382 ASSERT_FALSE(
383 minimizeSourceToDependencyDirectives("#__include_macros <A>\n", Out));
384 EXPECT_STREQ("#__include_macros <A>\n", Out.data());
387 TEST(MinimizeSourceToDependencyDirectivesTest, AtImport) {
388 SmallVector<char, 128> Out;
390 ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A;\n", Out));
391 EXPECT_STREQ("@import A;\n", Out.data());
393 ASSERT_FALSE(minimizeSourceToDependencyDirectives(" @ import A;\n", Out));
394 EXPECT_STREQ("@import A;\n", Out.data());
396 ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A\n;", Out));
397 EXPECT_STREQ("@import A;\n", Out.data());
399 ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A.B;\n", Out));
400 EXPECT_STREQ("@import A.B;\n", Out.data());
402 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
403 "@import /*x*/ A /*x*/ . /*x*/ B /*x*/ \n /*x*/ ; /*x*/", Out));
404 EXPECT_STREQ("@import A.B;\n", Out.data());
407 TEST(MinimizeSourceToDependencyDirectivesTest, AtImportFailures) {
408 SmallVector<char, 128> Out;
410 ASSERT_TRUE(minimizeSourceToDependencyDirectives("@import A\n", Out));
411 ASSERT_TRUE(minimizeSourceToDependencyDirectives("@import MACRO(A);\n", Out));
412 ASSERT_TRUE(minimizeSourceToDependencyDirectives("@import \" \";\n", Out));
415 TEST(MinimizeSourceToDependencyDirectivesTest, RawStringLiteral) {
416 SmallVector<char, 128> Out;
418 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifndef GUARD\n"
419 "#define GUARD\n"
420 "R\"()\"\n"
421 "#endif\n",
422 Out));
423 EXPECT_STREQ("#ifndef GUARD\n"
424 "#define GUARD\n"
425 "#endif\n",
426 Out.data());
428 bool RawStringLiteralResult = minimizeSourceToDependencyDirectives(
429 "#ifndef GUARD\n"
430 "#define GUARD\n"
431 R"raw(static constexpr char bytes[] = R"(-?:\,[]{}#&*!|>'"%@`)";)raw"
432 "\n"
433 "#endif\n",
434 Out);
435 ASSERT_FALSE(RawStringLiteralResult);
436 EXPECT_STREQ("#ifndef GUARD\n"
437 "#define GUARD\n"
438 "#endif\n",
439 Out.data());
441 bool RawStringLiteralResult2 = minimizeSourceToDependencyDirectives(
442 "#ifndef GUARD\n"
443 "#define GUARD\n"
444 R"raw(static constexpr char bytes[] = R"abc(-?:\,[]{}#&*!|>'"%@`)abc";)raw"
445 "\n"
446 "#endif\n",
447 Out);
448 ASSERT_FALSE(RawStringLiteralResult2);
449 EXPECT_STREQ("#ifndef GUARD\n"
450 "#define GUARD\n"
451 "#endif\n",
452 Out.data());
455 TEST(MinimizeSourceToDependencyDirectivesTest, SplitIdentifier) {
456 SmallVector<char, 128> Out;
458 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#if\\\n"
459 "ndef GUARD\n"
460 "#define GUARD\n"
461 "#endif\n",
462 Out));
463 EXPECT_STREQ("#ifndef GUARD\n"
464 "#define GUARD\n"
465 "#endif\n",
466 Out.data());
468 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\n"
469 "RD\n",
470 Out));
471 EXPECT_STREQ("#define GUARD\n", Out.data());
473 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\r"
474 "RD\n",
475 Out));
476 EXPECT_STREQ("#define GUARD\n", Out.data());
478 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\n"
479 " RD\n",
480 Out));
481 EXPECT_STREQ("#define GUA RD\n", Out.data());
484 TEST(MinimizeSourceToDependencyDirectivesTest,
485 WhitespaceAfterLineContinuationSlash) {
486 SmallVector<char, 128> Out;
488 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define A 1 + \\ \n"
489 "2 + \\\t\n"
490 "3\n",
491 Out));
492 EXPECT_STREQ("#define A 1 + 2 + 3\n", Out.data());
495 TEST(MinimizeSourceToDependencyDirectivesTest, PoundWarningAndError) {
496 SmallVector<char, 128> Out;
498 for (auto Source : {
499 "#warning '\n#include <t.h>\n",
500 "#warning \"\n#include <t.h>\n",
501 "#warning /*\n#include <t.h>\n",
502 "#warning \\\n#include <t.h>\n#include <t.h>\n",
503 "#error '\n#include <t.h>\n",
504 "#error \"\n#include <t.h>\n",
505 "#error /*\n#include <t.h>\n",
506 "#error \\\n#include <t.h>\n#include <t.h>\n",
507 }) {
508 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
509 EXPECT_STREQ("#include <t.h>\n", Out.data());
512 for (auto Source : {
513 "#warning \\\n#include <t.h>\n",
514 "#error \\\n#include <t.h>\n",
515 }) {
516 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
517 EXPECT_STREQ("", Out.data());
520 for (auto Source : {
521 "#if MACRO\n#warning '\n#endif\n",
522 "#if MACRO\n#warning \"\n#endif\n",
523 "#if MACRO\n#warning /*\n#endif\n",
524 "#if MACRO\n#error '\n#endif\n",
525 "#if MACRO\n#error \"\n#endif\n",
526 "#if MACRO\n#error /*\n#endif\n",
527 }) {
528 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
529 EXPECT_STREQ("#if MACRO\n#endif\n", Out.data());
533 TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteral) {
534 SmallVector<char, 128> Out;
536 StringRef Source = R"(
537 #include <bob>
538 int a = 0'1;
539 int b = 0xfa'af'fa;
540 int c = 12 ' ';
541 #include <foo>
543 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
544 EXPECT_STREQ("#include <bob>\n#include <foo>\n", Out.data());
547 TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixL) {
548 SmallVector<char, 128> Out;
550 StringRef Source = R"(L'P'
551 #if DEBUG
552 // '
553 #endif
554 #include <test.h>
556 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
557 EXPECT_STREQ("#if DEBUG\n#endif\n#include <test.h>\n", Out.data());
560 TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixU) {
561 SmallVector<char, 128> Out;
563 StringRef Source = R"(int x = U'P';
564 #include <test.h>
565 // '
567 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
568 EXPECT_STREQ("#include <test.h>\n", Out.data());
571 TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixu) {
572 SmallVector<char, 128> Out;
574 StringRef Source = R"(int x = u'b';
575 int y = u8'a';
576 int z = 128'78;
577 #include <test.h>
578 // '
580 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
581 EXPECT_STREQ("#include <test.h>\n", Out.data());
584 TEST(MinimizeSourceToDependencyDirectivesTest, PragmaOnce) {
585 SmallVector<char, 128> Out;
586 SmallVector<Token, 4> Tokens;
588 StringRef Source = R"(// comment
589 #pragma once
590 // another comment
591 #include <test.h>
593 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out, Tokens));
594 EXPECT_STREQ("#pragma once\n#include <test.h>\n", Out.data());
595 ASSERT_EQ(Tokens.size(), 3u);
596 EXPECT_EQ(Tokens[0].K,
597 minimize_source_to_dependency_directives::pp_pragma_once);
599 Source = R"(// comment
600 #pragma once extra tokens
601 // another comment
602 #include <test.h>
604 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
605 EXPECT_STREQ("#pragma once\n#include <test.h>\n", Out.data());
608 TEST(MinimizeSourceToDependencyDirectivesTest,
609 SkipLineStringCharLiteralsUntilNewline) {
610 SmallVector<char, 128> Out;
612 StringRef Source = R"(#if NEVER_ENABLED
613 #define why(fmt, ...) #error don't try me
614 #endif
616 void foo();
618 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
619 EXPECT_STREQ(
620 "#if NEVER_ENABLED\n#define why(fmt,...) #error don't try me\n#endif\n",
621 Out.data());
623 Source = R"(#if NEVER_ENABLED
624 #define why(fmt, ...) "quote dropped
625 #endif
627 void foo();
629 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
630 EXPECT_STREQ(
631 "#if NEVER_ENABLED\n#define why(fmt,...) \"quote dropped\n#endif\n",
632 Out.data());
635 TEST(MinimizeSourceToDependencyDirectivesTest,
636 SupportWhitespaceBeforeLineContinuationInStringSkipping) {
637 SmallVector<char, 128> Out;
639 StringRef Source = "#define X '\\ \t\nx'\nvoid foo() {}";
640 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
641 EXPECT_STREQ("#define X '\\ \t\nx'\n", Out.data());
643 Source = "#define X \"\\ \r\nx\"\nvoid foo() {}";
644 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
645 EXPECT_STREQ("#define X \"\\ \r\nx\"\n", Out.data());
647 Source = "#define X \"\\ \r\nx\n#include <x>\n";
648 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
649 EXPECT_STREQ("#define X \"\\ \r\nx\n#include <x>\n", Out.data());
652 TEST(MinimizeSourceToDependencyDirectivesTest, CxxModules) {
653 SmallVector<char, 128> Out;
654 SmallVector<Token, 4> Tokens;
656 StringRef Source = R"(
657 module;
658 #include "textual-header.h"
660 export module m;
661 exp\
662 ort \
663 import \
664 :l [[rename]];
666 export void f();
668 void h() {
669 import.a = 3;
670 import = 3;
671 import <<= 3;
672 import->a = 3;
673 import();
674 import . a();
676 import a b d e d e f e;
677 import foo [[no_unique_address]];
678 import foo();
679 import f(:sefse);
680 import f(->a = 3);
683 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out, Tokens));
684 EXPECT_STREQ("#include \"textual-header.h\"\nexport module m;\n"
685 "export import :l [[rename]];\n"
686 "import <<= 3;\nimport a b d e d e f e;\n"
687 "import foo [[no_unique_address]];\nimport foo();\n"
688 "import f(:sefse);\nimport f(->a = 3);\n", Out.data());
689 ASSERT_EQ(Tokens.size(), 12u);
690 EXPECT_EQ(Tokens[0].K,
691 minimize_source_to_dependency_directives::pp_include);
692 EXPECT_EQ(Tokens[2].K,
693 minimize_source_to_dependency_directives::cxx_module_decl);
696 TEST(MinimizeSourceToDependencyDirectivesTest, SkippedPPRangesBasic) {
697 SmallString<128> Out;
698 SmallVector<Token, 32> Toks;
699 StringRef Source = "#ifndef GUARD\n"
700 "#define GUARD\n"
701 "void foo();\n"
702 "#endif\n";
703 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out, Toks));
704 SmallVector<SkippedRange, 4> Ranges;
705 ASSERT_FALSE(computeSkippedRanges(Toks, Ranges));
706 EXPECT_EQ(Ranges.size(), 1u);
707 EXPECT_EQ(Ranges[0].Offset, 0);
708 EXPECT_EQ(Ranges[0].Length, (int)Out.find("#endif"));
711 TEST(MinimizeSourceToDependencyDirectivesTest, SkippedPPRangesNested) {
712 SmallString<128> Out;
713 SmallVector<Token, 32> Toks;
714 StringRef Source = "#ifndef GUARD\n"
715 "#define GUARD\n"
716 "#if FOO\n"
717 "#include hello\n"
718 "#elif BAR\n"
719 "#include bye\n"
720 "#endif\n"
721 "#else\n"
722 "#include nothing\n"
723 "#endif\n";
724 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out, Toks));
725 SmallVector<SkippedRange, 4> Ranges;
726 ASSERT_FALSE(computeSkippedRanges(Toks, Ranges));
727 EXPECT_EQ(Ranges.size(), 4u);
728 EXPECT_EQ(Ranges[0].Offset, (int)Out.find("#if FOO"));
729 EXPECT_EQ(Ranges[0].Offset + Ranges[0].Length, (int)Out.find("#elif"));
730 EXPECT_EQ(Ranges[1].Offset, (int)Out.find("#elif BAR"));
731 EXPECT_EQ(Ranges[1].Offset + Ranges[1].Length, (int)Out.find("#endif"));
732 EXPECT_EQ(Ranges[2].Offset, 0);
733 EXPECT_EQ(Ranges[2].Length, (int)Out.find("#else"));
734 EXPECT_EQ(Ranges[3].Offset, (int)Out.find("#else"));
735 EXPECT_EQ(Ranges[3].Offset + Ranges[3].Length, (int)Out.rfind("#endif"));
738 } // end anonymous namespace