Skip to content

Commit

Permalink
Re-land [clangd] Add support for missing includes analysis.
Browse files Browse the repository at this point in the history
This reverts commit 2eb5ac9.
  • Loading branch information
VitaNuo committed Mar 8, 2023
1 parent cac1805 commit 85a5c17
Show file tree
Hide file tree
Showing 14 changed files with 538 additions and 128 deletions.
12 changes: 7 additions & 5 deletions clang-tools-extra/clangd/Config.h
Expand Up @@ -88,11 +88,12 @@ struct Config {
bool StandardLibrary = true;
} Index;

enum class UnusedIncludesPolicy {
/// Diagnose unused includes.
enum class IncludesPolicy {
/// Diagnose missing and unused includes.
Strict,
None,
/// The same as Strict, but using the include-cleaner library.
/// The same as Strict, but using the include-cleaner library for
/// unused includes.
Experiment,
};
/// Controls warnings and errors when parsing code.
Expand All @@ -107,11 +108,12 @@ struct Config {
llvm::StringMap<std::string> CheckOptions;
} ClangTidy;

UnusedIncludesPolicy UnusedIncludes = UnusedIncludesPolicy::None;

/// Enable emitting diagnostics using stale preambles.
bool AllowStalePreamble = false;

IncludesPolicy UnusedIncludes = IncludesPolicy::None;
IncludesPolicy MissingIncludes = IncludesPolicy::None;

/// IncludeCleaner will not diagnose usages of these headers matched by
/// these regexes.
struct {
Expand Down
24 changes: 17 additions & 7 deletions clang-tools-extra/clangd/ConfigCompile.cpp
Expand Up @@ -431,23 +431,33 @@ struct FragmentCompiler {
});

if (F.UnusedIncludes)
if (auto Val =
compileEnum<Config::UnusedIncludesPolicy>("UnusedIncludes",
**F.UnusedIncludes)
.map("Strict", Config::UnusedIncludesPolicy::Strict)
.map("Experiment", Config::UnusedIncludesPolicy::Experiment)
.map("None", Config::UnusedIncludesPolicy::None)
.value())
if (auto Val = compileEnum<Config::IncludesPolicy>("UnusedIncludes",
**F.UnusedIncludes)
.map("Strict", Config::IncludesPolicy::Strict)
.map("Experiment", Config::IncludesPolicy::Experiment)
.map("None", Config::IncludesPolicy::None)
.value())
Out.Apply.push_back([Val](const Params &, Config &C) {
C.Diagnostics.UnusedIncludes = *Val;
});

if (F.AllowStalePreamble) {
if (auto Val = F.AllowStalePreamble)
Out.Apply.push_back([Val](const Params &, Config &C) {
C.Diagnostics.AllowStalePreamble = **Val;
});
}

if (F.MissingIncludes)
if (auto Val = compileEnum<Config::IncludesPolicy>("MissingIncludes",
**F.MissingIncludes)
.map("Strict", Config::IncludesPolicy::Strict)
.map("None", Config::IncludesPolicy::None)
.value())
Out.Apply.push_back([Val](const Params &, Config &C) {
C.Diagnostics.MissingIncludes = *Val;
});

compile(std::move(F.Includes));
compile(std::move(F.ClangTidy));
}
Expand Down
16 changes: 15 additions & 1 deletion clang-tools-extra/clangd/ConfigFragment.h
Expand Up @@ -221,7 +221,7 @@ struct Fragment {
/// This often has other advantages, such as skipping some analysis.
std::vector<Located<std::string>> Suppress;

/// Controls how clangd will correct "unnecessary #include directives.
/// Controls how clangd will correct "unnecessary" #include directives.
/// clangd can warn if a header is `#include`d but not used, and suggest
/// removing it.
//
Expand All @@ -236,9 +236,23 @@ struct Fragment {
/// - None
std::optional<Located<std::string>> UnusedIncludes;


/// Enable emitting diagnostics using stale preambles.
std::optional<Located<bool>> AllowStalePreamble;

/// Controls if clangd should analyze missing #include directives.
/// clangd will warn if no header providing a symbol is `#include`d
/// (missing) directly, and suggest adding it.
///
/// Strict means a header providing a symbol is missing if it is not
/// *directly #include'd. The file might still compile if the header is
/// included transitively.
///
/// Valid values are:
/// - Strict
/// - None
std::optional<Located<std::string>> MissingIncludes;

/// Controls IncludeCleaner diagnostics.
struct IncludesBlock {
/// Regexes that will be used to avoid diagnosing certain includes as
Expand Down
3 changes: 3 additions & 0 deletions clang-tools-extra/clangd/ConfigYAML.cpp
Expand Up @@ -128,6 +128,9 @@ class Parser {
Dict.handle("UnusedIncludes", [&](Node &N) {
F.UnusedIncludes = scalarValue(N, "UnusedIncludes");
});
Dict.handle("MissingIncludes", [&](Node &N) {
F.MissingIncludes = scalarValue(N, "MissingIncludes");
});
Dict.handle("Includes", [&](Node &N) { parse(F.Includes, N); });
Dict.handle("ClangTidy", [&](Node &N) { parse(F.ClangTidy, N); });
Dict.handle("AllowStalePreamble", [&](Node &N) {
Expand Down

0 comments on commit 85a5c17

Please sign in to comment.