Expr *LastE = nullptr;
while (E != LastE) {
LastE = E;
- E = IgnoreExprNodes(E, IgnoreImplicitSingleStep, IgnoreImpCastsExtraSingleStep,
+ E = IgnoreExprNodes(E, IgnoreImplicitSingleStep,
+ IgnoreImpCastsExtraSingleStep,
IgnoreParensOnlySingleStep);
auto SR = E->getSourceRange();
C1 c1 = (*c2);
}
+template <unsigned alignment>
+void template_test() {
+ static_assert(alignment, "");
+}
+void actual_template_test() {
+ template_test<4>();
+}
)cpp");
{
`-DeclRefExpr 'c2'
)cpp");
}
+
+ {
+ auto FN = ast_matchers::match(
+ functionDecl(hasName("template_test"),
+ hasDescendant(staticAssertDecl().bind("staticAssert"))),
+ AST->getASTContext());
+ EXPECT_EQ(FN.size(), 2u);
+
+ EXPECT_EQ(dumpASTString(TK_AsIs, FN[1].getNodeAs<Decl>("staticAssert")),
+ R"cpp(
+StaticAssertDecl
+|-ImplicitCastExpr
+| `-SubstNonTypeTemplateParmExpr
+| `-IntegerLiteral
+`-StringLiteral
+)cpp");
+
+ EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource,
+ FN[1].getNodeAs<Decl>("staticAssert")),
+ R"cpp(
+StaticAssertDecl
+|-IntegerLiteral
+`-StringLiteral
+)cpp");
+ }
}
TEST(Traverse, IgnoreUnlessSpelledInSourceStructs) {
hasDescendant(varDecl(
hasName("c1"), hasInitializer(unaryOperator(
hasOperatorName("*")))))))));
+
+ Code = R"cpp(
+
+template <unsigned alignment>
+void template_test() {
+ static_assert(alignment, "");
+}
+void actual_template_test() {
+ template_test<4>();
+}
+
+)cpp";
+ EXPECT_TRUE(matches(
+ Code,
+ traverse(TK_AsIs,
+ staticAssertDecl(has(implicitCastExpr(has(
+ substNonTypeTemplateParmExpr(has(integerLiteral())))))))));
+
+ EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ staticAssertDecl(has(integerLiteral())))));
}
template <typename MatcherT>