[clang-tools-extra] [clang-tidy][NFC] Replace stateless struct with namespace in `readability-identifier-naming` (PR #173506)
Victor Chernyakin via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 24 11:16:38 PST 2025
https://github.com/localspook created https://github.com/llvm/llvm-project/pull/173506
None
>From f3dcfaf13f73e38eb2c8c464a0f92855c3d3eb6f Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <chernyakin.victor.j at outlook.com>
Date: Wed, 24 Dec 2025 12:12:12 -0700
Subject: [PATCH 1/2] [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 <chernyakin.victor.j at outlook.com>
Date: Wed, 24 Dec 2025 12:14:03 -0700
Subject: [PATCH 2/2] 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;
More information about the cfe-commits
mailing list