Skip to content

Commit 9a3ff47

Browse files
committed
Fix the invisible-traversal to ignore more nodes
1 parent 39f1335 commit 9a3ff47

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed

clang/lib/AST/Expr.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -2900,6 +2900,12 @@ static Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
29002900
return IgnoreImplicitSingleStep(E);
29012901
}
29022902

2903+
static Expr *IgnoreParensOnlySingleStep(Expr *E) {
2904+
if (auto *PE = dyn_cast<ParenExpr>(E))
2905+
return PE->getSubExpr();
2906+
return E;
2907+
}
2908+
29032909
static Expr *IgnoreParensSingleStep(Expr *E) {
29042910
if (auto *PE = dyn_cast<ParenExpr>(E))
29052911
return PE->getSubExpr();
@@ -3026,7 +3032,8 @@ Expr *Expr::IgnoreUnlessSpelledInSource() {
30263032
Expr *LastE = nullptr;
30273033
while (E != LastE) {
30283034
LastE = E;
3029-
E = E->IgnoreParenImpCasts();
3035+
E = IgnoreExprNodes(E, IgnoreImplicitSingleStep, IgnoreImpCastsSingleStep,
3036+
IgnoreParensOnlySingleStep);
30303037

30313038
auto SR = E->getSourceRange();
30323039

clang/unittests/AST/ASTTraverserTest.cpp

+84-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,90 @@ TemplateArgument
260260
19u);
261261
}
262262

263-
TEST(Traverse, IgnoreUnlessSpelledInSource) {
263+
TEST(Traverse, IgnoreUnlessSpelledInSourceStructs) {
264+
auto AST = buildASTFromCode(R"cpp(
265+
266+
struct MyStruct {
267+
MyStruct();
268+
MyStruct(int i) {
269+
MyStruct();
270+
}
271+
~MyStruct();
272+
};
273+
274+
)cpp");
275+
276+
auto BN = ast_matchers::match(
277+
cxxConstructorDecl(hasName("MyStruct"),
278+
hasParameter(0, parmVarDecl(hasType(isInteger()))))
279+
.bind("ctor"),
280+
AST->getASTContext());
281+
EXPECT_EQ(BN.size(), 1u);
282+
283+
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
284+
BN[0].getNodeAs<Decl>("ctor")),
285+
R"cpp(
286+
CXXConstructorDecl 'MyStruct'
287+
|-ParmVarDecl 'i'
288+
`-CompoundStmt
289+
`-CXXTemporaryObjectExpr
290+
)cpp");
291+
292+
EXPECT_EQ(
293+
dumpASTString(ast_type_traits::TK_AsIs, BN[0].getNodeAs<Decl>("ctor")),
294+
R"cpp(
295+
CXXConstructorDecl 'MyStruct'
296+
|-ParmVarDecl 'i'
297+
`-CompoundStmt
298+
`-ExprWithCleanups
299+
`-CXXBindTemporaryExpr
300+
`-CXXTemporaryObjectExpr
301+
)cpp");
302+
}
303+
304+
TEST(Traverse, IgnoreUnlessSpelledInSourceReturnStruct) {
305+
306+
auto AST = buildASTFromCode(R"cpp(
307+
struct Retval {
308+
Retval() {}
309+
~Retval() {}
310+
};
311+
312+
Retval someFun();
313+
314+
void foo()
315+
{
316+
someFun();
317+
}
318+
)cpp");
319+
320+
auto BN = ast_matchers::match(functionDecl(hasName("foo")).bind("fn"),
321+
AST->getASTContext());
322+
EXPECT_EQ(BN.size(), 1u);
323+
324+
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
325+
BN[0].getNodeAs<Decl>("fn")),
326+
R"cpp(
327+
FunctionDecl 'foo'
328+
`-CompoundStmt
329+
`-CallExpr
330+
`-DeclRefExpr 'someFun'
331+
)cpp");
332+
333+
EXPECT_EQ(
334+
dumpASTString(ast_type_traits::TK_AsIs, BN[0].getNodeAs<Decl>("fn")),
335+
R"cpp(
336+
FunctionDecl 'foo'
337+
`-CompoundStmt
338+
`-ExprWithCleanups
339+
`-CXXBindTemporaryExpr
340+
`-CallExpr
341+
`-ImplicitCastExpr
342+
`-DeclRefExpr 'someFun'
343+
)cpp");
344+
}
345+
346+
TEST(Traverse, IgnoreUnlessSpelledInSourceReturns) {
264347

265348
auto AST = buildASTFromCode(R"cpp(
266349

0 commit comments

Comments
 (0)