| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // Clang tool to change calls to scoper::Pass() to just use std::move(). | 5 // Clang tool to change calls to scoper::Pass() to just use std::move(). |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "clang/AST/ASTContext.h" | 10 #include "clang/AST/ASTContext.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 : replacements_(replacements) {} | 34 : replacements_(replacements) {} |
| 35 virtual void run(const MatchFinder::MatchResult& result) override; | 35 virtual void run(const MatchFinder::MatchResult& result) override; |
| 36 | 36 |
| 37 private: | 37 private: |
| 38 Replacements* const replacements_; | 38 Replacements* const replacements_; |
| 39 }; | 39 }; |
| 40 | 40 |
| 41 void RewriterCallback::run(const MatchFinder::MatchResult& result) { | 41 void RewriterCallback::run(const MatchFinder::MatchResult& result) { |
| 42 const clang::CXXMemberCallExpr* call_expr = | 42 const clang::CXXMemberCallExpr* call_expr = |
| 43 result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("expr"); | 43 result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("expr"); |
| 44 const bool is_arrow = | 44 const clang::MemberExpr* callee = |
| 45 clang::dyn_cast<clang::MemberExpr>(call_expr->getCallee())->isArrow(); | 45 clang::dyn_cast<clang::MemberExpr>(call_expr->getCallee()); |
| 46 const bool is_arrow = callee->isArrow(); |
| 46 const clang::Expr* arg = result.Nodes.getNodeAs<clang::Expr>("arg"); | 47 const clang::Expr* arg = result.Nodes.getNodeAs<clang::Expr>("arg"); |
| 47 | 48 |
| 48 clang::CharSourceRange arg_range = clang::CharSourceRange::getTokenRange( | 49 const char kMoveRefText[] = "std::move("; |
| 49 result.SourceManager->getSpellingLoc(arg->getLocStart()), | 50 const char kMovePtrText[] = "std::move(*"; |
| 50 result.SourceManager->getSpellingLoc(arg->getLocEnd())); | |
| 51 std::string new_source_text = "std::move("; | |
| 52 if (is_arrow) | |
| 53 new_source_text += "*"; | |
| 54 llvm::StringRef arg_text = clang::Lexer::getSourceText( | |
| 55 arg_range, *result.SourceManager, result.Context->getLangOpts()); | |
| 56 new_source_text.append(arg_text.data(), arg_text.size()); | |
| 57 new_source_text += ")"; | |
| 58 | 51 |
| 59 // Replace the entire original expression with std::move(arg). | 52 replacements_->emplace(*result.SourceManager, |
| 60 clang::CharSourceRange expr_range = clang::CharSourceRange::getTokenRange( | 53 result.SourceManager->getSpellingLoc( |
| 61 result.SourceManager->getSpellingLoc(call_expr->getLocStart()), | 54 arg->getLocStart()), |
| 62 result.SourceManager->getSpellingLoc(call_expr->getLocEnd())); | 55 0, |
| 63 replacements_->emplace(*result.SourceManager, expr_range, new_source_text); | 56 is_arrow ? kMovePtrText : kMoveRefText); |
| 57 |
| 58 // Delete everything but the closing parentheses from the original call to |
| 59 // Pass(): the closing parantheses is left to match up with the parantheses |
| 60 // just inserted with std::move. |
| 61 replacements_->emplace(*result.SourceManager, |
| 62 clang::CharSourceRange::getCharRange( |
| 63 result.SourceManager->getSpellingLoc( |
| 64 callee->getOperatorLoc()), |
| 65 result.SourceManager->getSpellingLoc( |
| 66 call_expr->getRParenLoc())), |
| 67 ""); |
| 64 } | 68 } |
| 65 | 69 |
| 66 } // namespace | 70 } // namespace |
| 67 | 71 |
| 68 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); | 72 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); |
| 69 | 73 |
| 70 int main(int argc, const char* argv[]) { | 74 int main(int argc, const char* argv[]) { |
| 71 // TODO(dcheng): Clang tooling should do this itself. | 75 // TODO(dcheng): Clang tooling should do this itself. |
| 72 // http://llvm.org/bugs/show_bug.cgi?id=21627 | 76 // http://llvm.org/bugs/show_bug.cgi?id=21627 |
| 73 llvm::InitializeNativeTarget(); | 77 llvm::InitializeNativeTarget(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 101 for (const auto& r : replacements) { | 105 for (const auto& r : replacements) { |
| 102 std::string replacement_text = r.getReplacementText().str(); | 106 std::string replacement_text = r.getReplacementText().str(); |
| 103 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); | 107 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); |
| 104 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() | 108 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() |
| 105 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; | 109 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; |
| 106 } | 110 } |
| 107 llvm::outs() << "==== END EDITS ====\n"; | 111 llvm::outs() << "==== END EDITS ====\n"; |
| 108 | 112 |
| 109 return 0; | 113 return 0; |
| 110 } | 114 } |
| OLD | NEW |