1*f4a2713aSLionel Sambuc //===--- StmtVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc // 10*f4a2713aSLionel Sambuc // This file defines the StmtVisitor and ConstStmtVisitor interfaces. 11*f4a2713aSLionel Sambuc // 12*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 13*f4a2713aSLionel Sambuc 14*f4a2713aSLionel Sambuc #ifndef LLVM_CLANG_AST_STMTVISITOR_H 15*f4a2713aSLionel Sambuc #define LLVM_CLANG_AST_STMTVISITOR_H 16*f4a2713aSLionel Sambuc 17*f4a2713aSLionel Sambuc #include "clang/AST/ExprCXX.h" 18*f4a2713aSLionel Sambuc #include "clang/AST/ExprObjC.h" 19*f4a2713aSLionel Sambuc #include "clang/AST/StmtCXX.h" 20*f4a2713aSLionel Sambuc #include "clang/AST/StmtObjC.h" 21*f4a2713aSLionel Sambuc #include "clang/AST/StmtOpenMP.h" 22*f4a2713aSLionel Sambuc 23*f4a2713aSLionel Sambuc namespace clang { 24*f4a2713aSLionel Sambuc 25*f4a2713aSLionel Sambuc template <typename T> struct make_ptr { typedef T *type; }; 26*f4a2713aSLionel Sambuc template <typename T> struct make_const_ptr { typedef const T *type; }; 27*f4a2713aSLionel Sambuc 28*f4a2713aSLionel Sambuc /// StmtVisitorBase - This class implements a simple visitor for Stmt 29*f4a2713aSLionel Sambuc /// subclasses. Since Expr derives from Stmt, this also includes support for 30*f4a2713aSLionel Sambuc /// visiting Exprs. 31*f4a2713aSLionel Sambuc template<template <typename> class Ptr, typename ImplClass, typename RetTy=void> 32*f4a2713aSLionel Sambuc class StmtVisitorBase { 33*f4a2713aSLionel Sambuc public: 34*f4a2713aSLionel Sambuc 35*f4a2713aSLionel Sambuc #define PTR(CLASS) typename Ptr<CLASS>::type 36*f4a2713aSLionel Sambuc #define DISPATCH(NAME, CLASS) \ 37*f4a2713aSLionel Sambuc return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S)) 38*f4a2713aSLionel Sambuc Visit(PTR (Stmt)S)39*f4a2713aSLionel Sambuc RetTy Visit(PTR(Stmt) S) { 40*f4a2713aSLionel Sambuc 41*f4a2713aSLionel Sambuc // If we have a binary expr, dispatch to the subcode of the binop. A smart 42*f4a2713aSLionel Sambuc // optimizer (e.g. LLVM) will fold this comparison into the switch stmt 43*f4a2713aSLionel Sambuc // below. 44*f4a2713aSLionel Sambuc if (PTR(BinaryOperator) BinOp = dyn_cast<BinaryOperator>(S)) { 45*f4a2713aSLionel Sambuc switch (BinOp->getOpcode()) { 46*f4a2713aSLionel Sambuc case BO_PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator); 47*f4a2713aSLionel Sambuc case BO_PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator); 48*f4a2713aSLionel Sambuc case BO_Mul: DISPATCH(BinMul, BinaryOperator); 49*f4a2713aSLionel Sambuc case BO_Div: DISPATCH(BinDiv, BinaryOperator); 50*f4a2713aSLionel Sambuc case BO_Rem: DISPATCH(BinRem, BinaryOperator); 51*f4a2713aSLionel Sambuc case BO_Add: DISPATCH(BinAdd, BinaryOperator); 52*f4a2713aSLionel Sambuc case BO_Sub: DISPATCH(BinSub, BinaryOperator); 53*f4a2713aSLionel Sambuc case BO_Shl: DISPATCH(BinShl, BinaryOperator); 54*f4a2713aSLionel Sambuc case BO_Shr: DISPATCH(BinShr, BinaryOperator); 55*f4a2713aSLionel Sambuc 56*f4a2713aSLionel Sambuc case BO_LT: DISPATCH(BinLT, BinaryOperator); 57*f4a2713aSLionel Sambuc case BO_GT: DISPATCH(BinGT, BinaryOperator); 58*f4a2713aSLionel Sambuc case BO_LE: DISPATCH(BinLE, BinaryOperator); 59*f4a2713aSLionel Sambuc case BO_GE: DISPATCH(BinGE, BinaryOperator); 60*f4a2713aSLionel Sambuc case BO_EQ: DISPATCH(BinEQ, BinaryOperator); 61*f4a2713aSLionel Sambuc case BO_NE: DISPATCH(BinNE, BinaryOperator); 62*f4a2713aSLionel Sambuc 63*f4a2713aSLionel Sambuc case BO_And: DISPATCH(BinAnd, BinaryOperator); 64*f4a2713aSLionel Sambuc case BO_Xor: DISPATCH(BinXor, BinaryOperator); 65*f4a2713aSLionel Sambuc case BO_Or : DISPATCH(BinOr, BinaryOperator); 66*f4a2713aSLionel Sambuc case BO_LAnd: DISPATCH(BinLAnd, BinaryOperator); 67*f4a2713aSLionel Sambuc case BO_LOr : DISPATCH(BinLOr, BinaryOperator); 68*f4a2713aSLionel Sambuc case BO_Assign: DISPATCH(BinAssign, BinaryOperator); 69*f4a2713aSLionel Sambuc case BO_MulAssign: DISPATCH(BinMulAssign, CompoundAssignOperator); 70*f4a2713aSLionel Sambuc case BO_DivAssign: DISPATCH(BinDivAssign, CompoundAssignOperator); 71*f4a2713aSLionel Sambuc case BO_RemAssign: DISPATCH(BinRemAssign, CompoundAssignOperator); 72*f4a2713aSLionel Sambuc case BO_AddAssign: DISPATCH(BinAddAssign, CompoundAssignOperator); 73*f4a2713aSLionel Sambuc case BO_SubAssign: DISPATCH(BinSubAssign, CompoundAssignOperator); 74*f4a2713aSLionel Sambuc case BO_ShlAssign: DISPATCH(BinShlAssign, CompoundAssignOperator); 75*f4a2713aSLionel Sambuc case BO_ShrAssign: DISPATCH(BinShrAssign, CompoundAssignOperator); 76*f4a2713aSLionel Sambuc case BO_AndAssign: DISPATCH(BinAndAssign, CompoundAssignOperator); 77*f4a2713aSLionel Sambuc case BO_OrAssign: DISPATCH(BinOrAssign, CompoundAssignOperator); 78*f4a2713aSLionel Sambuc case BO_XorAssign: DISPATCH(BinXorAssign, CompoundAssignOperator); 79*f4a2713aSLionel Sambuc case BO_Comma: DISPATCH(BinComma, BinaryOperator); 80*f4a2713aSLionel Sambuc } 81*f4a2713aSLionel Sambuc } else if (PTR(UnaryOperator) UnOp = dyn_cast<UnaryOperator>(S)) { 82*f4a2713aSLionel Sambuc switch (UnOp->getOpcode()) { 83*f4a2713aSLionel Sambuc case UO_PostInc: DISPATCH(UnaryPostInc, UnaryOperator); 84*f4a2713aSLionel Sambuc case UO_PostDec: DISPATCH(UnaryPostDec, UnaryOperator); 85*f4a2713aSLionel Sambuc case UO_PreInc: DISPATCH(UnaryPreInc, UnaryOperator); 86*f4a2713aSLionel Sambuc case UO_PreDec: DISPATCH(UnaryPreDec, UnaryOperator); 87*f4a2713aSLionel Sambuc case UO_AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator); 88*f4a2713aSLionel Sambuc case UO_Deref: DISPATCH(UnaryDeref, UnaryOperator); 89*f4a2713aSLionel Sambuc case UO_Plus: DISPATCH(UnaryPlus, UnaryOperator); 90*f4a2713aSLionel Sambuc case UO_Minus: DISPATCH(UnaryMinus, UnaryOperator); 91*f4a2713aSLionel Sambuc case UO_Not: DISPATCH(UnaryNot, UnaryOperator); 92*f4a2713aSLionel Sambuc case UO_LNot: DISPATCH(UnaryLNot, UnaryOperator); 93*f4a2713aSLionel Sambuc case UO_Real: DISPATCH(UnaryReal, UnaryOperator); 94*f4a2713aSLionel Sambuc case UO_Imag: DISPATCH(UnaryImag, UnaryOperator); 95*f4a2713aSLionel Sambuc case UO_Extension: DISPATCH(UnaryExtension, UnaryOperator); 96*f4a2713aSLionel Sambuc } 97*f4a2713aSLionel Sambuc } 98*f4a2713aSLionel Sambuc 99*f4a2713aSLionel Sambuc // Top switch stmt: dispatch to VisitFooStmt for each FooStmt. 100*f4a2713aSLionel Sambuc switch (S->getStmtClass()) { 101*f4a2713aSLionel Sambuc default: llvm_unreachable("Unknown stmt kind!"); 102*f4a2713aSLionel Sambuc #define ABSTRACT_STMT(STMT) 103*f4a2713aSLionel Sambuc #define STMT(CLASS, PARENT) \ 104*f4a2713aSLionel Sambuc case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS); 105*f4a2713aSLionel Sambuc #include "clang/AST/StmtNodes.inc" 106*f4a2713aSLionel Sambuc } 107*f4a2713aSLionel Sambuc } 108*f4a2713aSLionel Sambuc 109*f4a2713aSLionel Sambuc // If the implementation chooses not to implement a certain visit method, fall 110*f4a2713aSLionel Sambuc // back on VisitExpr or whatever else is the superclass. 111*f4a2713aSLionel Sambuc #define STMT(CLASS, PARENT) \ 112*f4a2713aSLionel Sambuc RetTy Visit ## CLASS(PTR(CLASS) S) { DISPATCH(PARENT, PARENT); } 113*f4a2713aSLionel Sambuc #include "clang/AST/StmtNodes.inc" 114*f4a2713aSLionel Sambuc 115*f4a2713aSLionel Sambuc // If the implementation doesn't implement binary operator methods, fall back 116*f4a2713aSLionel Sambuc // on VisitBinaryOperator. 117*f4a2713aSLionel Sambuc #define BINOP_FALLBACK(NAME) \ 118*f4a2713aSLionel Sambuc RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \ 119*f4a2713aSLionel Sambuc DISPATCH(BinaryOperator, BinaryOperator); \ 120*f4a2713aSLionel Sambuc } BINOP_FALLBACK(PtrMemI)121*f4a2713aSLionel Sambuc BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI) 122*f4a2713aSLionel Sambuc BINOP_FALLBACK(Mul) BINOP_FALLBACK(Div) BINOP_FALLBACK(Rem) 123*f4a2713aSLionel Sambuc BINOP_FALLBACK(Add) BINOP_FALLBACK(Sub) BINOP_FALLBACK(Shl) 124*f4a2713aSLionel Sambuc BINOP_FALLBACK(Shr) 125*f4a2713aSLionel Sambuc 126*f4a2713aSLionel Sambuc BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE) 127*f4a2713aSLionel Sambuc BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE) 128*f4a2713aSLionel Sambuc BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or) 129*f4a2713aSLionel Sambuc BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr) 130*f4a2713aSLionel Sambuc 131*f4a2713aSLionel Sambuc BINOP_FALLBACK(Assign) 132*f4a2713aSLionel Sambuc BINOP_FALLBACK(Comma) 133*f4a2713aSLionel Sambuc #undef BINOP_FALLBACK 134*f4a2713aSLionel Sambuc 135*f4a2713aSLionel Sambuc // If the implementation doesn't implement compound assignment operator 136*f4a2713aSLionel Sambuc // methods, fall back on VisitCompoundAssignOperator. 137*f4a2713aSLionel Sambuc #define CAO_FALLBACK(NAME) \ 138*f4a2713aSLionel Sambuc RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \ 139*f4a2713aSLionel Sambuc DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \ 140*f4a2713aSLionel Sambuc } 141*f4a2713aSLionel Sambuc CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign) 142*f4a2713aSLionel Sambuc CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign) 143*f4a2713aSLionel Sambuc CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign) 144*f4a2713aSLionel Sambuc CAO_FALLBACK(XorAssign) 145*f4a2713aSLionel Sambuc #undef CAO_FALLBACK 146*f4a2713aSLionel Sambuc 147*f4a2713aSLionel Sambuc // If the implementation doesn't implement unary operator methods, fall back 148*f4a2713aSLionel Sambuc // on VisitUnaryOperator. 149*f4a2713aSLionel Sambuc #define UNARYOP_FALLBACK(NAME) \ 150*f4a2713aSLionel Sambuc RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \ 151*f4a2713aSLionel Sambuc DISPATCH(UnaryOperator, UnaryOperator); \ 152*f4a2713aSLionel Sambuc } 153*f4a2713aSLionel Sambuc UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec) 154*f4a2713aSLionel Sambuc UNARYOP_FALLBACK(PreInc) UNARYOP_FALLBACK(PreDec) 155*f4a2713aSLionel Sambuc UNARYOP_FALLBACK(AddrOf) UNARYOP_FALLBACK(Deref) 156*f4a2713aSLionel Sambuc 157*f4a2713aSLionel Sambuc UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus) 158*f4a2713aSLionel Sambuc UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot) 159*f4a2713aSLionel Sambuc UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag) 160*f4a2713aSLionel Sambuc UNARYOP_FALLBACK(Extension) 161*f4a2713aSLionel Sambuc #undef UNARYOP_FALLBACK 162*f4a2713aSLionel Sambuc 163*f4a2713aSLionel Sambuc // Base case, ignore it. :) 164*f4a2713aSLionel Sambuc RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); } 165*f4a2713aSLionel Sambuc 166*f4a2713aSLionel Sambuc #undef PTR 167*f4a2713aSLionel Sambuc #undef DISPATCH 168*f4a2713aSLionel Sambuc }; 169*f4a2713aSLionel Sambuc 170*f4a2713aSLionel Sambuc /// StmtVisitor - This class implements a simple visitor for Stmt subclasses. 171*f4a2713aSLionel Sambuc /// Since Expr derives from Stmt, this also includes support for visiting Exprs. 172*f4a2713aSLionel Sambuc /// 173*f4a2713aSLionel Sambuc /// This class does not preserve constness of Stmt pointers (see also 174*f4a2713aSLionel Sambuc /// ConstStmtVisitor). 175*f4a2713aSLionel Sambuc template<typename ImplClass, typename RetTy=void> 176*f4a2713aSLionel Sambuc class StmtVisitor 177*f4a2713aSLionel Sambuc : public StmtVisitorBase<make_ptr, ImplClass, RetTy> {}; 178*f4a2713aSLionel Sambuc 179*f4a2713aSLionel Sambuc /// ConstStmtVisitor - This class implements a simple visitor for Stmt 180*f4a2713aSLionel Sambuc /// subclasses. Since Expr derives from Stmt, this also includes support for 181*f4a2713aSLionel Sambuc /// visiting Exprs. 182*f4a2713aSLionel Sambuc /// 183*f4a2713aSLionel Sambuc /// This class preserves constness of Stmt pointers (see also StmtVisitor). 184*f4a2713aSLionel Sambuc template<typename ImplClass, typename RetTy=void> 185*f4a2713aSLionel Sambuc class ConstStmtVisitor 186*f4a2713aSLionel Sambuc : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {}; 187*f4a2713aSLionel Sambuc 188*f4a2713aSLionel Sambuc /// \brief This class implements a simple visitor for OMPClause 189*f4a2713aSLionel Sambuc /// subclasses. 190*f4a2713aSLionel Sambuc template<class ImplClass, template <typename> class Ptr, typename RetTy> 191*f4a2713aSLionel Sambuc class OMPClauseVisitorBase { 192*f4a2713aSLionel Sambuc public: 193*f4a2713aSLionel Sambuc #define PTR(CLASS) typename Ptr<CLASS>::type 194*f4a2713aSLionel Sambuc #define DISPATCH(CLASS) \ 195*f4a2713aSLionel Sambuc return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S)) 196*f4a2713aSLionel Sambuc 197*f4a2713aSLionel Sambuc #define OPENMP_CLAUSE(Name, Class) \ 198*f4a2713aSLionel Sambuc RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); } 199*f4a2713aSLionel Sambuc #include "clang/Basic/OpenMPKinds.def" 200*f4a2713aSLionel Sambuc Visit(PTR (OMPClause)S)201*f4a2713aSLionel Sambuc RetTy Visit(PTR(OMPClause) S) { 202*f4a2713aSLionel Sambuc // Top switch clause: visit each OMPClause. 203*f4a2713aSLionel Sambuc switch (S->getClauseKind()) { 204*f4a2713aSLionel Sambuc default: llvm_unreachable("Unknown clause kind!"); 205*f4a2713aSLionel Sambuc #define OPENMP_CLAUSE(Name, Class) \ 206*f4a2713aSLionel Sambuc case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S)); 207*f4a2713aSLionel Sambuc #include "clang/Basic/OpenMPKinds.def" 208*f4a2713aSLionel Sambuc } 209*f4a2713aSLionel Sambuc } 210*f4a2713aSLionel Sambuc // Base case, ignore it. :) VisitOMPClause(PTR (OMPClause)Node)211*f4a2713aSLionel Sambuc RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); } 212*f4a2713aSLionel Sambuc #undef PTR 213*f4a2713aSLionel Sambuc #undef DISPATCH 214*f4a2713aSLionel Sambuc }; 215*f4a2713aSLionel Sambuc 216*f4a2713aSLionel Sambuc template<class ImplClass, typename RetTy = void> 217*f4a2713aSLionel Sambuc class OMPClauseVisitor : 218*f4a2713aSLionel Sambuc public OMPClauseVisitorBase <ImplClass, make_ptr, RetTy> {}; 219*f4a2713aSLionel Sambuc template<class ImplClass, typename RetTy = void> 220*f4a2713aSLionel Sambuc class ConstOMPClauseVisitor : 221*f4a2713aSLionel Sambuc public OMPClauseVisitorBase <ImplClass, make_const_ptr, RetTy> {}; 222*f4a2713aSLionel Sambuc 223*f4a2713aSLionel Sambuc } // end namespace clang 224*f4a2713aSLionel Sambuc 225*f4a2713aSLionel Sambuc #endif 226