10 #include "llvm/ADT/STLExtras.h" 15 using tooling::RewriteRule;
19 return C.Explanation !=
nullptr;
29 std::function<Optional<RewriteRule>(
const LangOptions &,
33 :
ClangTidyCheck(Name, Context), Rule(MakeRule(getLangOpts(), Options)) {
36 "clang-tidy checks must have an explanation by default;" 37 " explicitly provide an empty explanation if none is desired");
45 "clang-tidy checks must have an explanation by default;" 46 " explicitly provide an empty explanation if none is desired");
50 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
53 if (Rule && llvm::any_of(Rule->Cases, [](
const RewriteRule::Case &C) {
54 return !C.AddedIncludes.empty();
56 Inserter = llvm::make_unique<IncludeInserter>(
58 PP->addPPCallbacks(Inserter->CreatePPCallbacks());
63 ast_matchers::MatchFinder *Finder) {
65 Finder->addDynamicMatcher(tooling::detail::buildMatcher(*Rule),
this);
69 const ast_matchers::MatchFinder::MatchResult &
Result) {
70 if (Result.Context->getDiagnostics().hasErrorOccurred())
74 const ast_matchers::BoundNodes::IDToNodeMap &NodesMap = Result.Nodes.getMap();
75 auto Root = NodesMap.find(RewriteRule::RootID);
76 assert(Root != NodesMap.end() &&
"Transformation failed: missing root node.");
77 SourceLocation RootLoc = Result.SourceManager->getExpansionLoc(
78 Root->second.getSourceRange().getBegin());
79 assert(RootLoc.isValid() &&
"Invalid location for Root node of match.");
81 assert(Rule &&
"check() should not fire if Rule is None");
82 RewriteRule::Case Case = tooling::detail::findSelectedCase(Result, *Rule);
83 Expected<SmallVector<tooling::detail::Transformation, 1>> Transformations =
84 tooling::detail::translateEdits(Result, Case.Edits);
85 if (!Transformations) {
86 llvm::errs() <<
"Rewrite failed: " 92 if (Transformations->empty())
95 Expected<std::string> Explanation = Case.Explanation(Result);
97 llvm::errs() <<
"Error in explanation: " 101 DiagnosticBuilder Diag =
diag(RootLoc, *Explanation);
102 for (
const auto &T : *Transformations) {
103 Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
106 for (
const auto &I : Case.AddedIncludes) {
107 auto &Header = I.first;
108 if (Optional<FixItHint>
Fix = Inserter->CreateIncludeInsertion(
109 Result.SourceManager->getMainFileID(), Header,
110 I.second == tooling::IncludeFormat::Angled)) {
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
Base class for all clang-tidy checks.
const LangOptions & getLangOpts() const
Returns the language options from the context.
static bool hasExplanation(const RewriteRule::Case &C)
static constexpr llvm::StringLiteral Name
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
static cl::opt< bool > Fix("fix", cl::desc(R"(
Apply suggested fixes. Without -fix-errors
clang-tidy will bail out if any compilation
errors were found.
)"), cl::init(false), cl::cat(ClangTidyCategory))
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.