35 #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
36 #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
49 #include "llvm/ADT/Optional.h"
50 #include "llvm/ADT/VariadicFunction.h"
51 #include "llvm/Support/ManagedStatic.h"
57 namespace ast_matchers {
69 void addNode(StringRef
ID,
const ast_type_traits::DynTypedNode& DynNode) {
70 NodeMap[
ID] = DynNode;
78 const T *getNodeAs(StringRef
ID)
const {
79 IDToNodeMap::const_iterator It = NodeMap.find(ID);
80 if (It == NodeMap.end()) {
83 return It->second.get<T>();
86 ast_type_traits::DynTypedNode getNode(StringRef ID)
const {
87 IDToNodeMap::const_iterator It = NodeMap.find(ID);
88 if (It == NodeMap.end()) {
89 return ast_type_traits::DynTypedNode();
95 bool operator<(
const BoundNodesMap &Other)
const {
96 return NodeMap < Other.NodeMap;
104 typedef std::map<std::string, ast_type_traits::DynTypedNode> IDToNodeMap;
106 const IDToNodeMap &getMap()
const {
112 bool isComparable()
const {
113 for (
const auto &IDAndNode : NodeMap) {
114 if (!IDAndNode.second.getMemoizationData())
128 class BoundNodesTreeBuilder {
134 virtual ~Visitor() {}
139 virtual void visitMatch(
const BoundNodes& BoundNodesView) = 0;
143 void setBinding(StringRef Id,
const ast_type_traits::DynTypedNode &DynNode) {
144 if (Bindings.empty())
145 Bindings.emplace_back();
146 for (BoundNodesMap &Binding : Bindings)
147 Binding.addNode(Id, DynNode);
151 void addMatch(
const BoundNodesTreeBuilder &Bindings);
156 void visitMatches(Visitor* ResultVisitor);
158 template <
typename ExcludePredicate>
159 bool removeBindings(
const ExcludePredicate &Predicate) {
160 Bindings.erase(std::remove_if(Bindings.begin(), Bindings.end(), Predicate),
162 return !Bindings.empty();
166 bool operator<(
const BoundNodesTreeBuilder &Other)
const {
167 return Bindings < Other.Bindings;
172 bool isComparable()
const {
173 for (
const BoundNodesMap &NodesMap : Bindings) {
174 if (!NodesMap.isComparable())
181 SmallVector<BoundNodesMap, 16> Bindings;
184 class ASTMatchFinder;
191 class DynMatcherInterface :
public RefCountedBaseVPTR {
197 virtual bool dynMatches(
const ast_type_traits::DynTypedNode &DynNode,
199 BoundNodesTreeBuilder *
Builder)
const = 0;
209 template <
typename T>
210 class MatcherInterface :
public DynMatcherInterface {
212 ~MatcherInterface()
override {}
220 BoundNodesTreeBuilder *
Builder)
const = 0;
222 bool dynMatches(
const ast_type_traits::DynTypedNode &DynNode,
224 BoundNodesTreeBuilder *
Builder)
const override {
225 return matches(DynNode.getUnchecked<T>(), Finder, Builder);
231 template <
typename T>
232 class SingleNodeMatcherInterface :
public MatcherInterface<T> {
237 virtual bool matchesNode(
const T &
Node)
const = 0;
243 BoundNodesTreeBuilder * )
const override {
244 return matchesNode(Node);
248 template <
typename>
class Matcher;
257 class DynTypedMatcher {
260 template <
typename T>
261 DynTypedMatcher(MatcherInterface<T> *Implementation)
263 SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
264 RestrictKind(SupportedKind), Implementation(Implementation) {}
267 enum VariadicOperator {
282 static DynTypedMatcher
283 constructVariadic(VariadicOperator Op,
289 static DynTypedMatcher trueMatcher(ast_type_traits::ASTNodeKind NodeKind);
291 void setAllowBind(
bool AB) { AllowBind = AB; }
296 bool canMatchNodesOfKind(ast_type_traits::ASTNodeKind
Kind)
const;
300 DynTypedMatcher dynCastTo(
const ast_type_traits::ASTNodeKind
Kind)
const;
303 bool matches(
const ast_type_traits::DynTypedNode &DynNode,
304 ASTMatchFinder *
Finder, BoundNodesTreeBuilder *
Builder)
const;
310 bool matchesNoKindCheck(
const ast_type_traits::DynTypedNode &DynNode,
312 BoundNodesTreeBuilder *
Builder)
const;
326 typedef std::pair<ast_type_traits::ASTNodeKind, uint64_t> MatcherIDType;
327 MatcherIDType getID()
const {
330 return std::make_pair(RestrictKind,
331 reinterpret_cast<uint64_t>(Implementation.get()));
338 ast_type_traits::ASTNodeKind getSupportedKind()
const {
339 return SupportedKind;
347 template <
typename T>
bool canConvertTo()
const {
348 return canConvertTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
350 bool canConvertTo(ast_type_traits::ASTNodeKind To)
const;
357 template <
typename T> Matcher<T> convertTo()
const {
358 assert(canConvertTo<T>());
359 return unconditionalConvertTo<T>();
366 template <
typename T> Matcher<T> unconditionalConvertTo()
const;
369 DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind,
370 ast_type_traits::ASTNodeKind RestrictKind,
371 IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
373 SupportedKind(SupportedKind),
374 RestrictKind(RestrictKind),
375 Implementation(std::move(Implementation)) {}
378 ast_type_traits::ASTNodeKind SupportedKind;
383 ast_type_traits::ASTNodeKind RestrictKind;
384 IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
391 template <
typename T>
392 class WrapperMatcherInterface :
public MatcherInterface<T> {
394 explicit WrapperMatcherInterface(DynTypedMatcher &&
InnerMatcher)
408 template <
typename T>
412 explicit Matcher(MatcherInterface<T> *Implementation)
413 : Implementation(Implementation) {}
418 template <
typename From>
419 Matcher(
const Matcher<From> &Other,
420 typename std::enable_if<std::is_base_of<From, T>::value &&
421 !std::is_same<From, T>::value>::
type * = 0)
422 : Implementation(restrictMatcher(Other.Implementation)) {
423 assert(Implementation.getSupportedKind().isSame(
424 ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
430 template <
typename TypeT>
431 Matcher(
const Matcher<TypeT> &Other,
432 typename std::enable_if<
433 std::is_same<T, QualType>::value &&
434 std::is_same<TypeT, Type>::value>::
type* = 0)
435 : Implementation(new TypeToQualType<TypeT>(Other)) {}
440 template <
typename To>
441 Matcher<To> dynCastTo()
const {
442 static_assert(std::is_base_of<To, T>::value,
"Invalid dynCast call.");
443 return Matcher<To>(Implementation);
449 BoundNodesTreeBuilder *
Builder)
const {
455 DynTypedMatcher::MatcherIDType getID()
const {
456 return Implementation.getID();
463 operator DynTypedMatcher()
const {
return Implementation; }
471 template <
typename TypeT>
472 class TypeToQualType :
public WrapperMatcherInterface<QualType> {
475 : TypeToQualType::WrapperMatcherInterface(InnerMatcher) {}
477 bool matches(
const QualType &Node, ASTMatchFinder *Finder,
478 BoundNodesTreeBuilder *Builder)
const override {
488 template <
typename U>
friend class Matcher;
490 friend class DynTypedMatcher;
492 static DynTypedMatcher restrictMatcher(
const DynTypedMatcher &Other) {
493 return Other.dynCastTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
496 explicit Matcher(
const DynTypedMatcher &Implementation)
497 : Implementation(restrictMatcher(Implementation)) {
498 assert(this->Implementation.getSupportedKind()
499 .isSame(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
502 DynTypedMatcher Implementation;
507 template <
typename T>
508 inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
509 return Matcher<T>(Implementation);
517 inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>()
const {
518 assert(canConvertTo<QualType>());
519 const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
520 if (SourceKind.isSame(
521 ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) {
523 return unconditionalConvertTo<Type>();
525 return unconditionalConvertTo<QualType>();
529 template <
typename MatcherT,
typename IteratorT>
530 bool matchesFirstInRange(
const MatcherT &
Matcher, IteratorT Start,
531 IteratorT
End, ASTMatchFinder *Finder,
532 BoundNodesTreeBuilder *Builder) {
533 for (IteratorT I = Start; I !=
End; ++I) {
534 BoundNodesTreeBuilder
Result(*Builder);
535 if (Matcher.matches(*I, Finder, &Result)) {
536 *Builder = std::move(Result);
545 template <
typename MatcherT,
typename IteratorT>
546 bool matchesFirstInPointerRange(
const MatcherT &Matcher, IteratorT Start,
547 IteratorT End, ASTMatchFinder *Finder,
548 BoundNodesTreeBuilder *Builder) {
549 for (IteratorT I = Start; I !=
End; ++I) {
550 BoundNodesTreeBuilder
Result(*Builder);
551 if (Matcher.matches(**I, Finder, &Result)) {
552 *Builder = std::move(Result);
560 template <
typename T>
struct has_getDecl {
561 struct Default {
int getDecl; };
562 struct Derived : T, Default { };
564 template<
typename C, C>
struct CheckT;
570 static char (&f(CheckT<int Default::*, &C::getDecl>*))[1];
571 template<
typename C>
static char (&f(...))[2];
573 static bool const value =
sizeof(f<Derived>(
nullptr)) == 2;
580 template <
typename T,
typename ArgT>
581 class HasOverloadedOperatorNameMatcher :
public SingleNodeMatcherInterface<T> {
582 static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
583 std::is_base_of<FunctionDecl, T>::value,
584 "unsupported class for matcher");
585 static_assert(std::is_same<ArgT, StringRef>::value,
586 "argument type must be StringRef");
589 explicit HasOverloadedOperatorNameMatcher(
const StringRef Name)
590 : SingleNodeMatcherInterface<T>(), Name(Name) {}
592 bool matchesNode(
const T &Node)
const override {
593 return matchesSpecialized(Node);
601 bool matchesSpecialized(
const CXXOperatorCallExpr &Node)
const {
607 bool matchesSpecialized(
const FunctionDecl &Node)
const {
608 return Node.isOverloadedOperator() &&
618 class HasNameMatcher :
public SingleNodeMatcherInterface<NamedDecl> {
620 explicit HasNameMatcher(StringRef Name);
622 bool matchesNode(
const NamedDecl &Node)
const override;
629 bool matchesNodeUnqualified(
const NamedDecl &Node)
const;
636 bool matchesNodeFull(
const NamedDecl &Node)
const;
638 const bool UseUnqualifiedMatch;
639 const std::string Name;
646 template <
typename T,
typename DeclMatcherT>
647 class HasDeclarationMatcher :
public WrapperMatcherInterface<T> {
648 static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
649 "instantiated with wrong types");
652 explicit HasDeclarationMatcher(
const Matcher<Decl> &
InnerMatcher)
653 : HasDeclarationMatcher::WrapperMatcherInterface(InnerMatcher) {}
655 bool matches(
const T &Node, ASTMatchFinder *Finder,
656 BoundNodesTreeBuilder *Builder)
const override {
657 return matchesSpecialized(Node, Finder, Builder);
663 template <
typename U>
664 bool matchesSpecialized(
665 const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
666 typename std::enable_if<has_getDecl<U>::value,
int>::
type = 0)
const {
672 bool matchesSpecialized(
const QualType &Node, ASTMatchFinder *Finder,
673 BoundNodesTreeBuilder *Builder)
const {
677 if (
const EnumType *AsEnum = dyn_cast<EnumType>(Node.getTypePtr()))
679 return matchesDecl(Node->getAsCXXRecordDecl(),
Finder,
Builder);
684 bool matchesSpecialized(
const TemplateSpecializationType &Node,
685 ASTMatchFinder *Finder,
686 BoundNodesTreeBuilder *Builder)
const {
687 return matchesDecl(Node.getTemplateName().getAsTemplateDecl(),
693 bool matchesSpecialized(
const CallExpr &Node, ASTMatchFinder *Finder,
694 BoundNodesTreeBuilder *Builder)
const {
700 bool matchesSpecialized(
const CXXConstructExpr &Node,
701 ASTMatchFinder *Finder,
702 BoundNodesTreeBuilder *Builder)
const {
708 bool matchesSpecialized(
const MemberExpr &Node,
709 ASTMatchFinder *Finder,
710 BoundNodesTreeBuilder *Builder)
const {
716 bool matchesDecl(
const Decl *Node, ASTMatchFinder *Finder,
717 BoundNodesTreeBuilder *Builder)
const {
718 return Node !=
nullptr &&
726 template <
typename T>
728 static const bool value =
729 std::is_same<T, Decl>::value ||
730 std::is_same<T, Stmt>::value ||
731 std::is_same<T, QualType>::value ||
732 std::is_same<T, Type>::value ||
733 std::is_same<T, TypeLoc>::value ||
734 std::is_same<T, NestedNameSpecifier>::value ||
735 std::is_same<T, NestedNameSpecifierLoc>::value ||
736 std::is_same<T, CXXCtorInitializer>::value;
738 template <
typename T>
739 const bool IsBaseType<T>::value;
759 class ASTMatchFinder {
767 TK_IgnoreImplicitCastsAndParentheses
779 enum AncestorMatchMode {
786 virtual ~ASTMatchFinder() {}
792 virtual bool classIsDerivedFrom(
const CXXRecordDecl *Declaration,
793 const Matcher<NamedDecl> &
Base,
794 BoundNodesTreeBuilder *Builder) = 0;
796 template <
typename T>
797 bool matchesChildOf(
const T &Node,
798 const DynTypedMatcher &Matcher,
799 BoundNodesTreeBuilder *Builder,
800 TraversalKind Traverse,
802 static_assert(std::is_base_of<Decl, T>::value ||
803 std::is_base_of<Stmt, T>::value ||
804 std::is_base_of<NestedNameSpecifier, T>::value ||
805 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
806 std::is_base_of<TypeLoc, T>::value ||
807 std::is_base_of<QualType, T>::value,
808 "unsupported type for recursive matching");
810 Matcher, Builder, Traverse, Bind);
813 template <
typename T>
814 bool matchesDescendantOf(
const T &Node,
815 const DynTypedMatcher &Matcher,
816 BoundNodesTreeBuilder *Builder,
818 static_assert(std::is_base_of<Decl, T>::value ||
819 std::is_base_of<Stmt, T>::value ||
820 std::is_base_of<NestedNameSpecifier, T>::value ||
821 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
822 std::is_base_of<TypeLoc, T>::value ||
823 std::is_base_of<QualType, T>::value,
824 "unsupported type for recursive matching");
826 Matcher, Builder, Bind);
830 template <
typename T>
831 bool matchesAncestorOf(
const T &Node,
832 const DynTypedMatcher &Matcher,
833 BoundNodesTreeBuilder *Builder,
834 AncestorMatchMode MatchMode) {
835 static_assert(std::is_base_of<Decl, T>::value ||
836 std::is_base_of<Stmt, T>::value,
837 "only Decl or Stmt allowed for recursive matching");
839 Matcher, Builder, MatchMode);
842 virtual ASTContext &getASTContext()
const = 0;
845 virtual bool matchesChildOf(
const ast_type_traits::DynTypedNode &Node,
846 const DynTypedMatcher &Matcher,
847 BoundNodesTreeBuilder *Builder,
848 TraversalKind Traverse,
851 virtual bool matchesDescendantOf(
const ast_type_traits::DynTypedNode &Node,
852 const DynTypedMatcher &Matcher,
853 BoundNodesTreeBuilder *Builder,
856 virtual bool matchesAncestorOf(
const ast_type_traits::DynTypedNode &Node,
857 const DynTypedMatcher &Matcher,
858 BoundNodesTreeBuilder *Builder,
859 AncestorMatchMode MatchMode) = 0;
866 template <
typename... Ts>
struct TypeList {};
868 template <
typename T1,
typename... Ts>
struct TypeList<T1, Ts...> {
876 typedef TypeList<Ts...> tail;
880 typedef TypeList<> EmptyTypeList;
884 template <
typename AnyTypeList,
typename T>
885 struct TypeListContainsSuperOf {
886 static const bool value =
887 std::is_base_of<typename AnyTypeList::head, T>::value ||
888 TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
890 template <
typename T>
891 struct TypeListContainsSuperOf<EmptyTypeList, T> {
892 static const bool value =
false;
898 typedef TypeList<Decl,
Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
899 QualType, Type, TypeLoc, CXXCtorInitializer> AllNodeBaseTypes;
905 template <
class T>
struct ExtractFunctionArgMeta;
906 template <
class T>
struct ExtractFunctionArgMeta<void(T)> {
911 typedef AllNodeBaseTypes AdaptativeDefaultFromTypes;
912 typedef TypeList<Decl,
Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
913 TypeLoc, QualType> AdaptativeDefaultToTypes;
916 typedef TypeList<CallExpr, CXXConstructExpr, DeclRefExpr, EnumType,
917 InjectedClassNameType, LabelStmt, MemberExpr, QualType,
918 RecordType, TagType, TemplateSpecializationType,
919 TemplateTypeParmType, TypedefType,
920 UnresolvedUsingType> HasDeclarationSupportedTypes;
935 template <
template <
typename ToArg,
typename FromArg>
class ArgumentAdapterT,
936 typename FromTypes = AdaptativeDefaultFromTypes,
937 typename ToTypes = AdaptativeDefaultToTypes>
938 struct ArgumentAdaptingMatcherFunc {
939 template <
typename T>
class Adaptor {
942 : InnerMatcher(InnerMatcher) {}
944 typedef ToTypes ReturnTypes;
946 template <
typename To>
operator Matcher<To>()
const {
947 return Matcher<To>(
new ArgumentAdapterT<To, T>(
InnerMatcher));
954 template <
typename T>
959 template <
typename T>
960 Adaptor<T> operator()(
const Matcher<T> &
InnerMatcher)
const {
961 return create(InnerMatcher);
977 template <
template <
typename T>
class MatcherT,
978 typename ReturnTypesF = void(AllNodeBaseTypes)>
979 class PolymorphicMatcherWithParam0 {
982 template <
typename T>
983 operator Matcher<T>()
const {
984 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
985 "right polymorphic conversion");
986 return Matcher<T>(
new MatcherT<T>());
990 template <
template <
typename T,
typename P1>
class MatcherT,
992 typename ReturnTypesF = void(AllNodeBaseTypes)>
993 class PolymorphicMatcherWithParam1 {
995 explicit PolymorphicMatcherWithParam1(
const P1 &Param1)
1000 template <
typename T>
1001 operator Matcher<T>()
const {
1002 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1003 "right polymorphic conversion");
1004 return Matcher<T>(
new MatcherT<T, P1>(Param1));
1011 template <
template <
typename T,
typename P1,
typename P2>
class MatcherT,
1012 typename P1,
typename P2,
1013 typename ReturnTypesF = void(AllNodeBaseTypes)>
1014 class PolymorphicMatcherWithParam2 {
1016 PolymorphicMatcherWithParam2(
const P1 &Param1,
const P2 &Param2)
1017 : Param1(Param1), Param2(Param2) {}
1021 template <
typename T>
1022 operator Matcher<T>()
const {
1023 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1024 "right polymorphic conversion");
1025 return Matcher<T>(
new MatcherT<T, P1, P2>(Param1, Param2));
1039 typedef AllNodeBaseTypes ReturnTypes;
1041 template <
typename T>
1042 operator Matcher<T>()
const {
1043 return DynTypedMatcher::trueMatcher(
1044 ast_type_traits::ASTNodeKind::getFromNodeKind<T>())
1045 .template unconditionalConvertTo<T>();
1053 template <
typename T>
1054 class BindableMatcher :
public Matcher<T> {
1056 explicit BindableMatcher(
const Matcher<T> &M) : Matcher<T>(M) {}
1057 explicit BindableMatcher(MatcherInterface<T> *Implementation)
1058 : Matcher<T>(Implementation) {}
1064 Matcher<T> bind(StringRef ID)
const {
1065 return DynTypedMatcher(*
this)
1067 ->template unconditionalConvertTo<T>();
1072 operator DynTypedMatcher()
const {
1073 DynTypedMatcher
Result =
static_cast<const Matcher<T>&
>(*this);
1074 Result.setAllowBind(
true);
1083 template <
typename T,
typename ChildT>
1084 class HasMatcher :
public WrapperMatcherInterface<T> {
1085 static_assert(IsBaseType<ChildT>::value,
1086 "has only accepts base type matcher");
1089 explicit HasMatcher(
const Matcher<ChildT> &ChildMatcher)
1090 : HasMatcher::WrapperMatcherInterface(ChildMatcher) {}
1092 bool matches(
const T &Node, ASTMatchFinder *Finder,
1093 BoundNodesTreeBuilder *Builder)
const override {
1094 return Finder->matchesChildOf(
1096 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
1097 ASTMatchFinder::BK_First);
1106 template <
typename T,
typename ChildT>
1107 class ForEachMatcher :
public WrapperMatcherInterface<T> {
1108 static_assert(IsBaseType<ChildT>::value,
1109 "for each only accepts base type matcher");
1112 explicit ForEachMatcher(
const Matcher<ChildT> &ChildMatcher)
1113 : ForEachMatcher::WrapperMatcherInterface(ChildMatcher) {}
1115 bool matches(
const T& Node, ASTMatchFinder* Finder,
1116 BoundNodesTreeBuilder* Builder)
const override {
1117 return Finder->matchesChildOf(
1119 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
1120 ASTMatchFinder::BK_All);
1133 template <
typename... Ps>
class VariadicOperatorMatcher {
1135 VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
1136 : Op(Op), Params(std::forward<Ps>(Params)...) {}
1138 template <
typename T>
operator Matcher<T>()
const {
1139 return DynTypedMatcher::constructVariadic(
1140 Op, getMatchers<T>(llvm::index_sequence_for<Ps...>()))
1141 .template unconditionalConvertTo<T>();
1147 std::vector<DynTypedMatcher> getMatchers(llvm::index_sequence<Is...>)
const {
1148 return {Matcher<T>(std::get<Is>(Params))...};
1151 const DynTypedMatcher::VariadicOperator Op;
1152 std::tuple<Ps...> Params;
1157 template <
unsigned MinCount,
unsigned MaxCount>
1158 struct VariadicOperatorMatcherFunc {
1159 DynTypedMatcher::VariadicOperator Op;
1161 template <
typename... Ms>
1162 VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps)
const {
1163 static_assert(MinCount <=
sizeof...(Ms) &&
sizeof...(Ms) <= MaxCount,
1164 "invalid number of parameters for variadic matcher");
1165 return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...);
1171 template <
typename T>
1172 inline Matcher<T> DynTypedMatcher::unconditionalConvertTo()
const {
1173 return Matcher<T>(*this);
1177 template<
typename T>
1178 BindableMatcher<T> makeAllOfComposite(
1182 return BindableMatcher<T>(TrueMatcher());
1190 typedef llvm::pointee_iterator<const Matcher<T> *
const *> PI;
1191 std::vector<DynTypedMatcher> DynMatchers(PI(
InnerMatchers.begin()),
1193 return BindableMatcher<T>(
1194 DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf,
1195 std::move(DynMatchers))
1196 .template unconditionalConvertTo<T>());
1205 template<
typename T,
typename InnerT>
1206 BindableMatcher<T> makeDynCastAllOfComposite(
1208 return BindableMatcher<T>(
1216 template <
typename T,
typename DescendantT>
1217 class HasDescendantMatcher :
public WrapperMatcherInterface<T> {
1218 static_assert(IsBaseType<DescendantT>::value,
1219 "has descendant only accepts base type matcher");
1222 explicit HasDescendantMatcher(
const Matcher<DescendantT> &DescendantMatcher)
1223 : HasDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
1225 bool matches(
const T &Node, ASTMatchFinder *Finder,
1226 BoundNodesTreeBuilder *Builder)
const override {
1227 return Finder->matchesDescendantOf(Node, this->
InnerMatcher, Builder,
1228 ASTMatchFinder::BK_First);
1236 template <
typename T,
typename ParentT>
1237 class HasParentMatcher :
public WrapperMatcherInterface<T> {
1238 static_assert(IsBaseType<ParentT>::value,
1239 "has parent only accepts base type matcher");
1242 explicit HasParentMatcher(
const Matcher<ParentT> &ParentMatcher)
1243 : HasParentMatcher::WrapperMatcherInterface(ParentMatcher) {}
1245 bool matches(
const T &Node, ASTMatchFinder *Finder,
1246 BoundNodesTreeBuilder *Builder)
const override {
1247 return Finder->matchesAncestorOf(Node, this->
InnerMatcher, Builder,
1248 ASTMatchFinder::AMM_ParentOnly);
1256 template <
typename T,
typename AncestorT>
1257 class HasAncestorMatcher :
public WrapperMatcherInterface<T> {
1258 static_assert(IsBaseType<AncestorT>::value,
1259 "has ancestor only accepts base type matcher");
1262 explicit HasAncestorMatcher(
const Matcher<AncestorT> &AncestorMatcher)
1263 : HasAncestorMatcher::WrapperMatcherInterface(AncestorMatcher) {}
1265 bool matches(
const T &Node, ASTMatchFinder *Finder,
1266 BoundNodesTreeBuilder *Builder)
const override {
1267 return Finder->matchesAncestorOf(Node, this->
InnerMatcher, Builder,
1268 ASTMatchFinder::AMM_All);
1278 template <
typename T,
typename DescendantT>
1279 class ForEachDescendantMatcher :
public WrapperMatcherInterface<T> {
1280 static_assert(IsBaseType<DescendantT>::value,
1281 "for each descendant only accepts base type matcher");
1284 explicit ForEachDescendantMatcher(
1285 const Matcher<DescendantT> &DescendantMatcher)
1286 : ForEachDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
1288 bool matches(
const T &Node, ASTMatchFinder *Finder,
1289 BoundNodesTreeBuilder *Builder)
const override {
1290 return Finder->matchesDescendantOf(Node, this->
InnerMatcher, Builder,
1291 ASTMatchFinder::BK_All);
1297 template <
typename T,
typename ValueT>
1298 class ValueEqualsMatcher :
public SingleNodeMatcherInterface<T> {
1299 static_assert(std::is_base_of<CharacterLiteral, T>::value ||
1300 std::is_base_of<CXXBoolLiteralExpr, T>::value ||
1301 std::is_base_of<FloatingLiteral, T>::value ||
1302 std::is_base_of<IntegerLiteral, T>::value,
1303 "the node must have a getValue method");
1306 explicit ValueEqualsMatcher(
const ValueT &ExpectedValue)
1307 : ExpectedValue(ExpectedValue) {}
1309 bool matchesNode(
const T &Node)
const override {
1310 return Node.getValue() == ExpectedValue;
1314 const ValueT ExpectedValue;
1320 inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
1321 const FloatingLiteral &Node)
const {
1322 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle)
1323 return Node.getValue().convertToFloat() == ExpectedValue;
1324 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble)
1325 return Node.getValue().convertToDouble() == ExpectedValue;
1329 inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
1330 const FloatingLiteral &Node)
const {
1331 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle)
1332 return Node.getValue().convertToFloat() == ExpectedValue;
1333 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble)
1334 return Node.getValue().convertToDouble() == ExpectedValue;
1338 inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
1339 const FloatingLiteral &Node)
const {
1340 return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
1355 template <
typename SourceT,
typename TargetT>
1356 class VariadicDynCastAllOfMatcher
1357 :
public llvm::VariadicFunction<
1358 BindableMatcher<SourceT>, Matcher<TargetT>,
1359 makeDynCastAllOfComposite<SourceT, TargetT> > {
1361 VariadicDynCastAllOfMatcher() {}
1374 template <
typename T>
1375 class VariadicAllOfMatcher :
public llvm::VariadicFunction<
1376 BindableMatcher<T>, Matcher<T>,
1377 makeAllOfComposite<T> > {
1379 VariadicAllOfMatcher() {}
1384 template <
typename TLoc,
typename T>
1385 class LocMatcher :
public WrapperMatcherInterface<TLoc> {
1388 : LocMatcher::WrapperMatcherInterface(InnerMatcher) {}
1390 bool matches(
const TLoc &Node, ASTMatchFinder *Finder,
1391 BoundNodesTreeBuilder *Builder)
const override {
1394 return this->
InnerMatcher.matches(extract(Node), Finder, Builder);
1398 static ast_type_traits::DynTypedNode
1399 extract(
const NestedNameSpecifierLoc &Loc) {
1408 class TypeLocTypeMatcher :
public WrapperMatcherInterface<TypeLoc> {
1410 explicit TypeLocTypeMatcher(
const Matcher<QualType> &
InnerMatcher)
1411 : TypeLocTypeMatcher::WrapperMatcherInterface(InnerMatcher) {}
1413 bool matches(
const TypeLoc &Node, ASTMatchFinder *Finder,
1414 BoundNodesTreeBuilder *Builder)
const override {
1425 template <
typename T>
1426 class TypeTraverseMatcher :
public WrapperMatcherInterface<T> {
1428 explicit TypeTraverseMatcher(
const Matcher<QualType> &
InnerMatcher,
1429 QualType (T::*TraverseFunction)()
const)
1430 : TypeTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
1431 TraverseFunction(TraverseFunction) {}
1433 bool matches(
const T &Node, ASTMatchFinder *Finder,
1434 BoundNodesTreeBuilder *Builder)
const override {
1435 QualType NextNode = (Node.*TraverseFunction)();
1436 if (NextNode.isNull())
1438 return this->InnerMatcher.matches(
1443 QualType (T::*TraverseFunction)()
const;
1449 template <
typename T>
1450 class TypeLocTraverseMatcher :
public WrapperMatcherInterface<T> {
1452 explicit TypeLocTraverseMatcher(
const Matcher<TypeLoc> &InnerMatcher,
1453 TypeLoc (T::*TraverseFunction)()
const)
1454 : TypeLocTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
1455 TraverseFunction(TraverseFunction) {}
1457 bool matches(
const T &Node, ASTMatchFinder *Finder,
1458 BoundNodesTreeBuilder *Builder)
const override {
1459 TypeLoc NextNode = (Node.*TraverseFunction)();
1462 return this->InnerMatcher.matches(
1467 TypeLoc (T::*TraverseFunction)()
const;
1476 template <
typename InnerTBase,
1477 template <
typename OuterT>
class Getter,
1478 template <
typename OuterT>
class MatcherImpl,
1479 typename ReturnTypesF>
1480 class TypeTraversePolymorphicMatcher {
1482 typedef TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
1489 explicit TypeTraversePolymorphicMatcher(
1493 template <
typename OuterT>
operator Matcher<OuterT>()
const {
1494 return Matcher<OuterT>(
1495 new MatcherImpl<OuterT>(
InnerMatcher, Getter<OuterT>::value()));
1498 struct Func :
public llvm::VariadicFunction<Self, Matcher<InnerTBase>,
1511 template <
typename Matcher, Matcher (*Func)()>
class MemoizedMatcher {
1513 Wrapper() : M(Func()) {}
1518 static const Matcher &getInstance() {
1519 static llvm::ManagedStatic<Wrapper> Instance;
1527 template <
typename InnerTBase,
template <
typename OuterT>
class Getter,
1528 template <
typename OuterT>
class MatcherImpl,
typename ReturnTypesF>
1529 TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF>
1530 TypeTraversePolymorphicMatcher<
1531 InnerTBase, Getter, MatcherImpl,
1538 inline ArrayRef<TemplateArgument>
1539 getTemplateSpecializationArgs(
const ClassTemplateSpecializationDecl &D) {
1540 return D.getTemplateArgs().asArray();
1543 inline ArrayRef<TemplateArgument>
1544 getTemplateSpecializationArgs(
const TemplateSpecializationType &T) {
1545 return llvm::makeArrayRef(T.getArgs(), T.getNumArgs());
1548 struct NotEqualsBoundNodePredicate {
1549 bool operator()(
const internal::BoundNodesMap &
Nodes)
const {
1550 return Nodes.getNode(ID) !=
Node;
1553 ast_type_traits::DynTypedNode
Node;
Defines the C++ template declaration subclasses.
const DynTypedMatcher *const Matcher
Defines the Objective-C statement AST node classes.
Defines the clang::Expr interface and subclasses for C++ expressions.
BoundNodesTreeBuilder Nodes
const ASTMatchFinder::BindKind Bind
std::vector< DynTypedMatcher > InnerMatchers
const IntrusiveRefCntPtr< DynMatcherInterface > InnerMatcher
ID
Defines the set of possible language-specific address spaces.
The result type of a method or function.
ASTMatchFinder *const Finder
bool operator<(DeclarationName LHS, DeclarationName RHS)
static DynTypedNode create(const T &Node)
Creates a DynTypedNode from Node.
BoundNodesTreeBuilder BoundNodes
ast_type_traits::DynTypedNode Node
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
BoundNodesTreeBuilder *const Builder
bool matches(const til::SExpr *E1, const til::SExpr *E2)