StmtVisitor.h 8.9 KB

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