1 //===- unittests/Lex/DependencyDirectivesScannerTest.cpp ------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "clang/Lex/DependencyDirectivesScanner.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "gtest/gtest.h"
14 using namespace clang
;
15 using namespace clang::dependency_directives_scan
;
17 static bool minimizeSourceToDependencyDirectives(
18 StringRef Input
, SmallVectorImpl
<char> &Out
,
19 SmallVectorImpl
<dependency_directives_scan::Token
> &Tokens
,
20 SmallVectorImpl
<Directive
> &Directives
) {
24 if (scanSourceForDependencyDirectives(Input
, Tokens
, Directives
))
27 raw_svector_ostream
OS(Out
);
28 printDependencyDirectivesAsSource(Input
, Directives
, OS
);
29 if (!Out
.empty() && Out
.back() != '\n')
37 static 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
);
46 TEST(MinimizeSourceToDependencyDirectivesTest
, Empty
) {
47 SmallVector
<char, 128> Out
;
48 SmallVector
<dependency_directives_scan::Token
, 4> Tokens
;
49 SmallVector
<Directive
, 4> Directives
;
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
);
58 ASSERT_FALSE(minimizeSourceToDependencyDirectives("abc def\nxyz", Out
, Tokens
,
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
);
67 TEST(MinimizeSourceToDependencyDirectivesTest
, AllTokens
) {
68 SmallVector
<char, 128> Out
;
69 SmallVector
<dependency_directives_scan::Token
, 4> Tokens
;
70 SmallVector
<Directive
, 4> Directives
;
73 minimizeSourceToDependencyDirectives("#define A\n"
85 "#__include_macros <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"
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
);
121 TEST(MinimizeSourceToDependencyDirectivesTest
, EmptyHash
) {
122 SmallVector
<char, 128> Out
;
125 minimizeSourceToDependencyDirectives("#\n#define MACRO a\n", Out
));
126 EXPECT_STREQ("#define MACRO a\n", Out
.data());
129 TEST(MinimizeSourceToDependencyDirectivesTest
, HashHash
) {
130 SmallVector
<char, 128> Out
;
132 StringRef Source
= R
"(
140 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source
, Out
));
141 EXPECT_STREQ("#define S\n#if 0\n#endif\n#define E\n", Out
.data());
144 TEST(MinimizeSourceToDependencyDirectivesTest
, Define
) {
145 SmallVector
<char, 128> Out
;
146 SmallVector
<dependency_directives_scan::Token
, 4> Tokens
;
147 SmallVector
<Directive
, 4> Directives
;
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
);
157 TEST(MinimizeSourceToDependencyDirectivesTest
, DefineSpacing
) {
158 SmallVector
<char, 128> Out
;
161 minimizeSourceToDependencyDirectives("#define MACRO\n\n\n", Out
));
162 EXPECT_STREQ("#define MACRO\n", Out
.data());
165 minimizeSourceToDependencyDirectives("#define MACRO \n\n\n", Out
));
166 EXPECT_STREQ("#define MACRO\n", Out
.data());
169 minimizeSourceToDependencyDirectives("#define MACRO a \n\n\n", Out
));
170 EXPECT_STREQ("#define MACRO a\n", Out
.data());
173 minimizeSourceToDependencyDirectives("#define MACRO\n\n\n", Out
));
174 EXPECT_STREQ("#define MACRO\n", Out
.data());
177 TEST(MinimizeSourceToDependencyDirectivesTest
, DefineMacroArguments
) {
178 SmallVector
<char, 128> Out
;
180 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO()", Out
));
181 EXPECT_STREQ("#define MACRO()\n", Out
.data());
184 minimizeSourceToDependencyDirectives("#define MACRO(a, b...)", Out
));
185 EXPECT_STREQ("#define MACRO(a,b...)\n", Out
.data());
188 minimizeSourceToDependencyDirectives("#define MACRO content", Out
));
189 EXPECT_STREQ("#define MACRO content\n", Out
.data());
191 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
192 "#define MACRO con tent ", Out
));
193 EXPECT_STREQ("#define MACRO con tent\n", Out
.data());
195 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
196 "#define MACRO() con tent ", Out
));
197 EXPECT_STREQ("#define MACRO() con tent\n", Out
.data());
200 TEST(MinimizeSourceToDependencyDirectivesTest
, DefineInvalidMacroArguments
) {
201 SmallVector
<char, 128> Out
;
203 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO((a))", Out
));
204 EXPECT_STREQ("#define MACRO((a))\n", Out
.data());
206 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO(", Out
));
207 EXPECT_STREQ("#define MACRO(\n", Out
.data());
210 minimizeSourceToDependencyDirectives("#define MACRO(a * b)", Out
));
211 EXPECT_STREQ("#define MACRO(a*b)\n", Out
.data());
214 TEST(MinimizeSourceToDependencyDirectivesTest
, DefineHorizontalWhitespace
) {
215 SmallVector
<char, 128> Out
;
217 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
218 "#define MACRO(\t)\tcon \t tent\t", Out
));
219 EXPECT_STREQ("#define MACRO() con tent\n", Out
.data());
221 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
222 "#define MACRO(\f)\fcon \f tent\f", Out
));
223 EXPECT_STREQ("#define MACRO() con tent\n", Out
.data());
225 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
226 "#define MACRO(\v)\vcon \v tent\v", Out
));
227 EXPECT_STREQ("#define MACRO() con tent\n", Out
.data());
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());
234 TEST(MinimizeSourceToDependencyDirectivesTest
, DefineMultilineArgs
) {
235 SmallVector
<char, 128> Out
;
238 minimizeSourceToDependencyDirectives("#define MACRO(a \\\n"
241 EXPECT_STREQ("#define MACRO(a)\n", Out
.data());
244 minimizeSourceToDependencyDirectives("#define MACRO(a, \\\n"
249 EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out
.data());
252 TEST(MinimizeSourceToDependencyDirectivesTest
,
253 DefineMultilineArgsCarriageReturn
) {
254 SmallVector
<char, 128> Out
;
257 minimizeSourceToDependencyDirectives("#define MACRO(a, \\\r"
262 EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out
.data());
265 TEST(MinimizeSourceToDependencyDirectivesTest
, DefineMultilineArgsStringize
) {
266 SmallVector
<char, 128> Out
;
268 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO(a,b) \\\n"
272 EXPECT_STREQ("#define MACRO(a,b) #a #b\n", Out
.data());
275 TEST(MinimizeSourceToDependencyDirectivesTest
,
276 DefineMultilineArgsCarriageReturnNewline
) {
277 SmallVector
<char, 128> Out
;
280 minimizeSourceToDependencyDirectives("#define MACRO(a, \\\r\n"
285 EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out
.data());
288 TEST(MinimizeSourceToDependencyDirectivesTest
,
289 DefineMultilineArgsNewlineCarriageReturn
) {
290 SmallVector
<char, 128> Out
;
293 minimizeSourceToDependencyDirectives("#define MACRO(a, \\\n\r"
298 EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out
.data());
301 TEST(MinimizeSourceToDependencyDirectivesTest
, DefineNumber
) {
302 SmallVector
<char, 128> Out
;
304 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define 0\n", Out
));
307 TEST(MinimizeSourceToDependencyDirectivesTest
, DefineNoName
) {
308 SmallVector
<char, 128> Out
;
310 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define &\n", Out
));
313 TEST(MinimizeSourceToDependencyDirectivesTest
, DefineNoWhitespace
) {
314 SmallVector
<char, 128> Out
;
316 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define AND&\n", Out
));
317 EXPECT_STREQ("#define AND&\n", Out
.data());
319 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define AND\\\n"
322 EXPECT_STREQ("#define AND\\\n"
327 TEST(MinimizeSourceToDependencyDirectivesTest
, MultilineComment
) {
328 SmallVector
<char, 128> Out
;
331 minimizeSourceToDependencyDirectives("#define MACRO a/*\n"
333 "#define MISSING abc\n"
335 " /* something */ \n"
336 "#include /* \"def\" */ <abc> \n",
338 EXPECT_STREQ("#define MACRO a\n"
343 TEST(MinimizeSourceToDependencyDirectivesTest
, MultilineCommentInStrings
) {
344 SmallVector
<char, 128> Out
;
346 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO1 \"/*\"\n"
347 "#define MACRO2 \"*/\"\n",
349 EXPECT_STREQ("#define MACRO1 \"/*\"\n"
350 "#define MACRO2 \"*/\"\n",
354 TEST(MinimizeSourceToDependencyDirectivesTest
, CommentSlashSlashStar
) {
355 SmallVector
<char, 128> Out
;
357 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
358 "#define MACRO 1 //* blah */\n", Out
));
359 EXPECT_STREQ("#define MACRO 1\n", Out
.data());
362 TEST(MinimizeSourceToDependencyDirectivesTest
, Ifdef
) {
363 SmallVector
<char, 128> Out
;
365 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
369 EXPECT_STREQ("#ifdef A\n"
374 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
384 EXPECT_STREQ("#ifdef A\n"
396 TEST(MinimizeSourceToDependencyDirectivesTest
, Elifdef
) {
397 SmallVector
<char, 128> Out
;
399 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
405 EXPECT_STREQ("#ifdef A\n"
412 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
422 EXPECT_STREQ("#ifdef A\n"
434 TEST(MinimizeSourceToDependencyDirectivesTest
, EmptyIfdef
) {
435 SmallVector
<char, 128> Out
;
437 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
444 EXPECT_STREQ("#ifdef A\n"
451 TEST(MinimizeSourceToDependencyDirectivesTest
, EmptyElifdef
) {
452 SmallVector
<char, 128> Out
;
454 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
461 EXPECT_STREQ("#ifdef A\n"
468 TEST(MinimizeSourceToDependencyDirectivesTest
, Pragma
) {
469 SmallVector
<char, 128> Out
;
471 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#pragma A\n", Out
));
472 EXPECT_STREQ("<TokBeforeEOF>\n", Out
.data());
474 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
475 "#pragma push_macro(\"MACRO\")\n", Out
));
476 EXPECT_STREQ("#pragma push_macro(\"MACRO\")\n", Out
.data());
478 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
479 "#pragma pop_macro(\"MACRO\")\n", Out
));
480 EXPECT_STREQ("#pragma pop_macro(\"MACRO\")\n", Out
.data());
482 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
483 "#pragma include_alias(\"A\", \"B\")\n", Out
));
484 EXPECT_STREQ("#pragma include_alias(\"A\", \"B\")\n", Out
.data());
486 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
487 "#pragma include_alias(<A>, <B>)\n", Out
));
488 EXPECT_STREQ("#pragma include_alias(<A>, <B>)\n", Out
.data());
490 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#pragma clang\n", Out
));
491 EXPECT_STREQ("<TokBeforeEOF>\n", Out
.data());
494 minimizeSourceToDependencyDirectives("#pragma clang module\n", Out
));
495 EXPECT_STREQ("<TokBeforeEOF>\n", Out
.data());
497 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
498 "#pragma clang module impor\n", Out
));
499 EXPECT_STREQ("<TokBeforeEOF>\n", Out
.data());
501 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
502 "#pragma clang module import\n", Out
));
503 EXPECT_STREQ("#pragma clang module import\n", Out
.data());
506 TEST(MinimizeSourceToDependencyDirectivesTest
, UnderscorePragma
) {
507 SmallVector
<char, 128> Out
;
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());
522 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
523 R"x(_Pragma("push_macro(\"MACRO\")"))x
", Out));
524 EXPECT_STREQ(R"x(_Pragma("push_macro(\"MACRO\")"))x
"
528 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
529 R"x(_Pragma("pop_macro(\"MACRO\")"))x
", Out));
530 EXPECT_STREQ(R"x(_Pragma("pop_macro(\"MACRO\")"))x
"
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
"
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
"
547 minimizeSourceToDependencyDirectives(R"(_Pragma("clang"))", Out));
548 EXPECT_STREQ("<TokBeforeEOF
>\n", Out.data());
551 minimizeSourceToDependencyDirectives(R"(_Pragma("clang module"))", Out));
552 EXPECT_STREQ("<TokBeforeEOF
>\n", Out.data());
554 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
555 R"(_Pragma("clang module impor"))", Out));
556 EXPECT_STREQ("<TokBeforeEOF
>\n", Out.data());
558 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
559 R"(_Pragma("clang module import"))", Out));
560 EXPECT_STREQ(R"(_Pragma("clang module import"))"
564 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
569 EXPECT_STREQ(R"(_Pragma("clang \
575 ASSERT_FALSE(minimizeSourceToDependencyDirectives(
576 R"(_Pragma(L
"clang module import"))", Out));
577 EXPECT_STREQ(R"(_Pragma(L
"clang module import"))"
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());
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"))"
594 TEST(MinimizeSourceToDependencyDirectivesTest, Include) {
595 SmallVector<char, 128> Out;
597 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include \"A\"\n", Out));
598 EXPECT_STREQ("#include \"A\"\n", Out.data());
600 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include <A>\n", Out));
601 EXPECT_STREQ("#include <A>\n", Out.data());
604 minimizeSourceToDependencyDirectives("#include <A//A.h>\n", Out));
605 EXPECT_STREQ("#include <A//A.h>\n", Out
.data());
608 minimizeSourceToDependencyDirectives("#include \"A//A.h\"\n", Out
));
609 EXPECT_STREQ("#include \"A//A.h\"\n", Out
.data());
612 minimizeSourceToDependencyDirectives("#include_next <A>\n", Out
));
613 EXPECT_STREQ("#include_next <A>\n", Out
.data());
615 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#import <A>\n", Out
));
616 EXPECT_STREQ("#import <A>\n", Out
.data());
618 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#import <A//A.h>\n", Out
));
619 EXPECT_STREQ("#import <A//A.h>\n", Out
.data());
622 minimizeSourceToDependencyDirectives("#import \"A//A.h\"\n", Out
));
623 EXPECT_STREQ("#import \"A//A.h\"\n", Out
.data());
626 minimizeSourceToDependencyDirectives("#__include_macros <A>\n", Out
));
627 EXPECT_STREQ("#__include_macros <A>\n", Out
.data());
629 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include MACRO\n", Out
));
630 EXPECT_STREQ("#include MACRO\n", Out
.data());
633 TEST(MinimizeSourceToDependencyDirectivesTest
, AtImport
) {
634 SmallVector
<char, 128> Out
;
636 ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A;\n", Out
));
637 EXPECT_STREQ("@import A;\n", Out
.data());
639 ASSERT_FALSE(minimizeSourceToDependencyDirectives(" @ import A;\n", Out
));
640 EXPECT_STREQ("@import A;\n", Out
.data());
642 ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A\n;", Out
));
643 EXPECT_STREQ("@import A;\n", Out
.data());
645 ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A.B;\n", Out
));
646 EXPECT_STREQ("@import A.B;\n", Out
.data());
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());
653 TEST(MinimizeSourceToDependencyDirectivesTest
, EmptyIncludesAndImports
) {
654 SmallVector
<char, 128> Out
;
656 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#import\n", Out
));
657 EXPECT_STREQ("<TokBeforeEOF>\n", Out
.data());
659 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include\n", Out
));
660 EXPECT_STREQ("<TokBeforeEOF>\n", Out
.data());
662 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
666 // The ifdef block is removed because it's "empty".
667 EXPECT_STREQ("<TokBeforeEOF>\n", Out
.data());
669 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
674 EXPECT_STREQ("#ifdef A\n"
680 TEST(MinimizeSourceToDependencyDirectivesTest
, AtImportFailures
) {
681 SmallVector
<char, 128> Out
;
683 ASSERT_TRUE(minimizeSourceToDependencyDirectives("@import A\n", Out
));
685 minimizeSourceToDependencyDirectives("@import MACRO(A);\n", Out
));
686 ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import \" \";\n", Out
));
689 TEST(MinimizeSourceToDependencyDirectivesTest
, RawStringLiteral
) {
690 SmallVector
<char, 128> Out
;
692 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifndef GUARD\n"
697 EXPECT_STREQ("#ifndef GUARD\n"
702 bool RawStringLiteralResult
= minimizeSourceToDependencyDirectives(
705 R
"raw(static constexpr char bytes[] = R"(-?:\
,[]{}#&*!|>'"%@`)";)raw"
709 ASSERT_FALSE(RawStringLiteralResult);
710 EXPECT_STREQ("#ifndef GUARD\n"
715 bool RawStringLiteralResult2 = minimizeSourceToDependencyDirectives(
718 R"raw(static constexpr char bytes[] = R"abc(-?:\,[]{}#&*!|>'"%@`)abc";)raw"
722 ASSERT_FALSE(RawStringLiteralResult2);
723 EXPECT_STREQ("#ifndef GUARD\n"
729 TEST(MinimizeSourceToDependencyDirectivesTest, SplitIdentifier) {
730 SmallVector<char, 128> Out;
732 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#if\\\n"
737 EXPECT_STREQ("#if\\\n"
743 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\n"
746 EXPECT_STREQ("#define GUA\\\n"
750 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\r"
753 EXPECT_STREQ("#define GUA\\\r"
757 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\n"
760 EXPECT_STREQ("#define GUA RD\n", Out.data());
763 TEST(MinimizeSourceToDependencyDirectivesTest,
764 WhitespaceAfterLineContinuationSlash) {
765 SmallVector<char, 128> Out;
767 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define A 1 + \\ \n"
771 EXPECT_STREQ("#define A 1+\\ \n"
777 TEST(MinimizeSourceToDependencyDirectivesTest, PoundWarningAndError) {
778 SmallVector<char, 128> Out;
781 "#warning '\n#include <t.h>\n",
782 "#warning \"\n#include <t.h>\n",
783 "#warning /*\n#include <t.h>\n",
784 "#warning \\\n#include <t.h>\n#include <t.h>\n",
785 "#error '\n#include <t.h>\n",
786 "#error \"\n#include <t.h>\n",
787 "#error /*\n#include <t.h>\n",
788 "#error \\\n#include <t.h>\n#include <t.h>\n",
790 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
791 EXPECT_STREQ("#include <t.h>\n", Out.data());
795 "#warning \\\n#include <t.h>\n",
796 "#error \\\n#include <t.h>\n",
798 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
799 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
803 "#if MACRO\n#warning '\n#endif\n",
804 "#if MACRO\n#warning \"\n#endif\n",
805 "#if MACRO\n#warning /*\n#endif\n",
806 "#if MACRO\n#error '\n#endif\n",
807 "#if MACRO\n#error \"\n#endif\n",
808 "#if MACRO\n#error /*\n#endif\n",
810 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
811 EXPECT_STREQ("#if MACRO\n#endif\n", Out.data());
815 TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteral) {
816 SmallVector<char, 128> Out;
818 StringRef Source = R"(
825 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
826 EXPECT_STREQ("#include <bob>\n#include <foo>\n", Out.data());
829 TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixL) {
830 SmallVector<char, 128> Out;
832 StringRef Source = R"(L'P'
838 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
839 EXPECT_STREQ("#if DEBUG\n#endif\n#include <test.h>\n", Out.data());
842 TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixU) {
843 SmallVector<char, 128> Out;
845 StringRef Source = R"(int x = U'P';
849 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
850 EXPECT_STREQ("#include <test.h>\n", Out.data());
853 TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixu) {
854 SmallVector<char, 128> Out;
856 StringRef Source = R"(int x = u'b';
862 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
863 EXPECT_STREQ("#include <test.h>\n", Out.data());
866 TEST(MinimizeSourceToDependencyDirectivesTest, PragmaOnce) {
867 SmallVector<char, 128> Out;
868 SmallVector<dependency_directives_scan::Token, 4> Tokens;
869 SmallVector<Directive, 4> Directives;
871 StringRef Source = R"(// comment
878 minimizeSourceToDependencyDirectives(Source, Out, Tokens, Directives));
879 EXPECT_STREQ("#pragma once\n#include <test.h>\n_Pragma(\"once\")\n",
881 ASSERT_EQ(Directives.size(), 4u);
882 EXPECT_EQ(Directives[0].Kind, dependency_directives_scan::pp_pragma_once);
883 EXPECT_EQ(Directives[2].Kind, dependency_directives_scan::pp_pragma_once);
885 Source = R"(// comment
886 #pragma once extra tokens
889 _Pragma("once") extra tokens
891 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
892 EXPECT_STREQ("#pragma once extra tokens\n#include "
893 "<test.h>\n_Pragma(\"once\")<TokBeforeEOF>\n",
897 TEST(MinimizeSourceToDependencyDirectivesTest,
898 SkipLineStringCharLiteralsUntilNewline) {
899 SmallVector<char, 128> Out;
901 StringRef Source = R"(#if NEVER_ENABLED
902 #define why(fmt, ...) #error don't try me
907 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
909 "#if NEVER_ENABLED\n#define why(fmt,...) #error don't try me\n#endif\n"
913 Source = R"(#if NEVER_ENABLED
914 #define why(fmt, ...) "quote dropped
919 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
921 "#if NEVER_ENABLED\n#define why(fmt,...) \"quote dropped\n#endif\n"
926 TEST(MinimizeSourceToDependencyDirectivesTest,
927 SupportWhitespaceBeforeLineContinuation) {
928 SmallVector<char, 128> Out;
930 ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define FOO(BAR) \\\n"
934 EXPECT_STREQ("#define FOO(BAR) #BAR baz\n", Out.data());
937 TEST(MinimizeSourceToDependencyDirectivesTest,
938 SupportWhitespaceBeforeLineContinuationInStringSkipping) {
939 SmallVector<char, 128> Out;
941 StringRef Source = "#define X '\\ \t\nx'\nvoid foo() {}";
942 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
943 EXPECT_STREQ("#define X '\\ \t\nx'\n<TokBeforeEOF>\n", Out.data());
945 Source = "#define X \"\\ \r\nx\"\nvoid foo() {}";
946 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
947 EXPECT_STREQ("#define X \"\\ \r\nx\"\n<TokBeforeEOF>\n", Out.data());
949 Source = "#define X \"\\ \r\nx\n#include <x>\n";
950 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
951 EXPECT_STREQ("#define X\"\\ \r\nx\n#include <x>\n", Out.data());
954 TEST(MinimizeSourceToDependencyDirectivesTest, CxxModules) {
955 SmallVector<char, 128> Out;
956 SmallVector<dependency_directives_scan::Token, 4> Tokens;
957 SmallVector<Directive, 4> Directives;
959 StringRef Source = R"(
961 #include "textual-header.h"
979 import a b d e d e f e;
980 import foo [[no_unique_address]];
987 minimizeSourceToDependencyDirectives(Source, Out, Tokens, Directives));
988 EXPECT_STREQ("#include \"textual-header.h\"\nexport module m;"
989 "exp\\\nort import:l[[rename]];"
990 "import<<=3;import a b d e d e f e;"
991 "import foo[[no_unique_address]];import foo();"
992 "import f(:sefse);import f(->a=3);"
995 ASSERT_EQ(Directives.size(), 11u);
996 EXPECT_EQ(Directives[0].Kind, pp_include);
997 EXPECT_EQ(Directives[1].Kind, cxx_export_module_decl);
1000 TEST(MinimizeSourceToDependencyDirectivesTest, ObjCMethodArgs) {
1001 SmallVector<char, 128> Out;
1003 StringRef Source = R"(
1004 @interface SomeObjcClass
1005 - (void)func:(int)otherData
1011 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1012 // `module :` and `import :` not followed by an identifier are not treated as
1013 // directive lines because they can be method argument decls.
1014 EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
1017 TEST(MinimizeSourceToDependencyDirectivesTest, TokensBeforeEOF) {
1018 SmallString<128> Out;
1020 StringRef Source = R"(
1026 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1027 EXPECT_STREQ("#define A\n<TokBeforeEOF>\n", Out.data());
1032 #endif // some comment
1036 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1037 EXPECT_STREQ("#ifndef A\n#define A\n#endif\n", Out.data());
1042 #endif /* some comment
1046 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1047 EXPECT_STREQ("#ifndef A\n#define A\n#endif\n", Out.data());
1052 #endif /* some comment
1057 ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
1058 EXPECT_STREQ("#ifndef A\n#define A\n#endif\n<TokBeforeEOF>\n", Out.data());
1061 } // end anonymous namespace