748 changes: 470 additions & 278 deletions clang/include/clang/ASTMatchers/ASTMatchers.h

Large diffs are not rendered by default.

28 changes: 5 additions & 23 deletions clang/unittests/ASTMatchers/ASTMatchersTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,6 @@ enum class MatchKind {
Code,
Name,
TypeStr,
TypeOfStr,
};

inline llvm::StringRef toString(const MatchKind Kind) {
Expand All @@ -607,8 +606,6 @@ inline llvm::StringRef toString(const MatchKind Kind) {
return "Name";
case MatchKind::TypeStr:
return "TypeStr";
case MatchKind::TypeOfStr:
return "TypeOfStr";
}
llvm_unreachable("Unhandled MatchKind");
}
Expand Down Expand Up @@ -651,8 +648,6 @@ template <typename T> class VerifyBoundNodeMatch : public BoundNodesCallback {
return getNameText(Node, EmitFailures);
case MatchKind::TypeStr:
return getTypeStrText(Node, EmitFailures);
case MatchKind::TypeOfStr:
return getTypeOfStrText(Node, EmitFailures);
}
}

Expand Down Expand Up @@ -695,27 +690,14 @@ template <typename T> class VerifyBoundNodeMatch : public BoundNodesCallback {
getTypeStrText(const U *const Node, const bool EmitFailures = true) {
if constexpr (std::is_base_of_v<Type, U>)
return QualType(Node, 0).getAsString();
if constexpr (std::is_base_of_v<Decl, U>)
if constexpr (std::is_base_of_v<Decl, U>) {
if (const auto *const TDecl = llvm::dyn_cast<TypeDecl>(Node))
return getTypeStrText(TDecl->getTypeForDecl());

if (EmitFailures)
ADD_FAILURE() << "Match kind is 'TypeStr', but node of type 'U' is "
"not handled.";
return std::nullopt;
}

template <typename U>
static std::optional<std::string>
getTypeOfStrText(const U *const Node, const bool EmitFailures = true) {
if constexpr (std::is_base_of_v<Decl, U>) {
if (const auto *const VDecl = llvm::dyn_cast<ValueDecl>(Node))
return VDecl->getType().getAsString();
} else if constexpr (std::is_base_of_v<Expr, U>)
return Node->getType().getAsString();

}
if (EmitFailures)
ADD_FAILURE() << "Match kind is 'TypeOfStr', but node of type 'U' is "
ADD_FAILURE() << "Match kind is 'TypeStr', but node of type 'U' is "
"not handled.";
return std::nullopt;
}
Expand Down Expand Up @@ -823,8 +805,8 @@ template <typename T> class VerifyBoundNodeMatch : public BoundNodesCallback {
static std::string getPossibleMatchStrings(const T *Node,
const ASTContext &Context) {
std::string MatchStrings{"\n"};
for (const auto Kind : {MatchKind::Code, MatchKind::Name,
MatchKind::TypeStr, MatchKind::TypeOfStr})
for (const auto Kind :
{MatchKind::Code, MatchKind::Name, MatchKind::TypeStr})
MatchStrings +=
llvm::formatv("\tMatchKind: {0}: '{1}',\n", toString(Kind),
Match::getMatchText(Node, Context, Kind, false)
Expand Down
18 changes: 5 additions & 13 deletions clang/utils/generate_ast_matcher_doc_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,15 +496,12 @@ class MatchType(Enum):
Name: Use the name of the matched node to check if it matches
TypeStr: Use the string representation of the matched type to check if
it matches
TypeOfStr: Use the string representation of the type of a matched node
to check if it matches
"""

Invalid = 0
Code = 1
Name = 2
TypeStr = 3
TypeOfStr = 4


def get_match_type(match: Match) -> MatchType:
Expand All @@ -515,9 +512,7 @@ def get_match_type(match: Match) -> MatchType:
return MatchType.Code
if match_type == "typestr":
return MatchType.TypeStr
if match_type == "typeofstr":
return MatchType.TypeOfStr
print(f"match {match} has an invalid match type, tags: {match.tags}")
print(f"match {match} has an invalid match type: {match_type}")
statistics["match_type_invalid"] += 1
return MatchType.Invalid

Expand Down Expand Up @@ -714,13 +709,6 @@ def build_test_case(self):
res += "\n#endif\n"
return res


# FIXME: add support in the html gen script to differentiate between overloads examples

# FIXME: should verify that all polymorphic ast nodes have a test
# FIXME: better diag messages during parsing, user does not need to know about parsing contexts


class ParsingContext(Enum):
NoneCtx = 0
Code = 1
Expand Down Expand Up @@ -1168,5 +1156,9 @@ def main():
exit(1)


# FIXME: add support in the html gen script to differentiate between overloads examples
# FIXME: should verify that all polymorphic ast nodes have a test


if __name__ == "__main__":
main()