1193326Sed//===--- StmtVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10223017Sdim// This file defines the StmtVisitor and ConstStmtVisitor interfaces. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#ifndef LLVM_CLANG_AST_STMTVISITOR_H 15193326Sed#define LLVM_CLANG_AST_STMTVISITOR_H 16193326Sed 17193326Sed#include "clang/AST/ExprCXX.h" 18193326Sed#include "clang/AST/ExprObjC.h" 19193326Sed#include "clang/AST/StmtCXX.h" 20193326Sed#include "clang/AST/StmtObjC.h" 21263508Sdim#include "clang/AST/StmtOpenMP.h" 22193326Sed 23193326Sednamespace clang { 24198092Srdivacky 25223017Sdimtemplate <typename T> struct make_ptr { typedef T *type; }; 26223017Sdimtemplate <typename T> struct make_const_ptr { typedef const T *type; }; 27198092Srdivacky 28223017Sdim/// StmtVisitorBase - This class implements a simple visitor for Stmt 29223017Sdim/// subclasses. Since Expr derives from Stmt, this also includes support for 30223017Sdim/// visiting Exprs. 31223017Sdimtemplate<template <typename> class Ptr, typename ImplClass, typename RetTy=void> 32223017Sdimclass StmtVisitorBase { 33193326Sedpublic: 34198092Srdivacky 35223017Sdim#define PTR(CLASS) typename Ptr<CLASS>::type 36223017Sdim#define DISPATCH(NAME, CLASS) \ 37223017Sdim return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S)) 38223017Sdim 39223017Sdim RetTy Visit(PTR(Stmt) S) { 40223017Sdim 41193326Sed // If we have a binary expr, dispatch to the subcode of the binop. A smart 42193326Sed // optimizer (e.g. LLVM) will fold this comparison into the switch stmt 43193326Sed // below. 44223017Sdim if (PTR(BinaryOperator) BinOp = dyn_cast<BinaryOperator>(S)) { 45193326Sed switch (BinOp->getOpcode()) { 46212904Sdim case BO_PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator); 47212904Sdim case BO_PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator); 48212904Sdim case BO_Mul: DISPATCH(BinMul, BinaryOperator); 49212904Sdim case BO_Div: DISPATCH(BinDiv, BinaryOperator); 50212904Sdim case BO_Rem: DISPATCH(BinRem, BinaryOperator); 51212904Sdim case BO_Add: DISPATCH(BinAdd, BinaryOperator); 52212904Sdim case BO_Sub: DISPATCH(BinSub, BinaryOperator); 53212904Sdim case BO_Shl: DISPATCH(BinShl, BinaryOperator); 54212904Sdim case BO_Shr: DISPATCH(BinShr, BinaryOperator); 55193326Sed 56212904Sdim case BO_LT: DISPATCH(BinLT, BinaryOperator); 57212904Sdim case BO_GT: DISPATCH(BinGT, BinaryOperator); 58212904Sdim case BO_LE: DISPATCH(BinLE, BinaryOperator); 59212904Sdim case BO_GE: DISPATCH(BinGE, BinaryOperator); 60212904Sdim case BO_EQ: DISPATCH(BinEQ, BinaryOperator); 61212904Sdim case BO_NE: DISPATCH(BinNE, BinaryOperator); 62198092Srdivacky 63212904Sdim case BO_And: DISPATCH(BinAnd, BinaryOperator); 64212904Sdim case BO_Xor: DISPATCH(BinXor, BinaryOperator); 65212904Sdim case BO_Or : DISPATCH(BinOr, BinaryOperator); 66212904Sdim case BO_LAnd: DISPATCH(BinLAnd, BinaryOperator); 67212904Sdim case BO_LOr : DISPATCH(BinLOr, BinaryOperator); 68212904Sdim case BO_Assign: DISPATCH(BinAssign, BinaryOperator); 69212904Sdim case BO_MulAssign: DISPATCH(BinMulAssign, CompoundAssignOperator); 70212904Sdim case BO_DivAssign: DISPATCH(BinDivAssign, CompoundAssignOperator); 71212904Sdim case BO_RemAssign: DISPATCH(BinRemAssign, CompoundAssignOperator); 72212904Sdim case BO_AddAssign: DISPATCH(BinAddAssign, CompoundAssignOperator); 73212904Sdim case BO_SubAssign: DISPATCH(BinSubAssign, CompoundAssignOperator); 74212904Sdim case BO_ShlAssign: DISPATCH(BinShlAssign, CompoundAssignOperator); 75212904Sdim case BO_ShrAssign: DISPATCH(BinShrAssign, CompoundAssignOperator); 76212904Sdim case BO_AndAssign: DISPATCH(BinAndAssign, CompoundAssignOperator); 77212904Sdim case BO_OrAssign: DISPATCH(BinOrAssign, CompoundAssignOperator); 78212904Sdim case BO_XorAssign: DISPATCH(BinXorAssign, CompoundAssignOperator); 79212904Sdim case BO_Comma: DISPATCH(BinComma, BinaryOperator); 80193326Sed } 81223017Sdim } else if (PTR(UnaryOperator) UnOp = dyn_cast<UnaryOperator>(S)) { 82193326Sed switch (UnOp->getOpcode()) { 83212904Sdim case UO_PostInc: DISPATCH(UnaryPostInc, UnaryOperator); 84212904Sdim case UO_PostDec: DISPATCH(UnaryPostDec, UnaryOperator); 85212904Sdim case UO_PreInc: DISPATCH(UnaryPreInc, UnaryOperator); 86212904Sdim case UO_PreDec: DISPATCH(UnaryPreDec, UnaryOperator); 87212904Sdim case UO_AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator); 88212904Sdim case UO_Deref: DISPATCH(UnaryDeref, UnaryOperator); 89212904Sdim case UO_Plus: DISPATCH(UnaryPlus, UnaryOperator); 90212904Sdim case UO_Minus: DISPATCH(UnaryMinus, UnaryOperator); 91212904Sdim case UO_Not: DISPATCH(UnaryNot, UnaryOperator); 92212904Sdim case UO_LNot: DISPATCH(UnaryLNot, UnaryOperator); 93212904Sdim case UO_Real: DISPATCH(UnaryReal, UnaryOperator); 94212904Sdim case UO_Imag: DISPATCH(UnaryImag, UnaryOperator); 95212904Sdim case UO_Extension: DISPATCH(UnaryExtension, UnaryOperator); 96193326Sed } 97193326Sed } 98198092Srdivacky 99193326Sed // Top switch stmt: dispatch to VisitFooStmt for each FooStmt. 100193326Sed switch (S->getStmtClass()) { 101226633Sdim default: llvm_unreachable("Unknown stmt kind!"); 102208600Srdivacky#define ABSTRACT_STMT(STMT) 103193326Sed#define STMT(CLASS, PARENT) \ 104193326Sed case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS); 105208600Srdivacky#include "clang/AST/StmtNodes.inc" 106193326Sed } 107193326Sed } 108198092Srdivacky 109193326Sed // If the implementation chooses not to implement a certain visit method, fall 110193326Sed // back on VisitExpr or whatever else is the superclass. 111193326Sed#define STMT(CLASS, PARENT) \ 112223017Sdim RetTy Visit ## CLASS(PTR(CLASS) S) { DISPATCH(PARENT, PARENT); } 113208600Srdivacky#include "clang/AST/StmtNodes.inc" 114193326Sed 115193326Sed // If the implementation doesn't implement binary operator methods, fall back 116193326Sed // on VisitBinaryOperator. 117193326Sed#define BINOP_FALLBACK(NAME) \ 118223017Sdim RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \ 119193326Sed DISPATCH(BinaryOperator, BinaryOperator); \ 120193326Sed } 121193326Sed BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI) 122193326Sed BINOP_FALLBACK(Mul) BINOP_FALLBACK(Div) BINOP_FALLBACK(Rem) 123193326Sed BINOP_FALLBACK(Add) BINOP_FALLBACK(Sub) BINOP_FALLBACK(Shl) 124193326Sed BINOP_FALLBACK(Shr) 125198092Srdivacky 126193326Sed BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE) 127193326Sed BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE) 128193326Sed BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or) 129193326Sed BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr) 130193326Sed 131193326Sed BINOP_FALLBACK(Assign) 132193326Sed BINOP_FALLBACK(Comma) 133193326Sed#undef BINOP_FALLBACK 134193326Sed 135193326Sed // If the implementation doesn't implement compound assignment operator 136193326Sed // methods, fall back on VisitCompoundAssignOperator. 137193326Sed#define CAO_FALLBACK(NAME) \ 138223017Sdim RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \ 139193326Sed DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \ 140193326Sed } 141193326Sed CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign) 142193326Sed CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign) 143193326Sed CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign) 144193326Sed CAO_FALLBACK(XorAssign) 145193326Sed#undef CAO_FALLBACK 146198092Srdivacky 147193326Sed // If the implementation doesn't implement unary operator methods, fall back 148193326Sed // on VisitUnaryOperator. 149193326Sed#define UNARYOP_FALLBACK(NAME) \ 150223017Sdim RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \ 151193326Sed DISPATCH(UnaryOperator, UnaryOperator); \ 152193326Sed } 153193326Sed UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec) 154193326Sed UNARYOP_FALLBACK(PreInc) UNARYOP_FALLBACK(PreDec) 155193326Sed UNARYOP_FALLBACK(AddrOf) UNARYOP_FALLBACK(Deref) 156198092Srdivacky 157193326Sed UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus) 158193326Sed UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot) 159193326Sed UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag) 160212904Sdim UNARYOP_FALLBACK(Extension) 161193326Sed#undef UNARYOP_FALLBACK 162198092Srdivacky 163193326Sed // Base case, ignore it. :) 164223017Sdim RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); } 165193326Sed 166223017Sdim#undef PTR 167193326Sed#undef DISPATCH 168223017Sdim}; 169193326Sed 170223017Sdim/// StmtVisitor - This class implements a simple visitor for Stmt subclasses. 171223017Sdim/// Since Expr derives from Stmt, this also includes support for visiting Exprs. 172223017Sdim/// 173223017Sdim/// This class does not preserve constness of Stmt pointers (see also 174223017Sdim/// ConstStmtVisitor). 175223017Sdimtemplate<typename ImplClass, typename RetTy=void> 176223017Sdimclass StmtVisitor 177223017Sdim : public StmtVisitorBase<make_ptr, ImplClass, RetTy> {}; 178223017Sdim 179223017Sdim/// ConstStmtVisitor - This class implements a simple visitor for Stmt 180223017Sdim/// subclasses. Since Expr derives from Stmt, this also includes support for 181223017Sdim/// visiting Exprs. 182223017Sdim/// 183223017Sdim/// This class preserves constness of Stmt pointers (see also StmtVisitor). 184223017Sdimtemplate<typename ImplClass, typename RetTy=void> 185223017Sdimclass ConstStmtVisitor 186223017Sdim : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {}; 187223017Sdim 188263508Sdim/// \brief This class implements a simple visitor for OMPClause 189263508Sdim/// subclasses. 190263508Sdimtemplate<class ImplClass, template <typename> class Ptr, typename RetTy> 191263508Sdimclass OMPClauseVisitorBase { 192263508Sdimpublic: 193263508Sdim#define PTR(CLASS) typename Ptr<CLASS>::type 194263508Sdim#define DISPATCH(CLASS) \ 195263508Sdim return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S)) 196263508Sdim 197263508Sdim#define OPENMP_CLAUSE(Name, Class) \ 198263508Sdim RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); } 199263508Sdim#include "clang/Basic/OpenMPKinds.def" 200263508Sdim 201263508Sdim RetTy Visit(PTR(OMPClause) S) { 202263508Sdim // Top switch clause: visit each OMPClause. 203263508Sdim switch (S->getClauseKind()) { 204263508Sdim default: llvm_unreachable("Unknown clause kind!"); 205263508Sdim#define OPENMP_CLAUSE(Name, Class) \ 206263508Sdim case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S)); 207263508Sdim#include "clang/Basic/OpenMPKinds.def" 208263508Sdim } 209263508Sdim } 210263508Sdim // Base case, ignore it. :) 211263508Sdim RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); } 212263508Sdim#undef PTR 213263508Sdim#undef DISPATCH 214263508Sdim}; 215263508Sdim 216263508Sdimtemplate<class ImplClass, typename RetTy = void> 217263508Sdimclass OMPClauseVisitor : 218263508Sdim public OMPClauseVisitorBase <ImplClass, make_ptr, RetTy> {}; 219263508Sdimtemplate<class ImplClass, typename RetTy = void> 220263508Sdimclass ConstOMPClauseVisitor : 221263508Sdim public OMPClauseVisitorBase <ImplClass, make_const_ptr, RetTy> {}; 222263508Sdim 223193326Sed} // end namespace clang 224193326Sed 225193326Sed#endif 226