174d4031b9a7dbb6204c4f97062d44bd26e21b014Nick Lewycky//===--- TypeVisitor.h - Visitor for Type subclasses ------------*- C++ -*-===// 2038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor// 3038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor// The LLVM Compiler Infrastructure 4038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor// 5038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor// This file is distributed under the University of Illinois Open Source 6038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor// License. See LICENSE.TXT for details. 7038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor// 8038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor//===----------------------------------------------------------------------===// 9038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor// 10038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor// This file defines the TypeVisitor interface. 11038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor// 12038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor//===----------------------------------------------------------------------===// 13038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor 14038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor#ifndef LLVM_CLANG_AST_TYPEVISITOR_H 15038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor#define LLVM_CLANG_AST_TYPEVISITOR_H 16038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor 17038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor#include "clang/AST/Type.h" 18038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor 19038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregornamespace clang { 201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor#define DISPATCH(CLASS) \ 22f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall return static_cast<ImplClass*>(this)-> \ 23f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall Visit##CLASS(static_cast<const CLASS*>(T)) 241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2534bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// \brief An operation on a type. 2634bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// 27c1d73fe9f44d302951f81b06271647c227c2a3e8Benjamin Kramer/// \tparam ImplClass Class implementing the operation. Must be inherited from 2834bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// TypeVisitor. 2934bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// \tparam RetTy %Type of result produced by the operation. 3034bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// 3134bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// The class implements polymorphic operation on an object of type derived 3234bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// from Type. The operation is performed by calling method Visit. It then 3334bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// dispatches the call to function \c VisitFooType, if actual argument type 3434bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// is \c FooType. 3534bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// 3634bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// The class implements static polymorphism using Curiously Recurring 3734bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// Template Pattern. It is designed to be a base class for some concrete 3834bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// class: 3934bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// 4034bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// \code 41da8d379f1e58af98640c2df222ec0161ff913941Serge Pavlov/// class SomeVisitor : public TypeVisitor<SomeVisitor,sometype> { ... }; 4234bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// ... 4334bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// Type *atype = ... 4434bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// ... 4534bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// SomeVisitor avisitor; 4634bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// sometype result = avisitor.Visit(atype); 4734bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// \endcode 4834bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// 4934bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// Actual treatment is made by methods of the derived class, TypeVisitor only 5034bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// dispatches call to the appropriate method. If the implementation class 51c1d73fe9f44d302951f81b06271647c227c2a3e8Benjamin Kramer/// \c ImplClass provides specific action for some type, say 5234bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// \c ConstantArrayType, it should define method 5334bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// <tt>VisitConstantArrayType(const ConstantArrayType*)</tt>. Otherwise 5434bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// \c TypeVisitor dispatches call to the method that handles parent type. In 5534bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// this example handlers are tried in the sequence: 5634bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// 57c1d73fe9f44d302951f81b06271647c227c2a3e8Benjamin Kramer/// \li <tt>ImplClass::VisitConstantArrayType(const ConstantArrayType*)</tt> 58c1d73fe9f44d302951f81b06271647c227c2a3e8Benjamin Kramer/// \li <tt>ImplClass::VisitArrayType(const ArrayType*)</tt> 59c1d73fe9f44d302951f81b06271647c227c2a3e8Benjamin Kramer/// \li <tt>ImplClass::VisitType(const Type*)</tt> 6034bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// \li <tt>TypeVisitor::VisitType(const Type*)</tt> 6134bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// 6234bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// The first function of this sequence that is defined will handle object of 6334bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov/// type \c ConstantArrayType. 64038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregortemplate<typename ImplClass, typename RetTy=void> 65038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregorclass TypeVisitor { 66038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregorpublic: 6734bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov 6834bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov /// \brief Performs the operation associated with this visitor object. 69f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall RetTy Visit(const Type *T) { 7074d4031b9a7dbb6204c4f97062d44bd26e21b014Nick Lewycky // Top switch stmt: dispatch to VisitFooType for each FooType. 71038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor switch (T->getTypeClass()) { 721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#define ABSTRACT_TYPE(CLASS, PARENT) 73038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor#define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type); 74038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor#include "clang/AST/TypeNodes.def" 75038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor } 76561d3abc881033776ece385a01a510e1cbc1fa92David Blaikie llvm_unreachable("Unknown type class!"); 77038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor } 781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 79038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor // If the implementation chooses not to implement a certain visit method, fall 80038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor // back on superclass. 81f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall#define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(const CLASS##Type *T) { \ 8278b89b0ef7f3803cd31df3656f9536bfd6f0dd48Douglas Gregor DISPATCH(PARENT); \ 8378b89b0ef7f3803cd31df3656f9536bfd6f0dd48Douglas Gregor} 84038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor#include "clang/AST/TypeNodes.def" 85038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor 8634bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov /// \brief Method called if \c ImpClass doesn't provide specific handler 8734bd3bf4996cf0941e3cdfde07d97f6b3d54070dSerge Pavlov /// for some type class. 88f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall RetTy VisitType(const Type*) { return RetTy(); } 89038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor}; 90038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor 91038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor#undef DISPATCH 92038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor 93038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor} // end namespace clang 94038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor 95038f75abf5abd1e35736dd5c751ba20df1158aaaDouglas Gregor#endif 96