67 lines
2.5 KiB
C++
67 lines
2.5 KiB
C++
//===--- UniqueptrResetRelease.cpp - clang-tidy ---------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "UniqueptrResetRelease.h"
|
|
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
|
#include "clang/Lex/Lexer.h"
|
|
|
|
using namespace clang::ast_matchers;
|
|
|
|
namespace clang {
|
|
namespace tidy {
|
|
|
|
void UniqueptrResetRelease::registerMatchers(MatchFinder *Finder) {
|
|
Finder->addMatcher(
|
|
memberCallExpr(
|
|
on(expr().bind("left")), callee(memberExpr().bind("reset_member")),
|
|
callee(methodDecl(hasName("reset"),
|
|
ofClass(hasName("::std::unique_ptr")))),
|
|
has(memberCallExpr(
|
|
on(expr().bind("right")),
|
|
callee(memberExpr().bind("release_member")),
|
|
callee(methodDecl(hasName("release"),
|
|
ofClass(hasName("::std::unique_ptr")))))))
|
|
.bind("reset_call"),
|
|
this);
|
|
}
|
|
|
|
void UniqueptrResetRelease::check(const MatchFinder::MatchResult &Result) {
|
|
const auto *ResetMember = Result.Nodes.getNodeAs<MemberExpr>("reset_member");
|
|
const auto *ReleaseMember =
|
|
Result.Nodes.getNodeAs<MemberExpr>("release_member");
|
|
const auto *Right = Result.Nodes.getNodeAs<Expr>("right");
|
|
const auto *Left = Result.Nodes.getNodeAs<Expr>("left");
|
|
const auto *ResetCall =
|
|
Result.Nodes.getNodeAs<CXXMemberCallExpr>("reset_call");
|
|
|
|
std::string LeftText = clang::Lexer::getSourceText(
|
|
CharSourceRange::getTokenRange(Left->getSourceRange()),
|
|
*Result.SourceManager, Result.Context->getLangOpts());
|
|
std::string RightText = clang::Lexer::getSourceText(
|
|
CharSourceRange::getTokenRange(Right->getSourceRange()),
|
|
*Result.SourceManager, Result.Context->getLangOpts());
|
|
|
|
if (ResetMember->isArrow())
|
|
LeftText = "*" + LeftText;
|
|
if (ReleaseMember->isArrow())
|
|
RightText = "*" + RightText;
|
|
// Even if x was rvalue, *x is not rvalue anymore.
|
|
if (!Right->isRValue() || ReleaseMember->isArrow())
|
|
RightText = "std::move(" + RightText + ")";
|
|
std::string NewText = LeftText + " = " + RightText;
|
|
|
|
diag(ResetMember->getExprLoc(),
|
|
"prefer ptr1 = std::move(ptr2) over ptr1.reset(ptr2.release())")
|
|
<< FixItHint::CreateReplacement(
|
|
CharSourceRange::getTokenRange(ResetCall->getSourceRange()), NewText);
|
|
}
|
|
|
|
} // namespace tidy
|
|
} // namespace clang
|