| Index: tools/clang/value_cleanup/ListValueRewriter.cpp
|
| diff --git a/tools/clang/value_cleanup/ListValueRewriter.cpp b/tools/clang/value_cleanup/ListValueRewriter.cpp
|
| index ce27dd1f5b41368ddbf1ac5eb19955ae67d3bee2..b5e5260eab1e6210d71425bb85079440e94f6246 100644
|
| --- a/tools/clang/value_cleanup/ListValueRewriter.cpp
|
| +++ b/tools/clang/value_cleanup/ListValueRewriter.cpp
|
| @@ -108,11 +108,39 @@ void ListValueRewriter::AppendStringCallback::run(
|
| AppendCallback::run(result);
|
| }
|
|
|
| +ListValueRewriter::AppendReleasedUniquePtrCallback::
|
| + AppendReleasedUniquePtrCallback(Replacements* replacements)
|
| + : replacements_(replacements) {}
|
| +
|
| +void ListValueRewriter::AppendReleasedUniquePtrCallback::run(
|
| + const MatchFinder::MatchResult& result) {
|
| + auto* object_expr = result.Nodes.getNodeAs<clang::Expr>("objectExpr");
|
| + bool arg_is_rvalue = object_expr->Classify(*result.Context).isRValue();
|
| +
|
| + // Remove .release()
|
| + auto* member_call =
|
| + result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("memberCall");
|
| + auto* member_expr = result.Nodes.getNodeAs<clang::MemberExpr>("memberExpr");
|
| + clang::CharSourceRange release_range = clang::CharSourceRange::getTokenRange(
|
| + member_expr->getOperatorLoc(), member_call->getLocEnd());
|
| + replacements_->emplace(*result.SourceManager, release_range,
|
| + arg_is_rvalue ? "" : ")");
|
| +
|
| + if (arg_is_rvalue)
|
| + return;
|
| +
|
| + // Insert `std::move(' for non-rvalue expressions.
|
| + clang::CharSourceRange insertion_range = clang::CharSourceRange::getCharRange(
|
| + object_expr->getLocStart(), object_expr->getLocStart());
|
| + replacements_->emplace(*result.SourceManager, insertion_range, "std::move(");
|
| +}
|
| +
|
| ListValueRewriter::ListValueRewriter(Replacements* replacements)
|
| : append_boolean_callback_(replacements),
|
| append_integer_callback_(replacements),
|
| append_double_callback_(replacements),
|
| - append_string_callback_(replacements) {}
|
| + append_string_callback_(replacements),
|
| + append_released_unique_ptr_callback_(replacements) {}
|
|
|
| void ListValueRewriter::RegisterMatchers(MatchFinder* match_finder) {
|
| auto is_list_append =
|
| @@ -191,4 +219,26 @@ void ListValueRewriter::RegisterMatchers(MatchFinder* match_finder) {
|
| argumentCountIs(1),
|
| hasArgument(0, id("argExpr", expr())))))))))),
|
| &append_string_callback_);
|
| +
|
| + auto is_unique_ptr_release =
|
| + allOf(callee(cxxMethodDecl(
|
| + hasName("release"),
|
| + ofClass(cxxRecordDecl(hasName("::std::unique_ptr"))))),
|
| + argumentCountIs(0));
|
| +
|
| + // base::ListValue::Append(ReturnsUniquePtr().release())
|
| + // => base::ListValue::Append(ReturnsUniquePtr())
|
| + // or
|
| + // base::ListValue::Append(unique_ptr_var.release())
|
| + // => base::ListValue::Append(std::move(unique_ptr_var))
|
| + match_finder->addMatcher(
|
| + cxxMemberCallExpr(
|
| + is_list_append,
|
| + hasArgument(
|
| + 0, ignoringParenImpCasts(
|
| + id("memberCall",
|
| + cxxMemberCallExpr(has(id("memberExpr", memberExpr())),
|
| + is_unique_ptr_release,
|
| + on(id("objectExpr", expr()))))))),
|
| + &append_released_unique_ptr_callback_);
|
| }
|
|
|