Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp

Issue 2256913002: Handling of DependentScopeDeclRefExpr and CXXDependentScopeMemberExpr nodes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@blink-style-new-clang
Patch Set: Avoiding "renaming" template-dependent operator names. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/clang/rewrite_to_chrome_style/tests/function-templates-expected.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tools/clang/rewrite_to_chrome_style/tests/function-templates-expected.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698