35 #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H 36 #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H 54 #include "llvm/ADT/APFloat.h" 55 #include "llvm/ADT/ArrayRef.h" 56 #include "llvm/ADT/IntrusiveRefCntPtr.h" 57 #include "llvm/ADT/None.h" 58 #include "llvm/ADT/Optional.h" 59 #include "llvm/ADT/STLExtras.h" 60 #include "llvm/ADT/SmallVector.h" 61 #include "llvm/ADT/StringRef.h" 62 #include "llvm/ADT/iterator.h" 63 #include "llvm/Support/Casting.h" 64 #include "llvm/Support/ManagedStatic.h" 72 #include <type_traits> 91 template <
typename ResultT,
typename ArgT,
92 ResultT (*Func)(ArrayRef<const ArgT *>)>
93 struct VariadicFunction {
94 ResultT operator()()
const {
return Func(None); }
96 template <
typename... ArgsT>
97 ResultT operator()(
const ArgT &Arg1,
const ArgsT &... Args)
const {
98 return Execute(Arg1, static_cast<const ArgT &>(Args)...);
103 ResultT operator()(ArrayRef<ArgT> Args)
const {
104 SmallVector<const ArgT*, 8> InnerArgs;
105 for (
const ArgT &Arg : Args)
106 InnerArgs.push_back(&Arg);
107 return Func(InnerArgs);
113 template <
typename... ArgsT> ResultT Execute(
const ArgsT &... Args)
const {
114 const ArgT *
const ArgsArray[] = {&Args...};
115 return Func(ArrayRef<const ArgT *>(ArgsArray,
sizeof...(ArgsT)));
124 return Node.getType();
127 return Node.getUnderlyingType();
130 if (
const TypeSourceInfo *TSI = Node.getFriendType())
131 return TSI->getType();
137 inline const FunctionProtoType *
138 getFunctionProtoType(
const FunctionProtoType &Node) {
142 inline const FunctionProtoType *getFunctionProtoType(
const FunctionDecl &Node) {
143 return Node.getType()->getAs<FunctionProtoType>();
147 class BoundNodesMap {
153 NodeMap[
ID] = DynNode;
160 template <
typename T>
161 const T *getNodeAs(StringRef
ID)
const {
162 IDToNodeMap::const_iterator It = NodeMap.find(ID);
163 if (It == NodeMap.end()) {
166 return It->second.get<T>();
170 IDToNodeMap::const_iterator It = NodeMap.find(ID);
171 if (It == NodeMap.end()) {
178 bool operator<(
const BoundNodesMap &Other)
const {
179 return NodeMap < Other.NodeMap;
187 using IDToNodeMap = std::map<std::string, ast_type_traits::DynTypedNode>;
189 const IDToNodeMap &getMap()
const {
195 bool isComparable()
const {
196 for (
const auto &IDAndNode : NodeMap) {
197 if (!IDAndNode.second.getMemoizationData())
211 class BoundNodesTreeBuilder {
217 virtual ~Visitor() =
default;
222 virtual void visitMatch(
const BoundNodes& BoundNodesView) = 0;
227 if (Bindings.empty())
228 Bindings.emplace_back();
229 for (BoundNodesMap &Binding : Bindings)
230 Binding.addNode(Id, DynNode);
234 void addMatch(
const BoundNodesTreeBuilder &Bindings);
239 void visitMatches(Visitor* ResultVisitor);
241 template <
typename ExcludePredicate>
242 bool removeBindings(
const ExcludePredicate &Predicate) {
243 Bindings.erase(std::remove_if(Bindings.begin(), Bindings.end(), Predicate),
245 return !Bindings.empty();
249 bool operator<(
const BoundNodesTreeBuilder &Other)
const {
250 return Bindings < Other.Bindings;
255 bool isComparable()
const {
256 for (
const BoundNodesMap &NodesMap : Bindings) {
257 if (!NodesMap.isComparable())
264 SmallVector<BoundNodesMap, 16> Bindings;
267 class ASTMatchFinder;
274 class DynMatcherInterface
275 :
public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> {
277 virtual ~DynMatcherInterface() =
default;
284 ASTMatchFinder *Finder,
285 BoundNodesTreeBuilder *Builder)
const = 0;
295 template <
typename T>
296 class MatcherInterface :
public DynMatcherInterface {
302 virtual bool matches(
const T &Node,
303 ASTMatchFinder *Finder,
304 BoundNodesTreeBuilder *Builder)
const = 0;
307 ASTMatchFinder *Finder,
308 BoundNodesTreeBuilder *Builder)
const override {
309 return matches(DynNode.getUnchecked<T>(), Finder, Builder);
315 template <
typename T>
316 class SingleNodeMatcherInterface :
public MatcherInterface<T> {
321 virtual bool matchesNode(
const T &Node)
const = 0;
327 BoundNodesTreeBuilder * )
const override {
328 return matchesNode(Node);
332 template <
typename>
class Matcher;
341 class DynTypedMatcher {
344 template <
typename T>
345 DynTypedMatcher(MatcherInterface<T> *Implementation)
346 : SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
347 RestrictKind(SupportedKind), Implementation(Implementation) {}
350 enum VariadicOperator {
369 static DynTypedMatcher
370 constructVariadic(VariadicOperator Op,
371 ast_type_traits::ASTNodeKind SupportedKind,
372 std::vector<DynTypedMatcher> InnerMatchers);
377 static DynTypedMatcher trueMatcher(ast_type_traits::ASTNodeKind NodeKind);
379 void setAllowBind(
bool AB) { AllowBind = AB; }
384 bool canMatchNodesOfKind(ast_type_traits::ASTNodeKind
Kind)
const;
388 DynTypedMatcher dynCastTo(
const ast_type_traits::ASTNodeKind
Kind)
const;
392 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder)
const;
399 ASTMatchFinder *Finder,
400 BoundNodesTreeBuilder *Builder)
const;
414 using MatcherIDType = std::pair<ast_type_traits::ASTNodeKind, uint64_t>;
415 MatcherIDType getID()
const {
418 return std::make_pair(RestrictKind,
419 reinterpret_cast<uint64_t>(Implementation.get()));
426 ast_type_traits::ASTNodeKind getSupportedKind()
const {
427 return SupportedKind;
435 template <
typename T>
bool canConvertTo()
const {
436 return canConvertTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
438 bool canConvertTo(ast_type_traits::ASTNodeKind To)
const;
445 template <
typename T> Matcher<T> convertTo()
const {
446 assert(canConvertTo<T>());
447 return unconditionalConvertTo<T>();
454 template <
typename T> Matcher<T> unconditionalConvertTo()
const;
457 DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind,
458 ast_type_traits::ASTNodeKind RestrictKind,
459 IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
460 : SupportedKind(SupportedKind), RestrictKind(RestrictKind),
461 Implementation(
std::move(Implementation)) {}
463 bool AllowBind =
false;
464 ast_type_traits::ASTNodeKind SupportedKind;
470 ast_type_traits::ASTNodeKind RestrictKind;
471 IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
478 template <
typename T>
479 class WrapperMatcherInterface :
public MatcherInterface<T> {
481 explicit WrapperMatcherInterface(DynTypedMatcher &&InnerMatcher)
482 : InnerMatcher(
std::move(InnerMatcher)) {}
484 const DynTypedMatcher InnerMatcher;
495 template <
typename T>
499 explicit Matcher(MatcherInterface<T> *Implementation)
500 : Implementation(Implementation) {}
505 template <
typename From>
506 Matcher(
const Matcher<From> &Other,
507 typename std::enable_if<std::is_base_of<From, T>::value &&
508 !std::is_same<From, T>::value>::
type * =
nullptr)
509 : Implementation(restrictMatcher(Other.Implementation)) {
510 assert(Implementation.getSupportedKind().isSame(
511 ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
517 template <
typename TypeT>
518 Matcher(
const Matcher<TypeT> &Other,
519 typename std::enable_if<
520 std::is_same<T, QualType>::value &&
521 std::is_same<TypeT, Type>::value>::
type* =
nullptr)
522 : Implementation(new TypeToQualType<TypeT>(Other)) {}
527 template <
typename To>
528 Matcher<To> dynCastTo()
const {
529 static_assert(std::is_base_of<To, T>::value,
"Invalid dynCast call.");
530 return Matcher<To>(Implementation);
535 ASTMatchFinder *Finder,
536 BoundNodesTreeBuilder *Builder)
const {
542 DynTypedMatcher::MatcherIDType getID()
const {
543 return Implementation.getID();
550 operator DynTypedMatcher()
const {
return Implementation; }
558 template <
typename TypeT>
559 class TypeToQualType :
public WrapperMatcherInterface<QualType> {
561 TypeToQualType(
const Matcher<TypeT> &InnerMatcher)
562 : TypeToQualType::WrapperMatcherInterface(InnerMatcher) {}
564 bool matches(
const QualType &Node, ASTMatchFinder *Finder,
565 BoundNodesTreeBuilder *Builder)
const override {
568 return this->InnerMatcher.matches(
575 template <
typename U>
friend class Matcher;
578 friend class DynTypedMatcher;
580 static DynTypedMatcher restrictMatcher(
const DynTypedMatcher &Other) {
581 return Other.dynCastTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
584 explicit Matcher(
const DynTypedMatcher &Implementation)
585 : Implementation(restrictMatcher(Implementation)) {
586 assert(this->Implementation.getSupportedKind()
587 .isSame(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
590 DynTypedMatcher Implementation;
595 template <
typename T>
596 inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
597 return Matcher<T>(Implementation);
605 inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>()
const {
606 assert(canConvertTo<QualType>());
607 const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
608 if (SourceKind.isSame(
609 ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) {
611 return unconditionalConvertTo<Type>();
613 return unconditionalConvertTo<QualType>();
617 template <
typename MatcherT,
typename IteratorT>
618 bool matchesFirstInRange(
const MatcherT &Matcher, IteratorT Start,
619 IteratorT
End, ASTMatchFinder *Finder,
620 BoundNodesTreeBuilder *Builder) {
621 for (IteratorT I = Start; I !=
End; ++I) {
622 BoundNodesTreeBuilder Result(*Builder);
623 if (Matcher.matches(*I, Finder, &Result)) {
624 *Builder = std::move(Result);
633 template <
typename MatcherT,
typename IteratorT>
634 bool matchesFirstInPointerRange(
const MatcherT &Matcher, IteratorT Start,
635 IteratorT End, ASTMatchFinder *Finder,
636 BoundNodesTreeBuilder *Builder) {
637 for (IteratorT I = Start; I !=
End; ++I) {
638 BoundNodesTreeBuilder Result(*Builder);
639 if (Matcher.matches(**I, Finder, &Result)) {
640 *Builder = std::move(Result);
648 template <
typename Ty>
653 template <
typename Inner>
654 static yes& test(Inner *I, decltype(I->getDecl()) * =
nullptr);
657 static no& test(...);
660 static const bool value =
sizeof(test<Ty>(
nullptr)) ==
sizeof(yes);
667 template <
typename T,
typename ArgT>
668 class HasOverloadedOperatorNameMatcher :
public SingleNodeMatcherInterface<T> {
669 static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
670 std::is_base_of<FunctionDecl, T>::value,
671 "unsupported class for matcher");
672 static_assert(std::is_same<ArgT, StringRef>::value,
673 "argument type must be StringRef");
676 explicit HasOverloadedOperatorNameMatcher(
const StringRef Name)
677 : SingleNodeMatcherInterface<T>(), Name(Name) {}
679 bool matchesNode(
const T &Node)
const override {
680 return matchesSpecialized(Node);
688 bool matchesSpecialized(
const CXXOperatorCallExpr &Node)
const {
694 bool matchesSpecialized(
const FunctionDecl &Node)
const {
695 return Node.isOverloadedOperator() &&
705 class HasNameMatcher :
public SingleNodeMatcherInterface<NamedDecl> {
707 explicit HasNameMatcher(std::vector<std::string> Names);
709 bool matchesNode(
const NamedDecl &Node)
const override;
716 bool matchesNodeUnqualified(
const NamedDecl &Node)
const;
724 bool matchesNodeFullFast(
const NamedDecl &Node)
const;
731 bool matchesNodeFullSlow(
const NamedDecl &Node)
const;
733 const bool UseUnqualifiedMatch;
734 const std::vector<std::string> Names;
739 Matcher<NamedDecl>
hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs);
744 ArrayRef<const StringRef *> NameRefs);
750 template <
typename T,
typename DeclMatcherT>
751 class HasDeclarationMatcher :
public WrapperMatcherInterface<T> {
752 static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
753 "instantiated with wrong types");
756 explicit HasDeclarationMatcher(
const Matcher<Decl> &InnerMatcher)
757 : HasDeclarationMatcher::WrapperMatcherInterface(InnerMatcher) {}
759 bool matches(
const T &Node, ASTMatchFinder *Finder,
760 BoundNodesTreeBuilder *Builder)
const override {
761 return matchesSpecialized(Node, Finder, Builder);
766 bool matchesSpecialized(
const QualType &Node, ASTMatchFinder *Finder,
767 BoundNodesTreeBuilder *Builder)
const {
771 return matchesSpecialized(*Node, Finder, Builder);
776 bool matchesSpecialized(
const Type &Node, ASTMatchFinder *Finder,
777 BoundNodesTreeBuilder *Builder)
const {
781 if (
const auto *S = dyn_cast<DeducedType>(&Node)) {
782 EffectiveType = S->getDeducedType().getTypePtrOrNull();
789 if (
const auto *S = dyn_cast<TagType>(EffectiveType)) {
790 return matchesDecl(S->getDecl(), Finder, Builder);
792 if (
const auto *S = dyn_cast<InjectedClassNameType>(EffectiveType)) {
793 return matchesDecl(S->getDecl(), Finder, Builder);
795 if (
const auto *S = dyn_cast<TemplateTypeParmType>(EffectiveType)) {
796 return matchesDecl(S->getDecl(), Finder, Builder);
798 if (
const auto *S = dyn_cast<TypedefType>(EffectiveType)) {
799 return matchesDecl(S->getDecl(), Finder, Builder);
801 if (
const auto *S = dyn_cast<UnresolvedUsingType>(EffectiveType)) {
802 return matchesDecl(S->getDecl(), Finder, Builder);
804 if (
const auto *S = dyn_cast<ObjCObjectType>(EffectiveType)) {
805 return matchesDecl(S->getInterface(), Finder, Builder);
816 if (
const auto *S = dyn_cast<SubstTemplateTypeParmType>(EffectiveType)) {
817 return matchesSpecialized(S->getReplacementType(), Finder, Builder);
823 if (
const auto *S = dyn_cast<TemplateSpecializationType>(EffectiveType)) {
824 if (!S->isTypeAlias() && S->isSugared()) {
831 return matchesSpecialized(*S->desugar(), Finder, Builder);
835 return matchesDecl(S->getTemplateName().getAsTemplateDecl(), Finder,
842 if (
const auto *S = dyn_cast<ElaboratedType>(EffectiveType)) {
843 return matchesSpecialized(S->desugar(), Finder, Builder);
850 bool matchesSpecialized(
const DeclRefExpr &Node, ASTMatchFinder *Finder,
851 BoundNodesTreeBuilder *Builder)
const {
852 return matchesDecl(Node.getDecl(), Finder, Builder);
857 bool matchesSpecialized(
const CallExpr &Node, ASTMatchFinder *Finder,
858 BoundNodesTreeBuilder *Builder)
const {
859 return matchesDecl(Node.getCalleeDecl(), Finder, Builder);
864 bool matchesSpecialized(
const CXXConstructExpr &Node,
865 ASTMatchFinder *Finder,
866 BoundNodesTreeBuilder *Builder)
const {
867 return matchesDecl(Node.getConstructor(), Finder, Builder);
870 bool matchesSpecialized(
const ObjCIvarRefExpr &Node,
871 ASTMatchFinder *Finder,
872 BoundNodesTreeBuilder *Builder)
const {
873 return matchesDecl(Node.getDecl(), Finder, Builder);
878 bool matchesSpecialized(
const CXXNewExpr &Node,
879 ASTMatchFinder *Finder,
880 BoundNodesTreeBuilder *Builder)
const {
881 return matchesDecl(Node.getOperatorNew(), Finder, Builder);
886 bool matchesSpecialized(
const MemberExpr &Node,
887 ASTMatchFinder *Finder,
888 BoundNodesTreeBuilder *Builder)
const {
889 return matchesDecl(Node.getMemberDecl(), Finder, Builder);
894 bool matchesSpecialized(
const AddrLabelExpr &Node,
895 ASTMatchFinder *Finder,
896 BoundNodesTreeBuilder *Builder)
const {
897 return matchesDecl(Node.getLabel(), Finder, Builder);
902 bool matchesSpecialized(
const LabelStmt &Node, ASTMatchFinder *Finder,
903 BoundNodesTreeBuilder *Builder)
const {
904 return matchesDecl(Node.getDecl(), Finder, Builder);
909 bool matchesDecl(
const Decl *Node, ASTMatchFinder *Finder,
910 BoundNodesTreeBuilder *Builder)
const {
911 return Node !=
nullptr &&
912 this->InnerMatcher.matches(
919 template <
typename T>
921 static const bool value =
922 std::is_same<T, Decl>::value ||
923 std::is_same<T, Stmt>::value ||
924 std::is_same<T, QualType>::value ||
925 std::is_same<T, Type>::value ||
926 std::is_same<T, TypeLoc>::value ||
927 std::is_same<T, NestedNameSpecifier>::value ||
928 std::is_same<T, NestedNameSpecifierLoc>::value ||
929 std::is_same<T, CXXCtorInitializer>::value;
931 template <
typename T>
932 const bool IsBaseType<T>::value;
952 class ASTMatchFinder {
961 TK_IgnoreImplicitCastsAndParentheses
974 enum AncestorMatchMode {
982 virtual ~ASTMatchFinder() =
default;
988 virtual bool classIsDerivedFrom(
const CXXRecordDecl *Declaration,
989 const Matcher<NamedDecl> &
Base,
990 BoundNodesTreeBuilder *Builder) = 0;
992 template <
typename T>
993 bool matchesChildOf(
const T &Node,
994 const DynTypedMatcher &Matcher,
995 BoundNodesTreeBuilder *Builder,
996 TraversalKind Traverse,
998 static_assert(std::is_base_of<Decl, T>::value ||
999 std::is_base_of<Stmt, T>::value ||
1000 std::is_base_of<NestedNameSpecifier, T>::value ||
1001 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
1002 std::is_base_of<TypeLoc, T>::value ||
1003 std::is_base_of<QualType, T>::value,
1004 "unsupported type for recursive matching");
1006 Matcher, Builder, Traverse, Bind);
1009 template <
typename T>
1010 bool matchesDescendantOf(
const T &Node,
1011 const DynTypedMatcher &Matcher,
1012 BoundNodesTreeBuilder *Builder,
1014 static_assert(std::is_base_of<Decl, T>::value ||
1015 std::is_base_of<Stmt, T>::value ||
1016 std::is_base_of<NestedNameSpecifier, T>::value ||
1017 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
1018 std::is_base_of<TypeLoc, T>::value ||
1019 std::is_base_of<QualType, T>::value,
1020 "unsupported type for recursive matching");
1022 Matcher, Builder, Bind);
1026 template <
typename T>
1027 bool matchesAncestorOf(
const T &Node,
1028 const DynTypedMatcher &Matcher,
1029 BoundNodesTreeBuilder *Builder,
1030 AncestorMatchMode MatchMode) {
1031 static_assert(std::is_base_of<Decl, T>::value ||
1032 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
1033 std::is_base_of<Stmt, T>::value ||
1034 std::is_base_of<TypeLoc, T>::value,
1035 "type not allowed for recursive matching");
1037 Matcher, Builder, MatchMode);
1040 virtual ASTContext &getASTContext()
const = 0;
1044 const DynTypedMatcher &Matcher,
1045 BoundNodesTreeBuilder *Builder,
1046 TraversalKind Traverse,
1050 const DynTypedMatcher &Matcher,
1051 BoundNodesTreeBuilder *Builder,
1055 const DynTypedMatcher &Matcher,
1056 BoundNodesTreeBuilder *Builder,
1057 AncestorMatchMode MatchMode) = 0;
1064 template <
typename... Ts>
struct TypeList {};
1066 template <
typename T1,
typename... Ts>
struct TypeList<T1, Ts...> {
1074 using tail = TypeList<Ts...>;
1078 using EmptyTypeList = TypeList<>;
1082 template <
typename AnyTypeList,
typename T>
1083 struct TypeListContainsSuperOf {
1084 static const bool value =
1085 std::is_base_of<typename AnyTypeList::head, T>::value ||
1086 TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
1088 template <
typename T>
1089 struct TypeListContainsSuperOf<EmptyTypeList, T> {
1090 static const bool value =
false;
1096 using AllNodeBaseTypes =
1097 TypeList<
Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
1098 Type, TypeLoc, CXXCtorInitializer>;
1104 template <
class T>
struct ExtractFunctionArgMeta;
1105 template <
class T>
struct ExtractFunctionArgMeta<void(T)> {
1110 using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
1111 using AdaptativeDefaultToTypes =
1112 TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
1116 using HasDeclarationSupportedTypes =
1117 TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
1118 ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
1119 MemberExpr, QualType, RecordType, TagType,
1120 TemplateSpecializationType, TemplateTypeParmType, TypedefType,
1121 UnresolvedUsingType, ObjCIvarRefExpr>;
1136 template <
template <
typename ToArg,
typename FromArg>
class ArgumentAdapterT,
1137 typename FromTypes = AdaptativeDefaultFromTypes,
1138 typename ToTypes = AdaptativeDefaultToTypes>
1139 struct ArgumentAdaptingMatcherFunc {
1140 template <
typename T>
class Adaptor {
1142 explicit Adaptor(
const Matcher<T> &InnerMatcher)
1143 : InnerMatcher(InnerMatcher) {}
1145 using ReturnTypes = ToTypes;
1147 template <
typename To>
operator Matcher<To>()
const {
1148 return Matcher<To>(
new ArgumentAdapterT<To, T>(InnerMatcher));
1152 const Matcher<T> InnerMatcher;
1155 template <
typename T>
1156 static Adaptor<T>
create(
const Matcher<T> &InnerMatcher) {
1157 return Adaptor<T>(InnerMatcher);
1160 template <
typename T>
1161 Adaptor<T> operator()(
const Matcher<T> &InnerMatcher)
const {
1162 return create(InnerMatcher);
1178 template <
template <
typename T>
class MatcherT,
1179 typename ReturnTypesF = void(AllNodeBaseTypes)>
1180 class PolymorphicMatcherWithParam0 {
1184 template <
typename T>
1185 operator Matcher<T>()
const {
1186 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1187 "right polymorphic conversion");
1188 return Matcher<T>(
new MatcherT<T>());
1192 template <
template <
typename T,
typename P1>
class MatcherT,
1194 typename ReturnTypesF = void(AllNodeBaseTypes)>
1195 class PolymorphicMatcherWithParam1 {
1197 explicit PolymorphicMatcherWithParam1(
const P1 &Param1)
1202 template <
typename T>
1203 operator Matcher<T>()
const {
1204 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1205 "right polymorphic conversion");
1206 return Matcher<T>(
new MatcherT<T, P1>(Param1));
1213 template <
template <
typename T,
typename P1,
typename P2>
class MatcherT,
1214 typename P1,
typename P2,
1215 typename ReturnTypesF = void(AllNodeBaseTypes)>
1216 class PolymorphicMatcherWithParam2 {
1218 PolymorphicMatcherWithParam2(
const P1 &Param1,
const P2 &Param2)
1219 : Param1(Param1), Param2(Param2) {}
1223 template <
typename T>
1224 operator Matcher<T>()
const {
1225 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1226 "right polymorphic conversion");
1227 return Matcher<T>(
new MatcherT<T, P1, P2>(Param1, Param2));
1241 using ReturnTypes = AllNodeBaseTypes;
1243 template <
typename T>
1244 operator Matcher<T>()
const {
1245 return DynTypedMatcher::trueMatcher(
1246 ast_type_traits::ASTNodeKind::getFromNodeKind<T>())
1247 .template unconditionalConvertTo<T>();
1255 template <
typename T>
1256 class BindableMatcher :
public Matcher<T> {
1258 explicit BindableMatcher(
const Matcher<T> &M) : Matcher<T>(M) {}
1259 explicit BindableMatcher(MatcherInterface<T> *Implementation)
1260 : Matcher<T>(Implementation) {}
1266 Matcher<T> bind(StringRef ID)
const {
1267 return DynTypedMatcher(*
this)
1269 ->template unconditionalConvertTo<T>();
1274 operator DynTypedMatcher()
const {
1275 DynTypedMatcher Result =
static_cast<const Matcher<T>&
>(*this);
1276 Result.setAllowBind(
true);
1285 template <
typename T,
typename ChildT>
1286 class HasMatcher :
public WrapperMatcherInterface<T> {
1288 explicit HasMatcher(
const Matcher<ChildT> &ChildMatcher)
1289 : HasMatcher::WrapperMatcherInterface(ChildMatcher) {}
1291 bool matches(
const T &Node, ASTMatchFinder *Finder,
1292 BoundNodesTreeBuilder *Builder)
const override {
1293 return Finder->matchesChildOf(Node, this->InnerMatcher, Builder,
1294 ASTMatchFinder::TK_AsIs,
1295 ASTMatchFinder::BK_First);
1304 template <
typename T,
typename ChildT>
1305 class ForEachMatcher :
public WrapperMatcherInterface<T> {
1306 static_assert(IsBaseType<ChildT>::value,
1307 "for each only accepts base type matcher");
1310 explicit ForEachMatcher(
const Matcher<ChildT> &ChildMatcher)
1311 : ForEachMatcher::WrapperMatcherInterface(ChildMatcher) {}
1313 bool matches(
const T& Node, ASTMatchFinder* Finder,
1314 BoundNodesTreeBuilder* Builder)
const override {
1315 return Finder->matchesChildOf(
1316 Node, this->InnerMatcher, Builder,
1317 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
1318 ASTMatchFinder::BK_All);
1331 template <
typename... Ps>
class VariadicOperatorMatcher {
1333 VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
1334 : Op(Op), Params(
std::forward<Ps>(Params)...) {}
1336 template <
typename T>
operator Matcher<T>()
const {
1337 return DynTypedMatcher::constructVariadic(
1338 Op, ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
1339 getMatchers<T>(llvm::index_sequence_for<Ps...>()))
1340 .template unconditionalConvertTo<T>();
1346 std::vector<DynTypedMatcher> getMatchers(llvm::index_sequence<Is...>)
const {
1347 return {Matcher<T>(std::get<Is>(Params))...};
1350 const DynTypedMatcher::VariadicOperator Op;
1351 std::tuple<Ps...> Params;
1356 template <
unsigned MinCount,
unsigned MaxCount>
1357 struct VariadicOperatorMatcherFunc {
1358 DynTypedMatcher::VariadicOperator Op;
1360 template <
typename... Ms>
1361 VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps)
const {
1362 static_assert(MinCount <=
sizeof...(Ms) &&
sizeof...(Ms) <= MaxCount,
1363 "invalid number of parameters for variadic matcher");
1364 return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...);
1370 template <
typename T>
1371 inline Matcher<T> DynTypedMatcher::unconditionalConvertTo()
const {
1372 return Matcher<T>(*this);
1376 template<
typename T>
1377 BindableMatcher<T> makeAllOfComposite(
1378 ArrayRef<
const Matcher<T> *> InnerMatchers) {
1380 if (InnerMatchers.empty()) {
1381 return BindableMatcher<T>(TrueMatcher());
1385 if (InnerMatchers.size() == 1) {
1386 return BindableMatcher<T>(*InnerMatchers[0]);
1389 using PI = llvm::pointee_iterator<const Matcher<T> *
const *>;
1391 std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
1392 PI(InnerMatchers.end()));
1393 return BindableMatcher<T>(
1394 DynTypedMatcher::constructVariadic(
1395 DynTypedMatcher::VO_AllOf,
1396 ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
1397 std::move(DynMatchers))
1398 .template unconditionalConvertTo<T>());
1407 template<
typename T,
typename InnerT>
1408 BindableMatcher<T> makeDynCastAllOfComposite(
1409 ArrayRef<
const Matcher<InnerT> *> InnerMatchers) {
1410 return BindableMatcher<T>(
1411 makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
1418 template <
typename T,
typename DescendantT>
1419 class HasDescendantMatcher :
public WrapperMatcherInterface<T> {
1420 static_assert(IsBaseType<DescendantT>::value,
1421 "has descendant only accepts base type matcher");
1424 explicit HasDescendantMatcher(
const Matcher<DescendantT> &DescendantMatcher)
1425 : HasDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
1427 bool matches(
const T &Node, ASTMatchFinder *Finder,
1428 BoundNodesTreeBuilder *Builder)
const override {
1429 return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder,
1430 ASTMatchFinder::BK_First);
1438 template <
typename T,
typename ParentT>
1439 class HasParentMatcher :
public WrapperMatcherInterface<T> {
1440 static_assert(IsBaseType<ParentT>::value,
1441 "has parent only accepts base type matcher");
1444 explicit HasParentMatcher(
const Matcher<ParentT> &ParentMatcher)
1445 : HasParentMatcher::WrapperMatcherInterface(ParentMatcher) {}
1447 bool matches(
const T &Node, ASTMatchFinder *Finder,
1448 BoundNodesTreeBuilder *Builder)
const override {
1449 return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder,
1450 ASTMatchFinder::AMM_ParentOnly);
1458 template <
typename T,
typename AncestorT>
1459 class HasAncestorMatcher :
public WrapperMatcherInterface<T> {
1460 static_assert(IsBaseType<AncestorT>::value,
1461 "has ancestor only accepts base type matcher");
1464 explicit HasAncestorMatcher(
const Matcher<AncestorT> &AncestorMatcher)
1465 : HasAncestorMatcher::WrapperMatcherInterface(AncestorMatcher) {}
1467 bool matches(
const T &Node, ASTMatchFinder *Finder,
1468 BoundNodesTreeBuilder *Builder)
const override {
1469 return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder,
1470 ASTMatchFinder::AMM_All);
1480 template <
typename T,
typename DescendantT>
1481 class ForEachDescendantMatcher :
public WrapperMatcherInterface<T> {
1482 static_assert(IsBaseType<DescendantT>::value,
1483 "for each descendant only accepts base type matcher");
1486 explicit ForEachDescendantMatcher(
1487 const Matcher<DescendantT> &DescendantMatcher)
1488 : ForEachDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
1490 bool matches(
const T &Node, ASTMatchFinder *Finder,
1491 BoundNodesTreeBuilder *Builder)
const override {
1492 return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder,
1493 ASTMatchFinder::BK_All);
1499 template <
typename T,
typename ValueT>
1500 class ValueEqualsMatcher :
public SingleNodeMatcherInterface<T> {
1501 static_assert(std::is_base_of<CharacterLiteral, T>::value ||
1502 std::is_base_of<CXXBoolLiteralExpr, T>::value ||
1503 std::is_base_of<FloatingLiteral, T>::value ||
1504 std::is_base_of<IntegerLiteral, T>::value,
1505 "the node must have a getValue method");
1508 explicit ValueEqualsMatcher(
const ValueT &ExpectedValue)
1509 : ExpectedValue(ExpectedValue) {}
1511 bool matchesNode(
const T &Node)
const override {
1512 return Node.getValue() == ExpectedValue;
1516 const ValueT ExpectedValue;
1522 inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
1523 const FloatingLiteral &Node)
const {
1524 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1525 return Node.getValue().convertToFloat() == ExpectedValue;
1526 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1527 return Node.getValue().convertToDouble() == ExpectedValue;
1531 inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
1532 const FloatingLiteral &Node)
const {
1533 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1534 return Node.getValue().convertToFloat() == ExpectedValue;
1535 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1536 return Node.getValue().convertToDouble() == ExpectedValue;
1540 inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
1541 const FloatingLiteral &Node)
const {
1542 return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
1557 template <
typename SourceT,
typename TargetT>
1558 class VariadicDynCastAllOfMatcher
1559 :
public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>,
1560 makeDynCastAllOfComposite<SourceT, TargetT>> {
1562 VariadicDynCastAllOfMatcher() {}
1575 template <
typename T>
1576 class VariadicAllOfMatcher
1577 :
public VariadicFunction<BindableMatcher<T>, Matcher<T>,
1578 makeAllOfComposite<T>> {
1580 VariadicAllOfMatcher() {}
1585 template <
typename TLoc,
typename T>
1586 class LocMatcher :
public WrapperMatcherInterface<TLoc> {
1588 explicit LocMatcher(
const Matcher<T> &InnerMatcher)
1589 : LocMatcher::WrapperMatcherInterface(InnerMatcher) {}
1591 bool matches(
const TLoc &Node, ASTMatchFinder *Finder,
1592 BoundNodesTreeBuilder *Builder)
const override {
1595 return this->InnerMatcher.matches(extract(Node), Finder, Builder);
1600 extract(
const NestedNameSpecifierLoc &Loc) {
1609 class TypeLocTypeMatcher :
public WrapperMatcherInterface<TypeLoc> {
1611 explicit TypeLocTypeMatcher(
const Matcher<QualType> &InnerMatcher)
1612 : TypeLocTypeMatcher::WrapperMatcherInterface(InnerMatcher) {}
1614 bool matches(
const TypeLoc &Node, ASTMatchFinder *Finder,
1615 BoundNodesTreeBuilder *Builder)
const override {
1618 return this->InnerMatcher.matches(
1626 template <
typename T>
1627 class TypeTraverseMatcher :
public WrapperMatcherInterface<T> {
1629 explicit TypeTraverseMatcher(
const Matcher<QualType> &InnerMatcher,
1630 QualType (T::*TraverseFunction)()
const)
1631 : TypeTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
1632 TraverseFunction(TraverseFunction) {}
1634 bool matches(
const T &Node, ASTMatchFinder *Finder,
1635 BoundNodesTreeBuilder *Builder)
const override {
1636 QualType NextNode = (Node.*TraverseFunction)();
1637 if (NextNode.isNull())
1639 return this->InnerMatcher.matches(
1644 QualType (T::*TraverseFunction)()
const;
1650 template <
typename T>
1651 class TypeLocTraverseMatcher :
public WrapperMatcherInterface<T> {
1653 explicit TypeLocTraverseMatcher(
const Matcher<TypeLoc> &InnerMatcher,
1654 TypeLoc (T::*TraverseFunction)()
const)
1655 : TypeLocTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
1656 TraverseFunction(TraverseFunction) {}
1658 bool matches(
const T &Node, ASTMatchFinder *Finder,
1659 BoundNodesTreeBuilder *Builder)
const override {
1660 TypeLoc NextNode = (Node.*TraverseFunction)();
1663 return this->InnerMatcher.matches(
1668 TypeLoc (T::*TraverseFunction)()
const;
1677 template <
typename InnerTBase,
1678 template <
typename OuterT>
class Getter,
1679 template <
typename OuterT>
class MatcherImpl,
1680 typename ReturnTypesF>
1681 class TypeTraversePolymorphicMatcher {
1683 using Self = TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
1686 static Self
create(ArrayRef<
const Matcher<InnerTBase> *> InnerMatchers);
1691 explicit TypeTraversePolymorphicMatcher(
1692 ArrayRef<
const Matcher<InnerTBase> *> InnerMatchers)
1693 : InnerMatcher(makeAllOfComposite(InnerMatchers)) {}
1695 template <
typename OuterT>
operator Matcher<OuterT>()
const {
1696 return Matcher<OuterT>(
1697 new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value()));
1701 :
public VariadicFunction<Self, Matcher<InnerTBase>, &Self::create> {
1706 const Matcher<InnerTBase> InnerMatcher;
1713 template <
typename Matcher, Matcher (*Func)()>
class MemoizedMatcher {
1715 Wrapper() : M(Func()) {}
1721 static const Matcher &getInstance() {
1722 static llvm::ManagedStatic<Wrapper> Instance;
1730 template <
typename InnerTBase,
template <
typename OuterT>
class Getter,
1731 template <
typename OuterT>
class MatcherImpl,
typename ReturnTypesF>
1732 TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF>
1733 TypeTraversePolymorphicMatcher<
1734 InnerTBase, Getter, MatcherImpl,
1735 ReturnTypesF>
::create(ArrayRef<
const Matcher<InnerTBase> *> InnerMatchers) {
1736 return Self(InnerMatchers);
1741 inline ArrayRef<TemplateArgument>
1742 getTemplateSpecializationArgs(
const ClassTemplateSpecializationDecl &D) {
1743 return D.getTemplateArgs().asArray();
1746 inline ArrayRef<TemplateArgument>
1747 getTemplateSpecializationArgs(
const TemplateSpecializationType &T) {
1748 return llvm::makeArrayRef(T.getArgs(), T.getNumArgs());
1751 inline ArrayRef<TemplateArgument>
1752 getTemplateSpecializationArgs(
const FunctionDecl &FD) {
1753 if (
const auto* TemplateArgs = FD.getTemplateSpecializationArgs())
1754 return TemplateArgs->asArray();
1755 return ArrayRef<TemplateArgument>();
1758 struct NotEqualsBoundNodePredicate {
1759 bool operator()(
const internal::BoundNodesMap &
Nodes)
const {
1760 return Nodes.getNode(ID) !=
Node;
1767 template <
typename Ty>
1768 struct GetBodyMatcher {
1769 static const Stmt *
get(
const Ty &
Node) {
1770 return Node.getBody();
1775 inline const Stmt *GetBodyMatcher<FunctionDecl>::get(
const FunctionDecl &Node) {
1776 return Node.doesThisDeclarationHaveABody() ? Node.getBody() :
nullptr;
1779 template <
typename Ty>
1780 struct HasSizeMatcher {
1781 static bool hasSize(
const Ty &Node,
unsigned int N) {
1782 return Node.getSize() == N;
1787 inline bool HasSizeMatcher<StringLiteral>::hasSize(
1788 const StringLiteral &Node,
unsigned int N) {
1789 return Node.getLength() == N;
1792 template <
typename Ty>
1793 struct GetSourceExpressionMatcher {
1794 static const Expr *
get(
const Ty &
Node) {
1795 return Node.getSubExpr();
1800 inline const Expr *GetSourceExpressionMatcher<OpaqueValueExpr>::get(
1801 const OpaqueValueExpr &Node) {
1802 return Node.getSourceExpr();
1805 template <
typename Ty>
1806 struct CompoundStmtMatcher {
1807 static const CompoundStmt *
get(
const Ty &
Node) {
1813 inline const CompoundStmt *
1814 CompoundStmtMatcher<StmtExpr>::get(
const StmtExpr &Node) {
1815 return Node.getSubStmt();
1824 #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
C Language Family Type Representation.
Defines the C++ template declaration subclasses.
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
Matcher< NamedDecl > hasAnyNameFunc(ArrayRef< const StringRef *> NameRefs)
Defines the clang::Expr interface and subclasses for C++ expressions.
BoundNodesTreeBuilder Nodes
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
Defines an enumeration for C++ overloaded operators.
Defines the clang::TypeLoc interface and its subclasses.
static QualType getUnderlyingType(const SubRegion *R)
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
static DynTypedNode create(const T &Node)
Creates a DynTypedNode from Node.
BoundNodesTreeBuilder BoundNodes
ast_type_traits::DynTypedNode DynTypedNode
ast_type_traits::DynTypedNode Node
Dataflow Directional Tag Classes.
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).
bool matches(const til::SExpr *E1, const til::SExpr *E2)
Matcher< ObjCMessageExpr > hasAnySelectorFunc(ArrayRef< const StringRef *> NameRefs)