From be40902a7dbac3f7a77cbf160fc76b2d71bb2106 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Mon, 6 Jun 2016 18:52:17 +0000 Subject: [PATCH] Adding an AST matcher to ignore parenthesis in *types* (rather than expressions). This is required for traversing certain types (like function pointer types). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@271927 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LibASTMatchersReference.html | 15 +++++++++++++++ include/clang/ASTMatchers/ASTMatchers.h | 16 ++++++++++++++++ lib/ASTMatchers/Dynamic/Registry.cpp | 1 + unittests/ASTMatchers/ASTMatchersNodeTest.cpp | 7 +++++++ 4 files changed, 39 insertions(+) diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index 433ba7843f..b944fc6b7e 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -3521,6 +3521,10 @@ Example matches X, Y ChildT must be an AST base type. Usable as: Any Matcher +Note that has is direct matcher, so it also matches things like implicit +casts and paren casts. If you are matching with expr then you should +probably consider using ignoringParenImpCasts like: +has(ignoringParenImpCasts(expr())). @@ -4897,6 +4901,17 @@ Usable as: Matcher<QualType>ignoringParensMatcher<QualType> InnerMatcher +
Matches types that match InnerMatcher after any parens are stripped.
+
+Given
+  void (*fp)(void);
+The matcher
+  varDecl(hasType(pointerType(pointee(ignoringParens(functionType())))))
+would match the declaration for fp.
+
+ + Matcher<QualType>pointsToMatcher<Decl> InnerMatcher
Overloaded to match the pointee type's declaration.
 
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 91a7f69472..1f70409826 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -625,6 +625,22 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts, return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder); } +/// \brief Matches types that match InnerMatcher after any parens are stripped. +/// +/// Given +/// \code +/// void (*fp)(void); +/// \endcode +/// The matcher +/// \code +/// varDecl(hasType(pointerType(pointee(ignoringParens(functionType()))))) +/// \endcode +/// would match the declaration for fp. +AST_MATCHER_P(QualType, ignoringParens, + internal::Matcher, InnerMatcher) { + return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder); +} + /// \brief Matches classTemplateSpecializations where the n'th TemplateArgument /// matches the given InnerMatcher. /// diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp index 7f5e50c29a..4961da8925 100644 --- a/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/lib/ASTMatchers/Dynamic/Registry.cpp @@ -268,6 +268,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(ignoringImpCasts); REGISTER_MATCHER(ignoringParenCasts); REGISTER_MATCHER(ignoringParenImpCasts); + REGISTER_MATCHER(ignoringParens); REGISTER_MATCHER(implicitCastExpr); REGISTER_MATCHER(implicitValueInitExpr); REGISTER_MATCHER(incompleteArrayType); diff --git a/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/unittests/ASTMatchers/ASTMatchersNodeTest.cpp index 0f665d6219..4bbc0a4801 100644 --- a/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -1165,6 +1165,13 @@ TEST(TypeMatching, MatchesFunctionTypes) { EXPECT_TRUE(matches("void f(int i) {}", functionType())); } +TEST(TypeMatching, IgnoringParens) { + EXPECT_TRUE( + notMatches("void (*fp)(void);", pointerType(pointee(functionType())))); + EXPECT_TRUE(matches("void (*fp)(void);", + pointerType(pointee(ignoringParens(functionType()))))); +} + TEST(TypeMatching, MatchesFunctionProtoTypes) { EXPECT_TRUE(matches("int (*f)(int);", functionProtoType())); EXPECT_TRUE(matches("void f(int i);", functionProtoType())); -- 2.50.1