Chris Lattner has strong opinions about directory
layout.  :)

Rename the 'EntoSA' directories to 'StaticAnalyzer'.

Internally we will still use the 'ento' namespace
for the analyzer engine (unless there are further
sabre rattlings...).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122514 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/AggExprVisitor.cpp b/lib/StaticAnalyzer/AggExprVisitor.cpp
new file mode 100644
index 0000000..0cc2390
--- /dev/null
+++ b/lib/StaticAnalyzer/AggExprVisitor.cpp
@@ -0,0 +1,63 @@
+//=-- AggExprVisitor.cpp - evaluating expressions of C++ class type -*- C++ -*-=
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines AggExprVisitor class, which contains lots of boiler
+// plate code for evaluating expressions of C++ class type.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/PathSensitive/ExprEngine.h"
+#include "clang/AST/StmtVisitor.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+/// AggExprVisitor is designed after AggExprEmitter of the CodeGen module.  It
+/// is used for evaluating exprs of C++ object type. Evaluating such exprs
+/// requires a destination pointer pointing to the object being evaluated
+/// into. Passing such a pointer around would pollute the Visit* interface of
+/// ExprEngine. AggExprVisitor encapsulates code that goes through various
+/// cast and construct exprs (and others), and at the final point, dispatches
+/// back to the ExprEngine to let the real evaluation logic happen.
+class AggExprVisitor : public StmtVisitor<AggExprVisitor> {
+  const MemRegion *Dest;
+  ExplodedNode *Pred;
+  ExplodedNodeSet &DstSet;
+  ExprEngine &Eng;
+
+public:
+  AggExprVisitor(const MemRegion *dest, ExplodedNode *N, ExplodedNodeSet &dst, 
+                 ExprEngine &eng)
+    : Dest(dest), Pred(N), DstSet(dst), Eng(eng) {}
+
+  void VisitCastExpr(CastExpr *E);
+  void VisitCXXConstructExpr(CXXConstructExpr *E);
+};
+}
+
+void AggExprVisitor::VisitCastExpr(CastExpr *E) {
+  switch (E->getCastKind()) {
+  default: 
+    assert(0 && "Unhandled cast kind");
+  case CK_NoOp:
+  case CK_ConstructorConversion:
+    Visit(E->getSubExpr());
+    break;
+  }
+}
+
+void AggExprVisitor::VisitCXXConstructExpr(CXXConstructExpr *E) {
+  Eng.VisitCXXConstructExpr(E, Dest, Pred, DstSet);
+}
+
+void ExprEngine::VisitAggExpr(const Expr *E, const MemRegion *Dest, 
+                                ExplodedNode *Pred, ExplodedNodeSet &Dst) {
+  AggExprVisitor(Dest, Pred, Dst, *this).Visit(const_cast<Expr *>(E));
+}