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