summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp34
-rw-r--r--clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h9
-rw-r--r--clang-tools-extra/docs/ReleaseNotes.rst5
-rw-r--r--clang-tools-extra/docs/clang-tidy/checks/readability-function-size.rst8
-rw-r--r--clang-tools-extra/test/clang-tidy/readability-function-size.cpp32
5 files changed, 78 insertions, 10 deletions
diff --git a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp
index c48b5132933..51b16849239 100644
--- a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp
@@ -38,6 +38,13 @@ public:
++Info.Branches;
// fallthrough
case Stmt::CompoundStmtClass:
+ // If this new compound statement is located in a compound statement,
+ // which is already nested NestingThreshold levels deep, record the start
+ // location of this new compound statement
+ if (CurrentNestingLevel == Info.NestingThreshold)
+ Info.NestingThresholders.push_back(Node->getLocStart());
+
+ ++CurrentNestingLevel;
TrackedParent.push_back(true);
break;
default:
@@ -47,7 +54,10 @@ public:
Base::TraverseStmt(Node);
+ if (TrackedParent.back())
+ --CurrentNestingLevel;
TrackedParent.pop_back();
+
return true;
}
@@ -59,13 +69,15 @@ public:
}
struct FunctionInfo {
- FunctionInfo() : Lines(0), Statements(0), Branches(0) {}
- unsigned Lines;
- unsigned Statements;
- unsigned Branches;
+ unsigned Lines = 0;
+ unsigned Statements = 0;
+ unsigned Branches = 0;
+ unsigned NestingThreshold = 0;
+ std::vector<SourceLocation> NestingThresholders;
};
FunctionInfo Info;
std::vector<bool> TrackedParent;
+ unsigned CurrentNestingLevel = 0;
};
FunctionSizeCheck::FunctionSizeCheck(StringRef Name, ClangTidyContext *Context)
@@ -73,13 +85,15 @@ FunctionSizeCheck::FunctionSizeCheck(StringRef Name, ClangTidyContext *Context)
LineThreshold(Options.get("LineThreshold", -1U)),
StatementThreshold(Options.get("StatementThreshold", 800U)),
BranchThreshold(Options.get("BranchThreshold", -1U)),
- ParameterThreshold(Options.get("ParameterThreshold", -1U)) {}
+ ParameterThreshold(Options.get("ParameterThreshold", -1U)),
+ NestingThreshold(Options.get("NestingThreshold", -1U)) {}
void FunctionSizeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "LineThreshold", LineThreshold);
Options.store(Opts, "StatementThreshold", StatementThreshold);
Options.store(Opts, "BranchThreshold", BranchThreshold);
Options.store(Opts, "ParameterThreshold", ParameterThreshold);
+ Options.store(Opts, "NestingThreshold", NestingThreshold);
}
void FunctionSizeCheck::registerMatchers(MatchFinder *Finder) {
@@ -90,6 +104,7 @@ void FunctionSizeCheck::check(const MatchFinder::MatchResult &Result) {
const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");
FunctionASTVisitor Visitor;
+ Visitor.Info.NestingThreshold = NestingThreshold;
Visitor.TraverseDecl(const_cast<FunctionDecl *>(Func));
auto &FI = Visitor.Info;
@@ -109,7 +124,8 @@ void FunctionSizeCheck::check(const MatchFinder::MatchResult &Result) {
if (FI.Lines > LineThreshold || FI.Statements > StatementThreshold ||
FI.Branches > BranchThreshold ||
- ActualNumberParameters > ParameterThreshold) {
+ ActualNumberParameters > ParameterThreshold ||
+ !FI.NestingThresholders.empty()) {
diag(Func->getLocation(),
"function %0 exceeds recommended size/complexity thresholds")
<< Func;
@@ -138,6 +154,12 @@ void FunctionSizeCheck::check(const MatchFinder::MatchResult &Result) {
DiagnosticIDs::Note)
<< ActualNumberParameters << ParameterThreshold;
}
+
+ for (const auto &CSPos : FI.NestingThresholders) {
+ diag(CSPos, "nesting level %0 starts here (threshold %1)",
+ DiagnosticIDs::Note)
+ << NestingThreshold + 1 << NestingThreshold;
+ }
}
} // namespace readability
diff --git a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h
index 905a0d79e84..3986b95a144 100644
--- a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h
@@ -27,8 +27,12 @@ namespace readability {
/// 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).
-/// * `ParameterThreshold` - flag functions having a high number of parameters.
-/// The default is `6`.
+/// * `ParameterThreshold` - flag functions having a high number of
+/// parameters. The default is `-1` (ignore the number of parameters).
+/// * `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).
class FunctionSizeCheck : public ClangTidyCheck {
public:
FunctionSizeCheck(StringRef Name, ClangTidyContext *Context);
@@ -42,6 +46,7 @@ private:
const unsigned StatementThreshold;
const unsigned BranchThreshold;
const unsigned ParameterThreshold;
+ const unsigned NestingThreshold;
};
} // namespace readability
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 26c9ede4f1b..85bb8b557d7 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -111,6 +111,11 @@ Improvements to clang-tidy
Finds possible inefficient vector operations in for loops that may cause
unnecessary memory reallocations.
+- Added `NestingThreshold` to `readability-function-size
+ <http://clang.llvm.org/extra/clang-tidy/checks/readability-function-size.html>`_ check
+
+ Finds compound statements which create next nesting level after `NestingThreshold` and emits a warning.
+
- Added `ParameterThreshold` to `readability-function-size
<http://clang.llvm.org/extra/clang-tidy/checks/readability-function-size.html>`_ check
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability-function-size.rst b/clang-tools-extra/docs/clang-tidy/checks/readability-function-size.rst
index 44b964f3e71..f903dd7aa95 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability-function-size.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability-function-size.rst
@@ -28,5 +28,11 @@ Options
.. option:: ParameterThreshold
- Flag functions that exceed a specified number of parameters. The default
+ Flag functions that exceed a specified number of parameters. The default
is `-1` (ignore the number of parameters).
+
+.. 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).
diff --git a/clang-tools-extra/test/clang-tidy/readability-function-size.cpp b/clang-tools-extra/test/clang-tidy/readability-function-size.cpp
index d98682c2b74..9a07eae7628 100644
--- a/clang-tools-extra/test/clang-tidy/readability-function-size.cpp
+++ b/clang-tools-extra/test/clang-tidy/readability-function-size.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s readability-function-size %t -- -config='{CheckOptions: [{key: readability-function-size.LineThreshold, value: 0}, {key: readability-function-size.StatementThreshold, value: 0}, {key: readability-function-size.BranchThreshold, value: 0}, {key: readability-function-size.ParameterThreshold, value: 5}]}' -- -std=c++11
+// RUN: %check_clang_tidy %s readability-function-size %t -- -config='{CheckOptions: [{key: readability-function-size.LineThreshold, value: 0}, {key: readability-function-size.StatementThreshold, value: 0}, {key: readability-function-size.BranchThreshold, value: 0}, {key: readability-function-size.ParameterThreshold, value: 5}, {key: readability-function-size.NestingThreshold, value: 2}]}' -- -std=c++11
// Bad formatting is intentional, don't run clang-format over the whole file!
@@ -59,3 +59,33 @@ void bar2() { class A { void barx() {;;} }; }
//
// CHECK-MESSAGES: :[[@LINE-4]]:30: warning: function 'barx' exceeds recommended size/complexity
// CHECK-MESSAGES: :[[@LINE-5]]:30: note: 2 statements (threshold 0)
+
+#define macro() {int x; {int y; {int z;}}}
+
+void baz0() { // 1
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'baz0' exceeds recommended size/complexity
+// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 9 statements (threshold 0)
+ int a;
+ { // 2
+ int b;
+ { // 3
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: nesting level 3 starts here (threshold 2)
+ int c;
+ { // 4
+ int d;
+ }
+ }
+ }
+ { // 2
+ int e;
+ }
+ { // 2
+ { // 3
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: nesting level 3 starts here (threshold 2)
+ int j;
+ }
+ }
+ macro()
+// CHECK-MESSAGES: :[[@LINE-1]]:3: note: nesting level 3 starts here (threshold 2)
+// CHECK-MESSAGES: :[[@LINE-27]]:25: note: expanded from macro 'macro'
+}
OpenPOWER on IntegriCloud