Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / unittests / Tooling / HeaderIncludesTest.cpp
blob256aa825554c5073ba9f0d8d4c83d13297a9cee8
1 //===- unittest/Tooling/CleanupTest.cpp - Include insertion/deletion tests ===//
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/Tooling/Inclusions/HeaderIncludes.h"
10 #include "../Tooling/ReplacementTest.h"
11 #include "../Tooling/RewriterTestContext.h"
12 #include "clang/Format/Format.h"
13 #include "clang/Tooling/Core/Replacement.h"
15 #include "gtest/gtest.h"
17 namespace clang {
18 namespace tooling {
19 namespace {
21 class HeaderIncludesTest : public ::testing::Test {
22 protected:
23 std::string insert(llvm::StringRef Code, llvm::StringRef Header,
24 IncludeDirective Directive = IncludeDirective::Include) {
25 HeaderIncludes Includes(FileName, Code, Style);
26 assert(Header.startswith("\"") || Header.startswith("<"));
27 auto R =
28 Includes.insert(Header.trim("\"<>"), Header.startswith("<"), Directive);
29 if (!R)
30 return std::string(Code);
31 auto Result = applyAllReplacements(Code, Replacements(*R));
32 EXPECT_TRUE(static_cast<bool>(Result));
33 return *Result;
36 std::string remove(llvm::StringRef Code, llvm::StringRef Header) {
37 HeaderIncludes Includes(FileName, Code, Style);
38 assert(Header.startswith("\"") || Header.startswith("<"));
39 auto Replaces = Includes.remove(Header.trim("\"<>"), Header.startswith("<"));
40 auto Result = applyAllReplacements(Code, Replaces);
41 EXPECT_TRUE(static_cast<bool>(Result));
42 return *Result;
45 std::string FileName = "fix.cpp";
46 IncludeStyle Style = format::getLLVMStyle().IncludeStyle;
49 TEST_F(HeaderIncludesTest, NoExistingIncludeWithoutDefine) {
50 std::string Code = "int main() {}";
51 std::string Expected = "#include \"a.h\"\n"
52 "int main() {}";
53 EXPECT_EQ(Expected, insert(Code, "\"a.h\""));
56 TEST_F(HeaderIncludesTest, RepeatedIncludes) {
57 std::string Code;
58 for (int i = 0; i < 100; ++i) {
59 Code += "#include \"a.h\"\n";
61 std::string Expected = Code + "#include \"a2.h\"\n";
62 EXPECT_EQ(Expected, insert(Code, "\"a2.h\""));
65 TEST_F(HeaderIncludesTest, InsertImportWithSameInclude) {
66 std::string Code = "#include \"a.h\"\n";
67 std::string Expected = Code + "#import \"a.h\"\n";
68 EXPECT_EQ(Expected, insert(Code, "\"a.h\"", IncludeDirective::Import));
71 TEST_F(HeaderIncludesTest, DontInsertAlreadyImported) {
72 std::string Code = "#import \"a.h\"\n";
73 EXPECT_EQ(Code, insert(Code, "\"a.h\"", IncludeDirective::Import));
76 TEST_F(HeaderIncludesTest, DeleteImportAndSameInclude) {
77 std::string Code = R"cpp(
78 #include <abc.h>
79 #import <abc.h>
80 int x;)cpp";
81 EXPECT_EQ("\nint x;", remove(Code, "<abc.h>"));
84 TEST_F(HeaderIncludesTest, NoExistingIncludeWithDefine) {
85 std::string Code = "#ifndef A_H\n"
86 "#define A_H\n"
87 "class A {};\n"
88 "#define MMM 123\n"
89 "#endif";
90 std::string Expected = "#ifndef A_H\n"
91 "#define A_H\n"
92 "#include \"b.h\"\n"
93 "class A {};\n"
94 "#define MMM 123\n"
95 "#endif";
97 EXPECT_EQ(Expected, insert(Code, "\"b.h\""));
100 TEST_F(HeaderIncludesTest, InsertBeforeCategoryWithLowerPriority) {
101 std::string Code = "#ifndef A_H\n"
102 "#define A_H\n"
103 "\n"
104 "\n"
105 "\n"
106 "#include <vector>\n"
107 "class A {};\n"
108 "#define MMM 123\n"
109 "#endif";
110 std::string Expected = "#ifndef A_H\n"
111 "#define A_H\n"
112 "\n"
113 "\n"
114 "\n"
115 "#include \"a.h\"\n"
116 "#include <vector>\n"
117 "class A {};\n"
118 "#define MMM 123\n"
119 "#endif";
121 EXPECT_EQ(Expected, insert(Code, "\"a.h\""));
124 TEST_F(HeaderIncludesTest, InsertAfterMainHeader) {
125 std::string Code = "#include \"fix.h\"\n"
126 "\n"
127 "int main() {}";
128 std::string Expected = "#include \"fix.h\"\n"
129 "#include <a>\n"
130 "\n"
131 "int main() {}";
132 Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
133 .IncludeStyle;
134 EXPECT_EQ(Expected, insert(Code, "<a>"));
136 FileName = "fix.cu.cpp";
137 EXPECT_EQ(Expected, insert(Code, "<a>"));
139 FileName = "fix_test.cu.cpp";
140 EXPECT_EQ(Expected, insert(Code, "<a>"));
142 FileName = "bar.cpp";
143 EXPECT_NE(Expected, insert(Code, "<a>")) << "Not main header";
146 TEST_F(HeaderIncludesTest, InsertMainHeader) {
147 Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
148 .IncludeStyle;
149 FileName = "fix.cpp";
150 EXPECT_EQ(R"cpp(#include "fix.h"
151 #include "a.h")cpp", insert("#include \"a.h\"", "\"fix.h\""));
153 // Respect the original main-file header.
154 EXPECT_EQ(R"cpp(#include "z/fix.h"
155 #include "a/fix.h"
156 )cpp", insert("#include \"z/fix.h\"", "\"a/fix.h\""));
159 TEST_F(HeaderIncludesTest, InsertBeforeSystemHeaderLLVM) {
160 std::string Code = "#include <memory>\n"
161 "\n"
162 "int main() {}";
163 std::string Expected = "#include \"z.h\"\n"
164 "#include <memory>\n"
165 "\n"
166 "int main() {}";
167 EXPECT_EQ(Expected, insert(Code, "\"z.h\""));
170 TEST_F(HeaderIncludesTest, InsertAfterSystemHeaderGoogle) {
171 std::string Code = "#include <memory>\n"
172 "\n"
173 "int main() {}";
174 std::string Expected = "#include <memory>\n"
175 "#include \"z.h\"\n"
176 "\n"
177 "int main() {}";
178 Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
179 .IncludeStyle;
180 EXPECT_EQ(Expected, insert(Code, "\"z.h\""));
183 TEST_F(HeaderIncludesTest, InsertOneIncludeLLVMStyle) {
184 std::string Code = "#include \"x/fix.h\"\n"
185 "#include \"a.h\"\n"
186 "#include \"b.h\"\n"
187 "#include \"clang/Format/Format.h\"\n"
188 "#include <memory>\n";
189 std::string Expected = "#include \"x/fix.h\"\n"
190 "#include \"a.h\"\n"
191 "#include \"b.h\"\n"
192 "#include \"clang/Format/Format.h\"\n"
193 "#include \"llvm/x/y.h\"\n"
194 "#include <memory>\n";
195 EXPECT_EQ(Expected, insert(Code, "\"llvm/x/y.h\""));
198 TEST_F(HeaderIncludesTest, InsertIntoBlockSorted) {
199 std::string Code = "#include \"x/fix.h\"\n"
200 "#include \"a.h\"\n"
201 "#include \"c.h\"\n"
202 "#include <memory>\n";
203 std::string Expected = "#include \"x/fix.h\"\n"
204 "#include \"a.h\"\n"
205 "#include \"b.h\"\n"
206 "#include \"c.h\"\n"
207 "#include <memory>\n";
208 EXPECT_EQ(Expected, insert(Code, "\"b.h\""));
211 TEST_F(HeaderIncludesTest, InsertIntoFirstBlockOfSameKind) {
212 std::string Code = "#include \"x/fix.h\"\n"
213 "#include \"c.h\"\n"
214 "#include \"e.h\"\n"
215 "#include \"f.h\"\n"
216 "#include <memory>\n"
217 "#include <vector>\n"
218 "#include \"m.h\"\n"
219 "#include \"n.h\"\n";
220 std::string Expected = "#include \"x/fix.h\"\n"
221 "#include \"c.h\"\n"
222 "#include \"d.h\"\n"
223 "#include \"e.h\"\n"
224 "#include \"f.h\"\n"
225 "#include <memory>\n"
226 "#include <vector>\n"
227 "#include \"m.h\"\n"
228 "#include \"n.h\"\n";
229 EXPECT_EQ(Expected, insert(Code, "\"d.h\""));
232 TEST_F(HeaderIncludesTest, InsertIntoSystemBlockSorted) {
233 std::string Code = "#include \"x/fix.h\"\n"
234 "#include \"a.h\"\n"
235 "#include \"c.h\"\n"
236 "#include <a>\n"
237 "#include <z>\n";
238 std::string Expected = "#include \"x/fix.h\"\n"
239 "#include \"a.h\"\n"
240 "#include \"c.h\"\n"
241 "#include <a>\n"
242 "#include <vector>\n"
243 "#include <z>\n";
244 EXPECT_EQ(Expected, insert(Code, "<vector>"));
247 TEST_F(HeaderIncludesTest, InsertNewSystemIncludeGoogleStyle) {
248 std::string Code = "#include \"x/fix.h\"\n"
249 "\n"
250 "#include \"y/a.h\"\n"
251 "#include \"z/b.h\"\n";
252 // FIXME: inserting after the empty line following the main header might be
253 // preferred.
254 std::string Expected = "#include \"x/fix.h\"\n"
255 "#include <vector>\n"
256 "\n"
257 "#include \"y/a.h\"\n"
258 "#include \"z/b.h\"\n";
259 Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
260 .IncludeStyle;
261 EXPECT_EQ(Expected, insert(Code, "<vector>"));
264 TEST_F(HeaderIncludesTest, NotConfusedByDefine) {
265 std::string Code = "void f() {}\n"
266 "#define A \\\n"
267 " int i;";
268 std::string Expected = "#include <vector>\n"
269 "void f() {}\n"
270 "#define A \\\n"
271 " int i;";
272 EXPECT_EQ(Expected, insert(Code, "<vector>"));
275 TEST_F(HeaderIncludesTest, SkippedTopComment) {
276 std::string Code = "// comment\n"
277 "\n"
278 " // comment\n";
279 std::string Expected = "// comment\n"
280 "\n"
281 " // comment\n"
282 "#include <vector>\n";
283 EXPECT_EQ(Expected, insert(Code, "<vector>"));
286 TEST_F(HeaderIncludesTest, SkippedMixedComments) {
287 std::string Code = "// comment\n"
288 "// comment \\\n"
289 " comment continued\n"
290 "/*\n"
291 "* comment\n"
292 "*/\n";
293 std::string Expected = "// comment\n"
294 "// comment \\\n"
295 " comment continued\n"
296 "/*\n"
297 "* comment\n"
298 "*/\n"
299 "#include <vector>\n";
300 EXPECT_EQ(Expected, insert(Code, "<vector>"));
303 TEST_F(HeaderIncludesTest, MultipleBlockCommentsInOneLine) {
304 std::string Code = "/*\n"
305 "* comment\n"
306 "*/ /* comment\n"
307 "*/\n"
308 "\n\n"
309 "/* c1 */ /*c2 */\n";
310 std::string Expected = "/*\n"
311 "* comment\n"
312 "*/ /* comment\n"
313 "*/\n"
314 "\n\n"
315 "/* c1 */ /*c2 */\n"
316 "#include <vector>\n";
317 EXPECT_EQ(Expected, insert(Code, "<vector>"));
320 TEST_F(HeaderIncludesTest, CodeAfterComments) {
321 std::string Code = "/*\n"
322 "* comment\n"
323 "*/ /* comment\n"
324 "*/\n"
325 "\n\n"
326 "/* c1 */ /*c2 */\n"
327 "\n"
328 "int x;\n";
329 std::string Expected = "/*\n"
330 "* comment\n"
331 "*/ /* comment\n"
332 "*/\n"
333 "\n\n"
334 "/* c1 */ /*c2 */\n"
335 "\n"
336 "#include <vector>\n"
337 "int x;\n";
338 EXPECT_EQ(Expected, insert(Code, "<vector>"));
341 TEST_F(HeaderIncludesTest, FakeHeaderGuardIfDef) {
342 std::string Code = "// comment \n"
343 "#ifdef X\n"
344 "#define X\n";
345 std::string Expected = "// comment \n"
346 "#include <vector>\n"
347 "#ifdef X\n"
348 "#define X\n";
349 EXPECT_EQ(Expected, insert(Code, "<vector>"));
352 TEST_F(HeaderIncludesTest, RealHeaderGuardAfterComments) {
353 std::string Code = "// comment \n"
354 "#ifndef X\n"
355 "#define X\n"
356 "int x;\n"
357 "#define Y 1\n";
358 std::string Expected = "// comment \n"
359 "#ifndef X\n"
360 "#define X\n"
361 "#include <vector>\n"
362 "int x;\n"
363 "#define Y 1\n";
364 EXPECT_EQ(Expected, insert(Code, "<vector>"));
367 TEST_F(HeaderIncludesTest, PragmaOnce) {
368 std::string Code = "// comment \n"
369 "#pragma once\n"
370 "int x;\n";
371 std::string Expected = "// comment \n"
372 "#pragma once\n"
373 "#include <vector>\n"
374 "int x;\n";
375 EXPECT_EQ(Expected, insert(Code, "<vector>"));
378 TEST_F(HeaderIncludesTest, IfNDefWithNoDefine) {
379 std::string Code = "// comment \n"
380 "#ifndef X\n"
381 "int x;\n"
382 "#define Y 1\n";
383 std::string Expected = "// comment \n"
384 "#include <vector>\n"
385 "#ifndef X\n"
386 "int x;\n"
387 "#define Y 1\n";
388 EXPECT_EQ(Expected, insert(Code, "<vector>"));
391 TEST_F(HeaderIncludesTest, FakeHeaderGuard) {
392 std::string Code = "// comment \n"
393 "#ifndef X\n"
394 "#define 1\n";
395 std::string Expected = "// comment \n"
396 "#include <vector>\n"
397 "#ifndef X\n"
398 "#define 1\n";
399 EXPECT_EQ(Expected, insert(Code, "<vector>"));
402 TEST_F(HeaderIncludesTest, FakeHeaderGuardIfnDef) {
403 std::string Code = "#ifndef A_H\n"
404 "#define A_H 1\n"
405 "#endif";
406 std::string Expected = "#include \"b.h\"\n"
407 "#ifndef A_H\n"
408 "#define A_H 1\n"
409 "#endif";
411 EXPECT_EQ(Expected, insert(Code, "\"b.h\""));
414 TEST_F(HeaderIncludesTest, HeaderGuardWithComment) {
415 std::string Code = "// comment \n"
416 "#ifndef X // comment\n"
417 "// comment\n"
418 "/* comment\n"
419 "*/\n"
420 "/* comment */ #define X\n"
421 "int x;\n"
422 "#define Y 1\n";
423 std::string Expected = "// comment \n"
424 "#ifndef X // comment\n"
425 "// comment\n"
426 "/* comment\n"
427 "*/\n"
428 "/* comment */ #define X\n"
429 "#include <vector>\n"
430 "int x;\n"
431 "#define Y 1\n";
432 EXPECT_EQ(Expected, insert(Code, "<vector>"));
435 TEST_F(HeaderIncludesTest, EmptyCode) {
436 std::string Code = "";
437 std::string Expected = "#include <vector>\n";
438 EXPECT_EQ(Expected, insert(Code, "<vector>"));
441 TEST_F(HeaderIncludesTest, NoNewLineAtTheEndOfCode) {
442 std::string Code = "#include <map>";
443 std::string Expected = "#include <map>\n#include <vector>\n";
444 EXPECT_EQ(Expected, insert(Code, "<vector>"));
447 TEST_F(HeaderIncludesTest, SkipExistingHeaders) {
448 std::string Code = "#include \"a.h\"\n"
449 "#include <vector>\n";
450 std::string Expected = "#include \"a.h\"\n"
451 "#include <vector>\n";
452 EXPECT_EQ(Expected, insert(Code, "<vector>"));
453 EXPECT_EQ(Expected, insert(Code, "\"a.h\""));
456 TEST_F(HeaderIncludesTest, AddIncludesWithDifferentForms) {
457 std::string Code = "#include <vector>\n";
458 // FIXME: this might not be the best behavior.
459 std::string Expected = "#include \"vector\"\n"
460 "#include <vector>\n";
461 EXPECT_EQ(Expected, insert(Code, "\"vector\""));
464 TEST_F(HeaderIncludesTest, NoInsertionAfterCode) {
465 std::string Code = "#include \"a.h\"\n"
466 "void f() {}\n"
467 "#include \"b.h\"\n";
468 std::string Expected = "#include \"a.h\"\n"
469 "#include \"c.h\"\n"
470 "void f() {}\n"
471 "#include \"b.h\"\n";
472 EXPECT_EQ(Expected, insert(Code, "\"c.h\""));
475 TEST_F(HeaderIncludesTest, NoInsertionInStringLiteral) {
476 std::string Code = "#include \"a.h\"\n"
477 "const char[] = R\"(\n"
478 "#include \"b.h\"\n"
479 ")\";\n";
480 std::string Expected = "#include \"a.h\"\n"
481 "#include \"c.h\"\n"
482 "const char[] = R\"(\n"
483 "#include \"b.h\"\n"
484 ")\";\n";
485 EXPECT_EQ(Expected, insert(Code, "\"c.h\""));
488 TEST_F(HeaderIncludesTest, NoInsertionAfterOtherDirective) {
489 std::string Code = "#include \"a.h\"\n"
490 "#ifdef X\n"
491 "#include \"b.h\"\n"
492 "#endif\n";
493 std::string Expected = "#include \"a.h\"\n"
494 "#include \"c.h\"\n"
495 "#ifdef X\n"
496 "#include \"b.h\"\n"
497 "#endif\n";
498 EXPECT_EQ(Expected, insert(Code, "\"c.h\""));
501 TEST_F(HeaderIncludesTest, CanInsertAfterLongSystemInclude) {
502 std::string Code = "#include \"a.h\"\n"
503 "// comment\n\n"
504 "#include <a/b/c/d/e.h>\n";
505 std::string Expected = "#include \"a.h\"\n"
506 "// comment\n\n"
507 "#include <a/b/c/d/e.h>\n"
508 "#include <x.h>\n";
509 EXPECT_EQ(Expected, insert(Code, "<x.h>"));
512 TEST_F(HeaderIncludesTest, CanInsertAfterComment) {
513 std::string Code = "#include \"a.h\"\n"
514 "// Comment\n"
515 "\n"
516 "/* Comment */\n"
517 "// Comment\n"
518 "\n"
519 "#include \"b.h\"\n";
520 std::string Expected = "#include \"a.h\"\n"
521 "// Comment\n"
522 "\n"
523 "/* Comment */\n"
524 "// Comment\n"
525 "\n"
526 "#include \"b.h\"\n"
527 "#include \"c.h\"\n";
528 EXPECT_EQ(Expected, insert(Code, "\"c.h\""));
531 TEST_F(HeaderIncludesTest, LongCommentsInTheBeginningOfFile) {
532 std::string Code = "// Loooooooooooooooooooooooooong comment\n"
533 "// Loooooooooooooooooooooooooong comment\n"
534 "// Loooooooooooooooooooooooooong comment\n"
535 "#include <string>\n"
536 "#include <vector>\n"
537 "\n"
538 "#include \"a.h\"\n"
539 "#include \"b.h\"\n";
540 std::string Expected = "// Loooooooooooooooooooooooooong comment\n"
541 "// Loooooooooooooooooooooooooong comment\n"
542 "// Loooooooooooooooooooooooooong comment\n"
543 "#include <string>\n"
544 "#include <vector>\n"
545 "\n"
546 "#include \"a.h\"\n"
547 "#include \"b.h\"\n"
548 "#include \"third.h\"\n";
549 Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
550 .IncludeStyle;
551 EXPECT_EQ(Expected, insert(Code, "\"third.h\""));
554 TEST_F(HeaderIncludesTest, SimpleDeleteInclude) {
555 std::string Code = "#include \"abc.h\"\n"
556 "#include \"xyz.h\" // comment\n"
557 "int x;\n";
558 std::string Expected = "#include \"abc.h\"\n"
559 "int x;\n";
560 EXPECT_EQ(Expected, remove(Code, "\"xyz.h\""));
563 TEST_F(HeaderIncludesTest, DeleteQuotedOnly) {
564 std::string Code = "#include \"abc.h\"\n"
565 "#include <abc.h>\n"
566 "int x;\n";
567 std::string Expected = "#include <abc.h>\n"
568 "int x;\n";
569 EXPECT_EQ(Expected, remove(Code, "\"abc.h\""));
572 TEST_F(HeaderIncludesTest, DeleteAllCode) {
573 std::string Code = "#include \"xyz.h\"\n";
574 std::string Expected = "";
575 EXPECT_EQ(Expected, remove(Code, "\"xyz.h\""));
578 TEST_F(HeaderIncludesTest, DeleteOnlyIncludesWithSameQuote) {
579 std::string Code = "#include \"xyz.h\"\n"
580 "#include \"xyz\"\n"
581 "#include <xyz.h>\n";
582 std::string Expected = "#include \"xyz.h\"\n"
583 "#include \"xyz\"\n";
584 EXPECT_EQ(Expected, remove(Code, "<xyz.h>"));
587 TEST_F(HeaderIncludesTest, CanDeleteAfterCode) {
588 std::string Code = "#include \"a.h\"\n"
589 "void f() {}\n"
590 "#include \"b.h\"\n";
591 std::string Expected = "#include \"a.h\"\n"
592 "void f() {}\n";
593 EXPECT_EQ(Expected, remove(Code, "\"b.h\""));
596 } // namespace
597 } // namespace tooling
598 } // namespace clang