diff options
Diffstat (limited to 'unittests/ASTMatchers/ASTMatchersTest.cpp')
-rw-r--r-- | unittests/ASTMatchers/ASTMatchersTest.cpp | 127 |
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 |