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