felix642 updated this revision to Diff 556334.
felix642 added a comment.
Forgot to update a comment
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D159436/new/
https://reviews.llvm.org/D159436
Files:
clang-tools-extra/clang-tidy/ClangTidyCheck.h
clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp
clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/readability/function-size.rst
clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp
clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp
Index: clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp
+++ clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp
@@ -55,5 +55,12 @@
// CHECK-CHILD6: Checks: {{.*-llvm-qualified-auto'? *$}}
// CHECK-CHILD6-NOT: modernize-use-using.IgnoreMacros
+// RUN: clang-tidy -dump-config \
+// RUN: --config='{CheckOptions: {readability-function-size.LineThreshold: ""}, \
+// RUN: Checks: readability-function-size}' \
+// RUN: %S/Inputs/config-files/4/44/- -- | FileCheck %s -check-prefix=CHECK-CHILD7
+// CHECK-CHILD7: readability-function-size.LineThreshold: none
+
+
// Validate that check options are printed in alphabetical order:
// RUN: clang-tidy --checks="-*,readability-identifier-naming" --dump-config %S/Inputs/config-files/- -- | grep "readability-identifier-naming\." | sort --check
Index: clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp
@@ -8,6 +8,16 @@
// RUN: readability-function-size.VariableThreshold: 1 \
// RUN: }}'
+
+// RUN: %check_clang_tidy -check-suffixes=OPTIONAL %s readability-function-size %t -- \
+// RUN: -config='{CheckOptions: { \
+// RUN: readability-function-size.StatementThreshold: "-1", \
+// RUN: readability-function-size.BranchThreshold: "5", \
+// RUN: readability-function-size.ParameterThreshold: "none", \
+// RUN: readability-function-size.NestingThreshold: "", \
+// RUN: readability-function-size.VariableThreshold: "" \
+// RUN: }}'
+
// Bad formatting is intentional, don't run clang-format over the whole file!
void foo1() {
@@ -103,9 +113,11 @@
// check that nested if's are not reported. this was broken initially
void nesting_if() { // 1
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'nesting_if' exceeds recommended size/complexity
- // CHECK-MESSAGES: :[[@LINE-2]]:6: note: 23 lines including whitespace and comments (threshold 0)
+ // CHECK-MESSAGES: :[[@LINE-2]]:6: note: 25 lines including whitespace and comments (threshold 0)
// CHECK-MESSAGES: :[[@LINE-3]]:6: note: 18 statements (threshold 0)
// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 6 branches (threshold 0)
+ // CHECK-MESSAGES-OPTIONAL: :[[@LINE-5]]:6: warning: function 'nesting_if' exceeds recommended size/complexity
+ // CHECK-MESSAGES-OPTIONAL: :[[@LINE-6]]:6: note: 6 branches (threshold 5)
if (true) { // 2
int j;
} else if (true) { // 2
@@ -123,7 +135,7 @@
} else if (true) { // 2
int j;
}
- // CHECK-MESSAGES: :[[@LINE-22]]:6: note: 6 variables (threshold 1)
+ // CHECK-MESSAGES: :[[@LINE-24]]:6: note: 6 variables (threshold 1)
}
// however this should warn
Index: clang-tools-extra/docs/clang-tidy/checks/readability/function-size.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/readability/function-size.rst
+++ clang-tools-extra/docs/clang-tidy/checks/readability/function-size.rst
@@ -12,8 +12,8 @@
.. option:: LineThreshold
- Flag functions exceeding this number of lines. The default is `-1` (ignore
- the number of lines).
+ Flag functions exceeding this number of lines. This parameter is disabled
+ by default.
.. option:: StatementThreshold
@@ -23,23 +23,23 @@
.. option:: BranchThreshold
- Flag functions exceeding this number of control statements. The default is
- `-1` (ignore the number of branches).
+ Flag functions exceeding this number of control statements. This parameter
+ is disabled by default.
.. option:: ParameterThreshold
- Flag functions that exceed a specified number of parameters. The default
- is `-1` (ignore the number of parameters).
+ Flag functions that exceed a specified number of parameters. This parameter
+ is disabled by default.
.. option:: NestingThreshold
Flag compound statements which create next nesting level after
`NestingThreshold`. This may differ significantly from the expected value
- for macro-heavy code. The default is `-1` (ignore the nesting level).
+ for macro-heavy code. This parameter is disabled by default.
.. option:: VariableThreshold
Flag functions exceeding this number of variables declared in the body.
- The default is `-1` (ignore the number of variables).
+ This parameter is disabled by default.
Please note that function parameters and variables declared in lambdas,
GNU Statement Expressions, and nested class inline functions are not counted.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -113,6 +113,10 @@
- Improved `--dump-config` to print check options in alphabetical order.
+- Added support for optional parameters. Parameters that previously used -1 to disable
+ their effect can now be set to `none`, `null`, or left empty to get the same
+ behaviour.
+
New checks
^^^^^^^^^^
Index: clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h
+++ clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h
@@ -17,21 +17,21 @@
///
/// These options are supported:
///
-/// * `LineThreshold` - flag functions exceeding this number of lines. The
-/// default is `-1` (ignore the number of lines).
+/// * `LineThreshold` - flag functions exceeding this number of lines. This
+/// parameter is disabled by default.
/// * `StatementThreshold` - flag functions exceeding this number of
/// statements. This may differ significantly from the number of lines for
/// macro-heavy code. The default is `800`.
/// * `BranchThreshold` - flag functions exceeding this number of control
-/// statements. The default is `-1` (ignore the number of branches).
+/// statements. This parameter is disabled by default.
/// * `ParameterThreshold` - flag functions having a high number of
-/// parameters. The default is `-1` (ignore the number of parameters).
+/// parameters. This parameter is disabled by default.
/// * `NestingThreshold` - flag compound statements which create next nesting
/// level after `NestingThreshold`. This may differ significantly from the
-/// expected value for macro-heavy code. The default is `-1` (ignore the
-/// nesting level).
+/// expected value for macro-heavy code. This parameter is disabled by
+/// default.
/// * `VariableThreshold` - flag functions having a high number of variable
-/// declarations. The default is `-1` (ignore the number of variables).
+/// declarations. This parameter is disabled by default.
class FunctionSizeCheck : public ClangTidyCheck {
public:
FunctionSizeCheck(StringRef Name, ClangTidyContext *Context);
@@ -41,12 +41,23 @@
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
- const unsigned LineThreshold;
- const unsigned StatementThreshold;
- const unsigned BranchThreshold;
- const unsigned ParameterThreshold;
- const unsigned NestingThreshold;
- const unsigned VariableThreshold;
+ const std::optional<unsigned> LineThreshold;
+ const std::optional<unsigned> StatementThreshold;
+ const std::optional<unsigned> BranchThreshold;
+ const std::optional<unsigned> ParameterThreshold;
+ const std::optional<unsigned> NestingThreshold;
+ const std::optional<unsigned> VariableThreshold;
+
+ static constexpr std::optional<unsigned> DefaultLineThreshold = std::nullopt;
+ static constexpr std::optional<unsigned> DefaultStatementThreshold = 800U;
+ static constexpr std::optional<unsigned> DefaultBranchThreshold =
+ std::nullopt;
+ static constexpr std::optional<unsigned> DefaultParameterThreshold =
+ std::nullopt;
+ static constexpr std::optional<unsigned> DefaultNestingThreshold =
+ std::nullopt;
+ static constexpr std::optional<unsigned> DefaultVariableThreshold =
+ std::nullopt;
};
} // namespace clang::tidy::readability
Index: clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp
@@ -126,12 +126,16 @@
FunctionSizeCheck::FunctionSizeCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
- LineThreshold(Options.get("LineThreshold", -1U)),
- StatementThreshold(Options.get("StatementThreshold", 800U)),
- BranchThreshold(Options.get("BranchThreshold", -1U)),
- ParameterThreshold(Options.get("ParameterThreshold", -1U)),
- NestingThreshold(Options.get("NestingThreshold", -1U)),
- VariableThreshold(Options.get("VariableThreshold", -1U)) {}
+ LineThreshold(Options.get("LineThreshold", DefaultLineThreshold)),
+ StatementThreshold(
+ Options.get("StatementThreshold", DefaultStatementThreshold)),
+ BranchThreshold(Options.get("BranchThreshold", DefaultBranchThreshold)),
+ ParameterThreshold(
+ Options.get("ParameterThreshold", DefaultParameterThreshold)),
+ NestingThreshold(
+ Options.get("NestingThreshold", DefaultNestingThreshold)),
+ VariableThreshold(
+ Options.get("VariableThreshold", DefaultVariableThreshold)) {}
void FunctionSizeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "LineThreshold", LineThreshold);
@@ -155,7 +159,7 @@
const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");
FunctionASTVisitor Visitor;
- Visitor.Info.NestingThreshold = NestingThreshold;
+ Visitor.Info.NestingThreshold = NestingThreshold.value_or(-1);
Visitor.TraverseDecl(const_cast<FunctionDecl *>(Func));
auto &FI = Visitor.Info;
@@ -173,49 +177,51 @@
unsigned ActualNumberParameters = Func->getNumParams();
- if (FI.Lines > LineThreshold || FI.Statements > StatementThreshold ||
- FI.Branches > BranchThreshold ||
- ActualNumberParameters > ParameterThreshold ||
- !FI.NestingThresholders.empty() || FI.Variables > VariableThreshold) {
+ if ((LineThreshold && FI.Lines > LineThreshold) ||
+ (StatementThreshold && FI.Statements > StatementThreshold) ||
+ (BranchThreshold && FI.Branches > BranchThreshold) ||
+ (ParameterThreshold && ActualNumberParameters > ParameterThreshold) ||
+ !FI.NestingThresholders.empty() ||
+ (VariableThreshold && FI.Variables > VariableThreshold)) {
diag(Func->getLocation(),
"function %0 exceeds recommended size/complexity thresholds")
<< Func;
}
- if (FI.Lines > LineThreshold) {
+ if (LineThreshold && FI.Lines > LineThreshold) {
diag(Func->getLocation(),
"%0 lines including whitespace and comments (threshold %1)",
DiagnosticIDs::Note)
- << FI.Lines << LineThreshold;
+ << FI.Lines << LineThreshold.value();
}
- if (FI.Statements > StatementThreshold) {
+ if (StatementThreshold && FI.Statements > StatementThreshold) {
diag(Func->getLocation(), "%0 statements (threshold %1)",
DiagnosticIDs::Note)
- << FI.Statements << StatementThreshold;
+ << FI.Statements << StatementThreshold.value();
}
- if (FI.Branches > BranchThreshold) {
+ if (BranchThreshold && FI.Branches > BranchThreshold) {
diag(Func->getLocation(), "%0 branches (threshold %1)", DiagnosticIDs::Note)
- << FI.Branches << BranchThreshold;
+ << FI.Branches << BranchThreshold.value();
}
- if (ActualNumberParameters > ParameterThreshold) {
+ if (ParameterThreshold && ActualNumberParameters > ParameterThreshold) {
diag(Func->getLocation(), "%0 parameters (threshold %1)",
DiagnosticIDs::Note)
- << ActualNumberParameters << ParameterThreshold;
+ << ActualNumberParameters << ParameterThreshold.value();
}
for (const auto &CSPos : FI.NestingThresholders) {
diag(CSPos, "nesting level %0 starts here (threshold %1)",
DiagnosticIDs::Note)
- << NestingThreshold + 1 << NestingThreshold;
+ << NestingThreshold.value() + 1 << NestingThreshold.value();
}
- if (FI.Variables > VariableThreshold) {
+ if (VariableThreshold && FI.Variables > VariableThreshold) {
diag(Func->getLocation(), "%0 variables (threshold %1)",
DiagnosticIDs::Note)
- << FI.Variables << VariableThreshold;
+ << FI.Variables << VariableThreshold.value();
}
}
Index: clang-tools-extra/clang-tidy/ClangTidyCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyCheck.h
+++ clang-tools-extra/clang-tidy/ClangTidyCheck.h
@@ -184,8 +184,8 @@
/// integral type ``T``.
///
/// Reads the option with the check-local name \p LocalName from the
- /// ``CheckOptions``. If the corresponding key is not present, return
- /// ``std::nullopt``.
+ /// ``CheckOptions``. If the corresponding key is not present,
+ /// return ``std::nullopt``.
///
/// If the corresponding key can't be parsed as a ``T``, emit a
/// diagnostic and return ``std::nullopt``.
@@ -201,6 +201,31 @@
return std::nullopt;
}
+ /// Read a named option from the ``Context`` and parse it as an
+ /// integral type ``T``.
+ ///
+ /// Reads the option with the check-local name \p LocalName from the
+ /// ``CheckOptions``. If the corresponding key is `none`, `null`,
+ /// `-1` or empty, return ``std::nullopt``. If the corresponding
+ /// key is not present, return \p Default.
+ ///
+ /// If the corresponding key can't be parsed as a ``T``, emit a
+ /// diagnostic and return \p Default.
+ template <typename T>
+ std::enable_if_t<std::is_integral_v<T>, std::optional<T>>
+ get(StringRef LocalName, std::optional<T> Default) const {
+ if (std::optional<StringRef> Value = get(LocalName)) {
+ if (Value == "" || Value == "none" || Value == "null" ||
+ (std::is_unsigned_v<T> && Value == "-1"))
+ return std::nullopt;
+ T Result{};
+ if (!StringRef(*Value).getAsInteger(10, Result))
+ return Result;
+ diagnoseBadIntegerOption(NamePrefix + LocalName, *Value);
+ }
+ return Default;
+ }
+
/// Read a named option from the ``Context`` and parse it as an
/// integral type ``T``.
///
@@ -245,6 +270,39 @@
return std::nullopt;
}
+ /// Read a named option from the ``Context`` and parse it as an
+ /// integral type ``T``.
+ ///
+ /// Reads the option with the check-local name \p LocalName from local or
+ /// global ``CheckOptions``. Gets local option first. If local is not
+ /// present, falls back to get global option. If global option is not
+ /// present either, return \p Default. If the value value was found
+ /// and equals ``none``, ``null``, ``-1`` or empty, return ``std::nullopt``.
+ ///
+ /// If the corresponding key can't be parsed as a ``T``, emit a
+ /// diagnostic and return \p Default.
+ template <typename T>
+ std::enable_if_t<std::is_integral_v<T>, std::optional<T>>
+ getLocalOrGlobal(StringRef LocalName, std::optional<T> Default) const {
+ std::optional<StringRef> ValueOr = get(LocalName);
+ bool IsGlobal = false;
+ if (!ValueOr) {
+ IsGlobal = true;
+ ValueOr = getLocalOrGlobal(LocalName);
+ if (!ValueOr)
+ return Default;
+ }
+ T Result{};
+ if (ValueOr == "" || ValueOr == "none" || ValueOr == "null" ||
+ (std::is_unsigned_v<T> && ValueOr == "-1"))
+ return std::nullopt;
+ if (!StringRef(*ValueOr).getAsInteger(10, Result))
+ return Result;
+ diagnoseBadIntegerOption(
+ IsGlobal ? Twine(LocalName) : NamePrefix + LocalName, *ValueOr);
+ return Default;
+ }
+
/// Read a named option from the ``Context`` and parse it as an
/// integral type ``T``.
///
@@ -286,8 +344,8 @@
/// enum type ``T``.
///
/// Reads the option with the check-local name \p LocalName from the
- /// ``CheckOptions``. If the corresponding key is not present, return
- /// \p Default.
+ /// ``CheckOptions``. If the corresponding key is not present,
+ /// return \p Default.
///
/// If the corresponding key can't be parsed as a ``T``, emit a
/// diagnostic and return \p Default.
@@ -356,6 +414,19 @@
storeInt(Options, LocalName, Value);
}
+ /// Stores an option with the check-local name \p LocalName with
+ /// integer value \p Value to \p Options. If the value is empty
+ /// stores ``
+ template <typename T>
+ std::enable_if_t<std::is_integral_v<T>>
+ store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
+ std::optional<T> Value) const {
+ if (Value)
+ storeInt(Options, LocalName, *Value);
+ else
+ store(Options, LocalName, "none");
+ }
+
/// Stores an option with the check-local name \p LocalName as the string
/// representation of the Enum \p Value to \p Options.
///
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits