Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:46

0001 //===--- TypeVisitor.h - Visitor for Type subclasses ------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines the TypeVisitor interface.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_CLANG_AST_TYPEVISITOR_H
0014 #define LLVM_CLANG_AST_TYPEVISITOR_H
0015 
0016 #include "clang/AST/Type.h"
0017 
0018 namespace clang {
0019 
0020 #define DISPATCH(CLASS) \
0021   return static_cast<ImplClass*>(this)-> \
0022            Visit##CLASS(static_cast<const CLASS*>(T))
0023 
0024 /// An operation on a type.
0025 ///
0026 /// \tparam ImplClass Class implementing the operation. Must be inherited from
0027 ///         TypeVisitor.
0028 /// \tparam RetTy %Type of result produced by the operation.
0029 ///
0030 /// The class implements polymorphic operation on an object of type derived
0031 /// from Type. The operation is performed by calling method Visit. It then
0032 /// dispatches the call to function \c VisitFooType, if actual argument type
0033 /// is \c FooType.
0034 ///
0035 /// The class implements static polymorphism using Curiously Recurring
0036 /// Template Pattern. It is designed to be a base class for some concrete
0037 /// class:
0038 ///
0039 /// \code
0040 ///     class SomeVisitor : public TypeVisitor<SomeVisitor,sometype> { ... };
0041 ///     ...
0042 ///     Type *atype = ...
0043 ///     ...
0044 ///     SomeVisitor avisitor;
0045 ///     sometype result = avisitor.Visit(atype);
0046 /// \endcode
0047 ///
0048 /// Actual treatment is made by methods of the derived class, TypeVisitor only
0049 /// dispatches call to the appropriate method. If the implementation class
0050 /// \c ImplClass provides specific action for some type, say
0051 /// \c ConstantArrayType, it should define method
0052 /// <tt>VisitConstantArrayType(const ConstantArrayType*)</tt>. Otherwise
0053 /// \c TypeVisitor dispatches call to the method that handles parent type. In
0054 /// this example handlers are tried in the sequence:
0055 ///
0056 /// \li <tt>ImplClass::VisitConstantArrayType(const ConstantArrayType*)</tt>
0057 /// \li <tt>ImplClass::VisitArrayType(const ArrayType*)</tt>
0058 /// \li <tt>ImplClass::VisitType(const Type*)</tt>
0059 /// \li <tt>TypeVisitor::VisitType(const Type*)</tt>
0060 ///
0061 /// The first function of this sequence that is defined will handle object of
0062 /// type \c ConstantArrayType.
0063 template<typename ImplClass, typename RetTy=void>
0064 class TypeVisitor {
0065 public:
0066 
0067   /// Performs the operation associated with this visitor object.
0068   RetTy Visit(const Type *T) {
0069     // Top switch stmt: dispatch to VisitFooType for each FooType.
0070     switch (T->getTypeClass()) {
0071 #define ABSTRACT_TYPE(CLASS, PARENT)
0072 #define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type);
0073 #include "clang/AST/TypeNodes.inc"
0074     }
0075     llvm_unreachable("Unknown type class!");
0076   }
0077 
0078   // If the implementation chooses not to implement a certain visit method, fall
0079   // back on superclass.
0080 #define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(const CLASS##Type *T) { \
0081   DISPATCH(PARENT);                                                          \
0082 }
0083 #include "clang/AST/TypeNodes.inc"
0084 
0085   /// Method called if \c ImpClass doesn't provide specific handler
0086   /// for some type class.
0087   RetTy VisitType(const Type*) { return RetTy(); }
0088 };
0089 
0090 #undef DISPATCH
0091 
0092 }  // end namespace clang
0093 
0094 #endif