Fix ignoring traversal of intermediate parens

This commit is contained in:
Stephen Kelly 2020-05-22 00:57:50 +01:00
parent aa5d2d2248
commit 26ac5a34ba
3 changed files with 57 additions and 7 deletions

View File

@ -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;
}

View File

@ -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");
}
}

View File

@ -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>