10 #include "clang/AST/ASTContext.h" 11 #include "clang/ASTMatchers/ASTMatchFinder.h" 12 #include "clang/Frontend/CompilerInstance.h" 13 #include "clang/Lex/Lexer.h" 14 #include "clang/Lex/Preprocessor.h" 16 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"));
74 ReplaceAutoPtrCheck::ReplaceAutoPtrCheck(StringRef
Name,
75 ClangTidyContext *Context)
76 : ClangTidyCheck(Name, Context),
77 IncludeStyle(utils::IncludeSorter::parseIncludeStyle(
78 Options.getLocalOrGlobal(
"IncludeStyle",
"llvm"))) {}
80 void ReplaceAutoPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
81 Options.store(Opts,
"IncludeStyle",
85 void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
88 if (!getLangOpts().CPlusPlus)
91 auto AutoPtrDecl = recordDecl(hasName(
"auto_ptr"), isFromStdNamespace());
92 auto AutoPtrType = qualType(hasDeclaration(AutoPtrDecl));
102 Finder->addMatcher(typeLoc(loc(qualType(AutoPtrType,
105 unless(elaboratedType()))))
106 .bind(AutoPtrTokenId),
111 Finder->addMatcher(usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(namedDecl(
112 hasName(
"auto_ptr"), isFromStdNamespace()))))
113 .bind(AutoPtrTokenId),
122 auto MovableArgumentMatcher =
123 expr(isLValue(), hasType(AutoPtrType)).bind(AutoPtrOwnershipTransferId);
126 cxxOperatorCallExpr(hasOverloadedOperatorName(
"="),
127 callee(cxxMethodDecl(ofClass(AutoPtrDecl))),
128 hasArgument(1, MovableArgumentMatcher)),
130 Finder->addMatcher(cxxConstructExpr(hasType(AutoPtrType), argumentCountIs(1),
131 hasArgument(0, MovableArgumentMatcher)),
135 void ReplaceAutoPtrCheck::registerPPCallbacks(
const SourceManager &SM,
137 Preprocessor *ModuleExpanderPP) {
141 if (!getLangOpts().CPlusPlus)
143 Inserter = llvm::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
145 PP->addPPCallbacks(Inserter->CreatePPCallbacks());
148 void ReplaceAutoPtrCheck::check(
const MatchFinder::MatchResult &
Result) {
149 SourceManager &SM = *Result.SourceManager;
151 Result.Nodes.getNodeAs<Expr>(AutoPtrOwnershipTransferId)) {
152 CharSourceRange
Range = Lexer::makeFileCharRange(
155 if (Range.isInvalid())
158 auto Diag = diag(Range.getBegin(),
"use std::move to transfer ownership")
159 << FixItHint::CreateInsertion(Range.getBegin(),
"std::move(")
160 << FixItHint::CreateInsertion(Range.getEnd(),
")");
163 Inserter->CreateIncludeInsertion(SM.getMainFileID(),
"utility",
170 SourceLocation AutoPtrLoc;
171 if (
const auto *TL = Result.Nodes.getNodeAs<TypeLoc>(AutoPtrTokenId)) {
174 if (
auto Loc = TL->getAs<TemplateSpecializationTypeLoc>())
175 AutoPtrLoc =
Loc.getTemplateNameLoc();
176 }
else if (
const auto *D =
177 Result.Nodes.getNodeAs<UsingDecl>(AutoPtrTokenId)) {
180 AutoPtrLoc = D->getNameInfo().getBeginLoc();
182 llvm_unreachable(
"Bad Callback. No node provided.");
185 if (AutoPtrLoc.isMacroID())
186 AutoPtrLoc = SM.getSpellingLoc(AutoPtrLoc);
190 if (StringRef(SM.getCharacterData(AutoPtrLoc), strlen(
"auto_ptr")) !=
194 SourceLocation EndLoc =
195 AutoPtrLoc.getLocWithOffset(strlen(
"auto_ptr") - 1);
196 diag(AutoPtrLoc,
"auto_ptr is deprecated, use unique_ptr instead")
197 << FixItHint::CreateReplacement(SourceRange(AutoPtrLoc, EndLoc),
SourceLocation Loc
'#' location in the include directive
AST_MATCHER(Expr, isMacroID)
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
static constexpr llvm::StringLiteral Name
llvm::Optional< Range > getTokenRange(const SourceManager &SM, const LangOptions &LangOpts, SourceLocation TokLoc)
Returns the taken range at TokLoc.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
CharSourceRange Range
SourceRange for the file name.
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))