1 //===--- TypeVisitor.h - Visitor for Type subclasses ------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the TypeVisitor interface. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_TYPEVISITOR_H 15 #define LLVM_CLANG_AST_TYPEVISITOR_H 16 17 #include "clang/AST/Type.h" 18 19 namespace clang { 20 21 #define DISPATCH(CLASS) \ 22 return static_cast<ImplClass*>(this)-> \ 23 Visit##CLASS(static_cast<const CLASS*>(T)) 24 25 /// \brief An operation on a type. 26 /// 27 /// \tparam ImplClass Class implementing the operation. Must be inherited from 28 /// TypeVisitor. 29 /// \tparam RetTy %Type of result produced by the operation. 30 /// 31 /// The class implements polymorphic operation on an object of type derived 32 /// from Type. The operation is performed by calling method Visit. It then 33 /// dispatches the call to function \c VisitFooType, if actual argument type 34 /// is \c FooType. 35 /// 36 /// The class implements static polymorphism using Curiously Recurring 37 /// Template Pattern. It is designed to be a base class for some concrete 38 /// class: 39 /// 40 /// \code 41 /// class SomeVisitor : public TypeVisitor<SomeVisitor,sometype> { ... }; 42 /// ... 43 /// Type *atype = ... 44 /// ... 45 /// SomeVisitor avisitor; 46 /// sometype result = avisitor.Visit(atype); 47 /// \endcode 48 /// 49 /// Actual treatment is made by methods of the derived class, TypeVisitor only 50 /// dispatches call to the appropriate method. If the implementation class 51 /// \c ImplClass provides specific action for some type, say 52 /// \c ConstantArrayType, it should define method 53 /// <tt>VisitConstantArrayType(const ConstantArrayType*)</tt>. Otherwise 54 /// \c TypeVisitor dispatches call to the method that handles parent type. In 55 /// this example handlers are tried in the sequence: 56 /// 57 /// \li <tt>ImplClass::VisitConstantArrayType(const ConstantArrayType*)</tt> 58 /// \li <tt>ImplClass::VisitArrayType(const ArrayType*)</tt> 59 /// \li <tt>ImplClass::VisitType(const Type*)</tt> 60 /// \li <tt>TypeVisitor::VisitType(const Type*)</tt> 61 /// 62 /// The first function of this sequence that is defined will handle object of 63 /// type \c ConstantArrayType. 64 template<typename ImplClass, typename RetTy=void> 65 class TypeVisitor { 66 public: 67 68 /// \brief Performs the operation associated with this visitor object. Visit(const Type * T)69 RetTy Visit(const Type *T) { 70 // Top switch stmt: dispatch to VisitFooType for each FooType. 71 switch (T->getTypeClass()) { 72 #define ABSTRACT_TYPE(CLASS, PARENT) 73 #define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type); 74 #include "clang/AST/TypeNodes.def" 75 } 76 llvm_unreachable("Unknown type class!"); 77 } 78 79 // If the implementation chooses not to implement a certain visit method, fall 80 // back on superclass. 81 #define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(const CLASS##Type *T) { \ 82 DISPATCH(PARENT); \ 83 } 84 #include "clang/AST/TypeNodes.def" 85 86 /// \brief Method called if \c ImpClass doesn't provide specific handler 87 /// for some type class. VisitType(const Type *)88 RetTy VisitType(const Type*) { return RetTy(); } 89 }; 90 91 #undef DISPATCH 92 93 } // end namespace clang 94 95 #endif 96