Home | History | Annotate | Download | only in Core
      1 //=-- AggExprVisitor.cpp - evaluating expressions of C++ class type -*- 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 AggExprVisitor class, which contains lots of boiler
     11 // plate code for evaluating expressions of C++ class type.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
     16 #include "clang/AST/StmtVisitor.h"
     17 
     18 using namespace clang;
     19 using namespace ento;
     20 
     21 namespace {
     22 /// AggExprVisitor is designed after AggExprEmitter of the CodeGen module.  It
     23 /// is used for evaluating exprs of C++ object type. Evaluating such exprs
     24 /// requires a destination pointer pointing to the object being evaluated
     25 /// into. Passing such a pointer around would pollute the Visit* interface of
     26 /// ExprEngine. AggExprVisitor encapsulates code that goes through various
     27 /// cast and construct exprs (and others), and at the final point, dispatches
     28 /// back to the ExprEngine to let the real evaluation logic happen.
     29 class AggExprVisitor : public StmtVisitor<AggExprVisitor> {
     30   const MemRegion *Dest;
     31   ExplodedNode *Pred;
     32   ExplodedNodeSet &DstSet;
     33   ExprEngine &Eng;
     34 
     35 public:
     36   AggExprVisitor(const MemRegion *dest, ExplodedNode *N, ExplodedNodeSet &dst,
     37                  ExprEngine &eng)
     38     : Dest(dest), Pred(N), DstSet(dst), Eng(eng) {}
     39 
     40   void VisitCastExpr(CastExpr *E);
     41   void VisitCXXConstructExpr(CXXConstructExpr *E);
     42   void VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
     43 };
     44 }
     45 
     46 void AggExprVisitor::VisitCastExpr(CastExpr *E) {
     47   switch (E->getCastKind()) {
     48   default:
     49     llvm_unreachable("Unhandled cast kind");
     50   case CK_NoOp:
     51   case CK_ConstructorConversion:
     52   case CK_UserDefinedConversion:
     53     Visit(E->getSubExpr());
     54     break;
     55   }
     56 }
     57 
     58 void AggExprVisitor::VisitCXXConstructExpr(CXXConstructExpr *E) {
     59   Eng.VisitCXXConstructExpr(E, Dest, Pred, DstSet);
     60 }
     61 
     62 void AggExprVisitor::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
     63   Eng.Visit(E, Pred, DstSet);
     64 }
     65 
     66 void ExprEngine::VisitAggExpr(const Expr *E, const MemRegion *Dest,
     67                                 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
     68   AggExprVisitor(Dest, Pred, Dst, *this).Visit(const_cast<Expr *>(E));
     69 }
     70