comparison clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h @ 150:1d019706d866

LLVM10
author anatofuz
date Thu, 13 Feb 2020 15:10:13 +0900
parents
children 0572611fdcc8
comparison
equal deleted inserted replaced
147:c2174574ed3a 150:1d019706d866
1 //===--- RenamderClangTidyCheck.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 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
11
12 #include "../ClangTidyCheck.h"
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/DenseSet.h"
15 #include "llvm/ADT/Optional.h"
16 #include <string>
17 #include <utility>
18
19 namespace clang {
20
21 class MacroInfo;
22
23 namespace tidy {
24
25 /// Base class for clang-tidy checks that want to flag declarations and/or
26 /// macros for renaming based on customizable criteria.
27 class RenamerClangTidyCheck : public ClangTidyCheck {
28 public:
29 RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
30 ~RenamerClangTidyCheck();
31
32 /// Derived classes should not implement any matching logic themselves; this
33 /// class will do the matching and call the derived class'
34 /// GetDeclFailureInfo() and GetMacroFailureInfo() for determining whether a
35 /// given identifier passes or fails the check.
36 void registerMatchers(ast_matchers::MatchFinder *Finder) override final;
37 void
38 check(const ast_matchers::MatchFinder::MatchResult &Result) override final;
39 void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
40 Preprocessor *ModuleExpanderPP) override final;
41 void onEndOfTranslationUnit() override final;
42
43 /// This enum will be used in %select of the diagnostic message.
44 /// Each value below IgnoreFailureThreshold should have an error message.
45 enum class ShouldFixStatus {
46 ShouldFix,
47
48 /// The fixup will conflict with a language keyword,
49 /// so we can't fix it automatically.
50 ConflictsWithKeyword,
51
52 /// The fixup will conflict with a macro
53 /// definition, so we can't fix it
54 /// automatically.
55 ConflictsWithMacroDefinition,
56
57 /// Values pass this threshold will be ignored completely
58 /// i.e no message, no fixup.
59 IgnoreFailureThreshold,
60
61 /// If the identifier was used or declared within a macro we
62 /// won't offer a fixup for safety reasons.
63 InsideMacro,
64 };
65
66 /// Information describing a failed check
67 struct FailureInfo {
68 std::string KindName; // Tag or misc info to be used as derived classes need
69 std::string Fixup; // The name that will be proposed as a fix-it hint
70 };
71
72 /// Holds an identifier name check failure, tracking the kind of the
73 /// identifier, its possible fixup and the starting locations of all the
74 /// identifier usages.
75 struct NamingCheckFailure {
76 FailureInfo Info;
77
78 /// Whether the failure should be fixed or not.
79 ///
80 /// e.g.: if the identifier was used or declared within a macro we won't
81 /// offer a fixup for safety reasons.
82 bool ShouldFix() const {
83 return FixStatus == ShouldFixStatus::ShouldFix && !Info.Fixup.empty();
84 }
85
86 bool ShouldNotify() const {
87 return FixStatus < ShouldFixStatus::IgnoreFailureThreshold;
88 }
89
90 ShouldFixStatus FixStatus = ShouldFixStatus::ShouldFix;
91
92 /// A set of all the identifier usages starting SourceLocation, in
93 /// their encoded form.
94 llvm::DenseSet<unsigned> RawUsageLocs;
95
96 NamingCheckFailure() = default;
97 };
98
99 using NamingCheckId = std::pair<SourceLocation, std::string>;
100
101 using NamingCheckFailureMap =
102 llvm::DenseMap<NamingCheckId, NamingCheckFailure>;
103
104 /// Check Macros for style violations.
105 void checkMacro(SourceManager &sourceMgr, const Token &MacroNameTok,
106 const MacroInfo *MI);
107
108 /// Add a usage of a macro if it already has a violation.
109 void expandMacro(const Token &MacroNameTok, const MacroInfo *MI);
110
111 protected:
112 /// Overridden by derived classes, returns information about if and how a Decl
113 /// failed the check. A 'None' result means the Decl did not fail the check.
114 virtual llvm::Optional<FailureInfo>
115 GetDeclFailureInfo(const NamedDecl *Decl, const SourceManager &SM) const = 0;
116
117 /// Overridden by derived classes, returns information about if and how a
118 /// macro failed the check. A 'None' result means the macro did not fail the
119 /// check.
120 virtual llvm::Optional<FailureInfo>
121 GetMacroFailureInfo(const Token &MacroNameTok,
122 const SourceManager &SM) const = 0;
123
124 /// Represents customized diagnostic text and how arguments should be applied.
125 /// Example usage:
126 ///
127 /// return DiagInfo{"my %1 very %2 special %3 text",
128 /// [=](DiagnosticBuilder &diag) {
129 /// diag << arg1 << arg2 << arg3;
130 /// }};
131 struct DiagInfo {
132 std::string Text;
133 llvm::unique_function<void(DiagnosticBuilder &)> ApplyArgs;
134 };
135
136 /// Overridden by derived classes, returns a description of the diagnostic
137 /// that should be emitted for the given failure. The base class will then
138 /// further customize the diagnostic by adding info about whether the fix-it
139 /// can be automatically applied or not.
140 virtual DiagInfo GetDiagInfo(const NamingCheckId &ID,
141 const NamingCheckFailure &Failure) const = 0;
142
143 private:
144 NamingCheckFailureMap NamingCheckFailures;
145 };
146
147 } // namespace tidy
148 } // namespace clang
149
150 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H