Chromium Code Reviews| Index: tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp |
| diff --git a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp |
| index 4f607edfe19262d174add2b3ebb3c66375277b66..670a636d01fb9e9b96ab6bb4d906b932879688c8 100644 |
| --- a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp |
| +++ b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp |
| @@ -55,6 +55,14 @@ const clang::ast_matchers::internal:: |
| VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr> |
| unresolvedMemberExpr; |
| +const clang::ast_matchers::internal:: |
| + VariadicDynCastAllOfMatcher<clang::Expr, clang::DependentScopeDeclRefExpr> |
| + dependentScopeDeclRefExpr; |
| + |
| +const clang::ast_matchers::internal:: |
| + VariadicDynCastAllOfMatcher<clang::Expr, clang::CXXDependentScopeMemberExpr> |
| + cxxDependentScopeMemberExpr; |
| + |
| AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) { |
| return Node.isOverloadedOperator(); |
| } |
| @@ -150,6 +158,44 @@ AST_MATCHER_P(clang::CXXMethodDecl, |
| return MatchAllOverriddenMethods(Node, InnerMatcher, Finder, Builder); |
| } |
| +// Matches |x.m| CXXDependentScopeMemberExpr if InnerMatcher matches |x|. |
| +AST_MATCHER_P(clang::CXXDependentScopeMemberExpr, |
| + hasBaseExpr, |
| + clang::ast_matchers::internal::Matcher<clang::Expr>, |
| + InnerMatcher) { |
| + clang::Expr* base_expr = Node.isImplicitAccess() ? nullptr : Node.getBase(); |
| + return base_expr && InnerMatcher.matches(*base_expr, Finder, Builder); |
| +} |
| + |
| +// Matches |T::m| CXXDependentScopeMemberExpr if InnerMatcher matches |T|. |
| +AST_MATCHER_P( |
| + clang::CXXDependentScopeMemberExpr, |
| + hasDependentQualifier, |
| + clang::ast_matchers::internal::Matcher<clang::NestedNameSpecifier>, |
| + InnerMatcher) { |
| + clang::NestedNameSpecifier* qual = Node.getQualifier(); |
| + return qual && InnerMatcher.matches(*qual, Finder, Builder); |
| +} |
| + |
| +// Matches |T::m| DependentScopeDeclRefExpr if InnerMatcher matches |T|. |
| +AST_MATCHER_P( |
| + clang::DependentScopeDeclRefExpr, |
| + dependentScopeIfQualifier, |
| + clang::ast_matchers::internal::Matcher<clang::NestedNameSpecifier>, |
| + InnerMatcher) { |
| + clang::NestedNameSpecifier* qual = Node.getQualifier(); |
| + return qual && InnerMatcher.matches(*qual, Finder, Builder); |
| +} |
| + |
| +// Matches |const Class<T>&| QualType if InnerMatcher matches |Class<T>|. |
| +AST_MATCHER_P(clang::QualType, |
| + hasUnderlyingType, |
| + clang::ast_matchers::internal::Matcher<clang::Type>, |
| + InnerMatcher) { |
| + const clang::Type* type = Node.getTypePtrOrNull(); |
| + return type && InnerMatcher.matches(*type, Finder, Builder); |
| +} |
| + |
| bool IsMethodOverrideOf(const clang::CXXMethodDecl& decl, |
| const char* class_name) { |
| if (decl.getParent()->getQualifiedNameAsString() == class_name) |
| @@ -477,6 +523,24 @@ struct TargetNodeTraits<clang::DeclRefExpr> { |
| }; |
| template <> |
| +struct TargetNodeTraits<clang::DependentScopeDeclRefExpr> { |
| + static clang::SourceLocation GetLoc( |
| + const clang::DependentScopeDeclRefExpr& expr) { |
| + return expr.getLocation(); |
| + } |
| + static const char* GetName() { return "expr"; } |
| +}; |
| + |
| +template <> |
| +struct TargetNodeTraits<clang::CXXDependentScopeMemberExpr> { |
| + static clang::SourceLocation GetLoc( |
| + const clang::CXXDependentScopeMemberExpr& expr) { |
| + return expr.getMemberLoc(); |
| + } |
| + static const char* GetName() { return "expr"; } |
| +}; |
| + |
| +template <> |
| struct TargetNodeTraits<clang::CXXCtorInitializer> { |
| static clang::SourceLocation GetLoc(const clang::CXXCtorInitializer& init) { |
| assert(init.isWritten()); |
| @@ -586,6 +650,14 @@ llvm::StringRef GetCurrentName(const clang::UnresolvedMemberExpr& expr) { |
| return expr.getMemberName().getAsString(); |
| } |
| +llvm::StringRef GetCurrentName(const clang::DependentScopeDeclRefExpr& expr) { |
| + return expr.getDeclName().getAsString(); |
| +} |
| + |
| +llvm::StringRef GetCurrentName(const clang::CXXDependentScopeMemberExpr& expr) { |
| + return expr.getMember().getAsString(); |
| +} |
| + |
| llvm::StringRef GetCurrentName(const clang::NamedDecl& decl) { |
| return decl.getName(); |
| } |
| @@ -696,6 +768,12 @@ using UnresolvedUsingValueDeclRewriter = |
| using UsingDeclRewriter = DeclRewriterBase<clang::UsingDecl, clang::NamedDecl>; |
| +using DependentScopeDeclRefExprRewriter = |
| + UnresolvedRewriterBase<clang::DependentScopeDeclRefExpr>; |
| + |
| +using CXXDependentScopeMemberExprRewriter = |
| + UnresolvedRewriterBase<clang::CXXDependentScopeMemberExpr>; |
| + |
| } // namespace |
| static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); |
| @@ -995,6 +1073,50 @@ int main(int argc, const char* argv[]) { |
| UsingDeclRewriter using_decl_rewriter(&replacements); |
| match_finder.addMatcher(using_decl_matcher, &using_decl_rewriter); |
| + // Matches any QualType that refers to a blink type: |
| + // - const blink::Foo& |
| + // - blink::Foo* |
| + // - blink::Foo<T> |
| + // - ... |
| + auto blink_qual_type_matcher = qualType( |
| + anyOf(pointsTo(in_blink_namespace), references(in_blink_namespace), |
|
Łukasz Anforowicz
2016/08/25 18:11:13
This strips only 1 layer of indirection, but I don
|
| + hasUnderlyingType(anyOf( |
| + enumType(hasDeclaration(in_blink_namespace)), |
| + recordType(hasDeclaration(in_blink_namespace)), |
| + templateSpecializationType(hasDeclaration(in_blink_namespace)), |
| + templateTypeParmType(hasDeclaration(in_blink_namespace)), |
| + typedefType(hasDeclaration(in_blink_namespace)))))); |
|
Łukasz Anforowicz
2016/08/25 18:11:13
I don't know how I can avoid listing all the vario
|
| + |
| + // Template-dependent decl lookup ======== |
| + // Given |
| + // template <typename T> void f() { T::foo(); } |
| + // matches |T::foo|. |
| + auto dependent_scope_decl_ref_expr_matcher = |
| + expr(id("expr", dependentScopeDeclRefExpr(dependentScopeIfQualifier( |
| + specifiesType(blink_qual_type_matcher))))); |
| + DependentScopeDeclRefExprRewriter dependent_scope_decl_ref_expr_rewriter( |
| + &replacements); |
| + match_finder.addMatcher(dependent_scope_decl_ref_expr_matcher, |
| + &dependent_scope_decl_ref_expr_rewriter); |
| + |
| + // Template-dependent member lookup ======== |
| + // Given |
| + // template <typename T> |
| + // class Foo { |
| + // void f() { T::foo(); } |
| + // void g(T x) { x.bar(); } |
| + // }; |
| + // matches |T::foo| and |x.bar|. |
| + auto cxx_dependent_scope_member_expr_matcher = expr( |
| + id("expr", |
| + cxxDependentScopeMemberExpr(anyOf( |
| + hasBaseExpr(hasType(blink_qual_type_matcher)), |
| + hasDependentQualifier(specifiesType(blink_qual_type_matcher)))))); |
| + CXXDependentScopeMemberExprRewriter cxx_dependent_scope_member_expr_rewriter( |
| + &replacements); |
| + match_finder.addMatcher(cxx_dependent_scope_member_expr_matcher, |
| + &cxx_dependent_scope_member_expr_rewriter); |
| + |
| std::unique_ptr<clang::tooling::FrontendActionFactory> factory = |
| clang::tooling::newFrontendActionFactory(&match_finder); |
| int result = tool.run(factory.get()); |