================
@@ -0,0 +1,526 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This checker uses a 9-step algorithm to accomplish scope analysis of a
+// variable and determine if it can be declared in a smaller scope. Note that
+// the clang-tidy framework is aimed mainly at supporting text-manipulation,
+// diagnostics, or common AST patterns. Scope reduction analysis is
+// quite specialized, and there's not much support specifically for
+// those steps. Perhaps someone else knows better and can help simplify
+// this code in a more concrete way other than simply suggesting it can
+// be simpler.
+//
+// The 9-step algorithm used by this checker for scope reduction analysis is:
+// 1) AST Matcher Filtering
+//    - Only match variables within functions (hasAncestor(functionDecl())
+//    - Exclude for-loop declared variables
+//       (unless(hasParent(declStmt(hasParent(forStmt))))))
+//    - Exclude variables with function call initializers
+//       (unless(hasInitializer(...)))
+//    - Exclude parameters from analysis
+//       (unless(parmVarDecl())
+//    - Exclude try-catch variables (unless(hasParent(cxxCatchStmt())))
+// 2) Collect variable uses
+//    - Find all DeclRefExpr nodes that reference the variable
+// 3) Build scope chains
+//    - For each use, find all compound statements that contain it (from
+//      innermost to outermost)
+// 4) Find the innermost compound statement that contains all uses
+//    - This is the smallest scope where the variable could be declared
+// 5) Check for modification detection
+//    - Skip analysis for initialized variables modified with unary operators
+//    - Skip analysis for initialized variables moved into switch bodies
+//    - This prevents moving variables where initialization would be lost or
+//    conditional
+// 6) Check for loop body placement
+//    - Skip analysis if suggested scope would place variable inside loop body
+//    - This prevents suggesting moving variables into loop bodies 
(inefficient)
+// 7) Switch case analysis
+//    - Check if variable uses span multiple case labels in the same switch
+//    - Skip analysis if so, as variables cannot be declared in switch body
+// 8) Verify scope nesting and report
+//    - Find the compound statement containing the variable declaration
+//    - Only report if the usage scope is nested within the declaration scope
+//    - This ensures we only suggest moving variables to smaller scopes
+// 9) Alternative analysis - check for for-loop initialization opportunity
+//    - Only runs if compound statement analysis didn't find a smaller scope
+//    - Only check local variables, not parameters
+//    - Determine if all uses are within the same for-loop and suggest
+//      for-loop initialization, but only if for-loop is in smaller scope
+//
+// The algorithm works by finding the smallest scope that could contain the
+// variable declaration while still encompassing all its uses, but only reports
+// when that scope is smaller than the current declaration scope.
+
+#include "ScopeReductionCheck.h"
+#include "../utils/DeclRefExprUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::misc {
+
+static void
+collectVariableUses(const clang::Stmt *S, const clang::VarDecl *Var,
----------------
zwuis wrote:

Why making a wrapper of `allDeclRefExprs`? Can we just use it?

https://github.com/llvm/llvm-project/pull/175429
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to