https://github.com/PiotrZSL created 
https://github.com/llvm/llvm-project/pull/131406

Extend readability-function-size check by adding
IgnoreMacros option.

Fixes #112835

>From 95b3e21c8712d9489cdff8bc2ce78b447d894837 Mon Sep 17 00:00:00 2001
From: Piotr Zegar <m...@piotrzegar.pl>
Date: Tue, 7 Jan 2025 16:21:12 +0000
Subject: [PATCH] [clang-tidy] Add IgnoreMacros to readability-function-size

Extend readability-function-size check by adding
IgnoreMacros option.

Fixes: #112835
---
 .../clang-tidy/readability/FunctionSizeCheck.cpp  | 15 +++++++++++++--
 .../clang-tidy/readability/FunctionSizeCheck.h    |  2 ++
 clang-tools-extra/docs/ReleaseNotes.rst           |  4 ++++
 .../checks/readability/function-size.rst          |  7 +++++++
 .../checkers/readability/function-size.cpp        | 15 ++++++++++++++-
 5 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp
index 3313bcb39b7f3..9535211413be6 100644
--- a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp
@@ -20,6 +20,8 @@ class FunctionASTVisitor : public 
RecursiveASTVisitor<FunctionASTVisitor> {
   using Base = RecursiveASTVisitor<FunctionASTVisitor>;
 
 public:
+  FunctionASTVisitor(bool IgnoreMacros) : IgnoreMacros(IgnoreMacros) {}
+
   bool VisitVarDecl(VarDecl *VD) {
     // Do not count function params.
     // Do not count decomposition declarations (C++17's structured bindings).
@@ -39,6 +41,9 @@ class FunctionASTVisitor : public 
RecursiveASTVisitor<FunctionASTVisitor> {
     if (!Node)
       return Base::TraverseStmt(Node);
 
+    if (IgnoreMacros && Node->getBeginLoc().isMacroID())
+      return true;
+
     if (TrackedParent.back() && !isa<CompoundStmt>(Node))
       ++Info.Statements;
 
@@ -120,6 +125,9 @@ class FunctionASTVisitor : public 
RecursiveASTVisitor<FunctionASTVisitor> {
   llvm::BitVector TrackedParent;
   unsigned StructNesting = 0;
   unsigned CurrentNestingLevel = 0;
+
+private:
+  const bool IgnoreMacros;
 };
 
 } // namespace
@@ -135,7 +143,9 @@ FunctionSizeCheck::FunctionSizeCheck(StringRef Name, 
ClangTidyContext *Context)
       NestingThreshold(
           Options.get("NestingThreshold", DefaultNestingThreshold)),
       VariableThreshold(
-          Options.get("VariableThreshold", DefaultVariableThreshold)) {}
+          Options.get("VariableThreshold", DefaultVariableThreshold)),
+      IgnoreMacros(
+          Options.getLocalOrGlobal("IgnoreMacros", DefaultIgnoreMacros)) {}
 
 void FunctionSizeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "LineThreshold", LineThreshold);
@@ -144,6 +154,7 @@ void 
FunctionSizeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "ParameterThreshold", ParameterThreshold);
   Options.store(Opts, "NestingThreshold", NestingThreshold);
   Options.store(Opts, "VariableThreshold", VariableThreshold);
+  Options.store(Opts, "IgnoreMacros", IgnoreMacros);
 }
 
 void FunctionSizeCheck::registerMatchers(MatchFinder *Finder) {
@@ -158,7 +169,7 @@ void FunctionSizeCheck::registerMatchers(MatchFinder 
*Finder) {
 void FunctionSizeCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");
 
-  FunctionASTVisitor Visitor;
+  FunctionASTVisitor Visitor(IgnoreMacros);
   Visitor.Info.NestingThreshold = NestingThreshold.value_or(-1);
   Visitor.TraverseDecl(const_cast<FunctionDecl *>(Func));
   auto &FI = Visitor.Info;
diff --git a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h 
b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h
index 106c69ff07393..b36de68f9583c 100644
--- a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h
@@ -47,6 +47,7 @@ class FunctionSizeCheck : public ClangTidyCheck {
   const std::optional<unsigned> ParameterThreshold;
   const std::optional<unsigned> NestingThreshold;
   const std::optional<unsigned> VariableThreshold;
+  const bool IgnoreMacros;
 
   static constexpr std::optional<unsigned> DefaultLineThreshold = std::nullopt;
   static constexpr std::optional<unsigned> DefaultStatementThreshold = 800U;
@@ -58,6 +59,7 @@ class FunctionSizeCheck : public ClangTidyCheck {
       std::nullopt;
   static constexpr std::optional<unsigned> DefaultVariableThreshold =
       std::nullopt;
+  static constexpr bool DefaultIgnoreMacros = false;
 };
 
 } // namespace clang::tidy::readability
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 0ad52f83fad85..6ae117ca57ed4 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -178,6 +178,10 @@ Changes in existing checks
   tolerating fix-it breaking compilation when functions is used as pointers
   to avoid matching usage of functions within the current compilation unit.
 
+- Improved :doc:`readability-function-size
+  <clang-tidy/checks/readability/function-size>` check by adding the option
+  `IgnoreMacros` to allow ignoring code inside macros.
+
 Removed checks
 ^^^^^^^^^^^^^^
 
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 133bd3e9c8cbe..4d7c8e9ed47f2 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
@@ -43,3 +43,10 @@ Options
    The default is `none` (ignore the number of variables).
    Please note that function parameters and variables declared in lambdas,
    GNU Statement Expressions, and nested class inline functions are not 
counted.
+
+.. option:: IgnoreMacros
+
+   If set to `true`, the check will ignore code inside macros. Note, that also
+   any macro arguments are ignored, even if they should count to the 
complexity.
+   As this might change in the future, this option isn't guaranteed to be
+   forward-compatible. Default is `false`.
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp
index 45b2604b43d03..f7fe5509fed99 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp
@@ -15,7 +15,8 @@
 // RUN:         readability-function-size.BranchThreshold: "5", \
 // RUN:         readability-function-size.ParameterThreshold: "none", \
 // RUN:         readability-function-size.NestingThreshold: "", \
-// RUN:         readability-function-size.VariableThreshold: "" \
+// RUN:         readability-function-size.VariableThreshold: "", \
+// RUN:         readability-function-size.IgnoreMacros: "true" \
 // RUN:     }}'
 
 // Bad formatting is intentional, don't run clang-format over the whole file!
@@ -319,3 +320,15 @@ void variables_16() {
 // CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and 
comments (threshold 0)
 // CHECK-MESSAGES: :[[@LINE-6]]:6: note: 4 statements (threshold 0)
 // CHECK-MESSAGES: :[[@LINE-7]]:6: note: 2 variables (threshold 1)
+
+#define CONDITION(value) if (value) { return value; }
+
+int macro_test(int v) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'macro_test' exceeds 
recommended size/complexity thresholds [readability-function-size]
+// CHECK-MESSAGES: :[[@LINE-2]]:5: note: 8 lines including whitespace and 
comments (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-3]]:5: note: 31 statements (threshold 0)
+// CHECK-MESSAGES: :[[@LINE-4]]:5: note: 8 branches (threshold 0)
+
+  
CONDITION(v);CONDITION(v);CONDITION(v);CONDITION(v);CONDITION(v);CONDITION(v);CONDITION(v);
+  if (v) { return v; }
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to