clang-tools  14.0.0git
TransformerClangTidyCheck.cpp
Go to the documentation of this file.
1 //===---------- TransformerClangTidyCheck.cpp - clang-tidy ----------------===//
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 
10 #include "clang/Lex/Preprocessor.h"
11 #include "llvm/ADT/STLExtras.h"
12 
13 namespace clang {
14 namespace tidy {
15 namespace utils {
16 using transformer::RewriteRule;
17 
18 #ifndef NDEBUG
19 static bool hasExplanation(const RewriteRule::Case &C) {
20  return C.Explanation != nullptr;
21 }
22 #endif
23 
24 static void verifyRule(const RewriteRule &Rule) {
25  assert(llvm::all_of(Rule.Cases, hasExplanation) &&
26  "clang-tidy checks must have an explanation by default;"
27  " explicitly provide an empty explanation if none is desired");
28 }
29 
31  ClangTidyContext *Context)
32  : ClangTidyCheck(Name, Context),
33  Inserter(
34  Options.getLocalOrGlobal("IncludeStyle", IncludeSorter::IS_LLVM)) {}
35 
36 // This constructor cannot dispatch to the simpler one (below), because, in
37 // order to get meaningful results from `getLangOpts` and `Options`, we need the
38 // `ClangTidyCheck()` constructor to have been called. If we were to dispatch,
39 // we would be accessing `getLangOpts` and `Options` before the underlying
40 // `ClangTidyCheck` instance was properly initialized.
42  std::function<Optional<RewriteRule>(const LangOptions &,
43  const OptionsView &)>
44  MakeRule,
45  StringRef Name, ClangTidyContext *Context)
46  : TransformerClangTidyCheck(Name, Context) {
47  if (Optional<RewriteRule> R = MakeRule(getLangOpts(), Options))
48  setRule(std::move(*R));
49 }
50 
52  StringRef Name,
53  ClangTidyContext *Context)
54  : TransformerClangTidyCheck(Name, Context) {
55  setRule(std::move(R));
56 }
57 
58 void TransformerClangTidyCheck::setRule(transformer::RewriteRule R) {
59  verifyRule(R);
60  Rule = std::move(R);
61 }
62 
64  const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
65  Inserter.registerPreprocessor(PP);
66 }
67 
69  ast_matchers::MatchFinder *Finder) {
70  if (!Rule.Cases.empty())
71  for (auto &Matcher : transformer::detail::buildMatchers(Rule))
72  Finder->addDynamicMatcher(Matcher, this);
73 }
74 
76  const ast_matchers::MatchFinder::MatchResult &Result) {
77  if (Result.Context->getDiagnostics().hasErrorOccurred())
78  return;
79 
80  RewriteRule::Case Case = transformer::detail::findSelectedCase(Result, Rule);
81  Expected<SmallVector<transformer::Edit, 1>> Edits = Case.Edits(Result);
82  if (!Edits) {
83  llvm::errs() << "Rewrite failed: " << llvm::toString(Edits.takeError())
84  << "\n";
85  return;
86  }
87 
88  // No rewrite applied, but no error encountered either.
89  if (Edits->empty())
90  return;
91 
92  Expected<std::string> Explanation = Case.Explanation->eval(Result);
93  if (!Explanation) {
94  llvm::errs() << "Error in explanation: "
95  << llvm::toString(Explanation.takeError()) << "\n";
96  return;
97  }
98 
99  // Associate the diagnostic with the location of the first change.
100  DiagnosticBuilder Diag = diag((*Edits)[0].Range.getBegin(), *Explanation);
101  for (const auto &T : *Edits)
102  switch (T.Kind) {
104  Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
105  break;
106  case transformer::EditKind::AddInclude:
107  Diag << Inserter.createIncludeInsertion(
108  Result.SourceManager->getFileID(T.Range.getBegin()), T.Replacement);
109  break;
110  }
111 }
112 
115  Options.store(Opts, "IncludeStyle", Inserter.getStyle());
116 }
117 
118 } // namespace utils
119 } // namespace tidy
120 } // namespace clang
Range
CharSourceRange Range
SourceRange for the file name.
Definition: IncludeOrderCheck.cpp:38
clang::tidy::ClangTidyOptions::OptionMap
llvm::StringMap< ClangTidyValue > OptionMap
Definition: ClangTidyOptions.h:115
clang::tidy::utils::IncludeSorter
Class used by IncludeInserterCallback to record the names of the inclusions in a given source file be...
Definition: IncludeSorter.h:23
TransformerClangTidyCheck.h
clang::tidy::utils::TransformerClangTidyCheck::check
void check(const ast_matchers::MatchFinder::MatchResult &Result) final
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Definition: TransformerClangTidyCheck.cpp:75
clang::tidy::utils::TransformerClangTidyCheck::setRule
void setRule(transformer::RewriteRule R)
Set the rule that this check implements.
Definition: TransformerClangTidyCheck.cpp:58
clang::tidy::utils::IncludeInserter::registerPreprocessor
void registerPreprocessor(Preprocessor *PP)
Registers this with the Preprocessor PP, must be called before this class is used.
Definition: IncludeInserter.cpp:42
clang::tidy::ClangTidyCheck
Base class for all clang-tidy checks.
Definition: ClangTidyCheck.h:54
clang::tidy::utils::TransformerClangTidyCheck::registerMatchers
void registerMatchers(ast_matchers::MatchFinder *Finder) final
Override this to register AST matchers with Finder.
Definition: TransformerClangTidyCheck.cpp:68
clang::tidy::ClangTidyCheck::getLangOpts
const LangOptions & getLangOpts() const
Returns the language options from the context.
Definition: ClangTidyCheck.h:420
clang::tidy::utils::TransformerClangTidyCheck::TransformerClangTidyCheck
TransformerClangTidyCheck(StringRef Name, ClangTidyContext *Context)
Definition: TransformerClangTidyCheck.cpp:30
clang::tidy::ClangTidyCheck::Options
OptionsView Options
Definition: ClangTidyCheck.h:416
clang::tidy::utils::verifyRule
static void verifyRule(const RewriteRule &Rule)
Definition: TransformerClangTidyCheck.cpp:24
clang::tidy::ClangTidyContext
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
Definition: ClangTidyDiagnosticConsumer.h:71
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:28
clang::tidy::utils::TransformerClangTidyCheck::registerPPCallbacks
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override
Override this to register PPCallbacks in the preprocessor.
Definition: TransformerClangTidyCheck.cpp:63
clang::tidy::ClangTidyCheck::diag
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Definition: ClangTidyCheck.cpp:25
clang::tidy::bugprone::PP
static Preprocessor * PP
Definition: BadSignalToKillThreadCheck.cpp:29
clang::tidy::utils::IncludeInserter::getStyle
IncludeSorter::IncludeStyle getStyle() const
Definition: IncludeInserter.h:84
clang::tidy::utils::TransformerClangTidyCheck
A base class for defining a ClangTidy check based on a RewriteRule.
Definition: TransformerClangTidyCheck.h:39
C
const Criteria C
Definition: FunctionCognitiveComplexityCheck.cpp:93
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::tidy::utils::TransformerClangTidyCheck::storeOptions
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Derived classes that override this function should call this method from the overridden method.
Definition: TransformerClangTidyCheck.cpp:113
clang::tidy::cppcoreguidelines::toString
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
Definition: SpecialMemberFunctionsCheck.cpp:55
clang::tidy::utils::IncludeInserter::createIncludeInsertion
llvm::Optional< FixItHint > createIncludeInsertion(FileID FileID, llvm::StringRef Header)
Creates a Header inclusion directive fixit in the File FileID.
Definition: IncludeInserter.cpp:70
SM
const SourceManager & SM
Definition: IncludeCleaner.cpp:140
clang::tidy::ClangTidyCheck::OptionsView::store
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, StringRef Value) const
Stores an option with the check-local name LocalName with string value Value to Options.
Definition: ClangTidyCheck.cpp:120
clang::tidy::utils::hasExplanation
static bool hasExplanation(const RewriteRule::Case &C)
Definition: TransformerClangTidyCheck.cpp:19