[clang] aa5d2d2 - Traverse-ignore invisible CXXConstructExprs with default args
Stephen Kelly via cfe-commits
cfe-commits at lists.llvm.org
Fri May 22 17:06:07 PDT 2020
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>
More information about the cfe-commits
mailing list