https://github.com/localspook updated 
https://github.com/llvm/llvm-project/pull/173506

>From f3dcfaf13f73e38eb2c8c464a0f92855c3d3eb6f Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <[email protected]>
Date: Wed, 24 Dec 2025 12:12:12 -0700
Subject: [PATCH 1/3] [clang-tidy][NFC] Replace stateless struct with namespace
 in `readability-identifier-naming`

---
 .../readability/IdentifierNamingCheck.cpp     | 70 +++++++++----------
 .../readability/IdentifierNamingCheck.h       | 37 ----------
 2 files changed, 35 insertions(+), 72 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
index 9cee6ddb93d4d..827bdb8374463 100644
--- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
@@ -254,8 +254,8 @@ IdentifierNamingCheck::FileStyle 
IdentifierNamingCheck::getFileStyleFromOptions(
     const ClangTidyCheck::OptionsView &Options) const {
   IdentifierNamingCheck::HungarianNotationOption HNOption;
 
-  HungarianNotation.loadDefaultConfig(HNOption);
-  HungarianNotation.loadFileConfig(Options, HNOption);
+  HungarianNotation::loadDefaultConfig(HNOption);
+  HungarianNotation::loadFileConfig(Options, HNOption);
 
   SmallVector<std::optional<IdentifierNamingCheck::NamingStyle>, 0> Styles;
   Styles.resize(SK_Count);
@@ -266,7 +266,7 @@ IdentifierNamingCheck::FileStyle 
IdentifierNamingCheck::getFileStyleFromOptions(
 
     auto HPTOpt =
         Options.get<IdentifierNamingCheck::HungarianPrefixType>(StyleString);
-    if (HPTOpt && !HungarianNotation.checkOptionValid(I))
+    if (HPTOpt && !HungarianNotation::checkOptionValid(I))
       configurationDiag("invalid identifier naming option '%0'") << 
StyleString;
 
     memcpy(&StyleString[StyleSize], "IgnoredRegexp", 13);
@@ -295,8 +295,7 @@ IdentifierNamingCheck::FileStyle 
IdentifierNamingCheck::getFileStyleFromOptions(
           CheckAnonFieldInParent};
 }
 
-std::string IdentifierNamingCheck::HungarianNotation::getDeclTypeName(
-    const NamedDecl *ND) const {
+static std::string getDeclTypeName(const NamedDecl *ND) {
   const auto *VD = dyn_cast<ValueDecl>(ND);
   if (!VD)
     return {};
@@ -415,8 +414,9 @@ IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name,
 
 IdentifierNamingCheck::~IdentifierNamingCheck() = default;
 
-bool IdentifierNamingCheck::HungarianNotation::checkOptionValid(
-    int StyleKindIndex) const {
+namespace HungarianNotation {
+
+static bool checkOptionValid(int StyleKindIndex) {
   if ((StyleKindIndex >= SK_EnumConstant) &&
       (StyleKindIndex <= SK_ConstantParameter))
     return true;
@@ -427,8 +427,8 @@ bool 
IdentifierNamingCheck::HungarianNotation::checkOptionValid(
   return false;
 }
 
-bool IdentifierNamingCheck::HungarianNotation::isOptionEnabled(
-    StringRef OptionKey, const llvm::StringMap<std::string> &StrMap) const {
+static bool isOptionEnabled(StringRef OptionKey,
+                            const llvm::StringMap<std::string> &StrMap) {
   if (OptionKey.empty())
     return false;
 
@@ -439,14 +439,14 @@ bool 
IdentifierNamingCheck::HungarianNotation::isOptionEnabled(
   return *llvm::yaml::parseBool(Iter->getValue());
 }
 
-void IdentifierNamingCheck::HungarianNotation::loadFileConfig(
-    const ClangTidyCheck::OptionsView &Options,
-    IdentifierNamingCheck::HungarianNotationOption &HNOption) const {
+static void
+loadFileConfig(const ClangTidyCheck::OptionsView &Options,
+               IdentifierNamingCheck::HungarianNotationOption &HNOption) {
   static constexpr StringRef HNOpts[] = {"TreatStructAsClass"};
   static constexpr StringRef HNDerivedTypes[] = {"Array", "Pointer",
                                                  "FunctionPointer"};
 
-  const StringRef Section = "HungarianNotation.";
+  const StringRef Section = "HungarianNotation::";
 
   SmallString<128> Buffer = {Section, "General."};
   size_t DefSize = Buffer.size();
@@ -508,9 +508,9 @@ void 
IdentifierNamingCheck::HungarianNotation::loadFileConfig(
   }
 }
 
-std::string IdentifierNamingCheck::HungarianNotation::getPrefix(
-    const Decl *D,
-    const IdentifierNamingCheck::HungarianNotationOption &HNOption) const {
+static std::string
+getPrefix(const Decl *D,
+          const IdentifierNamingCheck::HungarianNotationOption &HNOption) {
   if (!D)
     return {};
   const auto *ND = dyn_cast<NamedDecl>(D);
@@ -531,9 +531,9 @@ std::string 
IdentifierNamingCheck::HungarianNotation::getPrefix(
   return Prefix;
 }
 
-bool IdentifierNamingCheck::HungarianNotation::removeDuplicatedPrefix(
+static bool removeDuplicatedPrefix(
     SmallVector<StringRef, 8> &Words,
-    const IdentifierNamingCheck::HungarianNotationOption &HNOption) const {
+    const IdentifierNamingCheck::HungarianNotationOption &HNOption) {
   if (Words.size() <= 1)
     return true;
 
@@ -554,9 +554,9 @@ bool 
IdentifierNamingCheck::HungarianNotation::removeDuplicatedPrefix(
   return false;
 }
 
-std::string IdentifierNamingCheck::HungarianNotation::getDataTypePrefix(
+static std::string getDataTypePrefix(
     StringRef TypeName, const NamedDecl *ND,
-    const IdentifierNamingCheck::HungarianNotationOption &HNOption) const {
+    const IdentifierNamingCheck::HungarianNotationOption &HNOption) {
   if (!ND || TypeName.empty())
     return TypeName.str();
 
@@ -634,9 +634,9 @@ std::string 
IdentifierNamingCheck::HungarianNotation::getDataTypePrefix(
   return PrefixStr;
 }
 
-std::string IdentifierNamingCheck::HungarianNotation::getClassPrefix(
-    const CXXRecordDecl *CRD,
-    const IdentifierNamingCheck::HungarianNotationOption &HNOption) const {
+static std::string
+getClassPrefix(const CXXRecordDecl *CRD,
+               const IdentifierNamingCheck::HungarianNotationOption &HNOption) 
{
   if (CRD->isUnion())
     return {};
 
@@ -647,8 +647,7 @@ std::string 
IdentifierNamingCheck::HungarianNotation::getClassPrefix(
   return CRD->isAbstract() ? "I" : "C";
 }
 
-std::string IdentifierNamingCheck::HungarianNotation::getEnumPrefix(
-    const EnumConstantDecl *ECD) const {
+static std::string getEnumPrefix(const EnumConstantDecl *ECD) {
   const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
 
   std::string Name = ED->getName().str();
@@ -692,8 +691,7 @@ std::string 
IdentifierNamingCheck::HungarianNotation::getEnumPrefix(
   return Initial;
 }
 
-size_t IdentifierNamingCheck::HungarianNotation::getAsteriskCount(
-    const std::string &TypeName) const {
+static size_t getAsteriskCount(const std::string &TypeName) {
   size_t Pos = TypeName.find('*');
   size_t Count = 0;
   for (; Pos < TypeName.length(); Pos++, Count++)
@@ -702,8 +700,8 @@ size_t 
IdentifierNamingCheck::HungarianNotation::getAsteriskCount(
   return Count;
 }
 
-size_t IdentifierNamingCheck::HungarianNotation::getAsteriskCount(
-    const std::string &TypeName, const NamedDecl *ND) const {
+static size_t getAsteriskCount(const std::string &TypeName,
+                               const NamedDecl *ND) {
   size_t PtrCount = 0;
   if (const auto *TD = dyn_cast<ValueDecl>(ND)) {
     const QualType QT = TD->getType();
@@ -713,8 +711,8 @@ size_t 
IdentifierNamingCheck::HungarianNotation::getAsteriskCount(
   return PtrCount;
 }
 
-void IdentifierNamingCheck::HungarianNotation::loadDefaultConfig(
-    IdentifierNamingCheck::HungarianNotationOption &HNOption) const {
+static void
+loadDefaultConfig(IdentifierNamingCheck::HungarianNotationOption &HNOption) {
   // Options
   static constexpr std::pair<StringRef, StringRef> General[] = {
       {"TreatStructAsClass", "false"}};
@@ -823,6 +821,8 @@ void 
IdentifierNamingCheck::HungarianNotation::loadDefaultConfig(
     HNOption.UserDefinedType.try_emplace(UDT.first, UDT.second);
 }
 
+} // namespace HungarianNotation
+
 void IdentifierNamingCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   RenamerClangTidyCheck::storeOptions(Opts);
   SmallString<64> StyleString;
@@ -880,7 +880,7 @@ bool IdentifierNamingCheck::matchesStyle(
   if (!Name.consume_back(Style.Suffix))
     return false;
   if (IdentifierNamingCheck::HungarianPrefixType::HPT_Off != Style.HPType) {
-    const std::string HNPrefix = HungarianNotation.getPrefix(Decl, HNOption);
+    const std::string HNPrefix = HungarianNotation::getPrefix(Decl, HNOption);
     if (!HNPrefix.empty()) {
       if (!Name.consume_front(HNPrefix))
         return false;
@@ -938,7 +938,7 @@ std::string IdentifierNamingCheck::fixupWithCase(
     return Name.str();
 
   if (IdentifierNamingCheck::HungarianPrefixType::HPT_Off != Style.HPType)
-    HungarianNotation.removeDuplicatedPrefix(Words, HNOption);
+    HungarianNotation::removeDuplicatedPrefix(Words, HNOption);
 
   SmallString<128> Fixup;
   switch (Case) {
@@ -1096,7 +1096,7 @@ std::string IdentifierNamingCheck::fixupWithStyle(
   std::string HungarianPrefix;
   using HungarianPrefixType = IdentifierNamingCheck::HungarianPrefixType;
   if (HungarianPrefixType::HPT_Off != Style.HPType) {
-    HungarianPrefix = HungarianNotation.getPrefix(D, HNOption);
+    HungarianPrefix = HungarianNotation::getPrefix(D, HNOption);
     if (!HungarianPrefix.empty()) {
       if (Style.HPType == HungarianPrefixType::HPT_LowerCase)
         HungarianPrefix += "_";
@@ -1379,7 +1379,7 @@ IdentifierNamingCheck::getDeclFailureInfo(const NamedDecl 
*Decl,
     return std::nullopt;
 
   return getFailureInfo(
-      HungarianNotation.getDeclTypeName(Decl), Decl->getName(), Decl, Loc,
+      HungarianNotation::getDeclTypeName(Decl), Decl->getName(), Decl, Loc,
       FileStyle.getStyles(), FileStyle.getHNOption(),
       findStyleKind(Decl, FileStyle.getStyles(),
                     FileStyle.isIgnoringMainLikeFunction(),
diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h 
b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
index 87735808dff39..ab945e7477f51 100644
--- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
@@ -88,42 +88,6 @@ class IdentifierNamingCheck final : public 
RenamerClangTidyCheck {
     HungarianPrefixType HPType;
   };
 
-  struct HungarianNotation {
-  public:
-    bool checkOptionValid(int StyleKindIndex) const;
-    bool isOptionEnabled(StringRef OptionKey,
-                         const llvm::StringMap<std::string> &StrMap) const;
-
-    size_t getAsteriskCount(const std::string &TypeName) const;
-    size_t getAsteriskCount(const std::string &TypeName,
-                            const NamedDecl *ND) const;
-
-    void loadDefaultConfig(
-        IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
-    void loadFileConfig(
-        const ClangTidyCheck::OptionsView &Options,
-        IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
-
-    bool removeDuplicatedPrefix(
-        SmallVector<StringRef, 8> &Words,
-        const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
-
-    std::string getPrefix(
-        const Decl *D,
-        const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
-
-    std::string getDataTypePrefix(
-        StringRef TypeName, const NamedDecl *ND,
-        const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
-
-    std::string getClassPrefix(
-        const CXXRecordDecl *CRD,
-        const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
-
-    std::string getEnumPrefix(const EnumConstantDecl *ECD) const;
-    std::string getDeclTypeName(const NamedDecl *ND) const;
-  };
-
   struct FileStyle {
     FileStyle() : IsActive(false), IgnoreMainLikeFunctions(false) {}
     FileStyle(SmallVectorImpl<std::optional<NamingStyle>> &&Styles,
@@ -231,7 +195,6 @@ class IdentifierNamingCheck final : public 
RenamerClangTidyCheck {
   ClangTidyContext *Context;
   const bool GetConfigPerFile;
   const bool IgnoreFailedSplit;
-  HungarianNotation HungarianNotation;
 };
 
 } // namespace readability

>From f859100ab1cc69996fca20aaa8f62750b8ae42da Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <[email protected]>
Date: Wed, 24 Dec 2025 12:14:03 -0700
Subject: [PATCH 2/3] Move functions up in .cpp file

---
 .../readability/IdentifierNamingCheck.cpp     | 356 +++++++++---------
 1 file changed, 178 insertions(+), 178 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
index 827bdb8374463..d155cab5330a7 100644
--- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
@@ -236,184 +236,6 @@ static StringRef const 
HungarianNotationUserDefinedTypes[] = {
 #undef NAMING_KEYS
 // clang-format on
 
-IdentifierNamingCheck::NamingStyle::NamingStyle(
-    std::optional<IdentifierNamingCheck::CaseType> Case, StringRef Prefix,
-    StringRef Suffix, StringRef IgnoredRegexpStr, HungarianPrefixType HPType)
-    : Case(Case), Prefix(Prefix), Suffix(Suffix),
-      IgnoredRegexpStr(IgnoredRegexpStr), HPType(HPType) {
-  if (!IgnoredRegexpStr.empty()) {
-    IgnoredRegexp =
-        llvm::Regex(llvm::SmallString<128>({"^", IgnoredRegexpStr, "$"}));
-    if (!IgnoredRegexp.isValid())
-      llvm::errs() << "Invalid IgnoredRegexp regular expression: "
-                   << IgnoredRegexpStr;
-  }
-}
-
-IdentifierNamingCheck::FileStyle 
IdentifierNamingCheck::getFileStyleFromOptions(
-    const ClangTidyCheck::OptionsView &Options) const {
-  IdentifierNamingCheck::HungarianNotationOption HNOption;
-
-  HungarianNotation::loadDefaultConfig(HNOption);
-  HungarianNotation::loadFileConfig(Options, HNOption);
-
-  SmallVector<std::optional<IdentifierNamingCheck::NamingStyle>, 0> Styles;
-  Styles.resize(SK_Count);
-  SmallString<64> StyleString;
-  for (unsigned I = 0; I < SK_Count; ++I) {
-    const size_t StyleSize = StyleNames[I].size();
-    StyleString.assign({StyleNames[I], "HungarianPrefix"});
-
-    auto HPTOpt =
-        Options.get<IdentifierNamingCheck::HungarianPrefixType>(StyleString);
-    if (HPTOpt && !HungarianNotation::checkOptionValid(I))
-      configurationDiag("invalid identifier naming option '%0'") << 
StyleString;
-
-    memcpy(&StyleString[StyleSize], "IgnoredRegexp", 13);
-    StyleString.truncate(StyleSize + 13);
-    const std::optional<StringRef> IgnoredRegexpStr = Options.get(StyleString);
-    memcpy(&StyleString[StyleSize], "Prefix", 6);
-    StyleString.truncate(StyleSize + 6);
-    const std::optional<StringRef> Prefix(Options.get(StyleString));
-    // Fast replacement of [Pre]fix -> [Suf]fix.
-    memcpy(&StyleString[StyleSize], "Suf", 3);
-    const std::optional<StringRef> Postfix(Options.get(StyleString));
-    memcpy(&StyleString[StyleSize], "Case", 4);
-    StyleString.pop_back_n(2);
-    std::optional<CaseType> CaseOptional =
-        Options.get<IdentifierNamingCheck::CaseType>(StyleString);
-
-    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));
-  }
-  const bool IgnoreMainLike = Options.get("IgnoreMainLikeFunctions", false);
-  const bool CheckAnonFieldInParent =
-      Options.get("CheckAnonFieldInParent", false);
-  return {std::move(Styles), std::move(HNOption), IgnoreMainLike,
-          CheckAnonFieldInParent};
-}
-
-static std::string getDeclTypeName(const NamedDecl *ND) {
-  const auto *VD = dyn_cast<ValueDecl>(ND);
-  if (!VD)
-    return {};
-
-  if (isa<FunctionDecl, EnumConstantDecl>(ND))
-    return {};
-
-  // Get type text of variable declarations.
-  auto &SM = VD->getASTContext().getSourceManager();
-  const char *Begin = SM.getCharacterData(VD->getBeginLoc());
-  const char *End = SM.getCharacterData(VD->getEndLoc());
-  intptr_t StrLen = End - Begin;
-
-  // FIXME: Sometimes the value that returns from ValDecl->getEndLoc()
-  // is wrong(out of location of Decl). This causes `StrLen` will be assigned
-  // an unexpected large value. Current workaround to find the terminated
-  // character instead of the `getEndLoc()` function.
-  const char *EOL = strchr(Begin, '\n');
-  if (!EOL)
-    EOL = Begin + strlen(Begin);
-
-  const char *const PosList[] = {strchr(Begin, '='), strchr(Begin, ';'),
-                                 strchr(Begin, ','), strchr(Begin, ')'), EOL};
-  for (const auto &Pos : PosList)
-    if (Pos > Begin)
-      EOL = std::min(EOL, Pos);
-
-  StrLen = EOL - Begin;
-  std::string TypeName;
-  if (StrLen > 0) {
-    std::string Type(Begin, StrLen);
-
-    static constexpr StringRef Keywords[] = {
-        // Constexpr specifiers
-        "constexpr", "constinit", "consteval",
-        // Qualifier
-        "const", "volatile", "restrict", "mutable",
-        // Storage class specifiers
-        "register", "static", "extern", "thread_local",
-        // Other keywords
-        "virtual"};
-
-    // Remove keywords
-    for (const StringRef Kw : Keywords)
-      for (size_t Pos = 0; (Pos = Type.find(Kw, Pos)) != std::string::npos;)
-        Type.replace(Pos, Kw.size(), "");
-    TypeName = Type.erase(0, Type.find_first_not_of(' '));
-
-    // Remove template parameters
-    const size_t Pos = Type.find('<');
-    if (Pos != std::string::npos)
-      TypeName = Type.erase(Pos, Type.size() - Pos);
-
-    // Replace spaces with single space.
-    for (size_t Pos = 0; (Pos = Type.find("  ", Pos)) != std::string::npos;
-         Pos += strlen(" ")) {
-      Type.replace(Pos, strlen("  "), " ");
-    }
-
-    // Replace " &" with "&".
-    for (size_t Pos = 0; (Pos = Type.find(" &", Pos)) != std::string::npos;
-         Pos += strlen("&")) {
-      Type.replace(Pos, strlen(" &"), "&");
-    }
-
-    // Replace " *" with "* ".
-    for (size_t Pos = 0; (Pos = Type.find(" *", Pos)) != std::string::npos;
-         Pos += strlen("*")) {
-      Type.replace(Pos, strlen(" *"), "* ");
-    }
-
-    // Remove redundant tailing.
-    static constexpr StringRef TailsOfMultiWordType[] = {
-        " int", " char", " double", " long", " short"};
-    bool RedundantRemoved = false;
-    for (auto Kw : TailsOfMultiWordType) {
-      const size_t Pos = Type.rfind(Kw);
-      if (Pos != std::string::npos) {
-        const size_t PtrCount = getAsteriskCount(Type, ND);
-        Type = Type.substr(0, Pos + Kw.size() + PtrCount);
-        RedundantRemoved = true;
-        break;
-      }
-    }
-
-    TypeName = Type.erase(0, Type.find_first_not_of(' '));
-    if (!RedundantRemoved) {
-      const std::size_t FoundSpace = Type.find(' ');
-      if (FoundSpace != std::string::npos)
-        Type = Type.substr(0, FoundSpace);
-    }
-
-    TypeName = Type.erase(0, Type.find_first_not_of(' '));
-
-    const QualType QT = VD->getType();
-    if (!QT.isNull() && QT->isArrayType())
-      TypeName.append("[]");
-  }
-
-  return TypeName;
-}
-
-IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name,
-                                             ClangTidyContext *Context)
-    : RenamerClangTidyCheck(Name, Context), Context(Context),
-      GetConfigPerFile(Options.get("GetConfigPerFile", true)),
-      IgnoreFailedSplit(Options.get("IgnoreFailedSplit", false)) {
-  auto IterAndInserted = NamingStylesCache.try_emplace(
-      llvm::sys::path::parent_path(Context->getCurrentFile()),
-      getFileStyleFromOptions(Options));
-  assert(IterAndInserted.second && "Couldn't insert Style");
-  // Holding a reference to the data in the vector is safe as it should never
-  // move.
-  MainFileStyle = &IterAndInserted.first->getValue();
-}
-
-IdentifierNamingCheck::~IdentifierNamingCheck() = default;
-
 namespace HungarianNotation {
 
 static bool checkOptionValid(int StyleKindIndex) {
@@ -823,6 +645,184 @@ 
loadDefaultConfig(IdentifierNamingCheck::HungarianNotationOption &HNOption) {
 
 } // namespace HungarianNotation
 
+IdentifierNamingCheck::NamingStyle::NamingStyle(
+    std::optional<IdentifierNamingCheck::CaseType> Case, StringRef Prefix,
+    StringRef Suffix, StringRef IgnoredRegexpStr, HungarianPrefixType HPType)
+    : Case(Case), Prefix(Prefix), Suffix(Suffix),
+      IgnoredRegexpStr(IgnoredRegexpStr), HPType(HPType) {
+  if (!IgnoredRegexpStr.empty()) {
+    IgnoredRegexp =
+        llvm::Regex(llvm::SmallString<128>({"^", IgnoredRegexpStr, "$"}));
+    if (!IgnoredRegexp.isValid())
+      llvm::errs() << "Invalid IgnoredRegexp regular expression: "
+                   << IgnoredRegexpStr;
+  }
+}
+
+IdentifierNamingCheck::FileStyle 
IdentifierNamingCheck::getFileStyleFromOptions(
+    const ClangTidyCheck::OptionsView &Options) const {
+  IdentifierNamingCheck::HungarianNotationOption HNOption;
+
+  HungarianNotation::loadDefaultConfig(HNOption);
+  HungarianNotation::loadFileConfig(Options, HNOption);
+
+  SmallVector<std::optional<IdentifierNamingCheck::NamingStyle>, 0> Styles;
+  Styles.resize(SK_Count);
+  SmallString<64> StyleString;
+  for (unsigned I = 0; I < SK_Count; ++I) {
+    const size_t StyleSize = StyleNames[I].size();
+    StyleString.assign({StyleNames[I], "HungarianPrefix"});
+
+    auto HPTOpt =
+        Options.get<IdentifierNamingCheck::HungarianPrefixType>(StyleString);
+    if (HPTOpt && !HungarianNotation::checkOptionValid(I))
+      configurationDiag("invalid identifier naming option '%0'") << 
StyleString;
+
+    memcpy(&StyleString[StyleSize], "IgnoredRegexp", 13);
+    StyleString.truncate(StyleSize + 13);
+    const std::optional<StringRef> IgnoredRegexpStr = Options.get(StyleString);
+    memcpy(&StyleString[StyleSize], "Prefix", 6);
+    StyleString.truncate(StyleSize + 6);
+    const std::optional<StringRef> Prefix(Options.get(StyleString));
+    // Fast replacement of [Pre]fix -> [Suf]fix.
+    memcpy(&StyleString[StyleSize], "Suf", 3);
+    const std::optional<StringRef> Postfix(Options.get(StyleString));
+    memcpy(&StyleString[StyleSize], "Case", 4);
+    StyleString.pop_back_n(2);
+    std::optional<CaseType> CaseOptional =
+        Options.get<IdentifierNamingCheck::CaseType>(StyleString);
+
+    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));
+  }
+  const bool IgnoreMainLike = Options.get("IgnoreMainLikeFunctions", false);
+  const bool CheckAnonFieldInParent =
+      Options.get("CheckAnonFieldInParent", false);
+  return {std::move(Styles), std::move(HNOption), IgnoreMainLike,
+          CheckAnonFieldInParent};
+}
+
+static std::string getDeclTypeName(const NamedDecl *ND) {
+  const auto *VD = dyn_cast<ValueDecl>(ND);
+  if (!VD)
+    return {};
+
+  if (isa<FunctionDecl, EnumConstantDecl>(ND))
+    return {};
+
+  // Get type text of variable declarations.
+  auto &SM = VD->getASTContext().getSourceManager();
+  const char *Begin = SM.getCharacterData(VD->getBeginLoc());
+  const char *End = SM.getCharacterData(VD->getEndLoc());
+  intptr_t StrLen = End - Begin;
+
+  // FIXME: Sometimes the value that returns from ValDecl->getEndLoc()
+  // is wrong(out of location of Decl). This causes `StrLen` will be assigned
+  // an unexpected large value. Current workaround to find the terminated
+  // character instead of the `getEndLoc()` function.
+  const char *EOL = strchr(Begin, '\n');
+  if (!EOL)
+    EOL = Begin + strlen(Begin);
+
+  const char *const PosList[] = {strchr(Begin, '='), strchr(Begin, ';'),
+                                 strchr(Begin, ','), strchr(Begin, ')'), EOL};
+  for (const auto &Pos : PosList)
+    if (Pos > Begin)
+      EOL = std::min(EOL, Pos);
+
+  StrLen = EOL - Begin;
+  std::string TypeName;
+  if (StrLen > 0) {
+    std::string Type(Begin, StrLen);
+
+    static constexpr StringRef Keywords[] = {
+        // Constexpr specifiers
+        "constexpr", "constinit", "consteval",
+        // Qualifier
+        "const", "volatile", "restrict", "mutable",
+        // Storage class specifiers
+        "register", "static", "extern", "thread_local",
+        // Other keywords
+        "virtual"};
+
+    // Remove keywords
+    for (const StringRef Kw : Keywords)
+      for (size_t Pos = 0; (Pos = Type.find(Kw, Pos)) != std::string::npos;)
+        Type.replace(Pos, Kw.size(), "");
+    TypeName = Type.erase(0, Type.find_first_not_of(' '));
+
+    // Remove template parameters
+    const size_t Pos = Type.find('<');
+    if (Pos != std::string::npos)
+      TypeName = Type.erase(Pos, Type.size() - Pos);
+
+    // Replace spaces with single space.
+    for (size_t Pos = 0; (Pos = Type.find("  ", Pos)) != std::string::npos;
+         Pos += strlen(" ")) {
+      Type.replace(Pos, strlen("  "), " ");
+    }
+
+    // Replace " &" with "&".
+    for (size_t Pos = 0; (Pos = Type.find(" &", Pos)) != std::string::npos;
+         Pos += strlen("&")) {
+      Type.replace(Pos, strlen(" &"), "&");
+    }
+
+    // Replace " *" with "* ".
+    for (size_t Pos = 0; (Pos = Type.find(" *", Pos)) != std::string::npos;
+         Pos += strlen("*")) {
+      Type.replace(Pos, strlen(" *"), "* ");
+    }
+
+    // Remove redundant tailing.
+    static constexpr StringRef TailsOfMultiWordType[] = {
+        " int", " char", " double", " long", " short"};
+    bool RedundantRemoved = false;
+    for (auto Kw : TailsOfMultiWordType) {
+      const size_t Pos = Type.rfind(Kw);
+      if (Pos != std::string::npos) {
+        const size_t PtrCount = getAsteriskCount(Type, ND);
+        Type = Type.substr(0, Pos + Kw.size() + PtrCount);
+        RedundantRemoved = true;
+        break;
+      }
+    }
+
+    TypeName = Type.erase(0, Type.find_first_not_of(' '));
+    if (!RedundantRemoved) {
+      const std::size_t FoundSpace = Type.find(' ');
+      if (FoundSpace != std::string::npos)
+        Type = Type.substr(0, FoundSpace);
+    }
+
+    TypeName = Type.erase(0, Type.find_first_not_of(' '));
+
+    const QualType QT = VD->getType();
+    if (!QT.isNull() && QT->isArrayType())
+      TypeName.append("[]");
+  }
+
+  return TypeName;
+}
+
+IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name,
+                                             ClangTidyContext *Context)
+    : RenamerClangTidyCheck(Name, Context), Context(Context),
+      GetConfigPerFile(Options.get("GetConfigPerFile", true)),
+      IgnoreFailedSplit(Options.get("IgnoreFailedSplit", false)) {
+  auto IterAndInserted = NamingStylesCache.try_emplace(
+      llvm::sys::path::parent_path(Context->getCurrentFile()),
+      getFileStyleFromOptions(Options));
+  assert(IterAndInserted.second && "Couldn't insert Style");
+  // Holding a reference to the data in the vector is safe as it should never
+  // move.
+  MainFileStyle = &IterAndInserted.first->getValue();
+}
+
+IdentifierNamingCheck::~IdentifierNamingCheck() = default;
+
 void IdentifierNamingCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   RenamerClangTidyCheck::storeOptions(Opts);
   SmallString<64> StyleString;

>From 225c2059ab6d33bb4a6cad48e1c3584cdd747963 Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <[email protected]>
Date: Wed, 24 Dec 2025 12:26:42 -0700
Subject: [PATCH 3/3] Reorder functions

---
 .../readability/IdentifierNamingCheck.cpp     | 354 +++++++++---------
 1 file changed, 177 insertions(+), 177 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
index d155cab5330a7..6fcabac7257e0 100644
--- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
@@ -330,50 +330,164 @@ loadFileConfig(const ClangTidyCheck::OptionsView 
&Options,
   }
 }
 
+static std::string getEnumPrefix(const EnumConstantDecl *ECD) {
+  const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
+
+  std::string Name = ED->getName().str();
+  if (StringRef(Name).contains("enum")) {
+    Name = Name.substr(strlen("enum"), Name.length() - strlen("enum"));
+    Name = Name.erase(0, Name.find_first_not_of(' '));
+  }
+
+  static const llvm::Regex Splitter(
+      "([a-z0-9A-Z]*)(_+)|([A-Z]?[a-z0-9]+)([A-Z]|$)|([A-Z]+)([A-Z]|$)");
+
+  const StringRef EnumName(Name);
+  SmallVector<StringRef, 8> Substrs;
+  EnumName.split(Substrs, "_", -1, false);
+
+  SmallVector<StringRef, 8> Words;
+  SmallVector<StringRef, 8> Groups;
+  for (auto Substr : Substrs) {
+    while (!Substr.empty()) {
+      Groups.clear();
+      if (!Splitter.match(Substr, &Groups))
+        break;
+
+      if (!Groups[2].empty()) {
+        Words.push_back(Groups[1]);
+        Substr = Substr.substr(Groups[0].size());
+      } else if (!Groups[3].empty()) {
+        Words.push_back(Groups[3]);
+        Substr = Substr.substr(Groups[0].size() - Groups[4].size());
+      } else if (!Groups[5].empty()) {
+        Words.push_back(Groups[5]);
+        Substr = Substr.substr(Groups[0].size() - Groups[6].size());
+      }
+    }
+  }
+
+  std::string Initial;
+  for (const StringRef Word : Words)
+    Initial += tolower(Word[0]);
+
+  return Initial;
+}
+
 static std::string
-getPrefix(const Decl *D,
-          const IdentifierNamingCheck::HungarianNotationOption &HNOption) {
-  if (!D)
-    return {};
-  const auto *ND = dyn_cast<NamedDecl>(D);
-  if (!ND)
+getClassPrefix(const CXXRecordDecl *CRD,
+               const IdentifierNamingCheck::HungarianNotationOption &HNOption) 
{
+  if (CRD->isUnion())
     return {};
 
-  std::string Prefix;
-  if (const auto *ECD = dyn_cast<EnumConstantDecl>(ND)) {
-    Prefix = getEnumPrefix(ECD);
-  } else if (const auto *CRD = dyn_cast<CXXRecordDecl>(ND)) {
-    Prefix = getClassPrefix(CRD, HNOption);
-  } else if (isa<VarDecl, FieldDecl, RecordDecl>(ND)) {
-    const std::string TypeName = getDeclTypeName(ND);
-    if (!TypeName.empty())
-      Prefix = getDataTypePrefix(TypeName, ND, HNOption);
-  }
+  if (CRD->isStruct() &&
+      !isOptionEnabled("TreatStructAsClass", HNOption.General))
+    return {};
 
-  return Prefix;
+  return CRD->isAbstract() ? "I" : "C";
 }
 
-static bool removeDuplicatedPrefix(
-    SmallVector<StringRef, 8> &Words,
-    const IdentifierNamingCheck::HungarianNotationOption &HNOption) {
-  if (Words.size() <= 1)
-    return true;
+static std::string getDeclTypeName(const NamedDecl *ND) {
+  const auto *VD = dyn_cast<ValueDecl>(ND);
+  if (!VD)
+    return {};
 
-  const std::string CorrectName = Words[0].str();
-  const std::vector<llvm::StringMap<std::string>> MapList = {
-      HNOption.CString, HNOption.DerivedType, HNOption.PrimitiveType,
-      HNOption.UserDefinedType};
+  if (isa<FunctionDecl, EnumConstantDecl>(ND))
+    return {};
 
-  for (const auto &Map : MapList) {
-    for (const auto &Str : Map) {
-      if (Str.getValue() == CorrectName) {
-        Words.erase(Words.begin(), Words.begin() + 1);
-        return true;
+  // Get type text of variable declarations.
+  auto &SM = VD->getASTContext().getSourceManager();
+  const char *Begin = SM.getCharacterData(VD->getBeginLoc());
+  const char *End = SM.getCharacterData(VD->getEndLoc());
+  intptr_t StrLen = End - Begin;
+
+  // FIXME: Sometimes the value that returns from ValDecl->getEndLoc()
+  // is wrong(out of location of Decl). This causes `StrLen` will be assigned
+  // an unexpected large value. Current workaround to find the terminated
+  // character instead of the `getEndLoc()` function.
+  const char *EOL = strchr(Begin, '\n');
+  if (!EOL)
+    EOL = Begin + strlen(Begin);
+
+  const char *const PosList[] = {strchr(Begin, '='), strchr(Begin, ';'),
+                                 strchr(Begin, ','), strchr(Begin, ')'), EOL};
+  for (const auto &Pos : PosList)
+    if (Pos > Begin)
+      EOL = std::min(EOL, Pos);
+
+  StrLen = EOL - Begin;
+  std::string TypeName;
+  if (StrLen > 0) {
+    std::string Type(Begin, StrLen);
+
+    static constexpr StringRef Keywords[] = {
+        // Constexpr specifiers
+        "constexpr", "constinit", "consteval",
+        // Qualifier
+        "const", "volatile", "restrict", "mutable",
+        // Storage class specifiers
+        "register", "static", "extern", "thread_local",
+        // Other keywords
+        "virtual"};
+
+    // Remove keywords
+    for (const StringRef Kw : Keywords)
+      for (size_t Pos = 0; (Pos = Type.find(Kw, Pos)) != std::string::npos;)
+        Type.replace(Pos, Kw.size(), "");
+    TypeName = Type.erase(0, Type.find_first_not_of(' '));
+
+    // Remove template parameters
+    const size_t Pos = Type.find('<');
+    if (Pos != std::string::npos)
+      TypeName = Type.erase(Pos, Type.size() - Pos);
+
+    // Replace spaces with single space.
+    for (size_t Pos = 0; (Pos = Type.find("  ", Pos)) != std::string::npos;
+         Pos += strlen(" ")) {
+      Type.replace(Pos, strlen("  "), " ");
+    }
+
+    // Replace " &" with "&".
+    for (size_t Pos = 0; (Pos = Type.find(" &", Pos)) != std::string::npos;
+         Pos += strlen("&")) {
+      Type.replace(Pos, strlen(" &"), "&");
+    }
+
+    // Replace " *" with "* ".
+    for (size_t Pos = 0; (Pos = Type.find(" *", Pos)) != std::string::npos;
+         Pos += strlen("*")) {
+      Type.replace(Pos, strlen(" *"), "* ");
+    }
+
+    // Remove redundant tailing.
+    static constexpr StringRef TailsOfMultiWordType[] = {
+        " int", " char", " double", " long", " short"};
+    bool RedundantRemoved = false;
+    for (auto Kw : TailsOfMultiWordType) {
+      const size_t Pos = Type.rfind(Kw);
+      if (Pos != std::string::npos) {
+        const size_t PtrCount = getAsteriskCount(Type, ND);
+        Type = Type.substr(0, Pos + Kw.size() + PtrCount);
+        RedundantRemoved = true;
+        break;
       }
     }
+
+    TypeName = Type.erase(0, Type.find_first_not_of(' '));
+    if (!RedundantRemoved) {
+      const std::size_t FoundSpace = Type.find(' ');
+      if (FoundSpace != std::string::npos)
+        Type = Type.substr(0, FoundSpace);
+    }
+
+    TypeName = Type.erase(0, Type.find_first_not_of(' '));
+
+    const QualType QT = VD->getType();
+    if (!QT.isNull() && QT->isArrayType())
+      TypeName.append("[]");
   }
 
-  return false;
+  return TypeName;
 }
 
 static std::string getDataTypePrefix(
@@ -457,60 +571,49 @@ static std::string getDataTypePrefix(
 }
 
 static std::string
-getClassPrefix(const CXXRecordDecl *CRD,
-               const IdentifierNamingCheck::HungarianNotationOption &HNOption) 
{
-  if (CRD->isUnion())
+getPrefix(const Decl *D,
+          const IdentifierNamingCheck::HungarianNotationOption &HNOption) {
+  if (!D)
     return {};
-
-  if (CRD->isStruct() &&
-      !isOptionEnabled("TreatStructAsClass", HNOption.General))
+  const auto *ND = dyn_cast<NamedDecl>(D);
+  if (!ND)
     return {};
 
-  return CRD->isAbstract() ? "I" : "C";
-}
-
-static std::string getEnumPrefix(const EnumConstantDecl *ECD) {
-  const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
-
-  std::string Name = ED->getName().str();
-  if (StringRef(Name).contains("enum")) {
-    Name = Name.substr(strlen("enum"), Name.length() - strlen("enum"));
-    Name = Name.erase(0, Name.find_first_not_of(' '));
+  std::string Prefix;
+  if (const auto *ECD = dyn_cast<EnumConstantDecl>(ND)) {
+    Prefix = getEnumPrefix(ECD);
+  } else if (const auto *CRD = dyn_cast<CXXRecordDecl>(ND)) {
+    Prefix = getClassPrefix(CRD, HNOption);
+  } else if (isa<VarDecl, FieldDecl, RecordDecl>(ND)) {
+    const std::string TypeName = getDeclTypeName(ND);
+    if (!TypeName.empty())
+      Prefix = getDataTypePrefix(TypeName, ND, HNOption);
   }
 
-  static const llvm::Regex Splitter(
-      "([a-z0-9A-Z]*)(_+)|([A-Z]?[a-z0-9]+)([A-Z]|$)|([A-Z]+)([A-Z]|$)");
+  return Prefix;
+}
 
-  const StringRef EnumName(Name);
-  SmallVector<StringRef, 8> Substrs;
-  EnumName.split(Substrs, "_", -1, false);
+static bool removeDuplicatedPrefix(
+    SmallVector<StringRef, 8> &Words,
+    const IdentifierNamingCheck::HungarianNotationOption &HNOption) {
+  if (Words.size() <= 1)
+    return true;
 
-  SmallVector<StringRef, 8> Words;
-  SmallVector<StringRef, 8> Groups;
-  for (auto Substr : Substrs) {
-    while (!Substr.empty()) {
-      Groups.clear();
-      if (!Splitter.match(Substr, &Groups))
-        break;
+  const std::string CorrectName = Words[0].str();
+  const std::vector<llvm::StringMap<std::string>> MapList = {
+      HNOption.CString, HNOption.DerivedType, HNOption.PrimitiveType,
+      HNOption.UserDefinedType};
 
-      if (!Groups[2].empty()) {
-        Words.push_back(Groups[1]);
-        Substr = Substr.substr(Groups[0].size());
-      } else if (!Groups[3].empty()) {
-        Words.push_back(Groups[3]);
-        Substr = Substr.substr(Groups[0].size() - Groups[4].size());
-      } else if (!Groups[5].empty()) {
-        Words.push_back(Groups[5]);
-        Substr = Substr.substr(Groups[0].size() - Groups[6].size());
+  for (const auto &Map : MapList) {
+    for (const auto &Str : Map) {
+      if (Str.getValue() == CorrectName) {
+        Words.erase(Words.begin(), Words.begin() + 1);
+        return true;
       }
     }
   }
 
-  std::string Initial;
-  for (const StringRef Word : Words)
-    Initial += tolower(Word[0]);
-
-  return Initial;
+  return false;
 }
 
 static size_t getAsteriskCount(const std::string &TypeName) {
@@ -704,109 +807,6 @@ IdentifierNamingCheck::FileStyle 
IdentifierNamingCheck::getFileStyleFromOptions(
           CheckAnonFieldInParent};
 }
 
-static std::string getDeclTypeName(const NamedDecl *ND) {
-  const auto *VD = dyn_cast<ValueDecl>(ND);
-  if (!VD)
-    return {};
-
-  if (isa<FunctionDecl, EnumConstantDecl>(ND))
-    return {};
-
-  // Get type text of variable declarations.
-  auto &SM = VD->getASTContext().getSourceManager();
-  const char *Begin = SM.getCharacterData(VD->getBeginLoc());
-  const char *End = SM.getCharacterData(VD->getEndLoc());
-  intptr_t StrLen = End - Begin;
-
-  // FIXME: Sometimes the value that returns from ValDecl->getEndLoc()
-  // is wrong(out of location of Decl). This causes `StrLen` will be assigned
-  // an unexpected large value. Current workaround to find the terminated
-  // character instead of the `getEndLoc()` function.
-  const char *EOL = strchr(Begin, '\n');
-  if (!EOL)
-    EOL = Begin + strlen(Begin);
-
-  const char *const PosList[] = {strchr(Begin, '='), strchr(Begin, ';'),
-                                 strchr(Begin, ','), strchr(Begin, ')'), EOL};
-  for (const auto &Pos : PosList)
-    if (Pos > Begin)
-      EOL = std::min(EOL, Pos);
-
-  StrLen = EOL - Begin;
-  std::string TypeName;
-  if (StrLen > 0) {
-    std::string Type(Begin, StrLen);
-
-    static constexpr StringRef Keywords[] = {
-        // Constexpr specifiers
-        "constexpr", "constinit", "consteval",
-        // Qualifier
-        "const", "volatile", "restrict", "mutable",
-        // Storage class specifiers
-        "register", "static", "extern", "thread_local",
-        // Other keywords
-        "virtual"};
-
-    // Remove keywords
-    for (const StringRef Kw : Keywords)
-      for (size_t Pos = 0; (Pos = Type.find(Kw, Pos)) != std::string::npos;)
-        Type.replace(Pos, Kw.size(), "");
-    TypeName = Type.erase(0, Type.find_first_not_of(' '));
-
-    // Remove template parameters
-    const size_t Pos = Type.find('<');
-    if (Pos != std::string::npos)
-      TypeName = Type.erase(Pos, Type.size() - Pos);
-
-    // Replace spaces with single space.
-    for (size_t Pos = 0; (Pos = Type.find("  ", Pos)) != std::string::npos;
-         Pos += strlen(" ")) {
-      Type.replace(Pos, strlen("  "), " ");
-    }
-
-    // Replace " &" with "&".
-    for (size_t Pos = 0; (Pos = Type.find(" &", Pos)) != std::string::npos;
-         Pos += strlen("&")) {
-      Type.replace(Pos, strlen(" &"), "&");
-    }
-
-    // Replace " *" with "* ".
-    for (size_t Pos = 0; (Pos = Type.find(" *", Pos)) != std::string::npos;
-         Pos += strlen("*")) {
-      Type.replace(Pos, strlen(" *"), "* ");
-    }
-
-    // Remove redundant tailing.
-    static constexpr StringRef TailsOfMultiWordType[] = {
-        " int", " char", " double", " long", " short"};
-    bool RedundantRemoved = false;
-    for (auto Kw : TailsOfMultiWordType) {
-      const size_t Pos = Type.rfind(Kw);
-      if (Pos != std::string::npos) {
-        const size_t PtrCount = getAsteriskCount(Type, ND);
-        Type = Type.substr(0, Pos + Kw.size() + PtrCount);
-        RedundantRemoved = true;
-        break;
-      }
-    }
-
-    TypeName = Type.erase(0, Type.find_first_not_of(' '));
-    if (!RedundantRemoved) {
-      const std::size_t FoundSpace = Type.find(' ');
-      if (FoundSpace != std::string::npos)
-        Type = Type.substr(0, FoundSpace);
-    }
-
-    TypeName = Type.erase(0, Type.find_first_not_of(' '));
-
-    const QualType QT = VD->getType();
-    if (!QT.isNull() && QT->isArrayType())
-      TypeName.append("[]");
-  }
-
-  return TypeName;
-}
-
 IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name,
                                              ClangTidyContext *Context)
     : RenamerClangTidyCheck(Name, Context), Context(Context),

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

Reply via email to