Author: Dmitrii Kuragin Date: 2026-08-29T15:02:20+08:00 New Revision: d34be0ff2eb68d0e486016d8278695fce7d80c3f
URL: https://github.com/llvm/llvm-project/commit/d34be0ff2eb68d0e486016d8278695fce7d80c3f DIFF: https://github.com/llvm/llvm-project/commit/d34be0ff2eb68d0e486016d8278695fce7d80c3f.diff LOG: [Clang-Tidy] Support lambda's init captures in `readability-identifier-naming`. (#214353) Add an ability to declare a custom rules for lambda's init-captures. It recently came up in some of the discussions and people find it useful to to have rules for those types of identifiers. Co-authored-by: Dmitrii Kuragin <[email protected]> Added: clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-lambda-capture.cpp Modified: clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp clang-tools-extra/docs/ReleaseNotes.md clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp index 50644bbf37bce..f4b1fc2a70ee3 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -94,6 +94,7 @@ namespace readability { m(LocalConstantPointer) \ m(LocalPointer) \ m(LocalVariable) \ + m(LambdaCapture) \ m(StaticConstexprVariable) \ m(StaticConstant) \ m(StaticVariable) \ @@ -1521,6 +1522,9 @@ StyleKind IdentifierNamingCheck::findStyleKindForField( StyleKind IdentifierNamingCheck::findStyleKindForVar( const VarDecl *Var, QualType Type, ArrayRef<std::optional<NamingStyle>> NamingStyles) const { + if (Var->isInitCapture() && NamingStyles[SK_LambdaCapture]) + return SK_LambdaCapture; + if (Var->isConstexpr()) { if (Var->isStaticDataMember() && NamingStyles[SK_ClassConstexpr]) return SK_ClassConstexpr; diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md index 420b7ddce20e6..633418a2abb98 100644 --- a/clang-tools-extra/docs/ReleaseNotes.md +++ b/clang-tools-extra/docs/ReleaseNotes.md @@ -206,6 +206,10 @@ infrastructure are described first, followed by tool-specific sections. - Fixed {option}`DefaultHungarianPrefix` being incorrectly diagnosed as an invalid option. + - Added support for naming lambda init-captures (e.g. `[Captured = Var]`) via + the new `LambdaCapture` options. Simple, non-init captures continue to follow + the naming style of the variable they capture. + - Improved {doc}`readability-named-parameter <clang-tidy/checks/readability/named-parameter>` check by ignoring standard tag types (e.g. `std::in_place_t`, `std::allocator_arg_t`, diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst index c8f87dcba8c0a..26d713bbb3d9e 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst @@ -159,6 +159,9 @@ The available options are summarized below: :option:`GlobalVariableHungarianPrefix` - :option:`InlineNamespaceCase`, :option:`InlineNamespacePrefix`, :option:`InlineNamespaceSuffix`, :option:`InlineNamespaceIgnoredRegexp` + - :option:`LambdaCaptureCase`, :option:`LambdaCapturePrefix`, + :option:`LambdaCaptureSuffix`, :option:`LambdaCaptureIgnoredRegexp`, + :option:`LambdaCaptureHungarianPrefix` - :option:`LocalConstexprVariableCase`, :option:`LocalConstexprVariablePrefix`, :option:`LocalConstexprVariableSuffix`, @@ -1491,6 +1494,63 @@ After: } } // namespace FOO_NS +.. option:: LambdaCaptureCase + + When defined, the check will ensure lambda init-capture names (e.g. + ``Captured`` in ``[Captured = Var]``) conform to the selected casing. + A simple, non-init capture (e.g. ``[Var]`` or ``[&Var]``) refers to the + same declaration as ``Var`` itself, so it keeps following whichever + naming style applies to ``Var``'s own declaration instead. + +.. option:: LambdaCapturePrefix + + When defined, the check will ensure lambda init-capture names will add + the prefix with the given value (regardless of casing). + +.. option:: LambdaCaptureIgnoredRegexp + + Identifier naming checks won't be enforced for lambda init-capture names + matching this regular expression. + +.. option:: LambdaCaptureSuffix + + When defined, the check will ensure lambda init-capture names will add + the suffix with the given value (regardless of casing). + +.. option:: LambdaCaptureHungarianPrefix + + When enabled, the check ensures that the declared identifier will + have a Hungarian notation prefix based on the declared type. + +For example using values of: + + - LambdaCaptureCase of ``CamelCase`` + - LambdaCapturePrefix of ``c_`` + +Identifies and/or transforms lambda init-capture names as follows: + +Before: + +.. code-block:: c++ + + void foo() { + int local_variable = 0; + auto lambda = [captured_value = local_variable]() { + return captured_value; + }; + } + +After: + +.. code-block:: c++ + + void foo() { + int local_variable = 0; + auto lambda = [c_CapturedValue = local_variable]() { + return c_CapturedValue; + }; + } + .. option:: LocalConstexprVariableCase When defined, the check will ensure local ``constexpr`` variable names diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-lambda-capture.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-lambda-capture.cpp new file mode 100644 index 0000000000000..a0180b5abe4d9 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-lambda-capture.cpp @@ -0,0 +1,45 @@ +// RUN: %check_clang_tidy -std=c++14-or-later %s readability-identifier-naming %t -- \ +// RUN: -config='{CheckOptions: { \ +// RUN: readability-identifier-naming.LambdaCaptureCase: CamelCase, \ +// RUN: readability-identifier-naming.LambdaCapturePrefix: 'c_', \ +// RUN: readability-identifier-naming.LocalVariableCase: lower_case, \ +// RUN: }}' + +void goodInitCapture() { + int local_variable = 0; + auto lambda = [c_LocalVariable = local_variable]() { + return c_LocalVariable; + }; + (void)lambda(); +} + +void badInitCapture() { + int local_variable = 0; + auto lambda = [captured_value = local_variable]() { + return captured_value; + }; + // CHECK-MESSAGES: :[[@LINE-3]]:18: warning: invalid case style for lambda capture 'captured_value' [readability-identifier-naming] + // CHECK-FIXES: auto lambda = [c_CapturedValue = local_variable]() { + // CHECK-FIXES-NEXT: return c_CapturedValue; + (void)lambda(); +} + +// Simple (non-init) explicit captures reuse the *same* VarDecl as the +// outer declaration, so they must keep following LocalVariable's style, +// not LambdaCapture, and must not gain the 'c_' prefix. +void simpleCapturesUseLocalVariableStyle() { + int local_variable = 0; + auto by_copy = [local_variable]() { return local_variable; }; + auto by_ref = [&local_variable]() { return local_variable; }; + (void)by_copy(); + (void)by_ref(); +} + +void badLocalVariableCapturedSimply() { + int LocalVariable = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for local variable 'LocalVariable' [readability-identifier-naming] + // CHECK-FIXES: int local_variable = 0; + auto lambda = [LocalVariable]() { return LocalVariable; }; + // CHECK-FIXES: auto lambda = [local_variable]() { return local_variable; }; + (void)lambda(); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
