diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index fceea21..b4e8bf5 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -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 {
@@ -1167,6 +1168,20 @@ AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
   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.
 ///
@@ -1212,6 +1227,42 @@ AST_POLYMORPHIC_MATCHER_P2(
               *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 due to the AST
+///
+/// Example: Given non-global declarations
+///   int a, b = 0;
+///   int c;
+///   int d = 2, e;
+///  declarationStatement(hasDecl(0, variable(hasInitializer(anything()))))
+///   matches only 'int d = 2, e;', and
+///  declarationStatement(hasDecl(1, variable()))
+///   matches 'int a, b = 0' as well as 'int d = 2, e;'
+///   but 'int c;' is not matched.
+AST_POLYMORPHIC_MATCHER_P2(
+    hasDecl, unsigned, N, internal::Matcher<Decl>, InnerMatcher) {
+  TOOLING_COMPILE_ASSERT((llvm::is_base_of<DeclStmt, NodeType>::value),
+                         has_decl_requires_decl_stmt);
+  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
diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp
index 597cf6f..e0038c2 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -2084,6 +2084,36 @@ TEST(UsingDeclaration, ThroughUsingDeclaration) {
       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, HasDecl) {
+  DeclarationMatcher MatchesInit = variable(hasInitializer(anything()));
+
+  EXPECT_TRUE(matches("void f() {int a = 4;}",
+                      declarationStatement(hasDecl(0, MatchesInit))));
+  EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
+                      declarationStatement(hasDecl(0, MatchesInit),
+                                           hasDecl(1, MatchesInit))));
+  unsigned WrongIndex = 42;
+  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
+                         declarationStatement(hasDecl(WrongIndex,
+                                                      MatchesInit))));
+}
+
+TEST(DeclCount, DeclCountIsCorrect) {
+  EXPECT_TRUE(matches("void f() {int i,j; int k;}",
+                      declarationStatement(declCountIs(2))));
+  EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
+                         declarationStatement(declCountIs(3))));
+}
+
 TEST(While, MatchesWhileLoops) {
   EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
   EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
