[cfe-commits] r162027 - in /cfe/trunk: include/clang/ASTMatchers/ASTMatchers.h unittests/ASTMatchers/ASTMatchersTest.cpp
Sam Panzer
espanz at gmail.com
Thu Aug 16 10:20:59 PDT 2012
Author: panzer
Date: Thu Aug 16 12:20:59 2012
New Revision: 162027
URL: http://llvm.org/viewvc/llvm-project?rev=162027&view=rev
Log:
Matchers related to DeclStmt for matching the count of declarations, a particular declaration within the statement, and single-Decl DeclStmts.
Modified:
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=162027&r1=162026&r2=162027&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Thu Aug 16 12:20:59 2012
@@ -50,6 +50,7 @@
#include "clang/ASTMatchers/ASTMatchersMacros.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Regex.h"
+#include <iterator>
namespace clang {
namespace ast_matchers {
@@ -1275,6 +1276,21 @@
return false;
}
+/// \brief Matches the Decl of a DeclStmt which has a single declaration.
+///
+/// Given
+/// int a, b;
+/// int c;
+/// declarationStatement(hasSingleDecl(anything()))
+/// matches 'int c;' but not 'int a, b;'.
+AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher<Decl>, InnerMatcher) {
+ if (Node.isSingleDecl()) {
+ const Decl *FoundDecl = Node.getSingleDecl();
+ return InnerMatcher.matches(*FoundDecl, Finder, Builder);
+ }
+ return false;
+}
+
/// \brief Matches a variable declaration that has an initializer expression
/// that matches the given matcher.
///
@@ -1320,6 +1336,44 @@
*Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
}
+/// \brief Matches declaration statements that contain a specific number of
+/// declarations.
+///
+/// Example: Given
+/// int a, b;
+/// int c;
+/// int d = 2, e;
+/// declCountIs(2)
+/// matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'.
+AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N) {
+ return std::distance(Node.decl_begin(), Node.decl_end()) == N;
+}
+
+/// \brief Matches the n'th declaration of a declaration statement.
+///
+/// Note that this does not work for global declarations because the AST
+/// breaks up multiple-declaration DeclStmt's into multiple single-declaration
+/// DeclStmt's.
+/// Example: Given non-global declarations
+/// int a, b = 0;
+/// int c;
+/// int d = 2, e;
+/// declarationStatement(containsDeclaration(
+/// 0, variable(hasInitializer(anything()))))
+/// matches only 'int d = 2, e;', and
+/// declarationStatement(containsDeclaration(1, variable()))
+/// matches 'int a, b = 0' as well as 'int d = 2, e;'
+/// but 'int c;' is not matched.
+AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N,
+ internal::Matcher<Decl>, InnerMatcher) {
+ const unsigned NumDecls = std::distance(Node.decl_begin(), Node.decl_end());
+ if (N >= NumDecls)
+ return false;
+ DeclStmt::const_decl_iterator Iterator = Node.decl_begin();
+ std::advance(Iterator, N);
+ return InnerMatcher.matches(**Iterator, Finder, Builder);
+}
+
/// \brief Matches a constructor initializer.
///
/// Given
Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=162027&r1=162026&r2=162027&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Thu Aug 16 12:20:59 2012
@@ -2377,6 +2377,40 @@
declarationReference(throughUsingDecl(anything()))));
}
+TEST(SingleDecl, IsSingleDecl) {
+ StatementMatcher SingleDeclStmt =
+ declarationStatement(hasSingleDecl(variable(hasInitializer(anything()))));
+ EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
+ EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
+ EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
+ SingleDeclStmt));
+}
+
+TEST(DeclStmt, ContainsDeclaration) {
+ DeclarationMatcher MatchesInit = variable(hasInitializer(anything()));
+
+ EXPECT_TRUE(matches("void f() {int a = 4;}",
+ declarationStatement(containsDeclaration(0,
+ MatchesInit))));
+ EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
+ declarationStatement(containsDeclaration(0, MatchesInit),
+ containsDeclaration(1,
+ MatchesInit))));
+ unsigned WrongIndex = 42;
+ EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
+ declarationStatement(containsDeclaration(WrongIndex,
+ MatchesInit))));
+}
+
+TEST(DeclCount, DeclCountIsCorrect) {
+ EXPECT_TRUE(matches("void f() {int i,j;}",
+ declarationStatement(declCountIs(2))));
+ EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
+ declarationStatement(declCountIs(3))));
+ EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
+ declarationStatement(declCountIs(3))));
+}
+
TEST(While, MatchesWhileLoops) {
EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
More information about the cfe-commits
mailing list