34 #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H 35 #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H 53 #include "llvm/ADT/APFloat.h" 54 #include "llvm/ADT/ArrayRef.h" 55 #include "llvm/ADT/IntrusiveRefCntPtr.h" 56 #include "llvm/ADT/None.h" 57 #include "llvm/ADT/Optional.h" 58 #include "llvm/ADT/STLExtras.h" 59 #include "llvm/ADT/SmallVector.h" 60 #include "llvm/ADT/StringRef.h" 61 #include "llvm/ADT/iterator.h" 62 #include "llvm/Support/Casting.h" 63 #include "llvm/Support/ManagedStatic.h" 71 #include <type_traits> 90 template <
typename ResultT,
typename ArgT,
91 ResultT (*Func)(ArrayRef<const ArgT *>)>
92 struct VariadicFunction {
93 ResultT operator()()
const {
return Func(None); }
95 template <
typename... ArgsT>
96 ResultT operator()(
const ArgT &Arg1,
const ArgsT &... Args)
const {
97 return Execute(Arg1, static_cast<const ArgT &>(Args)...);
102 ResultT operator()(ArrayRef<ArgT> Args)
const {
103 SmallVector<const ArgT*, 8> InnerArgs;
104 for (
const ArgT &Arg : Args)
105 InnerArgs.push_back(&Arg);
106 return Func(InnerArgs);
112 template <
typename... ArgsT> ResultT Execute(
const ArgsT &... Args)
const {
113 const ArgT *
const ArgsArray[] = {&Args...};
114 return Func(ArrayRef<const ArgT *>(ArgsArray,
sizeof...(ArgsT)));
123 return Node.getType();
126 return Node.getUnderlyingType();
129 if (
const TypeSourceInfo *TSI = Node.getFriendType())
130 return TSI->getType();
136 inline const FunctionProtoType *
137 getFunctionProtoType(
const FunctionProtoType &Node) {
141 inline const FunctionProtoType *getFunctionProtoType(
const FunctionDecl &Node) {
142 return Node.getType()->getAs<FunctionProtoType>();
146 class BoundNodesMap {
152 NodeMap[
ID] = DynNode;
159 template <
typename T>
160 const T *getNodeAs(StringRef
ID)
const {
161 IDToNodeMap::const_iterator It = NodeMap.find(ID);
162 if (It == NodeMap.end()) {
165 return It->second.get<T>();
169 IDToNodeMap::const_iterator It = NodeMap.find(ID);
170 if (It == NodeMap.end()) {
177 bool operator<(
const BoundNodesMap &Other)
const {
178 return NodeMap < Other.NodeMap;
186 using IDToNodeMap = std::map<std::string, ast_type_traits::DynTypedNode>;
188 const IDToNodeMap &getMap()
const {
194 bool isComparable()
const {
195 for (
const auto &IDAndNode : NodeMap) {
196 if (!IDAndNode.second.getMemoizationData())
210 class BoundNodesTreeBuilder {
216 virtual ~Visitor() =
default;
221 virtual void visitMatch(
const BoundNodes& BoundNodesView) = 0;
226 if (Bindings.empty())
227 Bindings.emplace_back();
228 for (BoundNodesMap &Binding : Bindings)
229 Binding.addNode(Id, DynNode);
233 void addMatch(
const BoundNodesTreeBuilder &Bindings);
238 void visitMatches(Visitor* ResultVisitor);
240 template <
typename ExcludePredicate>
241 bool removeBindings(
const ExcludePredicate &Predicate) {
242 Bindings.erase(std::remove_if(Bindings.begin(), Bindings.end(), Predicate),
244 return !Bindings.empty();
248 bool operator<(
const BoundNodesTreeBuilder &Other)
const {
249 return Bindings < Other.Bindings;
254 bool isComparable()
const {
255 for (
const BoundNodesMap &NodesMap : Bindings) {
256 if (!NodesMap.isComparable())
263 SmallVector<BoundNodesMap, 1> Bindings;
266 class ASTMatchFinder;
273 class DynMatcherInterface
274 :
public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> {
276 virtual ~DynMatcherInterface() =
default;
283 ASTMatchFinder *Finder,
284 BoundNodesTreeBuilder *Builder)
const = 0;
294 template <
typename T>
295 class MatcherInterface :
public DynMatcherInterface {
301 virtual bool matches(
const T &Node,
302 ASTMatchFinder *Finder,
303 BoundNodesTreeBuilder *Builder)
const = 0;
306 ASTMatchFinder *Finder,
307 BoundNodesTreeBuilder *Builder)
const override {
308 return matches(DynNode.getUnchecked<T>(), Finder, Builder);
314 template <
typename T>
315 class SingleNodeMatcherInterface :
public MatcherInterface<T> {
320 virtual bool matchesNode(
const T &Node)
const = 0;
326 BoundNodesTreeBuilder * )
const override {
327 return matchesNode(Node);
331 template <
typename>
class Matcher;
340 class DynTypedMatcher {
343 template <
typename T>
344 DynTypedMatcher(MatcherInterface<T> *Implementation)
345 : SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
346 RestrictKind(SupportedKind), Implementation(Implementation) {}
349 enum VariadicOperator {
368 static DynTypedMatcher
369 constructVariadic(VariadicOperator Op,
370 ast_type_traits::ASTNodeKind SupportedKind,
371 std::vector<DynTypedMatcher> InnerMatchers);
376 static DynTypedMatcher trueMatcher(ast_type_traits::ASTNodeKind
NodeKind);
378 void setAllowBind(
bool AB) { AllowBind = AB; }
383 bool canMatchNodesOfKind(ast_type_traits::ASTNodeKind
Kind)
const;
387 DynTypedMatcher dynCastTo(
const ast_type_traits::ASTNodeKind
Kind)
const;
391 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder)
const;
398 ASTMatchFinder *Finder,
399 BoundNodesTreeBuilder *Builder)
const;
413 using MatcherIDType = std::pair<ast_type_traits::ASTNodeKind, uint64_t>;
414 MatcherIDType getID()
const {
417 return std::make_pair(RestrictKind,
418 reinterpret_cast<uint64_t>(Implementation.get()));
425 ast_type_traits::ASTNodeKind getSupportedKind()
const {
426 return SupportedKind;
434 template <
typename T>
bool canConvertTo()
const {
435 return canConvertTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
437 bool canConvertTo(ast_type_traits::ASTNodeKind To)
const;
444 template <
typename T> Matcher<T> convertTo()
const {
445 assert(canConvertTo<T>());
446 return unconditionalConvertTo<T>();
453 template <
typename T> Matcher<T> unconditionalConvertTo()
const;
456 DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind,
457 ast_type_traits::ASTNodeKind RestrictKind,
458 IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
459 : SupportedKind(SupportedKind), RestrictKind(RestrictKind),
460 Implementation(
std::move(Implementation)) {}
462 bool AllowBind =
false;
463 ast_type_traits::ASTNodeKind SupportedKind;
469 ast_type_traits::ASTNodeKind RestrictKind;
470 IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
477 template <
typename T>
478 class WrapperMatcherInterface :
public MatcherInterface<T> {
480 explicit WrapperMatcherInterface(DynTypedMatcher &&InnerMatcher)
481 : InnerMatcher(
std::move(InnerMatcher)) {}
483 const DynTypedMatcher InnerMatcher;
494 template <
typename T>
498 explicit Matcher(MatcherInterface<T> *Implementation)
499 : Implementation(Implementation) {}
504 template <
typename From>
505 Matcher(
const Matcher<From> &Other,
506 typename std::enable_if<std::is_base_of<From, T>::value &&
507 !std::is_same<From, T>::value>::
type * =
nullptr)
508 : Implementation(restrictMatcher(Other.Implementation)) {
509 assert(Implementation.getSupportedKind().isSame(
510 ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
516 template <
typename TypeT>
517 Matcher(
const Matcher<TypeT> &Other,
518 typename std::enable_if<
519 std::is_same<T, QualType>::value &&
520 std::is_same<TypeT, Type>::value>::
type* =
nullptr)
521 : Implementation(new TypeToQualType<TypeT>(Other)) {}
526 template <
typename To>
527 Matcher<To> dynCastTo()
const {
528 static_assert(std::is_base_of<To, T>::value,
"Invalid dynCast call.");
529 return Matcher<To>(Implementation);
534 ASTMatchFinder *Finder,
535 BoundNodesTreeBuilder *Builder)
const {
541 DynTypedMatcher::MatcherIDType getID()
const {
542 return Implementation.getID();
549 operator DynTypedMatcher()
const {
return Implementation; }
557 template <
typename TypeT>
558 class TypeToQualType :
public WrapperMatcherInterface<QualType> {
560 TypeToQualType(
const Matcher<TypeT> &InnerMatcher)
561 : TypeToQualType::WrapperMatcherInterface(InnerMatcher) {}
563 bool matches(
const QualType &Node, ASTMatchFinder *Finder,
564 BoundNodesTreeBuilder *Builder)
const override {
567 return this->InnerMatcher.matches(
574 template <
typename U>
friend class Matcher;
577 friend class DynTypedMatcher;
579 static DynTypedMatcher restrictMatcher(
const DynTypedMatcher &Other) {
580 return Other.dynCastTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
583 explicit Matcher(
const DynTypedMatcher &Implementation)
584 : Implementation(restrictMatcher(Implementation)) {
585 assert(this->Implementation.getSupportedKind()
586 .isSame(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
589 DynTypedMatcher Implementation;
594 template <
typename T>
595 inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
596 return Matcher<T>(Implementation);
604 inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>()
const {
605 assert(canConvertTo<QualType>());
606 const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
607 if (SourceKind.isSame(
608 ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) {
610 return unconditionalConvertTo<Type>();
612 return unconditionalConvertTo<QualType>();
616 template <
typename MatcherT,
typename IteratorT>
617 bool matchesFirstInRange(
const MatcherT &Matcher, IteratorT Start,
618 IteratorT
End, ASTMatchFinder *Finder,
619 BoundNodesTreeBuilder *Builder) {
620 for (IteratorT I = Start; I !=
End; ++I) {
621 BoundNodesTreeBuilder Result(*Builder);
622 if (Matcher.matches(*I, Finder, &Result)) {
623 *Builder = std::move(Result);
632 template <
typename MatcherT,
typename IteratorT>
633 bool matchesFirstInPointerRange(
const MatcherT &Matcher, IteratorT Start,
634 IteratorT End, ASTMatchFinder *Finder,
635 BoundNodesTreeBuilder *Builder) {
636 for (IteratorT I = Start; I !=
End; ++I) {
637 BoundNodesTreeBuilder Result(*Builder);
638 if (Matcher.matches(**I, Finder, &Result)) {
639 *Builder = std::move(Result);
647 template <
typename Ty>
652 template <
typename Inner>
653 static yes& test(Inner *I, decltype(I->getDecl()) * =
nullptr);
656 static no& test(...);
659 static const bool value =
sizeof(test<Ty>(
nullptr)) ==
sizeof(yes);
666 template <
typename T,
typename ArgT>
667 class HasOverloadedOperatorNameMatcher :
public SingleNodeMatcherInterface<T> {
668 static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
669 std::is_base_of<FunctionDecl, T>::value,
670 "unsupported class for matcher");
671 static_assert(std::is_same<ArgT, StringRef>::value,
672 "argument type must be StringRef");
675 explicit HasOverloadedOperatorNameMatcher(
const StringRef Name)
676 : SingleNodeMatcherInterface<T>(), Name(Name) {}
678 bool matchesNode(
const T &Node)
const override {
679 return matchesSpecialized(Node);
687 bool matchesSpecialized(
const CXXOperatorCallExpr &Node)
const {
693 bool matchesSpecialized(
const FunctionDecl &Node)
const {
694 return Node.isOverloadedOperator() &&
704 class HasNameMatcher :
public SingleNodeMatcherInterface<NamedDecl> {
706 explicit HasNameMatcher(std::vector<std::string> Names);
708 bool matchesNode(
const NamedDecl &Node)
const override;
715 bool matchesNodeUnqualified(
const NamedDecl &Node)
const;
723 bool matchesNodeFullFast(
const NamedDecl &Node)
const;
730 bool matchesNodeFullSlow(
const NamedDecl &Node)
const;
732 const bool UseUnqualifiedMatch;
733 const std::vector<std::string> Names;
738 Matcher<NamedDecl>
hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs);
743 ArrayRef<const StringRef *> NameRefs);
749 template <
typename T,
typename DeclMatcherT>
750 class HasDeclarationMatcher :
public WrapperMatcherInterface<T> {
751 static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
752 "instantiated with wrong types");
755 explicit HasDeclarationMatcher(
const Matcher<Decl> &InnerMatcher)
756 : HasDeclarationMatcher::WrapperMatcherInterface(InnerMatcher) {}
758 bool matches(
const T &Node, ASTMatchFinder *Finder,
759 BoundNodesTreeBuilder *Builder)
const override {
760 return matchesSpecialized(Node, Finder, Builder);
765 bool matchesSpecialized(
const QualType &Node, ASTMatchFinder *Finder,
766 BoundNodesTreeBuilder *Builder)
const {
770 return matchesSpecialized(*Node, Finder, Builder);
775 bool matchesSpecialized(
const Type &Node, ASTMatchFinder *Finder,
776 BoundNodesTreeBuilder *Builder)
const {
780 if (
const auto *S = dyn_cast<DeducedType>(&Node)) {
781 EffectiveType = S->getDeducedType().getTypePtrOrNull();
788 if (
const auto *S = dyn_cast<TagType>(EffectiveType)) {
789 return matchesDecl(S->getDecl(), Finder, Builder);
791 if (
const auto *S = dyn_cast<InjectedClassNameType>(EffectiveType)) {
792 return matchesDecl(S->getDecl(), Finder, Builder);
794 if (
const auto *S = dyn_cast<TemplateTypeParmType>(EffectiveType)) {
795 return matchesDecl(S->getDecl(), Finder, Builder);
797 if (
const auto *S = dyn_cast<TypedefType>(EffectiveType)) {
798 return matchesDecl(S->getDecl(), Finder, Builder);
800 if (
const auto *S = dyn_cast<UnresolvedUsingType>(EffectiveType)) {
801 return matchesDecl(S->getDecl(), Finder, Builder);
803 if (
const auto *S = dyn_cast<ObjCObjectType>(EffectiveType)) {
804 return matchesDecl(S->getInterface(), Finder, Builder);
815 if (
const auto *S = dyn_cast<SubstTemplateTypeParmType>(EffectiveType)) {
816 return matchesSpecialized(S->getReplacementType(), Finder, Builder);
822 if (
const auto *S = dyn_cast<TemplateSpecializationType>(EffectiveType)) {
823 if (!S->isTypeAlias() && S->isSugared()) {
830 return matchesSpecialized(*S->desugar(), Finder, Builder);
834 return matchesDecl(S->getTemplateName().getAsTemplateDecl(), Finder,
841 if (
const auto *S = dyn_cast<ElaboratedType>(EffectiveType)) {
842 return matchesSpecialized(S->desugar(), Finder, Builder);
849 bool matchesSpecialized(
const DeclRefExpr &Node, ASTMatchFinder *Finder,
850 BoundNodesTreeBuilder *Builder)
const {
851 return matchesDecl(Node.getDecl(), Finder, Builder);
856 bool matchesSpecialized(
const CallExpr &Node, ASTMatchFinder *Finder,
857 BoundNodesTreeBuilder *Builder)
const {
858 return matchesDecl(Node.getCalleeDecl(), Finder, Builder);
863 bool matchesSpecialized(
const CXXConstructExpr &Node,
864 ASTMatchFinder *Finder,
865 BoundNodesTreeBuilder *Builder)
const {
866 return matchesDecl(Node.getConstructor(), Finder, Builder);
869 bool matchesSpecialized(
const ObjCIvarRefExpr &Node,
870 ASTMatchFinder *Finder,
871 BoundNodesTreeBuilder *Builder)
const {
872 return matchesDecl(Node.getDecl(), Finder, Builder);
877 bool matchesSpecialized(
const CXXNewExpr &Node,
878 ASTMatchFinder *Finder,
879 BoundNodesTreeBuilder *Builder)
const {
880 return matchesDecl(Node.getOperatorNew(), Finder, Builder);
885 bool matchesSpecialized(
const MemberExpr &Node,
886 ASTMatchFinder *Finder,
887 BoundNodesTreeBuilder *Builder)
const {
888 return matchesDecl(Node.getMemberDecl(), Finder, Builder);
893 bool matchesSpecialized(
const AddrLabelExpr &Node,
894 ASTMatchFinder *Finder,
895 BoundNodesTreeBuilder *Builder)
const {
896 return matchesDecl(Node.getLabel(), Finder, Builder);
901 bool matchesSpecialized(
const LabelStmt &Node, ASTMatchFinder *Finder,
902 BoundNodesTreeBuilder *Builder)
const {
903 return matchesDecl(Node.getDecl(), Finder, Builder);
908 bool matchesDecl(
const Decl *Node, ASTMatchFinder *Finder,
909 BoundNodesTreeBuilder *Builder)
const {
910 return Node !=
nullptr &&
911 this->InnerMatcher.matches(
918 template <
typename T>
920 static const bool value =
921 std::is_same<T, Decl>::value ||
922 std::is_same<T, Stmt>::value ||
923 std::is_same<T, QualType>::value ||
924 std::is_same<T, Type>::value ||
925 std::is_same<T, TypeLoc>::value ||
926 std::is_same<T, NestedNameSpecifier>::value ||
927 std::is_same<T, NestedNameSpecifierLoc>::value ||
928 std::is_same<T, CXXCtorInitializer>::value;
930 template <
typename T>
931 const bool IsBaseType<T>::value;
951 class ASTMatchFinder {
964 enum AncestorMatchMode {
972 virtual ~ASTMatchFinder() =
default;
978 virtual bool classIsDerivedFrom(
const CXXRecordDecl *Declaration,
979 const Matcher<NamedDecl> &
Base,
980 BoundNodesTreeBuilder *Builder) = 0;
982 template <
typename T>
983 bool matchesChildOf(
const T &Node,
const DynTypedMatcher &Matcher,
984 BoundNodesTreeBuilder *Builder,
986 static_assert(std::is_base_of<Decl, T>::value ||
987 std::is_base_of<Stmt, T>::value ||
988 std::is_base_of<NestedNameSpecifier, T>::value ||
989 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
990 std::is_base_of<TypeLoc, T>::value ||
991 std::is_base_of<QualType, T>::value,
992 "unsupported type for recursive matching");
994 Matcher, Builder, Traverse, Bind);
997 template <
typename T>
998 bool matchesDescendantOf(
const T &Node,
999 const DynTypedMatcher &Matcher,
1000 BoundNodesTreeBuilder *Builder,
1002 static_assert(std::is_base_of<Decl, T>::value ||
1003 std::is_base_of<Stmt, T>::value ||
1004 std::is_base_of<NestedNameSpecifier, T>::value ||
1005 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
1006 std::is_base_of<TypeLoc, T>::value ||
1007 std::is_base_of<QualType, T>::value,
1008 "unsupported type for recursive matching");
1010 Matcher, Builder, Bind);
1014 template <
typename T>
1015 bool matchesAncestorOf(
const T &Node,
1016 const DynTypedMatcher &Matcher,
1017 BoundNodesTreeBuilder *Builder,
1018 AncestorMatchMode MatchMode) {
1019 static_assert(std::is_base_of<Decl, T>::value ||
1020 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
1021 std::is_base_of<Stmt, T>::value ||
1022 std::is_base_of<TypeLoc, T>::value,
1023 "type not allowed for recursive matching");
1025 Matcher, Builder, MatchMode);
1028 virtual ASTContext &getASTContext()
const = 0;
1032 const DynTypedMatcher &Matcher,
1033 BoundNodesTreeBuilder *Builder,
1038 const DynTypedMatcher &Matcher,
1039 BoundNodesTreeBuilder *Builder,
1043 const DynTypedMatcher &Matcher,
1044 BoundNodesTreeBuilder *Builder,
1045 AncestorMatchMode MatchMode) = 0;
1052 template <
typename... Ts>
struct TypeList {};
1054 template <
typename T1,
typename... Ts>
struct TypeList<T1, Ts...> {
1062 using tail = TypeList<Ts...>;
1066 using EmptyTypeList = TypeList<>;
1070 template <
typename AnyTypeList,
typename T>
1071 struct TypeListContainsSuperOf {
1072 static const bool value =
1073 std::is_base_of<typename AnyTypeList::head, T>::value ||
1074 TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
1076 template <
typename T>
1077 struct TypeListContainsSuperOf<EmptyTypeList, T> {
1078 static const bool value =
false;
1084 using AllNodeBaseTypes =
1085 TypeList<
Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
1086 Type, TypeLoc, CXXCtorInitializer>;
1092 template <
class T>
struct ExtractFunctionArgMeta;
1093 template <
class T>
struct ExtractFunctionArgMeta<void(T)> {
1098 using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
1099 using AdaptativeDefaultToTypes =
1100 TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
1104 using HasDeclarationSupportedTypes =
1105 TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
1106 ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
1107 MemberExpr, QualType, RecordType, TagType,
1108 TemplateSpecializationType, TemplateTypeParmType, TypedefType,
1109 UnresolvedUsingType, ObjCIvarRefExpr>;
1124 template <
template <
typename ToArg,
typename FromArg>
class ArgumentAdapterT,
1125 typename FromTypes = AdaptativeDefaultFromTypes,
1126 typename ToTypes = AdaptativeDefaultToTypes>
1127 struct ArgumentAdaptingMatcherFunc {
1128 template <
typename T>
class Adaptor {
1130 explicit Adaptor(
const Matcher<T> &InnerMatcher)
1131 : InnerMatcher(InnerMatcher) {}
1133 using ReturnTypes = ToTypes;
1135 template <
typename To>
operator Matcher<To>()
const {
1136 return Matcher<To>(
new ArgumentAdapterT<To, T>(InnerMatcher));
1140 const Matcher<T> InnerMatcher;
1143 template <
typename T>
1144 static Adaptor<T>
create(
const Matcher<T> &InnerMatcher) {
1145 return Adaptor<T>(InnerMatcher);
1148 template <
typename T>
1149 Adaptor<T> operator()(
const Matcher<T> &InnerMatcher)
const {
1150 return create(InnerMatcher);
1166 template <
template <
typename T>
class MatcherT,
1167 typename ReturnTypesF = void(AllNodeBaseTypes)>
1168 class PolymorphicMatcherWithParam0 {
1172 template <
typename T>
1173 operator Matcher<T>()
const {
1174 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1175 "right polymorphic conversion");
1176 return Matcher<T>(
new MatcherT<T>());
1180 template <
template <
typename T,
typename P1>
class MatcherT,
1182 typename ReturnTypesF = void(AllNodeBaseTypes)>
1183 class PolymorphicMatcherWithParam1 {
1185 explicit PolymorphicMatcherWithParam1(
const P1 &Param1)
1190 template <
typename T>
1191 operator Matcher<T>()
const {
1192 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1193 "right polymorphic conversion");
1194 return Matcher<T>(
new MatcherT<T, P1>(Param1));
1201 template <
template <
typename T,
typename P1,
typename P2>
class MatcherT,
1202 typename P1,
typename P2,
1203 typename ReturnTypesF = void(AllNodeBaseTypes)>
1204 class PolymorphicMatcherWithParam2 {
1206 PolymorphicMatcherWithParam2(
const P1 &Param1,
const P2 &Param2)
1207 : Param1(Param1), Param2(Param2) {}
1211 template <
typename T>
1212 operator Matcher<T>()
const {
1213 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1214 "right polymorphic conversion");
1215 return Matcher<T>(
new MatcherT<T, P1, P2>(Param1, Param2));
1229 using ReturnTypes = AllNodeBaseTypes;
1231 template <
typename T>
1232 operator Matcher<T>()
const {
1233 return DynTypedMatcher::trueMatcher(
1234 ast_type_traits::ASTNodeKind::getFromNodeKind<T>())
1235 .template unconditionalConvertTo<T>();
1243 template <
typename T>
1244 class BindableMatcher :
public Matcher<T> {
1246 explicit BindableMatcher(
const Matcher<T> &M) : Matcher<T>(M) {}
1247 explicit BindableMatcher(MatcherInterface<T> *Implementation)
1248 : Matcher<T>(Implementation) {}
1254 Matcher<T> bind(StringRef ID)
const {
1255 return DynTypedMatcher(*
this)
1257 ->template unconditionalConvertTo<T>();
1262 operator DynTypedMatcher()
const {
1263 DynTypedMatcher Result =
static_cast<const Matcher<T>&
>(*this);
1264 Result.setAllowBind(
true);
1273 template <
typename T,
typename ChildT>
1274 class HasMatcher :
public WrapperMatcherInterface<T> {
1276 explicit HasMatcher(
const Matcher<ChildT> &ChildMatcher)
1277 : HasMatcher::WrapperMatcherInterface(ChildMatcher) {}
1279 bool matches(
const T &Node, ASTMatchFinder *Finder,
1280 BoundNodesTreeBuilder *Builder)
const override {
1281 return Finder->matchesChildOf(Node, this->InnerMatcher, Builder,
1283 ASTMatchFinder::BK_First);
1292 template <
typename T,
typename ChildT>
1293 class ForEachMatcher :
public WrapperMatcherInterface<T> {
1294 static_assert(IsBaseType<ChildT>::value,
1295 "for each only accepts base type matcher");
1298 explicit ForEachMatcher(
const Matcher<ChildT> &ChildMatcher)
1299 : ForEachMatcher::WrapperMatcherInterface(ChildMatcher) {}
1301 bool matches(
const T& Node, ASTMatchFinder* Finder,
1302 BoundNodesTreeBuilder* Builder)
const override {
1303 return Finder->matchesChildOf(
1304 Node, this->InnerMatcher, Builder,
1306 ASTMatchFinder::BK_All);
1319 template <
typename... Ps>
class VariadicOperatorMatcher {
1321 VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
1322 : Op(Op), Params(
std::forward<Ps>(Params)...) {}
1324 template <
typename T>
operator Matcher<T>()
const {
1325 return DynTypedMatcher::constructVariadic(
1326 Op, ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
1327 getMatchers<T>(llvm::index_sequence_for<Ps...>()))
1328 .template unconditionalConvertTo<T>();
1334 std::vector<DynTypedMatcher> getMatchers(llvm::index_sequence<Is...>)
const {
1335 return {Matcher<T>(std::get<Is>(Params))...};
1338 const DynTypedMatcher::VariadicOperator Op;
1339 std::tuple<Ps...> Params;
1344 template <
unsigned MinCount,
unsigned MaxCount>
1345 struct VariadicOperatorMatcherFunc {
1346 DynTypedMatcher::VariadicOperator Op;
1348 template <
typename... Ms>
1349 VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps)
const {
1350 static_assert(MinCount <=
sizeof...(Ms) &&
sizeof...(Ms) <= MaxCount,
1351 "invalid number of parameters for variadic matcher");
1352 return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...);
1358 template <
typename T>
1359 inline Matcher<T> DynTypedMatcher::unconditionalConvertTo()
const {
1360 return Matcher<T>(*this);
1364 template<
typename T>
1365 BindableMatcher<T> makeAllOfComposite(
1366 ArrayRef<
const Matcher<T> *> InnerMatchers) {
1368 if (InnerMatchers.empty()) {
1369 return BindableMatcher<T>(TrueMatcher());
1373 if (InnerMatchers.size() == 1) {
1374 return BindableMatcher<T>(*InnerMatchers[0]);
1377 using PI = llvm::pointee_iterator<const Matcher<T> *
const *>;
1379 std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
1380 PI(InnerMatchers.end()));
1381 return BindableMatcher<T>(
1382 DynTypedMatcher::constructVariadic(
1383 DynTypedMatcher::VO_AllOf,
1384 ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
1385 std::move(DynMatchers))
1386 .template unconditionalConvertTo<T>());
1395 template<
typename T,
typename InnerT>
1396 BindableMatcher<T> makeDynCastAllOfComposite(
1397 ArrayRef<
const Matcher<InnerT> *> InnerMatchers) {
1398 return BindableMatcher<T>(
1399 makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
1406 template <
typename T,
typename DescendantT>
1407 class HasDescendantMatcher :
public WrapperMatcherInterface<T> {
1408 static_assert(IsBaseType<DescendantT>::value,
1409 "has descendant only accepts base type matcher");
1412 explicit HasDescendantMatcher(
const Matcher<DescendantT> &DescendantMatcher)
1413 : HasDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
1415 bool matches(
const T &Node, ASTMatchFinder *Finder,
1416 BoundNodesTreeBuilder *Builder)
const override {
1417 return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder,
1418 ASTMatchFinder::BK_First);
1426 template <
typename T,
typename ParentT>
1427 class HasParentMatcher :
public WrapperMatcherInterface<T> {
1428 static_assert(IsBaseType<ParentT>::value,
1429 "has parent only accepts base type matcher");
1432 explicit HasParentMatcher(
const Matcher<ParentT> &ParentMatcher)
1433 : HasParentMatcher::WrapperMatcherInterface(ParentMatcher) {}
1435 bool matches(
const T &Node, ASTMatchFinder *Finder,
1436 BoundNodesTreeBuilder *Builder)
const override {
1437 return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder,
1438 ASTMatchFinder::AMM_ParentOnly);
1446 template <
typename T,
typename AncestorT>
1447 class HasAncestorMatcher :
public WrapperMatcherInterface<T> {
1448 static_assert(IsBaseType<AncestorT>::value,
1449 "has ancestor only accepts base type matcher");
1452 explicit HasAncestorMatcher(
const Matcher<AncestorT> &AncestorMatcher)
1453 : HasAncestorMatcher::WrapperMatcherInterface(AncestorMatcher) {}
1455 bool matches(
const T &Node, ASTMatchFinder *Finder,
1456 BoundNodesTreeBuilder *Builder)
const override {
1457 return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder,
1458 ASTMatchFinder::AMM_All);
1468 template <
typename T,
typename DescendantT>
1469 class ForEachDescendantMatcher :
public WrapperMatcherInterface<T> {
1470 static_assert(IsBaseType<DescendantT>::value,
1471 "for each descendant only accepts base type matcher");
1474 explicit ForEachDescendantMatcher(
1475 const Matcher<DescendantT> &DescendantMatcher)
1476 : ForEachDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
1478 bool matches(
const T &Node, ASTMatchFinder *Finder,
1479 BoundNodesTreeBuilder *Builder)
const override {
1480 return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder,
1481 ASTMatchFinder::BK_All);
1487 template <
typename T,
typename ValueT>
1488 class ValueEqualsMatcher :
public SingleNodeMatcherInterface<T> {
1489 static_assert(std::is_base_of<CharacterLiteral, T>::value ||
1490 std::is_base_of<CXXBoolLiteralExpr, T>::value ||
1491 std::is_base_of<FloatingLiteral, T>::value ||
1492 std::is_base_of<IntegerLiteral, T>::value,
1493 "the node must have a getValue method");
1496 explicit ValueEqualsMatcher(
const ValueT &ExpectedValue)
1497 : ExpectedValue(ExpectedValue) {}
1499 bool matchesNode(
const T &Node)
const override {
1500 return Node.getValue() == ExpectedValue;
1504 const ValueT ExpectedValue;
1510 inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
1511 const FloatingLiteral &Node)
const {
1512 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1513 return Node.getValue().convertToFloat() == ExpectedValue;
1514 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1515 return Node.getValue().convertToDouble() == ExpectedValue;
1519 inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
1520 const FloatingLiteral &Node)
const {
1521 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1522 return Node.getValue().convertToFloat() == ExpectedValue;
1523 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1524 return Node.getValue().convertToDouble() == ExpectedValue;
1528 inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
1529 const FloatingLiteral &Node)
const {
1530 return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
1544 template <
typename SourceT,
typename TargetT>
1545 class VariadicDynCastAllOfMatcher
1546 :
public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>,
1547 makeDynCastAllOfComposite<SourceT, TargetT>> {
1549 VariadicDynCastAllOfMatcher() {}
1562 template <
typename T>
1563 class VariadicAllOfMatcher
1564 :
public VariadicFunction<BindableMatcher<T>, Matcher<T>,
1565 makeAllOfComposite<T>> {
1567 VariadicAllOfMatcher() {}
1572 template <
typename TLoc,
typename T>
1573 class LocMatcher :
public WrapperMatcherInterface<TLoc> {
1575 explicit LocMatcher(
const Matcher<T> &InnerMatcher)
1576 : LocMatcher::WrapperMatcherInterface(InnerMatcher) {}
1578 bool matches(
const TLoc &Node, ASTMatchFinder *Finder,
1579 BoundNodesTreeBuilder *Builder)
const override {
1582 return this->InnerMatcher.matches(extract(Node), Finder, Builder);
1587 extract(
const NestedNameSpecifierLoc &Loc) {
1596 class TypeLocTypeMatcher :
public WrapperMatcherInterface<TypeLoc> {
1598 explicit TypeLocTypeMatcher(
const Matcher<QualType> &InnerMatcher)
1599 : TypeLocTypeMatcher::WrapperMatcherInterface(InnerMatcher) {}
1601 bool matches(
const TypeLoc &Node, ASTMatchFinder *Finder,
1602 BoundNodesTreeBuilder *Builder)
const override {
1605 return this->InnerMatcher.matches(
1613 template <
typename T>
1614 class TypeTraverseMatcher :
public WrapperMatcherInterface<T> {
1616 explicit TypeTraverseMatcher(
const Matcher<QualType> &InnerMatcher,
1617 QualType (T::*TraverseFunction)()
const)
1618 : TypeTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
1619 TraverseFunction(TraverseFunction) {}
1621 bool matches(
const T &Node, ASTMatchFinder *Finder,
1622 BoundNodesTreeBuilder *Builder)
const override {
1623 QualType NextNode = (Node.*TraverseFunction)();
1624 if (NextNode.isNull())
1626 return this->InnerMatcher.matches(
1631 QualType (T::*TraverseFunction)()
const;
1637 template <
typename T>
1638 class TypeLocTraverseMatcher :
public WrapperMatcherInterface<T> {
1640 explicit TypeLocTraverseMatcher(
const Matcher<TypeLoc> &InnerMatcher,
1641 TypeLoc (T::*TraverseFunction)()
const)
1642 : TypeLocTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
1643 TraverseFunction(TraverseFunction) {}
1645 bool matches(
const T &Node, ASTMatchFinder *Finder,
1646 BoundNodesTreeBuilder *Builder)
const override {
1647 TypeLoc NextNode = (Node.*TraverseFunction)();
1650 return this->InnerMatcher.matches(
1655 TypeLoc (T::*TraverseFunction)()
const;
1664 template <
typename InnerTBase,
1665 template <
typename OuterT>
class Getter,
1666 template <
typename OuterT>
class MatcherImpl,
1667 typename ReturnTypesF>
1668 class TypeTraversePolymorphicMatcher {
1670 using Self = TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
1673 static Self
create(ArrayRef<
const Matcher<InnerTBase> *> InnerMatchers);
1678 explicit TypeTraversePolymorphicMatcher(
1679 ArrayRef<
const Matcher<InnerTBase> *> InnerMatchers)
1680 : InnerMatcher(makeAllOfComposite(InnerMatchers)) {}
1682 template <
typename OuterT>
operator Matcher<OuterT>()
const {
1683 return Matcher<OuterT>(
1684 new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value()));
1688 :
public VariadicFunction<Self, Matcher<InnerTBase>, &Self::create> {
1693 const Matcher<InnerTBase> InnerMatcher;
1700 template <
typename Matcher, Matcher (*Func)()>
class MemoizedMatcher {
1702 Wrapper() : M(Func()) {}
1708 static const Matcher &getInstance() {
1709 static llvm::ManagedStatic<Wrapper> Instance;
1717 template <
typename InnerTBase,
template <
typename OuterT>
class Getter,
1718 template <
typename OuterT>
class MatcherImpl,
typename ReturnTypesF>
1719 TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF>
1720 TypeTraversePolymorphicMatcher<
1721 InnerTBase, Getter, MatcherImpl,
1722 ReturnTypesF>
::create(ArrayRef<
const Matcher<InnerTBase> *> InnerMatchers) {
1723 return Self(InnerMatchers);
1728 inline ArrayRef<TemplateArgument>
1729 getTemplateSpecializationArgs(
const ClassTemplateSpecializationDecl &D) {
1730 return D.getTemplateArgs().asArray();
1733 inline ArrayRef<TemplateArgument>
1734 getTemplateSpecializationArgs(
const TemplateSpecializationType &T) {
1735 return llvm::makeArrayRef(T.getArgs(), T.getNumArgs());
1738 inline ArrayRef<TemplateArgument>
1739 getTemplateSpecializationArgs(
const FunctionDecl &FD) {
1740 if (
const auto* TemplateArgs = FD.getTemplateSpecializationArgs())
1741 return TemplateArgs->asArray();
1742 return ArrayRef<TemplateArgument>();
1745 struct NotEqualsBoundNodePredicate {
1746 bool operator()(
const internal::BoundNodesMap &
Nodes)
const {
1747 return Nodes.getNode(ID) !=
Node;
1754 template <
typename Ty>
1755 struct GetBodyMatcher {
1756 static const Stmt *
get(
const Ty &
Node) {
1757 return Node.getBody();
1762 inline const Stmt *GetBodyMatcher<FunctionDecl>::get(
const FunctionDecl &Node) {
1763 return Node.doesThisDeclarationHaveABody() ? Node.getBody() :
nullptr;
1766 template <
typename Ty>
1767 struct HasSizeMatcher {
1768 static bool hasSize(
const Ty &Node,
unsigned int N) {
1769 return Node.getSize() == N;
1774 inline bool HasSizeMatcher<StringLiteral>::hasSize(
1775 const StringLiteral &Node,
unsigned int N) {
1776 return Node.getLength() == N;
1779 template <
typename Ty>
1780 struct GetSourceExpressionMatcher {
1781 static const Expr *
get(
const Ty &
Node) {
1782 return Node.getSubExpr();
1787 inline const Expr *GetSourceExpressionMatcher<OpaqueValueExpr>::get(
1788 const OpaqueValueExpr &Node) {
1789 return Node.getSourceExpr();
1792 template <
typename Ty>
1793 struct CompoundStmtMatcher {
1794 static const CompoundStmt *
get(
const Ty &
Node) {
1800 inline const CompoundStmt *
1801 CompoundStmtMatcher<StmtExpr>::get(
const StmtExpr &Node) {
1802 return Node.getSubStmt();
1811 #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
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
Will traverse all child nodes.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
Will not traverse implicit casts and parentheses.
Defines an enumeration for C++ overloaded operators.
Defines the clang::TypeLoc interface and its subclasses.
NodeKind
A kind of a syntax node, used for implementing casts.
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
Optional< types::ID > Type
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...
static Expected< DynTypedNode > getNode(const ast_matchers::BoundNodes &Nodes, StringRef ID)
TraversalKind
Defines how we descend a level in the AST when we pass through expressions.
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)