[TargetVersion] Only enable on RISC-V and AArch64 (#115991)
[llvm-project.git] / clang-tools-extra / clang-tidy / readability / IdentifierNamingCheck.h
blob646ec0eac8dd1c889dad7ad2dc932863cfbb363d
1 //===--- IdentifierNamingCheck.h - clang-tidy -------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
12 #include "../utils/RenamerClangTidyCheck.h"
13 #include <optional>
14 #include <string>
15 namespace clang::tidy {
16 namespace readability {
18 enum StyleKind : int;
20 /// Checks for identifiers naming style mismatch.
21 ///
22 /// This check will try to enforce coding guidelines on the identifiers naming.
23 /// It supports `lower_case`, `UPPER_CASE`, `camelBack` and `CamelCase` casing
24 /// and tries to convert from one to another if a mismatch is detected.
25 ///
26 /// It also supports a fixed prefix and suffix that will be prepended or
27 /// appended to the identifiers, regardless of the casing.
28 ///
29 /// Many configuration options are available, in order to be able to create
30 /// different rules for different kind of identifier. In general, the
31 /// rules are falling back to a more generic rule if the specific case is not
32 /// configured.
33 class IdentifierNamingCheck final : public RenamerClangTidyCheck {
34 public:
35 IdentifierNamingCheck(StringRef Name, ClangTidyContext *Context);
36 ~IdentifierNamingCheck();
38 void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
40 enum CaseType {
41 CT_AnyCase = 0,
42 CT_LowerCase,
43 CT_CamelBack,
44 CT_UpperCase,
45 CT_CamelCase,
46 CT_CamelSnakeCase,
47 CT_CamelSnakeBack,
48 CT_LeadingUpperSnakeCase
51 enum HungarianPrefixType {
52 HPT_Off = 0,
53 HPT_On,
54 HPT_LowerCase,
55 HPT_CamelCase,
58 struct HungarianNotationOption {
59 HungarianNotationOption() = default;
61 std::optional<CaseType> Case;
62 HungarianPrefixType HPType = HungarianPrefixType::HPT_Off;
63 llvm::StringMap<std::string> General;
64 llvm::StringMap<std::string> CString;
65 llvm::StringMap<std::string> PrimitiveType;
66 llvm::StringMap<std::string> UserDefinedType;
67 llvm::StringMap<std::string> DerivedType;
70 struct NamingStyle {
71 NamingStyle() = default;
73 NamingStyle(std::optional<CaseType> Case, StringRef Prefix,
74 StringRef Suffix, StringRef IgnoredRegexpStr,
75 HungarianPrefixType HPType);
76 NamingStyle(const NamingStyle &O) = delete;
77 NamingStyle &operator=(NamingStyle &&O) = default;
78 NamingStyle(NamingStyle &&O) = default;
80 std::optional<CaseType> Case;
81 std::string Prefix;
82 std::string Suffix;
83 // Store both compiled and non-compiled forms so original value can be
84 // serialized
85 llvm::Regex IgnoredRegexp;
86 std::string IgnoredRegexpStr;
88 HungarianPrefixType HPType;
91 struct HungarianNotation {
92 public:
93 bool checkOptionValid(int StyleKindIndex) const;
94 bool isOptionEnabled(StringRef OptionKey,
95 const llvm::StringMap<std::string> &StrMap) const;
97 size_t getAsteriskCount(const std::string &TypeName) const;
98 size_t getAsteriskCount(const std::string &TypeName,
99 const NamedDecl *ND) const;
101 void loadDefaultConfig(
102 IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
103 void loadFileConfig(
104 const ClangTidyCheck::OptionsView &Options,
105 IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
107 bool removeDuplicatedPrefix(
108 SmallVector<StringRef, 8> &Words,
109 const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
111 std::string getPrefix(
112 const Decl *D,
113 const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
115 std::string getDataTypePrefix(
116 StringRef TypeName, const NamedDecl *ND,
117 const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
119 std::string getClassPrefix(
120 const CXXRecordDecl *CRD,
121 const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
123 std::string getEnumPrefix(const EnumConstantDecl *ECD) const;
124 std::string getDeclTypeName(const NamedDecl *ND) const;
127 struct FileStyle {
128 FileStyle() : IsActive(false), IgnoreMainLikeFunctions(false) {}
129 FileStyle(SmallVectorImpl<std::optional<NamingStyle>> &&Styles,
130 HungarianNotationOption HNOption, bool IgnoreMainLike,
131 bool CheckAnonFieldInParent)
132 : Styles(std::move(Styles)), HNOption(std::move(HNOption)),
133 IsActive(true), IgnoreMainLikeFunctions(IgnoreMainLike),
134 CheckAnonFieldInParentScope(CheckAnonFieldInParent) {}
136 ArrayRef<std::optional<NamingStyle>> getStyles() const {
137 assert(IsActive);
138 return Styles;
141 const HungarianNotationOption &getHNOption() const {
142 assert(IsActive);
143 return HNOption;
146 bool isActive() const { return IsActive; }
147 bool isIgnoringMainLikeFunction() const { return IgnoreMainLikeFunctions; }
149 bool isCheckingAnonFieldInParentScope() const {
150 return CheckAnonFieldInParentScope;
153 private:
154 SmallVector<std::optional<NamingStyle>, 0> Styles;
155 HungarianNotationOption HNOption;
156 bool IsActive;
157 bool IgnoreMainLikeFunctions;
158 bool CheckAnonFieldInParentScope;
161 IdentifierNamingCheck::FileStyle
162 getFileStyleFromOptions(const ClangTidyCheck::OptionsView &Options) const;
164 bool
165 matchesStyle(StringRef Type, StringRef Name,
166 const IdentifierNamingCheck::NamingStyle &Style,
167 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
168 const NamedDecl *Decl) const;
170 std::string
171 fixupWithCase(StringRef Type, StringRef Name, const Decl *D,
172 const IdentifierNamingCheck::NamingStyle &Style,
173 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
174 IdentifierNamingCheck::CaseType Case) const;
176 std::string
177 fixupWithStyle(StringRef Type, StringRef Name,
178 const IdentifierNamingCheck::NamingStyle &Style,
179 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
180 const Decl *D) const;
182 StyleKind findStyleKind(
183 const NamedDecl *D,
184 ArrayRef<std::optional<IdentifierNamingCheck::NamingStyle>> NamingStyles,
185 bool IgnoreMainLikeFunctions, bool CheckAnonFieldInParentScope) const;
187 std::optional<RenamerClangTidyCheck::FailureInfo> getFailureInfo(
188 StringRef Type, StringRef Name, const NamedDecl *ND,
189 SourceLocation Location,
190 ArrayRef<std::optional<IdentifierNamingCheck::NamingStyle>> NamingStyles,
191 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
192 StyleKind SK, const SourceManager &SM, bool IgnoreFailedSplit) const;
194 bool isParamInMainLikeFunction(const ParmVarDecl &ParmDecl,
195 bool IncludeMainLike) const;
197 private:
198 std::optional<FailureInfo>
199 getDeclFailureInfo(const NamedDecl *Decl,
200 const SourceManager &SM) const override;
201 std::optional<FailureInfo>
202 getMacroFailureInfo(const Token &MacroNameTok,
203 const SourceManager &SM) const override;
204 DiagInfo getDiagInfo(const NamingCheckId &ID,
205 const NamingCheckFailure &Failure) const override;
207 const FileStyle &getStyleForFile(StringRef FileName) const;
208 StringRef getRealFileName(StringRef FileName) const;
210 /// Find the style kind of a field in an anonymous record.
211 StyleKind findStyleKindForAnonField(
212 const FieldDecl *AnonField,
213 ArrayRef<std::optional<NamingStyle>> NamingStyles) const;
215 StyleKind findStyleKindForField(
216 const FieldDecl *Field, QualType Type,
217 ArrayRef<std::optional<NamingStyle>> NamingStyles) const;
219 StyleKind
220 findStyleKindForVar(const VarDecl *Var, QualType Type,
221 ArrayRef<std::optional<NamingStyle>> NamingStyles) const;
223 /// Stores the style options as a vector, indexed by the specified \ref
224 /// StyleKind, for a given directory.
225 mutable llvm::StringMap<FileStyle> NamingStylesCache;
226 mutable llvm::StringMap<SmallString<256U>> RealFileNameCache;
227 FileStyle *MainFileStyle;
228 ClangTidyContext *Context;
229 const bool GetConfigPerFile;
230 const bool IgnoreFailedSplit;
231 HungarianNotation HungarianNotation;
234 } // namespace readability
235 template <>
236 struct OptionEnumMapping<readability::IdentifierNamingCheck::CaseType> {
237 static llvm::ArrayRef<
238 std::pair<readability::IdentifierNamingCheck::CaseType, StringRef>>
239 getEnumMapping();
241 } // namespace clang::tidy
243 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H