Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:21

0001 //===--- IdentifierNamingCheck.h - clang-tidy -------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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 /// Checks for identifiers naming style mismatch.
0021 ///
0022 /// This check will try to enforce coding guidelines on the identifiers naming.
0023 /// It supports `lower_case`, `UPPER_CASE`, `camelBack` and `CamelCase` casing
0024 /// and tries to convert from one to another if a mismatch is detected.
0025 ///
0026 /// It also supports a fixed prefix and suffix that will be prepended or
0027 /// appended to the identifiers, regardless of the casing.
0028 ///
0029 /// Many configuration options are available, in order to be able to create
0030 /// different rules for different kind of identifier. In general, the
0031 /// rules are falling back to a more generic rule if the specific case is not
0032 /// configured.
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     // Store both compiled and non-compiled forms so original value can be
0084     // serialized
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   /// Find the style kind of a field in an anonymous record.
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   /// Stores the style options as a vector, indexed by the specified \ref
0224   /// StyleKind, for a given directory.
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 } // namespace readability
0235 template <>
0236 struct OptionEnumMapping<readability::IdentifierNamingCheck::CaseType> {
0237   static llvm::ArrayRef<
0238       std::pair<readability::IdentifierNamingCheck::CaseType, StringRef>>
0239   getEnumMapping();
0240 };
0241 } // namespace clang::tidy
0242 
0243 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H