[clang-tools-extra] [clang-tidy] identifier-naming: TrimPrefixSuffix option to avoid concatenating multiple pre(suf)fixes (PR #181502)
Brice Decaestecker via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 14 11:26:03 PST 2026
https://github.com/NyuB created https://github.com/llvm/llvm-project/pull/181502
This pull request proposal is intended to smooth a use cases such as: 'prefix all members by `m_`, local variables by `l_` and function parameters by `p_`
We use this check at work in combination with cland to enforce such coding guidelines. When extracting a function from a local block of code or auto-generating a constructor via clangd and applying the check, the naming end up looking like `p_m_foo`, `p_l_foo`, `m_l_foo` ... and we are back at tediously _searchandreplacing_ by ourselves.
This pull request introduces an option and the associated logic to trim all known prefixes and suffixes from a given identifer before applying the correct prefix/suffix, solving the issue.
>From b1669fef265623eb9e1f4a591a3972483b80794c Mon Sep 17 00:00:00 2001
From: Brice Decaestecker <brice.decaestecker at gmx.fr>
Date: Sat, 14 Feb 2026 12:17:30 +0100
Subject: [PATCH] [clang-tidy] Avoid identifier-naming concatenating multiple
(pre/su)ffixes, introducing an option to strip out any other known
(pre/su)ffix before renaming
---
.../readability/IdentifierNamingCheck.cpp | 41 ++++-
.../readability/IdentifierNamingCheck.h | 5 +-
.../checks/readability/identifier-naming.rst | 165 ++++++++++++++++++
3 files changed, 205 insertions(+), 6 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
index 83fc3727cb5c8..8de8d7089288c 100644
--- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
@@ -238,9 +238,11 @@ static StringRef const HungarianNotationUserDefinedTypes[] = {
IdentifierNamingCheck::NamingStyle::NamingStyle(
std::optional<IdentifierNamingCheck::CaseType> Case, StringRef Prefix,
- StringRef Suffix, StringRef IgnoredRegexpStr, HungarianPrefixType HPType)
+ StringRef Suffix, StringRef IgnoredRegexpStr, HungarianPrefixType HPType,
+ bool TrimPrefixSuffix)
: Case(Case), Prefix(Prefix), Suffix(Suffix),
- IgnoredRegexpStr(IgnoredRegexpStr), HPType(HPType) {
+ IgnoredRegexpStr(IgnoredRegexpStr), HPType(HPType),
+ TrimPrefixSuffix(TrimPrefixSuffix) {
if (!IgnoredRegexpStr.empty()) {
IgnoredRegexp =
llvm::Regex(llvm::SmallString<128>({"^", IgnoredRegexpStr, "$"}));
@@ -269,9 +271,13 @@ IdentifierNamingCheck::FileStyle IdentifierNamingCheck::getFileStyleFromOptions(
if (HPTOpt && !HungarianNotation.checkOptionValid(I))
configurationDiag("invalid identifier naming option '%0'") << StyleString;
+ memcpy(&StyleString[StyleSize], "TrimPrefixSuffix", 16);
+ StyleString.truncate(StyleSize + 16);
+ const std::optional<bool> TrimPrefixSuffix =
+ Options.get<bool>(StyleString);
memcpy(&StyleString[StyleSize], "IgnoredRegexp", 13);
StyleString.truncate(StyleSize + 13);
- const std::optional<StringRef> IgnoredRegexpStr = Options.get(StyleString);
+ std::optional<StringRef> IgnoredRegexpStr = Options.get(StyleString);
memcpy(&StyleString[StyleSize], "Prefix", 6);
StyleString.truncate(StyleSize + 6);
const std::optional<StringRef> Prefix(Options.get(StyleString));
@@ -286,7 +292,8 @@ IdentifierNamingCheck::FileStyle IdentifierNamingCheck::getFileStyleFromOptions(
if (CaseOptional || Prefix || Postfix || IgnoredRegexpStr || HPTOpt)
Styles[I].emplace(std::move(CaseOptional), Prefix.value_or(""),
Postfix.value_or(""), IgnoredRegexpStr.value_or(""),
- HPTOpt.value_or(IdentifierNamingCheck::HPT_Off));
+ HPTOpt.value_or(IdentifierNamingCheck::HPT_Off),
+ TrimPrefixSuffix.value_or(false));
}
const bool IgnoreMainLike = Options.get("IgnoreMainLikeFunctions", false);
const bool CheckAnonFieldInParent =
@@ -1084,9 +1091,30 @@ bool IdentifierNamingCheck::isParamInMainLikeFunction(
return Matcher.match(FDecl->getName());
}
+static void trimPrefixesAndSuffixes(
+ StringRef &Mid,
+ ArrayRef<std::optional<IdentifierNamingCheck::NamingStyle>> NamingStyles) {
+ bool LoopWhileToRemove = true;
+ while (LoopWhileToRemove) {
+ LoopWhileToRemove = false;
+ for (unsigned I = 0; I < SK_Count; ++I) {
+ if (const std::optional<IdentifierNamingCheck::NamingStyle> &OtherStyle =
+ NamingStyles[I]) {
+ while (!OtherStyle->Prefix.empty() &&
+ Mid.consume_front(OtherStyle->Prefix))
+ LoopWhileToRemove = true;
+
+ while (!OtherStyle->Suffix.empty() && Mid.consume_back(OtherStyle->Suffix))
+ LoopWhileToRemove = true;
+ }
+ }
+ }
+}
+
std::string IdentifierNamingCheck::fixupWithStyle(
StringRef Type, StringRef Name,
const IdentifierNamingCheck::NamingStyle &Style,
+ ArrayRef<std::optional<IdentifierNamingCheck::NamingStyle>> NamingStyles,
const IdentifierNamingCheck::HungarianNotationOption &HNOption,
const Decl *D) const {
Name.consume_front(Style.Prefix);
@@ -1108,6 +1136,8 @@ std::string IdentifierNamingCheck::fixupWithStyle(
}
}
StringRef Mid = StringRef(Fixed).trim("_");
+ if (Style.TrimPrefixSuffix)
+ trimPrefixesAndSuffixes(Mid, NamingStyles);
if (Mid.empty())
Mid = "_";
@@ -1359,7 +1389,8 @@ IdentifierNamingCheck::getFailureInfo(
IdentifierNamingCheck::CT_LowerCase);
llvm::replace(KindName, '_', ' ');
- std::string Fixup = fixupWithStyle(Type, Name, Style, HNOption, ND);
+ std::string Fixup =
+ fixupWithStyle(Type, Name, Style, NamingStyles, HNOption, ND);
if (StringRef(Fixup) == Name) {
if (!IgnoreFailedSplit) {
LLVM_DEBUG(Location.print(llvm::dbgs(), SM);
diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
index b016556cc2ab8..bdac7f5b1e8b9 100644
--- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
@@ -72,7 +72,7 @@ class IdentifierNamingCheck final : public RenamerClangTidyCheck {
NamingStyle(std::optional<CaseType> Case, StringRef Prefix,
StringRef Suffix, StringRef IgnoredRegexpStr,
- HungarianPrefixType HPType);
+ HungarianPrefixType HPType, bool TrimPrefixSuffix);
NamingStyle(const NamingStyle &O) = delete;
NamingStyle &operator=(NamingStyle &&O) = default;
NamingStyle(NamingStyle &&O) = default;
@@ -86,6 +86,8 @@ class IdentifierNamingCheck final : public RenamerClangTidyCheck {
std::string IgnoredRegexpStr;
HungarianPrefixType HPType;
+
+ bool TrimPrefixSuffix;
};
struct HungarianNotation {
@@ -176,6 +178,7 @@ class IdentifierNamingCheck final : public RenamerClangTidyCheck {
std::string
fixupWithStyle(StringRef Type, StringRef Name,
const IdentifierNamingCheck::NamingStyle &Style,
+ ArrayRef<std::optional<IdentifierNamingCheck::NamingStyle>> NamingStyles,
const IdentifierNamingCheck::HungarianNotationOption &HNOption,
const Decl *D) const;
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..34d440f45dae2 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
@@ -276,6 +276,11 @@ A detailed description of each option is presented below:
When defined, the check will ensure all names by default will add the
suffix with the given value (regardless of casing).
+.. option:: DefaultTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: DefaultHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -301,6 +306,11 @@ A detailed description of each option is presented below:
When defined, the check will ensure abstract class names will add the
suffix with the given value (regardless of casing).
+.. option:: AbstractClassTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: AbstractClassHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -438,6 +448,11 @@ and thus no warnings will be emitted.
When defined, the check will ensure class names will add the
suffix with the given value (regardless of casing).
+.. option:: ClassTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: ClassHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -492,6 +507,11 @@ After:
When defined, the check will ensure class ``constexpr`` names will add the
suffix with the given value (regardless of casing).
+.. option:: ClassConstexprTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: ClassConstexprHungarianPrefix
When enabled, the check ensures that the declared identifier will have a
@@ -544,6 +564,11 @@ After:
When defined, the check will ensure class constant names will add the
suffix with the given value (regardless of casing).
+.. option:: ClassConstantTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: ClassConstantHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -596,6 +621,11 @@ After:
When defined, the check will ensure class member names will add the
suffix with the given value (regardless of casing).
+.. option:: ClassMemberTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: ClassMemberHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -734,6 +764,11 @@ After:
When defined, the check will ensure constant names will add the
suffix with the given value (regardless of casing).
+.. option:: ConstantTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: ConstantHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -780,6 +815,11 @@ After:
When defined, the check will ensure constant member names will add the
suffix with the given value (regardless of casing).
+.. option:: ConstantMemberTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: ConstantMemberHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -830,6 +870,11 @@ After:
When defined, the check will ensure constant parameter names will add the
suffix with the given value (regardless of casing).
+.. option:: ConstantParameterTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: ConstantParameterHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -876,6 +921,11 @@ After:
When defined, the check will ensure constant pointer parameter names will add the
suffix with the given value (regardless of casing).
+.. option:: ConstantPointerParameterTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: ConstantPointerParameterHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -1008,6 +1058,11 @@ After:
When defined, the check will ensure constexpr variable names will add the
suffix with the given value (regardless of casing).
+.. option:: ConstexprVariableTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: ConstexprVariableHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -1094,6 +1149,11 @@ After:
When defined, the check will ensure enumeration constant names will add the
suffix with the given value (regardless of casing).
+.. option:: EnumConstantTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: EnumConstantHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -1187,6 +1247,11 @@ After:
When defined, the check will ensure global ``constexpr`` variable names
will add the suffix with the given value (regardless of casing).
+.. option:: GlobalConstexprVariableTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: GlobalConstexprVariableHungarianPrefix
When enabled, the check ensures that the declared identifier will have a
@@ -1233,6 +1298,11 @@ After:
When defined, the check will ensure global constant names will add the
suffix with the given value (regardless of casing).
+.. option:: GlobalConstantTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: GlobalConstantHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -1279,6 +1349,11 @@ After:
When defined, the check will ensure global constant pointer names will add the
suffix with the given value (regardless of casing).
+.. option:: GlobalConstantPointerTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: GlobalConstantPointerHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -1365,6 +1440,11 @@ After:
When defined, the check will ensure global pointer names will add the
suffix with the given value (regardless of casing).
+.. option:: GlobalPointerTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: GlobalPointerHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -1411,6 +1491,11 @@ After:
When defined, the check will ensure global variable names will add the
suffix with the given value (regardless of casing).
+.. option:: GlobalVariableTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: GlobalVariableHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -1511,6 +1596,11 @@ After:
When defined, the check will ensure local ``constexpr`` variable names will
add the suffix with the given value (regardless of casing).
+.. option:: LocalConstexprVariableTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: LocalConstexprVariableHungarianPrefix
When enabled, the check ensures that the declared identifier will have a
@@ -1557,6 +1647,11 @@ After:
When defined, the check will ensure local constant names will add the
suffix with the given value (regardless of casing).
+.. option:: LocalConstantTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: LocalConstantHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -1603,6 +1698,11 @@ After:
When defined, the check will ensure local constant pointer names will add the
suffix with the given value (regardless of casing).
+.. option:: LocalConstantPointerTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: LocalConstantPointerHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -1649,6 +1749,11 @@ After:
When defined, the check will ensure local pointer names will add the
suffix with the given value (regardless of casing).
+.. option:: LocalPointerTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: LocalPointerHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -1703,6 +1808,11 @@ camel case check applied to other variables.
When defined, the check will ensure local variable names will add the
suffix with the given value (regardless of casing).
+.. option:: LocalVariableTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: LocalVariableHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -1792,6 +1902,11 @@ command line using the ``-D`` flag.
When defined, the check will ensure member names will add the
suffix with the given value (regardless of casing).
+.. option:: MemberTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: MemberHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -1930,6 +2045,11 @@ After:
When defined, the check will ensure parameter names will add the
suffix with the given value (regardless of casing).
+.. option:: ParameterTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: ParameterHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -2020,6 +2140,11 @@ After:
When defined, the check will ensure pointer parameter names will add the
suffix with the given value (regardless of casing).
+.. option:: PointerParameterTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: PointerParameterHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -2066,6 +2191,11 @@ After:
When defined, the check will ensure private member names will add the
suffix with the given value (regardless of casing).
+.. option:: PrivateMemberTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: PrivateMemberHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -2164,6 +2294,11 @@ After:
When defined, the check will ensure protected member names will add the
suffix with the given value (regardless of casing).
+.. option:: ProtectedMemberTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: ProtectedMemberHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -2262,6 +2397,11 @@ After:
When defined, the check will ensure public member names will add the
suffix with the given value (regardless of casing).
+.. option:: PublicMemberTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: PublicMemberHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -2360,6 +2500,11 @@ After:
When defined, the check will ensure scoped enum constant names will add the
suffix with the given value (regardless of casing).
+.. option:: ScopedEnumConstantTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: ScopedEnumConstantHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -2406,6 +2551,11 @@ After:
When defined, the check will ensure static ``constexpr`` variable names
will add the suffix with the given value (regardless of casing).
+.. option:: StaticConstexprVariableTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: StaticConstexprVariableHungarianPrefix
When enabled, the check ensures that the declared identifier will have a
@@ -2452,6 +2602,11 @@ After:
When defined, the check will ensure static constant names will add the
suffix with the given value (regardless of casing).
+.. option:: StaticConstantTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: StaticConstantHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -2498,6 +2653,11 @@ After:
When defined, the check will ensure static variable names will add the
suffix with the given value (regardless of casing).
+.. option:: StaticVariableTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: StaticVariableHungarianPrefix
When enabled, the check ensures that the declared identifier will
@@ -2882,6 +3042,11 @@ After:
When defined, the check will ensure variable names will add the
suffix with the given value (regardless of casing).
+.. option:: VariableTrimPrefixSuffix
+
+ When enabled, the check ensures that the declared identifier does not
+ start or end with any other prefix or suffix defined for this check
+
.. option:: VariableHungarianPrefix
When enabled, the check ensures that the declared identifier will
More information about the cfe-commits
mailing list