1218887Sdim//===--- EvaluatedExprVisitor.h - Evaluated expression visitor --*- C++ -*-===// 2218887Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6218887Sdim// 7218887Sdim//===----------------------------------------------------------------------===// 8218887Sdim// 9218887Sdim// This file defines the EvaluatedExprVisitor class template, which visits 10218887Sdim// the potentially-evaluated subexpressions of a potentially-evaluated 11218887Sdim// expression. 12218887Sdim// 13218887Sdim//===----------------------------------------------------------------------===// 14218887Sdim#ifndef LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H 15218887Sdim#define LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H 16218887Sdim 17218887Sdim#include "clang/AST/DeclCXX.h" 18218887Sdim#include "clang/AST/Expr.h" 19218887Sdim#include "clang/AST/ExprCXX.h" 20249423Sdim#include "clang/AST/StmtVisitor.h" 21344779Sdim#include "llvm/ADT/STLExtras.h" 22218887Sdim 23218887Sdimnamespace clang { 24341825Sdim 25218887Sdimclass ASTContext; 26341825Sdim 27341825Sdim/// Given a potentially-evaluated expression, this visitor visits all 28218887Sdim/// of its potentially-evaluated subexpressions, recursively. 29288943Sdimtemplate<template <typename> class Ptr, typename ImplClass> 30288943Sdimclass EvaluatedExprVisitorBase : public StmtVisitorBase<Ptr, ImplClass, void> { 31288943Sdimprotected: 32288943Sdim const ASTContext &Context; 33288943Sdim 34218887Sdimpublic: 35288943Sdim#define PTR(CLASS) typename Ptr<CLASS>::type 36288943Sdim 37288943Sdim explicit EvaluatedExprVisitorBase(const ASTContext &Context) : Context(Context) { } 38288943Sdim 39218887Sdim // Expressions that have no potentially-evaluated subexpressions (but may have 40218887Sdim // other sub-expressions). 41288943Sdim void VisitDeclRefExpr(PTR(DeclRefExpr) E) { } 42288943Sdim void VisitOffsetOfExpr(PTR(OffsetOfExpr) E) { } 43288943Sdim void VisitUnaryExprOrTypeTraitExpr(PTR(UnaryExprOrTypeTraitExpr) E) { } 44288943Sdim void VisitExpressionTraitExpr(PTR(ExpressionTraitExpr) E) { } 45288943Sdim void VisitBlockExpr(PTR(BlockExpr) E) { } 46288943Sdim void VisitCXXUuidofExpr(PTR(CXXUuidofExpr) E) { } 47288943Sdim void VisitCXXNoexceptExpr(PTR(CXXNoexceptExpr) E) { } 48288943Sdim 49288943Sdim void VisitMemberExpr(PTR(MemberExpr) E) { 50218887Sdim // Only the base matters. 51218887Sdim return this->Visit(E->getBase()); 52218887Sdim } 53288943Sdim 54288943Sdim void VisitChooseExpr(PTR(ChooseExpr) E) { 55249423Sdim // Don't visit either child expression if the condition is dependent. 56249423Sdim if (E->getCond()->isValueDependent()) 57249423Sdim return; 58218887Sdim // Only the selected subexpression matters; the other one is not evaluated. 59261991Sdim return this->Visit(E->getChosenSubExpr()); 60218887Sdim } 61251662Sdim 62288943Sdim void VisitGenericSelectionExpr(PTR(GenericSelectionExpr) E) { 63280031Sdim // The controlling expression of a generic selection is not evaluated. 64280031Sdim 65280031Sdim // Don't visit either child expression if the condition is type-dependent. 66280031Sdim if (E->isResultDependent()) 67280031Sdim return; 68280031Sdim // Only the selected subexpression matters; the other subexpressions and the 69280031Sdim // controlling expression are not evaluated. 70280031Sdim return this->Visit(E->getResultExpr()); 71280031Sdim } 72280031Sdim 73288943Sdim void VisitDesignatedInitExpr(PTR(DesignatedInitExpr) E) { 74218887Sdim // Only the actual initializer matters; the designators are all constant 75218887Sdim // expressions. 76218887Sdim return this->Visit(E->getInit()); 77218887Sdim } 78249423Sdim 79288943Sdim void VisitCXXTypeidExpr(PTR(CXXTypeidExpr) E) { 80249423Sdim if (E->isPotentiallyEvaluated()) 81249423Sdim return this->Visit(E->getExprOperand()); 82218887Sdim } 83249423Sdim 84288943Sdim void VisitCallExpr(PTR(CallExpr) CE) { 85249423Sdim if (!CE->isUnevaluatedBuiltinCall(Context)) 86249423Sdim return static_cast<ImplClass*>(this)->VisitExpr(CE); 87249423Sdim } 88249423Sdim 89288943Sdim void VisitLambdaExpr(PTR(LambdaExpr) LE) { 90251662Sdim // Only visit the capture initializers, and not the body. 91296417Sdim for (LambdaExpr::const_capture_init_iterator I = LE->capture_init_begin(), 92296417Sdim E = LE->capture_init_end(); 93251662Sdim I != E; ++I) 94251662Sdim if (*I) 95251662Sdim this->Visit(*I); 96251662Sdim } 97251662Sdim 98341825Sdim /// The basis case walks all of the children of the statement or 99218887Sdim /// expression, assuming they are all potentially evaluated. 100288943Sdim void VisitStmt(PTR(Stmt) S) { 101288943Sdim for (auto *SubStmt : S->children()) 102288943Sdim if (SubStmt) 103288943Sdim this->Visit(SubStmt); 104218887Sdim } 105288943Sdim 106288943Sdim#undef PTR 107218887Sdim}; 108218887Sdim 109288943Sdim/// EvaluatedExprVisitor - This class visits 'Expr *'s 110344779Sdimtemplate <typename ImplClass> 111288943Sdimclass EvaluatedExprVisitor 112344779Sdim : public EvaluatedExprVisitorBase<std::add_pointer, ImplClass> { 113288943Sdimpublic: 114344779Sdim explicit EvaluatedExprVisitor(const ASTContext &Context) 115344779Sdim : EvaluatedExprVisitorBase<std::add_pointer, ImplClass>(Context) {} 116288943Sdim}; 117288943Sdim 118288943Sdim/// ConstEvaluatedExprVisitor - This class visits 'const Expr *'s. 119344779Sdimtemplate <typename ImplClass> 120288943Sdimclass ConstEvaluatedExprVisitor 121344779Sdim : public EvaluatedExprVisitorBase<llvm::make_const_ptr, ImplClass> { 122288943Sdimpublic: 123344779Sdim explicit ConstEvaluatedExprVisitor(const ASTContext &Context) 124344779Sdim : EvaluatedExprVisitorBase<llvm::make_const_ptr, ImplClass>(Context) {} 125288943Sdim}; 126218887Sdim} 127218887Sdim 128218887Sdim#endif // LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H 129