Author: Stephen Kelly Date: 2020-05-23T01:04:44+01:00 New Revision: 26ac5a34bae7cb5b65e0580b317d4559af847ddb
URL: https://github.com/llvm/llvm-project/commit/26ac5a34bae7cb5b65e0580b317d4559af847ddb DIFF: https://github.com/llvm/llvm-project/commit/26ac5a34bae7cb5b65e0580b317d4559af847ddb.diff LOG: Fix ignoring traversal of intermediate parens Added: Modified: clang/lib/AST/Expr.cpp clang/unittests/AST/ASTTraverserTest.cpp clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 7b1badf133f9..f173c2408866 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2925,7 +2925,16 @@ Expr *Expr::IgnoreUnlessSpelledInSource() { } if (auto *C = dyn_cast<CXXMemberCallExpr>(E)) { - Expr *ExprNode = C->getImplicitObjectArgument()->IgnoreParenImpCasts(); + Expr *ExprNode = C->getImplicitObjectArgument(); + if (ExprNode->getSourceRange() == SR) { + E = ExprNode; + continue; + } + if (auto *PE = dyn_cast<ParenExpr>(ExprNode)) { + E = PE; + continue; + } + ExprNode = ExprNode->IgnoreParenImpCasts(); if (ExprNode->getSourceRange() == SR) E = ExprNode; } diff --git a/clang/unittests/AST/ASTTraverserTest.cpp b/clang/unittests/AST/ASTTraverserTest.cpp index 9a951c7bec5e..f56a49bf8e51 100644 --- a/clang/unittests/AST/ASTTraverserTest.cpp +++ b/clang/unittests/AST/ASTTraverserTest.cpp @@ -273,6 +273,15 @@ void stringConstruct() s = "bar"; } +struct C1 {}; +struct C2 { operator C1(); }; + +void conversionOperator() +{ + C2* c2; + C1 c1 = (*c2); +} + )cpp"); { @@ -319,6 +328,37 @@ FunctionDecl 'stringConstruct' |-DeclRefExpr 'operator=' |-DeclRefExpr 's' `-StringLiteral +)cpp"); + } + + { + auto FN = ast_matchers::match( + functionDecl(hasName("conversionOperator"), + hasDescendant(varDecl(hasName("c1")).bind("var"))), + AST->getASTContext()); + EXPECT_EQ(FN.size(), 1u); + + EXPECT_EQ(dumpASTString(TK_AsIs, FN[0].getNodeAs<Decl>("var")), + R"cpp( +VarDecl 'c1' +`-ExprWithCleanups + `-CXXConstructExpr + `-MaterializeTemporaryExpr + `-ImplicitCastExpr + `-CXXMemberCallExpr + `-MemberExpr + `-ParenExpr + `-UnaryOperator + `-ImplicitCastExpr + `-DeclRefExpr 'c2' +)cpp"); + + EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource, + FN[0].getNodeAs<Decl>("var")), + R"cpp( +VarDecl 'c1' +`-UnaryOperator + `-DeclRefExpr 'c2' )cpp"); } } diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index b4b7e2b43cf7..648e73c4bf57 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1823,12 +1823,13 @@ void stringConstruct() hasDescendant(varDecl( hasName("s"), hasInitializer(stringLiteral()))))))); - EXPECT_TRUE( - matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, - functionDecl(hasName("stringConstruct"), - hasDescendant(cxxOperatorCallExpr( - isAssignmentOperator(), - hasArgument(1, stringLiteral()))))))); + EXPECT_TRUE(matches( + Code, + traverse(TK_IgnoreUnlessSpelledInSource, + functionDecl(hasName("conversionOperator"), + hasDescendant(varDecl( + hasName("c1"), hasInitializer(unaryOperator( + hasOperatorName("*"))))))))); } template <typename MatcherT> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits