[analyzer] Reduce code duplication: make CXXDestructorCall a CXXInstanceCall.

While there is now some duplication between SimpleCall and the CXXInstanceCall
sub-hierarchy, this is much better than copy-and-pasting the devirtualization
logic shared by both instance methods and destructors.

An unfortunate side effect is that there is no longer a single CallEvent type
that corresponds to "calls written as CallExprs". For the most part this is a
good thing, but the checker callback eval::Call still takes a CallExpr rather
than a CallEvent (since we're not sure if we want to allow checkers to
evaluate other kinds of calls). A mistake here will be caught by a cast<> in
CheckerManager::runCheckersForEvalCall.

No functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161809 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index aef9e71..e11b6d5 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -319,9 +319,11 @@
                                                SVal Cond, bool Assumption);
 
   /// \brief Run checkers for evaluating a call.
+  ///
+  /// Warning: Currently, the CallEvent MUST come from a CallExpr!
   void runCheckersForEvalCall(ExplodedNodeSet &Dst,
                               const ExplodedNodeSet &Src,
-                              const SimpleCall &CE, ExprEngine &Eng);
+                              const CallEvent &CE, ExprEngine &Eng);
   
   /// \brief Run checkers for the entire Translation Unit.
   void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index 0a9590f..47edfe9 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -32,15 +32,15 @@
 
 enum CallEventKind {
   CE_Function,
-  CE_CXXMember,
-  CE_CXXMemberOperator,
-  CE_BEG_CXX_INSTANCE_CALLS = CE_CXXMember,
-  CE_END_CXX_INSTANCE_CALLS = CE_CXXMemberOperator,
   CE_Block,
   CE_BEG_SIMPLE_CALLS = CE_Function,
   CE_END_SIMPLE_CALLS = CE_Block,
-  CE_CXXConstructor,
+  CE_CXXMember,
+  CE_CXXMemberOperator,
   CE_CXXDestructor,
+  CE_BEG_CXX_INSTANCE_CALLS = CE_CXXMember,
+  CE_END_CXX_INSTANCE_CALLS = CE_CXXDestructor,
+  CE_CXXConstructor,
   CE_CXXAllocator,
   CE_BEG_FUNCTION_CALLS = CE_Function,
   CE_END_FUNCTION_CALLS = CE_CXXAllocator,
@@ -377,7 +377,7 @@
   }
 };
 
-/// \brief Represents a call to a written as a CallExpr.
+/// \brief Represents a call to a non-C++ function, written as a CallExpr.
 class SimpleCall : public AnyFunctionCall {
 protected:
   SimpleCall(const CallExpr *CE, ProgramStateRef St,
@@ -426,109 +426,6 @@
   }
 };
 
-/// \brief Represents a non-static C++ member function call, no matter how
-/// it is written.
-class CXXInstanceCall : public SimpleCall {
-protected:
-  virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
-
-  CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
-                  const LocationContext *LCtx)
-    : SimpleCall(CE, St, LCtx) {}
-
-  CXXInstanceCall(const CXXInstanceCall &Other) : SimpleCall(Other) {}
-
-public:
-  /// \brief Returns the expression representing the implicit 'this' object.
-  virtual const Expr *getCXXThisExpr() const = 0;
-
-  /// \brief Returns the value of the implicit 'this' object.
-  SVal getCXXThisVal() const {
-    const Expr *Base = getCXXThisExpr();
-    // FIXME: This doesn't handle an overloaded ->* operator.
-    if (!Base)
-      return UnknownVal();
-    return getSVal(Base);
-  }
-
-  virtual RuntimeDefinition getRuntimeDefinition() const;
-
-  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
-                                            BindingsTy &Bindings) const;
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS &&
-           CA->getKind() <= CE_END_CXX_INSTANCE_CALLS;
-  }
-};
-
-/// \brief Represents a non-static C++ member function call.
-///
-/// Example: \c obj.fun()
-class CXXMemberCall : public CXXInstanceCall {
-  friend class CallEventManager;
-
-protected:
-  CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St,
-                const LocationContext *LCtx)
-    : CXXInstanceCall(CE, St, LCtx) {}
-
-  CXXMemberCall(const CXXMemberCall &Other) : CXXInstanceCall(Other) {}
-  virtual void cloneTo(void *Dest) const { new (Dest) CXXMemberCall(*this); }
-
-public:
-  virtual const CXXMemberCallExpr *getOriginExpr() const {
-    return cast<CXXMemberCallExpr>(SimpleCall::getOriginExpr());
-  }
-
-  virtual const Expr *getCXXThisExpr() const;
-
-  virtual Kind getKind() const { return CE_CXXMember; }
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() == CE_CXXMember;
-  }
-};
-
-/// \brief Represents a C++ overloaded operator call where the operator is
-/// implemented as a non-static member function.
-///
-/// Example: <tt>iter + 1</tt>
-class CXXMemberOperatorCall : public CXXInstanceCall {
-  friend class CallEventManager;
-
-protected:
-  CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
-                        const LocationContext *LCtx)
-    : CXXInstanceCall(CE, St, LCtx) {}
-
-  CXXMemberOperatorCall(const CXXMemberOperatorCall &Other)
-    : CXXInstanceCall(Other) {}
-  virtual void cloneTo(void *Dest) const {
-    new (Dest) CXXMemberOperatorCall(*this);
-  }
-
-public:
-  virtual const CXXOperatorCallExpr *getOriginExpr() const {
-    return cast<CXXOperatorCallExpr>(SimpleCall::getOriginExpr());
-  }
-
-  virtual unsigned getNumArgs() const {
-    return getOriginExpr()->getNumArgs() - 1;
-  }
-  virtual const Expr *getArgExpr(unsigned Index) const {
-    return getOriginExpr()->getArg(Index + 1);
-  }
-
-  virtual const Expr *getCXXThisExpr() const;
-
-  virtual Kind getKind() const { return CE_CXXMemberOperator; }
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() == CE_CXXMemberOperator;
-  }
-};
-
 /// \brief Represents a call to a block.
 ///
 /// Example: <tt>^{ /* ... */ }()</tt>
@@ -581,6 +478,165 @@
   }
 };
 
+/// \brief Represents a non-static C++ member function call, no matter how
+/// it is written.
+class CXXInstanceCall : public AnyFunctionCall {
+protected:
+  virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
+
+  CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
+                  const LocationContext *LCtx)
+    : AnyFunctionCall(CE, St, LCtx) {}
+  CXXInstanceCall(const FunctionDecl *D, ProgramStateRef St,
+                  const LocationContext *LCtx)
+    : AnyFunctionCall(D, St, LCtx) {}
+
+
+  CXXInstanceCall(const CXXInstanceCall &Other) : AnyFunctionCall(Other) {}
+
+public:
+  /// \brief Returns the expression representing the implicit 'this' object.
+  virtual const Expr *getCXXThisExpr() const { return 0; }
+
+  /// \brief Returns the value of the implicit 'this' object.
+  virtual SVal getCXXThisVal() const {
+    const Expr *Base = getCXXThisExpr();
+    // FIXME: This doesn't handle an overloaded ->* operator.
+    if (!Base)
+      return UnknownVal();
+    return getSVal(Base);
+  }
+
+  virtual const FunctionDecl *getDecl() const;
+
+  virtual RuntimeDefinition getRuntimeDefinition() const;
+
+  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                            BindingsTy &Bindings) const;
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS &&
+           CA->getKind() <= CE_END_CXX_INSTANCE_CALLS;
+  }
+};
+
+/// \brief Represents a non-static C++ member function call.
+///
+/// Example: \c obj.fun()
+class CXXMemberCall : public CXXInstanceCall {
+  friend class CallEventManager;
+
+protected:
+  CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St,
+                const LocationContext *LCtx)
+    : CXXInstanceCall(CE, St, LCtx) {}
+
+  CXXMemberCall(const CXXMemberCall &Other) : CXXInstanceCall(Other) {}
+  virtual void cloneTo(void *Dest) const { new (Dest) CXXMemberCall(*this); }
+
+public:
+  virtual const CXXMemberCallExpr *getOriginExpr() const {
+    return cast<CXXMemberCallExpr>(CXXInstanceCall::getOriginExpr());
+  }
+
+  virtual unsigned getNumArgs() const {
+    if (const CallExpr *CE = getOriginExpr())
+      return CE->getNumArgs();
+    return 0;
+  }
+
+  virtual const Expr *getArgExpr(unsigned Index) const {
+    return getOriginExpr()->getArg(Index);
+  }
+
+  virtual const Expr *getCXXThisExpr() const;
+
+  virtual Kind getKind() const { return CE_CXXMember; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_CXXMember;
+  }
+};
+
+/// \brief Represents a C++ overloaded operator call where the operator is
+/// implemented as a non-static member function.
+///
+/// Example: <tt>iter + 1</tt>
+class CXXMemberOperatorCall : public CXXInstanceCall {
+  friend class CallEventManager;
+
+protected:
+  CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
+                        const LocationContext *LCtx)
+    : CXXInstanceCall(CE, St, LCtx) {}
+
+  CXXMemberOperatorCall(const CXXMemberOperatorCall &Other)
+    : CXXInstanceCall(Other) {}
+  virtual void cloneTo(void *Dest) const {
+    new (Dest) CXXMemberOperatorCall(*this);
+  }
+
+public:
+  virtual const CXXOperatorCallExpr *getOriginExpr() const {
+    return cast<CXXOperatorCallExpr>(CXXInstanceCall::getOriginExpr());
+  }
+
+  virtual unsigned getNumArgs() const {
+    return getOriginExpr()->getNumArgs() - 1;
+  }
+  virtual const Expr *getArgExpr(unsigned Index) const {
+    return getOriginExpr()->getArg(Index + 1);
+  }
+
+  virtual const Expr *getCXXThisExpr() const;
+
+  virtual Kind getKind() const { return CE_CXXMemberOperator; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_CXXMemberOperator;
+  }
+};
+
+/// \brief Represents an implicit call to a C++ destructor.
+///
+/// This can occur at the end of a scope (for automatic objects), at the end
+/// of a full-expression (for temporaries), or as part of a delete.
+class CXXDestructorCall : public CXXInstanceCall {
+  friend class CallEventManager;
+
+protected:
+  /// Creates an implicit destructor.
+  ///
+  /// \param DD The destructor that will be called.
+  /// \param Trigger The statement whose completion causes this destructor call.
+  /// \param Target The object region to be destructed.
+  /// \param St The path-sensitive state at this point in the program.
+  /// \param LCtx The location context at this point in the program.
+  CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
+                    const MemRegion *Target, ProgramStateRef St,
+                    const LocationContext *LCtx)
+    : CXXInstanceCall(DD, St, LCtx) {
+    Data = Target;
+    Location = Trigger->getLocEnd();
+  }
+
+  CXXDestructorCall(const CXXDestructorCall &Other) : CXXInstanceCall(Other) {}
+  virtual void cloneTo(void *Dest) const { new (Dest) CXXDestructorCall(*this); }
+
+public:
+  virtual SourceRange getSourceRange() const { return Location; }
+  virtual unsigned getNumArgs() const { return 0; }
+
+  /// \brief Returns the value of the implicit 'this' object.
+  virtual SVal getCXXThisVal() const;
+
+  virtual Kind getKind() const { return CE_CXXDestructor; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_CXXDestructor;
+  }
+};
+
 /// \brief Represents a call to a C++ constructor.
 ///
 /// Example: \c T(1)
@@ -622,7 +678,7 @@
   }
 
   /// \brief Returns the value of the implicit 'this' object.
-  virtual SVal getCXXThisVal() const;
+  SVal getCXXThisVal() const;
 
   virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
                                             BindingsTy &Bindings) const;
@@ -634,53 +690,6 @@
   }
 };
 
-/// \brief Represents an implicit call to a C++ destructor.
-///
-/// This can occur at the end of a scope (for automatic objects), at the end
-/// of a full-expression (for temporaries), or as part of a delete.
-class CXXDestructorCall : public AnyFunctionCall {
-  friend class CallEventManager;
-
-protected:
-  /// Creates an implicit destructor.
-  ///
-  /// \param DD The destructor that will be called.
-  /// \param Trigger The statement whose completion causes this destructor call.
-  /// \param Target The object region to be destructed.
-  /// \param St The path-sensitive state at this point in the program.
-  /// \param LCtx The location context at this point in the program.
-  CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
-                    const MemRegion *Target, ProgramStateRef St,
-                    const LocationContext *LCtx)
-    : AnyFunctionCall(DD, St, LCtx) {
-    Data = Target;
-    Location = Trigger->getLocEnd();
-  }
-
-  CXXDestructorCall(const CXXDestructorCall &Other) : AnyFunctionCall(Other) {}
-  virtual void cloneTo(void *Dest) const { new (Dest) CXXDestructorCall(*this); }
-
-  virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
-
-public:
-  virtual SourceRange getSourceRange() const { return Location; }
-  virtual unsigned getNumArgs() const { return 0; }
-
-  /// \brief Returns the value of the implicit 'this' object.
-  virtual SVal getCXXThisVal() const;
-
-  virtual RuntimeDefinition getRuntimeDefinition() const;
-
-  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
-                                            BindingsTy &Bindings) const;
-
-  virtual Kind getKind() const { return CE_CXXDestructor; }
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() == CE_CXXDestructor;
-  }
-};
-
 /// \brief Represents the memory allocation call in a C++ new-expression.
 ///
 /// This is a call to "operator new".
@@ -874,7 +883,7 @@
   getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State);
 
 
