1be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor//===--- EvaluatedExprVisitor.h - Evaluated expression visitor --*- C++ -*-===//
2be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor//
3be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor//                     The LLVM Compiler Infrastructure
4be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor//
5be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor// This file is distributed under the University of Illinois Open Source
6be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor// License. See LICENSE.TXT for details.
7be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor//
8be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor//===----------------------------------------------------------------------===//
9be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor//
10be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor//  This file defines the EvaluatedExprVisitor class template, which visits
11be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor//  the potentially-evaluated subexpressions of a potentially-evaluated
12be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor//  expression.
13be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor//
14be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor//===----------------------------------------------------------------------===//
15be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor#ifndef LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
16be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor#define LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
17be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
18be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor#include "clang/AST/StmtVisitor.h"
19be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor#include "clang/AST/DeclCXX.h"
20be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor#include "clang/AST/Expr.h"
21be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor#include "clang/AST/ExprCXX.h"
22be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
23be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregornamespace clang {
24be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
25be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregorclass ASTContext;
26be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
270982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \brief Given a potentially-evaluated expression, this visitor visits all
28be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor/// of its potentially-evaluated subexpressions, recursively.
29be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregortemplate<typename ImplClass>
30be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregorclass EvaluatedExprVisitor : public StmtVisitor<ImplClass> {
31be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  ASTContext &Context;
32be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
33be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregorpublic:
34be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  explicit EvaluatedExprVisitor(ASTContext &Context) : Context(Context) { }
35be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
36be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  // Expressions that have no potentially-evaluated subexpressions (but may have
37be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  // other sub-expressions).
38be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitDeclRefExpr(DeclRefExpr *E) { }
39be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitOffsetOfExpr(OffsetOfExpr *E) { }
40f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne  void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { }
41552622067dc45013d240f73952fece703f5e63bdJohn Wiegley  void VisitExpressionTraitExpr(ExpressionTraitExpr *E) { }
42be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitBlockExpr(BlockExpr *E) { }
43be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitCXXUuidofExpr(CXXUuidofExpr *E) { }
44be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { }
45be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
46be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitMemberExpr(MemberExpr *E) {
47be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    // Only the base matters.
48be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    return this->Visit(E->getBase());
49be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  }
50be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
51be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitChooseExpr(ChooseExpr *E) {
52be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    // Only the selected subexpression matters; the other one is not evaluated.
53be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    return this->Visit(E->getChosenSubExpr(Context));
54be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  }
55be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
56be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitDesignatedInitExpr(DesignatedInitExpr *E) {
57be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    // Only the actual initializer matters; the designators are all constant
58be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    // expressions.
59be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    return this->Visit(E->getInit());
60be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  }
61be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
62be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitCXXTypeidExpr(CXXTypeidExpr *E) {
63be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    // typeid(expression) is potentially evaluated when the argument is
64be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    // a glvalue of polymorphic type. (C++ 5.2.8p2-3)
65be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    if (!E->isTypeOperand() && E->Classify(Context).isGLValue())
66be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor      if (const RecordType *Record
67d9a8bbcf8db776de126aa6dc15d66e2ce666d70dDouglas Gregor                 = E->getExprOperand()->getType()->template getAs<RecordType>())
68be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor        if (cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic())
69be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor          return this->Visit(E->getExprOperand());
70be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  }
714fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor
724fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor  /// \brief The basis case walks all of the children of the statement or
734fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor  /// expression, assuming they are all potentially evaluated.
744fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor  void VisitStmt(Stmt *S) {
757502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    for (Stmt::child_range C = S->children(); C; ++C)
760656e5b9aa52f2a90fb38517e504b4eebbe53381Chandler Carruth      if (*C)
770656e5b9aa52f2a90fb38517e504b4eebbe53381Chandler Carruth        this->Visit(*C);
784fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor  }
79be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor};
80be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
81be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor}
82be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
83be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor#endif // LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
84