clang API Documentation

TypeVisitor.h
Go to the documentation of this file.
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