Home | History | Annotate | Download | only in AST
      1 //===--- EvaluatedExprVisitor.h - Evaluated expression visitor --*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file defines the EvaluatedExprVisitor class template, which visits
     11 //  the potentially-evaluated subexpressions of a potentially-evaluated
     12 //  expression.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 #ifndef LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
     16 #define LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
     17 
     18 #include "clang/AST/DeclCXX.h"
     19 #include "clang/AST/Expr.h"
     20 #include "clang/AST/ExprCXX.h"
     21 #include "clang/AST/StmtVisitor.h"
     22 
     23 namespace clang {
     24 
     25 class ASTContext;
     26 
     27 /// \brief 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 #define PTR(CLASS) typename Ptr<CLASS>::type
     36 
     37   explicit EvaluatedExprVisitorBase(const ASTContext &Context) : Context(Context) { }
     38 
     39   // Expressions that have no potentially-evaluated subexpressions (but may have
     40   // other sub-expressions).
     41   void VisitDeclRefExpr(PTR(DeclRefExpr) E) { }
     42   void VisitOffsetOfExpr(PTR(OffsetOfExpr) E) { }
     43   void VisitUnaryExprOrTypeTraitExpr(PTR(UnaryExprOrTypeTraitExpr) E) { }
     44   void VisitExpressionTraitExpr(PTR(ExpressionTraitExpr) E) { }
     45   void VisitBlockExpr(PTR(BlockExpr) E) { }
     46   void VisitCXXUuidofExpr(PTR(CXXUuidofExpr) E) { }
     47   void VisitCXXNoexceptExpr(PTR(CXXNoexceptExpr) E) { }
     48 
     49   void VisitMemberExpr(PTR(MemberExpr) E) {
     50     // Only the base matters.
     51     return this->Visit(E->getBase());
     52   }
     53 
     54   void VisitChooseExpr(PTR(ChooseExpr) E) {
     55     // Don't visit either child expression if the condition is dependent.
     56     if (E->getCond()->isValueDependent())
     57       return;
     58     // Only the selected subexpression matters; the other one is not evaluated.
     59     return this->Visit(E->getChosenSubExpr());
     60   }
     61 
     62   void VisitGenericSelectionExpr(PTR(GenericSelectionExpr) E) {
     63     // The controlling expression of a generic selection is not evaluated.
     64 
     65     // Don't visit either child expression if the condition is type-dependent.
     66     if (E->isResultDependent())
     67       return;
     68     // Only the selected subexpression matters; the other subexpressions and the
     69     // controlling expression are not evaluated.
     70     return this->Visit(E->getResultExpr());
     71   }
     72 
     73   void VisitDesignatedInitExpr(PTR(DesignatedInitExpr) E) {
     74     // Only the actual initializer matters; the designators are all constant
     75     // expressions.
     76     return this->Visit(E->getInit());
     77   }
     78 
     79   void VisitCXXTypeidExpr(PTR(CXXTypeidExpr) E) {
     80     if (E->isPotentiallyEvaluated())
     81       return this->Visit(E->getExprOperand());
     82   }
     83 
     84   void VisitCallExpr(PTR(CallExpr) CE) {
     85     if (!CE->isUnevaluatedBuiltinCall(Context))
     86       return static_cast<ImplClass*>(this)->VisitExpr(CE);
     87   }
     88 
     89   void VisitLambdaExpr(PTR(LambdaExpr) LE) {
     90     // Only visit the capture initializers, and not the body.
     91     for (LambdaExpr::const_capture_init_iterator I = LE->capture_init_begin(),
     92                                                  E = LE->capture_init_end();
     93          I != E; ++I)
     94       if (*I)
     95         this->Visit(*I);
     96   }
     97 
     98   /// \brief The basis case walks all of the children of the statement or
     99   /// expression, assuming they are all potentially evaluated.
    100   void VisitStmt(PTR(Stmt) S) {
    101     for (auto *SubStmt : S->children())
    102       if (SubStmt)
    103         this->Visit(SubStmt);
    104   }
    105 
    106 #undef PTR
    107 };
    108 
    109 /// EvaluatedExprVisitor - This class visits 'Expr *'s
    110 template<typename ImplClass>
    111 class EvaluatedExprVisitor
    112  : public EvaluatedExprVisitorBase<make_ptr, ImplClass> {
    113 public:
    114   explicit EvaluatedExprVisitor(const ASTContext &Context) :
    115     EvaluatedExprVisitorBase<make_ptr, ImplClass>(Context) { }
    116 };
    117 
    118 /// ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
    119 template<typename ImplClass>
    120 class ConstEvaluatedExprVisitor
    121  : public EvaluatedExprVisitorBase<make_const_ptr, ImplClass> {
    122 public:
    123   explicit ConstEvaluatedExprVisitor(const ASTContext &Context) :
    124     EvaluatedExprVisitorBase<make_const_ptr, ImplClass>(Context) { }
    125 };
    126 
    127 }
    128 
    129 #endif // LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
    130