DynTypedMatcher DynTypedMatcher::constructVariadic( DynTypedMatcher::VariadicOperator Op, std::vector<DynTypedMatcher> InnerMatchers) { assert(InnerMatchers.size() > 0 && "Array must not be empty."); assert(std::all_of(InnerMatchers.begin(), InnerMatchers.end(), [&InnerMatchers](const DynTypedMatcher &M) { return InnerMatchers[0].canConvertTo(M.SupportedKind); }) && "SupportedKind must be convertible to a common type!"); auto SupportedKind = InnerMatchers[0].SupportedKind; // We must relax the restrict kind here. // The different operators might deal differently with a mismatch. // Make it the same as SupportedKind, since that is the broadest type we are // allowed to accept. auto RestrictKind = SupportedKind; switch (Op) { case VO_AllOf: // In the case of allOf() we must pass all the checks, so making // RestrictKind the most restrictive can save us time. This way we reject // invalid types earlier and we can elide the kind checks inside the // matcher. for (auto &IM : InnerMatchers) { RestrictKind = ast_type_traits::ASTNodeKind::getMostDerivedType( RestrictKind, IM.RestrictKind); } return DynTypedMatcher( SupportedKind, RestrictKind, new VariadicMatcher<AllOfVariadicOperator>(std::move(InnerMatchers))); case VO_AnyOf: return DynTypedMatcher( SupportedKind, RestrictKind, new VariadicMatcher<AnyOfVariadicOperator>(std::move(InnerMatchers))); case VO_EachOf: return DynTypedMatcher( SupportedKind, RestrictKind, new VariadicMatcher<EachOfVariadicOperator>(std::move(InnerMatchers))); case VO_UnaryNot: // FIXME: Implement the Not operator to take a single matcher instead of a // vector. return DynTypedMatcher( SupportedKind, RestrictKind, new VariadicMatcher<NotUnaryOperator>(std::move(InnerMatchers))); } llvm_unreachable("Invalid Op value."); }
DynTypedMatcher DynTypedMatcher::constructVariadic( DynTypedMatcher::VariadicOperator Op, std::vector<DynTypedMatcher> InnerMatchers) { assert(InnerMatchers.size() > 0 && "Array must not be empty."); assert(std::all_of(InnerMatchers.begin(), InnerMatchers.end(), [&InnerMatchers](const DynTypedMatcher &M) { return InnerMatchers[0].SupportedKind.isSame(M.SupportedKind); }) && "SupportedKind must match!"); // We must relax the restrict kind here. // The different operators might deal differently with a mismatch. // Make it the same as SupportedKind, since that is the broadest type we are // allowed to accept. auto SupportedKind = InnerMatchers[0].SupportedKind; VariadicMatcher::VariadicOperatorFunction Func; switch (Op) { case VO_AllOf: Func = AllOfVariadicOperator; break; case VO_AnyOf: Func = AnyOfVariadicOperator; break; case VO_EachOf: Func = EachOfVariadicOperator; break; case VO_UnaryNot: Func = NotUnaryOperator; break; } return DynTypedMatcher(SupportedKind, SupportedKind, new VariadicMatcher(Func, std::move(InnerMatchers))); }
DynTypedMatcher DynTypedMatcher::trueMatcher( ast_type_traits::ASTNodeKind NodeKind) { return DynTypedMatcher(NodeKind, NodeKind, &*TrueMatcherInstance); }