OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 // This implements a Clang tool to convert all instances of std::string("") to | 5 // This implements a Clang tool to convert all instances of std::string("") to |
6 // std::string(). The latter is more efficient (as std::string doesn't have to | 6 // std::string(). The latter is more efficient (as std::string doesn't have to |
7 // take a copy of an empty string) and generates fewer instructions as well. It | 7 // take a copy of an empty string) and generates fewer instructions as well. It |
8 // should be run using the tools/clang/scripts/run_tool.py helper. | 8 // should be run using the tools/clang/scripts/run_tool.py helper. |
9 | 9 |
10 #include "clang/ASTMatchers/ASTMatchers.h" | 10 #include "clang/ASTMatchers/ASTMatchers.h" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 | 89 |
90 void SetupMatchers(MatchFinder* match_finder); | 90 void SetupMatchers(MatchFinder* match_finder); |
91 | 91 |
92 private: | 92 private: |
93 ConstructorCallback constructor_callback_; | 93 ConstructorCallback constructor_callback_; |
94 InitializerCallback initializer_callback_; | 94 InitializerCallback initializer_callback_; |
95 TemporaryCallback temporary_callback_; | 95 TemporaryCallback temporary_callback_; |
96 }; | 96 }; |
97 | 97 |
98 void EmptyStringConverter::SetupMatchers(MatchFinder* match_finder) { | 98 void EmptyStringConverter::SetupMatchers(MatchFinder* match_finder) { |
99 const auto& constructor_call = | 99 const clang::ast_matchers::StatementMatcher& constructor_call = |
100 id("call", | 100 id("call", |
101 constructExpr( | 101 constructExpr( |
102 hasDeclaration(methodDecl(ofClass(hasName("std::basic_string")))), | 102 hasDeclaration(methodDecl(ofClass(hasName("std::basic_string")))), |
103 argumentCountIs(2), | 103 argumentCountIs(2), |
104 hasArgument(0, id("literal", stringLiteral())), | 104 hasArgument(0, id("literal", stringLiteral())), |
105 hasArgument(1, defaultArgExpr()))); | 105 hasArgument(1, defaultArgExpr()))); |
106 | 106 |
107 // Note that expr(has()) in the matcher is significant; the Clang AST wraps | 107 // Note that expr(has()) in the matcher is significant; the Clang AST wraps |
108 // calls to the std::string constructor with exprWithCleanups nodes. Without | 108 // calls to the std::string constructor with exprWithCleanups nodes. Without |
109 // the expr(has()) matcher, the first and last rules would not match anything! | 109 // the expr(has()) matcher, the first and last rules would not match anything! |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 int result = | 182 int result = |
183 tool.run(clang::tooling::newFrontendActionFactory(&match_finder)); | 183 tool.run(clang::tooling::newFrontendActionFactory(&match_finder)); |
184 if (result != 0) | 184 if (result != 0) |
185 return result; | 185 return result; |
186 | 186 |
187 // Each replacement line should have the following format: | 187 // Each replacement line should have the following format: |
188 // r:<file path>:<offset>:<length>:<replacement text> | 188 // r:<file path>:<offset>:<length>:<replacement text> |
189 // Only the <replacement text> field can contain embedded ":" characters. | 189 // Only the <replacement text> field can contain embedded ":" characters. |
190 // TODO(dcheng): Use a more clever serialization. | 190 // TODO(dcheng): Use a more clever serialization. |
191 llvm::outs() << "==== BEGIN EDITS ====\n"; | 191 llvm::outs() << "==== BEGIN EDITS ====\n"; |
192 for (const Replacement& r : replacements) { | 192 for (Replacements::const_iterator it = replacements.begin(); |
193 llvm::outs() << "r:" << r.getFilePath() << ":" << r.getOffset() << ":" | 193 it != replacements.end(); ++it) { |
194 << r.getLength() << ":" << r.getReplacementText() << "\n"; | 194 llvm::outs() << "r:" << it->getFilePath() << ":" << it->getOffset() << ":" |
| 195 << it->getLength() << ":" << it->getReplacementText() << "\n"; |
195 } | 196 } |
196 llvm::outs() << "==== END EDITS ====\n"; | 197 llvm::outs() << "==== END EDITS ====\n"; |
197 | 198 |
198 return 0; | 199 return 0; |
199 } | 200 } |
OLD | NEW |