clang-tools  12.0.0git
RenamerClangTidyCheck.h
Go to the documentation of this file.
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/FunctionExtras.h"
16 #include "llvm/ADT/Optional.h"
17 #include <string>
18 #include <utility>
19 
20 namespace clang {
21 
22 class MacroInfo;
23 
24 namespace tidy {
25 
26 /// Base class for clang-tidy checks that want to flag declarations and/or
27 /// macros for renaming based on customizable criteria.
29 public:
30  RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
32 
33  /// Derived classes should not implement any matching logic themselves; this
34  /// class will do the matching and call the derived class'
35  /// GetDeclFailureInfo() and GetMacroFailureInfo() for determining whether a
36  /// given identifier passes or fails the check.
37  void registerMatchers(ast_matchers::MatchFinder *Finder) override final;
38  void
39  check(const ast_matchers::MatchFinder::MatchResult &Result) override final;
40  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
41  Preprocessor *ModuleExpanderPP) override final;
42  void onEndOfTranslationUnit() override final;
43 
44  /// Derived classes that override this function should call this method from
45  /// the overridden method.
46  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
47 
48  /// This enum will be used in %select of the diagnostic message.
49  /// Each value below IgnoreFailureThreshold should have an error message.
50  enum class ShouldFixStatus {
51  ShouldFix,
52 
53  /// The fixup will conflict with a language keyword,
54  /// so we can't fix it automatically.
56 
57  /// The fixup will conflict with a macro
58  /// definition, so we can't fix it
59  /// automatically.
61 
62  /// Values pass this threshold will be ignored completely
63  /// i.e no message, no fixup.
65 
66  /// If the identifier was used or declared within a macro we
67  /// won't offer a fixup for safety reasons.
69  };
70 
71  /// Information describing a failed check
72  struct FailureInfo {
73  std::string KindName; // Tag or misc info to be used as derived classes need
74  std::string Fixup; // The name that will be proposed as a fix-it hint
75  };
76 
77  /// Holds an identifier name check failure, tracking the kind of the
78  /// identifier, its possible fixup and the starting locations of all the
79  /// identifier usages.
82 
83  /// Whether the failure should be fixed or not.
84  ///
85  /// e.g.: if the identifier was used or declared within a macro we won't
86  /// offer a fixup for safety reasons.
87  bool ShouldFix() const {
88  return FixStatus == ShouldFixStatus::ShouldFix && !Info.Fixup.empty();
89  }
90 
91  bool ShouldNotify() const {
92  return FixStatus < ShouldFixStatus::IgnoreFailureThreshold;
93  }
94 
96 
97  /// A set of all the identifier usages starting SourceLocation, in
98  /// their encoded form.
99  llvm::DenseSet<unsigned> RawUsageLocs;
100 
101  NamingCheckFailure() = default;
102  };
103 
104  using NamingCheckId = std::pair<SourceLocation, std::string>;
105 
106  using NamingCheckFailureMap =
107  llvm::DenseMap<NamingCheckId, NamingCheckFailure>;
108 
109  /// Check Macros for style violations.
110  void checkMacro(SourceManager &sourceMgr, const Token &MacroNameTok,
111  const MacroInfo *MI);
112 
113  /// Add a usage of a macro if it already has a violation.
114  void expandMacro(const Token &MacroNameTok, const MacroInfo *MI);
115 
117  SourceRange Range, SourceManager *SourceMgr = nullptr);
118 
119  /// Convenience method when the usage to be added is a NamedDecl.
120  void addUsage(const NamedDecl *Decl, SourceRange Range,
121  SourceManager *SourceMgr = nullptr);
122 
123 protected:
124  /// Overridden by derived classes, returns information about if and how a Decl
125  /// failed the check. A 'None' result means the Decl did not fail the check.
126  virtual llvm::Optional<FailureInfo>
127  GetDeclFailureInfo(const NamedDecl *Decl, const SourceManager &SM) const = 0;
128 
129  /// Overridden by derived classes, returns information about if and how a
130  /// macro failed the check. A 'None' result means the macro did not fail the
131  /// check.
132  virtual llvm::Optional<FailureInfo>
133  GetMacroFailureInfo(const Token &MacroNameTok,
134  const SourceManager &SM) const = 0;
135 
136  /// Represents customized diagnostic text and how arguments should be applied.
137  /// Example usage:
138  ///
139  /// return DiagInfo{"my %1 very %2 special %3 text",
140  /// [=](DiagnosticBuilder &diag) {
141  /// diag << arg1 << arg2 << arg3;
142  /// }};
143  struct DiagInfo {
144  std::string Text;
145  llvm::unique_function<void(DiagnosticBuilder &)> ApplyArgs;
146  };
147 
148  /// Overridden by derived classes, returns a description of the diagnostic
149  /// that should be emitted for the given failure. The base class will then
150  /// further customize the diagnostic by adding info about whether the fix-it
151  /// can be automatically applied or not.
152  virtual DiagInfo GetDiagInfo(const NamingCheckId &ID,
153  const NamingCheckFailure &Failure) const = 0;
154 
155 private:
156  NamingCheckFailureMap NamingCheckFailures;
157  const bool AggressiveDependentMemberLookup;
158 };
159 
160 } // namespace tidy
161 } // namespace clang
162 
163 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
virtual DiagInfo GetDiagInfo(const NamingCheckId &ID, const NamingCheckFailure &Failure) const =0
Overridden by derived classes, returns a description of the diagnostic that should be emitted for the...
void expandMacro(const Token &MacroNameTok, const MacroInfo *MI)
Add a usage of a macro if it already has a violation.
const FunctionDecl * Decl
bool ShouldFix() const
Whether the failure should be fixed or not.
virtual llvm::Optional< FailureInfo > GetDeclFailureInfo(const NamedDecl *Decl, const SourceManager &SM) const =0
Overridden by derived classes, returns information about if and how a Decl failed the check...
Information describing a failed check.
llvm::SourceMgr * SourceMgr
Represents customized diagnostic text and how arguments should be applied.
std::pair< SourceLocation, std::string > NamingCheckId
llvm::DenseMap< NamingCheckId, NamingCheckFailure > NamingCheckFailureMap
Base class for all clang-tidy checks.
void addUsage(const RenamerClangTidyCheck::NamingCheckId &Decl, SourceRange Range, SourceManager *SourceMgr=nullptr)
llvm::DenseSet< unsigned > RawUsageLocs
A set of all the identifier usages starting SourceLocation, in their encoded form.
Values pass this threshold will be ignored completely i.e no message, no fixup.
virtual llvm::Optional< FailureInfo > GetMacroFailureInfo(const Token &MacroNameTok, const SourceManager &SM) const =0
Overridden by derived classes, returns information about if and how a macro failed the check...
If the identifier was used or declared within a macro we won&#39;t offer a fixup for safety reasons...
llvm::unique_function< void(DiagnosticBuilder &)> ApplyArgs
void check(const ast_matchers::MatchFinder::MatchResult &Result) override final
ClangTidyChecks that register ASTMatchers should do the actual work in here.
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Derived classes that override this function should call this method from the overridden method...
Holds an identifier name check failure, tracking the kind of the identifier, its possible fixup and t...
Base class for clang-tidy checks that want to flag declarations and/or macros for renaming based on c...
The fixup will conflict with a language keyword, so we can&#39;t fix it automatically.
The fixup will conflict with a macro definition, so we can&#39;t fix it automatically.
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override final
Override this to register PPCallbacks in the preprocessor.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context)
void checkMacro(SourceManager &sourceMgr, const Token &MacroNameTok, const MacroInfo *MI)
Check Macros for style violations.
CharSourceRange Range
SourceRange for the file name.
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
ShouldFixStatus
This enum will be used in select of the diagnostic message.
void registerMatchers(ast_matchers::MatchFinder *Finder) override final
Derived classes should not implement any matching logic themselves; this class will do the matching a...
std::map< std::string, ClangTidyValue > OptionMap