kbobyrev updated this revision to Diff 422228.
kbobyrev added a comment.
Fix the comment.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D123488/new/
https://reviews.llvm.org/D123488
Files:
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/IncludeCleaner.cpp
clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
Index: clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
+++ clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
@@ -1677,6 +1677,8 @@
]]
#include "used.h"
+ #include "ignore.h"
+
#include <system_header.h>
void foo() {
@@ -1693,12 +1695,19 @@
#pragma once
void used() {}
)cpp";
+ TU.AdditionalFiles["ignore.h"] = R"cpp(
+ #pragma once
+ void ignore() {}
+ )cpp";
TU.AdditionalFiles["system/system_header.h"] = "";
TU.ExtraArgs = {"-isystem" + testPath("system")};
// Off by default.
EXPECT_THAT(*TU.build().getDiagnostics(), IsEmpty());
Config Cfg;
Cfg.Diagnostics.UnusedIncludes = Config::UnusedIncludesPolicy::Strict;
+ // Set filtering.
+ Cfg.Diagnostics.Includes.IgnoreHeader.emplace_back(
+ [](llvm::StringRef Header) { return Header.endswith("ignore.h"); });
WithContextValue WithCfg(Config::Key, std::move(Cfg));
EXPECT_THAT(
*TU.build().getDiagnostics(),
Index: clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
+++ clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
@@ -263,6 +263,24 @@
EXPECT_TRUE(compileAndApply());
EXPECT_EQ(Conf.Diagnostics.UnusedIncludes,
Config::UnusedIncludesPolicy::Strict);
+
+ Frag = {};
+ EXPECT_TRUE(Conf.Diagnostics.Includes.IgnoreHeader.empty())
+ << Conf.Diagnostics.Includes.IgnoreHeader.size();
+ Frag.Diagnostics.Includes.IgnoreHeader.push_back(
+ Located<std::string>("foo.h"));
+ Frag.Diagnostics.Includes.IgnoreHeader.push_back(
+ Located<std::string>(".*inc"));
+ EXPECT_TRUE(compileAndApply());
+ auto HeaderFilter = [this](llvm::StringRef Path) {
+ for (auto &Filter : Conf.Diagnostics.Includes.IgnoreHeader) {
+ if (Filter(Path))
+ return true;
+ }
+ return false;
+ };
+ EXPECT_TRUE(HeaderFilter("foo.h"));
+ EXPECT_FALSE(HeaderFilter("bar.h"));
}
TEST_F(ConfigCompileTests, DiagnosticSuppression) {
Index: clang-tools-extra/clangd/IncludeCleaner.cpp
===================================================================
--- clang-tools-extra/clangd/IncludeCleaner.cpp
+++ clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -23,10 +23,14 @@
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/Syntax/Tokens.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Regex.h"
+#include <functional>
namespace clang {
namespace clangd {
@@ -233,7 +237,9 @@
}
}
-static bool mayConsiderUnused(const Inclusion &Inc, ParsedAST &AST) {
+static bool mayConsiderUnused(
+ const Inclusion &Inc, ParsedAST &AST,
+ llvm::ArrayRef<std::function<bool(llvm::StringRef)>> HeaderFilters) {
if (Inc.BehindPragmaKeep)
return false;
@@ -258,6 +264,15 @@
FE->getName());
return false;
}
+ for (auto &Filter : HeaderFilters) {
+ // Convert the path to Unix slashes and try to match aginast the fiilter.
+ llvm::SmallString<64> Path(Inc.Resolved);
+ llvm::sys::path::native(Path, llvm::sys::path::Style::posix);
+ if (Filter(Inc.Resolved)) {
+ dlog("{0} header is filtered out by the configuration", FE->getName());
+ return false;
+ }
+ }
return true;
}
@@ -369,6 +384,7 @@
const llvm::DenseSet<IncludeStructure::HeaderID> &ReferencedFiles,
const llvm::StringSet<> &ReferencedPublicHeaders) {
trace::Span Tracer("IncludeCleaner::getUnused");
+ const Config &Cfg = Config::current();
std::vector<const Inclusion *> Unused;
for (const Inclusion &MFI : AST.getIncludeStructure().MainFileIncludes) {
if (!MFI.HeaderID)
@@ -377,7 +393,8 @@
continue;
auto IncludeID = static_cast<IncludeStructure::HeaderID>(*MFI.HeaderID);
bool Used = ReferencedFiles.contains(IncludeID);
- if (!Used && !mayConsiderUnused(MFI, AST)) {
+ if (!Used &&
+ !mayConsiderUnused(MFI, AST, Cfg.Diagnostics.Includes.IgnoreHeader)) {
dlog("{0} was not used, but is not eligible to be diagnosed as unused",
MFI.Written);
continue;
Index: clang-tools-extra/clangd/ConfigFragment.h
===================================================================
--- clang-tools-extra/clangd/ConfigFragment.h
+++ clang-tools-extra/clangd/ConfigFragment.h
@@ -232,6 +232,15 @@
/// - None
llvm::Optional<Located<std::string>> UnusedIncludes;
+ /// Controls IncludeCleaner diagnostics.
+ struct IncludesBlock {
+ /// Regexes that will be used to avoid diagnosing certain includes as
+ /// unused or missing. These can match any suffix of the header file in
+ /// question.
+ std::vector<Located<std::string>> IgnoreHeader;
+ };
+ IncludesBlock Includes;
+
/// Controls how clang-tidy will run over the code base.
///
/// The settings are merged with any settings found in .clang-tidy
Index: clang-tools-extra/clangd/ConfigCompile.cpp
===================================================================
--- clang-tools-extra/clangd/ConfigCompile.cpp
+++ clang-tools-extra/clangd/ConfigCompile.cpp
@@ -45,7 +45,9 @@
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
#include <algorithm>
+#include <memory>
#include <string>
+#include <vector>
namespace clang {
namespace clangd {
@@ -432,6 +434,7 @@
Out.Apply.push_back([Val](const Params &, Config &C) {
C.Diagnostics.UnusedIncludes = *Val;
});
+ compile(std::move(F.Includes));
compile(std::move(F.ClangTidy));
}
@@ -507,6 +510,40 @@
}
}
+ void compile(Fragment::DiagnosticsBlock::IncludesBlock &&F) {
+#ifdef CLANGD_PATH_CASE_INSENSITIVE
+ static llvm::Regex::RegexFlags Flags = llvm::Regex::IgnoreCase;
+#else
+ static llvm::Regex::RegexFlags Flags = llvm::Regex::NoFlags;
+#endif
+ auto Filters = std::make_shared<std::vector<llvm::Regex>>();
+ for (auto &HeaderPattern : F.IgnoreHeader) {
+ // Anchor on the right.
+ std::string AnchoredPattern = "(" + *HeaderPattern + ")$";
+ llvm::Regex CompiledRegex(AnchoredPattern, Flags);
+ std::string RegexError;
+ if (!CompiledRegex.isValid(RegexError)) {
+ diag(Warning,
+ llvm::formatv("Invalid regular expression: {0}", *HeaderPattern)
+ .str(),
+ HeaderPattern.Range);
+ continue;
+ }
+ Filters->push_back(std::move(CompiledRegex));
+ }
+ if (Filters->empty())
+ return;
+ auto Filter = [Filters](llvm::StringRef Path) {
+ for (auto &Regex : *Filters)
+ if (Regex.match(Path))
+ return true;
+ return false;
+ };
+ Out.Apply.push_back([Filter](const Params &, Config &C) {
+ C.Diagnostics.Includes.IgnoreHeader.emplace_back(Filter);
+ });
+ }
+
void compile(Fragment::CompletionBlock &&F) {
if (F.AllScopes) {
Out.Apply.push_back(
Index: clang-tools-extra/clangd/Config.h
===================================================================
--- clang-tools-extra/clangd/Config.h
+++ clang-tools-extra/clangd/Config.h
@@ -29,6 +29,8 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Regex.h"
+#include <functional>
#include <string>
#include <vector>
@@ -100,6 +102,12 @@
} ClangTidy;
UnusedIncludesPolicy UnusedIncludes = None;
+
+ /// IncludeCleaner will not diagnose usages of these headers matched by
+ /// these regexes.
+ struct {
+ std::vector<std::function<bool(llvm::StringRef)>> IgnoreHeader;
+ } Includes;
} Diagnostics;
/// Style of the codebase.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits