File indexing completed on 2026-05-10 08:36:21
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
0010 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
0011
0012 #include "../utils/RenamerClangTidyCheck.h"
0013 #include <optional>
0014 #include <string>
0015 namespace clang::tidy {
0016 namespace readability {
0017
0018 enum StyleKind : int;
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 class IdentifierNamingCheck final : public RenamerClangTidyCheck {
0034 public:
0035 IdentifierNamingCheck(StringRef Name, ClangTidyContext *Context);
0036 ~IdentifierNamingCheck();
0037
0038 void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
0039
0040 enum CaseType {
0041 CT_AnyCase = 0,
0042 CT_LowerCase,
0043 CT_CamelBack,
0044 CT_UpperCase,
0045 CT_CamelCase,
0046 CT_CamelSnakeCase,
0047 CT_CamelSnakeBack,
0048 CT_LeadingUpperSnakeCase
0049 };
0050
0051 enum HungarianPrefixType {
0052 HPT_Off = 0,
0053 HPT_On,
0054 HPT_LowerCase,
0055 HPT_CamelCase,
0056 };
0057
0058 struct HungarianNotationOption {
0059 HungarianNotationOption() = default;
0060
0061 std::optional<CaseType> Case;
0062 HungarianPrefixType HPType = HungarianPrefixType::HPT_Off;
0063 llvm::StringMap<std::string> General;
0064 llvm::StringMap<std::string> CString;
0065 llvm::StringMap<std::string> PrimitiveType;
0066 llvm::StringMap<std::string> UserDefinedType;
0067 llvm::StringMap<std::string> DerivedType;
0068 };
0069
0070 struct NamingStyle {
0071 NamingStyle() = default;
0072
0073 NamingStyle(std::optional<CaseType> Case, StringRef Prefix,
0074 StringRef Suffix, StringRef IgnoredRegexpStr,
0075 HungarianPrefixType HPType);
0076 NamingStyle(const NamingStyle &O) = delete;
0077 NamingStyle &operator=(NamingStyle &&O) = default;
0078 NamingStyle(NamingStyle &&O) = default;
0079
0080 std::optional<CaseType> Case;
0081 std::string Prefix;
0082 std::string Suffix;
0083
0084
0085 llvm::Regex IgnoredRegexp;
0086 std::string IgnoredRegexpStr;
0087
0088 HungarianPrefixType HPType;
0089 };
0090
0091 struct HungarianNotation {
0092 public:
0093 bool checkOptionValid(int StyleKindIndex) const;
0094 bool isOptionEnabled(StringRef OptionKey,
0095 const llvm::StringMap<std::string> &StrMap) const;
0096
0097 size_t getAsteriskCount(const std::string &TypeName) const;
0098 size_t getAsteriskCount(const std::string &TypeName,
0099 const NamedDecl *ND) const;
0100
0101 void loadDefaultConfig(
0102 IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
0103 void loadFileConfig(
0104 const ClangTidyCheck::OptionsView &Options,
0105 IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
0106
0107 bool removeDuplicatedPrefix(
0108 SmallVector<StringRef, 8> &Words,
0109 const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
0110
0111 std::string getPrefix(
0112 const Decl *D,
0113 const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
0114
0115 std::string getDataTypePrefix(
0116 StringRef TypeName, const NamedDecl *ND,
0117 const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
0118
0119 std::string getClassPrefix(
0120 const CXXRecordDecl *CRD,
0121 const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
0122
0123 std::string getEnumPrefix(const EnumConstantDecl *ECD) const;
0124 std::string getDeclTypeName(const NamedDecl *ND) const;
0125 };
0126
0127 struct FileStyle {
0128 FileStyle() : IsActive(false), IgnoreMainLikeFunctions(false) {}
0129 FileStyle(SmallVectorImpl<std::optional<NamingStyle>> &&Styles,
0130 HungarianNotationOption HNOption, bool IgnoreMainLike,
0131 bool CheckAnonFieldInParent)
0132 : Styles(std::move(Styles)), HNOption(std::move(HNOption)),
0133 IsActive(true), IgnoreMainLikeFunctions(IgnoreMainLike),
0134 CheckAnonFieldInParentScope(CheckAnonFieldInParent) {}
0135
0136 ArrayRef<std::optional<NamingStyle>> getStyles() const {
0137 assert(IsActive);
0138 return Styles;
0139 }
0140
0141 const HungarianNotationOption &getHNOption() const {
0142 assert(IsActive);
0143 return HNOption;
0144 }
0145
0146 bool isActive() const { return IsActive; }
0147 bool isIgnoringMainLikeFunction() const { return IgnoreMainLikeFunctions; }
0148
0149 bool isCheckingAnonFieldInParentScope() const {
0150 return CheckAnonFieldInParentScope;
0151 }
0152
0153 private:
0154 SmallVector<std::optional<NamingStyle>, 0> Styles;
0155 HungarianNotationOption HNOption;
0156 bool IsActive;
0157 bool IgnoreMainLikeFunctions;
0158 bool CheckAnonFieldInParentScope;
0159 };
0160
0161 IdentifierNamingCheck::FileStyle
0162 getFileStyleFromOptions(const ClangTidyCheck::OptionsView &Options) const;
0163
0164 bool
0165 matchesStyle(StringRef Type, StringRef Name,
0166 const IdentifierNamingCheck::NamingStyle &Style,
0167 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
0168 const NamedDecl *Decl) const;
0169
0170 std::string
0171 fixupWithCase(StringRef Type, StringRef Name, const Decl *D,
0172 const IdentifierNamingCheck::NamingStyle &Style,
0173 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
0174 IdentifierNamingCheck::CaseType Case) const;
0175
0176 std::string
0177 fixupWithStyle(StringRef Type, StringRef Name,
0178 const IdentifierNamingCheck::NamingStyle &Style,
0179 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
0180 const Decl *D) const;
0181
0182 StyleKind findStyleKind(
0183 const NamedDecl *D,
0184 ArrayRef<std::optional<IdentifierNamingCheck::NamingStyle>> NamingStyles,
0185 bool IgnoreMainLikeFunctions, bool CheckAnonFieldInParentScope) const;
0186
0187 std::optional<RenamerClangTidyCheck::FailureInfo> getFailureInfo(
0188 StringRef Type, StringRef Name, const NamedDecl *ND,
0189 SourceLocation Location,
0190 ArrayRef<std::optional<IdentifierNamingCheck::NamingStyle>> NamingStyles,
0191 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
0192 StyleKind SK, const SourceManager &SM, bool IgnoreFailedSplit) const;
0193
0194 bool isParamInMainLikeFunction(const ParmVarDecl &ParmDecl,
0195 bool IncludeMainLike) const;
0196
0197 private:
0198 std::optional<FailureInfo>
0199 getDeclFailureInfo(const NamedDecl *Decl,
0200 const SourceManager &SM) const override;
0201 std::optional<FailureInfo>
0202 getMacroFailureInfo(const Token &MacroNameTok,
0203 const SourceManager &SM) const override;
0204 DiagInfo getDiagInfo(const NamingCheckId &ID,
0205 const NamingCheckFailure &Failure) const override;
0206
0207 const FileStyle &getStyleForFile(StringRef FileName) const;
0208 StringRef getRealFileName(StringRef FileName) const;
0209
0210
0211 StyleKind findStyleKindForAnonField(
0212 const FieldDecl *AnonField,
0213 ArrayRef<std::optional<NamingStyle>> NamingStyles) const;
0214
0215 StyleKind findStyleKindForField(
0216 const FieldDecl *Field, QualType Type,
0217 ArrayRef<std::optional<NamingStyle>> NamingStyles) const;
0218
0219 StyleKind
0220 findStyleKindForVar(const VarDecl *Var, QualType Type,
0221 ArrayRef<std::optional<NamingStyle>> NamingStyles) const;
0222
0223
0224
0225 mutable llvm::StringMap<FileStyle> NamingStylesCache;
0226 mutable llvm::StringMap<SmallString<256U>> RealFileNameCache;
0227 FileStyle *MainFileStyle;
0228 ClangTidyContext *Context;
0229 const bool GetConfigPerFile;
0230 const bool IgnoreFailedSplit;
0231 HungarianNotation HungarianNotation;
0232 };
0233
0234 }
0235 template <>
0236 struct OptionEnumMapping<readability::IdentifierNamingCheck::CaseType> {
0237 static llvm::ArrayRef<
0238 std::pair<readability::IdentifierNamingCheck::CaseType, StringRef>>
0239 getEnumMapping();
0240 };
0241 }
0242
0243 #endif