1 //===--- IdentifierNamingCheck.h - clang-tidy -------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
11 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
12 
13 #include "../ClangTidy.h"
14 
15 namespace clang {
16 
17 class MacroInfo;
18 
19 namespace tidy {
20 namespace readability {
21 
22 /// Checks for identifiers naming style mismatch.
23 ///
24 /// This check will try to enforce coding guidelines on the identifiers naming.
25 /// It supports `lower_case`, `UPPER_CASE`, `camelBack` and `CamelCase` casing
26 /// and tries to convert from one to another if a mismatch is detected.
27 ///
28 /// It also supports a fixed prefix and suffix that will be prepended or
29 /// appended to the identifiers, regardless of the casing.
30 ///
31 /// Many configuration options are available, in order to be able to create
32 /// different rules for different kind of identifier. In general, the
33 /// rules are falling back to a more generic rule if the specific case is not
34 /// configured.
35 class IdentifierNamingCheck : public ClangTidyCheck {
36 public:
37   IdentifierNamingCheck(StringRef Name, ClangTidyContext *Context);
38 
39   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
40   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
41   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
42   void registerPPCallbacks(CompilerInstance &Compiler) override;
43   void onEndOfTranslationUnit() override;
44 
45   enum CaseType {
46     CT_AnyCase = 0,
47     CT_LowerCase,
48     CT_CamelBack,
49     CT_UpperCase,
50     CT_CamelCase,
51     CT_CamelSnakeCase,
52     CT_CamelSnakeBack
53   };
54 
55   struct NamingStyle {
56     NamingStyle() = default;
57 
NamingStyleNamingStyle58     NamingStyle(llvm::Optional<CaseType> Case, const std::string &Prefix,
59                 const std::string &Suffix)
60         : Case(Case), Prefix(Prefix), Suffix(Suffix) {}
61 
62     llvm::Optional<CaseType> Case;
63     std::string Prefix;
64     std::string Suffix;
65   };
66 
67   /// \brief Holds an identifier name check failure, tracking the kind of the
68   /// identifer, its possible fixup and the starting locations of all the
69   /// identifier usages.
70   struct NamingCheckFailure {
71     std::string KindName;
72     std::string Fixup;
73 
74     /// \brief Whether the failure should be fixed or not.
75     ///
76     /// ie: if the identifier was used or declared within a macro we won't offer
77     /// a fixup for safety reasons.
78     bool ShouldFix;
79 
80     /// \brief A set of all the identifier usages starting SourceLocation, in
81     /// their encoded form.
82     llvm::DenseSet<unsigned> RawUsageLocs;
83 
NamingCheckFailureNamingCheckFailure84     NamingCheckFailure() : ShouldFix(true) {}
85   };
86 
87   typedef std::pair<SourceLocation, std::string> NamingCheckId;
88 
89   typedef llvm::DenseMap<NamingCheckId, NamingCheckFailure>
90       NamingCheckFailureMap;
91 
92   /// Check Macros for style violations.
93   void checkMacro(SourceManager &sourceMgr, const Token &MacroNameTok,
94                   const MacroInfo *MI);
95 
96   /// Add a usage of a macro if it already has a violation.
97   void expandMacro(const Token &MacroNameTok, const MacroInfo *MI);
98 
99 private:
100   std::vector<llvm::Optional<NamingStyle>> NamingStyles;
101   bool IgnoreFailedSplit;
102   NamingCheckFailureMap NamingCheckFailures;
103 };
104 
105 } // namespace readability
106 } // namespace tidy
107 } // namespace clang
108 
109 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
110