Set traversal explicitly where needed in tests

Reviewers: aaron.ballman, shafik

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D72531
This commit is contained in:
Stephen Kelly 2019-11-12 13:29:40 +00:00
parent a72307c3a6
commit a30d411629
11 changed files with 298 additions and 238 deletions

View File

@ -638,22 +638,16 @@ TEST_P(ImportExpr, ImportSwitch) {
TEST_P(ImportExpr, ImportStmtExpr) {
MatchVerifier<Decl> Verifier;
testImport(
"void declToImport() { int b; int a = b ?: 1; int C = ({int X=4; X;}); }",
Lang_C, "", Lang_C, Verifier,
functionDecl(hasDescendant(
varDecl(
hasName("C"),
hasType(asString("int")),
hasInitializer(
stmtExpr(
hasAnySubstatement(declStmt(hasSingleDecl(
varDecl(
hasName("X"),
hasType(asString("int")),
hasInitializer(
integerLiteral(equals(4))))))),
hasDescendant(
implicitCastExpr())))))));
"void declToImport() { int b; int a = b ?: 1; int C = ({int X=4; X;}); }",
Lang_C, "", Lang_C, Verifier,
traverse(ast_type_traits::TK_AsIs,
functionDecl(hasDescendant(varDecl(
hasName("C"), hasType(asString("int")),
hasInitializer(stmtExpr(
hasAnySubstatement(declStmt(hasSingleDecl(varDecl(
hasName("X"), hasType(asString("int")),
hasInitializer(integerLiteral(equals(4))))))),
hasDescendant(implicitCastExpr()))))))));
}
TEST_P(ImportExpr, ImportConditionalOperator) {
@ -673,22 +667,19 @@ TEST_P(ImportExpr, ImportConditionalOperator) {
TEST_P(ImportExpr, ImportBinaryConditionalOperator) {
MatchVerifier<Decl> Verifier;
testImport(
"void declToImport() { (void)(1 ?: -5); }",
Lang_CXX, "", Lang_CXX, Verifier,
functionDecl(hasDescendant(
binaryConditionalOperator(
hasCondition(
implicitCastExpr(
hasSourceExpression(opaqueValueExpr(
hasSourceExpression(integerLiteral(equals(1))))),
hasType(booleanType()))),
hasTrueExpression(
opaqueValueExpr(
hasSourceExpression(integerLiteral(equals(1))))),
hasFalseExpression(
unaryOperator(
hasOperatorName("-"),
hasUnaryOperand(integerLiteral(equals(5)))))))));
"void declToImport() { (void)(1 ?: -5); }", Lang_CXX, "", Lang_CXX,
Verifier,
traverse(ast_type_traits::TK_AsIs,
functionDecl(hasDescendant(binaryConditionalOperator(
hasCondition(implicitCastExpr(
hasSourceExpression(opaqueValueExpr(
hasSourceExpression(integerLiteral(equals(1))))),
hasType(booleanType()))),
hasTrueExpression(opaqueValueExpr(
hasSourceExpression(integerLiteral(equals(1))))),
hasFalseExpression(unaryOperator(
hasOperatorName("-"),
hasUnaryOperand(integerLiteral(equals(5))))))))));
}
TEST_P(ImportExpr, ImportDesignatedInitExpr) {
@ -774,10 +765,10 @@ TEST_P(ImportExpr, CXXTemporaryObjectExpr) {
"struct C {};"
"void declToImport() { C c = C(); }",
Lang_CXX, "", Lang_CXX, Verifier,
functionDecl(hasDescendant(
exprWithCleanups(has(cxxConstructExpr(
has(materializeTemporaryExpr(has(implicitCastExpr(
has(cxxTemporaryObjectExpr())))))))))));
traverse(ast_type_traits::TK_AsIs,
functionDecl(hasDescendant(exprWithCleanups(has(cxxConstructExpr(
has(materializeTemporaryExpr(has(implicitCastExpr(
has(cxxTemporaryObjectExpr()))))))))))));
}
TEST_P(ImportType, ImportAtomicType) {
@ -828,9 +819,10 @@ TEST_P(ImportType, ImportTypeAliasTemplate) {
"template <int K> using dummy2 = dummy<K>;"
"int declToImport() { return dummy2<3>::i; }",
Lang_CXX11, "", Lang_CXX11, Verifier,
functionDecl(
hasDescendant(implicitCastExpr(has(declRefExpr()))),
unless(hasAncestor(translationUnitDecl(has(typeAliasDecl()))))));
traverse(ast_type_traits::TK_AsIs,
functionDecl(hasDescendant(implicitCastExpr(has(declRefExpr()))),
unless(hasAncestor(
translationUnitDecl(has(typeAliasDecl())))))));
}
const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateSpecializationDecl>
@ -851,16 +843,16 @@ TEST_P(ImportDecl, ImportVarTemplate) {
TEST_P(ImportType, ImportPackExpansion) {
MatchVerifier<Decl> Verifier;
testImport(
"template <typename... Args>"
"struct dummy {"
" dummy(Args... args) {}"
" static const int i = 4;"
"};"
"int declToImport() { return dummy<int>::i; }",
Lang_CXX11, "", Lang_CXX11, Verifier,
functionDecl(hasDescendant(
returnStmt(has(implicitCastExpr(has(declRefExpr())))))));
testImport("template <typename... Args>"
"struct dummy {"
" dummy(Args... args) {}"
" static const int i = 4;"
"};"
"int declToImport() { return dummy<int>::i; }",
Lang_CXX11, "", Lang_CXX11, Verifier,
traverse(ast_type_traits::TK_AsIs,
functionDecl(hasDescendant(returnStmt(
has(implicitCastExpr(has(declRefExpr()))))))));
}
const internal::VariadicDynCastAllOfMatcher<Type,
@ -937,11 +929,13 @@ TEST_P(ImportExpr, ImportCXXTypeidExpr) {
" auto a = typeid(int); auto b = typeid(x);"
"}",
Lang_CXX11, "", Lang_CXX11, Verifier,
functionDecl(
hasDescendant(varDecl(
hasName("a"), hasInitializer(hasDescendant(cxxTypeidExpr())))),
hasDescendant(varDecl(
hasName("b"), hasInitializer(hasDescendant(cxxTypeidExpr()))))));
traverse(
ast_type_traits::TK_AsIs,
functionDecl(
hasDescendant(varDecl(hasName("a"), hasInitializer(hasDescendant(
cxxTypeidExpr())))),
hasDescendant(varDecl(hasName("b"), hasInitializer(hasDescendant(
cxxTypeidExpr())))))));
}
TEST_P(ImportExpr, ImportTypeTraitExprValDep) {

View File

@ -622,16 +622,16 @@ TEST(FriendDecl, InstantiationSourceRange) {
friendDecl(hasParent(cxxRecordDecl(isTemplateInstantiation())))));
}
TEST(ObjCMessageExpr, CXXConstructExprRange) {
RangeVerifier<CXXConstructExpr> Verifier;
TEST(ObjCMessageExpr, ParenExprRange) {
RangeVerifier<ParenExpr> Verifier;
Verifier.expectRange(5, 25, 5, 27);
EXPECT_TRUE(Verifier.match(
"struct A { int a; };\n"
"@interface B {}\n"
"+ (void) f1: (A)arg;\n"
"@end\n"
"void f2() { A a; [B f1: (a)]; }\n",
cxxConstructExpr(), Lang_OBJCXX));
EXPECT_TRUE(Verifier.match("struct A { int a; };\n"
"@interface B {}\n"
"+ (void) f1: (A)arg;\n"
"@end\n"
"void f2() { A a; [B f1: (a)]; }\n",
traverse(ast_type_traits::TK_AsIs, parenExpr()),
Lang_OBJCXX));
}
TEST(FunctionDecl, FunctionDeclWithThrowSpecification) {

View File

@ -129,17 +129,19 @@ TEST(StmtPrinter, TestFloatingPointLiteral) {
}
TEST(StmtPrinter, TestCXXConversionDeclImplicit) {
ASSERT_TRUE(PrintedStmtCXXMatches(StdVer::CXX98,
"struct A {"
"operator void *();"
"A operator&(A);"
"};"
"void bar(void *);"
"void foo(A a, A b) {"
" bar(a & b);"
"}",
cxxMemberCallExpr(anything()).bind("id"),
"a & b"));
ASSERT_TRUE(
PrintedStmtCXXMatches(StdVer::CXX98,
"struct A {"
"operator void *();"
"A operator&(A);"
"};"
"void bar(void *);"
"void foo(A a, A b) {"
" bar(a & b);"
"}",
traverse(ast_type_traits::TK_AsIs,
cxxMemberCallExpr(anything()).bind("id")),
"a & b"));
}
TEST(StmtPrinter, TestCXXConversionDeclExplicit) {

View File

@ -302,12 +302,18 @@ TEST(DeclarationMatcher, MatchNot) {
}
TEST(CastExpression, HasCastKind) {
EXPECT_TRUE(matches("char *p = 0;",
castExpr(hasCastKind(CK_NullToPointer))));
EXPECT_TRUE(notMatches("char *p = 0;",
castExpr(hasCastKind(CK_DerivedToBase))));
EXPECT_TRUE(matches("char *p = 0;",
implicitCastExpr(hasCastKind(CK_NullToPointer))));
EXPECT_TRUE(
matches("char *p = 0;",
traverse(ast_type_traits::TK_AsIs,
varDecl(has(castExpr(hasCastKind(CK_NullToPointer)))))));
EXPECT_TRUE(notMatches(
"char *p = 0;",
traverse(ast_type_traits::TK_AsIs,
varDecl(has(castExpr(hasCastKind(CK_DerivedToBase)))))));
EXPECT_TRUE(matches(
"char *p = 0;",
traverse(ast_type_traits::TK_AsIs,
varDecl(has(implicitCastExpr(hasCastKind(CK_NullToPointer)))))));
}
TEST(DeclarationMatcher, HasDescendant) {
@ -1380,8 +1386,9 @@ TEST(Matcher, MatchesOverridingMethod) {
}
TEST(Matcher, ConstructorArgument) {
StatementMatcher Constructor = cxxConstructExpr(
hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
auto Constructor = traverse(
ast_type_traits::TK_AsIs,
cxxConstructExpr(hasArgument(0, declRefExpr(to(varDecl(hasName("y")))))));
EXPECT_TRUE(
matches("class X { public: X(int); }; void x() { int y; X x(y); }",
@ -1396,15 +1403,18 @@ TEST(Matcher, ConstructorArgument) {
notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
Constructor));
StatementMatcher WrongIndex = cxxConstructExpr(
hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
StatementMatcher WrongIndex =
traverse(ast_type_traits::TK_AsIs,
cxxConstructExpr(
hasArgument(42, declRefExpr(to(varDecl(hasName("y")))))));
EXPECT_TRUE(
notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
WrongIndex));
}
TEST(Matcher, ConstructorArgumentCount) {
StatementMatcher Constructor1Arg = cxxConstructExpr(argumentCountIs(1));
auto Constructor1Arg =
traverse(ast_type_traits::TK_AsIs, cxxConstructExpr(argumentCountIs(1)));
EXPECT_TRUE(
matches("class X { public: X(int); }; void x() { X x(0); }",
@ -1421,8 +1431,9 @@ TEST(Matcher, ConstructorArgumentCount) {
}
TEST(Matcher, ConstructorListInitialization) {
StatementMatcher ConstructorListInit =
cxxConstructExpr(isListInitialization());
auto ConstructorListInit =
traverse(ast_type_traits::TK_AsIs,
varDecl(has(cxxConstructExpr(isListInitialization()))));
EXPECT_TRUE(
matches("class X { public: X(int); }; void x() { X x{0}; }",

View File

@ -374,7 +374,8 @@ TEST(Matcher, OverloadedOperatorCall) {
TEST(Matcher, ThisPointerType) {
StatementMatcher MethodOnY =
cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))));
traverse(ast_type_traits::TK_AsIs,
cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y")))));
EXPECT_TRUE(
matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
@ -579,7 +580,8 @@ TEST(ParmVarDecl, MatchesParmVars) {
}
TEST(Matcher, ConstructorCall) {
StatementMatcher Constructor = cxxConstructExpr();
StatementMatcher Constructor =
traverse(ast_type_traits::TK_AsIs, cxxConstructExpr());
EXPECT_TRUE(
matches("class X { public: X(); }; void x() { X x; }", Constructor));
@ -605,7 +607,8 @@ TEST(Matcher, ThisExpr) {
}
TEST(Matcher, BindTemporaryExpression) {
StatementMatcher TempExpression = cxxBindTemporaryExpr();
StatementMatcher TempExpression =
traverse(ast_type_traits::TK_AsIs, cxxBindTemporaryExpr());
std::string ClassString = "class string { public: string(); ~string(); }; ";
@ -638,36 +641,33 @@ TEST(Matcher, BindTemporaryExpression) {
TEST(MaterializeTemporaryExpr, MatchesTemporary) {
std::string ClassString =
"class string { public: string(); int length(); }; ";
StatementMatcher TempExpression =
traverse(ast_type_traits::TK_AsIs, materializeTemporaryExpr());
EXPECT_TRUE(
matches(ClassString +
"string GetStringByValue();"
"void FunctionTakesString(string s);"
"void run() { FunctionTakesString(GetStringByValue()); }",
materializeTemporaryExpr()));
EXPECT_TRUE(matches(
ClassString + "string GetStringByValue();"
"void FunctionTakesString(string s);"
"void run() { FunctionTakesString(GetStringByValue()); }",
TempExpression));
EXPECT_TRUE(
notMatches(ClassString +
"string* GetStringPointer(); "
"void FunctionTakesStringPtr(string* s);"
"void run() {"
" string* s = GetStringPointer();"
" FunctionTakesStringPtr(GetStringPointer());"
" FunctionTakesStringPtr(s);"
"}",
materializeTemporaryExpr()));
EXPECT_TRUE(notMatches(ClassString +
"string* GetStringPointer(); "
"void FunctionTakesStringPtr(string* s);"
"void run() {"
" string* s = GetStringPointer();"
" FunctionTakesStringPtr(GetStringPointer());"
" FunctionTakesStringPtr(s);"
"}",
TempExpression));
EXPECT_TRUE(
matches(ClassString +
"string GetStringByValue();"
"void run() { int k = GetStringByValue().length(); }",
materializeTemporaryExpr()));
EXPECT_TRUE(matches(ClassString +
"string GetStringByValue();"
"void run() { int k = GetStringByValue().length(); }",
TempExpression));
EXPECT_TRUE(
notMatches(ClassString +
"string GetStringByValue();"
"void run() { GetStringByValue(); }",
materializeTemporaryExpr()));
EXPECT_TRUE(notMatches(ClassString + "string GetStringByValue();"
"void run() { GetStringByValue(); }",
TempExpression));
}
TEST(Matcher, NewExpression) {
@ -893,12 +893,12 @@ TEST(Matcher, ConditionalOperator) {
}
TEST(Matcher, BinaryConditionalOperator) {
StatementMatcher AlwaysOne = binaryConditionalOperator(
hasCondition(implicitCastExpr(
has(
opaqueValueExpr(
hasSourceExpression((integerLiteral(equals(1)))))))),
hasFalseExpression(integerLiteral(equals(0))));
StatementMatcher AlwaysOne =
traverse(ast_type_traits::TK_AsIs,
binaryConditionalOperator(
hasCondition(implicitCastExpr(has(opaqueValueExpr(
hasSourceExpression((integerLiteral(equals(1)))))))),
hasFalseExpression(integerLiteral(equals(0)))));
EXPECT_TRUE(matches("void x() { 1 ?: 0; }", AlwaysOne));
@ -953,9 +953,11 @@ TEST(CastExpression, MatchesExplicitCasts) {
}
TEST(CastExpression, MatchesImplicitCasts) {
// This test creates an implicit cast from int to char.
EXPECT_TRUE(matches("char c = 0;", castExpr()));
EXPECT_TRUE(
matches("char c = 0;", traverse(ast_type_traits::TK_AsIs, castExpr())));
// This test creates an implicit cast from lvalue to rvalue.
EXPECT_TRUE(matches("char c = 0, d = c;", castExpr()));
EXPECT_TRUE(matches("char c = 0, d = c;",
traverse(ast_type_traits::TK_AsIs, castExpr())));
}
TEST(CastExpression, DoesNotMatchNonCasts) {
@ -1039,13 +1041,16 @@ TEST(CStyleCast, DoesNotMatchOtherCasts) {
TEST(ImplicitCast, MatchesSimpleCase) {
// This test creates an implicit const cast.
EXPECT_TRUE(matches("int x = 0; const int y = x;",
varDecl(hasInitializer(implicitCastExpr()))));
traverse(ast_type_traits::TK_AsIs,
varDecl(hasInitializer(implicitCastExpr())))));
// This test creates an implicit cast from int to char.
EXPECT_TRUE(matches("char c = 0;",
varDecl(hasInitializer(implicitCastExpr()))));
traverse(ast_type_traits::TK_AsIs,
varDecl(hasInitializer(implicitCastExpr())))));
// This test creates an implicit array-to-pointer cast.
EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
varDecl(hasInitializer(implicitCastExpr()))));
traverse(ast_type_traits::TK_AsIs,
varDecl(hasInitializer(implicitCastExpr())))));
}
TEST(ImplicitCast, DoesNotMatchIncorrectly) {
@ -1085,11 +1090,13 @@ TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
TEST(ExprWithCleanups, MatchesExprWithCleanups) {
EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
"const Foo f = Foo();",
varDecl(hasInitializer(exprWithCleanups()))));
"const Foo f = Foo();",
traverse(ast_type_traits::TK_AsIs,
varDecl(hasInitializer(exprWithCleanups())))));
EXPECT_FALSE(matches("struct Foo { }; Foo a;"
"const Foo f = a;",
varDecl(hasInitializer(exprWithCleanups()))));
traverse(ast_type_traits::TK_AsIs,
varDecl(hasInitializer(exprWithCleanups())))));
}
TEST(InitListExpression, MatchesInitListExpression) {
@ -1114,14 +1121,18 @@ TEST(CXXStdInitializerListExpression, MatchesCXXStdInitializerListExpression) {
"struct A {"
" A(std::initializer_list<int>) {}"
"};";
EXPECT_TRUE(matches(code + "A a{0};",
cxxConstructExpr(has(cxxStdInitializerListExpr()),
hasDeclaration(cxxConstructorDecl(
ofClass(hasName("A")))))));
EXPECT_TRUE(matches(code + "A a = {0};",
cxxConstructExpr(has(cxxStdInitializerListExpr()),
hasDeclaration(cxxConstructorDecl(
ofClass(hasName("A")))))));
EXPECT_TRUE(
matches(code + "A a{0};",
traverse(ast_type_traits::TK_AsIs,
cxxConstructExpr(has(cxxStdInitializerListExpr()),
hasDeclaration(cxxConstructorDecl(
ofClass(hasName("A"))))))));
EXPECT_TRUE(
matches(code + "A a = {0};",
traverse(ast_type_traits::TK_AsIs,
cxxConstructExpr(has(cxxStdInitializerListExpr()),
hasDeclaration(cxxConstructorDecl(
ofClass(hasName("A"))))))));
EXPECT_TRUE(notMatches("int a[] = { 1, 2 };", cxxStdInitializerListExpr()));
EXPECT_TRUE(notMatches("struct B { int x, y; }; B b = { 5, 6 };",
@ -1195,19 +1206,25 @@ TEST(ExceptionHandling, SimpleCases) {
}
TEST(ParenExpression, SimpleCases) {
EXPECT_TRUE(matches("int i = (3);", parenExpr()));
EXPECT_TRUE(matches("int i = (3 + 7);", parenExpr()));
EXPECT_TRUE(notMatches("int i = 3;", parenExpr()));
EXPECT_TRUE(
matches("int i = (3);", traverse(ast_type_traits::TK_AsIs, parenExpr())));
EXPECT_TRUE(matches("int i = (3 + 7);",
traverse(ast_type_traits::TK_AsIs, parenExpr())));
EXPECT_TRUE(notMatches("int i = 3;",
traverse(ast_type_traits::TK_AsIs, parenExpr())));
EXPECT_TRUE(notMatches("int foo() { return 1; }; int a = foo();",
parenExpr()));
traverse(ast_type_traits::TK_AsIs, parenExpr())));
}
TEST(ParenExpression, IgnoringParens) {
EXPECT_FALSE(matches("const char* str = (\"my-string\");",
implicitCastExpr(hasSourceExpression(stringLiteral()))));
EXPECT_TRUE(matches(
EXPECT_FALSE(matches(
"const char* str = (\"my-string\");",
implicitCastExpr(hasSourceExpression(ignoringParens(stringLiteral())))));
traverse(ast_type_traits::TK_AsIs,
implicitCastExpr(hasSourceExpression(stringLiteral())))));
EXPECT_TRUE(matches("const char* str = (\"my-string\");",
traverse(ast_type_traits::TK_AsIs,
implicitCastExpr(hasSourceExpression(
ignoringParens(stringLiteral()))))));
}
TEST(TypeMatching, MatchesTypes) {

View File

@ -373,7 +373,8 @@ TEST(Callee, MatchesDeclarations) {
EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
CallMethodX = callExpr(callee(cxxConversionDecl()));
CallMethodX =
traverse(ast_type_traits::TK_AsIs, callExpr(callee(cxxConversionDecl())));
EXPECT_TRUE(
matches("struct Y { operator int() const; }; int i = Y();", CallMethodX));
EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();",
@ -435,8 +436,8 @@ TEST(Matcher, AnyArgument) {
"void x() { int y; (void)Y(1, 2); }",
UnresolvedCtorArgumentY));
StatementMatcher ImplicitCastedArgument = callExpr(
hasAnyArgument(implicitCastExpr()));
StatementMatcher ImplicitCastedArgument = traverse(
ast_type_traits::TK_AsIs, callExpr(hasAnyArgument(implicitCastExpr())));
EXPECT_TRUE(matches("void x(long) { int y; x(y); }", ImplicitCastedArgument));
}
@ -590,13 +591,15 @@ TEST(MatcherCXXMemberCallExpr, OnImplicitObjectArgument) {
struct X : public Y {};
void z(X x) { x.m(); }
)cc";
auto MatchesY = cxxMemberCallExpr(
onImplicitObjectArgument(hasType(cxxRecordDecl(hasName("Y")))));
auto MatchesY = traverse(ast_type_traits::TK_AsIs,
cxxMemberCallExpr(onImplicitObjectArgument(
hasType(cxxRecordDecl(hasName("Y"))))));
EXPECT_TRUE(matches(Snippet1, MatchesY));
EXPECT_TRUE(matches(Snippet2, MatchesY));
auto MatchesX = cxxMemberCallExpr(
onImplicitObjectArgument(hasType(cxxRecordDecl(hasName("X")))));
auto MatchesX = traverse(ast_type_traits::TK_AsIs,
cxxMemberCallExpr(onImplicitObjectArgument(
hasType(cxxRecordDecl(hasName("X"))))));
EXPECT_TRUE(notMatches(Snippet2, MatchesX));
// Parens are not ignored.
@ -607,7 +610,9 @@ TEST(MatcherCXXMemberCallExpr, OnImplicitObjectArgument) {
Y g();
void z(Y y) { (g()).m(); }
)cc";
auto MatchesCall = cxxMemberCallExpr(onImplicitObjectArgument(callExpr()));
auto MatchesCall =
traverse(ast_type_traits::TK_AsIs,
cxxMemberCallExpr(onImplicitObjectArgument(callExpr())));
EXPECT_TRUE(notMatches(Snippet3, MatchesCall));
}
@ -706,7 +711,8 @@ TEST(ForEachArgumentWithParam, MatchesConstructExpr) {
declRefExpr(to(varDecl(hasName("y")))).bind("arg");
DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
StatementMatcher ConstructExpr =
cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam));
traverse(ast_type_traits::TK_AsIs,
cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam)));
EXPECT_TRUE(matchAndVerifyResultTrue(
"struct C {"
@ -1145,8 +1151,10 @@ TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
StatementMatcher OperatorIntPointer = arraySubscriptExpr(
hasLHS(hasType(isInteger())), hasRHS(hasType(pointsTo(qualType()))));
StatementMatcher OperatorIntPointer =
arraySubscriptExpr(hasLHS(hasType(isInteger())),
traverse(ast_type_traits::TK_AsIs,
hasRHS(hasType(pointsTo(qualType())))));
EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer));
EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer));
}
@ -1347,10 +1355,10 @@ TEST(ArraySubscriptMatchers, ArrayIndex) {
}
TEST(ArraySubscriptMatchers, MatchesArrayBase) {
EXPECT_TRUE(matches(
"int i[2]; void f() { i[1] = 2; }",
arraySubscriptExpr(hasBase(implicitCastExpr(
hasSourceExpression(declRefExpr()))))));
EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 2; }",
traverse(ast_type_traits::TK_AsIs,
arraySubscriptExpr(hasBase(implicitCastExpr(
hasSourceExpression(declRefExpr())))))));
}
TEST(Matcher, OfClass) {
@ -1497,13 +1505,15 @@ TEST(HasDestinationType, MatchesSimpleCase) {
TEST(HasImplicitDestinationType, MatchesSimpleCase) {
// This test creates an implicit const cast.
EXPECT_TRUE(matches("int x; const int i = x;",
implicitCastExpr(
hasImplicitDestinationType(isInteger()))));
EXPECT_TRUE(matches(
"int x; const int i = x;",
traverse(ast_type_traits::TK_AsIs,
implicitCastExpr(hasImplicitDestinationType(isInteger())))));
// This test creates an implicit array-to-pointer cast.
EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
implicitCastExpr(hasImplicitDestinationType(
pointsTo(TypeMatcher(anything()))))));
traverse(ast_type_traits::TK_AsIs,
implicitCastExpr(hasImplicitDestinationType(
pointsTo(TypeMatcher(anything())))))));
}
TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
@ -1635,20 +1645,19 @@ int main()
SomeType i = something();
}
)";
EXPECT_TRUE(matches(Code, varDecl(
hasName("i"),
hasInitializer(exprWithCleanups(has(
cxxConstructExpr(has(expr(ignoringImplicit(cxxConstructExpr(
has(expr(ignoringImplicit(callExpr())))
)))))
)))
)
));
EXPECT_TRUE(matches(
Code,
traverse(ast_type_traits::TK_AsIs,
varDecl(hasName("i"),
hasInitializer(exprWithCleanups(has(cxxConstructExpr(
has(expr(ignoringImplicit(cxxConstructExpr(has(
expr(ignoringImplicit(callExpr())))))))))))))));
}
TEST(IgnoringImplicit, DoesNotMatchIncorrectly) {
EXPECT_TRUE(
notMatches("class C {}; C a = C();", varDecl(has(cxxConstructExpr()))));
EXPECT_TRUE(notMatches(
"class C {}; C a = C();",
traverse(ast_type_traits::TK_AsIs, varDecl(has(cxxConstructExpr())))));
}
TEST(Traversal, traverseMatcher) {
@ -2119,9 +2128,10 @@ TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
varDecl(hasInitializer(ignoringImpCasts(
integerLiteral())))));
EXPECT_TRUE(notMatches("int i = (0);",
varDecl(hasInitializer(ignoringImpCasts(
integerLiteral())))));
EXPECT_TRUE(notMatches(
"int i = (0);",
traverse(ast_type_traits::TK_AsIs,
varDecl(hasInitializer(ignoringImpCasts(integerLiteral()))))));
EXPECT_TRUE(notMatches("float i = (float)0;",
varDecl(hasInitializer(ignoringImpCasts(
integerLiteral())))));
@ -2233,17 +2243,18 @@ TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
}
TEST(HasSourceExpression, MatchesImplicitCasts) {
EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
"void r() {string a_string; URL url = a_string; }",
implicitCastExpr(
hasSourceExpression(cxxConstructExpr()))));
EXPECT_TRUE(matches(
"class string {}; class URL { public: URL(string s); };"
"void r() {string a_string; URL url = a_string; }",
traverse(ast_type_traits::TK_AsIs,
implicitCastExpr(hasSourceExpression(cxxConstructExpr())))));
}
TEST(HasSourceExpression, MatchesExplicitCasts) {
EXPECT_TRUE(matches("float x = static_cast<float>(42);",
explicitCastExpr(
hasSourceExpression(hasDescendant(
expr(integerLiteral()))))));
traverse(ast_type_traits::TK_AsIs,
explicitCastExpr(hasSourceExpression(
hasDescendant(expr(integerLiteral())))))));
}
TEST(UsingDeclaration, MatchesSpecificTarget) {
@ -2297,18 +2308,21 @@ TEST(SwitchCase, MatchesEachCase) {
EXPECT_TRUE(notMatches(
"void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
EXPECT_TRUE(matches("void x() { switch(42) { case 1+1: case 4:; } }",
switchStmt(forEachSwitchCase(
caseStmt(hasCaseConstant(
constantExpr(has(integerLiteral()))))))));
EXPECT_TRUE(notMatches("void x() { switch(42) { case 1+1: case 2+2:; } }",
switchStmt(forEachSwitchCase(
caseStmt(hasCaseConstant(
constantExpr(has(integerLiteral()))))))));
EXPECT_TRUE(notMatches("void x() { switch(42) { case 1 ... 2:; } }",
switchStmt(forEachSwitchCase(
caseStmt(hasCaseConstant(
constantExpr(has(integerLiteral()))))))));
EXPECT_TRUE(
matches("void x() { switch(42) { case 1+1: case 4:; } }",
traverse(ast_type_traits::TK_AsIs,
switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
constantExpr(has(integerLiteral())))))))));
EXPECT_TRUE(
notMatches("void x() { switch(42) { case 1+1: case 2+2:; } }",
traverse(ast_type_traits::TK_AsIs,
switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
constantExpr(has(integerLiteral())))))))));
EXPECT_TRUE(
notMatches("void x() { switch(42) { case 1 ... 2:; } }",
traverse(ast_type_traits::TK_AsIs,
switchStmt(forEachSwitchCase(caseStmt(hasCaseConstant(
constantExpr(has(integerLiteral())))))))));
EXPECT_TRUE(matchAndVerifyResultTrue(
"void x() { switch (42) { case 1: case 2: case 3: default:; } }",
switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
@ -2316,6 +2330,7 @@ TEST(SwitchCase, MatchesEachCase) {
}
TEST(Declaration, HasExplicitSpecifier) {
EXPECT_TRUE(matchesConditionally(
"void f();", functionDecl(hasExplicitSpecifier(constantExpr())), false,
"-std=c++2a"));
@ -2327,42 +2342,57 @@ TEST(Declaration, HasExplicitSpecifier) {
"template<bool b> struct S { explicit(b) operator int(); };",
cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
false, "-std=c++2a"));
EXPECT_TRUE(matchesConditionally(
"struct S { explicit(true) operator int(); };",
cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
true, "-std=c++2a"));
EXPECT_TRUE(matchesConditionally(
"struct S { explicit(false) operator int(); };",
cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
true, "-std=c++2a"));
EXPECT_TRUE(matchesConditionally(
"template<bool b> struct S { explicit(b) S(int); };",
cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
false, "-std=c++2a"));
EXPECT_TRUE(matchesConditionally(
"struct S { explicit(true) S(int); };",
cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
true, "-std=c++2a"));
EXPECT_TRUE(matchesConditionally(
"struct S { explicit(false) S(int); };",
cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
true, "-std=c++2a"));
EXPECT_TRUE(
matchesConditionally("struct S { explicit(true) operator int(); };",
traverse(ast_type_traits::TK_AsIs,
cxxConversionDecl(hasExplicitSpecifier(
constantExpr(has(cxxBoolLiteral()))))),
true, "-std=c++2a"));
EXPECT_TRUE(
matchesConditionally("struct S { explicit(false) operator int(); };",
traverse(ast_type_traits::TK_AsIs,
cxxConversionDecl(hasExplicitSpecifier(
constantExpr(has(cxxBoolLiteral()))))),
true, "-std=c++2a"));
EXPECT_TRUE(
matchesConditionally("template<bool b> struct S { explicit(b) S(int); };",
traverse(ast_type_traits::TK_AsIs,
cxxConstructorDecl(hasExplicitSpecifier(
constantExpr(has(cxxBoolLiteral()))))),
false, "-std=c++2a"));
EXPECT_TRUE(
matchesConditionally("struct S { explicit(true) S(int); };",
traverse(ast_type_traits::TK_AsIs,
cxxConstructorDecl(hasExplicitSpecifier(
constantExpr(has(cxxBoolLiteral()))))),
true, "-std=c++2a"));
EXPECT_TRUE(
matchesConditionally("struct S { explicit(false) S(int); };",
traverse(ast_type_traits::TK_AsIs,
cxxConstructorDecl(hasExplicitSpecifier(
constantExpr(has(cxxBoolLiteral()))))),
true, "-std=c++2a"));
EXPECT_TRUE(matchesConditionally(
"template<typename T> struct S { S(int); };"
"template<bool b = true> explicit(b) S(int) -> S<int>;",
cxxDeductionGuideDecl(
hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
traverse(ast_type_traits::TK_AsIs,
cxxDeductionGuideDecl(
hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral()))))),
false, "-std=c++2a"));
EXPECT_TRUE(matchesConditionally("template<typename T> struct S { S(int); };"
"explicit(true) S(int) -> S<int>;",
cxxDeductionGuideDecl(hasExplicitSpecifier(
constantExpr(has(cxxBoolLiteral())))),
true, "-std=c++2a"));
EXPECT_TRUE(matchesConditionally("template<typename T> struct S { S(int); };"
"explicit(false) S(int) -> S<int>;",
cxxDeductionGuideDecl(hasExplicitSpecifier(
constantExpr(has(cxxBoolLiteral())))),
true, "-std=c++2a"));
EXPECT_TRUE(
matchesConditionally("template<typename T> struct S { S(int); };"
"explicit(true) S(int) -> S<int>;",
traverse(ast_type_traits::TK_AsIs,
cxxDeductionGuideDecl(hasExplicitSpecifier(
constantExpr(has(cxxBoolLiteral()))))),
true, "-std=c++2a"));
EXPECT_TRUE(
matchesConditionally("template<typename T> struct S { S(int); };"
"explicit(false) S(int) -> S<int>;",
traverse(ast_type_traits::TK_AsIs,
cxxDeductionGuideDecl(hasExplicitSpecifier(
constantExpr(has(cxxBoolLiteral()))))),
true, "-std=c++2a"));
}
TEST(ForEachConstructorInitializer, MatchesInitializers) {

View File

@ -507,8 +507,10 @@ TEST_F(RegistryTest, HasArgs) {
TEST_F(RegistryTest, ParenExpr) {
Matcher<Stmt> Value = constructMatcher("parenExpr").getTypedMatcher<Stmt>();
EXPECT_TRUE(matches("int i = (1);", Value));
EXPECT_FALSE(matches("int i = 1;", Value));
EXPECT_TRUE(
matches("int i = (1);", traverse(ast_type_traits::TK_AsIs, Value)));
EXPECT_FALSE(
matches("int i = 1;", traverse(ast_type_traits::TK_AsIs, Value)));
}
TEST_F(RegistryTest, EqualsMatcher) {

View File

@ -54,6 +54,7 @@ StmtMatcher withEnclosingCompound(ExprMatcher Matcher) {
bool isMutated(const SmallVectorImpl<BoundNodes> &Results, ASTUnit *AST) {
const auto *const S = selectFirst<Stmt>("stmt", Results);
const auto *const E = selectFirst<Expr>("expr", Results);
TraversalKindScope RAII(AST->getASTContext(), ast_type_traits::TK_AsIs);
return ExprMutationAnalyzer(*S, AST->getASTContext()).isMutated(E);
}

View File

@ -46,6 +46,7 @@ template <typename M> TestMatch matchCode(StringRef Code, M Matcher) {
ASTContext &Context = ASTUnit->getASTContext();
assert(!Context.getDiagnostics().hasErrorOccurred() && "Compilation error");
TraversalKindScope RAII(Context, ast_type_traits::TK_AsIs);
auto Matches = ast_matchers::match(Matcher, Context);
// We expect a single, exact match.
assert(Matches.size() != 0 && "no matches found");

View File

@ -22,7 +22,7 @@ void expectRewritten(const std::string &Code, const std::string &Expected,
const T &AMatcher, RefactoringCallback &Callback) {
std::map<std::string, Replacements> FileToReplace;
ASTMatchRefactorer Finder(FileToReplace);
Finder.addMatcher(AMatcher, &Callback);
Finder.addMatcher(traverse(ast_type_traits::TK_AsIs, AMatcher), &Callback);
std::unique_ptr<tooling::FrontendActionFactory> Factory(
tooling::newFrontendActionFactory(&Finder));
ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), Code))

View File

@ -60,7 +60,8 @@ static llvm::Optional<TestMatch> matchStmt(StringRef StatementCode,
return llvm::None;
}
ASTContext &Context = AstUnit->getASTContext();
auto Matches = ast_matchers::match(wrapMatcher(Matcher), Context);
auto Matches = ast_matchers::match(
traverse(ast_type_traits::TK_AsIs, wrapMatcher(Matcher)), Context);
// We expect a single, exact match for the statement.
if (Matches.size() != 1) {
ADD_FAILURE() << "Wrong number of matches: " << Matches.size();
@ -333,9 +334,10 @@ TEST_F(StencilTest, AccessOpExplicitThis) {
int foo() { return this->x; }
};
)cc";
auto StmtMatch =
matchStmt(Snippet, returnStmt(hasReturnValue(ignoringImplicit(memberExpr(
hasObjectExpression(expr().bind("obj")))))));
auto StmtMatch = matchStmt(
Snippet, traverse(ast_type_traits::TK_AsIs,
returnStmt(hasReturnValue(ignoringImplicit(memberExpr(
hasObjectExpression(expr().bind("obj"))))))));
ASSERT_TRUE(StmtMatch);
const Stencil Stencil = access("obj", "field");
EXPECT_THAT_EXPECTED(Stencil->eval(StmtMatch->Result),