clang API Documentation
00001 //===--- TypeVisitor.h - Visitor for Type subclasses ------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the TypeVisitor interface. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_AST_TYPEVISITOR_H 00015 #define LLVM_CLANG_AST_TYPEVISITOR_H 00016 00017 #include "clang/AST/Type.h" 00018 00019 namespace clang { 00020 00021 #define DISPATCH(CLASS) \ 00022 return static_cast<ImplClass*>(this)-> \ 00023 Visit##CLASS(static_cast<const CLASS*>(T)) 00024 00025 /// \brief An operation on a type. 00026 /// 00027 /// \tparam ImplClass Class implementing the operation. Must be inherited from 00028 /// TypeVisitor. 00029 /// \tparam RetTy %Type of result produced by the operation. 00030 /// 00031 /// The class implements polymorphic operation on an object of type derived 00032 /// from Type. The operation is performed by calling method Visit. It then 00033 /// dispatches the call to function \c VisitFooType, if actual argument type 00034 /// is \c FooType. 00035 /// 00036 /// The class implements static polymorphism using Curiously Recurring 00037 /// Template Pattern. It is designed to be a base class for some concrete 00038 /// class: 00039 /// 00040 /// \code 00041 /// class SomeVisitor : public TypeVisitor<SomeVisitor,sometype> { ... }; 00042 /// ... 00043 /// Type *atype = ... 00044 /// ... 00045 /// SomeVisitor avisitor; 00046 /// sometype result = avisitor.Visit(atype); 00047 /// \endcode 00048 /// 00049 /// Actual treatment is made by methods of the derived class, TypeVisitor only 00050 /// dispatches call to the appropriate method. If the implementation class 00051 /// \c ImplClass provides specific action for some type, say 00052 /// \c ConstantArrayType, it should define method 00053 /// <tt>VisitConstantArrayType(const ConstantArrayType*)</tt>. Otherwise 00054 /// \c TypeVisitor dispatches call to the method that handles parent type. In 00055 /// this example handlers are tried in the sequence: 00056 /// 00057 /// \li <tt>ImplClass::VisitConstantArrayType(const ConstantArrayType*)</tt> 00058 /// \li <tt>ImplClass::VisitArrayType(const ArrayType*)</tt> 00059 /// \li <tt>ImplClass::VisitType(const Type*)</tt> 00060 /// \li <tt>TypeVisitor::VisitType(const Type*)</tt> 00061 /// 00062 /// The first function of this sequence that is defined will handle object of 00063 /// type \c ConstantArrayType. 00064 template<typename ImplClass, typename RetTy=void> 00065 class TypeVisitor { 00066 public: 00067 00068 /// \brief Performs the operation associated with this visitor object. 00069 RetTy Visit(const Type *T) { 00070 // Top switch stmt: dispatch to VisitFooType for each FooType. 00071 switch (T->getTypeClass()) { 00072 #define ABSTRACT_TYPE(CLASS, PARENT) 00073 #define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type); 00074 #include "clang/AST/TypeNodes.def" 00075 } 00076 llvm_unreachable("Unknown type class!"); 00077 } 00078 00079 // If the implementation chooses not to implement a certain visit method, fall 00080 // back on superclass. 00081 #define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(const CLASS##Type *T) { \ 00082 DISPATCH(PARENT); \ 00083 } 00084 #include "clang/AST/TypeNodes.def" 00085 00086 /// \brief Method called if \c ImpClass doesn't provide specific handler 00087 /// for some type class. 00088 RetTy VisitType(const Type*) { return RetTy(); } 00089 }; 00090 00091 #undef DISPATCH 00092 00093 } // end namespace clang 00094 00095 #endif