diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -196,6 +196,14 @@ } } +// FIXME(kirillbobyrev): We currently do not support the umbrella headers. +// Standard Library headers are typically umbrella headers, and system headers +// are likely to be the Standard Library headers. Until we have a good support +// for umbrella headers and Standard Library headers, don't warn about them. +bool mayConsiderUnused(const Inclusion *Inc) { + return Inc->Written.front() != '<'; +} + } // namespace ReferencedLocations findReferencedLocations(ParsedAST &AST) { @@ -283,6 +291,8 @@ ->getName() .str(); for (const auto *Inc : computeUnusedIncludes(AST)) { + if (!mayConsiderUnused(Inc)) + continue; Diag D; D.Message = llvm::formatv("included header {0} is not used", diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -1483,7 +1483,9 @@ TEST(DiagnosticsTest, IncludeCleaner) { Annotations Test(R"cpp( $fix[[ $diag[[#include "unused.h"]] -]] #include "used.h" +]]#include "used.h" + + #include void foo() { used(); @@ -1497,6 +1499,8 @@ TU.AdditionalFiles["used.h"] = R"cpp( void used() {} )cpp"; + TU.AdditionalFiles["system/system_header.h"] = ""; + TU.ExtraArgs = {"-isystem" + testPath("system")}; // Off by default. EXPECT_THAT(*TU.build().getDiagnostics(), IsEmpty()); Config Cfg; diff --git a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp --- a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp +++ b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp @@ -206,6 +206,7 @@ #include "dir/c.h" #include "dir/unused.h" #include "unused.h" + #include void foo() { a(); b(); @@ -220,17 +221,17 @@ TU.AdditionalFiles["dir/c.h"] = "void c();"; TU.AdditionalFiles["unused.h"] = "void unused();"; TU.AdditionalFiles["dir/unused.h"] = "void dirUnused();"; - TU.AdditionalFiles["not_included.h"] = "void notIncluded();"; - TU.ExtraArgs = {"-I" + testPath("dir")}; + TU.AdditionalFiles["system/system_header.h"] = ""; + TU.ExtraArgs.push_back("-I" + testPath("dir")); + TU.ExtraArgs.push_back("-isystem" + testPath("system")); TU.Code = MainFile.str(); ParsedAST AST = TU.build(); - auto UnusedIncludes = computeUnusedIncludes(AST); - std::vector UnusedHeaders; - UnusedHeaders.reserve(UnusedIncludes.size()); - for (const auto &Include : UnusedIncludes) - UnusedHeaders.push_back(Include->Written); - EXPECT_THAT(UnusedHeaders, - UnorderedElementsAre("\"unused.h\"", "\"dir/unused.h\"")); + std::vector UnusedIncludes; + for (const auto &Include : computeUnusedIncludes(AST)) + UnusedIncludes.push_back(Include->Written); + EXPECT_THAT(UnusedIncludes, + UnorderedElementsAre("\"unused.h\"", "\"dir/unused.h\"", + "")); } TEST(IncludeCleaner, ScratchBuffer) {