//===--- 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("reset_member"); const auto *ReleaseMember = Result.Nodes.getNodeAs("release_member"); const auto *Right = Result.Nodes.getNodeAs("right"); const auto *Left = Result.Nodes.getNodeAs("left"); const auto *ResetCall = Result.Nodes.getNodeAs("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