Author: Stephen Kelly Date: 2020-05-23T01:04:44+01:00 New Revision: aa5d2d22485470365cc8f7016c1be672a273c2fe
URL: https://github.com/llvm/llvm-project/commit/aa5d2d22485470365cc8f7016c1be672a273c2fe DIFF: https://github.com/llvm/llvm-project/commit/aa5d2d22485470365cc8f7016c1be672a273c2fe.diff LOG: Traverse-ignore invisible CXXConstructExprs with default args 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 468540ddf06f..7b1badf133f9 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2915,7 +2915,9 @@ Expr *Expr::IgnoreUnlessSpelledInSource() { auto SR = E->getSourceRange(); if (auto *C = dyn_cast<CXXConstructExpr>(E)) { - if (C->getNumArgs() == 1) { + auto NumArgs = C->getNumArgs(); + if (NumArgs == 1 || + (NumArgs > 1 && isa<CXXDefaultArgExpr>(C->getArg(1)))) { Expr *A = C->getArg(0); if (A->getSourceRange() == SR || !isa<CXXTemporaryObjectExpr>(C)) E = A; diff --git a/clang/unittests/AST/ASTTraverserTest.cpp b/clang/unittests/AST/ASTTraverserTest.cpp index 4ecb02325d6a..9a951c7bec5e 100644 --- a/clang/unittests/AST/ASTTraverserTest.cpp +++ b/clang/unittests/AST/ASTTraverserTest.cpp @@ -258,6 +258,71 @@ TemplateArgument 19u); } +TEST(Traverse, IgnoreUnlessSpelledInSourceVars) { + + auto AST = buildASTFromCode(R"cpp( + +struct String +{ + String(const char*, int = -1) {} +}; + +void stringConstruct() +{ + String s = "foo"; + s = "bar"; +} + +)cpp"); + + { + auto FN = + ast_matchers::match(functionDecl(hasName("stringConstruct")).bind("fn"), + AST->getASTContext()); + EXPECT_EQ(FN.size(), 1u); + + EXPECT_EQ(dumpASTString(TK_AsIs, FN[0].getNodeAs<Decl>("fn")), + R"cpp( +FunctionDecl 'stringConstruct' +`-CompoundStmt + |-DeclStmt + | `-VarDecl 's' + | `-ExprWithCleanups + | `-CXXConstructExpr + | `-MaterializeTemporaryExpr + | `-ImplicitCastExpr + | `-CXXConstructExpr + | |-ImplicitCastExpr + | | `-StringLiteral + | `-CXXDefaultArgExpr + `-ExprWithCleanups + `-CXXOperatorCallExpr + |-ImplicitCastExpr + | `-DeclRefExpr 'operator=' + |-DeclRefExpr 's' + `-MaterializeTemporaryExpr + `-CXXConstructExpr + |-ImplicitCastExpr + | `-StringLiteral + `-CXXDefaultArgExpr +)cpp"); + + EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource, + FN[0].getNodeAs<Decl>("fn")), + R"cpp( +FunctionDecl 'stringConstruct' +`-CompoundStmt + |-DeclStmt + | `-VarDecl 's' + | `-StringLiteral + `-CXXOperatorCallExpr + |-DeclRefExpr 'operator=' + |-DeclRefExpr 's' + `-StringLiteral +)cpp"); + } +} + TEST(Traverse, IgnoreUnlessSpelledInSourceStructs) { auto AST = buildASTFromCode(R"cpp( diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index 2a36d7a64efd..b4b7e2b43cf7 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1780,6 +1780,55 @@ const char *SomeString{"str"}; EXPECT_TRUE( matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, stringLiteral(hasParent(initListExpr()))))); + + Code = R"cpp( +struct String +{ + String(const char*, int = -1) {} +}; + +void stringConstruct() +{ + String s = "foo"; + s = "bar"; +} +)cpp"; + EXPECT_TRUE(matches( + Code, + traverse( + TK_AsIs, + functionDecl( + hasName("stringConstruct"), + hasDescendant(varDecl( + hasName("s"), + hasInitializer(ignoringImplicit(cxxConstructExpr(hasArgument( + 0, ignoringImplicit(cxxConstructExpr(hasArgument( + 0, ignoringImplicit(stringLiteral())))))))))))))); + + EXPECT_TRUE(matches( + Code, + traverse( + TK_AsIs, + functionDecl(hasName("stringConstruct"), + hasDescendant(cxxOperatorCallExpr( + isAssignmentOperator(), + hasArgument(1, ignoringImplicit( + cxxConstructExpr(hasArgument( + 0, ignoringImplicit(stringLiteral()))))) + )))))); + + EXPECT_TRUE(matches( + Code, traverse(TK_IgnoreUnlessSpelledInSource, + functionDecl(hasName("stringConstruct"), + hasDescendant(varDecl( + hasName("s"), + hasInitializer(stringLiteral()))))))); + EXPECT_TRUE( + matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, + functionDecl(hasName("stringConstruct"), + hasDescendant(cxxOperatorCallExpr( + isAssignmentOperator(), + hasArgument(1, stringLiteral()))))))); } template <typename MatcherT> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits