EvaluatedExprVisitor.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- EvaluatedExprVisitor.h - Evaluated expression visitor --*- 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 EvaluatedExprVisitor class template, which visits
  15. // the potentially-evaluated subexpressions of a potentially-evaluated
  16. // expression.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
  20. #define LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
  21. #include "clang/AST/DeclCXX.h"
  22. #include "clang/AST/Expr.h"
  23. #include "clang/AST/ExprCXX.h"
  24. #include "clang/AST/StmtVisitor.h"
  25. #include "llvm/ADT/STLExtras.h"
  26. namespace clang {
  27. class ASTContext;
  28. /// Given a potentially-evaluated expression, this visitor visits all
  29. /// of its potentially-evaluated subexpressions, recursively.
  30. template<template <typename> class Ptr, typename ImplClass>
  31. class EvaluatedExprVisitorBase : public StmtVisitorBase<Ptr, ImplClass, void> {
  32. protected:
  33. const ASTContext &Context;
  34. public:
  35. // Return whether this visitor should recurse into discarded statements for a
  36. // 'constexpr-if'.
  37. bool shouldVisitDiscardedStmt() const { return true; }
  38. #define PTR(CLASS) typename Ptr<CLASS>::type
  39. explicit EvaluatedExprVisitorBase(const ASTContext &Context) : Context(Context) { }
  40. // Expressions that have no potentially-evaluated subexpressions (but may have
  41. // other sub-expressions).
  42. void VisitDeclRefExpr(PTR(DeclRefExpr) E) { }
  43. void VisitOffsetOfExpr(PTR(OffsetOfExpr) E) { }
  44. void VisitUnaryExprOrTypeTraitExpr(PTR(UnaryExprOrTypeTraitExpr) E) { }
  45. void VisitExpressionTraitExpr(PTR(ExpressionTraitExpr) E) { }
  46. void VisitBlockExpr(PTR(BlockExpr) E) { }
  47. void VisitCXXUuidofExpr(PTR(CXXUuidofExpr) E) { }
  48. void VisitCXXNoexceptExpr(PTR(CXXNoexceptExpr) E) { }
  49. void VisitMemberExpr(PTR(MemberExpr) E) {
  50. // Only the base matters.
  51. return this->Visit(E->getBase());
  52. }
  53. void VisitChooseExpr(PTR(ChooseExpr) E) {
  54. // Don't visit either child expression if the condition is dependent.
  55. if (E->getCond()->isValueDependent())
  56. return;
  57. // Only the selected subexpression matters; the other one is not evaluated.
  58. return this->Visit(E->getChosenSubExpr());
  59. }
  60. void VisitGenericSelectionExpr(PTR(GenericSelectionExpr) E) {
  61. // The controlling expression of a generic selection is not evaluated.
  62. // Don't visit either child expression if the condition is type-dependent.
  63. if (E->isResultDependent())
  64. return;
  65. // Only the selected subexpression matters; the other subexpressions and the
  66. // controlling expression are not evaluated.
  67. return this->Visit(E->getResultExpr());
  68. }
  69. void VisitDesignatedInitExpr(PTR(DesignatedInitExpr) E) {
  70. // Only the actual initializer matters; the designators are all constant
  71. // expressions.
  72. return this->Visit(E->getInit());
  73. }
  74. void VisitCXXTypeidExpr(PTR(CXXTypeidExpr) E) {
  75. if (E->isPotentiallyEvaluated())
  76. return this->Visit(E->getExprOperand());
  77. }
  78. void VisitCallExpr(PTR(CallExpr) CE) {
  79. if (!CE->isUnevaluatedBuiltinCall(Context))
  80. return getDerived().VisitExpr(CE);
  81. }
  82. void VisitLambdaExpr(PTR(LambdaExpr) LE) {
  83. // Only visit the capture initializers, and not the body.
  84. for (LambdaExpr::const_capture_init_iterator I = LE->capture_init_begin(),
  85. E = LE->capture_init_end();
  86. I != E; ++I)
  87. if (*I)
  88. this->Visit(*I);
  89. }
  90. /// The basis case walks all of the children of the statement or
  91. /// expression, assuming they are all potentially evaluated.
  92. void VisitStmt(PTR(Stmt) S) {
  93. for (auto *SubStmt : S->children())
  94. if (SubStmt)
  95. this->Visit(SubStmt);
  96. }
  97. void VisitIfStmt(PTR(IfStmt) If) {
  98. if (!getDerived().shouldVisitDiscardedStmt()) {
  99. if (auto SubStmt = If->getNondiscardedCase(Context)) {
  100. if (*SubStmt)
  101. this->Visit(*SubStmt);
  102. return;
  103. }
  104. }
  105. getDerived().VisitStmt(If);
  106. }
  107. ImplClass &getDerived() { return *static_cast<ImplClass *>(this); }
  108. #undef PTR
  109. };
  110. /// EvaluatedExprVisitor - This class visits 'Expr *'s
  111. template <typename ImplClass>
  112. class EvaluatedExprVisitor
  113. : public EvaluatedExprVisitorBase<std::add_pointer, ImplClass> {
  114. public:
  115. explicit EvaluatedExprVisitor(const ASTContext &Context)
  116. : EvaluatedExprVisitorBase<std::add_pointer, ImplClass>(Context) {}
  117. };
  118. /// ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
  119. template <typename ImplClass>
  120. class ConstEvaluatedExprVisitor
  121. : public EvaluatedExprVisitorBase<llvm::make_const_ptr, ImplClass> {
  122. public:
  123. explicit ConstEvaluatedExprVisitor(const ASTContext &Context)
  124. : EvaluatedExprVisitorBase<llvm::make_const_ptr, ImplClass>(Context) {}
  125. };
  126. }
  127. #endif // LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
  128. #ifdef __GNUC__
  129. #pragma GCC diagnostic pop
  130. #endif