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 |