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;
187 std::map<std::string, ast_type_traits::DynTypedNode, std::less<>>;
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, 1> Bindings;
267 class ASTMatchFinder;
274 class DynMatcherInterface
275 :
public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> {
277 virtual ~DynMatcherInterface() =
default;
284 ASTMatchFinder *Finder,
285 BoundNodesTreeBuilder *Builder)
const = 0;
299 template <
typename T>
300 class MatcherInterface :
public DynMatcherInterface {
306 virtual bool matches(
const T &Node,
307 ASTMatchFinder *Finder,
308 BoundNodesTreeBuilder *Builder)
const = 0;
311 ASTMatchFinder *Finder,
312 BoundNodesTreeBuilder *Builder)
const override {
313 return matches(DynNode.getUnchecked<T>(), Finder, Builder);
319 template <
typename T>
320 class SingleNodeMatcherInterface :
public MatcherInterface<T> {
325 virtual bool matchesNode(
const T &Node)
const = 0;
331 BoundNodesTreeBuilder * )
const override {
332 return matchesNode(Node);
336 template <
typename>
class Matcher;
345 class DynTypedMatcher {
348 template <
typename T>
349 DynTypedMatcher(MatcherInterface<T> *Implementation)
350 : SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
351 RestrictKind(SupportedKind), Implementation(Implementation) {}
354 enum VariadicOperator {
377 static DynTypedMatcher
378 constructVariadic(VariadicOperator Op,
379 ast_type_traits::ASTNodeKind SupportedKind,
380 std::vector<DynTypedMatcher> InnerMatchers);
382 static DynTypedMatcher
383 constructRestrictedWrapper(
const DynTypedMatcher &InnerMatcher,
384 ast_type_traits::ASTNodeKind RestrictKind);
389 static DynTypedMatcher trueMatcher(ast_type_traits::ASTNodeKind
NodeKind);
391 void setAllowBind(
bool AB) { AllowBind = AB; }
396 bool canMatchNodesOfKind(ast_type_traits::ASTNodeKind
Kind)
const;
400 DynTypedMatcher dynCastTo(
const ast_type_traits::ASTNodeKind
Kind)
const;
404 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder)
const;
411 ASTMatchFinder *Finder,
412 BoundNodesTreeBuilder *Builder)
const;
426 using MatcherIDType = std::pair<ast_type_traits::ASTNodeKind, uint64_t>;
427 MatcherIDType getID()
const {
430 return std::make_pair(RestrictKind,
431 reinterpret_cast<uint64_t>(Implementation.get()));
438 ast_type_traits::ASTNodeKind getSupportedKind()
const {
439 return SupportedKind;
447 template <
typename T>
bool canConvertTo()
const {
448 return canConvertTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
450 bool canConvertTo(ast_type_traits::ASTNodeKind To)
const;
457 template <
typename T> Matcher<T> convertTo()
const {
458 assert(canConvertTo<T>());
459 return unconditionalConvertTo<T>();
466 template <
typename T> Matcher<T> unconditionalConvertTo()
const;
469 DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind,
470 ast_type_traits::ASTNodeKind RestrictKind,
471 IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
472 : SupportedKind(SupportedKind), RestrictKind(RestrictKind),
473 Implementation(
std::move(Implementation)) {}
475 bool AllowBind =
false;
476 ast_type_traits::ASTNodeKind SupportedKind;
482 ast_type_traits::ASTNodeKind RestrictKind;
483 IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
490 template <
typename T>
491 class WrapperMatcherInterface :
public MatcherInterface<T> {
493 explicit WrapperMatcherInterface(DynTypedMatcher &&InnerMatcher)
494 : InnerMatcher(
std::move(InnerMatcher)) {}
496 const DynTypedMatcher InnerMatcher;
507 template <
typename T>
511 explicit Matcher(MatcherInterface<T> *Implementation)
512 : Implementation(Implementation) {}
517 template <
typename From>
518 Matcher(
const Matcher<From> &Other,
519 typename std::enable_if<std::is_base_of<From, T>::value &&
520 !std::is_same<From, T>::value>::
type * =
nullptr)
521 : Implementation(restrictMatcher(Other.Implementation)) {
522 assert(Implementation.getSupportedKind().isSame(
523 ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
529 template <
typename TypeT>
530 Matcher(
const Matcher<TypeT> &Other,
531 typename std::enable_if<
532 std::is_same<T, QualType>::value &&
533 std::is_same<TypeT, Type>::value>::
type* =
nullptr)
534 : Implementation(new TypeToQualType<TypeT>(Other)) {}
539 template <
typename To>
540 Matcher<To> dynCastTo()
const {
541 static_assert(std::is_base_of<To, T>::value,
"Invalid dynCast call.");
542 return Matcher<To>(Implementation);
547 ASTMatchFinder *Finder,
548 BoundNodesTreeBuilder *Builder)
const {
554 DynTypedMatcher::MatcherIDType getID()
const {
555 return Implementation.getID();
562 operator DynTypedMatcher()
const {
return Implementation; }
570 template <
typename TypeT>
571 class TypeToQualType :
public WrapperMatcherInterface<QualType> {
573 TypeToQualType(
const Matcher<TypeT> &InnerMatcher)
574 : TypeToQualType::WrapperMatcherInterface(InnerMatcher) {}
576 bool matches(
const QualType &Node, ASTMatchFinder *Finder,
577 BoundNodesTreeBuilder *Builder)
const override {
580 return this->InnerMatcher.matches(
587 template <
typename U>
friend class Matcher;
590 friend class DynTypedMatcher;
592 static DynTypedMatcher restrictMatcher(
const DynTypedMatcher &Other) {
593 return Other.dynCastTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
596 explicit Matcher(
const DynTypedMatcher &Implementation)
597 : Implementation(restrictMatcher(Implementation)) {
598 assert(this->Implementation.getSupportedKind()
599 .isSame(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
602 DynTypedMatcher Implementation;
607 template <
typename T>
608 inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
609 return Matcher<T>(Implementation);
617 inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>()
const {
618 assert(canConvertTo<QualType>());
619 const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
620 if (SourceKind.isSame(
621 ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) {
623 return unconditionalConvertTo<Type>();
625 return unconditionalConvertTo<QualType>();
629 template <
typename MatcherT,
typename IteratorT>
630 bool matchesFirstInRange(
const MatcherT &Matcher, IteratorT Start,
631 IteratorT
End, ASTMatchFinder *Finder,
632 BoundNodesTreeBuilder *Builder) {
633 for (IteratorT I = Start; I !=
End; ++I) {
634 BoundNodesTreeBuilder Result(*Builder);
635 if (Matcher.matches(*I, Finder, &Result)) {
636 *Builder = std::move(Result);
645 template <
typename MatcherT,
typename IteratorT>
646 bool matchesFirstInPointerRange(
const MatcherT &Matcher, IteratorT Start,
647 IteratorT End, ASTMatchFinder *Finder,
648 BoundNodesTreeBuilder *Builder) {
649 for (IteratorT I = Start; I !=
End; ++I) {
650 BoundNodesTreeBuilder Result(*Builder);
651 if (Matcher.matches(**I, Finder, &Result)) {
652 *Builder = std::move(Result);
660 template <
typename Ty>
665 template <
typename Inner>
666 static yes& test(Inner *I, decltype(I->getDecl()) * =
nullptr);
669 static no& test(...);
672 static const bool value =
sizeof(test<Ty>(
nullptr)) ==
sizeof(yes);
679 template <
typename T,
typename ArgT>
680 class HasOverloadedOperatorNameMatcher :
public SingleNodeMatcherInterface<T> {
681 static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
682 std::is_base_of<FunctionDecl, T>::value,
683 "unsupported class for matcher");
684 static_assert(std::is_same<ArgT, StringRef>::value,
685 "argument type must be StringRef");
688 explicit HasOverloadedOperatorNameMatcher(
const StringRef Name)
689 : SingleNodeMatcherInterface<T>(), Name(Name) {}
691 bool matchesNode(
const T &Node)
const override {
692 return matchesSpecialized(Node);
700 bool matchesSpecialized(
const CXXOperatorCallExpr &Node)
const {
706 bool matchesSpecialized(
const FunctionDecl &Node)
const {
707 return Node.isOverloadedOperator() &&
717 class HasNameMatcher :
public SingleNodeMatcherInterface<NamedDecl> {
719 explicit HasNameMatcher(std::vector<std::string> Names);
721 bool matchesNode(
const NamedDecl &Node)
const override;
728 bool matchesNodeUnqualified(
const NamedDecl &Node)
const;
736 bool matchesNodeFullFast(
const NamedDecl &Node)
const;
743 bool matchesNodeFullSlow(
const NamedDecl &Node)
const;
745 const bool UseUnqualifiedMatch;
746 const std::vector<std::string> Names;
751 Matcher<NamedDecl>
hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs);
756 ArrayRef<const StringRef *> NameRefs);
762 template <
typename T,
typename DeclMatcherT>
763 class HasDeclarationMatcher :
public WrapperMatcherInterface<T> {
764 static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
765 "instantiated with wrong types");
768 explicit HasDeclarationMatcher(
const Matcher<Decl> &InnerMatcher)
769 : HasDeclarationMatcher::WrapperMatcherInterface(InnerMatcher) {}
771 bool matches(
const T &Node, ASTMatchFinder *Finder,
772 BoundNodesTreeBuilder *Builder)
const override {
773 return matchesSpecialized(Node, Finder, Builder);
778 bool matchesSpecialized(
const QualType &Node, ASTMatchFinder *Finder,
779 BoundNodesTreeBuilder *Builder)
const {
783 return matchesSpecialized(*Node, Finder, Builder);
788 bool matchesSpecialized(
const Type &Node, ASTMatchFinder *Finder,
789 BoundNodesTreeBuilder *Builder)
const {
793 if (
const auto *S = dyn_cast<DeducedType>(&Node)) {
794 EffectiveType = S->getDeducedType().getTypePtrOrNull();
801 if (
const auto *S = dyn_cast<TagType>(EffectiveType)) {
802 return matchesDecl(S->getDecl(), Finder, Builder);
804 if (
const auto *S = dyn_cast<InjectedClassNameType>(EffectiveType)) {
805 return matchesDecl(S->getDecl(), Finder, Builder);
807 if (
const auto *S = dyn_cast<TemplateTypeParmType>(EffectiveType)) {
808 return matchesDecl(S->getDecl(), Finder, Builder);
810 if (
const auto *S = dyn_cast<TypedefType>(EffectiveType)) {
811 return matchesDecl(S->getDecl(), Finder, Builder);
813 if (
const auto *S = dyn_cast<UnresolvedUsingType>(EffectiveType)) {
814 return matchesDecl(S->getDecl(), Finder, Builder);
816 if (
const auto *S = dyn_cast<ObjCObjectType>(EffectiveType)) {
817 return matchesDecl(S->getInterface(), Finder, Builder);
828 if (
const auto *S = dyn_cast<SubstTemplateTypeParmType>(EffectiveType)) {
829 return matchesSpecialized(S->getReplacementType(), Finder, Builder);
835 if (
const auto *S = dyn_cast<TemplateSpecializationType>(EffectiveType)) {
836 if (!S->isTypeAlias() && S->isSugared()) {
843 return matchesSpecialized(*S->desugar(), Finder, Builder);
847 return matchesDecl(S->getTemplateName().getAsTemplateDecl(), Finder,
854 if (
const auto *S = dyn_cast<ElaboratedType>(EffectiveType)) {
855 return matchesSpecialized(S->desugar(), Finder, Builder);
862 bool matchesSpecialized(
const DeclRefExpr &Node, ASTMatchFinder *Finder,
863 BoundNodesTreeBuilder *Builder)
const {
864 return matchesDecl(Node.getDecl(), Finder, Builder);
869 bool matchesSpecialized(
const CallExpr &Node, ASTMatchFinder *Finder,
870 BoundNodesTreeBuilder *Builder)
const {
871 return matchesDecl(Node.getCalleeDecl(), Finder, Builder);
876 bool matchesSpecialized(
const CXXConstructExpr &Node,
877 ASTMatchFinder *Finder,
878 BoundNodesTreeBuilder *Builder)
const {
879 return matchesDecl(Node.getConstructor(), Finder, Builder);
882 bool matchesSpecialized(
const ObjCIvarRefExpr &Node,
883 ASTMatchFinder *Finder,
884 BoundNodesTreeBuilder *Builder)
const {
885 return matchesDecl(Node.getDecl(), Finder, Builder);
890 bool matchesSpecialized(
const CXXNewExpr &Node,
891 ASTMatchFinder *Finder,
892 BoundNodesTreeBuilder *Builder)
const {
893 return matchesDecl(Node.getOperatorNew(), Finder, Builder);
898 bool matchesSpecialized(
const MemberExpr &Node,
899 ASTMatchFinder *Finder,
900 BoundNodesTreeBuilder *Builder)
const {
901 return matchesDecl(Node.getMemberDecl(), Finder, Builder);
906 bool matchesSpecialized(
const AddrLabelExpr &Node,
907 ASTMatchFinder *Finder,
908 BoundNodesTreeBuilder *Builder)
const {
909 return matchesDecl(Node.getLabel(), Finder, Builder);
914 bool matchesSpecialized(
const LabelStmt &Node, ASTMatchFinder *Finder,
915 BoundNodesTreeBuilder *Builder)
const {
916 return matchesDecl(Node.getDecl(), Finder, Builder);
921 bool matchesDecl(
const Decl *Node, ASTMatchFinder *Finder,
922 BoundNodesTreeBuilder *Builder)
const {
923 return Node !=
nullptr &&
924 this->InnerMatcher.matches(
931 template <
typename T>
933 static const bool value =
934 std::is_same<T, Decl>::value ||
935 std::is_same<T, Stmt>::value ||
936 std::is_same<T, QualType>::value ||
937 std::is_same<T, Type>::value ||
938 std::is_same<T, TypeLoc>::value ||
939 std::is_same<T, NestedNameSpecifier>::value ||
940 std::is_same<T, NestedNameSpecifierLoc>::value ||
941 std::is_same<T, CXXCtorInitializer>::value;
943 template <
typename T>
944 const bool IsBaseType<T>::value;
964 class ASTMatchFinder {
977 enum AncestorMatchMode {
985 virtual ~ASTMatchFinder() =
default;
991 virtual bool classIsDerivedFrom(
const CXXRecordDecl *Declaration,
992 const Matcher<NamedDecl> &
Base,
993 BoundNodesTreeBuilder *Builder,
1000 virtual bool objcClassIsDerivedFrom(
const ObjCInterfaceDecl *Declaration,
1001 const Matcher<NamedDecl> &
Base,
1002 BoundNodesTreeBuilder *Builder,
1005 template <
typename T>
1006 bool matchesChildOf(
const T &Node,
const DynTypedMatcher &Matcher,
1007 BoundNodesTreeBuilder *Builder,
1009 static_assert(std::is_base_of<Decl, T>::value ||
1010 std::is_base_of<Stmt, T>::value ||
1011 std::is_base_of<NestedNameSpecifier, T>::value ||
1012 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
1013 std::is_base_of<TypeLoc, T>::value ||
1014 std::is_base_of<QualType, T>::value,
1015 "unsupported type for recursive matching");
1017 getASTContext(), Matcher, Builder, Traverse, Bind);
1020 template <
typename T>
1021 bool matchesDescendantOf(
const T &Node,
1022 const DynTypedMatcher &Matcher,
1023 BoundNodesTreeBuilder *Builder,
1025 static_assert(std::is_base_of<Decl, T>::value ||
1026 std::is_base_of<Stmt, T>::value ||
1027 std::is_base_of<NestedNameSpecifier, T>::value ||
1028 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
1029 std::is_base_of<TypeLoc, T>::value ||
1030 std::is_base_of<QualType, T>::value,
1031 "unsupported type for recursive matching");
1033 getASTContext(), Matcher, Builder, Bind);
1037 template <
typename T>
1038 bool matchesAncestorOf(
const T &Node,
1039 const DynTypedMatcher &Matcher,
1040 BoundNodesTreeBuilder *Builder,
1041 AncestorMatchMode MatchMode) {
1042 static_assert(std::is_base_of<Decl, T>::value ||
1043 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
1044 std::is_base_of<Stmt, T>::value ||
1045 std::is_base_of<TypeLoc, T>::value,
1046 "type not allowed for recursive matching");
1048 getASTContext(), Matcher, Builder, MatchMode);
1051 virtual ASTContext &getASTContext()
const = 0;
1055 ASTContext &Ctx,
const DynTypedMatcher &Matcher,
1056 BoundNodesTreeBuilder *Builder,
1062 const DynTypedMatcher &Matcher,
1063 BoundNodesTreeBuilder *Builder,
1068 const DynTypedMatcher &Matcher,
1069 BoundNodesTreeBuilder *Builder,
1070 AncestorMatchMode MatchMode) = 0;
1077 template <
typename... Ts>
struct TypeList {};
1079 template <
typename T1,
typename... Ts>
struct TypeList<T1, Ts...> {
1087 using tail = TypeList<Ts...>;
1091 using EmptyTypeList = TypeList<>;
1095 template <
typename AnyTypeList,
typename T>
1096 struct TypeListContainsSuperOf {
1097 static const bool value =
1098 std::is_base_of<typename AnyTypeList::head, T>::value ||
1099 TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
1101 template <
typename T>
1102 struct TypeListContainsSuperOf<EmptyTypeList, T> {
1103 static const bool value =
false;
1109 using AllNodeBaseTypes =
1110 TypeList<
Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
1111 Type, TypeLoc, CXXCtorInitializer>;
1117 template <
class T>
struct ExtractFunctionArgMeta;
1118 template <
class T>
struct ExtractFunctionArgMeta<void(T)> {
1123 using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
1124 using AdaptativeDefaultToTypes =
1125 TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
1129 using HasDeclarationSupportedTypes =
1130 TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
1131 ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
1132 MemberExpr, QualType, RecordType, TagType,
1133 TemplateSpecializationType, TemplateTypeParmType, TypedefType,
1134 UnresolvedUsingType, ObjCIvarRefExpr>;
1136 template <
template <
typename ToArg,
typename FromArg>
class ArgumentAdapterT,
1137 typename T,
typename ToTypes>
1138 class ArgumentAdaptingMatcherFuncAdaptor {
1140 explicit ArgumentAdaptingMatcherFuncAdaptor(
const Matcher<T> &InnerMatcher)
1141 : InnerMatcher(InnerMatcher) {}
1143 using ReturnTypes = ToTypes;
1145 template <
typename To>
operator Matcher<To>()
const {
1146 return Matcher<To>(
new ArgumentAdapterT<To, T>(InnerMatcher));
1150 const Matcher<T> InnerMatcher;
1166 template <
template <
typename ToArg,
typename FromArg>
class ArgumentAdapterT,
1167 typename FromTypes = AdaptativeDefaultFromTypes,
1168 typename ToTypes = AdaptativeDefaultToTypes>
1169 struct ArgumentAdaptingMatcherFunc {
1170 template <
typename T>
1171 static ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>
1172 create(
const Matcher<T> &InnerMatcher) {
1173 return ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>(
1177 template <
typename T>
1178 ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>
1179 operator()(
const Matcher<T> &InnerMatcher)
const {
1180 return create(InnerMatcher);
1184 template <
typename T>
1185 class TraversalMatcher :
public WrapperMatcherInterface<T> {
1190 const Matcher<T> &ChildMatcher)
1191 : TraversalMatcher::WrapperMatcherInterface(ChildMatcher), Traversal(TK) {
1194 bool matches(
const T &Node, ASTMatchFinder *Finder,
1195 BoundNodesTreeBuilder *Builder)
const override {
1196 return this->InnerMatcher.matches(
1206 template <
typename MatcherType>
class TraversalWrapper {
1209 const MatcherType &InnerMatcher)
1210 : TK(TK), InnerMatcher(InnerMatcher) {}
1212 template <
typename T>
operator Matcher<T>()
const {
1213 return internal::DynTypedMatcher::constructRestrictedWrapper(
1214 new internal::TraversalMatcher<T>(TK, InnerMatcher),
1215 ast_type_traits::ASTNodeKind::getFromNodeKind<T>())
1216 .template unconditionalConvertTo<T>();
1221 MatcherType InnerMatcher;
1236 template <
template <
typename T>
class MatcherT,
1237 typename ReturnTypesF = void(AllNodeBaseTypes)>
1238 class PolymorphicMatcherWithParam0 {
1242 template <
typename T>
1243 operator Matcher<T>()
const {
1244 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1245 "right polymorphic conversion");
1246 return Matcher<T>(
new MatcherT<T>());
1250 template <
template <
typename T,
typename P1>
class MatcherT,
1252 typename ReturnTypesF = void(AllNodeBaseTypes)>
1253 class PolymorphicMatcherWithParam1 {
1255 explicit PolymorphicMatcherWithParam1(
const P1 &Param1)
1260 template <
typename T>
1261 operator Matcher<T>()
const {
1262 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1263 "right polymorphic conversion");
1264 return Matcher<T>(
new MatcherT<T, P1>(Param1));
1271 template <
template <
typename T,
typename P1,
typename P2>
class MatcherT,
1272 typename P1,
typename P2,
1273 typename ReturnTypesF = void(AllNodeBaseTypes)>
1274 class PolymorphicMatcherWithParam2 {
1276 PolymorphicMatcherWithParam2(
const P1 &Param1,
const P2 &Param2)
1277 : Param1(Param1), Param2(Param2) {}
1281 template <
typename T>
1282 operator Matcher<T>()
const {
1283 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1284 "right polymorphic conversion");
1285 return Matcher<T>(
new MatcherT<T, P1, P2>(Param1, Param2));
1299 using ReturnTypes = AllNodeBaseTypes;
1301 template <
typename T>
1302 operator Matcher<T>()
const {
1303 return DynTypedMatcher::trueMatcher(
1304 ast_type_traits::ASTNodeKind::getFromNodeKind<T>())
1305 .template unconditionalConvertTo<T>();
1313 template <
typename T>
1314 class BindableMatcher :
public Matcher<T> {
1316 explicit BindableMatcher(
const Matcher<T> &M) : Matcher<T>(M) {}
1317 explicit BindableMatcher(MatcherInterface<T> *Implementation)
1318 : Matcher<T>(Implementation) {}
1324 Matcher<T> bind(StringRef ID)
const {
1325 return DynTypedMatcher(*
this)
1327 ->template unconditionalConvertTo<T>();
1332 operator DynTypedMatcher()
const {
1333 DynTypedMatcher Result =
static_cast<const Matcher<T>&
>(*this);
1334 Result.setAllowBind(
true);
1343 template <
typename T,
typename ChildT>
1344 class HasMatcher :
public WrapperMatcherInterface<T> {
1346 explicit HasMatcher(
const Matcher<ChildT> &ChildMatcher)
1347 : HasMatcher::WrapperMatcherInterface(ChildMatcher) {}
1349 bool matches(
const T &Node, ASTMatchFinder *Finder,
1350 BoundNodesTreeBuilder *Builder)
const override {
1351 return Finder->matchesChildOf(Node, this->InnerMatcher, Builder,
1353 ASTMatchFinder::BK_First);
1362 template <
typename T,
typename ChildT>
1363 class ForEachMatcher :
public WrapperMatcherInterface<T> {
1364 static_assert(IsBaseType<ChildT>::value,
1365 "for each only accepts base type matcher");
1368 explicit ForEachMatcher(
const Matcher<ChildT> &ChildMatcher)
1369 : ForEachMatcher::WrapperMatcherInterface(ChildMatcher) {}
1371 bool matches(
const T& Node, ASTMatchFinder* Finder,
1372 BoundNodesTreeBuilder* Builder)
const override {
1373 return Finder->matchesChildOf(
1374 Node, this->InnerMatcher, Builder,
1376 ASTMatchFinder::BK_All);
1389 template <
typename... Ps>
class VariadicOperatorMatcher {
1391 VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
1392 : Op(Op), Params(
std::forward<Ps>(Params)...) {}
1394 template <
typename T>
operator Matcher<T>()
const {
1395 return DynTypedMatcher::constructVariadic(
1396 Op, ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
1397 getMatchers<T>(std::index_sequence_for<Ps...>()))
1398 .template unconditionalConvertTo<T>();
1404 std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>)
const {
1405 return {Matcher<T>(std::get<Is>(Params))...};
1408 const DynTypedMatcher::VariadicOperator Op;
1409 std::tuple<Ps...> Params;
1414 template <
unsigned MinCount,
unsigned MaxCount>
1415 struct VariadicOperatorMatcherFunc {
1416 DynTypedMatcher::VariadicOperator Op;
1418 template <
typename... Ms>
1419 VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps)
const {
1420 static_assert(MinCount <=
sizeof...(Ms) &&
sizeof...(Ms) <= MaxCount,
1421 "invalid number of parameters for variadic matcher");
1422 return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...);
1428 template <
typename T>
1429 inline Matcher<T> DynTypedMatcher::unconditionalConvertTo()
const {
1430 return Matcher<T>(*this);
1434 template<
typename T>
1435 BindableMatcher<T> makeAllOfComposite(
1436 ArrayRef<
const Matcher<T> *> InnerMatchers) {
1438 if (InnerMatchers.empty()) {
1439 return BindableMatcher<T>(TrueMatcher());
1443 if (InnerMatchers.size() == 1) {
1444 return BindableMatcher<T>(*InnerMatchers[0]);
1447 using PI = llvm::pointee_iterator<const Matcher<T> *
const *>;
1449 std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
1450 PI(InnerMatchers.end()));
1451 return BindableMatcher<T>(
1452 DynTypedMatcher::constructVariadic(
1453 DynTypedMatcher::VO_AllOf,
1454 ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
1455 std::move(DynMatchers))
1456 .template unconditionalConvertTo<T>());
1465 template<
typename T,
typename InnerT>
1466 BindableMatcher<T> makeDynCastAllOfComposite(
1467 ArrayRef<
const Matcher<InnerT> *> InnerMatchers) {
1468 return BindableMatcher<T>(
1469 makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
1476 template <
typename T,
typename DescendantT>
1477 class HasDescendantMatcher :
public WrapperMatcherInterface<T> {
1478 static_assert(IsBaseType<DescendantT>::value,
1479 "has descendant only accepts base type matcher");
1482 explicit HasDescendantMatcher(
const Matcher<DescendantT> &DescendantMatcher)
1483 : HasDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
1485 bool matches(
const T &Node, ASTMatchFinder *Finder,
1486 BoundNodesTreeBuilder *Builder)
const override {
1487 return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder,
1488 ASTMatchFinder::BK_First);
1496 template <
typename T,
typename ParentT>
1497 class HasParentMatcher :
public WrapperMatcherInterface<T> {
1498 static_assert(IsBaseType<ParentT>::value,
1499 "has parent only accepts base type matcher");
1502 explicit HasParentMatcher(
const Matcher<ParentT> &ParentMatcher)
1503 : HasParentMatcher::WrapperMatcherInterface(ParentMatcher) {}
1505 bool matches(
const T &Node, ASTMatchFinder *Finder,
1506 BoundNodesTreeBuilder *Builder)
const override {
1507 return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder,
1508 ASTMatchFinder::AMM_ParentOnly);
1516 template <
typename T,
typename AncestorT>
1517 class HasAncestorMatcher :
public WrapperMatcherInterface<T> {
1518 static_assert(IsBaseType<AncestorT>::value,
1519 "has ancestor only accepts base type matcher");
1522 explicit HasAncestorMatcher(
const Matcher<AncestorT> &AncestorMatcher)
1523 : HasAncestorMatcher::WrapperMatcherInterface(AncestorMatcher) {}
1525 bool matches(
const T &Node, ASTMatchFinder *Finder,
1526 BoundNodesTreeBuilder *Builder)
const override {
1527 return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder,
1528 ASTMatchFinder::AMM_All);
1538 template <
typename T,
typename DescendantT>
1539 class ForEachDescendantMatcher :
public WrapperMatcherInterface<T> {
1540 static_assert(IsBaseType<DescendantT>::value,
1541 "for each descendant only accepts base type matcher");
1544 explicit ForEachDescendantMatcher(
1545 const Matcher<DescendantT> &DescendantMatcher)
1546 : ForEachDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {}
1548 bool matches(
const T &Node, ASTMatchFinder *Finder,
1549 BoundNodesTreeBuilder *Builder)
const override {
1550 return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder,
1551 ASTMatchFinder::BK_All);
1557 template <
typename T,
typename ValueT>
1558 class ValueEqualsMatcher :
public SingleNodeMatcherInterface<T> {
1559 static_assert(std::is_base_of<CharacterLiteral, T>::value ||
1560 std::is_base_of<CXXBoolLiteralExpr, T>::value ||
1561 std::is_base_of<FloatingLiteral, T>::value ||
1562 std::is_base_of<IntegerLiteral, T>::value,
1563 "the node must have a getValue method");
1566 explicit ValueEqualsMatcher(
const ValueT &ExpectedValue)
1567 : ExpectedValue(ExpectedValue) {}
1569 bool matchesNode(
const T &Node)
const override {
1570 return Node.getValue() == ExpectedValue;
1574 const ValueT ExpectedValue;
1580 inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
1581 const FloatingLiteral &Node)
const {
1582 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1583 return Node.getValue().convertToFloat() == ExpectedValue;
1584 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1585 return Node.getValue().convertToDouble() == ExpectedValue;
1589 inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
1590 const FloatingLiteral &Node)
const {
1591 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1592 return Node.getValue().convertToFloat() == ExpectedValue;
1593 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1594 return Node.getValue().convertToDouble() == ExpectedValue;
1598 inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
1599 const FloatingLiteral &Node)
const {
1600 return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
1614 template <
typename SourceT,
typename TargetT>
1615 class VariadicDynCastAllOfMatcher
1616 :
public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>,
1617 makeDynCastAllOfComposite<SourceT, TargetT>> {
1619 VariadicDynCastAllOfMatcher() {}
1632 template <
typename T>
1633 class VariadicAllOfMatcher
1634 :
public VariadicFunction<BindableMatcher<T>, Matcher<T>,
1635 makeAllOfComposite<T>> {
1637 VariadicAllOfMatcher() {}
1642 template <
typename TLoc,
typename T>
1643 class LocMatcher :
public WrapperMatcherInterface<TLoc> {
1645 explicit LocMatcher(
const Matcher<T> &InnerMatcher)
1646 : LocMatcher::WrapperMatcherInterface(InnerMatcher) {}
1648 bool matches(
const TLoc &Node, ASTMatchFinder *Finder,
1649 BoundNodesTreeBuilder *Builder)
const override {
1652 return this->InnerMatcher.matches(extract(Node), Finder, Builder);
1657 extract(
const NestedNameSpecifierLoc &Loc) {
1666 class TypeLocTypeMatcher :
public WrapperMatcherInterface<TypeLoc> {
1668 explicit TypeLocTypeMatcher(
const Matcher<QualType> &InnerMatcher)
1669 : TypeLocTypeMatcher::WrapperMatcherInterface(InnerMatcher) {}
1671 bool matches(
const TypeLoc &Node, ASTMatchFinder *Finder,
1672 BoundNodesTreeBuilder *Builder)
const override {
1675 return this->InnerMatcher.matches(
1683 template <
typename T>
1684 class TypeTraverseMatcher :
public WrapperMatcherInterface<T> {
1686 explicit TypeTraverseMatcher(
const Matcher<QualType> &InnerMatcher,
1687 QualType (T::*TraverseFunction)()
const)
1688 : TypeTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
1689 TraverseFunction(TraverseFunction) {}
1691 bool matches(
const T &Node, ASTMatchFinder *Finder,
1692 BoundNodesTreeBuilder *Builder)
const override {
1693 QualType NextNode = (Node.*TraverseFunction)();
1694 if (NextNode.isNull())
1696 return this->InnerMatcher.matches(
1701 QualType (T::*TraverseFunction)()
const;
1707 template <
typename T>
1708 class TypeLocTraverseMatcher :
public WrapperMatcherInterface<T> {
1710 explicit TypeLocTraverseMatcher(
const Matcher<TypeLoc> &InnerMatcher,
1711 TypeLoc (T::*TraverseFunction)()
const)
1712 : TypeLocTraverseMatcher::WrapperMatcherInterface(InnerMatcher),
1713 TraverseFunction(TraverseFunction) {}
1715 bool matches(
const T &Node, ASTMatchFinder *Finder,
1716 BoundNodesTreeBuilder *Builder)
const override {
1717 TypeLoc NextNode = (Node.*TraverseFunction)();
1720 return this->InnerMatcher.matches(
1725 TypeLoc (T::*TraverseFunction)()
const;
1734 template <
typename InnerTBase,
1735 template <
typename OuterT>
class Getter,
1736 template <
typename OuterT>
class MatcherImpl,
1737 typename ReturnTypesF>
1738 class TypeTraversePolymorphicMatcher {
1740 using Self = TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
1743 static Self
create(ArrayRef<
const Matcher<InnerTBase> *> InnerMatchers);
1748 explicit TypeTraversePolymorphicMatcher(
1749 ArrayRef<
const Matcher<InnerTBase> *> InnerMatchers)
1750 : InnerMatcher(makeAllOfComposite(InnerMatchers)) {}
1752 template <
typename OuterT>
operator Matcher<OuterT>()
const {
1753 return Matcher<OuterT>(
1754 new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value()));
1758 :
public VariadicFunction<Self, Matcher<InnerTBase>, &Self::create> {
1763 const Matcher<InnerTBase> InnerMatcher;
1770 template <
typename Matcher, Matcher (*Func)()>
class MemoizedMatcher {
1772 Wrapper() : M(Func()) {}
1778 static const Matcher &getInstance() {
1779 static llvm::ManagedStatic<Wrapper> Instance;
1787 template <
typename InnerTBase,
template <
typename OuterT>
class Getter,
1788 template <
typename OuterT>
class MatcherImpl,
typename ReturnTypesF>
1789 TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF>
1790 TypeTraversePolymorphicMatcher<
1791 InnerTBase, Getter, MatcherImpl,
1792 ReturnTypesF>
::create(ArrayRef<
const Matcher<InnerTBase> *> InnerMatchers) {
1793 return Self(InnerMatchers);
1798 inline ArrayRef<TemplateArgument>
1799 getTemplateSpecializationArgs(
const ClassTemplateSpecializationDecl &D) {
1800 return D.getTemplateArgs().asArray();
1803 inline ArrayRef<TemplateArgument>
1804 getTemplateSpecializationArgs(
const TemplateSpecializationType &T) {
1805 return llvm::makeArrayRef(T.getArgs(), T.getNumArgs());
1808 inline ArrayRef<TemplateArgument>
1809 getTemplateSpecializationArgs(
const FunctionDecl &FD) {
1810 if (
const auto* TemplateArgs = FD.getTemplateSpecializationArgs())
1811 return TemplateArgs->asArray();
1812 return ArrayRef<TemplateArgument>();
1815 struct NotEqualsBoundNodePredicate {
1816 bool operator()(
const internal::BoundNodesMap &
Nodes)
const {
1817 return Nodes.getNode(ID) !=
Node;
1824 template <
typename Ty>
1825 struct GetBodyMatcher {
1826 static const Stmt *
get(
const Ty &
Node) {
1827 return Node.getBody();
1832 inline const Stmt *GetBodyMatcher<FunctionDecl>::get(
const FunctionDecl &Node) {
1833 return Node.doesThisDeclarationHaveABody() ? Node.getBody() :
nullptr;
1836 template <
typename Ty>
1837 struct HasSizeMatcher {
1838 static bool hasSize(
const Ty &Node,
unsigned int N) {
1839 return Node.getSize() == N;
1844 inline bool HasSizeMatcher<StringLiteral>::hasSize(
1845 const StringLiteral &Node,
unsigned int N) {
1846 return Node.getLength() == N;
1849 template <
typename Ty>
1850 struct GetSourceExpressionMatcher {
1851 static const Expr *
get(
const Ty &
Node) {
1852 return Node.getSubExpr();
1857 inline const Expr *GetSourceExpressionMatcher<OpaqueValueExpr>::get(
1858 const OpaqueValueExpr &Node) {
1859 return Node.getSourceExpr();
1862 template <
typename Ty>
1863 struct CompoundStmtMatcher {
1864 static const CompoundStmt *
get(
const Ty &
Node) {
1870 inline const CompoundStmt *
1871 CompoundStmtMatcher<StmtExpr>::get(
const StmtExpr &Node) {
1872 return Node.getSubStmt();
1881 #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...
ast_type_traits::TraversalKind Traversal
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)