Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===--- EvaluatedExprVisitor.h - Evaluated expression visitor --*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. //  This file defines the EvaluatedExprVisitor class template, which visits
  10. //  the potentially-evaluated subexpressions of a potentially-evaluated
  11. //  expression.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
  15. #define LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
  16.  
  17. #include "clang/AST/DeclCXX.h"
  18. #include "clang/AST/Expr.h"
  19. #include "clang/AST/ExprCXX.h"
  20. #include "clang/AST/StmtVisitor.h"
  21. #include "llvm/ADT/STLExtras.h"
  22.  
  23. namespace clang {
  24.  
  25. class ASTContext;
  26.  
  27. /// Given a potentially-evaluated expression, this visitor visits all
  28. /// of its potentially-evaluated subexpressions, recursively.
  29. template<template <typename> class Ptr, typename ImplClass>
  30. class EvaluatedExprVisitorBase : public StmtVisitorBase<Ptr, ImplClass, void> {
  31. protected:
  32.   const ASTContext &Context;
  33.  
  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.  
  40.   explicit EvaluatedExprVisitorBase(const ASTContext &Context) : Context(Context) { }
  41.  
  42.   // Expressions that have no potentially-evaluated subexpressions (but may have
  43.   // other sub-expressions).
  44.   void VisitDeclRefExpr(PTR(DeclRefExpr) E) { }
  45.   void VisitOffsetOfExpr(PTR(OffsetOfExpr) E) { }
  46.   void VisitUnaryExprOrTypeTraitExpr(PTR(UnaryExprOrTypeTraitExpr) E) { }
  47.   void VisitExpressionTraitExpr(PTR(ExpressionTraitExpr) E) { }
  48.   void VisitBlockExpr(PTR(BlockExpr) E) { }
  49.   void VisitCXXUuidofExpr(PTR(CXXUuidofExpr) E) { }
  50.   void VisitCXXNoexceptExpr(PTR(CXXNoexceptExpr) E) { }
  51.  
  52.   void VisitMemberExpr(PTR(MemberExpr) E) {
  53.     // Only the base matters.
  54.     return this->Visit(E->getBase());
  55.   }
  56.  
  57.   void VisitChooseExpr(PTR(ChooseExpr) E) {
  58.     // Don't visit either child expression if the condition is dependent.
  59.     if (E->getCond()->isValueDependent())
  60.       return;
  61.     // Only the selected subexpression matters; the other one is not evaluated.
  62.     return this->Visit(E->getChosenSubExpr());
  63.   }
  64.  
  65.   void VisitGenericSelectionExpr(PTR(GenericSelectionExpr) E) {
  66.     // The controlling expression of a generic selection is not evaluated.
  67.  
  68.     // Don't visit either child expression if the condition is type-dependent.
  69.     if (E->isResultDependent())
  70.       return;
  71.     // Only the selected subexpression matters; the other subexpressions and the
  72.     // controlling expression are not evaluated.
  73.     return this->Visit(E->getResultExpr());
  74.   }
  75.  
  76.   void VisitDesignatedInitExpr(PTR(DesignatedInitExpr) E) {
  77.     // Only the actual initializer matters; the designators are all constant
  78.     // expressions.
  79.     return this->Visit(E->getInit());
  80.   }
  81.  
  82.   void VisitCXXTypeidExpr(PTR(CXXTypeidExpr) E) {
  83.     if (E->isPotentiallyEvaluated())
  84.       return this->Visit(E->getExprOperand());
  85.   }
  86.  
  87.   void VisitCallExpr(PTR(CallExpr) CE) {
  88.     if (!CE->isUnevaluatedBuiltinCall(Context))
  89.       return getDerived().VisitExpr(CE);
  90.   }
  91.  
  92.   void VisitLambdaExpr(PTR(LambdaExpr) LE) {
  93.     // Only visit the capture initializers, and not the body.
  94.     for (LambdaExpr::const_capture_init_iterator I = LE->capture_init_begin(),
  95.                                                  E = LE->capture_init_end();
  96.          I != E; ++I)
  97.       if (*I)
  98.         this->Visit(*I);
  99.   }
  100.  
  101.   /// The basis case walks all of the children of the statement or
  102.   /// expression, assuming they are all potentially evaluated.
  103.   void VisitStmt(PTR(Stmt) S) {
  104.     for (auto *SubStmt : S->children())
  105.       if (SubStmt)
  106.         this->Visit(SubStmt);
  107.   }
  108.  
  109.   void VisitIfStmt(PTR(IfStmt) If) {
  110.     if (!getDerived().shouldVisitDiscardedStmt()) {
  111.       if (auto SubStmt = If->getNondiscardedCase(Context)) {
  112.         if (*SubStmt)
  113.           this->Visit(*SubStmt);
  114.         return;
  115.       }
  116.     }
  117.  
  118.     getDerived().VisitStmt(If);
  119.   }
  120.  
  121.   ImplClass &getDerived() { return *static_cast<ImplClass *>(this); }
  122.  
  123. #undef PTR
  124. };
  125.  
  126. /// EvaluatedExprVisitor - This class visits 'Expr *'s
  127. template <typename ImplClass>
  128. class EvaluatedExprVisitor
  129.     : public EvaluatedExprVisitorBase<std::add_pointer, ImplClass> {
  130. public:
  131.   explicit EvaluatedExprVisitor(const ASTContext &Context)
  132.       : EvaluatedExprVisitorBase<std::add_pointer, ImplClass>(Context) {}
  133. };
  134.  
  135. /// ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
  136. template <typename ImplClass>
  137. class ConstEvaluatedExprVisitor
  138.     : public EvaluatedExprVisitorBase<llvm::make_const_ptr, ImplClass> {
  139. public:
  140.   explicit ConstEvaluatedExprVisitor(const ASTContext &Context)
  141.       : EvaluatedExprVisitorBase<llvm::make_const_ptr, ImplClass>(Context) {}
  142. };
  143. }
  144.  
  145. #endif // LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
  146.