From 639522ca3589285e69598460d66206f6a333d816 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Mon, 25 Feb 2013 12:02:08 +0000 Subject: [PATCH] Add matcher for AccessSpecDecls. Also, add matchers isPrivate(), isProtected() and isPublic(), that restrict the matching of such AccessSpecDecls and all other Decls. llvm-svn: 176017 --- clang/include/clang/ASTMatchers/ASTMatchers.h | 63 +++++++++++++++++++ .../unittests/ASTMatchers/ASTMatchersTest.cpp | 40 ++++++++++++ 2 files changed, 103 insertions(+) diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index de9919aaf0da..443c628519a1 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -192,6 +192,69 @@ const internal::VariadicDynCastAllOfMatcher< Decl, ClassTemplateSpecializationDecl> classTemplateSpecializationDecl; +/// \brief Matches C++ access specifier declarations. +/// +/// Given +/// \code +/// class C { +/// public: +/// int a; +/// }; +/// \endcode +/// accessSpecDecl() +/// matches 'public:' +const internal::VariadicDynCastAllOfMatcher< + Decl, + AccessSpecDecl> accessSpecDecl; + +/// \brief Matches public C++ declarations. +/// +/// Given +/// \code +/// class C { +/// public: int a; +/// protected: int b; +/// private: int c; +/// }; +/// \endcode +/// fieldDecl(isPublic()) +/// matches 'int a;' +AST_MATCHER(Decl, isPublic) { + return Node.getAccess() == AS_public; +} + +/// \brief Matches protected C++ declarations. +/// +/// Given +/// \code +/// class C { +/// public: int a; +/// protected: int b; +/// private: int c; +/// }; +/// \endcode +/// fieldDecl(isProtected()) +/// matches 'int b;' +AST_MATCHER(Decl, isProtected) { + return Node.getAccess() == AS_protected; +} + +/// \brief Matches private C++ declarations. +/// +/// Given +/// \code +/// class C { +/// public: int a; +/// protected: int b; +/// private: int c; +/// }; +/// \endcode +/// fieldDecl(isPrivate()) +/// matches 'int c;' +AST_MATCHER(Decl, isPrivate) { + return Node.getAccess() == AS_private; +} + /// \brief Matches classTemplateSpecializations that have at least one /// TemplateArgument matching the given InnerMatcher. /// diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index 8e4f3e932748..63017473f427 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -1413,6 +1413,18 @@ TEST(Matcher, MatchesSpecificArgument) { 1, refersToType(asString("int")))))); } +TEST(Matcher, MatchesAccessSpecDecls) { + EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl())); + EXPECT_TRUE( + matches("class C { public: int i; };", accessSpecDecl(isPublic()))); + EXPECT_TRUE( + notMatches("class C { public: int i; };", accessSpecDecl(isProtected()))); + EXPECT_TRUE( + notMatches("class C { public: int i; };", accessSpecDecl(isPrivate()))); + + EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl())); +} + TEST(Matcher, ConstructorCall) { StatementMatcher Constructor = constructExpr(); @@ -2283,6 +2295,34 @@ TEST(Member, MatchesMember) { memberExpr(hasDeclaration(fieldDecl(hasType(isInteger())))))); } +TEST(Member, UnderstandsAccess) { + EXPECT_TRUE(matches( + "struct A { int i; };", fieldDecl(isPublic(), hasName("i")))); + EXPECT_TRUE(notMatches( + "struct A { int i; };", fieldDecl(isProtected(), hasName("i")))); + EXPECT_TRUE(notMatches( + "struct A { int i; };", fieldDecl(isPrivate(), hasName("i")))); + + EXPECT_TRUE(notMatches( + "class A { int i; };", fieldDecl(isPublic(), hasName("i")))); + EXPECT_TRUE(notMatches( + "class A { int i; };", fieldDecl(isProtected(), hasName("i")))); + EXPECT_TRUE(matches( + "class A { int i; };", fieldDecl(isPrivate(), hasName("i")))); + + EXPECT_TRUE(notMatches( + "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i")))); + EXPECT_TRUE(matches("class A { protected: int i; };", + fieldDecl(isProtected(), hasName("i")))); + EXPECT_TRUE(notMatches( + "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i")))); + + // Non-member decls have the AccessSpecifier AS_none and thus aren't matched. + EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i")))); + EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i")))); + EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i")))); +} + TEST(Member, MatchesMemberAllocationFunction) { // Fails in C++11 mode EXPECT_TRUE(matchesConditionally(