TypeVisitor.h revision da8d379f1e58af98640c2df222ec0161ff913941
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
19namespace 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 ImpClass 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 ImpClass 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>ImpClass::VisitConstantArrayType(const ConstantArrayType*)</tt>
58/// \li <tt>ImpClass::VisitArrayType(const ArrayType*)</tt>
59/// \li <tt>ImpClass::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.
64template<typename ImplClass, typename RetTy=void>
65class TypeVisitor {
66public:
67
68  /// \brief Performs the operation associated with this visitor object.
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.
88  RetTy VisitType(const Type*) { return RetTy(); }
89};
90
91#undef DISPATCH
92
93}  // end namespace clang
94
95#endif
96