EvaluatedExprVisitor.h revision 4fcf5b2f816347ba7a3f16557d5e2b293634d4d6
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
27be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor/// \begin 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) { }
40be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { }
41be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitBlockExpr(BlockExpr *E) { }
42be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitCXXUuidofExpr(CXXUuidofExpr *E) { }
43be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { }
44be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
45be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitMemberExpr(MemberExpr *E) {
46be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    // Only the base matters.
47be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    return this->Visit(E->getBase());
48be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  }
49be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
50be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitChooseExpr(ChooseExpr *E) {
51be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    // Only the selected subexpression matters; the other one is not evaluated.
52be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    return this->Visit(E->getChosenSubExpr(Context));
53be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  }
54be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
55be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitDesignatedInitExpr(DesignatedInitExpr *E) {
56be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    // Only the actual initializer matters; the designators are all constant
57be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    // expressions.
58be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    return this->Visit(E->getInit());
59be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  }
60be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
61be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  void VisitCXXTypeidExpr(CXXTypeidExpr *E) {
62be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    // typeid(expression) is potentially evaluated when the argument is
63be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    // a glvalue of polymorphic type. (C++ 5.2.8p2-3)
64be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor    if (!E->isTypeOperand() && E->Classify(Context).isGLValue())
65be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor      if (const RecordType *Record
66d9a8bbcf8db776de126aa6dc15d66e2ce666d70dDouglas Gregor                 = E->getExprOperand()->getType()->template getAs<RecordType>())
67be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor        if (cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic())
68be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor          return this->Visit(E->getExprOperand());
69be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor  }
704fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor
714fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor  /// \brief The basis case walks all of the children of the statement or
724fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor  /// expression, assuming they are all potentially evaluated.
734fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor  void VisitStmt(Stmt *S) {
744fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor    for(Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end();
754fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor        C != CEnd; ++C)
764fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor      this->Visit(*C);
774fcf5b2f816347ba7a3f16557d5e2b293634d4d6Douglas Gregor  }
78be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor};
79be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
80be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor}
81be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor
82be0f7bd61c7b2879d02ae75aad7a91d92f819d94Douglas Gregor#endif // LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
83