kadircet created this revision.
kadircet added reviewers: hokein, sammccall.
Herald added a subscriber: arphaman.
Herald added a project: All.
kadircet requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D142890
Files:
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/ConfigYAML.cpp
clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
Index: clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
+++ clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
@@ -538,7 +538,7 @@
void foo() {}
)cpp");
Config Cfg;
- Cfg.Diagnostics.UnusedIncludes = Config::Experiment;
+ Cfg.Diagnostics.UnusedIncludes = Config::UnusedIncludesPolicy::Experiment;
WithContextValue Ctx(Config::Key, std::move(Cfg));
ParsedAST AST = TU.build();
@@ -627,7 +627,7 @@
TU.ExtraArgs.emplace_back("-xobjective-c");
Config Cfg;
- Cfg.Diagnostics.UnusedIncludes = Config::Strict;
+ Cfg.Diagnostics.UnusedIncludes = Config::UnusedIncludesPolicy::Strict;
WithContextValue Ctx(Config::Key, std::move(Cfg));
ParsedAST AST = TU.build();
EXPECT_THAT(AST.getDiagnostics(), llvm::ValueIs(IsEmpty()));
Index: clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
+++ clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
@@ -273,6 +273,31 @@
EXPECT_THAT(Results[0].Style.FullyQualifiedNamespaces,
ElementsAre(val("foo"), val("bar")));
}
+
+TEST(ParseYAML, DiagnosticsMode) {
+ CapturedDiags Diags;
+ {
+ Annotations YAML(R"yaml(
+Diagnostics:
+ Mode: Fast)yaml");
+ auto Results =
+ Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback());
+ ASSERT_THAT(Diags.Diagnostics, IsEmpty());
+ ASSERT_EQ(Results.size(), 1u);
+ EXPECT_THAT(Results[0].Diagnostics.Mode, llvm::ValueIs(val("Fast")));
+ }
+
+ {
+ Annotations YAML(R"yaml(
+Diagnostics:
+ Mode: Strict)yaml");
+ auto Results =
+ Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback());
+ ASSERT_THAT(Diags.Diagnostics, IsEmpty());
+ ASSERT_EQ(Results.size(), 1u);
+ EXPECT_THAT(Results[0].Diagnostics.Mode, llvm::ValueIs(val("Strict")));
+ }
+}
} // namespace
} // namespace config
} // namespace clangd
Index: clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
+++ clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
@@ -543,6 +543,23 @@
EXPECT_TRUE(compileAndApply());
EXPECT_THAT(Conf.Style.FullyQualifiedNamespaces, ElementsAre("foo", "bar"));
}
+
+TEST_F(ConfigCompileTests, DiagnosticsMode) {
+ Frag = {};
+ EXPECT_TRUE(compileAndApply());
+ // Defaults to Strict.
+ EXPECT_EQ(Conf.Diagnostics.Mode, Config::DiagnosticsMode::Strict);
+
+ Frag.Diagnostics.Mode.emplace("Fast");
+ EXPECT_TRUE(compileAndApply());
+ // Defaults to Strict.
+ EXPECT_EQ(Conf.Diagnostics.Mode, Config::DiagnosticsMode::Fast);
+
+ Frag.Diagnostics.Mode.emplace("Strict");
+ EXPECT_TRUE(compileAndApply());
+ // Defaults to Strict.
+ EXPECT_EQ(Conf.Diagnostics.Mode, Config::DiagnosticsMode::Strict);
+}
} // namespace
} // namespace config
} // namespace clangd
Index: clang-tools-extra/clangd/ConfigYAML.cpp
===================================================================
--- clang-tools-extra/clangd/ConfigYAML.cpp
+++ clang-tools-extra/clangd/ConfigYAML.cpp
@@ -130,6 +130,7 @@
});
Dict.handle("Includes", [&](Node &N) { parse(F.Includes, N); });
Dict.handle("ClangTidy", [&](Node &N) { parse(F.ClangTidy, N); });
+ Dict.handle("Mode", [&](Node &N) { F.Mode = scalarValue(N, "Mode"); });
Dict.parse(N);
}
@@ -268,7 +269,7 @@
// If Key is seen twice, Parse runs only once and an error is reported.
void handle(llvm::StringLiteral Key, std::function<void(Node &)> Parse) {
for (const auto &Entry : Keys) {
- (void) Entry;
+ (void)Entry;
assert(Entry.first != Key && "duplicate key handler");
}
Keys.emplace_back(Key, std::move(Parse));
Index: clang-tools-extra/clangd/ConfigFragment.h
===================================================================
--- clang-tools-extra/clangd/ConfigFragment.h
+++ clang-tools-extra/clangd/ConfigFragment.h
@@ -232,9 +232,16 @@
///
/// Valid values are:
/// - Strict
+ /// - Experiment
/// - None
std::optional<Located<std::string>> UnusedIncludes;
+ /// Controls whether clangd should emit fast but loose diagnostics.
+ /// Valid values are:
+ /// - Fast
+ /// - Strict
+ std::optional<Located<std::string>> Mode;
+
/// Controls IncludeCleaner diagnostics.
struct IncludesBlock {
/// Regexes that will be used to avoid diagnosing certain includes as
Index: clang-tools-extra/clangd/ConfigCompile.cpp
===================================================================
--- clang-tools-extra/clangd/ConfigCompile.cpp
+++ clang-tools-extra/clangd/ConfigCompile.cpp
@@ -441,8 +441,16 @@
Out.Apply.push_back([Val](const Params &, Config &C) {
C.Diagnostics.UnusedIncludes = *Val;
});
- compile(std::move(F.Includes));
+ if (F.Mode) {
+ if (auto Val = compileEnum<Config::DiagnosticsMode>("Mode", **F.Mode)
+ .map("Strict", Config::DiagnosticsMode::Strict)
+ .map("Fast", Config::DiagnosticsMode::Fast)
+ .value())
+ Out.Apply.push_back(
+ [Val](const Params &, Config &C) { C.Diagnostics.Mode = *Val; });
+ }
+ compile(std::move(F.Includes));
compile(std::move(F.ClangTidy));
}
Index: clang-tools-extra/clangd/Config.h
===================================================================
--- clang-tools-extra/clangd/Config.h
+++ clang-tools-extra/clangd/Config.h
@@ -88,13 +88,21 @@
bool StandardLibrary = true;
} Index;
- enum UnusedIncludesPolicy {
+ enum class UnusedIncludesPolicy {
/// Diagnose unused includes.
Strict,
None,
/// The same as Strict, but using the include-cleaner library.
Experiment,
};
+ /// Configures whether clangd can emit fast but possibly inaccurate
+ /// diagnostics.
+ enum class DiagnosticsMode {
+ /// Only emit diagnostics with up-to-date analysis.
+ Strict,
+ /// Can emit diagnostics with stale analysis.
+ Fast,
+ };
/// Controls warnings and errors when parsing code.
struct {
bool SuppressAll = false;
@@ -107,7 +115,9 @@
llvm::StringMap<std::string> CheckOptions;
} ClangTidy;
- UnusedIncludesPolicy UnusedIncludes = None;
+ UnusedIncludesPolicy UnusedIncludes = UnusedIncludesPolicy::None;
+
+ DiagnosticsMode Mode = DiagnosticsMode::Strict;
/// IncludeCleaner will not diagnose usages of these headers matched by
/// these regexes.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits