clang API Documentation
00001 //=-- AggExprVisitor.cpp - evaluating expressions of C++ class type -*- C++ -*-= 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines AggExprVisitor class, which contains lots of boiler 00011 // plate code for evaluating expressions of C++ class type. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 00016 #include "clang/AST/StmtVisitor.h" 00017 00018 using namespace clang; 00019 using namespace ento; 00020 00021 namespace { 00022 /// AggExprVisitor is designed after AggExprEmitter of the CodeGen module. It 00023 /// is used for evaluating exprs of C++ object type. Evaluating such exprs 00024 /// requires a destination pointer pointing to the object being evaluated 00025 /// into. Passing such a pointer around would pollute the Visit* interface of 00026 /// ExprEngine. AggExprVisitor encapsulates code that goes through various 00027 /// cast and construct exprs (and others), and at the final point, dispatches 00028 /// back to the ExprEngine to let the real evaluation logic happen. 00029 class AggExprVisitor : public StmtVisitor<AggExprVisitor> { 00030 const MemRegion *Dest; 00031 ExplodedNode *Pred; 00032 ExplodedNodeSet &DstSet; 00033 ExprEngine &Eng; 00034 00035 public: 00036 AggExprVisitor(const MemRegion *dest, ExplodedNode *N, ExplodedNodeSet &dst, 00037 ExprEngine &eng) 00038 : Dest(dest), Pred(N), DstSet(dst), Eng(eng) {} 00039 00040 void VisitCastExpr(CastExpr *E); 00041 void VisitCXXConstructExpr(CXXConstructExpr *E); 00042 void VisitCXXMemberCallExpr(CXXMemberCallExpr *E); 00043 }; 00044 } 00045 00046 void AggExprVisitor::VisitCastExpr(CastExpr *E) { 00047 switch (E->getCastKind()) { 00048 default: 00049 llvm_unreachable("Unhandled cast kind"); 00050 case CK_NoOp: 00051 case CK_ConstructorConversion: 00052 case CK_UserDefinedConversion: 00053 // FIXME: The CFG is fully linearised, so a recursive visit is probably not 00054 // needed anymore. 00055 Visit(E->getSubExpr()); 00056 break; 00057 } 00058 } 00059 00060 void AggExprVisitor::VisitCXXConstructExpr(CXXConstructExpr *E) { 00061 Eng.VisitCXXConstructExpr(E, Dest, Pred, DstSet); 00062 } 00063 00064 void AggExprVisitor::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { 00065 // FIXME: The CFG is fully linearised, so a recursive visit is probably not 00066 // needed anymore. 00067 Eng.Visit(E, Pred, DstSet); 00068 } 00069 00070 void ExprEngine::VisitAggExpr(const Expr *E, const MemRegion *Dest, 00071 ExplodedNode *Pred, ExplodedNodeSet &Dst) { 00072 AggExprVisitor(Dest, Pred, Dst, *this).Visit(const_cast<Expr *>(E)); 00073 }