| 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 // Changes Blink-style names to Chrome-style names. Currently transforms: | 5 // Changes Blink-style names to Chrome-style names. Currently transforms: |
| 6 // fields: | 6 // fields: |
| 7 // int m_operationCount => int operation_count_ | 7 // int m_operationCount => int operation_count_ |
| 8 // variables (including parameters): | 8 // variables (including parameters): |
| 9 // int mySuperVariable => int my_super_variable | 9 // int mySuperVariable => int my_super_variable |
| 10 // constants: | 10 // constants: |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 namespace { | 48 namespace { |
| 49 | 49 |
| 50 const char kBlinkFieldPrefix[] = "m_"; | 50 const char kBlinkFieldPrefix[] = "m_"; |
| 51 const char kBlinkStaticMemberPrefix[] = "s_"; | 51 const char kBlinkStaticMemberPrefix[] = "s_"; |
| 52 const char kGeneratedFileRegex[] = "^gen/|/gen/"; | 52 const char kGeneratedFileRegex[] = "^gen/|/gen/"; |
| 53 | 53 |
| 54 const clang::ast_matchers::internal:: | 54 const clang::ast_matchers::internal:: |
| 55 VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr> | 55 VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr> |
| 56 unresolvedMemberExpr; | 56 unresolvedMemberExpr; |
| 57 | 57 |
| 58 const clang::ast_matchers::internal:: |
| 59 VariadicDynCastAllOfMatcher<clang::Expr, clang::DependentScopeDeclRefExpr> |
| 60 dependentScopeDeclRefExpr; |
| 61 |
| 62 const clang::ast_matchers::internal:: |
| 63 VariadicDynCastAllOfMatcher<clang::Expr, clang::CXXDependentScopeMemberExpr> |
| 64 cxxDependentScopeMemberExpr; |
| 65 |
| 58 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) { | 66 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) { |
| 59 return Node.isOverloadedOperator(); | 67 return Node.isOverloadedOperator(); |
| 60 } | 68 } |
| 61 | 69 |
| 62 AST_MATCHER_P(clang::FunctionTemplateDecl, | 70 AST_MATCHER_P(clang::FunctionTemplateDecl, |
| 63 templatedDecl, | 71 templatedDecl, |
| 64 clang::ast_matchers::internal::Matcher<clang::FunctionDecl>, | 72 clang::ast_matchers::internal::Matcher<clang::FunctionDecl>, |
| 65 InnerMatcher) { | 73 InnerMatcher) { |
| 66 return InnerMatcher.matches(*Node.getTemplatedDecl(), Finder, Builder); | 74 return InnerMatcher.matches(*Node.getTemplatedDecl(), Finder, Builder); |
| 67 } | 75 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 return inner_matcher.matches(decl, finder, builder); | 155 return inner_matcher.matches(decl, finder, builder); |
| 148 } | 156 } |
| 149 | 157 |
| 150 AST_MATCHER_P(clang::CXXMethodDecl, | 158 AST_MATCHER_P(clang::CXXMethodDecl, |
| 151 includeAllOverriddenMethods, | 159 includeAllOverriddenMethods, |
| 152 clang::ast_matchers::internal::Matcher<clang::CXXMethodDecl>, | 160 clang::ast_matchers::internal::Matcher<clang::CXXMethodDecl>, |
| 153 InnerMatcher) { | 161 InnerMatcher) { |
| 154 return MatchAllOverriddenMethods(Node, InnerMatcher, Finder, Builder); | 162 return MatchAllOverriddenMethods(Node, InnerMatcher, Finder, Builder); |
| 155 } | 163 } |
| 156 | 164 |
| 165 // Matches |x.m| CXXDependentScopeMemberExpr if InnerMatcher matches |x|. |
| 166 AST_MATCHER_P(clang::CXXDependentScopeMemberExpr, |
| 167 hasBaseExprMissingOrMatching, |
| 168 clang::ast_matchers::internal::Matcher<clang::Expr>, |
| 169 InnerMatcher) { |
| 170 clang::Expr* base_expr = Node.isImplicitAccess() ? nullptr : Node.getBase(); |
| 171 return !base_expr || InnerMatcher.matches(*base_expr, Finder, Builder); |
| 172 } |
| 173 |
| 174 // Matches |T::m| CXXDependentScopeMemberExpr if InnerMatcher matches |T|. |
| 175 AST_MATCHER_P( |
| 176 clang::CXXDependentScopeMemberExpr, |
| 177 hasQualifierMissingOrMatching, |
| 178 clang::ast_matchers::internal::Matcher<clang::NestedNameSpecifier>, |
| 179 InnerMatcher) { |
| 180 clang::NestedNameSpecifier* qual = Node.getQualifier(); |
| 181 return !qual || InnerMatcher.matches(*qual, Finder, Builder); |
| 182 } |
| 183 |
| 184 // Matches |const Class<T>&| QualType if InnerMatcher matches |Class<T>|. |
| 185 AST_MATCHER_P(clang::QualType, |
| 186 hasUnderlyingType, |
| 187 clang::ast_matchers::internal::Matcher<clang::Type>, |
| 188 InnerMatcher) { |
| 189 const clang::Type* type = Node.getTypePtrOrNull(); |
| 190 return type && InnerMatcher.matches(*type, Finder, Builder); |
| 191 } |
| 192 |
| 157 bool IsMethodOverrideOf(const clang::CXXMethodDecl& decl, | 193 bool IsMethodOverrideOf(const clang::CXXMethodDecl& decl, |
| 158 const char* class_name) { | 194 const char* class_name) { |
| 159 if (decl.getParent()->getQualifiedNameAsString() == class_name) | 195 if (decl.getParent()->getQualifiedNameAsString() == class_name) |
| 160 return true; | 196 return true; |
| 161 for (auto it = decl.begin_overridden_methods(); | 197 for (auto it = decl.begin_overridden_methods(); |
| 162 it != decl.end_overridden_methods(); ++it) { | 198 it != decl.end_overridden_methods(); ++it) { |
| 163 if (IsMethodOverrideOf(**it, class_name)) | 199 if (IsMethodOverrideOf(**it, class_name)) |
| 164 return true; | 200 return true; |
| 165 } | 201 } |
| 166 return false; | 202 return false; |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 | 516 |
| 481 template <> | 517 template <> |
| 482 struct TargetNodeTraits<clang::DeclRefExpr> { | 518 struct TargetNodeTraits<clang::DeclRefExpr> { |
| 483 static clang::SourceLocation GetLoc(const clang::DeclRefExpr& expr) { | 519 static clang::SourceLocation GetLoc(const clang::DeclRefExpr& expr) { |
| 484 return expr.getLocation(); | 520 return expr.getLocation(); |
| 485 } | 521 } |
| 486 static const char* GetName() { return "expr"; } | 522 static const char* GetName() { return "expr"; } |
| 487 }; | 523 }; |
| 488 | 524 |
| 489 template <> | 525 template <> |
| 526 struct TargetNodeTraits<clang::DependentScopeDeclRefExpr> { |
| 527 static clang::SourceLocation GetLoc( |
| 528 const clang::DependentScopeDeclRefExpr& expr) { |
| 529 return expr.getLocation(); |
| 530 } |
| 531 static const char* GetName() { return "expr"; } |
| 532 }; |
| 533 |
| 534 template <> |
| 535 struct TargetNodeTraits<clang::CXXDependentScopeMemberExpr> { |
| 536 static clang::SourceLocation GetLoc( |
| 537 const clang::CXXDependentScopeMemberExpr& expr) { |
| 538 return expr.getMemberLoc(); |
| 539 } |
| 540 static const char* GetName() { return "expr"; } |
| 541 }; |
| 542 |
| 543 template <> |
| 490 struct TargetNodeTraits<clang::CXXCtorInitializer> { | 544 struct TargetNodeTraits<clang::CXXCtorInitializer> { |
| 491 static clang::SourceLocation GetLoc(const clang::CXXCtorInitializer& init) { | 545 static clang::SourceLocation GetLoc(const clang::CXXCtorInitializer& init) { |
| 492 assert(init.isWritten()); | 546 assert(init.isWritten()); |
| 493 return init.getSourceLocation(); | 547 return init.getSourceLocation(); |
| 494 } | 548 } |
| 495 static const char* GetName() { return "initializer"; } | 549 static const char* GetName() { return "initializer"; } |
| 496 }; | 550 }; |
| 497 | 551 |
| 498 template <> | 552 template <> |
| 499 struct TargetNodeTraits<clang::UnresolvedLookupExpr> { | 553 struct TargetNodeTraits<clang::UnresolvedLookupExpr> { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 } | 639 } |
| 586 clang::ASTContext* context = result.Context; | 640 clang::ASTContext* context = result.Context; |
| 587 std::string new_name; | 641 std::string new_name; |
| 588 if (!GetNameForDecl(*decl, *context, new_name)) | 642 if (!GetNameForDecl(*decl, *context, new_name)) |
| 589 return; // If false, the name was not suitable for renaming. | 643 return; // If false, the name was not suitable for renaming. |
| 590 llvm::StringRef old_name = decl->getName(); | 644 llvm::StringRef old_name = decl->getName(); |
| 591 Base::AddReplacement(result, old_name, std::move(new_name)); | 645 Base::AddReplacement(result, old_name, std::move(new_name)); |
| 592 } | 646 } |
| 593 }; | 647 }; |
| 594 | 648 |
| 595 llvm::StringRef GetCurrentName(const clang::UnresolvedMemberExpr& expr) { | 649 clang::DeclarationName GetUnresolvedName( |
| 596 return expr.getMemberName().getAsString(); | 650 const clang::UnresolvedMemberExpr& expr) { |
| 651 return expr.getMemberName(); |
| 597 } | 652 } |
| 598 | 653 |
| 599 llvm::StringRef GetCurrentName(const clang::NamedDecl& decl) { | 654 clang::DeclarationName GetUnresolvedName( |
| 600 return decl.getName(); | 655 const clang::DependentScopeDeclRefExpr& expr) { |
| 656 return expr.getDeclName(); |
| 657 } |
| 658 |
| 659 clang::DeclarationName GetUnresolvedName( |
| 660 const clang::CXXDependentScopeMemberExpr& expr) { |
| 661 return expr.getMember(); |
| 662 } |
| 663 |
| 664 clang::DeclarationName GetUnresolvedName( |
| 665 const clang::UnresolvedUsingValueDecl& decl) { |
| 666 return decl.getDeclName(); |
| 601 } | 667 } |
| 602 | 668 |
| 603 // Returns whether |expr| is a callee of a method or function call. | 669 // Returns whether |expr| is a callee of a method or function call. |
| 604 bool IsCallee(const clang::Expr& expr, clang::ASTContext& context) { | 670 bool IsCallee(const clang::Expr& expr, clang::ASTContext& context) { |
| 605 auto parents = context.getParents(expr); | 671 auto parents = context.getParents(expr); |
| 606 return std::all_of( | 672 return std::all_of( |
| 607 parents.begin(), parents.end(), | 673 parents.begin(), parents.end(), |
| 608 [&expr](const clang::ast_type_traits::DynTypedNode& parent) { | 674 [&expr](const clang::ast_type_traits::DynTypedNode& parent) { |
| 609 const clang::CallExpr* call = parent.get<clang::CallExpr>(); | 675 const clang::CallExpr* call = parent.get<clang::CallExpr>(); |
| 610 return call && call->getCallee() == &expr; | 676 return call && call->getCallee() == &expr; |
| 611 }); | 677 }); |
| 612 } | 678 } |
| 613 | 679 |
| 614 bool IsCallee(const clang::UnresolvedUsingValueDecl& /* decl */, | 680 bool IsCallee(const clang::UnresolvedUsingValueDecl& /* decl */, |
| 615 clang::ASTContext& /* context */) { | 681 clang::ASTContext& /* context */) { |
| 616 // Heuristic - assuming that |using Base::foo| refers to a method. | 682 // Heuristic - assuming that |using Base::foo| refers to a method. |
| 617 return true; | 683 return true; |
| 618 } | 684 } |
| 619 | 685 |
| 620 template <typename TargetNode> | 686 template <typename TargetNode> |
| 621 class UnresolvedRewriterBase : public RewriterBase<TargetNode> { | 687 class UnresolvedRewriterBase : public RewriterBase<TargetNode> { |
| 622 public: | 688 public: |
| 623 using Base = RewriterBase<TargetNode>; | 689 using Base = RewriterBase<TargetNode>; |
| 624 | 690 |
| 625 explicit UnresolvedRewriterBase(std::set<Replacement>* replacements) | 691 explicit UnresolvedRewriterBase(std::set<Replacement>* replacements) |
| 626 : RewriterBase<TargetNode>(replacements) {} | 692 : RewriterBase<TargetNode>(replacements) {} |
| 627 | 693 |
| 628 void run(const MatchFinder::MatchResult& result) override { | 694 void run(const MatchFinder::MatchResult& result) override { |
| 629 const TargetNode& expr = Base::GetTargetNode(result); | 695 const TargetNode& expr = Base::GetTargetNode(result); |
| 630 llvm::StringRef old_name = GetCurrentName(expr); | 696 |
| 697 clang::DeclarationName unresolved_name = GetUnresolvedName(expr); |
| 698 switch (unresolved_name.getNameKind()) { |
| 699 // Do not rewrite this: |
| 700 // return operator T*(); |
| 701 // into this: |
| 702 // return Operator type - parameter - 0 - 0 * T * (); |
| 703 case clang::DeclarationName::NameKind::CXXConversionFunctionName: |
| 704 case clang::DeclarationName::NameKind::CXXOperatorName: |
| 705 case clang::DeclarationName::NameKind::CXXLiteralOperatorName: |
| 706 return; |
| 707 default: |
| 708 break; |
| 709 } |
| 710 |
| 711 llvm::StringRef old_name = unresolved_name.getAsString(); |
| 631 std::string new_name; | 712 std::string new_name; |
| 632 if (GuessNameForUnresolvedDependentNode(expr, *result.Context, old_name, | 713 if (GuessNameForUnresolvedDependentNode(expr, *result.Context, old_name, |
| 633 new_name)) { | 714 new_name)) { |
| 634 Base::AddReplacement(result, old_name, std::move(new_name)); | 715 Base::AddReplacement(result, old_name, std::move(new_name)); |
| 635 } | 716 } |
| 636 } | 717 } |
| 637 | 718 |
| 638 private: | 719 private: |
| 639 // This method calculates a new name for nodes that depend on template | 720 // This method calculates a new name for nodes that depend on template |
| 640 // parameters (http://en.cppreference.com/w/cpp/language/dependent_name). The | 721 // parameters (http://en.cppreference.com/w/cpp/language/dependent_name). The |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>; | 784 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>; |
| 704 | 785 |
| 705 using UnresolvedDependentMemberRewriter = | 786 using UnresolvedDependentMemberRewriter = |
| 706 UnresolvedRewriterBase<clang::UnresolvedMemberExpr>; | 787 UnresolvedRewriterBase<clang::UnresolvedMemberExpr>; |
| 707 | 788 |
| 708 using UnresolvedUsingValueDeclRewriter = | 789 using UnresolvedUsingValueDeclRewriter = |
| 709 UnresolvedRewriterBase<clang::UnresolvedUsingValueDecl>; | 790 UnresolvedRewriterBase<clang::UnresolvedUsingValueDecl>; |
| 710 | 791 |
| 711 using UsingDeclRewriter = DeclRewriterBase<clang::UsingDecl, clang::NamedDecl>; | 792 using UsingDeclRewriter = DeclRewriterBase<clang::UsingDecl, clang::NamedDecl>; |
| 712 | 793 |
| 794 using DependentScopeDeclRefExprRewriter = |
| 795 UnresolvedRewriterBase<clang::DependentScopeDeclRefExpr>; |
| 796 |
| 797 using CXXDependentScopeMemberExprRewriter = |
| 798 UnresolvedRewriterBase<clang::CXXDependentScopeMemberExpr>; |
| 799 |
| 713 } // namespace | 800 } // namespace |
| 714 | 801 |
| 715 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); | 802 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); |
| 716 | 803 |
| 717 int main(int argc, const char* argv[]) { | 804 int main(int argc, const char* argv[]) { |
| 718 // TODO(dcheng): Clang tooling should do this itself. | 805 // TODO(dcheng): Clang tooling should do this itself. |
| 719 // http://llvm.org/bugs/show_bug.cgi?id=21627 | 806 // http://llvm.org/bugs/show_bug.cgi?id=21627 |
| 720 llvm::InitializeNativeTarget(); | 807 llvm::InitializeNativeTarget(); |
| 721 llvm::InitializeNativeTargetAsmParser(); | 808 llvm::InitializeNativeTargetAsmParser(); |
| 722 llvm::cl::OptionCategory category( | 809 llvm::cl::OptionCategory category( |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 // using blink::X; | 1114 // using blink::X; |
| 1028 // matches |using blink::X|. | 1115 // matches |using blink::X|. |
| 1029 auto using_decl_matcher = id( | 1116 auto using_decl_matcher = id( |
| 1030 "decl", usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(anyOf( | 1117 "decl", usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(anyOf( |
| 1031 var_decl_matcher, field_decl_matcher, function_decl_matcher, | 1118 var_decl_matcher, field_decl_matcher, function_decl_matcher, |
| 1032 method_decl_matcher, function_template_decl_matcher, | 1119 method_decl_matcher, function_template_decl_matcher, |
| 1033 method_template_decl_matcher, enum_member_decl_matcher))))); | 1120 method_template_decl_matcher, enum_member_decl_matcher))))); |
| 1034 UsingDeclRewriter using_decl_rewriter(&replacements); | 1121 UsingDeclRewriter using_decl_rewriter(&replacements); |
| 1035 match_finder.addMatcher(using_decl_matcher, &using_decl_rewriter); | 1122 match_finder.addMatcher(using_decl_matcher, &using_decl_rewriter); |
| 1036 | 1123 |
| 1124 // Matches any QualType that refers to a blink type: |
| 1125 // - const blink::Foo& |
| 1126 // - blink::Foo* |
| 1127 // - blink::Foo<T> |
| 1128 // - ... |
| 1129 auto blink_qual_type_matcher = qualType( |
| 1130 anyOf(pointsTo(in_blink_namespace), references(in_blink_namespace), |
| 1131 hasUnderlyingType(anyOf( |
| 1132 enumType(hasDeclaration(in_blink_namespace)), |
| 1133 recordType(hasDeclaration(in_blink_namespace)), |
| 1134 templateSpecializationType(hasDeclaration(in_blink_namespace)), |
| 1135 templateTypeParmType(hasDeclaration(in_blink_namespace)), |
| 1136 typedefType(hasDeclaration(in_blink_namespace)))))); |
| 1137 |
| 1138 // Template-dependent decl lookup ======== |
| 1139 // Given |
| 1140 // template <typename T> void f() { T::foo(); } |
| 1141 // matches |T::foo|. |
| 1142 auto dependent_scope_decl_ref_expr_matcher = |
| 1143 expr(id("expr", dependentScopeDeclRefExpr(has(nestedNameSpecifier( |
| 1144 specifiesType(blink_qual_type_matcher)))))); |
| 1145 DependentScopeDeclRefExprRewriter dependent_scope_decl_ref_expr_rewriter( |
| 1146 &replacements); |
| 1147 match_finder.addMatcher(dependent_scope_decl_ref_expr_matcher, |
| 1148 &dependent_scope_decl_ref_expr_rewriter); |
| 1149 |
| 1150 // Template-dependent member lookup ======== |
| 1151 // Given |
| 1152 // template <typename T> |
| 1153 // class Foo { |
| 1154 // void f() { T::foo(); } |
| 1155 // void g(T x) { x.bar(); } |
| 1156 // }; |
| 1157 // matches |T::foo| and |x.bar|. |
| 1158 auto cxx_dependent_scope_member_expr_matcher = expr( |
| 1159 id("expr", |
| 1160 cxxDependentScopeMemberExpr(allOf( |
| 1161 hasBaseExprMissingOrMatching(hasType(blink_qual_type_matcher)), |
| 1162 hasQualifierMissingOrMatching( |
| 1163 specifiesType(blink_qual_type_matcher)))))); |
| 1164 CXXDependentScopeMemberExprRewriter cxx_dependent_scope_member_expr_rewriter( |
| 1165 &replacements); |
| 1166 match_finder.addMatcher(cxx_dependent_scope_member_expr_matcher, |
| 1167 &cxx_dependent_scope_member_expr_rewriter); |
| 1168 |
| 1037 std::unique_ptr<clang::tooling::FrontendActionFactory> factory = | 1169 std::unique_ptr<clang::tooling::FrontendActionFactory> factory = |
| 1038 clang::tooling::newFrontendActionFactory(&match_finder); | 1170 clang::tooling::newFrontendActionFactory(&match_finder); |
| 1039 int result = tool.run(factory.get()); | 1171 int result = tool.run(factory.get()); |
| 1040 if (result != 0) | 1172 if (result != 0) |
| 1041 return result; | 1173 return result; |
| 1042 | 1174 |
| 1043 #if defined(_WIN32) | 1175 #if defined(_WIN32) |
| 1044 HANDLE lockfd = CreateFile("rewrite-sym.lock", GENERIC_READ, FILE_SHARE_READ, | 1176 HANDLE lockfd = CreateFile("rewrite-sym.lock", GENERIC_READ, FILE_SHARE_READ, |
| 1045 NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | 1177 NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
| 1046 OVERLAPPED overlapped = {}; | 1178 OVERLAPPED overlapped = {}; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1078 for (const auto& r : replacements) { | 1210 for (const auto& r : replacements) { |
| 1079 std::string replacement_text = r.getReplacementText().str(); | 1211 std::string replacement_text = r.getReplacementText().str(); |
| 1080 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); | 1212 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); |
| 1081 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() | 1213 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() |
| 1082 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; | 1214 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; |
| 1083 } | 1215 } |
| 1084 llvm::outs() << "==== END EDITS ====\n"; | 1216 llvm::outs() << "==== END EDITS ====\n"; |
| 1085 | 1217 |
| 1086 return 0; | 1218 return 0; |
| 1087 } | 1219 } |
| OLD | NEW |