1 //===- TemplateArgumentVisitor.h - Visitor for TArg subclasses --*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the TemplateArgumentVisitor interface. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H 14 #define LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H 15 16 #include "clang/AST/TemplateBase.h" 17 18 namespace clang { 19 20 namespace templateargumentvisitor { 21 22 /// A simple visitor class that helps create template argument visitors. 23 template <template <typename> class Ref, typename ImplClass, 24 typename RetTy = void, typename... ParamTys> 25 class Base { 26 public: 27 #define REF(CLASS) typename Ref<CLASS>::type 28 #define DISPATCH(NAME) \ 29 case TemplateArgument::NAME: \ 30 return static_cast<ImplClass *>(this)->Visit##NAME##TemplateArgument( \ 31 TA, std::forward<ParamTys>(P)...) 32 Visit(REF (TemplateArgument)TA,ParamTys...P)33 RetTy Visit(REF(TemplateArgument) TA, ParamTys... P) { 34 switch (TA.getKind()) { 35 DISPATCH(Null); 36 DISPATCH(Type); 37 DISPATCH(Declaration); 38 DISPATCH(NullPtr); 39 DISPATCH(Integral); 40 DISPATCH(Template); 41 DISPATCH(TemplateExpansion); 42 DISPATCH(Expression); 43 DISPATCH(Pack); 44 } 45 llvm_unreachable("TemplateArgument is not covered in switch!"); 46 } 47 48 // If the implementation chooses not to implement a certain visit 49 // method, fall back to the parent. 50 51 #define VISIT_METHOD(CATEGORY) \ 52 RetTy Visit##CATEGORY##TemplateArgument(REF(TemplateArgument) TA, \ 53 ParamTys... P) { \ 54 return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); \ 55 } 56 57 VISIT_METHOD(Null); 58 VISIT_METHOD(Type); 59 VISIT_METHOD(Declaration); 60 VISIT_METHOD(NullPtr); 61 VISIT_METHOD(Integral); 62 VISIT_METHOD(Template); 63 VISIT_METHOD(TemplateExpansion); 64 VISIT_METHOD(Expression); 65 VISIT_METHOD(Pack); 66 VisitTemplateArgument(REF (TemplateArgument),ParamTys...)67 RetTy VisitTemplateArgument(REF(TemplateArgument), ParamTys...) { 68 return RetTy(); 69 } 70 71 #undef REF 72 #undef DISPATCH 73 #undef VISIT_METHOD 74 }; 75 76 } // namespace templateargumentvisitor 77 78 /// A simple visitor class that helps create template argument visitors. 79 /// 80 /// This class does not preserve constness of TemplateArgument references (see 81 /// also ConstTemplateArgumentVisitor). 82 template <typename ImplClass, typename RetTy = void, typename... ParamTys> 83 class TemplateArgumentVisitor 84 : public templateargumentvisitor::Base<std::add_lvalue_reference, ImplClass, 85 RetTy, ParamTys...> {}; 86 87 /// A simple visitor class that helps create template argument visitors. 88 /// 89 /// This class preserves constness of TemplateArgument references (see also 90 /// TemplateArgumentVisitor). 91 template <typename ImplClass, typename RetTy = void, typename... ParamTys> 92 class ConstTemplateArgumentVisitor 93 : public templateargumentvisitor::Base<llvm::make_const_ref, ImplClass, 94 RetTy, ParamTys...> {}; 95 96 } // namespace clang 97 98 #endif // LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H 99