| 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 21a696afa0d65de0ba6d3a2ee9d3fa36b39bef60..7d7b67b4744796c116ea66003d26ada30269bd19 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();
|
| }
|
| @@ -154,6 +162,34 @@ AST_MATCHER_P(clang::CXXMethodDecl,
|
| return MatchAllOverriddenMethods(Node, InnerMatcher, Finder, Builder);
|
| }
|
|
|
| +// Matches |x.m| CXXDependentScopeMemberExpr if InnerMatcher matches |x|.
|
| +AST_MATCHER_P(clang::CXXDependentScopeMemberExpr,
|
| + hasBaseExprMissingOrMatching,
|
| + 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,
|
| + hasQualifierMissingOrMatching,
|
| + 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)
|
| @@ -487,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());
|
| @@ -592,12 +646,24 @@ class DeclRewriterBase : public RewriterBase<TargetNode> {
|
| }
|
| };
|
|
|
| -llvm::StringRef GetCurrentName(const clang::UnresolvedMemberExpr& expr) {
|
| - return expr.getMemberName().getAsString();
|
| +clang::DeclarationName GetUnresolvedName(
|
| + const clang::UnresolvedMemberExpr& expr) {
|
| + return expr.getMemberName();
|
| }
|
|
|
| -llvm::StringRef GetCurrentName(const clang::NamedDecl& decl) {
|
| - return decl.getName();
|
| +clang::DeclarationName GetUnresolvedName(
|
| + const clang::DependentScopeDeclRefExpr& expr) {
|
| + return expr.getDeclName();
|
| +}
|
| +
|
| +clang::DeclarationName GetUnresolvedName(
|
| + const clang::CXXDependentScopeMemberExpr& expr) {
|
| + return expr.getMember();
|
| +}
|
| +
|
| +clang::DeclarationName GetUnresolvedName(
|
| + const clang::UnresolvedUsingValueDecl& decl) {
|
| + return decl.getDeclName();
|
| }
|
|
|
| // Returns whether |expr| is a callee of a method or function call.
|
| @@ -627,7 +693,22 @@ class UnresolvedRewriterBase : public RewriterBase<TargetNode> {
|
|
|
| void run(const MatchFinder::MatchResult& result) override {
|
| const TargetNode& expr = Base::GetTargetNode(result);
|
| - llvm::StringRef old_name = GetCurrentName(expr);
|
| +
|
| + clang::DeclarationName unresolved_name = GetUnresolvedName(expr);
|
| + switch (unresolved_name.getNameKind()) {
|
| + // Do not rewrite this:
|
| + // return operator T*();
|
| + // into this:
|
| + // return Operator type - parameter - 0 - 0 * T * ();
|
| + case clang::DeclarationName::NameKind::CXXConversionFunctionName:
|
| + case clang::DeclarationName::NameKind::CXXOperatorName:
|
| + case clang::DeclarationName::NameKind::CXXLiteralOperatorName:
|
| + return;
|
| + default:
|
| + break;
|
| + }
|
| +
|
| + llvm::StringRef old_name = unresolved_name.getAsString();
|
| std::string new_name;
|
| if (GuessNameForUnresolvedDependentNode(expr, *result.Context, old_name,
|
| new_name)) {
|
| @@ -710,6 +791,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);
|
| @@ -1034,6 +1121,51 @@ 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),
|
| + 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))))));
|
| +
|
| + // 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(has(nestedNameSpecifier(
|
| + 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(allOf(
|
| + hasBaseExprMissingOrMatching(hasType(blink_qual_type_matcher)),
|
| + hasQualifierMissingOrMatching(
|
| + 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());
|
|
|