11 #include "../utils/FixItHintUtils.h" 12 #include "clang/AST/ASTContext.h" 13 #include "clang/ASTMatchers/ASTMatchFinder.h" 14 #include "clang/Frontend/CompilerInstance.h" 15 #include "clang/Lex/Preprocessor.h" 16 #include "clang/Tooling/FixIt.h" 24 ReplaceRandomShuffleCheck::ReplaceRandomShuffleCheck(StringRef
Name,
27 IncludeStyle(utils::IncludeSorter::parseIncludeStyle(
28 Options.getLocalOrGlobal(
"IncludeStyle",
"llvm"))) {}
34 const auto Begin = hasArgument(0, expr());
35 const auto End = hasArgument(1, expr());
36 const auto RandomFunc = hasArgument(2, expr().bind(
"randomFunc"));
38 callExpr(anyOf(allOf(Begin, End, argumentCountIs(2)),
39 allOf(Begin, End, RandomFunc, argumentCountIs(3))),
40 hasDeclaration(functionDecl(hasName(
"::std::random_shuffle"))),
41 has(implicitCastExpr(has(declRefExpr().bind(
"name")))))
47 CompilerInstance &Compiler) {
48 IncludeInserter = llvm::make_unique<utils::IncludeInserter>(
49 Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle);
50 Compiler.getPreprocessor().addPPCallbacks(
51 IncludeInserter->CreatePPCallbacks());
61 const auto *MatchedDecl = Result.Nodes.getNodeAs<DeclRefExpr>(
"name");
62 const auto *MatchedArgumentThree = Result.Nodes.getNodeAs<Expr>(
"randomFunc");
63 const auto *MatchedCallExpr = Result.Nodes.getNodeAs<CallExpr>(
"match");
65 if (MatchedCallExpr->getLocStart().isMacroID())
69 if (MatchedCallExpr->getNumArgs() == 3) {
71 diag(MatchedCallExpr->getLocStart(),
72 "'std::random_shuffle' has been removed in C++17; use " 73 "'std::shuffle' and an alternative random mechanism instead");
74 DiagL << FixItHint::CreateReplacement(
75 MatchedArgumentThree->getSourceRange(),
76 "std::mt19937(std::random_device()())");
79 auto DiagL =
diag(MatchedCallExpr->getLocStart(),
80 "'std::random_shuffle' has been removed in C++17; use " 81 "'std::shuffle' instead");
82 DiagL << FixItHint::CreateInsertion(
83 MatchedCallExpr->getRParenLoc(),
84 ", std::mt19937(std::random_device()())");
89 std::string NewName =
"shuffle";
90 StringRef ContainerText = Lexer::getSourceText(
91 CharSourceRange::getTokenRange(MatchedDecl->getSourceRange()),
93 if (ContainerText.startswith(
"std::"))
94 NewName =
"std::" + NewName;
96 Diag << FixItHint::CreateRemoval(MatchedDecl->getSourceRange());
97 Diag << FixItHint::CreateInsertion(MatchedDecl->getLocStart(), NewName);
99 if (Optional<FixItHint> IncludeFixit =
100 IncludeInserter->CreateIncludeInsertion(
101 Result.Context->getSourceManager().getFileID(
102 MatchedCallExpr->getLocStart()),
104 Diag << IncludeFixit.getValue();
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.
LangOptions getLangOpts() const
Returns the language options from the context.
static StringRef toString(IncludeStyle Style)
Converts IncludeStyle to string representation.
Base class for all clang-tidy checks.
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Should store all options supported by this check with their current values or default values for opti...
std::map< std::string, std::string > OptionMap
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
void registerPPCallbacks(CompilerInstance &Compiler) override
Override this to register PPCallbacks with Compiler.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.