11 #include "clang/AST/ASTContext.h" 12 #include "clang/ASTMatchers/ASTMatchFinder.h" 13 #include "clang/Frontend/CompilerInstance.h" 14 #include "clang/Lex/Lexer.h" 15 #include "clang/Lex/Preprocessor.h" 17 using namespace clang;
24 static const char AutoPtrTokenId[] =
"AutoPrTokenId";
25 static const char AutoPtrOwnershipTransferId[] =
"AutoPtrOwnershipTransferId";
36 AST_MATCHER(Expr, isLValue) {
return Node.getValueKind() == VK_LValue; }
59 const DeclContext *D = Node.getDeclContext();
61 while (D->isInlineNamespace())
64 if (!D->isNamespace() || !D->getParent()->isTranslationUnit())
67 const IdentifierInfo *
Info = cast<NamespaceDecl>(D)->getIdentifier();
69 return (Info && Info->isStr(
"std"));
72 ReplaceAutoPtrCheck::ReplaceAutoPtrCheck(StringRef
Name,
73 ClangTidyContext *Context)
74 : ClangTidyCheck(Name, Context),
75 IncludeStyle(utils::IncludeSorter::parseIncludeStyle(
76 Options.getLocalOrGlobal(
"IncludeStyle",
"llvm"))) {}
89 auto AutoPtrDecl = recordDecl(hasName(
"auto_ptr"), isFromStdNamespace());
90 auto AutoPtrType = qualType(hasDeclaration(AutoPtrDecl));
100 Finder->addMatcher(typeLoc(loc(qualType(AutoPtrType,
103 unless(elaboratedType()))))
104 .bind(AutoPtrTokenId),
109 Finder->addMatcher(usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(allOf(
110 hasName(
"auto_ptr"), isFromStdNamespace()))))
111 .bind(AutoPtrTokenId),
120 auto MovableArgumentMatcher =
121 expr(isLValue(), hasType(AutoPtrType)).bind(AutoPtrOwnershipTransferId);
124 cxxOperatorCallExpr(hasOverloadedOperatorName(
"="),
125 callee(cxxMethodDecl(ofClass(AutoPtrDecl))),
126 hasArgument(1, MovableArgumentMatcher)),
128 Finder->addMatcher(cxxConstructExpr(hasType(AutoPtrType), argumentCountIs(1),
129 hasArgument(0, MovableArgumentMatcher)),
139 Inserter.reset(
new utils::IncludeInserter(
140 Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle));
141 Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
145 SourceManager &SM = *Result.SourceManager;
147 Result.Nodes.getNodeAs<Expr>(AutoPtrOwnershipTransferId)) {
148 CharSourceRange
Range = Lexer::makeFileCharRange(
149 CharSourceRange::getTokenRange(E->getSourceRange()), SM, LangOptions());
151 if (Range.isInvalid())
154 auto Diag =
diag(Range.getBegin(),
"use std::move to transfer ownership")
155 << FixItHint::CreateInsertion(Range.getBegin(),
"std::move(")
156 << FixItHint::CreateInsertion(Range.getEnd(),
")");
159 Inserter->CreateIncludeInsertion(SM.getMainFileID(),
"utility",
166 SourceLocation AutoPtrLoc;
167 if (
const auto *TL = Result.Nodes.getNodeAs<TypeLoc>(AutoPtrTokenId)) {
170 if (
auto Loc = TL->getAs<TemplateSpecializationTypeLoc>())
171 AutoPtrLoc =
Loc.getTemplateNameLoc();
172 }
else if (
const auto *D =
173 Result.Nodes.getNodeAs<UsingDecl>(AutoPtrTokenId)) {
176 AutoPtrLoc = D->getNameInfo().getBeginLoc();
178 llvm_unreachable(
"Bad Callback. No node provided.");
181 if (AutoPtrLoc.isMacroID())
182 AutoPtrLoc = SM.getSpellingLoc(AutoPtrLoc);
186 if (StringRef(SM.getCharacterData(AutoPtrLoc), strlen(
"auto_ptr")) !=
190 SourceLocation EndLoc =
191 AutoPtrLoc.getLocWithOffset(strlen(
"auto_ptr") - 1);
192 diag(AutoPtrLoc,
"auto_ptr is deprecated, use unique_ptr instead")
193 << FixItHint::CreateReplacement(SourceRange(AutoPtrLoc, EndLoc),
SourceLocation Loc
'#' location in the include directive
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.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
std::map< std::string, std::string > OptionMap
void registerPPCallbacks(CompilerInstance &Compiler) override
Override this to register PPCallbacks with Compiler.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
CharSourceRange Range
SourceRange for the file name.
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Should store all options supported by this check with their current values or default values for opti...
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))
AST_MATCHER(VarDecl, isAsm)
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.