Index: docs/LibASTMatchersReference.html =================================================================== --- docs/LibASTMatchersReference.html +++ docs/LibASTMatchersReference.html @@ -1299,6 +1299,17 @@ +Matcher<Type>functionProtoTypeMatcher<FunctionProtoType>... +
Matches FunctionProtoType nodes.
+
+Given
+  int (*f)(int);
+  void g();
+functionProtoType()
+  matches "int (*f)(int)" and the type of "g".
+
+ + Matcher<Type>functionTypeMatcher<FunctionType>...
Matches FunctionType nodes.
 
@@ -2284,13 +2295,34 @@
 
 
 Matcher<FunctionDecl>parameterCountIsunsigned N
-
Matches FunctionDecls that have a specific parameter count.
+
Matches FunctionDecls and FunctionProtoTypes that have a specific
+parameter count.
 
 Given
   void f(int i) {}
   void g(int i, int j) {}
+  void h(int i, int j);
+  void j(int i);
 functionDecl(parameterCountIs(2))
-  matches g(int i, int j) {}
+  matches void g(int i, int j) {}
+functionProtoType(parameterCountIs(2))
+  matches void h(int i, int j)
+
+ + +Matcher<FunctionProtoType>parameterCountIsunsigned N +
Matches FunctionDecls and FunctionProtoTypes that have a specific
+parameter count.
+
+Given
+  void f(int i) {}
+  void g(int i, int j) {}
+  void h(int i, int j);
+  void j(int i);
+functionDecl(parameterCountIs(2))
+  matches void g(int i, int j) {}
+functionProtoType(parameterCountIs(2))
+  matches void h(int i, int j)
 
@@ -4698,6 +4730,17 @@
+Matcher<TypedefDecl>hasUnderlyingTypeMatcher<QualType> InnerMatcher +
Matches the underlying type of a typedef declaration
+
+Given
+  typedef int X;
+  typedef float Y;
+typedefDecl(hasUnderlyingType(asString("int")))
+  matches "typedef int X"
+
+ + Matcher<TypedefType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -168,6 +168,21 @@
 ///   matches "typedef int X"
 const internal::VariadicDynCastAllOfMatcher typedefDecl;
 
+/// \brief Matches the underlying type of a typedef declaration
+///
+/// Given
+/// \code
+///   typedef int X;
+///   typedef float Y;
+/// \endcode
+/// typedefDecl(hasUnderlyingType(asString("int")))
+///   matches "typedef int X"
+AST_MATCHER_P(TypedefDecl, hasUnderlyingType, internal::Matcher,
+              InnerMatcher) {
+  QualType UnderlyingType = Node.getUnderlyingType();
+  return InnerMatcher.matches(UnderlyingType, Finder, Builder);
+}
+
 /// \brief Matches AST nodes that were expanded within the main-file.
 ///
 /// Example matches X but not Y
@@ -2889,16 +2904,24 @@
                                     Node.param_end(), Finder, Builder);
 }
 
-/// \brief Matches \c FunctionDecls that have a specific parameter count.
+/// \brief Matches \c FunctionDecls and FunctionProtoTypes that have a specific
+/// parameter count.
 ///
 /// Given
 /// \code
 ///   void f(int i) {}
 ///   void g(int i, int j) {}
+///   void h(int i, int j);
+///   void j(int i);
 /// \endcode
 /// functionDecl(parameterCountIs(2))
-///   matches g(int i, int j) {}
-AST_MATCHER_P(FunctionDecl, parameterCountIs, unsigned, N) {
+///   matches void g(int i, int j) {}
+/// functionProtoType(parameterCountIs(2))
+///   matches void h(int i, int j)
+AST_POLYMORPHIC_MATCHER_P(parameterCountIs,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+                                                          FunctionProtoType),
+                          unsigned, N) {
   return Node.getNumParams() == N;
 }
 
@@ -3988,6 +4011,17 @@
 ///   matches "int (*f)(int)" and the type of "g".
 AST_TYPE_MATCHER(FunctionType, functionType);
 
+/// \brief Matches \c FunctionProtoType nodes.
+///
+/// Given
+/// \code
+///   int (*f)(int);
+///   void g();
+/// \endcode
+/// functionProtoType()
+///   matches "int (*f)(int)" and the type of "g".
+AST_TYPE_MATCHER(FunctionProtoType, functionProtoType);
+
 /// \brief Matches \c ParenType nodes.
 ///
 /// Given
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -181,6 +181,7 @@
   REGISTER_MATCHER(forStmt);
   REGISTER_MATCHER(friendDecl);
   REGISTER_MATCHER(functionDecl);
+  REGISTER_MATCHER(functionProtoType);
   REGISTER_MATCHER(functionTemplateDecl);
   REGISTER_MATCHER(functionType);
   REGISTER_MATCHER(gotoStmt);
@@ -248,6 +249,7 @@
   REGISTER_MATCHER(hasTrueExpression);
   REGISTER_MATCHER(hasTypeLoc);
   REGISTER_MATCHER(hasUnaryOperand);
+  REGISTER_MATCHER(hasUnderlyingType);
   REGISTER_MATCHER(hasUnarySelector);
   REGISTER_MATCHER(hasValueType);
   REGISTER_MATCHER(ifStmt);
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -1622,6 +1622,7 @@
   EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
   EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
   EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
+  EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));
 }
 
 TEST(Matcher, References) {
@@ -4276,6 +4277,15 @@
   EXPECT_TRUE(matches("void f(int i) {}", functionType()));
 }
 
+TEST(TypeMatching, MatchesFunctionProtoTypes) {
+  EXPECT_TRUE(matches("int (*f)(int);", functionProtoType()));
+  EXPECT_TRUE(matches("void f(int i);", functionProtoType()));
+  EXPECT_TRUE(matches("void f();", functionProtoType(parameterCountIs(0))));
+  EXPECT_TRUE(notMatchesC("void f();", functionProtoType()));
+  EXPECT_TRUE(
+      matchesC("void f(void);", functionProtoType(parameterCountIs(0))));
+}
+
 TEST(TypeMatching, MatchesParenType) {
   EXPECT_TRUE(
       matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType())))));
@@ -4977,7 +4987,20 @@
                       namespaceDecl(isInline(), hasName("m"))));
 }
 
-// FIXME: Figure out how to specify paths so the following tests pass on Windows.
+TEST(HasUnderlyingTypeMatcher, Match) {
+  EXPECT_TRUE(matches("typedef int hasUnderlyingTypeTest;",
+                      typedefDecl(hasUnderlyingType(asString("int")))));
+  EXPECT_TRUE(matches("typedef const int T;",
+                      typedefDecl(hasUnderlyingType(asString("const int")))));
+  EXPECT_TRUE(notMatches("typedef const int T;",
+                         typedefDecl(hasUnderlyingType(asString("int")))));
+  EXPECT_TRUE(
+      matches("typedef int foo; typedef foo bar;",
+              typedefDecl(hasUnderlyingType(asString("foo")), hasName("bar"))));
+}
+
+// FIXME: Figure out how to specify paths so the following tests pass on
+// Windows.
 #ifndef LLVM_ON_WIN32
 
 TEST(Matcher, IsExpansionInMainFileMatcher) {