//===-- ASTVisitor.h - Decl, Expr and Stmt Visitor --------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // This file defines the ASTVisitor class, and the DeclVisitor, ExprVisitor, and // StmtVisitor template typedefs. // //===----------------------------------------------------------------------===// #ifndef SWIFT_AST_ASTVISITOR_H #define SWIFT_AST_ASTVISITOR_H #include "swift/AST/Decl.h" #include "swift/AST/Expr.h" #include "swift/AST/Pattern.h" #include "swift/AST/Stmt.h" #include "swift/AST/TypeRepr.h" #include "llvm/Support/ErrorHandling.h" namespace swift { /// ASTVisitor - This is a simple visitor class for Swift expressions. template class ASTVisitor { public: typedef ASTVisitor ASTVisitorType; DeclRetTy visit(Decl *D, Args... AA) { switch (D->getKind()) { #define DECL(CLASS, PARENT) \ case DeclKind::CLASS: \ return static_cast(this) \ ->visit##CLASS##Decl(static_cast(D), \ ::std::forward(AA)...); #include "swift/AST/DeclNodes.def" } llvm_unreachable("Not reachable, all cases handled"); } ExprRetTy visit(Expr *E, Args... AA) { switch (E->getKind()) { #define EXPR(CLASS, PARENT) \ case ExprKind::CLASS: \ return static_cast(this) \ ->visit##CLASS##Expr(static_cast(E), \ ::std::forward(AA)...); #include "swift/AST/ExprNodes.def" } llvm_unreachable("Not reachable, all cases handled"); } // Provide default implementations of abstract "visit" implementations that // just chain to their base class. This allows visitors to just implement // the base behavior and handle all subclasses if they desire. Since this is // a template, it will only instantiate cases that are used and thus we still // require full coverage of the AST nodes by the visitor. #define ABSTRACT_EXPR(CLASS, PARENT) \ ExprRetTy visit##CLASS##Expr(CLASS##Expr *E, Args... AA) { \ return static_cast(this)->visit##PARENT(E, \ ::std::forward(AA)...); \ } #define EXPR(CLASS, PARENT) ABSTRACT_EXPR(CLASS, PARENT) #include "swift/AST/ExprNodes.def" StmtRetTy visit(Stmt *S, Args... AA) { switch (S->getKind()) { #define STMT(CLASS, PARENT) \ case StmtKind::CLASS: \ return static_cast(this) \ ->visit##CLASS##Stmt(static_cast(S), \ ::std::forward(AA)...); #include "swift/AST/StmtNodes.def" } llvm_unreachable("Not reachable, all cases handled"); } DeclRetTy visitDecl(Decl *D, Args... AA) { return DeclRetTy(); } #define DECL(CLASS, PARENT) \ DeclRetTy visit##CLASS##Decl(CLASS##Decl *D, Args... AA) {\ return static_cast(this)->visit##PARENT(D, \ ::std::forward(AA)...); \ } #define ABSTRACT_DECL(CLASS, PARENT) DECL(CLASS, PARENT) #include "swift/AST/DeclNodes.def" PatternRetTy visit(Pattern *P, Args... AA) { switch (P->getKind()) { #define PATTERN(CLASS, PARENT) \ case PatternKind::CLASS: \ return static_cast(this) \ ->visit##CLASS##Pattern(static_cast(P), \ ::std::forward(AA)...); #include "swift/AST/PatternNodes.def" } llvm_unreachable("Not reachable, all cases handled"); } TypeReprRetTy visit(TypeRepr *T, Args... AA) { switch (T->getKind()) { #define TYPEREPR(CLASS, PARENT) \ case TypeReprKind::CLASS: \ return static_cast(this) \ ->visit##CLASS##TypeRepr(static_cast(T), \ ::std::forward(AA)...); #include "swift/AST/TypeReprNodes.def" } llvm_unreachable("Not reachable, all cases handled"); } TypeReprRetTy visitTypeRepr(TypeRepr *T, Args... AA) { return TypeReprRetTy(); } #define TYPEREPR(CLASS, PARENT) \ TypeReprRetTy visit##CLASS##TypeRepr(CLASS##TypeRepr *T, Args... AA) {\ return static_cast(this)->visit##PARENT(T, \ ::std::forward(AA)...); \ } #include "swift/AST/TypeReprNodes.def" }; template using ExprVisitor = ASTVisitor; template using StmtVisitor = ASTVisitor; template using DeclVisitor = ASTVisitor; template using PatternVisitor = ASTVisitor; template using TypeReprVisitor = ASTVisitor; } // end namespace swift #endif