Chromium Code Reviews| 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 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 723 | 723 |
| 724 return false; | 724 return false; |
| 725 } | 725 } |
| 726 | 726 |
| 727 AST_MATCHER(clang::FunctionDecl, shouldPrefixFunctionName) { | 727 AST_MATCHER(clang::FunctionDecl, shouldPrefixFunctionName) { |
| 728 return ShouldPrefixFunctionName(Node.getName().str()); | 728 return ShouldPrefixFunctionName(Node.getName().str()); |
| 729 } | 729 } |
| 730 | 730 |
| 731 bool GetNameForDecl(const clang::FunctionDecl& decl, | 731 bool GetNameForDecl(const clang::FunctionDecl& decl, |
| 732 clang::ASTContext& context, | 732 clang::ASTContext& context, |
| 733 bool for_type_trait, | |
| 734 std::string& name) { | 733 std::string& name) { |
| 735 name = decl.getName().str(); | 734 name = decl.getName().str(); |
| 736 name[0] = clang::toUppercase(name[0]); | 735 name[0] = clang::toUppercase(name[0]); |
| 737 | 736 |
| 738 // Given | 737 // Given |
| 739 // class Foo {}; | 738 // class Foo {}; |
| 740 // class DerivedFoo : class Foo; | 739 // class DerivedFoo : class Foo; |
| 741 // using Bar = Foo; | 740 // using Bar = Foo; |
| 742 // Bar f1(); // <- |Bar| would be matched by hasString("Bar") below. | 741 // Bar f1(); // <- |Bar| would be matched by hasString("Bar") below. |
| 743 // Bar f2(); // <- |Bar| would be matched by hasName("Foo") below. | 742 // Bar f2(); // <- |Bar| would be matched by hasName("Foo") below. |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 771 // And also check hardcoded list of function names to prefix with "Get". | 770 // And also check hardcoded list of function names to prefix with "Get". |
| 772 shouldPrefixFunctionName())); | 771 shouldPrefixFunctionName())); |
| 773 if (IsMatching(conflict_matcher, decl, context)) | 772 if (IsMatching(conflict_matcher, decl, context)) |
| 774 name = "Get" + name; | 773 name = "Get" + name; |
| 775 | 774 |
| 776 return true; | 775 return true; |
| 777 } | 776 } |
| 778 | 777 |
| 779 bool GetNameForDecl(const clang::EnumConstantDecl& decl, | 778 bool GetNameForDecl(const clang::EnumConstantDecl& decl, |
| 780 clang::ASTContext& context, | 779 clang::ASTContext& context, |
| 781 bool for_type_trait, | |
| 782 std::string& name) { | 780 std::string& name) { |
| 783 StringRef original_name = decl.getName(); | 781 StringRef original_name = decl.getName(); |
| 784 | 782 |
| 785 // If it's already correct leave it alone. | 783 // If it's already correct leave it alone. |
| 786 if (original_name.size() >= 2 && original_name[0] == 'k' && | 784 if (original_name.size() >= 2 && original_name[0] == 'k' && |
| 787 clang::isUppercase(original_name[1])) | 785 clang::isUppercase(original_name[1])) |
| 788 return false; | 786 return false; |
| 789 | 787 |
| 790 bool is_shouty = true; | 788 bool is_shouty = true; |
| 791 for (char c : original_name) { | 789 for (char c : original_name) { |
| 792 if (!clang::isUppercase(c) && !clang::isDigit(c) && c != '_') { | 790 if (!clang::isUppercase(c) && !clang::isDigit(c) && c != '_') { |
| 793 is_shouty = false; | 791 is_shouty = false; |
| 794 break; | 792 break; |
| 795 } | 793 } |
| 796 } | 794 } |
| 797 | 795 |
| 798 if (is_shouty) | 796 if (is_shouty) |
| 799 return false; | 797 return false; |
| 800 | 798 |
| 801 name = 'k'; // k prefix on enum values. | 799 name = 'k'; // k prefix on enum values. |
| 802 name += original_name; | 800 name += original_name; |
| 803 name[1] = clang::toUppercase(name[1]); | 801 name[1] = clang::toUppercase(name[1]); |
| 804 return true; | 802 return true; |
| 805 } | 803 } |
| 806 | 804 |
| 807 bool GetNameForDecl(const clang::FieldDecl& decl, | 805 bool GetNameForDecl(const clang::FieldDecl& decl, |
| 808 clang::ASTContext& context, | 806 clang::ASTContext& context, |
| 809 bool for_type_trait, | |
| 810 std::string& name) { | 807 std::string& name) { |
| 811 StringRef original_name = decl.getName(); | 808 StringRef original_name = decl.getName(); |
| 812 bool member_prefix = original_name.startswith(kBlinkFieldPrefix); | 809 bool member_prefix = original_name.startswith(kBlinkFieldPrefix); |
| 813 | 810 |
| 814 StringRef rename_part = !member_prefix | 811 StringRef rename_part = !member_prefix |
| 815 ? original_name | 812 ? original_name |
| 816 : original_name.substr(strlen(kBlinkFieldPrefix)); | 813 : original_name.substr(strlen(kBlinkFieldPrefix)); |
| 817 name = CamelCaseToUnderscoreCase(rename_part); | 814 name = CamelCaseToUnderscoreCase(rename_part); |
| 818 | 815 |
| 819 // Assume that prefix of m_ was intentional and always replace it with a | 816 // Assume that prefix of m_ was intentional and always replace it with a |
| 820 // suffix _. | 817 // suffix _. |
| 821 if (member_prefix && name.back() != '_') | 818 if (member_prefix && name.back() != '_') |
| 822 name += '_'; | 819 name += '_'; |
| 823 | 820 |
| 824 return true; | 821 return true; |
| 825 } | 822 } |
| 826 | 823 |
| 827 bool GetNameForDecl(const clang::VarDecl& decl, | 824 bool GetNameForDecl(const clang::VarDecl& decl, |
| 828 clang::ASTContext& context, | 825 clang::ASTContext& context, |
| 829 bool for_type_trait, | |
| 830 std::string& name) { | 826 std::string& name) { |
| 831 StringRef original_name = decl.getName(); | 827 StringRef original_name = decl.getName(); |
| 832 | 828 |
| 833 // Nothing to do for unnamed parameters. | 829 // Nothing to do for unnamed parameters. |
| 834 if (clang::isa<clang::ParmVarDecl>(decl)) { | 830 if (clang::isa<clang::ParmVarDecl>(decl)) { |
| 835 if (original_name.empty()) | 831 if (original_name.empty()) |
| 836 return false; | 832 return false; |
| 837 | 833 |
| 838 // Check if |decl| and |decl.getLocation| are in sync. We need to skip | 834 // Check if |decl| and |decl.getLocation| are in sync. We need to skip |
| 839 // out-of-sync ParmVarDecls to avoid renaming buggy ParmVarDecls that | 835 // out-of-sync ParmVarDecls to avoid renaming buggy ParmVarDecls that |
| 840 // 1) have decl.getLocation() pointing at a parameter declaration without a | 836 // 1) have decl.getLocation() pointing at a parameter declaration without a |
| 841 // name, but 2) have decl.getName() retained from a template specialization | 837 // name, but 2) have decl.getName() retained from a template specialization |
| 842 // of a method. See also: https://llvm.org/bugs/show_bug.cgi?id=29145 | 838 // of a method. See also: https://llvm.org/bugs/show_bug.cgi?id=29145 |
| 843 clang::SourceLocation loc = | 839 clang::SourceLocation loc = |
| 844 context.getSourceManager().getSpellingLoc(decl.getLocation()); | 840 context.getSourceManager().getSpellingLoc(decl.getLocation()); |
| 845 auto parents = context.getParents(decl); | 841 auto parents = context.getParents(decl); |
| 846 bool is_child_location_within_parent_source_range = std::all_of( | 842 bool is_child_location_within_parent_source_range = std::all_of( |
| 847 parents.begin(), parents.end(), | 843 parents.begin(), parents.end(), |
| 848 [&loc](const clang::ast_type_traits::DynTypedNode& parent) { | 844 [&loc](const clang::ast_type_traits::DynTypedNode& parent) { |
| 849 clang::SourceLocation begin = parent.getSourceRange().getBegin(); | 845 clang::SourceLocation begin = parent.getSourceRange().getBegin(); |
| 850 clang::SourceLocation end = parent.getSourceRange().getEnd(); | 846 clang::SourceLocation end = parent.getSourceRange().getEnd(); |
| 851 return (begin < loc) && (loc < end); | 847 return (begin < loc) && (loc < end); |
| 852 }); | 848 }); |
| 853 if (!is_child_location_within_parent_source_range) | 849 if (!is_child_location_within_parent_source_range) |
| 854 return false; | 850 return false; |
| 855 } | 851 } |
| 856 | 852 |
| 853 // This is a type trait that appears in consumers of WTF as well as inside | |
| 854 // WTF. We want it to be named in this_style_of_case accordingly. | |
| 855 if (IsKnownTraitName(original_name)) { | |
| 856 name = CamelCaseToUnderscoreCase(original_name); | |
| 857 return true; | |
| 858 } | |
| 859 | |
| 857 // static class members match against VarDecls. Blink style dictates that | 860 // static class members match against VarDecls. Blink style dictates that |
| 858 // these should be prefixed with `s_`, so strip that off. Also check for `m_` | 861 // these should be prefixed with `s_`, so strip that off. Also check for `m_` |
| 859 // and strip that off too, for code that accidentally uses the wrong prefix. | 862 // and strip that off too, for code that accidentally uses the wrong prefix. |
| 860 if (original_name.startswith(kBlinkStaticMemberPrefix)) | 863 if (original_name.startswith(kBlinkStaticMemberPrefix)) |
| 861 original_name = original_name.substr(strlen(kBlinkStaticMemberPrefix)); | 864 original_name = original_name.substr(strlen(kBlinkStaticMemberPrefix)); |
| 862 else if (original_name.startswith(kBlinkFieldPrefix)) | 865 else if (original_name.startswith(kBlinkFieldPrefix)) |
| 863 original_name = original_name.substr(strlen(kBlinkFieldPrefix)); | 866 original_name = original_name.substr(strlen(kBlinkFieldPrefix)); |
| 864 | 867 |
| 865 // Type traits are written in_this_form rather than kInThisForm and not like | |
| 866 // members. | |
| 867 if (for_type_trait) { | |
| 868 name = CamelCaseToUnderscoreCase(original_name); | |
| 869 return true; | |
| 870 } | |
| 871 | |
| 872 bool is_const = IsProbablyConst(decl, context); | 868 bool is_const = IsProbablyConst(decl, context); |
| 873 if (is_const) { | 869 if (is_const) { |
| 874 // Don't try to rename constants that already conform to Chrome style. | 870 // Don't try to rename constants that already conform to Chrome style. |
| 875 if (original_name.size() >= 2 && original_name[0] == 'k' && | 871 if (original_name.size() >= 2 && original_name[0] == 'k' && |
| 876 clang::isUppercase(original_name[1])) | 872 clang::isUppercase(original_name[1])) |
| 877 return false; | 873 return false; |
| 878 // Or names are spelt with underscore casing. While they are actually | 874 // Or names are spelt with underscore casing. While they are actually |
| 879 // compile consts, the author wrote it explicitly as a variable not as | 875 // compile consts, the author wrote it explicitly as a variable not as |
| 880 // a constant (they would have used kFormat otherwise here), so preserve | 876 // a constant (they would have used kFormat otherwise here), so preserve |
| 881 // it rather than try to mangle a kFormat out of it. | 877 // it rather than try to mangle a kFormat out of it. |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 900 // not. | 896 // not. |
| 901 if (!is_const && decl.isStaticDataMember()) { | 897 if (!is_const && decl.isStaticDataMember()) { |
| 902 name += '_'; | 898 name += '_'; |
| 903 } | 899 } |
| 904 | 900 |
| 905 return true; | 901 return true; |
| 906 } | 902 } |
| 907 | 903 |
| 908 bool GetNameForDecl(const clang::FunctionTemplateDecl& decl, | 904 bool GetNameForDecl(const clang::FunctionTemplateDecl& decl, |
| 909 clang::ASTContext& context, | 905 clang::ASTContext& context, |
| 910 bool for_type_trait, | |
| 911 std::string& name) { | 906 std::string& name) { |
| 912 clang::FunctionDecl* templated_function = decl.getTemplatedDecl(); | 907 clang::FunctionDecl* templated_function = decl.getTemplatedDecl(); |
| 913 return GetNameForDecl(*templated_function, context, for_type_trait, name); | 908 return GetNameForDecl(*templated_function, context, name); |
| 914 } | 909 } |
| 915 | 910 |
| 916 bool GetNameForDecl(const clang::NamedDecl& decl, | 911 bool GetNameForDecl(const clang::NamedDecl& decl, |
| 917 clang::ASTContext& context, | 912 clang::ASTContext& context, |
| 918 bool for_type_trait, | |
| 919 std::string& name) { | 913 std::string& name) { |
| 920 if (auto* function = clang::dyn_cast<clang::FunctionDecl>(&decl)) | 914 if (auto* function = clang::dyn_cast<clang::FunctionDecl>(&decl)) |
| 921 return GetNameForDecl(*function, context, for_type_trait, name); | 915 return GetNameForDecl(*function, context, name); |
| 922 if (auto* var = clang::dyn_cast<clang::VarDecl>(&decl)) | 916 if (auto* var = clang::dyn_cast<clang::VarDecl>(&decl)) |
| 923 return GetNameForDecl(*var, context, for_type_trait, name); | 917 return GetNameForDecl(*var, context, name); |
| 924 if (auto* field = clang::dyn_cast<clang::FieldDecl>(&decl)) | 918 if (auto* field = clang::dyn_cast<clang::FieldDecl>(&decl)) |
| 925 return GetNameForDecl(*field, context, for_type_trait, name); | 919 return GetNameForDecl(*field, context, name); |
| 926 if (auto* function_template = | 920 if (auto* function_template = |
| 927 clang::dyn_cast<clang::FunctionTemplateDecl>(&decl)) | 921 clang::dyn_cast<clang::FunctionTemplateDecl>(&decl)) |
| 928 return GetNameForDecl(*function_template, context, for_type_trait, name); | 922 return GetNameForDecl(*function_template, context, name); |
| 929 if (auto* enumc = clang::dyn_cast<clang::EnumConstantDecl>(&decl)) | 923 if (auto* enumc = clang::dyn_cast<clang::EnumConstantDecl>(&decl)) |
| 930 return GetNameForDecl(*enumc, context, for_type_trait, name); | 924 return GetNameForDecl(*enumc, context, name); |
| 931 | 925 |
| 932 return false; | 926 return false; |
| 933 } | 927 } |
| 934 | 928 |
| 935 bool GetNameForDecl(const clang::UsingDecl& decl, | 929 bool GetNameForDecl(const clang::UsingDecl& decl, |
| 936 clang::ASTContext& context, | 930 clang::ASTContext& context, |
| 937 bool for_type_trait, | |
| 938 std::string& name) { | 931 std::string& name) { |
| 939 assert(decl.shadow_size() > 0); | 932 assert(decl.shadow_size() > 0); |
| 940 | 933 |
| 941 // If a using declaration's targeted declaration is a set of overloaded | 934 // If a using declaration's targeted declaration is a set of overloaded |
| 942 // functions, it can introduce multiple shadowed declarations. Just using the | 935 // functions, it can introduce multiple shadowed declarations. Just using the |
| 943 // first one is OK, since overloaded functions have the same name, by | 936 // first one is OK, since overloaded functions have the same name, by |
| 944 // definition. | 937 // definition. |
| 945 return GetNameForDecl(*decl.shadow_begin()->getTargetDecl(), context, | 938 return GetNameForDecl(*decl.shadow_begin()->getTargetDecl(), context, name); |
| 946 for_type_trait, name); | |
| 947 } | 939 } |
| 948 | 940 |
| 949 template <typename Type> | 941 template <typename Type> |
| 950 struct TargetNodeTraits; | 942 struct TargetNodeTraits; |
| 951 | 943 |
| 952 template <> | 944 template <> |
| 953 struct TargetNodeTraits<clang::NamedDecl> { | 945 struct TargetNodeTraits<clang::NamedDecl> { |
| 954 static clang::SourceLocation GetLoc(const clang::NamedDecl& decl) { | 946 static clang::SourceLocation GetLoc(const clang::NamedDecl& decl) { |
| 955 return decl.getLocation(); | 947 return decl.getLocation(); |
| 956 } | 948 } |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1141 const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl"); | 1133 const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl"); |
| 1142 assert(decl); | 1134 assert(decl); |
| 1143 llvm::StringRef old_name = decl->getName(); | 1135 llvm::StringRef old_name = decl->getName(); |
| 1144 | 1136 |
| 1145 // Return early if there's no name to be renamed. | 1137 // Return early if there's no name to be renamed. |
| 1146 if (!decl->getIdentifier()) | 1138 if (!decl->getIdentifier()) |
| 1147 return; | 1139 return; |
| 1148 | 1140 |
| 1149 // Get the new name. | 1141 // Get the new name. |
| 1150 std::string new_name; | 1142 std::string new_name; |
| 1151 if (!GetNameForDecl(*decl, *result.Context, for_type_traits_, new_name)) | 1143 if (!GetNameForDecl(*decl, *result.Context, new_name)) |
| 1152 return; // If false, the name was not suitable for renaming. | 1144 return; // If false, the name was not suitable for renaming. |
| 1153 | 1145 |
| 1154 // Check if we are able to rewrite the decl (to avoid rewriting if the | 1146 // Check if we are able to rewrite the decl (to avoid rewriting if the |
| 1155 // decl's identifier is part of macro##Token##Concatenation). | 1147 // decl's identifier is part of macro##Token##Concatenation). |
| 1156 clang::SourceLocation decl_loc = | 1148 clang::SourceLocation decl_loc = |
| 1157 TargetNodeTraits<clang::NamedDecl>::GetLoc(*decl); | 1149 TargetNodeTraits<clang::NamedDecl>::GetLoc(*decl); |
| 1158 if (!Base::GenerateReplacement(result, decl_loc, old_name, new_name, | 1150 if (!Base::GenerateReplacement(result, decl_loc, old_name, new_name, |
| 1159 nullptr)) | 1151 nullptr)) |
| 1160 return; | 1152 return; |
| 1161 | 1153 |
| 1162 Base::AddReplacement(result, old_name, std::move(new_name)); | 1154 Base::AddReplacement(result, old_name, std::move(new_name)); |
| 1163 } | 1155 } |
| 1164 | |
| 1165 void set_for_type_traits(bool set) { for_type_traits_ = set; } | |
| 1166 | |
| 1167 protected: | |
| 1168 bool for_type_traits_ = false; | |
| 1169 }; | 1156 }; |
| 1170 | 1157 |
| 1171 using FieldDeclRewriter = DeclRewriterBase<clang::FieldDecl, clang::NamedDecl>; | 1158 using FieldDeclRewriter = DeclRewriterBase<clang::FieldDecl, clang::NamedDecl>; |
| 1172 using VarDeclRewriter = DeclRewriterBase<clang::VarDecl, clang::NamedDecl>; | 1159 using VarDeclRewriter = DeclRewriterBase<clang::VarDecl, clang::NamedDecl>; |
| 1173 using MemberRewriter = DeclRewriterBase<clang::FieldDecl, clang::MemberExpr>; | 1160 using MemberRewriter = DeclRewriterBase<clang::FieldDecl, clang::MemberExpr>; |
| 1174 using DeclRefRewriter = DeclRewriterBase<clang::VarDecl, clang::DeclRefExpr>; | 1161 using DeclRefRewriter = DeclRewriterBase<clang::VarDecl, clang::DeclRefExpr>; |
| 1175 using FieldDeclRefRewriter = | 1162 using FieldDeclRefRewriter = |
| 1176 DeclRewriterBase<clang::FieldDecl, clang::DeclRefExpr>; | 1163 DeclRewriterBase<clang::FieldDecl, clang::DeclRefExpr>; |
| 1177 using FunctionDeclRewriter = | 1164 using FunctionDeclRewriter = |
| 1178 DeclRewriterBase<clang::FunctionDecl, clang::NamedDecl>; | 1165 DeclRewriterBase<clang::FunctionDecl, clang::NamedDecl>; |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1486 | 1473 |
| 1487 // Field, variable, and enum declarations ======== | 1474 // Field, variable, and enum declarations ======== |
| 1488 // Given | 1475 // Given |
| 1489 // int x; | 1476 // int x; |
| 1490 // struct S { | 1477 // struct S { |
| 1491 // int y; | 1478 // int y; |
| 1492 // enum { VALUE }; | 1479 // enum { VALUE }; |
| 1493 // }; | 1480 // }; |
| 1494 // matches |x|, |y|, and |VALUE|. | 1481 // matches |x|, |y|, and |VALUE|. |
| 1495 auto field_decl_matcher = id("decl", fieldDecl(in_blink_namespace)); | 1482 auto field_decl_matcher = id("decl", fieldDecl(in_blink_namespace)); |
| 1496 auto is_type_trait_value = varDecl( | 1483 auto is_type_trait_value = |
| 1497 anyOf(hasName("value"), isKnownTraitName()), hasStaticStorageDuration(), | 1484 varDecl(hasName("value"), hasStaticStorageDuration(), isPublic(), |
| 1498 isPublic(), hasType(isConstQualified()), | 1485 hasType(isConstQualified()), |
| 1499 hasType(type(anyOf(builtinType(), enumType()))), | 1486 hasType(type(anyOf(builtinType(), enumType()))), |
| 1500 unless(hasAncestor(recordDecl( | 1487 unless(hasAncestor(recordDecl( |
| 1501 has(cxxMethodDecl(isUserProvided(), isInstanceMethod())))))); | 1488 has(cxxMethodDecl(isUserProvided(), isInstanceMethod())))))); |
| 1502 auto var_decl_matcher = | 1489 auto var_decl_matcher = |
| 1503 id("decl", varDecl(in_blink_namespace, unless(is_type_trait_value))); | 1490 id("decl", varDecl(in_blink_namespace, unless(is_type_trait_value))); |
| 1504 auto type_trait_matcher = | 1491 auto type_trait_decl_matcher = id("decl", varDecl(isKnownTraitName())); |
|
dcheng
2017/01/31 00:01:05
Is it OK to skip is_type_trait_value here now?
danakj
2017/01/31 00:02:32
Yeh, we'll just do it for all names that match now
danakj
2017/01/31 00:03:06
It will match any vardecl in the codebase, but it
dcheng
2017/01/31 00:08:31
I'm probably missing something, but don't we need
danakj
2017/01/31 00:09:58
Right, the other ones are all named value and are
| |
| 1505 id("decl", varDecl(is_type_trait_value, unless(hasName("value")))); | |
| 1506 auto enum_member_decl_matcher = | 1492 auto enum_member_decl_matcher = |
| 1507 id("decl", enumConstantDecl(in_blink_namespace)); | 1493 id("decl", enumConstantDecl(in_blink_namespace)); |
| 1508 | 1494 |
| 1509 FieldDeclRewriter field_decl_rewriter(&replacements); | 1495 FieldDeclRewriter field_decl_rewriter(&replacements); |
| 1510 match_finder.addMatcher(field_decl_matcher, &field_decl_rewriter); | 1496 match_finder.addMatcher(field_decl_matcher, &field_decl_rewriter); |
| 1511 | 1497 |
| 1512 VarDeclRewriter var_decl_rewriter(&replacements); | 1498 VarDeclRewriter var_decl_rewriter(&replacements); |
| 1513 match_finder.addMatcher(var_decl_matcher, &var_decl_rewriter); | 1499 match_finder.addMatcher(var_decl_matcher, &var_decl_rewriter); |
| 1514 | 1500 match_finder.addMatcher(type_trait_decl_matcher, &var_decl_rewriter); |
| 1515 VarDeclRewriter type_trait_rewriter(&replacements); | |
| 1516 type_trait_rewriter.set_for_type_traits(true); | |
| 1517 match_finder.addMatcher(type_trait_matcher, &type_trait_rewriter); | |
| 1518 | 1501 |
| 1519 EnumConstantDeclRewriter enum_member_decl_rewriter(&replacements); | 1502 EnumConstantDeclRewriter enum_member_decl_rewriter(&replacements); |
| 1520 match_finder.addMatcher(enum_member_decl_matcher, &enum_member_decl_rewriter); | 1503 match_finder.addMatcher(enum_member_decl_matcher, &enum_member_decl_rewriter); |
| 1521 | 1504 |
| 1522 // Field, variable, and enum references ======== | 1505 // Field, variable, and enum references ======== |
| 1523 // Given | 1506 // Given |
| 1524 // bool x = true; | 1507 // bool x = true; |
| 1525 // if (x) { | 1508 // if (x) { |
| 1526 // ... | 1509 // ... |
| 1527 // } | 1510 // } |
| 1528 // matches |x| in if (x). | 1511 // matches |x| in if (x). |
| 1529 auto member_matcher = id( | 1512 auto member_matcher = id( |
| 1530 "expr", | 1513 "expr", |
| 1531 memberExpr( | 1514 memberExpr( |
| 1532 member(field_decl_matcher), | 1515 member(field_decl_matcher), |
| 1533 // Needed to avoid matching member references in functions (which will | 1516 // Needed to avoid matching member references in functions (which will |
| 1534 // be an ancestor of the member reference) synthesized by the | 1517 // be an ancestor of the member reference) synthesized by the |
| 1535 // compiler, such as a synthesized copy constructor. | 1518 // compiler, such as a synthesized copy constructor. |
| 1536 // This skips explicitly defaulted functions as well, but that's OK: | 1519 // This skips explicitly defaulted functions as well, but that's OK: |
| 1537 // there's nothing interesting to rewrite in those either. | 1520 // there's nothing interesting to rewrite in those either. |
| 1538 unless(hasAncestor(functionDecl(isDefaulted()))))); | 1521 unless(hasAncestor(functionDecl(isDefaulted()))))); |
| 1539 auto decl_ref_matcher = id("expr", declRefExpr(to(var_decl_matcher))); | 1522 auto decl_ref_matcher = id("expr", declRefExpr(to(var_decl_matcher))); |
| 1540 auto type_trait_ref_matcher = id("expr", declRefExpr(to(type_trait_matcher))); | 1523 auto type_trait_ref_matcher = |
| 1524 id("expr", declRefExpr(to(type_trait_decl_matcher))); | |
| 1541 auto enum_member_ref_matcher = | 1525 auto enum_member_ref_matcher = |
| 1542 id("expr", declRefExpr(to(enum_member_decl_matcher))); | 1526 id("expr", declRefExpr(to(enum_member_decl_matcher))); |
| 1543 | 1527 |
| 1544 MemberRewriter member_rewriter(&replacements); | 1528 MemberRewriter member_rewriter(&replacements); |
| 1545 match_finder.addMatcher(member_matcher, &member_rewriter); | 1529 match_finder.addMatcher(member_matcher, &member_rewriter); |
| 1546 | 1530 |
| 1547 DeclRefRewriter decl_ref_rewriter(&replacements); | 1531 DeclRefRewriter decl_ref_rewriter(&replacements); |
| 1548 match_finder.addMatcher(decl_ref_matcher, &decl_ref_rewriter); | 1532 match_finder.addMatcher(decl_ref_matcher, &decl_ref_rewriter); |
| 1549 | 1533 match_finder.addMatcher(type_trait_ref_matcher, &decl_ref_rewriter); |
| 1550 DeclRefRewriter type_trait_ref_rewriter(&replacements); | |
| 1551 type_trait_ref_rewriter.set_for_type_traits(true); | |
| 1552 match_finder.addMatcher(type_trait_ref_matcher, &type_trait_ref_rewriter); | |
| 1553 | 1534 |
| 1554 EnumConstantDeclRefRewriter enum_member_ref_rewriter(&replacements); | 1535 EnumConstantDeclRefRewriter enum_member_ref_rewriter(&replacements); |
| 1555 match_finder.addMatcher(enum_member_ref_matcher, &enum_member_ref_rewriter); | 1536 match_finder.addMatcher(enum_member_ref_matcher, &enum_member_ref_rewriter); |
| 1556 | 1537 |
| 1557 // Member references in a non-member context ======== | 1538 // Member references in a non-member context ======== |
| 1558 // Given | 1539 // Given |
| 1559 // struct S { | 1540 // struct S { |
| 1560 // typedef int U::*UnspecifiedBoolType; | 1541 // typedef int U::*UnspecifiedBoolType; |
| 1561 // operator UnspecifiedBoolType() { return s_ ? &U::s_ : 0; } | 1542 // operator UnspecifiedBoolType() { return s_ ? &U::s_ : 0; } |
| 1562 // int s_; | 1543 // int s_; |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1861 for (const auto& r : replacements) { | 1842 for (const auto& r : replacements) { |
| 1862 std::string replacement_text = r.getReplacementText().str(); | 1843 std::string replacement_text = r.getReplacementText().str(); |
| 1863 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); | 1844 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); |
| 1864 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() | 1845 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() |
| 1865 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; | 1846 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; |
| 1866 } | 1847 } |
| 1867 llvm::outs() << "==== END EDITS ====\n"; | 1848 llvm::outs() << "==== END EDITS ====\n"; |
| 1868 | 1849 |
| 1869 return 0; | 1850 return 0; |
| 1870 } | 1851 } |
| OLD | NEW |