Adding an AST matcher to ignore parenthesis in *types* (rather than expressions). This is required for traversing certain types (like function pointer types).

llvm-svn: 271927
This commit is contained in:
Aaron Ballman 2016-06-06 18:52:17 +00:00
parent ef2b488482
commit ba8dbbe86f
4 changed files with 39 additions and 0 deletions

View File

@ -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())).
</pre></td></tr>
@ -4897,6 +4901,17 @@ Usable as: Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1CallE
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('ignoringParens0')"><a name="ignoringParens0Anchor">ignoringParens</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="ignoringParens0"><pre>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.
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('pointsTo1')"><a name="pointsTo1Anchor">pointsTo</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="pointsTo1"><pre>Overloaded to match the pointee type's declaration.
</pre></td></tr>

View File

@ -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<QualType>, InnerMatcher) {
return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
}
/// \brief Matches classTemplateSpecializations where the n'th TemplateArgument
/// matches the given InnerMatcher.
///

View File

@ -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);

View File

@ -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()));