35 #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H 36 #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H 51 #include "llvm/ADT/APFloat.h" 52 #include "llvm/ADT/ArrayRef.h" 53 #include "llvm/ADT/IntrusiveRefCntPtr.h" 54 #include "llvm/ADT/None.h" 55 #include "llvm/ADT/Optional.h" 56 #include "llvm/ADT/STLExtras.h" 57 #include "llvm/ADT/SmallVector.h" 58 #include "llvm/ADT/StringRef.h" 59 #include "llvm/ADT/iterator.h" 60 #include "llvm/Support/Casting.h" 61 #include "llvm/Support/ManagedStatic.h" 69 #include <type_traits> 88 template <
typename ResultT,
typename ArgT,
89 ResultT (*Func)(ArrayRef<const ArgT *>)>
90 struct VariadicFunction {
91 ResultT operator()()
const {
return Func(None); }
93 template <
typename... ArgsT>
94 ResultT operator()(
const ArgT &Arg1,
const ArgsT &... Args)
const {
95 return Execute(Arg1, static_cast<const ArgT &>(Args)...);
100 ResultT operator()(ArrayRef<ArgT> Args)
const {
101 SmallVector<const ArgT*, 8> InnerArgs;
102 for (
const ArgT &Arg : Args)
103 InnerArgs.push_back(&Arg);
104 return Func(InnerArgs);
110 template <
typename... ArgsT> ResultT Execute(
const ArgsT &... Args)
const {
111 const ArgT *
const ArgsArray[] = {&Args...};
112 return Func(ArrayRef<const ArgT *>(ArgsArray,
sizeof...(ArgsT)));
121 return Node.getType();
125 return Node.getUnderlyingType();
130 inline const FunctionProtoType *
131 getFunctionProtoType(
const FunctionProtoType &Node) {
135 inline const FunctionProtoType *getFunctionProtoType(
const FunctionDecl &Node) {
136 return Node.getType()->getAs<FunctionProtoType>();
140 class BoundNodesMap {
146 NodeMap[
ID] = DynNode;
153 template <
typename T>
154 const T *getNodeAs(StringRef
ID)
const {
155 IDToNodeMap::const_iterator It = NodeMap.find(ID);
156 if (It == NodeMap.end()) {
159 return It->second.get<
T>();
163 IDToNodeMap::const_iterator It = NodeMap.find(ID);
164 if (It == NodeMap.end()) {
171 bool operator<(
const BoundNodesMap &Other)
const {
172 return NodeMap < Other.NodeMap;
180 using IDToNodeMap = std::map<std::string, ast_type_traits::DynTypedNode>;
182 const IDToNodeMap &getMap()
const {
188 bool isComparable()
const {
189 for (
const auto &IDAndNode : NodeMap) {
190 if (!IDAndNode.second.getMemoizationData())
204 class BoundNodesTreeBuilder {
210 virtual ~Visitor() =
default;
215 virtual void visitMatch(
const BoundNodes& BoundNodesView) = 0;
220 if (Bindings.empty())
221 Bindings.emplace_back();
222 for (BoundNodesMap &Binding : Bindings)
223 Binding.addNode(Id, DynNode);
227 void addMatch(
const BoundNodesTreeBuilder &Bindings);
232 void visitMatches(Visitor* ResultVisitor);
234 template <
typename ExcludePredicate>
235 bool removeBindings(
const ExcludePredicate &Predicate) {
236 Bindings.erase(std::remove_if(Bindings.begin(), Bindings.end(), Predicate),
238 return !Bindings.empty();
242 bool operator<(
const BoundNodesTreeBuilder &Other)
const {
243 return Bindings < Other.Bindings;
248 bool isComparable()
const {
249 for (
const BoundNodesMap &NodesMap : Bindings) {
250 if (!NodesMap.isComparable())
257 SmallVector<BoundNodesMap, 16> Bindings;
260 class ASTMatchFinder;
267 class DynMatcherInterface
268 :
public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> {
270 virtual ~DynMatcherInterface() =
default;
277 ASTMatchFinder *Finder,
278 BoundNodesTreeBuilder *Builder)
const = 0;
288 template <
typename T>
289 class MatcherInterface :
public DynMatcherInterface {
296 ASTMatchFinder *Finder,
297 BoundNodesTreeBuilder *Builder)
const = 0;
300 ASTMatchFinder *Finder,
301 BoundNodesTreeBuilder *Builder)
const override {
302 return matches(DynNode.getUnchecked<
T>(), Finder, Builder);
308 template <
typename T>
309 class SingleNodeMatcherInterface :
public MatcherInterface<T> {
314 virtual bool matchesNode(
const T &Node)
const = 0;
320 BoundNodesTreeBuilder * )
const override {
321 return matchesNode(Node);
325 template <
typename>
class Matcher;
334 class DynTypedMatcher {
337 template <
typename T>
338 DynTypedMatcher(MatcherInterface<T> *Implementation)
339 : SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<
T>()),
340 RestrictKind(SupportedKind), Implementation(Implementation) {}
343 enum VariadicOperator {
362 static DynTypedMatcher
363 constructVariadic(VariadicOperator Op,
364 ast_type_traits::ASTNodeKind SupportedKind,
365 std::vector<DynTypedMatcher> InnerMatchers);
370 static DynTypedMatcher trueMatcher(ast_type_traits::ASTNodeKind NodeKind);
372 void setAllowBind(
bool AB) { AllowBind = AB; }
377 bool canMatchNodesOfKind(ast_type_traits::ASTNodeKind
Kind)
const;
381 DynTypedMatcher dynCastTo(
const ast_type_traits::ASTNodeKind
Kind)
const;
385 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder)
const;
392 ASTMatchFinder *Finder,
393 BoundNodesTreeBuilder *Builder)
const;
407 using MatcherIDType = std::pair<ast_type_traits::ASTNodeKind, uint64_t>;
408 MatcherIDType getID()
const {
411 return std::make_pair(RestrictKind,
412 reinterpret_cast<uint64_t>(Implementation.get()));
419 ast_type_traits::ASTNodeKind getSupportedKind()
const {
420 return SupportedKind;
428 template <
typename T>
bool canConvertTo()
const {
429 return canConvertTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
431 bool canConvertTo(ast_type_traits::ASTNodeKind To)
const;
438 template <
typename T> Matcher<T> convertTo()
const {
439 assert(canConvertTo<T>());
440 return unconditionalConvertTo<T>();
447 template <
typename T> Matcher<T> unconditionalConvertTo()
const;
450 DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind,
451 ast_type_traits::ASTNodeKind RestrictKind,
452 IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
453 : SupportedKind(SupportedKind), RestrictKind(RestrictKind),
454 Implementation(
std::move(Implementation)) {}
456 bool AllowBind =
false;
457 ast_type_traits::ASTNodeKind SupportedKind;
463 ast_type_traits::ASTNodeKind RestrictKind;
464 IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
471 template <
typename T>
472 class WrapperMatcherInterface :
public MatcherInterface<T> {
474 explicit WrapperMatcherInterface(DynTypedMatcher &&InnerMatcher)
475 : InnerMatcher(
std::move(InnerMatcher)) {}
477 const DynTypedMatcher InnerMatcher;
488 template <
typename T>
492 explicit Matcher(MatcherInterface<T> *Implementation)
493 : Implementation(Implementation) {}
498 template <
typename From>
499 Matcher(
const Matcher<From> &Other,
500 typename std::enable_if<std::is_base_of<From, T>::value &&
501 !std::is_same<From, T>::value>::
type * =
nullptr)
502 : Implementation(restrictMatcher(Other.Implementation)) {
503 assert(Implementation.getSupportedKind().isSame(
504 ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
510 template <
typename TypeT>
511 Matcher(
const Matcher<TypeT> &Other,
512 typename std::enable_if<
513 std::is_same<T, QualType>::value &&
514 std::is_same<TypeT, Type>::value>::
type* =
nullptr)
515 : Implementation(new TypeToQualType<TypeT>(Other)) {}
520 template <
typename To>
521 Matcher<To> dynCastTo()
const {
522 static_assert(std::is_base_of<To, T>::value,
"Invalid dynCast call.");
523 return Matcher<To>(Implementation);
528 ASTMatchFinder *Finder,
529 BoundNodesTreeBuilder *Builder)
const {
535 DynTypedMatcher::MatcherIDType getID()
const {
536 return Implementation.getID();
543 operator DynTypedMatcher()
const {
return Implementation; }
551 template <
typename TypeT>
552 class TypeToQualType :
public WrapperMatcherInterface<QualType> {
554 TypeToQualType(
const Matcher<TypeT> &InnerMatcher)
555 : TypeToQualType::WrapperMatcherInterface(InnerMatcher) {}
557 bool matches(
const QualType &Node, ASTMatchFinder *Finder,
558 BoundNodesTreeBuilder *Builder)
const override {
561 return this->InnerMatcher.matches(
568 template <
typename U>
friend class Matcher;
571 friend class DynTypedMatcher;
573 static DynTypedMatcher restrictMatcher(
const DynTypedMatcher &Other) {
574 return Other.dynCastTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
577 explicit Matcher(
const DynTypedMatcher &Implementation)
578 : Implementation(restrictMatcher(Implementation)) {
579 assert(this->Implementation.getSupportedKind()
580 .isSame(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
583 DynTypedMatcher Implementation;
588 template <
typename T>
589 inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
590 return Matcher<T>(Implementation);
598 inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>()
const {
599 assert(canConvertTo<QualType>());
600 const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
601 if (SourceKind.isSame(
602 ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) {
604 return unconditionalConvertTo<Type>();
606 return unconditionalConvertTo<QualType>();
610 template <
typename MatcherT,
typename IteratorT>
611 bool matchesFirstInRange(
const MatcherT &Matcher, IteratorT Start,
612 IteratorT
End, ASTMatchFinder *Finder,
613 BoundNodesTreeBuilder *Builder) {
614 for (IteratorT I = Start; I !=
End; ++I) {
615 BoundNodesTreeBuilder Result(*Builder);
616 if (Matcher.matches(*I, Finder, &Result)) {
617 *Builder = std::move(Result);
626 template <
typename MatcherT,
typename IteratorT>
627 bool matchesFirstInPointerRange(
const MatcherT &Matcher, IteratorT Start,
628 IteratorT End, ASTMatchFinder *Finder,
629 BoundNodesTreeBuilder *Builder) {
630 for (IteratorT I = Start; I !=
End; ++I) {
631 BoundNodesTreeBuilder Result(*Builder);
632 if (Matcher.matches(**I, Finder, &Result)) {
633 *Builder = std::move(Result);
641 template <
typename Ty>
646 template <
typename Inner>
647 static yes& test(Inner *I, decltype(I->getDecl()) * =
nullptr);
650 static no& test(...);
653 static const bool value =
sizeof(test<Ty>(
nullptr)) ==
sizeof(yes);
660 template <
typename T,
typename ArgT>
661 class HasOverloadedOperatorNameMatcher :
public SingleNodeMatcherInterface<T> {
662 static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
663 std::is_base_of<FunctionDecl, T>::value,
664 "unsupported class for matcher");
665 static_assert(std::is_same<ArgT, StringRef>::value,
666 "argument type must be StringRef");
669 explicit HasOverloadedOperatorNameMatcher(
const StringRef Name)
670 : SingleNodeMatcherInterface<
T>(), Name(Name) {}
672 bool matchesNode(
const T &Node)
const override {
673 return matchesSpecialized(Node);
681 bool matchesSpecialized(
const CXXOperatorCallExpr &Node)
const {
687 bool matchesSpecialized(
const FunctionDecl &Node)
const {
688 return Node.isOverloadedOperator() &&
698 class HasNameMatcher :
public SingleNodeMatcherInterface<NamedDecl> {
700 explicit HasNameMatcher(std::vector<std::string> Names);
702 bool matchesNode(
const NamedDecl &Node)
const override;
709 bool matchesNodeUnqualified(
const NamedDecl &Node)
const;
717 bool matchesNodeFullFast(
const NamedDecl &Node)
const;
724 bool matchesNodeFullSlow(
const NamedDecl &Node)
const;
726 const bool UseUnqualifiedMatch;
727 const std::vector<std::string> Names;
732 Matcher<NamedDecl>
hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs);
738 template <
typename T,
typename DeclMatcherT>
739 class HasDeclarationMatcher :
public WrapperMatcherInterface<T> {
740 static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
741 "instantiated with wrong types");
744 explicit HasDeclarationMatcher(
const Matcher<Decl> &InnerMatcher)
745 : HasDeclarationMatcher::WrapperMatcherInterface(InnerMatcher) {}
747 bool matches(
const T &Node, ASTMatchFinder *Finder,
748 BoundNodesTreeBuilder *Builder)
const override {
749 return matchesSpecialized(Node, Finder, Builder);
754 bool matchesSpecialized(
const QualType &Node, ASTMatchFinder *Finder,
755 BoundNodesTreeBuilder *Builder)
const {
759 return matchesSpecialized(*Node, Finder, Builder);
764 bool matchesSpecialized(
const Type &Node, ASTMatchFinder *Finder,
765 BoundNodesTreeBuilder *Builder)
const {
769 if (
const auto *S = dyn_cast<DeducedType>(&Node)) {
770 EffectiveType = S->getDeducedType().getTypePtrOrNull();
777 if (
const auto *S = dyn_cast<TagType>(EffectiveType)) {
778 return matchesDecl(S->getDecl(), Finder, Builder);
780 if (
const auto *S = dyn_cast<InjectedClassNameType>(EffectiveType)) {
781 return matchesDecl(S->getDecl(), Finder, Builder);
783 if (
const auto *S = dyn_cast<TemplateTypeParmType>(EffectiveType)) {
784 return matchesDecl(S->getDecl(), Finder, Builder);
786 if (
const auto *S = dyn_cast<TypedefType>(EffectiveType)) {
787 return matchesDecl(S->getDecl(), Finder, Builder);
789 if (
const auto *S = dyn_cast<UnresolvedUsingType>(EffectiveType)) {
790 return matchesDecl(S->getDecl(), Finder, Builder);
792 if (
const auto *S = dyn_cast<ObjCObjectType>(EffectiveType)) {
793 return matchesDecl(S->getInterface(), Finder, Builder);
804 if (
const auto *S = dyn_cast<SubstTemplateTypeParmType>(EffectiveType)) {
805 return matchesSpecialized(S->getReplacementType(), Finder, Builder);
811 if (
const auto *S = dyn_cast<TemplateSpecializationType>(EffectiveType)) {
812 if (!S->isTypeAlias() && S->isSugared()) {
819 return matchesSpecialized(*S->desugar(), Finder, Builder);
823 return matchesDecl(S->getTemplateName().getAsTemplateDecl(), Finder,
830 if (
const auto *S = dyn_cast<ElaboratedType>(EffectiveType)) {
831 return matchesSpecialized(S->desugar(), Finder, Builder);
838 bool matchesSpecialized(
const DeclRefExpr &Node, ASTMatchFinder *Finder,
839 BoundNodesTreeBuilder *Builder)
const {
840 return matchesDecl(Node.getDecl(), Finder, Builder);
845 bool matchesSpecialized(
const CallExpr &Node, ASTMatchFinder *Finder,
846 BoundNodesTreeBuilder *Builder)
const {
847 return matchesDecl(Node.getCalleeDecl(), Finder, Builder);
852 bool matchesSpecialized(
const CXXConstructExpr &Node,
853 ASTMatchFinder *Finder,
854 BoundNodesTreeBuilder *Builder)
const {
855 return matchesDecl(Node.getConstructor(), Finder, Builder);
860 bool matchesSpecialized(
const CXXNewExpr &Node,
861 ASTMatchFinder *Finder,
862 BoundNodesTreeBuilder *Builder)
const {
863 return matchesDecl(Node.getOperatorNew(), Finder, Builder);
868 bool matchesSpecialized(
const MemberExpr &Node,
869 ASTMatchFinder *Finder,
870 BoundNodesTreeBuilder *Builder)
const {
871 return matchesDecl(Node.getMemberDecl(), Finder, Builder);
876 bool matchesSpecialized(
const AddrLabelExpr &Node,
877 ASTMatchFinder *Finder,
878 BoundNodesTreeBuilder *Builder)
const {
879 return matchesDecl(Node.getLabel(), Finder, Builder);
884 bool matchesSpecialized(
const LabelStmt &Node, ASTMatchFinder *Finder,
885 BoundNodesTreeBuilder *Builder)
const {
886 return matchesDecl(Node.getDecl(), Finder, Builder);
891 bool matchesDecl(
const Decl *Node, ASTMatchFinder *Finder,
892 BoundNodesTreeBuilder *Builder)
const {
893 return Node !=
nullptr &&
894 this->InnerMatcher.matches(
901 template <
typename T>
903 static const bool value =
904 std::is_same<T, Decl>::value ||
905 std::is_same<T, Stmt>::value ||
906 std::is_same<T, QualType>::value ||
907 std::is_same<T, Type>::value ||
908 std::is_same<T, TypeLoc>::value ||
909 std::is_same<T, NestedNameSpecifier>::value ||
910 std::is_same<T, NestedNameSpecifierLoc>::value ||
911 std::is_same<T, CXXCtorInitializer>::value;
913 template <
typename T>
914 const bool IsBaseType<T>::value;
934 class ASTMatchFinder {
943 TK_IgnoreImplicitCastsAndParentheses
956 enum AncestorMatchMode {
964 virtual ~ASTMatchFinder() =
default;
970 virtual bool classIsDerivedFrom(
const CXXRecordDecl *Declaration,
971 const Matcher<NamedDecl> &
Base,
972 BoundNodesTreeBuilder *Builder) = 0;
974 template <
typename T>
975 bool matchesChildOf(
const T &Node,
976 const DynTypedMatcher &Matcher,
977 BoundNodesTreeBuilder *Builder,
978 TraversalKind Traverse,
980 static_assert(std::is_base_of<Decl, T>::value ||
981 std::is_base_of<Stmt, T>::value ||
982 std::is_base_of<NestedNameSpecifier, T>::value ||
983 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
984 std::is_base_of<TypeLoc, T>::value ||
985 std::is_base_of<QualType, T>::value,
986 "unsupported type for recursive matching");
988 Matcher, Builder, Traverse, Bind);
991 template <
typename T>
992 bool matchesDescendantOf(
const T &Node,
993 const DynTypedMatcher &Matcher,
994 BoundNodesTreeBuilder *Builder,
996 static_assert(std::is_base_of<Decl, T>::value ||
997 std::is_base_of<Stmt, T>::value ||
998 std::is_base_of<NestedNameSpecifier, T>::value ||
999 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
1000 std::is_base_of<TypeLoc, T>::value ||
1001 std::is_base_of<QualType, T>::value,
1002 "unsupported type for recursive matching");
1004 Matcher, Builder, Bind);
1008 template <
typename T>
1009 bool matchesAncestorOf(
const T &Node,
1010 const DynTypedMatcher &Matcher,
1011 BoundNodesTreeBuilder *Builder,
1012 AncestorMatchMode MatchMode) {
1013 static_assert(std::is_base_of<Decl, T>::value ||
1014 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
1015 std::is_base_of<Stmt, T>::value ||
1016 std::is_base_of<TypeLoc, T>::value,
1017 "type not allowed for recursive matching");
1019 Matcher, Builder, MatchMode);
1022 virtual ASTContext &getASTContext()
const = 0;
1026 const DynTypedMatcher &Matcher,
1027 BoundNodesTreeBuilder *Builder,
1028 TraversalKind Traverse,
1032 const DynTypedMatcher &Matcher,
1033 BoundNodesTreeBuilder *Builder,
1037 const DynTypedMatcher &Matcher,
1038 BoundNodesTreeBuilder *Builder,
1039 AncestorMatchMode MatchMode) = 0;
1046 template <
typename... Ts>
struct TypeList {};
1048 template <
typename T1,
typename... Ts>
struct TypeList<T1, Ts...> {
1056 using tail = TypeList<Ts...>;
1060 using EmptyTypeList = TypeList<>;
1064 template <
typename AnyTypeList,
typename T>
1065 struct TypeListContainsSuperOf {
1066 static const bool value =
1067 std::is_base_of<typename AnyTypeList::head, T>::value ||
1068 TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
1070 template <
typename T>
1071 struct TypeListContainsSuperOf<EmptyTypeList,
T> {
1072 static const bool value =
false;
1078 using AllNodeBaseTypes =
1079 TypeList<
Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
1080 Type, TypeLoc, CXXCtorInitializer>;
1086 template <
class T>
struct ExtractFunctionArgMeta;
1087 template <
class T>
struct ExtractFunctionArgMeta<void(
T)> {
1092 using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
1093 using AdaptativeDefaultToTypes =
1094 TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
1098 using HasDeclarationSupportedTypes =
1099 TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
1100 ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
1101 MemberExpr, QualType, RecordType, TagType,
1102 TemplateSpecializationType, TemplateTypeParmType, TypedefType,
1103 UnresolvedUsingType>;
1118 template <
template <
typename ToArg,
typename FromArg>
class ArgumentAdapterT,
1119 typename FromTypes = AdaptativeDefaultFromTypes,
1120 typename ToTypes = AdaptativeDefaultToTypes>
1121 struct ArgumentAdaptingMatcherFunc {
1122 template <
typename T>
class Adaptor {
1124 explicit Adaptor(
const Matcher<T> &InnerMatcher)
1125 : InnerMatcher(InnerMatcher) {}
1127 using ReturnTypes = ToTypes;
1129 template <
typename To>
operator Matcher<To>()
const {
1130 return Matcher<To>(
new ArgumentAdapterT<To, T>(InnerMatcher));
1134 const Matcher<T> InnerMatcher;
1137 template <
typename T>
1138 static Adaptor<T>
create(
const Matcher<T> &InnerMatcher) {
1139 return Adaptor<T>(InnerMatcher);
1142 template <
typename T>
1143 Adaptor<T> operator()(
const Matcher<T> &InnerMatcher)
const {
1144 return create(InnerMatcher);
1160 template <
template <
typename T>
class MatcherT,
1161 typename ReturnTypesF = void(AllNodeBaseTypes)>
1162 class PolymorphicMatcherWithParam0 {
1166 template <
typename T>
1167 operator Matcher<T>()
const {
1168 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1169 "right polymorphic conversion");
1170 return Matcher<T>(
new MatcherT<T>());
1174 template <
template <
typename T,
typename P1>
class MatcherT,
1176 typename ReturnTypesF = void(AllNodeBaseTypes)>
1177 class PolymorphicMatcherWithParam1 {
1179 explicit PolymorphicMatcherWithParam1(
const P1 &Param1)
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, P1>(Param1));
1195 template <
template <
typename T,
typename P1,
typename P2>
class MatcherT,
1196 typename P1,
typename P2,
1197 typename ReturnTypesF = void(AllNodeBaseTypes)>
1198 class PolymorphicMatcherWithParam2 {
1200 PolymorphicMatcherWithParam2(
const P1 &Param1,
const P2 &Param2)
1201 : Param1(Param1), Param2(Param2) {}
1205 template <
typename T>
1206 operator Matcher<T>()
const {
1207 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1208 "right polymorphic conversion");
1209 return Matcher<T>(
new MatcherT<T, P1, P2>(Param1, Param2));
1223 using ReturnTypes = AllNodeBaseTypes;
1225 template <
typename T>
1226 operator Matcher<T>()
const {
1227 return DynTypedMatcher::trueMatcher(
1228 ast_type_traits::ASTNodeKind::getFromNodeKind<T>())
1229 .template unconditionalConvertTo<T>();
1237 template <
typename T>
1238 class BindableMatcher :
public Matcher<T> {
1240 explicit BindableMatcher(
const Matcher<T> &M) : Matcher<
T>(M) {}
1241 explicit BindableMatcher(MatcherInterface<T> *Implementation)
1242 : Matcher<
T>(Implementation) {}
1248 Matcher<T> bind(StringRef ID)
const {
1249 return DynTypedMatcher(*
this)
1251 ->template unconditionalConvertTo<T>();
1256 operator DynTypedMatcher()
const {
1257 DynTypedMatcher Result =
static_cast<const Matcher<T>&
>(*this);
1258 Result.setAllowBind(
true);
1267 template <
typename T,
typename ChildT>
1268 class HasMatcher :
public WrapperMatcherInterface<T> {
1270 explicit HasMatcher(
const Matcher<ChildT> &ChildMatcher)
1271 : HasMatcher::WrapperMatcherInterface(ChildMatcher) {}
1273 bool matches(
const T &Node, ASTMatchFinder *Finder,
1274 BoundNodesTreeBuilder *Builder)
const override {
1275 return Finder->matchesChildOf(Node, this->InnerMatcher, Builder,
1276 ASTMatchFinder::TK_AsIs,
1277 ASTMatchFinder::BK_First);
1286 template <
typename T,
typename ChildT>
1287 class ForEachMatcher :
public WrapperMatcherInterface<T> {
1288 static_assert(IsBaseType<ChildT>::value,
1289 "for each only accepts base type matcher");
1292 explicit ForEachMatcher(
const Matcher<ChildT> &ChildMatcher)
1293 : ForEachMatcher::WrapperMatcherInterface(ChildMatcher) {}
1295 bool matches(
const T& Node, ASTMatchFinder* Finder,
1296 BoundNodesTreeBuilder* Builder)
const override {
1297 return Finder->matchesChildOf(
1298 Node, this->InnerMatcher, Builder,
1299 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
1300 ASTMatchFinder::BK_All);
1313 template <
typename... Ps>
class VariadicOperatorMatcher {
1315 VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
1316 : Op(Op), Params(
std::forward<Ps>(Params)...) {}
1318 template <
typename T>
operator Matcher<T>()
const {
1319 return DynTypedMatcher::constructVariadic(
1320 Op, ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
1321 getMatchers<T>(llvm::index_sequence_for<Ps...>()))
1322 .template unconditionalConvertTo<T>();
1328 std::vector<DynTypedMatcher> getMatchers(llvm::index_sequence<Is...>)
const {
1329 return {Matcher<T>(std::get<Is>(Params))...};
1332 const DynTypedMatcher::VariadicOperator Op;
1333 std::tuple<Ps...> Params;
1338 template <
unsigned MinCount,
unsigned MaxCount>
1339 struct VariadicOperatorMatcherFunc {
1340 DynTypedMatcher::VariadicOperator Op;
1342 template <
typename... Ms>
1343 VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps)
const {
1344 static_assert(MinCount <=
sizeof...(Ms) &&
sizeof...(Ms) <= MaxCount,
1345 "invalid number of parameters for variadic matcher");
1346 return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...);
1352 template <
typename T>
1353 inline Matcher<T> DynTypedMatcher::unconditionalConvertTo()
const {
1354 return Matcher<T>(*this);
1358 template<
typename T>
1359 BindableMatcher<T> makeAllOfComposite(
1360 ArrayRef<
const Matcher<T> *> InnerMatchers) {
1362 if (InnerMatchers.empty()) {
1363 return BindableMatcher<T>(TrueMatcher());
1367 if (InnerMatchers.size() == 1) {
1368 return BindableMatcher<T>(*InnerMatchers[0]);
1371 using PI = llvm::pointee_iterator<const Matcher<T> *
const *>;
1373 std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
1374 PI(InnerMatchers.end()));
1375 return BindableMatcher<T>(
1376 DynTypedMatcher::constructVariadic(
1377 DynTypedMatcher::VO_AllOf,
1378 ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
1379 std::move(DynMatchers))
1380 .template unconditionalConvertTo<T>());
1389 template<
typename T,
typename InnerT>
1390 BindableMatcher<T> makeDynCastAllOfComposite(
1391 ArrayRef<
const Matcher<InnerT> *> InnerMatchers) {
1392 return BindableMatcher<T>(
1393 makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
1400 template <
typename T,
typename DescendantT>
1401 class HasDescendantMatcher :
public WrapperMatcherInterface<T> {
1402 static_assert(IsBaseType<DescendantT>::value,
1403 "has descendant only accepts base type matcher");
1406 explicit HasDescendantMatcher(
const Matcher<DescendantT> &DescendantMatcher)
1407 : HasDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
1409 bool matches(
const T &Node, ASTMatchFinder *Finder,
1410 BoundNodesTreeBuilder *Builder)
const override {
1411 return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder,
1412 ASTMatchFinder::BK_First);
1420 template <
typename T,
typename ParentT>
1421 class HasParentMatcher :
public WrapperMatcherInterface<T> {
1422 static_assert(IsBaseType<ParentT>::value,
1423 "has parent only accepts base type matcher");
1426 explicit HasParentMatcher(
const Matcher<ParentT> &ParentMatcher)
1427 : HasParentMatcher::WrapperMatcherInterface(ParentMatcher) {}
1429 bool matches(
const T &Node, ASTMatchFinder *Finder,
1430 BoundNodesTreeBuilder *Builder)
const override {
1431 return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder,
1432 ASTMatchFinder::AMM_ParentOnly);
1440 template <
typename T,
typename AncestorT>
1441 class HasAncestorMatcher :
public WrapperMatcherInterface<T> {
1442 static_assert(IsBaseType<AncestorT>::value,
1443 "has ancestor only accepts base type matcher");
1446 explicit HasAncestorMatcher(
const Matcher<AncestorT> &AncestorMatcher)
1447 : HasAncestorMatcher::WrapperMatcherInterface(AncestorMatcher) {}
1449 bool matches(
const T &Node, ASTMatchFinder *Finder,
1450 BoundNodesTreeBuilder *Builder)
const override {
1451 return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder,
1452 ASTMatchFinder::AMM_All);
1462 template <
typename T,
typename DescendantT>
1463 class ForEachDescendantMatcher :
public WrapperMatcherInterface<T> {
1464 static_assert(IsBaseType<DescendantT>::value,
1465 "for each descendant only accepts base type matcher");
1468 explicit ForEachDescendantMatcher(
1469 const Matcher<DescendantT> &DescendantMatcher)
1470 : ForEachDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
1472 bool matches(
const T &Node, ASTMatchFinder *Finder,
1473 BoundNodesTreeBuilder *Builder)
const override {
1474 return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder,
1475 ASTMatchFinder::BK_All);
1481 template <
typename T,
typename ValueT>
1482 class ValueEqualsMatcher :
public SingleNodeMatcherInterface<T> {
1483 static_assert(std::is_base_of<CharacterLiteral, T>::value ||
1484 std::is_base_of<CXXBoolLiteralExpr, T>::value ||
1485 std::is_base_of<FloatingLiteral, T>::value ||
1486 std::is_base_of<IntegerLiteral, T>::value,
1487 "the node must have a getValue method");
1490 explicit ValueEqualsMatcher(
const ValueT &ExpectedValue)
1491 : ExpectedValue(ExpectedValue) {}
1493 bool matchesNode(
const T &Node)
const override {
1494 return Node.getValue() == ExpectedValue;
1498 const ValueT ExpectedValue;
1504 inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
1505 const FloatingLiteral &Node)
const {
1506 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1507 return Node.getValue().convertToFloat() == ExpectedValue;
1508 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1509 return Node.getValue().convertToDouble() == ExpectedValue;
1513 inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
1514 const FloatingLiteral &Node)
const {
1515 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1516 return Node.getValue().convertToFloat() == ExpectedValue;
1517 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1518 return Node.getValue().convertToDouble() == ExpectedValue;
1522 inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
1523 const FloatingLiteral &Node)
const {
1524 return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
1539 template <
typename SourceT,
typename TargetT>
1540 class VariadicDynCastAllOfMatcher
1541 :
public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>,
1542 makeDynCastAllOfComposite<SourceT, TargetT>> {
1544 VariadicDynCastAllOfMatcher() {}
1557 template <
typename T>
1558 class VariadicAllOfMatcher
1559 :
public VariadicFunction<BindableMatcher<T>, Matcher<T>,
1560 makeAllOfComposite<T>> {
1562 VariadicAllOfMatcher() {}
1567 template <
typename TLoc,
typename T>
1568 class LocMatcher :
public WrapperMatcherInterface<TLoc> {
1570 explicit LocMatcher(
const Matcher<T> &InnerMatcher)
1571 : LocMatcher::WrapperMatcherInterface(InnerMatcher) {}
1573 bool matches(
const TLoc &Node, ASTMatchFinder *Finder,
1574 BoundNodesTreeBuilder *Builder)
const override {
1577 return this->InnerMatcher.matches(extract(Node), Finder, Builder);
1582 extract(
const NestedNameSpecifierLoc &Loc) {
1591 class TypeLocTypeMatcher :
public WrapperMatcherInterface<TypeLoc> {
1593 explicit TypeLocTypeMatcher(
const Matcher<QualType> &InnerMatcher)
1594 : TypeLocTypeMatcher::WrapperMatcherInterface(InnerMatcher) {}
1596 bool matches(
const TypeLoc &Node, ASTMatchFinder *Finder,
1597 BoundNodesTreeBuilder *Builder)
const override {
1600 return this->InnerMatcher.matches(
1608 template <
typename T>
1609 class TypeTraverseMatcher :
public WrapperMatcherInterface<T> {
1611 explicit TypeTraverseMatcher(
const Matcher<QualType> &InnerMatcher,
1612 QualType (
T::*TraverseFunction)()
const)
1613 : TypeTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
1614 TraverseFunction(TraverseFunction) {}
1616 bool matches(
const T &Node, ASTMatchFinder *Finder,
1617 BoundNodesTreeBuilder *Builder)
const override {
1618 QualType NextNode = (Node.*TraverseFunction)();
1619 if (NextNode.isNull())
1621 return this->InnerMatcher.matches(
1626 QualType (
T::*TraverseFunction)()
const;
1632 template <
typename T>
1633 class TypeLocTraverseMatcher :
public WrapperMatcherInterface<T> {
1635 explicit TypeLocTraverseMatcher(
const Matcher<TypeLoc> &InnerMatcher,
1636 TypeLoc (
T::*TraverseFunction)()
const)
1637 : TypeLocTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
1638 TraverseFunction(TraverseFunction) {}
1640 bool matches(
const T &Node, ASTMatchFinder *Finder,
1641 BoundNodesTreeBuilder *Builder)
const override {
1642 TypeLoc NextNode = (Node.*TraverseFunction)();
1645 return this->InnerMatcher.matches(
1650 TypeLoc (
T::*TraverseFunction)()
const;
1659 template <
typename InnerTBase,
1660 template <
typename OuterT>
class Getter,
1661 template <
typename OuterT>
class MatcherImpl,
1662 typename ReturnTypesF>
1663 class TypeTraversePolymorphicMatcher {
1665 using Self = TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
1668 static Self
create(ArrayRef<
const Matcher<InnerTBase> *> InnerMatchers);
1673 explicit TypeTraversePolymorphicMatcher(
1674 ArrayRef<
const Matcher<InnerTBase> *> InnerMatchers)
1675 : InnerMatcher(makeAllOfComposite(InnerMatchers)) {}
1677 template <
typename OuterT>
operator Matcher<OuterT>()
const {
1678 return Matcher<OuterT>(
1679 new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value()));
1683 :
public VariadicFunction<Self, Matcher<InnerTBase>, &Self::create> {
1688 const Matcher<InnerTBase> InnerMatcher;
1695 template <
typename Matcher, Matcher (*Func)()>
class MemoizedMatcher {
1697 Wrapper() : M(Func()) {}
1703 static const Matcher &getInstance() {
1704 static llvm::ManagedStatic<Wrapper> Instance;
1712 template <
typename InnerTBase,
template <
typename OuterT>
class Getter,
1713 template <
typename OuterT>
class MatcherImpl,
typename ReturnTypesF>
1714 TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF>
1715 TypeTraversePolymorphicMatcher<
1716 InnerTBase, Getter, MatcherImpl,
1717 ReturnTypesF>
::create(ArrayRef<
const Matcher<InnerTBase> *> InnerMatchers) {
1718 return Self(InnerMatchers);
1723 inline ArrayRef<TemplateArgument>
1724 getTemplateSpecializationArgs(
const ClassTemplateSpecializationDecl &D) {
1725 return D.getTemplateArgs().asArray();
1728 inline ArrayRef<TemplateArgument>
1729 getTemplateSpecializationArgs(
const TemplateSpecializationType &
T) {
1730 return llvm::makeArrayRef(T.getArgs(), T.getNumArgs());
1733 inline ArrayRef<TemplateArgument>
1734 getTemplateSpecializationArgs(
const FunctionDecl &FD) {
1735 if (
const auto* TemplateArgs = FD.getTemplateSpecializationArgs())
1736 return TemplateArgs->asArray();
1737 return ArrayRef<TemplateArgument>();
1740 struct NotEqualsBoundNodePredicate {
1741 bool operator()(
const internal::BoundNodesMap &
Nodes)
const {
1742 return Nodes.getNode(ID) !=
Node;
1749 template <
typename Ty>
1750 struct GetBodyMatcher {
1751 static const Stmt *
get(
const Ty &
Node) {
1752 return Node.getBody();
1757 inline const Stmt *GetBodyMatcher<FunctionDecl>::get(
const FunctionDecl &Node) {
1758 return Node.doesThisDeclarationHaveABody() ? Node.getBody() :
nullptr;
1761 template <
typename Ty>
1762 struct HasSizeMatcher {
1763 static bool hasSize(
const Ty &Node,
unsigned int N) {
1764 return Node.getSize() == N;
1769 inline bool HasSizeMatcher<StringLiteral>::hasSize(
1770 const StringLiteral &Node,
unsigned int N) {
1771 return Node.getLength() == N;
1774 template <
typename Ty>
1775 struct GetSourceExpressionMatcher {
1776 static const Expr *
get(
const Ty &
Node) {
1777 return Node.getSubExpr();
1782 inline const Expr *GetSourceExpressionMatcher<OpaqueValueExpr>::get(
1783 const OpaqueValueExpr &Node) {
1784 return Node.getSourceExpr();
1787 template <
typename Ty>
1788 struct CompoundStmtMatcher {
1789 static const CompoundStmt *
get(
const Ty &
Node) {
1795 inline const CompoundStmt *
1796 CompoundStmtMatcher<StmtExpr>::get(
const StmtExpr &Node) {
1797 return Node.getSubStmt();
1806 #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...
const FunctionProtoType * T
Defines an enumeration for C++ overloaded operators.
Defines the clang::TypeLoc interface and its subclasses.
The l-value was considered opaque, so the alignment was determined from a type.
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)