-  CallEventRef<SimpleCall>
+  CallEventRef<>
   getSimpleCall(const CallExpr *E, ProgramStateRef State,
                 const LocationContext *LCtx);
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 792b24e..4addb9d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -463,8 +463,10 @@
                                   const LocationContext *LCtx,
                                   ProgramStateRef State);
 
+  /// Evaluate a call, running pre- and post-call checks and allowing checkers
+  /// to be responsible for handling the evaluation of the call itself.
   void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
-                const SimpleCall &Call);
+                const CallEvent &Call);
 
   /// \brief Default implementation of call evaluation.
   void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred,
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index cacd347..e3f4c61 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -355,6 +355,18 @@
 }
 
 
+const FunctionDecl *CXXInstanceCall::getDecl() const {
+  const CallExpr *CE = cast_or_null<CallExpr>(getOriginExpr());
+  if (!CE)
+    return AnyFunctionCall::getDecl();
+
+  const FunctionDecl *D = CE->getDirectCallee();
+  if (D)
+    return D;
+
+  return getSVal(CE->getCallee()).getAsFunctionDecl();
+}
+
 void CXXInstanceCall::getExtraInvalidatedRegions(RegionList &Regions) const {
   if (const MemRegion *R = getCXXThisVal().getAsRegion())
     Regions.push_back(R);
@@ -389,7 +401,7 @@
 
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
   if (!MD->isVirtual())
-    return SimpleCall::getRuntimeDefinition();
+    return AnyFunctionCall::getRuntimeDefinition();
 
   // If the method is virtual, see if we can find the actual implementation
   // based on context-sensitivity.
@@ -527,46 +539,6 @@
   return UnknownVal();
 }
 
-void CXXDestructorCall::getExtraInvalidatedRegions(RegionList &Regions) const {
-  if (Data)
-    Regions.push_back(static_cast<const MemRegion *>(Data));
-}
-
-RuntimeDefinition CXXDestructorCall::getRuntimeDefinition() const {
-  const Decl *D = AnyFunctionCall::getRuntimeDefinition().getDecl();
-  if (!D)
-    return RuntimeDefinition();
-
-  const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
-  if (!MD->isVirtual())
-    return RuntimeDefinition(MD);
-
-  // If the method is virtual, see if we can find the actual implementation
-  // based on context-sensitivity.
-  // FIXME: Virtual method calls behave differently when an object is being
-  // constructed or destructed. It's not as simple as "no devirtualization"
-  // because a /partially/ constructed object can be referred to through a
-  // base pointer. We'll eventually want to use DynamicTypeInfo here.
-  if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal()))
-    return RuntimeDefinition(Devirtualized);
-
-  return RuntimeDefinition();
-}
-
-void CXXDestructorCall::getInitialStackFrameContents(
-                                             const StackFrameContext *CalleeCtx,
-                                             BindingsTy &Bindings) const {
-  AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
-
-  SVal ThisVal = getCXXThisVal();
-  if (!ThisVal.isUnknown()) {
-    SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
-    const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
-    Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
-    Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
-  }
-}
-
 
 CallEvent::param_iterator ObjCMethodCall::param_begin() const {
   const ObjCMethodDecl *D = getDecl();
@@ -805,7 +777,7 @@
   }
 }
 
-CallEventRef<SimpleCall>
+CallEventRef<>
 CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State,
                                 const LocationContext *LCtx) {
   if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE))
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index 564404e..c786655 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -504,9 +504,9 @@
 /// Only one checker will evaluate the call.
 void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst,
                                             const ExplodedNodeSet &Src,
-                                            const SimpleCall &Call,
+                                            const CallEvent &Call,
                                             ExprEngine &Eng) {
-  const CallExpr *CE = Call.getOriginExpr();
+  const CallExpr *CE = cast<CallExpr>(Call.getOriginExpr());
   for (ExplodedNodeSet::iterator
          NI = Src.begin(), NE = Src.end(); NI != NE; ++NI) {
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 37c48d4..8ee6723 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -445,7 +445,7 @@
   // Get the call in its initial state. We use this as a template to perform
   // all the checks.
   CallEventManager &CEMgr = getStateManager().getCallEventManager();
-  CallEventRef<SimpleCall> CallTemplate
+  CallEventRef<> CallTemplate
     = CEMgr.getSimpleCall(CE, Pred->getState(), Pred->getLocationContext());
 
   // Evaluate the function call.  We try each of the checkers
@@ -465,7 +465,7 @@
 }
 
 void ExprEngine::evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
-                          const SimpleCall &Call) {
+                          const CallEvent &Call) {
   // WARNING: At this time, the state attached to 'Call' may be older than the
   // state in 'Pred'. This is a minor optimization since CheckerManager will
   // use an updated CallEvent instance when calling checkers, but if 'Call' is