//===- TemplateArgumentVisitor.h - Visitor for TArg subclasses --*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines the TemplateArgumentVisitor interface. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H #define LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H #include "clang/AST/TemplateBase.h" namespace clang { namespace templateargumentvisitor { /// A simple visitor class that helps create template argument visitors. template <template <typename> class Ref, typename ImplClass, typename RetTy = void, typename... ParamTys> class Base { public: #define REF(CLASS) typename Ref<CLASS>::type #define DISPATCH(NAME) \ case TemplateArgument::NAME: \ return static_cast<ImplClass *>(this)->Visit##NAME##TemplateArgument( \ TA, std::forward<ParamTys>(P)...) RetTy Visit(REF(TemplateArgument) TA, ParamTys... P) { switch (TA.getKind()) { DISPATCH(Null); DISPATCH(Type); DISPATCH(Declaration); DISPATCH(NullPtr); DISPATCH(Integral); DISPATCH(Template); DISPATCH(TemplateExpansion); DISPATCH(Expression); DISPATCH(Pack); } llvm_unreachable("TemplateArgument is not covered in switch!"); } // If the implementation chooses not to implement a certain visit // method, fall back to the parent. #define VISIT_METHOD(CATEGORY) \ RetTy Visit##CATEGORY##TemplateArgument(REF(TemplateArgument) TA, \ ParamTys... P) { \ return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); \ } VISIT_METHOD(Null); VISIT_METHOD(Type); VISIT_METHOD(Declaration); VISIT_METHOD(NullPtr); VISIT_METHOD(Integral); VISIT_METHOD(Template); VISIT_METHOD(TemplateExpansion); VISIT_METHOD(Expression); VISIT_METHOD(Pack); RetTy VisitTemplateArgument(REF(TemplateArgument), ParamTys...) { return RetTy(); } #undef REF #undef DISPATCH #undef VISIT_METHOD }; } // namespace templateargumentvisitor /// A simple visitor class that helps create template argument visitors. /// /// This class does not preserve constness of TemplateArgument references (see /// also ConstTemplateArgumentVisitor). template <typename ImplClass, typename RetTy = void, typename... ParamTys> class TemplateArgumentVisitor : public templateargumentvisitor::Base<std::add_lvalue_reference, ImplClass, RetTy, ParamTys...> {}; /// A simple visitor class that helps create template argument visitors. /// /// This class preserves constness of TemplateArgument references (see also /// TemplateArgumentVisitor). template <typename ImplClass, typename RetTy = void, typename... ParamTys> class ConstTemplateArgumentVisitor : public templateargumentvisitor::Base<llvm::make_const_ref, ImplClass, RetTy, ParamTys...> {}; } // namespace clang #endif // LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H |