Index: docs/LibASTMatchersReference.html =================================================================== --- docs/LibASTMatchersReference.html +++ docs/LibASTMatchersReference.html @@ -1299,6 +1299,17 @@ +
Matches FunctionProtoType nodes. + +Given + int (*f)(int); + void g(); +functionProtoType() + matches "int (*f)(int)" and the type of "g". +
Matches FunctionType nodes. @@ -2284,13 +2295,34 @@- Matcher<FunctionDecl> parameterCountIs unsigned 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> parameterCountIs unsigned N @@ -4698,6 +4730,17 @@ 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)+ Matcher<TypedefDecl> hasUnderlyingType Matcher<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> hasDeclaration Matcher<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::VariadicDynCastAllOfMatchertypedefDecl; +/// \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) {