clang API Documentation

StmtVisitor.h
Go to the documentation of this file.
00001 //===--- StmtVisitor.h - Visitor for Stmt 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 StmtVisitor and ConstStmtVisitor interfaces.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_AST_STMTVISITOR_H
00015 #define LLVM_CLANG_AST_STMTVISITOR_H
00016 
00017 #include "clang/AST/ExprCXX.h"
00018 #include "clang/AST/ExprObjC.h"
00019 #include "clang/AST/StmtCXX.h"
00020 #include "clang/AST/StmtObjC.h"
00021 #include "clang/AST/StmtOpenMP.h"
00022 
00023 namespace clang {
00024 
00025 template <typename T> struct make_ptr       { typedef       T *type; };
00026 template <typename T> struct make_const_ptr { typedef const T *type; };
00027 
00028 /// StmtVisitorBase - This class implements a simple visitor for Stmt
00029 /// subclasses. Since Expr derives from Stmt, this also includes support for
00030 /// visiting Exprs.
00031 template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
00032 class StmtVisitorBase {
00033 public:
00034 
00035 #define PTR(CLASS) typename Ptr<CLASS>::type
00036 #define DISPATCH(NAME, CLASS) \
00037  return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S))
00038 
00039   RetTy Visit(PTR(Stmt) S) {
00040 
00041     // If we have a binary expr, dispatch to the subcode of the binop.  A smart
00042     // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
00043     // below.
00044     if (PTR(BinaryOperator) BinOp = dyn_cast<BinaryOperator>(S)) {
00045       switch (BinOp->getOpcode()) {
00046       case BO_PtrMemD:   DISPATCH(BinPtrMemD,   BinaryOperator);
00047       case BO_PtrMemI:   DISPATCH(BinPtrMemI,   BinaryOperator);
00048       case BO_Mul:       DISPATCH(BinMul,       BinaryOperator);
00049       case BO_Div:       DISPATCH(BinDiv,       BinaryOperator);
00050       case BO_Rem:       DISPATCH(BinRem,       BinaryOperator);
00051       case BO_Add:       DISPATCH(BinAdd,       BinaryOperator);
00052       case BO_Sub:       DISPATCH(BinSub,       BinaryOperator);
00053       case BO_Shl:       DISPATCH(BinShl,       BinaryOperator);
00054       case BO_Shr:       DISPATCH(BinShr,       BinaryOperator);
00055 
00056       case BO_LT:        DISPATCH(BinLT,        BinaryOperator);
00057       case BO_GT:        DISPATCH(BinGT,        BinaryOperator);
00058       case BO_LE:        DISPATCH(BinLE,        BinaryOperator);
00059       case BO_GE:        DISPATCH(BinGE,        BinaryOperator);
00060       case BO_EQ:        DISPATCH(BinEQ,        BinaryOperator);
00061       case BO_NE:        DISPATCH(BinNE,        BinaryOperator);
00062 
00063       case BO_And:       DISPATCH(BinAnd,       BinaryOperator);
00064       case BO_Xor:       DISPATCH(BinXor,       BinaryOperator);
00065       case BO_Or :       DISPATCH(BinOr,        BinaryOperator);
00066       case BO_LAnd:      DISPATCH(BinLAnd,      BinaryOperator);
00067       case BO_LOr :      DISPATCH(BinLOr,       BinaryOperator);
00068       case BO_Assign:    DISPATCH(BinAssign,    BinaryOperator);
00069       case BO_MulAssign: DISPATCH(BinMulAssign, CompoundAssignOperator);
00070       case BO_DivAssign: DISPATCH(BinDivAssign, CompoundAssignOperator);
00071       case BO_RemAssign: DISPATCH(BinRemAssign, CompoundAssignOperator);
00072       case BO_AddAssign: DISPATCH(BinAddAssign, CompoundAssignOperator);
00073       case BO_SubAssign: DISPATCH(BinSubAssign, CompoundAssignOperator);
00074       case BO_ShlAssign: DISPATCH(BinShlAssign, CompoundAssignOperator);
00075       case BO_ShrAssign: DISPATCH(BinShrAssign, CompoundAssignOperator);
00076       case BO_AndAssign: DISPATCH(BinAndAssign, CompoundAssignOperator);
00077       case BO_OrAssign:  DISPATCH(BinOrAssign,  CompoundAssignOperator);
00078       case BO_XorAssign: DISPATCH(BinXorAssign, CompoundAssignOperator);
00079       case BO_Comma:     DISPATCH(BinComma,     BinaryOperator);
00080       }
00081     } else if (PTR(UnaryOperator) UnOp = dyn_cast<UnaryOperator>(S)) {
00082       switch (UnOp->getOpcode()) {
00083       case UO_PostInc:   DISPATCH(UnaryPostInc,   UnaryOperator);
00084       case UO_PostDec:   DISPATCH(UnaryPostDec,   UnaryOperator);
00085       case UO_PreInc:    DISPATCH(UnaryPreInc,    UnaryOperator);
00086       case UO_PreDec:    DISPATCH(UnaryPreDec,    UnaryOperator);
00087       case UO_AddrOf:    DISPATCH(UnaryAddrOf,    UnaryOperator);
00088       case UO_Deref:     DISPATCH(UnaryDeref,     UnaryOperator);
00089       case UO_Plus:      DISPATCH(UnaryPlus,      UnaryOperator);
00090       case UO_Minus:     DISPATCH(UnaryMinus,     UnaryOperator);
00091       case UO_Not:       DISPATCH(UnaryNot,       UnaryOperator);
00092       case UO_LNot:      DISPATCH(UnaryLNot,      UnaryOperator);
00093       case UO_Real:      DISPATCH(UnaryReal,      UnaryOperator);
00094       case UO_Imag:      DISPATCH(UnaryImag,      UnaryOperator);
00095       case UO_Extension: DISPATCH(UnaryExtension, UnaryOperator);
00096       }
00097     }
00098 
00099     // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
00100     switch (S->getStmtClass()) {
00101     default: llvm_unreachable("Unknown stmt kind!");
00102 #define ABSTRACT_STMT(STMT)
00103 #define STMT(CLASS, PARENT)                              \
00104     case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
00105 #include "clang/AST/StmtNodes.inc"
00106     }
00107   }
00108 
00109   // If the implementation chooses not to implement a certain visit method, fall
00110   // back on VisitExpr or whatever else is the superclass.
00111 #define STMT(CLASS, PARENT)                                   \
00112   RetTy Visit ## CLASS(PTR(CLASS) S) { DISPATCH(PARENT, PARENT); }
00113 #include "clang/AST/StmtNodes.inc"
00114 
00115   // If the implementation doesn't implement binary operator methods, fall back
00116   // on VisitBinaryOperator.
00117 #define BINOP_FALLBACK(NAME) \
00118   RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \
00119     DISPATCH(BinaryOperator, BinaryOperator); \
00120   }
00121   BINOP_FALLBACK(PtrMemD)                    BINOP_FALLBACK(PtrMemI)
00122   BINOP_FALLBACK(Mul)   BINOP_FALLBACK(Div)  BINOP_FALLBACK(Rem)
00123   BINOP_FALLBACK(Add)   BINOP_FALLBACK(Sub)  BINOP_FALLBACK(Shl)
00124   BINOP_FALLBACK(Shr)
00125 
00126   BINOP_FALLBACK(LT)    BINOP_FALLBACK(GT)   BINOP_FALLBACK(LE)
00127   BINOP_FALLBACK(GE)    BINOP_FALLBACK(EQ)   BINOP_FALLBACK(NE)
00128   BINOP_FALLBACK(And)   BINOP_FALLBACK(Xor)  BINOP_FALLBACK(Or)
00129   BINOP_FALLBACK(LAnd)  BINOP_FALLBACK(LOr)
00130 
00131   BINOP_FALLBACK(Assign)
00132   BINOP_FALLBACK(Comma)
00133 #undef BINOP_FALLBACK
00134 
00135   // If the implementation doesn't implement compound assignment operator
00136   // methods, fall back on VisitCompoundAssignOperator.
00137 #define CAO_FALLBACK(NAME) \
00138   RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \
00139     DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
00140   }
00141   CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
00142   CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign)
00143   CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign)
00144   CAO_FALLBACK(XorAssign)
00145 #undef CAO_FALLBACK
00146 
00147   // If the implementation doesn't implement unary operator methods, fall back
00148   // on VisitUnaryOperator.
00149 #define UNARYOP_FALLBACK(NAME) \
00150   RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \
00151     DISPATCH(UnaryOperator, UnaryOperator);    \
00152   }
00153   UNARYOP_FALLBACK(PostInc)   UNARYOP_FALLBACK(PostDec)
00154   UNARYOP_FALLBACK(PreInc)    UNARYOP_FALLBACK(PreDec)
00155   UNARYOP_FALLBACK(AddrOf)    UNARYOP_FALLBACK(Deref)
00156 
00157   UNARYOP_FALLBACK(Plus)      UNARYOP_FALLBACK(Minus)
00158   UNARYOP_FALLBACK(Not)       UNARYOP_FALLBACK(LNot)
00159   UNARYOP_FALLBACK(Real)      UNARYOP_FALLBACK(Imag)
00160   UNARYOP_FALLBACK(Extension)
00161 #undef UNARYOP_FALLBACK
00162 
00163   // Base case, ignore it. :)
00164   RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); }
00165 
00166 #undef PTR
00167 #undef DISPATCH
00168 };
00169 
00170 /// StmtVisitor - This class implements a simple visitor for Stmt subclasses.
00171 /// Since Expr derives from Stmt, this also includes support for visiting Exprs.
00172 ///
00173 /// This class does not preserve constness of Stmt pointers (see also
00174 /// ConstStmtVisitor).
00175 template<typename ImplClass, typename RetTy=void>
00176 class StmtVisitor
00177  : public StmtVisitorBase<make_ptr, ImplClass, RetTy> {};
00178 
00179 /// ConstStmtVisitor - This class implements a simple visitor for Stmt
00180 /// subclasses. Since Expr derives from Stmt, this also includes support for
00181 /// visiting Exprs.
00182 ///
00183 /// This class preserves constness of Stmt pointers (see also StmtVisitor).
00184 template<typename ImplClass, typename RetTy=void>
00185 class ConstStmtVisitor
00186  : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {};
00187 
00188 /// \brief This class implements a simple visitor for OMPClause
00189 /// subclasses.
00190 template<class ImplClass, template <typename> class Ptr, typename RetTy>
00191 class OMPClauseVisitorBase {
00192 public:
00193 #define PTR(CLASS) typename Ptr<CLASS>::type
00194 #define DISPATCH(CLASS) \
00195   return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S))
00196 
00197 #define OPENMP_CLAUSE(Name, Class)                              \
00198   RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); }
00199 #include "clang/Basic/OpenMPKinds.def"
00200 
00201   RetTy Visit(PTR(OMPClause) S) {
00202     // Top switch clause: visit each OMPClause.
00203     switch (S->getClauseKind()) {
00204     default: llvm_unreachable("Unknown clause kind!");
00205 #define OPENMP_CLAUSE(Name, Class)                              \
00206     case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S));
00207 #include "clang/Basic/OpenMPKinds.def"
00208     }
00209   }
00210   // Base case, ignore it. :)
00211   RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); }
00212 #undef PTR
00213 #undef DISPATCH
00214 };
00215 
00216 template<class ImplClass, typename RetTy = void>
00217 class OMPClauseVisitor :
00218       public OMPClauseVisitorBase <ImplClass, make_ptr, RetTy> {};
00219 template<class ImplClass, typename RetTy = void>
00220 class ConstOMPClauseVisitor :
00221       public OMPClauseVisitorBase <ImplClass, make_const_ptr, RetTy> {};
00222 
00223 }  // end namespace clang
00224 
00225 #endif