aboutsummaryrefslogtreecommitdiff
path: root/unittests/ASTMatchers/ASTMatchersTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/ASTMatchers/ASTMatchersTest.cpp')
-rw-r--r--unittests/ASTMatchers/ASTMatchersTest.cpp127
1 files changed, 108 insertions, 19 deletions
diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp
index d2e9ee19b2cf..ae363e974b5d 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -379,6 +379,21 @@ TEST(DeclarationMatcher, hasDeclContext) {
EXPECT_TRUE(matches("class D{};", decl(hasDeclContext(decl()))));
}
+TEST(DeclarationMatcher, translationUnitDecl) {
+ const std::string Code = "int MyVar1;\n"
+ "namespace NameSpace {\n"
+ "int MyVar2;\n"
+ "} // namespace NameSpace\n";
+ EXPECT_TRUE(matches(
+ Code, varDecl(hasName("MyVar1"), hasDeclContext(translationUnitDecl()))));
+ EXPECT_FALSE(matches(
+ Code, varDecl(hasName("MyVar2"), hasDeclContext(translationUnitDecl()))));
+ EXPECT_TRUE(matches(
+ Code,
+ varDecl(hasName("MyVar2"),
+ hasDeclContext(decl(hasDeclContext(translationUnitDecl()))))));
+}
+
TEST(DeclarationMatcher, LinkageSpecification) {
EXPECT_TRUE(matches("extern \"C\" { void foo() {}; }", linkageSpecDecl()));
EXPECT_TRUE(notMatches("void foo() {};", linkageSpecDecl()));
@@ -732,12 +747,12 @@ public:
Name.clear();
}
- ~VerifyIdIsBoundTo() {
+ ~VerifyIdIsBoundTo() override {
EXPECT_EQ(0, Count);
EXPECT_EQ("", Name);
}
- virtual bool run(const BoundNodes *Nodes) override {
+ bool run(const BoundNodes *Nodes) override {
const BoundNodes::IDToNodeMap &M = Nodes->getMap();
if (Nodes->getNodeAs<T>(Id)) {
++Count;
@@ -759,7 +774,7 @@ public:
return false;
}
- virtual bool run(const BoundNodes *Nodes, ASTContext *Context) override {
+ bool run(const BoundNodes *Nodes, ASTContext *Context) override {
return run(Nodes);
}
@@ -1383,6 +1398,12 @@ TEST(Callee, MatchesDeclarations) {
EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
+
+ CallMethodX = callExpr(callee(conversionDecl()));
+ EXPECT_TRUE(
+ matches("struct Y { operator int() const; }; int i = Y();", CallMethodX));
+ EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();",
+ CallMethodX));
}
TEST(Callee, MatchesMemberExpressions) {
@@ -1574,6 +1595,13 @@ TEST(IsDeleted, MatchesDeletedFunctionDeclarations) {
functionDecl(hasName("Func"), isDeleted())));
}
+TEST(isConstexpr, MatchesConstexprDeclarations) {
+ EXPECT_TRUE(matches("constexpr int foo = 42;",
+ varDecl(hasName("foo"), isConstexpr())));
+ EXPECT_TRUE(matches("constexpr int bar();",
+ functionDecl(hasName("bar"), isConstexpr())));
+}
+
TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
@@ -1775,6 +1803,9 @@ TEST(Matcher, MatchesOverridingMethod) {
methodDecl(isOverride())));
EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
methodDecl(isOverride())));
+ EXPECT_TRUE(
+ matches("template <typename Base> struct Y : Base { void f() override;};",
+ methodDecl(isOverride(), hasName("::Y::f"))));
}
TEST(Matcher, ConstructorCall) {
@@ -2104,14 +2135,26 @@ TEST(Matcher, FloatLiterals) {
EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral));
EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral));
EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral));
+ EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0))));
+ EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f))));
+ EXPECT_TRUE(
+ matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0)))));
EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral));
+ EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0))));
+ EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f))));
+ EXPECT_TRUE(
+ notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0)))));
}
TEST(Matcher, NullPtrLiteral) {
EXPECT_TRUE(matches("int* i = nullptr;", nullPtrLiteralExpr()));
}
+TEST(Matcher, GNUNullExpr) {
+ EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr()));
+}
+
TEST(Matcher, AsmStatement) {
EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));
}
@@ -2515,10 +2558,9 @@ TEST(AstMatcherPMacro, Works) {
HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
}
-AST_POLYMORPHIC_MATCHER_P(
- polymorphicHas,
- AST_POLYMORPHIC_SUPPORTED_TYPES_2(Decl, Stmt),
- internal::Matcher<Decl>, AMatcher) {
+AST_POLYMORPHIC_MATCHER_P(polymorphicHas,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt),
+ internal::Matcher<Decl>, AMatcher) {
return Finder->matchesChildOf(
Node, AMatcher, Builder,
ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
@@ -3136,6 +3178,12 @@ TEST(InitListExpression, MatchesInitListExpression) {
initListExpr(hasType(asString("int [2]")))));
EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
initListExpr(hasType(recordDecl(hasName("B"))))));
+ EXPECT_TRUE(matches("struct S { S(void (*a)()); };"
+ "void f();"
+ "S s[1] = { &f };",
+ declRefExpr(to(functionDecl(hasName("f"))))));
+ EXPECT_TRUE(
+ matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42))));
}
TEST(UsingDeclaration, MatchesUsingDeclarations) {
@@ -4348,9 +4396,9 @@ public:
: Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
}
- virtual bool run(const BoundNodes *Nodes) { return false; }
+ bool run(const BoundNodes *Nodes) override { return false; }
- virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
+ bool run(const BoundNodes *Nodes, ASTContext *Context) override {
const T *Node = Nodes->getNodeAs<T>(Id);
return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) !=
nullptr;
@@ -4399,9 +4447,9 @@ TEST(MatchFinder, CanMatchSingleNodesRecursively) {
template <typename T>
class VerifyAncestorHasChildIsEqual : public BoundNodesCallback {
public:
- virtual bool run(const BoundNodes *Nodes) { return false; }
+ bool run(const BoundNodes *Nodes) override { return false; }
- virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
+ bool run(const BoundNodes *Nodes, ASTContext *Context) override {
const T *Node = Nodes->getNodeAs<T>("");
return verify(*Nodes, *Context, Node);
}
@@ -4457,12 +4505,10 @@ TEST(MatchFinder, CheckProfiling) {
class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
public:
VerifyStartOfTranslationUnit() : Called(false) {}
- virtual void run(const MatchFinder::MatchResult &Result) {
+ void run(const MatchFinder::MatchResult &Result) override {
EXPECT_TRUE(Called);
}
- virtual void onStartOfTranslationUnit() {
- Called = true;
- }
+ void onStartOfTranslationUnit() override { Called = true; }
bool Called;
};
@@ -4485,12 +4531,10 @@ TEST(MatchFinder, InterceptsStartOfTranslationUnit) {
class VerifyEndOfTranslationUnit : public MatchFinder::MatchCallback {
public:
VerifyEndOfTranslationUnit() : Called(false) {}
- virtual void run(const MatchFinder::MatchResult &Result) {
+ void run(const MatchFinder::MatchResult &Result) override {
EXPECT_FALSE(Called);
}
- virtual void onEndOfTranslationUnit() {
- Called = true;
- }
+ void onEndOfTranslationUnit() override { Called = true; }
bool Called;
};
@@ -4683,5 +4727,50 @@ TEST(Matcher, IsExpansionInFileMatching) {
#endif // LLVM_ON_WIN32
+
+TEST(ObjCMessageExprMatcher, SimpleExprs) {
+ // don't find ObjCMessageExpr where none are present
+ EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything())));
+
+ std::string Objc1String =
+ "@interface Str "
+ " - (Str *)uppercaseString:(Str *)str;"
+ "@end "
+ "@interface foo "
+ "- (void)meth:(Str *)text;"
+ "@end "
+ " "
+ "@implementation foo "
+ "- (void) meth:(Str *)text { "
+ " [self contents];"
+ " Str *up = [text uppercaseString];"
+ "} "
+ "@end ";
+ EXPECT_TRUE(matchesObjC(
+ Objc1String,
+ objcMessageExpr(anything())));
+ EXPECT_TRUE(matchesObjC(
+ Objc1String,
+ objcMessageExpr(hasSelector("contents"))));
+ EXPECT_TRUE(matchesObjC(
+ Objc1String,
+ objcMessageExpr(matchesSelector("cont*"))));
+ EXPECT_FALSE(matchesObjC(
+ Objc1String,
+ objcMessageExpr(matchesSelector("?cont*"))));
+ EXPECT_TRUE(notMatchesObjC(
+ Objc1String,
+ objcMessageExpr(hasSelector("contents"), hasNullSelector())));
+ EXPECT_TRUE(matchesObjC(
+ Objc1String,
+ objcMessageExpr(hasSelector("contents"), hasUnarySelector())));
+ EXPECT_TRUE(matchesObjC(
+ Objc1String,
+ objcMessageExpr(matchesSelector("uppercase*"),
+ argumentCountIs(0)
+ )));
+
+}
+
} // end namespace ast_matchers
} // end namespace clang