clang API Documentation

AggExprVisitor.cpp
Go to the documentation of this file.
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 }