Index: include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- include/clang/ASTMatchers/ASTMatchers.h +++ include/clang/ASTMatchers/ASTMatchers.h @@ -4123,6 +4123,24 @@ /// \endcode AST_TYPE_MATCHER(InjectedClassNameType, injectedClassNameType); +/// \brief Matches decayed type +/// Example matches i[] in declaration of f. +/// (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))) +/// Example matches i[1]. +/// (matcher = expr(hasType(decayedType(hasDecayedType(pointerType()))))) +/// \code +/// void f(int i[]) { +/// i[1] = 0; +/// } +/// \endcode +AST_TYPE_MATCHER(DecayedType, decayedType); + +/// \brief Matches the decayed type, whos decayed type matches \c InnerMatcher +AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher, + InnerType) { + return InnerType.matches(Node.getDecayedType(), Finder, Builder); +} + /// \brief Matches declarations whose declaration context, interpreted as a /// Decl, matches \c InnerMatcher. /// Index: lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- lib/ASTMatchers/Dynamic/Registry.cpp +++ lib/ASTMatchers/Dynamic/Registry.cpp @@ -152,6 +152,7 @@ REGISTER_MATCHER(cxxThrowExpr); REGISTER_MATCHER(cxxTryStmt); REGISTER_MATCHER(cxxUnresolvedConstructExpr); + REGISTER_MATCHER(decayedType); REGISTER_MATCHER(decl); REGISTER_MATCHER(declaratorDecl); REGISTER_MATCHER(declCountIs); @@ -199,6 +200,7 @@ REGISTER_MATCHER(hasCaseConstant); REGISTER_MATCHER(hasCondition); REGISTER_MATCHER(hasConditionVariableStatement); + REGISTER_MATCHER(hasDecayedType); REGISTER_MATCHER(hasDeclaration); REGISTER_MATCHER(hasDeclContext); REGISTER_MATCHER(hasDeducedType); Index: unittests/ASTMatchers/ASTMatchersTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersTest.cpp +++ unittests/ASTMatchers/ASTMatchersTest.cpp @@ -4109,6 +4109,11 @@ EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger()))); } +TEST(TypeMatching, DecayedType) { + EXPECT_TRUE(matches("void f(int i[]);", valueDecl(hasType(decayedType(hasDecayedType(pointerType())))))); + EXPECT_TRUE(notMatches("int i[7];", decayedType())); +} + TEST(TypeMatching, MatchesComplexTypes) { EXPECT_TRUE(matches("_Complex float f;", complexType())); EXPECT_TRUE(matches(