10#include "clang/Basic/DiagnosticIDs.h"
11#include "clang/Lex/Preprocessor.h"
12#include "llvm/ADT/STLExtras.h"
16using transformer::RewriteRuleWith;
19static bool hasGenerator(
const transformer::Generator<std::string> &G) {
24static void verifyRule(
const RewriteRuleWith<std::string> &Rule) {
26 "clang-tidy checks must have an explanation by default;"
27 " explicitly provide an empty explanation if none is desired");
36 auto Pos = ToEscape.find(
'%');
37 if (
Pos == std::string::npos)
41 Result.reserve(ToEscape.size());
44 Result.append(ToEscape, 0,
Pos);
47 for (
auto N = ToEscape.size();
Pos < N; ++
Pos) {
48 const char C = ToEscape.at(
Pos);
60 Inserter(Options.getLocalOrGlobal(
"IncludeStyle",
IncludeSorter::IS_LLVM),
61 areDiagsSelfContained()) {}
69 std::function<std::optional<RewriteRuleWith<std::string>>(
70 const LangOptions &,
const OptionsView &)>
74 if (std::optional<RewriteRuleWith<std::string>> R =
81 : TransformerClangTidyCheck(
Name, Context) {
86 transformer::RewriteRuleWith<std::string> R) {
92 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
97 ast_matchers::MatchFinder *Finder) {
98 if (!Rule.Cases.empty())
99 for (
auto &Matcher : transformer::detail::buildMatchers(Rule))
100 Finder->addDynamicMatcher(Matcher,
this);
104 const ast_matchers::MatchFinder::MatchResult &Result) {
105 if (Result.Context->getDiagnostics().hasErrorOccurred())
108 size_t I = transformer::detail::findSelectedCase(Result, Rule);
109 Expected<SmallVector<transformer::Edit, 1>> Edits =
110 Rule.Cases[I].Edits(Result);
112 llvm::errs() <<
"Rewrite failed: " << llvm::toString(Edits.takeError())
121 Expected<std::string> Explanation = Rule.Metadata[I]->eval(Result);
123 llvm::errs() <<
"Error in explanation: "
124 << llvm::toString(Explanation.takeError()) <<
"\n";
130 DiagnosticBuilder Diag =
132 for (
const auto &T : *Edits) {
134 case transformer::EditKind::Range:
135 Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
137 case transformer::EditKind::AddInclude:
139 Result.SourceManager->getFileID(T.Range.getBegin()), T.Replacement);
145 for (
const auto &T : *Edits) {
146 if (!T.Note.empty()) {
148 DiagnosticIDs::Note);
llvm::SmallString< 256U > Name
CharSourceRange Range
SourceRange for the file name.
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.
Base class for all clang-tidy checks.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
const LangOptions & getLangOpts() const
Returns the language options from the context.
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
void registerPreprocessor(Preprocessor *PP)
Registers this with the Preprocessor PP, must be called before this class is used.
std::optional< FixItHint > createIncludeInsertion(FileID FileID, llvm::StringRef Header)
Creates a Header inclusion directive fixit in the File FileID.
IncludeSorter::IncludeStyle getStyle() const
Class used by IncludeInserterCallback to record the names of the inclusions in a given source file be...
std::string escapeForDiagnostic(std::string ToEscape)
static bool hasGenerator(const transformer::Generator< std::string > &G)
static void verifyRule(const RewriteRuleWith< std::string > &Rule)
llvm::StringMap< ClangTidyValue > OptionMap