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;
25 static const char AutoPtrTokenId[] =
"AutoPrTokenId";
26 static const char AutoPtrOwnershipTransferId[] =
"AutoPtrOwnershipTransferId";
37 AST_MATCHER(Expr, isLValue) {
return Node.getValueKind() == VK_LValue; }
60 const DeclContext *D = Node.getDeclContext();
62 while (D->isInlineNamespace())
65 if (!D->isNamespace() || !D->getParent()->isTranslationUnit())
68 const IdentifierInfo *
Info = cast<NamespaceDecl>(D)->getIdentifier();
70 return (Info && Info->isStr(
"std"));
75 ReplaceAutoPtrCheck::ReplaceAutoPtrCheck(StringRef
Name,
76 ClangTidyContext *Context)
77 : ClangTidyCheck(Name, Context),
78 IncludeStyle(utils::IncludeSorter::parseIncludeStyle(
79 Options.getLocalOrGlobal(
"IncludeStyle",
"llvm"))) {}
81 void ReplaceAutoPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
82 Options.store(Opts,
"IncludeStyle",
86 void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
89 if (!getLangOpts().CPlusPlus)
92 auto AutoPtrDecl = recordDecl(hasName(
"auto_ptr"), isFromStdNamespace());
93 auto AutoPtrType = qualType(hasDeclaration(AutoPtrDecl));
103 Finder->addMatcher(typeLoc(loc(qualType(AutoPtrType,
106 unless(elaboratedType()))))
107 .bind(AutoPtrTokenId),
112 Finder->addMatcher(usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(allOf(
113 hasName(
"auto_ptr"), isFromStdNamespace()))))
114 .bind(AutoPtrTokenId),
123 auto MovableArgumentMatcher =
124 expr(isLValue(), hasType(AutoPtrType)).bind(AutoPtrOwnershipTransferId);
127 cxxOperatorCallExpr(hasOverloadedOperatorName(
"="),
128 callee(cxxMethodDecl(ofClass(AutoPtrDecl))),
129 hasArgument(1, MovableArgumentMatcher)),
131 Finder->addMatcher(cxxConstructExpr(hasType(AutoPtrType), argumentCountIs(1),
132 hasArgument(0, MovableArgumentMatcher)),
136 void ReplaceAutoPtrCheck::registerPPCallbacks(CompilerInstance &Compiler) {
140 if (!getLangOpts().CPlusPlus)
142 Inserter.reset(
new utils::IncludeInserter(
143 Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle));
144 Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
147 void ReplaceAutoPtrCheck::check(
const MatchFinder::MatchResult &Result) {
148 SourceManager &SM = *Result.SourceManager;
150 Result.Nodes.getNodeAs<Expr>(AutoPtrOwnershipTransferId)) {
151 CharSourceRange
Range = Lexer::makeFileCharRange(
152 CharSourceRange::getTokenRange(E->getSourceRange()), SM, LangOptions());
154 if (Range.isInvalid())
157 auto Diag = diag(Range.getBegin(),
"use std::move to transfer ownership")
158 << FixItHint::CreateInsertion(Range.getBegin(),
"std::move(")
159 << FixItHint::CreateInsertion(Range.getEnd(),
")");
162 Inserter->CreateIncludeInsertion(SM.getMainFileID(),
"utility",
169 SourceLocation AutoPtrLoc;
170 if (
const auto *TL = Result.Nodes.getNodeAs<TypeLoc>(AutoPtrTokenId)) {
173 if (
auto Loc = TL->getAs<TemplateSpecializationTypeLoc>())
174 AutoPtrLoc =
Loc.getTemplateNameLoc();
175 }
else if (
const auto *D =
176 Result.Nodes.getNodeAs<UsingDecl>(AutoPtrTokenId)) {
179 AutoPtrLoc = D->getNameInfo().getBeginLoc();
181 llvm_unreachable(
"Bad Callback. No node provided.");
184 if (AutoPtrLoc.isMacroID())
185 AutoPtrLoc = SM.getSpellingLoc(AutoPtrLoc);
189 if (StringRef(SM.getCharacterData(AutoPtrLoc), strlen(
"auto_ptr")) !=
193 SourceLocation EndLoc =
194 AutoPtrLoc.getLocWithOffset(strlen(
"auto_ptr") - 1);
195 diag(AutoPtrLoc,
"auto_ptr is deprecated, use unique_ptr instead")
196 << FixItHint::CreateReplacement(SourceRange(AutoPtrLoc, EndLoc),
SourceLocation Loc
'#' location in the include directive
AST_MATCHER(BinaryOperator, isAssignmentOperator)
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
CharSourceRange Range
SourceRange for the file name.
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))