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

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

Issue 2274653002: Handling of UnresolvedUsingValueDecl nodes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@blink-style-new-clang
Patch Set: Having UnresolvedRewriterBase work with DeclarationName instead of std::string. 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/template-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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 return true; 168 return true;
169 } 169 }
170 return false; 170 return false;
171 } 171 }
172 172
173 bool IsBlacklistedFunction(const clang::FunctionDecl& decl) { 173 bool IsBlacklistedFunction(const clang::FunctionDecl& decl) {
174 // swap() functions should match the signature of std::swap for ADL tricks. 174 // swap() functions should match the signature of std::swap for ADL tricks.
175 return decl.getName() == "swap"; 175 return decl.getName() == "swap";
176 } 176 }
177 177
178 bool IsBlacklistedMethod(const clang::CXXMethodDecl& decl) { 178 bool IsBlacklistedMethod(const std::string& name,
dcheng 2016/09/10 04:00:55 Pass as llvm::StringRef here, so we don't need to
Łukasz Anforowicz 2016/09/12 19:52:56 Done. This is how I started actually, but then go
179 if (decl.isStatic()) 179 const clang::CXXMethodDecl* decl) {
180 if (decl && decl->isStatic())
dcheng 2016/09/10 04:00:55 It feels like we should just have two versions of
Łukasz Anforowicz 2016/09/12 19:52:56 In the latest patchset I have 1) reverted changes
180 return false; 181 return false;
181 182
182 clang::StringRef name = decl.getName(); 183 if (decl)
184 assert(decl->getName().str() == name);
183 185
184 // These methods should never be renamed. 186 // These methods should never be renamed.
185 static const char* kBlacklistMethods[] = {"trace", "traceImpl", "lock", 187 static const char* kBlacklistMethods[] = {"trace", "traceImpl", "lock",
186 "unlock", "try_lock"}; 188 "unlock", "try_lock"};
187 for (const auto& b : kBlacklistMethods) { 189 for (const auto& b : kBlacklistMethods) {
188 if (name == b) 190 if (name == b)
189 return true; 191 return true;
190 } 192 }
191 193
192 // Iterator methods shouldn't be renamed to work with stl and range-for 194 // Iterator methods shouldn't be renamed to work with stl and range-for
193 // loops. 195 // loops.
194 std::string ret_type = decl.getReturnType().getAsString(); 196 bool is_iterator = false;
195 if (ret_type.find("iterator") != std::string::npos || 197 if (decl) {
196 ret_type.find("Iterator") != std::string::npos) { 198 std::string ret_type = decl->getReturnType().getAsString();
199 is_iterator = ret_type.find("iterator") != std::string::npos ||
200 ret_type.find("Iterator") != std::string::npos;
dcheng 2016/09/10 04:00:55 For this, we can just have a simple shared method
Łukasz Anforowicz 2016/09/12 19:52:56 I think this comment is not applicable to the most
201 } else {
202 is_iterator = true;
203 }
204 if (is_iterator) {
197 static const char* kIteratorBlacklist[] = {"begin", "end", "rbegin", 205 static const char* kIteratorBlacklist[] = {"begin", "end", "rbegin",
198 "rend"}; 206 "rend"};
199 for (const auto& b : kIteratorBlacklist) { 207 for (const auto& b : kIteratorBlacklist) {
200 if (name == b) 208 if (name == b)
201 return true; 209 return true;
202 } 210 }
203 } 211 }
204 212
205 // Subclasses of InspectorAgent will subclass "disable()" from both blink and 213 // Subclasses of InspectorAgent will subclass "disable()" from both blink and
206 // from gen/, which is problematic, but DevTools folks don't want to rename 214 // from gen/, which is problematic, but DevTools folks don't want to rename
207 // it or split this up. So don't rename it at all. 215 // it or split this up. So don't rename it at all.
208 if (name.equals("disable") && 216 if (name == "disable" &&
209 IsMethodOverrideOf(decl, "blink::InspectorAgent")) 217 (!decl || IsMethodOverrideOf(*decl, "blink::InspectorAgent")))
210 return true; 218 return true;
211 219
212 return false; 220 return false;
213 } 221 }
214 222
215 AST_MATCHER(clang::FunctionDecl, isBlacklistedFunction) { 223 AST_MATCHER(clang::FunctionDecl, isBlacklistedFunction) {
216 return IsBlacklistedFunction(Node); 224 return IsBlacklistedFunction(Node);
217 } 225 }
218 226
219 AST_MATCHER(clang::CXXMethodDecl, isBlacklistedMethod) { 227 AST_MATCHER(clang::CXXMethodDecl, isBlacklistedMethod) {
220 return IsBlacklistedMethod(Node); 228 return IsBlacklistedMethod(Node.getName().str(), &Node);
221 } 229 }
222 230
223 // Helper to convert from a camelCaseName to camel_case_name. It uses some 231 // Helper to convert from a camelCaseName to camel_case_name. It uses some
224 // heuristics to try to handle acronyms in camel case names correctly. 232 // heuristics to try to handle acronyms in camel case names correctly.
225 std::string CamelCaseToUnderscoreCase(StringRef input) { 233 std::string CamelCaseToUnderscoreCase(StringRef input) {
226 std::string output; 234 std::string output;
227 bool needs_underscore = false; 235 bool needs_underscore = false;
228 bool was_lowercase = false; 236 bool was_lowercase = false;
229 bool was_uppercase = false; 237 bool was_uppercase = false;
230 bool first_char = true; 238 bool first_char = true;
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 465
458 template <typename Type> 466 template <typename Type>
459 struct TargetNodeTraits; 467 struct TargetNodeTraits;
460 468
461 template <> 469 template <>
462 struct TargetNodeTraits<clang::NamedDecl> { 470 struct TargetNodeTraits<clang::NamedDecl> {
463 static clang::SourceLocation GetLoc(const clang::NamedDecl& decl) { 471 static clang::SourceLocation GetLoc(const clang::NamedDecl& decl) {
464 return decl.getLocation(); 472 return decl.getLocation();
465 } 473 }
466 static const char* GetName() { return "decl"; } 474 static const char* GetName() { return "decl"; }
467 static const char* GetType() { return "NamedDecl"; }
dcheng 2016/09/10 04:00:55 While unused, these were helpful for debugging in
Łukasz Anforowicz 2016/09/12 19:52:56 Done.
468 }; 475 };
469 476
470 template <> 477 template <>
471 struct TargetNodeTraits<clang::MemberExpr> { 478 struct TargetNodeTraits<clang::MemberExpr> {
472 static clang::SourceLocation GetLoc(const clang::MemberExpr& expr) { 479 static clang::SourceLocation GetLoc(const clang::MemberExpr& expr) {
473 return expr.getMemberLoc(); 480 return expr.getMemberLoc();
474 } 481 }
475 static const char* GetName() { return "expr"; } 482 static const char* GetName() { return "expr"; }
476 static const char* GetType() { return "MemberExpr"; }
477 }; 483 };
478 484
479 template <> 485 template <>
480 struct TargetNodeTraits<clang::DeclRefExpr> { 486 struct TargetNodeTraits<clang::DeclRefExpr> {
481 static clang::SourceLocation GetLoc(const clang::DeclRefExpr& expr) { 487 static clang::SourceLocation GetLoc(const clang::DeclRefExpr& expr) {
482 return expr.getLocation(); 488 return expr.getLocation();
483 } 489 }
484 static const char* GetName() { return "expr"; } 490 static const char* GetName() { return "expr"; }
485 static const char* GetType() { return "DeclRefExpr"; }
486 }; 491 };
487 492
488 template <> 493 template <>
489 struct TargetNodeTraits<clang::CXXCtorInitializer> { 494 struct TargetNodeTraits<clang::CXXCtorInitializer> {
490 static clang::SourceLocation GetLoc(const clang::CXXCtorInitializer& init) { 495 static clang::SourceLocation GetLoc(const clang::CXXCtorInitializer& init) {
491 assert(init.isWritten()); 496 assert(init.isWritten());
492 return init.getSourceLocation(); 497 return init.getSourceLocation();
493 } 498 }
494 static const char* GetName() { return "initializer"; } 499 static const char* GetName() { return "initializer"; }
495 static const char* GetType() { return "CXXCtorInitializer"; }
496 }; 500 };
497 501
498 template <> 502 template <>
499 struct TargetNodeTraits<clang::UnresolvedLookupExpr> { 503 struct TargetNodeTraits<clang::UnresolvedLookupExpr> {
500 static clang::SourceLocation GetLoc(const clang::UnresolvedLookupExpr& expr) { 504 static clang::SourceLocation GetLoc(const clang::UnresolvedLookupExpr& expr) {
501 return expr.getNameLoc(); 505 return expr.getNameLoc();
502 } 506 }
503 static const char* GetName() { return "expr"; } 507 static const char* GetName() { return "expr"; }
504 static const char* GetType() { return "UnresolvedLookupExpr"; }
505 }; 508 };
506 509
507 template <> 510 template <>
508 struct TargetNodeTraits<clang::UnresolvedMemberExpr> { 511 struct TargetNodeTraits<clang::UnresolvedMemberExpr> {
509 static clang::SourceLocation GetLoc(const clang::UnresolvedMemberExpr& expr) { 512 static clang::SourceLocation GetLoc(const clang::UnresolvedMemberExpr& expr) {
510 return expr.getMemberLoc(); 513 return expr.getMemberLoc();
511 } 514 }
512 static const char* GetName() { return "expr"; } 515 static const char* GetName() { return "expr"; }
513 static const char* GetType() { return "UnresolvedMemberExpr"; }
514 }; 516 };
515 517
516 template <typename DeclNode, typename TargetNode> 518 template <>
519 struct TargetNodeTraits<clang::UnresolvedUsingValueDecl> {
520 static clang::SourceLocation GetLoc(
521 const clang::UnresolvedUsingValueDecl& decl) {
522 return decl.getNameInfo().getLoc();
523 }
524 static const char* GetName() { return "decl"; }
525 };
526
527 template <typename TargetNode>
517 class RewriterBase : public MatchFinder::MatchCallback { 528 class RewriterBase : public MatchFinder::MatchCallback {
518 public: 529 public:
519 explicit RewriterBase(std::set<Replacement>* replacements) 530 explicit RewriterBase(std::set<Replacement>* replacements)
520 : replacements_(replacements) {} 531 : replacements_(replacements) {}
521 532
533 const TargetNode& GetTargetNode(const MatchFinder::MatchResult& result) {
534 const TargetNode* target_node = result.Nodes.getNodeAs<TargetNode>(
535 TargetNodeTraits<TargetNode>::GetName());
536 assert(target_node);
537 return *target_node;
538 }
539
540 void AddReplacement(const MatchFinder::MatchResult& result,
541 llvm::StringRef old_name,
542 std::string new_name) {
543 if (old_name == new_name)
544 return;
545
546 clang::SourceLocation loc =
547 TargetNodeTraits<TargetNode>::GetLoc(GetTargetNode(result));
548 clang::CharSourceRange range = clang::CharSourceRange::getTokenRange(loc);
549 replacements_->emplace(*result.SourceManager, range, new_name);
550 replacement_names_.emplace(old_name.str(), std::move(new_name));
551 }
552
553 const std::unordered_map<std::string, std::string>& replacement_names()
554 const {
555 return replacement_names_;
556 }
557
558 private:
559 std::set<Replacement>* const replacements_;
560 std::unordered_map<std::string, std::string> replacement_names_;
561 };
562
563 template <typename DeclNode, typename TargetNode>
564 class DeclRewriterBase : public RewriterBase<TargetNode> {
565 public:
566 using Base = RewriterBase<TargetNode>;
567
568 explicit DeclRewriterBase(std::set<Replacement>* replacements)
569 : Base(replacements) {}
570
522 void run(const MatchFinder::MatchResult& result) override { 571 void run(const MatchFinder::MatchResult& result) override {
523 const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl"); 572 const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl");
573 assert(decl);
524 // If false, there's no name to be renamed. 574 // If false, there's no name to be renamed.
525 if (!decl->getIdentifier()) 575 if (!decl->getIdentifier())
526 return; 576 return;
527 clang::SourceLocation decl_loc = 577 clang::SourceLocation decl_loc =
528 TargetNodeTraits<clang::NamedDecl>::GetLoc(*decl); 578 TargetNodeTraits<clang::NamedDecl>::GetLoc(*decl);
529 if (decl_loc.isMacroID()) { 579 if (decl_loc.isMacroID()) {
530 // Get the location of the spelling of the declaration. If token pasting 580 // Get the location of the spelling of the declaration. If token pasting
531 // was used this will be in "scratch space" and we don't know how to get 581 // was used this will be in "scratch space" and we don't know how to get
532 // from there back to/ the actual macro with the foo##bar text. So just 582 // from there back to/ the actual macro with the foo##bar text. So just
533 // don't replace in that case. 583 // don't replace in that case.
534 clang::SourceLocation spell = 584 clang::SourceLocation spell =
535 result.SourceManager->getSpellingLoc(decl_loc); 585 result.SourceManager->getSpellingLoc(decl_loc);
536 if (strcmp(result.SourceManager->getBufferName(spell), 586 if (strcmp(result.SourceManager->getBufferName(spell),
537 "<scratch space>") == 0) 587 "<scratch space>") == 0)
538 return; 588 return;
539 } 589 }
540 clang::ASTContext* context = result.Context; 590 clang::ASTContext* context = result.Context;
541 std::string new_name; 591 std::string new_name;
542 if (!GetNameForDecl(*decl, *context, new_name)) 592 if (!GetNameForDecl(*decl, *context, new_name))
543 return; // If false, the name was not suitable for renaming. 593 return; // If false, the name was not suitable for renaming.
544 llvm::StringRef old_name = decl->getName(); 594 llvm::StringRef old_name = decl->getName();
545 if (old_name == new_name) 595 Base::AddReplacement(result, old_name, std::move(new_name));
546 return;
547 clang::SourceLocation loc = TargetNodeTraits<TargetNode>::GetLoc(
548 *result.Nodes.getNodeAs<TargetNode>(
549 TargetNodeTraits<TargetNode>::GetName()));
550 clang::CharSourceRange range = clang::CharSourceRange::getTokenRange(loc);
551 replacements_->emplace(*result.SourceManager, range, new_name);
552 replacement_names_.emplace(old_name.str(), std::move(new_name));
553 } 596 }
597 };
dcheng 2016/09/10 04:00:55 Nit: let's move the DeclRewriterBase using decls u
Łukasz Anforowicz 2016/09/12 19:52:56 Done.
554 598
555 const std::unordered_map<std::string, std::string>& replacement_names() 599 clang::DeclarationName GetUnresolvedName(
556 const { 600 const clang::UnresolvedMemberExpr& expr) {
557 return replacement_names_; 601 return expr.getMemberName();
602 }
603
604 clang::DeclarationName GetUnresolvedName(
605 const clang::UnresolvedUsingValueDecl& decl) {
606 return decl.getDeclName();
607 }
608
609 // Returns whether |expr| is a callee of a method or function call.
610 bool IsCallee(const clang::Expr& expr, clang::ASTContext& context) {
dcheng 2016/09/10 04:00:55 Can this logic be encapsulated into a matcher?
Łukasz Anforowicz 2016/09/12 19:52:56 Done. Thanks for helping figure out that I need |
611 auto parents = context.getParents(expr);
612 return std::all_of(
613 parents.begin(), parents.end(),
614 [&expr](const clang::ast_type_traits::DynTypedNode& parent) {
615 const clang::CallExpr* call = parent.get<clang::CallExpr>();
616 return call && call->getCallee() == &expr;
617 });
618 }
619
620 bool IsCallee(const clang::UnresolvedUsingValueDecl& /* decl */,
621 clang::ASTContext& /* context */) {
622 // Heuristic - assuming that |using Base::foo| refers to a method.
dcheng 2016/09/10 04:00:55 We can guess from the name though, right?
Łukasz Anforowicz 2016/09/12 19:52:56 Yes, we can guess from the name - we do it in Gues
623 return true;
624 }
625
626 template <typename TargetNode>
627 class UnresolvedRewriterBase : public RewriterBase<TargetNode> {
628 public:
629 using Base = RewriterBase<TargetNode>;
630
631 explicit UnresolvedRewriterBase(std::set<Replacement>* replacements)
632 : RewriterBase<TargetNode>(replacements) {}
633
634 void run(const MatchFinder::MatchResult& result) override {
635 const TargetNode& expr = Base::GetTargetNode(result);
636 llvm::StringRef old_name = GetUnresolvedName(expr).getAsString();
637 std::string new_name;
638 if (GuessNameForUnresolvedDependentNode(expr, *result.Context, old_name,
639 new_name)) {
640 Base::AddReplacement(result, old_name, std::move(new_name));
641 }
558 } 642 }
559 643
560 private: 644 private:
561 std::set<Replacement>* const replacements_; 645 // This method calculates a new name for nodes that depend on template
562 std::unordered_map<std::string, std::string> replacement_names_; 646 // parameters (http://en.cppreference.com/w/cpp/language/dependent_name). The
647 // renaming is based on crude heuristics, because such nodes are not bound to
648 // a specific decl until template instantiation - at the point of rename, one
649 // cannot tell whether the node will eventually resolve to a field / method /
650 // constant / etc.
651 bool GuessNameForUnresolvedDependentNode(const TargetNode& node,
652 clang::ASTContext& context,
653 const std::string& old_name,
dcheng 2016/09/10 04:00:56 Pass this as a llvm::StringRef.
Łukasz Anforowicz 2016/09/12 19:52:56 Done.
654 std::string& new_name) {
655 // |m_fieldName| -> |field_name_|.
656 if (old_name.substr(0, strlen(kBlinkFieldPrefix)) == kBlinkFieldPrefix) {
dcheng 2016/09/10 04:00:55 Then this can just use llvm::StringRef::startswith
Łukasz Anforowicz 2016/09/12 19:52:56 Done.
657 std::string field_name = old_name.substr(strlen(kBlinkFieldPrefix));
Łukasz Anforowicz 2016/09/12 19:52:56 This is the reason why in the end I've used std::s
658 if (field_name.find('_') == std::string::npos) {
659 new_name = CamelCaseToUnderscoreCase(field_name) + "_";
660 return true;
661 }
662 }
663
664 if ((old_name.find('_') == std::string::npos) && IsCallee(node, context) &&
665 !IsBlacklistedMethod(old_name, nullptr)) {
666 // |T::myMethod(...)| -> |T::MyMethod(...)|.
667 new_name = old_name;
668 new_name[0] = clang::toUppercase(new_name[0]);
669 return true;
670 }
671
672 // In the future we can consider more heuristics:
673 // - "s_" and "g_" prefixes
674 // - "ALL_CAPS"
675 // - |T::myStaticField| -> |T::kMyStaticField|
676 // (but have to be careful not to rename |value| in WTF/TypeTraits.h?)
677 return false;
678 }
563 }; 679 };
564 680
565 using FieldDeclRewriter = RewriterBase<clang::FieldDecl, clang::NamedDecl>; 681 using FieldDeclRewriter = DeclRewriterBase<clang::FieldDecl, clang::NamedDecl>;
566 using VarDeclRewriter = RewriterBase<clang::VarDecl, clang::NamedDecl>; 682 using VarDeclRewriter = DeclRewriterBase<clang::VarDecl, clang::NamedDecl>;
567 using MemberRewriter = RewriterBase<clang::FieldDecl, clang::MemberExpr>; 683 using MemberRewriter = DeclRewriterBase<clang::FieldDecl, clang::MemberExpr>;
568 using DeclRefRewriter = RewriterBase<clang::VarDecl, clang::DeclRefExpr>; 684 using DeclRefRewriter = DeclRewriterBase<clang::VarDecl, clang::DeclRefExpr>;
569 using FieldDeclRefRewriter = RewriterBase<clang::FieldDecl, clang::DeclRefExpr>; 685 using FieldDeclRefRewriter =
686 DeclRewriterBase<clang::FieldDecl, clang::DeclRefExpr>;
570 using FunctionDeclRewriter = 687 using FunctionDeclRewriter =
571 RewriterBase<clang::FunctionDecl, clang::NamedDecl>; 688 DeclRewriterBase<clang::FunctionDecl, clang::NamedDecl>;
572 using FunctionRefRewriter = 689 using FunctionRefRewriter =
573 RewriterBase<clang::FunctionDecl, clang::DeclRefExpr>; 690 DeclRewriterBase<clang::FunctionDecl, clang::DeclRefExpr>;
574 using ConstructorInitializerRewriter = 691 using ConstructorInitializerRewriter =
575 RewriterBase<clang::FieldDecl, clang::CXXCtorInitializer>; 692 DeclRewriterBase<clang::FieldDecl, clang::CXXCtorInitializer>;
576 693
577 using MethodDeclRewriter = RewriterBase<clang::CXXMethodDecl, clang::NamedDecl>; 694 using MethodDeclRewriter =
695 DeclRewriterBase<clang::CXXMethodDecl, clang::NamedDecl>;
578 using MethodRefRewriter = 696 using MethodRefRewriter =
579 RewriterBase<clang::CXXMethodDecl, clang::DeclRefExpr>; 697 DeclRewriterBase<clang::CXXMethodDecl, clang::DeclRefExpr>;
580 using MethodMemberRewriter = 698 using MethodMemberRewriter =
581 RewriterBase<clang::CXXMethodDecl, clang::MemberExpr>; 699 DeclRewriterBase<clang::CXXMethodDecl, clang::MemberExpr>;
582 700
583 using EnumConstantDeclRewriter = 701 using EnumConstantDeclRewriter =
584 RewriterBase<clang::EnumConstantDecl, clang::NamedDecl>; 702 DeclRewriterBase<clang::EnumConstantDecl, clang::NamedDecl>;
585 using EnumConstantDeclRefRewriter = 703 using EnumConstantDeclRefRewriter =
586 RewriterBase<clang::EnumConstantDecl, clang::DeclRefExpr>; 704 DeclRewriterBase<clang::EnumConstantDecl, clang::DeclRefExpr>;
587 705
588 using UnresolvedLookupRewriter = 706 using UnresolvedLookupRewriter =
589 RewriterBase<clang::NamedDecl, clang::UnresolvedLookupExpr>; 707 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedLookupExpr>;
590 using UnresolvedMemberRewriter = 708 using UnresolvedMemberRewriter =
591 RewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>; 709 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>;
592 710
593 using UsingDeclRewriter = RewriterBase<clang::UsingDecl, clang::NamedDecl>; 711 using UnresolvedDependentMemberRewriter =
712 UnresolvedRewriterBase<clang::UnresolvedMemberExpr>;
713
714 using UnresolvedUsingValueDeclRewriter =
715 UnresolvedRewriterBase<clang::UnresolvedUsingValueDecl>;
716
717 using UsingDeclRewriter = DeclRewriterBase<clang::UsingDecl, clang::NamedDecl>;
594 718
595 } // namespace 719 } // namespace
596 720
597 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); 721 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);
598 722
599 int main(int argc, const char* argv[]) { 723 int main(int argc, const char* argv[]) {
600 // TODO(dcheng): Clang tooling should do this itself. 724 // TODO(dcheng): Clang tooling should do this itself.
601 // http://llvm.org/bugs/show_bug.cgi?id=21627 725 // http://llvm.org/bugs/show_bug.cgi?id=21627
602 llvm::InitializeNativeTarget(); 726 llvm::InitializeNativeTarget();
603 llvm::InitializeNativeTargetAsmParser(); 727 llvm::InitializeNativeTargetAsmParser();
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 // UnresolvedMemberExpr matcher below are analogous to how the 979 // UnresolvedMemberExpr matcher below are analogous to how the
856 // rewriter has both a MemberRefRewriter matcher to rewrite 980 // rewriter has both a MemberRefRewriter matcher to rewrite
857 // &T::method and a MethodMemberRewriter matcher to rewriter 981 // &T::method and a MethodMemberRewriter matcher to rewriter
858 // t.method(). 982 // t.method().
859 allOverloadsMatch(anyOf(method_decl_matcher, 983 allOverloadsMatch(anyOf(method_decl_matcher,
860 method_template_decl_matcher)))))); 984 method_template_decl_matcher))))));
861 UnresolvedLookupRewriter unresolved_lookup_rewriter(&replacements); 985 UnresolvedLookupRewriter unresolved_lookup_rewriter(&replacements);
862 match_finder.addMatcher(unresolved_lookup_matcher, 986 match_finder.addMatcher(unresolved_lookup_matcher,
863 &unresolved_lookup_rewriter); 987 &unresolved_lookup_rewriter);
864 988
865 // Unresolved member expressions ======== 989 // Unresolved member expressions (for non-dependent fields / methods) ========
866 // Similar to unresolved lookup expressions, but for methods in a member 990 // Similar to unresolved lookup expressions, but for methods in a member
867 // context, e.g. var_with_templated_type.Method(). 991 // context, e.g. var_with_templated_type.Method().
868 auto unresolved_member_matcher = expr(id( 992 auto unresolved_member_matcher = expr(id(
869 "expr", 993 "expr",
870 unresolvedMemberExpr( 994 unresolvedMemberExpr(
871 // Similar to UnresolvedLookupExprs, all the candidate methods must be 995 // Similar to UnresolvedLookupExprs, all the candidate methods must be
872 // Blink methods/method templates. 996 // Blink methods/method templates.
873 allOverloadsMatch( 997 allOverloadsMatch(
874 anyOf(method_decl_matcher, method_template_decl_matcher))))); 998 anyOf(method_decl_matcher, method_template_decl_matcher)))));
875 UnresolvedMemberRewriter unresolved_member_rewriter(&replacements); 999 UnresolvedMemberRewriter unresolved_member_rewriter(&replacements);
876 match_finder.addMatcher(unresolved_member_matcher, 1000 match_finder.addMatcher(unresolved_member_matcher,
877 &unresolved_member_rewriter); 1001 &unresolved_member_rewriter);
878 1002
1003 // Unresolved using value decls ========
1004 // Example:
1005 // template <typename T>
1006 // class BaseClass {
1007 // public:
1008 // unsigned long m_size;
1009 // };
1010 // template <typename T>
1011 // class DerivedClass : protected BaseClass<T> {
1012 // private:
1013 // using Base = BaseClass<T>;
1014 // using Base::m_size; <- matched by |unresolved_using_value_decl_matcher|.
1015 // void method() {
1016 // m_size = 123; // <- |m_size| matched by
1017 // } // |unresolved_dependent_using_matcher|.
1018 // };
1019 auto unresolved_dependent_using_matcher =
1020 expr(id("expr", unresolvedMemberExpr(allOverloadsMatch(allOf(
1021 in_blink_namespace, unresolvedUsingValueDecl())))));
1022 UnresolvedDependentMemberRewriter unresolved_dependent_member_rewriter(
1023 &replacements);
1024 match_finder.addMatcher(unresolved_dependent_using_matcher,
1025 &unresolved_dependent_member_rewriter);
1026 auto unresolved_using_value_decl_matcher =
1027 decl(id("decl", unresolvedUsingValueDecl(in_blink_namespace)));
1028 UnresolvedUsingValueDeclRewriter unresolved_using_value_decl_rewriter(
1029 &replacements);
1030 match_finder.addMatcher(unresolved_using_value_decl_matcher,
1031 &unresolved_using_value_decl_rewriter);
1032
879 // Using declarations ======== 1033 // Using declarations ========
880 // Given 1034 // Given
881 // using blink::X; 1035 // using blink::X;
882 // matches |using blink::X|. 1036 // matches |using blink::X|.
883 auto using_decl_matcher = id( 1037 auto using_decl_matcher = id(
884 "decl", usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(anyOf( 1038 "decl", usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(anyOf(
885 var_decl_matcher, field_decl_matcher, function_decl_matcher, 1039 var_decl_matcher, field_decl_matcher, function_decl_matcher,
886 method_decl_matcher, function_template_decl_matcher, 1040 method_decl_matcher, function_template_decl_matcher,
887 method_template_decl_matcher, enum_member_decl_matcher))))); 1041 method_template_decl_matcher, enum_member_decl_matcher)))));
888 UsingDeclRewriter using_decl_rewriter(&replacements); 1042 UsingDeclRewriter using_decl_rewriter(&replacements);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 for (const auto& r : replacements) { 1086 for (const auto& r : replacements) {
933 std::string replacement_text = r.getReplacementText().str(); 1087 std::string replacement_text = r.getReplacementText().str();
934 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); 1088 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0');
935 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() 1089 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset()
936 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; 1090 << ":::" << r.getLength() << ":::" << replacement_text << "\n";
937 } 1091 }
938 llvm::outs() << "==== END EDITS ====\n"; 1092 llvm::outs() << "==== END EDITS ====\n";
939 1093
940 return 0; 1094 return 0;
941 } 1095 }
OLDNEW
« no previous file with comments | « no previous file | tools/clang/rewrite_to_chrome_style/tests/template-expected.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698