diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index b6758ae57af30ee7efe5f7f55f57578fd9af9421..63b3c3a65a012ea52e3c6731f4c22054c551c195 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -33,7 +33,6 @@ namespace ento {
   class AnalysisManager;
   class BugReporter;
   class CheckerContext;
-  class SimpleCall;
   class ObjCMethodCall;
   class SVal;
   class ExplodedNode;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index e2baf38e0beb05d68eef54b5ccf26faa80ec3f84..396a9fe364458860f985d847d698973a6a2daac1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -33,9 +33,6 @@ namespace ento {
 
 enum CallEventKind {
   CE_Function,
-  CE_Block,
-  CE_BEG_SIMPLE_CALLS = CE_Function,
-  CE_END_SIMPLE_CALLS = CE_Block,
   CE_CXXMember,
   CE_CXXMemberOperator,
   CE_CXXDestructor,
@@ -45,6 +42,7 @@ enum CallEventKind {
   CE_CXXAllocator,
   CE_BEG_FUNCTION_CALLS = CE_Function,
   CE_END_FUNCTION_CALLS = CE_CXXAllocator,
+  CE_Block,
   CE_ObjCMessage
 };
 
@@ -431,13 +429,21 @@ public:
   }
 };
 
-/// \brief Represents a call to a non-C++ function, written as a CallExpr.
-class SimpleCall : public AnyFunctionCall {
+/// \brief Represents a C function or static C++ member function call.
+///
+/// Example: \c fun()
+class SimpleFunctionCall : public AnyFunctionCall {
+  friend class CallEventManager;
+
 protected:
-  SimpleCall(const CallExpr *CE, ProgramStateRef St,
-             const LocationContext *LCtx)
+  SimpleFunctionCall(const CallExpr *CE, ProgramStateRef St,
+                     const LocationContext *LCtx)
     : AnyFunctionCall(CE, St, LCtx) {}
-  SimpleCall(const SimpleCall &Other) : AnyFunctionCall(Other) {}
+  SimpleFunctionCall(const SimpleFunctionCall &Other)
+    : AnyFunctionCall(Other) {}
+  virtual void cloneTo(void *Dest) const {
+    new (Dest) SimpleFunctionCall(*this);
+  }
 
 public:
   virtual const CallExpr *getOriginExpr() const {
@@ -452,27 +458,6 @@ public:
     return getOriginExpr()->getArg(Index);
   }
 
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() >= CE_BEG_SIMPLE_CALLS &&
-           CA->getKind() <= CE_END_SIMPLE_CALLS;
-  }
-};
-
-/// \brief Represents a C function or static C++ member function call.
-///
-/// Example: \c fun()
-class FunctionCall : public SimpleCall {
-  friend class CallEventManager;
-
-protected:
-  FunctionCall(const CallExpr *CE, ProgramStateRef St,
-               const LocationContext *LCtx)
-    : SimpleCall(CE, St, LCtx) {}
-
-  FunctionCall(const FunctionCall &Other) : SimpleCall(Other) {}
-  virtual void cloneTo(void *Dest) const { new (Dest) FunctionCall(*this); }
-
-public:
   virtual Kind getKind() const { return CE_Function; }
 
   static bool classof(const CallEvent *CA) {
@@ -483,30 +468,36 @@ public:
 /// \brief Represents a call to a block.
 ///
 /// Example: <tt>^{ /* ... */ }()</tt>
-class BlockCall : public SimpleCall {
+class BlockCall : public CallEvent {
   friend class CallEventManager;
 
 protected:
   BlockCall(const CallExpr *CE, ProgramStateRef St,
             const LocationContext *LCtx)
-    : SimpleCall(CE, St, LCtx) {}
+    : CallEvent(CE, St, LCtx) {}
 
-  BlockCall(const BlockCall &Other) : SimpleCall(Other) {}
+  BlockCall(const BlockCall &Other) : CallEvent(Other) {}
   virtual void cloneTo(void *Dest) const { new (Dest) BlockCall(*this); }
 
   virtual void getExtraInvalidatedValues(ValueList &Values) const;
 
 public:
+  virtual const CallExpr *getOriginExpr() const {
+    return cast<CallExpr>(CallEvent::getOriginExpr());
+  }
+
+  virtual unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
+
+  virtual const Expr *getArgExpr(unsigned Index) const {
+    return getOriginExpr()->getArg(Index);
+  }
+
   /// \brief Returns the region associated with this instance of the block.
   ///
   /// This may be NULL if the block's origin is unknown.
   const BlockDataRegion *getBlockRegion() const;
 
-  /// \brief Gets the declaration of the block.
-  ///
-  /// This is not an override of getDecl() because AnyFunctionCall has already
-  /// assumed that it's a FunctionDecl.
-  const BlockDecl *getBlockDecl() const {
+  virtual const BlockDecl *getDecl() const {
     const BlockDataRegion *BR = getBlockRegion();
     if (!BR)
       return 0;
@@ -514,7 +505,11 @@ public:
   }
 
   virtual RuntimeDefinition getRuntimeDefinition() const {
-    return RuntimeDefinition(getBlockDecl());
+    return RuntimeDefinition(getDecl());
+  }
+
+  virtual bool argumentsMayEscape() const {
+    return true;
   }
 
   virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
@@ -913,6 +908,7 @@ class CallEventManager {
 
   llvm::BumpPtrAllocator &Alloc;
   SmallVector<void *, 8> Cache;
+  typedef SimpleFunctionCall CallEventTemplateTy;
 
   void reclaim(const void *Memory) {
     Cache.push_back(const_cast<void *>(Memory));
@@ -921,24 +917,30 @@ class CallEventManager {
   /// Returns memory that can be initialized as a CallEvent.
   void *allocate() {
     if (Cache.empty())
-      return Alloc.Allocate<FunctionCall>();
+      return Alloc.Allocate<CallEventTemplateTy>();
     else
       return Cache.pop_back_val();
   }
 
   template <typename T, typename Arg>
   T *create(Arg A, ProgramStateRef St, const LocationContext *LCtx) {
+    LLVM_STATIC_ASSERT(sizeof(T) == sizeof(CallEventTemplateTy),
+                       "CallEvent subclasses are not all the same size");
     return new (allocate()) T(A, St, LCtx);
   }
 
   template <typename T, typename Arg1, typename Arg2>
   T *create(Arg1 A1, Arg2 A2, ProgramStateRef St, const LocationContext *LCtx) {
+    LLVM_STATIC_ASSERT(sizeof(T) == sizeof(CallEventTemplateTy),
+                       "CallEvent subclasses are not all the same size");
     return new (allocate()) T(A1, A2, St, LCtx);
   }
 
   template <typename T, typename Arg1, typename Arg2, typename Arg3>
   T *create(Arg1 A1, Arg2 A2, Arg3 A3, ProgramStateRef St,
             const LocationContext *LCtx) {
+    LLVM_STATIC_ASSERT(sizeof(T) == sizeof(CallEventTemplateTy),
+                       "CallEvent subclasses are not all the same size");
     return new (allocate()) T(A1, A2, A3, St, LCtx);
   }
 
@@ -946,6 +948,8 @@ class CallEventManager {
             typename Arg4>
   T *create(Arg1 A1, Arg2 A2, Arg3 A3, Arg4 A4, ProgramStateRef St,
             const LocationContext *LCtx) {
+    LLVM_STATIC_ASSERT(sizeof(T) == sizeof(CallEventTemplateTy),
+                       "CallEvent subclasses are not all the same size");
     return new (allocate()) T(A1, A2, A3, A4, St, LCtx);
   }
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index e0dbc5e583dbfe9226ed991d156f8e84b416bd9e..2699f7d0d767c8457d32fa707684a6f84a8a06a8 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -43,7 +43,6 @@ namespace ento {
 
 class AnalysisManager;
 class CallEvent;
-class SimpleCall;
 class CXXConstructorCall;
 
 class ExprEngine : public SubEngine {
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 92297ca3886d2f57cc945e0ab5218d8c1921938a..1e996589c1b03120f15f1487d679b8d7f3fe7030 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1907,11 +1907,11 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
   assert(Call);
   EscapingSymbol = 0;
   
-  // For now, assume that any C++ call can free memory.
+  // For now, assume that any C++ or block call can free memory.
   // TODO: If we want to be more optimistic here, we'll need to make sure that
   // regions escape to C++ containers. They seem to do that even now, but for
   // mysterious reasons.
-  if (!(isa<FunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
+  if (!(isa<SimpleFunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
     return true;
 
   // Check Objective-C messages by selector name.
@@ -1966,7 +1966,7 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
   }
 
   // At this point the only thing left to handle is straight function calls.
-  const FunctionDecl *FD = cast<FunctionCall>(Call)->getDecl();
+  const FunctionDecl *FD = cast<SimpleFunctionCall>(Call)->getDecl();
   if (!FD)
     return true;
 
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 32f762e1453389db4140df142eb1391b07d40333..4302cc7fd29360b37d29a672d16691ed78acce97 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -860,7 +860,7 @@ void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S,
     // Special cases where the callback argument CANNOT free the return value.
     // This can generally only happen if we know that the callback will only be
     // called when the return value is already being deallocated.
-    if (const FunctionCall *FC = dyn_cast<FunctionCall>(&Call)) {
+    if (const SimpleFunctionCall *FC = dyn_cast<SimpleFunctionCall>(&Call)) {
       if (IdentifierInfo *Name = FC->getDecl()->getIdentifier()) {
         // When the CGBitmapContext is deallocated, the callback here will free
         // the associated data buffer.
@@ -908,7 +908,7 @@ RetainSummaryManager::getSummary(const CallEvent &Call,
   const RetainSummary *Summ;
   switch (Call.getKind()) {
   case CE_Function:
-    Summ = getFunctionSummary(cast<FunctionCall>(Call).getDecl());
+    Summ = getFunctionSummary(cast<SimpleFunctionCall>(Call).getDecl());
     break;
   case CE_CXXMember:
   case CE_CXXMemberOperator:
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index 71895051e2cf65fbc6488120c04979b6ec67134b..16bbc86dd48f0804e59547009131134e3909c9d4 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -387,7 +387,7 @@ bool AnyFunctionCall::argumentsMayEscape() const {
 }
 
 
-const FunctionDecl *SimpleCall::getDecl() const {
+const FunctionDecl *SimpleFunctionCall::getDecl() const {
   const FunctionDecl *D = getOriginExpr()->getDirectCallee();
   if (D)
     return D;
@@ -549,14 +549,14 @@ const BlockDataRegion *BlockCall::getBlockRegion() const {
 }
 
 CallEvent::param_iterator BlockCall::param_begin() const {
-  const BlockDecl *D = getBlockDecl();
+  const BlockDecl *D = getDecl();
   if (!D)
     return 0;
   return D->param_begin();
 }
 
 CallEvent::param_iterator BlockCall::param_end() const {
-  const BlockDecl *D = getBlockDecl();
+  const BlockDecl *D = getDecl();
   if (!D)
     return 0;
   return D->param_end();
@@ -940,7 +940,7 @@ CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State,
 
   // Otherwise, it's a normal function call, static member function call, or
   // something we can't reason about.
-  return create<FunctionCall>(CE, State, LCtx);
+  return create<SimpleFunctionCall>(CE, State, LCtx);
 }