[analyzer] Refactor checkers to use helper function for getting callee Decl and name.

We are getting name of the called function or it's declaration in a few checkers. Refactor them to use the helper function in the CheckerContext. 

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145576 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 6f4bdd4..02c92c9 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -142,6 +142,9 @@
     Eng.getBugReporter().EmitReport(R);
   }
 
+  /// \brief Get the declaration of the called function (path-sensitive).
+  const FunctionDecl *getCalleeDecl(const CallExpr *CE) const;
+
   /// \brief Get the name of the called function (path-sensitive).
   StringRef getCalleeName(const CallExpr *CE) const;
 
diff --git a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index bc6e8f3..1f62729 100644
--- a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -249,11 +249,8 @@
 
 void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
                                          CheckerContext &C) const {
-  const Expr *Callee = CE->getCallee();
   const ProgramState *state = C.getState();
-  SVal CallV = state->getSVal(Callee);
-  const FunctionDecl *FD = CallV.getAsFunctionDecl();
-
+  const FunctionDecl *FD = C.getCalleeDecl(CE);
   if (!FD)
     return;
   
@@ -363,11 +360,8 @@
   if (CE->getNumArgs() != 1)
     return;
 
-  // Get the function declaration of the callee.
   const ProgramState *state = C.getState();
-  SVal X = state->getSVal(CE->getCallee());
-  const FunctionDecl *FD = X.getAsFunctionDecl();
-
+  const FunctionDecl *FD = C.getCalleeDecl(CE);
   if (!FD)
     return;
   
diff --git a/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
index 4ad7cc9..2cf1209 100644
--- a/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -30,12 +30,9 @@
 }
 
 bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
-                                      CheckerContext &C) const{
+                                      CheckerContext &C) const {
   const ProgramState *state = C.getState();
-  const Expr *Callee = CE->getCallee();
-  SVal L = state->getSVal(Callee);
-  const FunctionDecl *FD = L.getAsFunctionDecl();
-
+  const FunctionDecl *FD = C.getCalleeDecl(CE);
   if (!FD)
     return false;
 
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 4299a12..6ab98b4 100644
--- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -1664,20 +1664,9 @@
 //===----------------------------------------------------------------------===//
 
 bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
-  // Get the callee.  All the functions we care about are C functions
-  // with simple identifiers.
-  const ProgramState *state = C.getState();
-  const Expr *Callee = CE->getCallee();
-  const FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl();
-
-  if (!FD)
+  StringRef Name = C.getCalleeName(CE);
+  if (Name.empty())
     return false;
-
-  // Get the name of the callee. If it's a builtin, strip off the prefix.
-  IdentifierInfo *II = FD->getIdentifier();
-  if (!II)   // if no identifier, not a simple C function
-    return false;
-  StringRef Name = II->getName();
   if (Name.startswith("__builtin_"))
     Name = Name.substr(10);
 
diff --git a/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp b/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
index 2f3ff26..fa79f21 100644
--- a/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
@@ -62,10 +62,7 @@
 } // end anonymous namespace
 
 bool ChrootChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
-  const ProgramState *state = C.getState();
-  const Expr *Callee = CE->getCallee();
-  SVal L = state->getSVal(Callee);
-  const FunctionDecl *FD = L.getAsFunctionDecl();
+  const FunctionDecl *FD = C.getCalleeDecl(CE);
   if (!FD)
     return false;
 
@@ -125,10 +122,7 @@
 
 // Check the jail state before any function call except chroot and chdir().
 void ChrootChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
-  const ProgramState *state = C.getState();
-  const Expr *Callee = CE->getCallee();
-  SVal L = state->getSVal(Callee);
-  const FunctionDecl *FD = L.getAsFunctionDecl();
+  const FunctionDecl *FD = C.getCalleeDecl(CE);
   if (!FD)
     return;
 
@@ -143,7 +137,7 @@
     return;
   
   // If jail state is ROOT_CHANGED, generate BugReport.
-  void *const* k = state->FindGDM(ChrootChecker::getTag());
+  void *const* k = C.getState()->FindGDM(ChrootChecker::getTag());
   if (k)
     if (isRootChanged((intptr_t) *k))
       if (ExplodedNode *N = C.addTransition()) {
diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
index c9de38c..b496842 100644
--- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
@@ -281,18 +281,12 @@
 
 void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
                                            CheckerContext &C) const {
-  const ProgramState *State = C.getState();
-  const Expr *Callee = CE->getCallee();
-  SVal L = State->getSVal(Callee);
   unsigned idx = InvalidIdx;
+  const ProgramState *State = C.getState();
 
-  const FunctionDecl *funDecl = L.getAsFunctionDecl();
-  if (!funDecl)
+  StringRef funName = C.getCalleeName(CE);
+  if (funName.empty())
     return;
-  IdentifierInfo *funI = funDecl->getIdentifier();
-  if (!funI)
-    return;
-  StringRef funName = funI->getName();
 
   // If it is a call to an allocator function, it could be a double allocation.
   idx = getTrackedFunctionIndex(funName, true);
diff --git a/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
index 88d492e..f8c0104 100644
--- a/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
@@ -37,11 +37,11 @@
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
 
   void CheckDispatchOnce(CheckerContext &C, const CallExpr *CE,
-                         const IdentifierInfo *FI) const;
+                         StringRef FName) const;
 
   typedef void (MacOSXAPIChecker::*SubChecker)(CheckerContext &,
                                                const CallExpr *,
-                                               const IdentifierInfo *) const;
+                                               StringRef FName) const;
 };
 } //end anonymous namespace
 
@@ -50,7 +50,7 @@
 //===----------------------------------------------------------------------===//
 
 void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE,
-                                         const IdentifierInfo *FI) const {
+                                         StringRef FName) const {
   if (CE->getNumArgs() < 1)
     return;
 
@@ -71,7 +71,7 @@
 
   llvm::SmallString<256> S;
   llvm::raw_svector_ostream os(S);
-  os << "Call to '" << FI->getName() << "' uses";
+  os << "Call to '" << FName << "' uses";
   if (const VarRegion *VR = dyn_cast<VarRegion>(R))
     os << " the local variable '" << VR->getDecl()->getName() << '\'';
   else
@@ -92,27 +92,18 @@
 
 void MacOSXAPIChecker::checkPreStmt(const CallExpr *CE,
                                     CheckerContext &C) const {
-  // FIXME: This sort of logic is common to several checkers, including
-  // UnixAPIChecker, PthreadLockChecker, and CStringChecker.  Should refactor.
-  const ProgramState *state = C.getState();
-  const Expr *Callee = CE->getCallee();
-  const FunctionDecl *Fn = state->getSVal(Callee).getAsFunctionDecl();
-
-  if (!Fn)
-    return;
-
-  const IdentifierInfo *FI = Fn->getIdentifier();
-  if (!FI)
+  StringRef Name = C.getCalleeName(CE);
+  if (Name.empty())
     return;
 
   SubChecker SC =
-    llvm::StringSwitch<SubChecker>(FI->getName())
+    llvm::StringSwitch<SubChecker>(Name)
       .Cases("dispatch_once", "dispatch_once_f",
              &MacOSXAPIChecker::CheckDispatchOnce)
       .Default(NULL);
 
   if (SC)
-    (this->*SC)(C, CE, FI);
+    (this->*SC)(C, CE, Name);
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index f217df9..dd919e3 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -128,11 +128,7 @@
 }
 
 bool MallocChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
-  const ProgramState *state = C.getState();
-  const Expr *Callee = CE->getCallee();
-  SVal L = state->getSVal(Callee);
-
-  const FunctionDecl *FD = L.getAsFunctionDecl();
+  const FunctionDecl *FD = C.getCalleeDecl(CE);
   if (!FD)
     return false;
 
diff --git a/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp b/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
index 7bdb871..27d8fb5 100644
--- a/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
@@ -35,24 +35,27 @@
 };
 }
 
+static StringRef getCalleeName(const ProgramState *State,
+                               const CallExpr *CE) {
+  const Expr *Callee = CE->getCallee();
+  SVal L = State->getSVal(Callee);
+  const FunctionDecl *funDecl =  L.getAsFunctionDecl();
+  if (!funDecl)
+    return StringRef();
+  IdentifierInfo *funI = funDecl->getIdentifier();
+  if (!funI)
+    return StringRef();
+  return funI->getName();
+}
+
 bool OSAtomicChecker::inlineCall(const CallExpr *CE,
                                  ExprEngine &Eng,
                                  ExplodedNode *Pred,
                                  ExplodedNodeSet &Dst) const {
-  const ProgramState *state = Pred->getState();
-  const Expr *Callee = CE->getCallee();
-  SVal L = state->getSVal(Callee);
-
-  const FunctionDecl *FD = L.getAsFunctionDecl();
-  if (!FD)
+  StringRef FName = getCalleeName(Pred->getState(), CE);
+  if (FName.empty())
     return false;
 
-  const IdentifierInfo *II = FD->getIdentifier();
-  if (!II)
-    return false;
-  
-  StringRef FName(II->getName());
-
   // Check for compare and swap.
   if (FName.startswith("OSAtomicCompareAndSwap") ||
       FName.startswith("objc_atomicCompareAndSwap"))
diff --git a/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp b/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
index c02b5b1..45988f0 100644
--- a/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
@@ -57,18 +57,10 @@
 void PthreadLockChecker::checkPostStmt(const CallExpr *CE,
                                        CheckerContext &C) const {
   const ProgramState *state = C.getState();
-  const Expr *Callee = CE->getCallee();
-  const FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl();
-
-  if (!FD)
+  StringRef FName = C.getCalleeName(CE);
+  if (FName.empty())
     return;
 
-  // Get the name of the callee.
-  IdentifierInfo *II = FD->getIdentifier();
-  if (!II)   // if no identifier, not a simple C function
-    return;
-  StringRef FName = II->getName();
-
   if (CE->getNumArgs() != 1)
     return;
 
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 9537b31..22cd050 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -2990,10 +2990,7 @@
 bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
   // Get the callee. We're only interested in simple C functions.
   const ProgramState *state = C.getState();
-  const Expr *Callee = CE->getCallee();
-  SVal L = state->getSVal(Callee);
-
-  const FunctionDecl *FD = L.getAsFunctionDecl();
+  const FunctionDecl *FD = C.getCalleeDecl(CE);
   if (!FD)
     return false;
 
@@ -3015,7 +3012,7 @@
   // See if it's one of the specific functions we know how to eval.
   bool canEval = false;
 
-  QualType ResultTy = FD->getResultType();
+  QualType ResultTy = CE->getCallReturnType();
   if (ResultTy->isObjCIdType()) {
     // Handle: id NSMakeCollectable(CFTypeRef)
     canEval = II->isStr("NSMakeCollectable");
diff --git a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 94ff266..2f96bbf 100644
--- a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -115,10 +115,7 @@
 }
 
 bool StreamChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
-  const ProgramState *state = C.getState();
-  const Expr *Callee = CE->getCallee();
-  SVal L = state->getSVal(Callee);
-  const FunctionDecl *FD = L.getAsFunctionDecl();
+  const FunctionDecl *FD = C.getCalleeDecl(CE);
   if (!FD)
     return false;
 
diff --git a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index cec286d..e955f9e 100644
--- a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -224,21 +224,12 @@
 //===----------------------------------------------------------------------===//
 
 void UnixAPIChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
-  // Get the callee.  All the functions we care about are C functions
-  // with simple identifiers.
-  const ProgramState *state = C.getState();
-  const Expr *Callee = CE->getCallee();
-  const FunctionDecl *Fn = state->getSVal(Callee).getAsFunctionDecl();
-
-  if (!Fn)
-    return;
-
-  const IdentifierInfo *FI = Fn->getIdentifier();
-  if (!FI)
+  StringRef FName = C.getCalleeName(CE);
+  if (FName.empty())
     return;
 
   SubChecker SC =
-    llvm::StringSwitch<SubChecker>(FI->getName())
+    llvm::StringSwitch<SubChecker>(FName)
       .Case("open", &UnixAPIChecker::CheckOpen)
       .Case("pthread_once", &UnixAPIChecker::CheckPthreadOnce)
       .Case("malloc", &UnixAPIChecker::CheckMallocZero)
diff --git a/lib/StaticAnalyzer/Core/CheckerContext.cpp b/lib/StaticAnalyzer/Core/CheckerContext.cpp
index 75cb82a..5552a99 100644
--- a/lib/StaticAnalyzer/Core/CheckerContext.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerContext.cpp
@@ -16,12 +16,15 @@
 using namespace clang;
 using namespace ento;
 
-StringRef CheckerContext::getCalleeName(const CallExpr *CE) const {
+const FunctionDecl *CheckerContext::getCalleeDecl(const CallExpr *CE) const {
   const ProgramState *State = getState();
   const Expr *Callee = CE->getCallee();
   SVal L = State->getSVal(Callee);
+  return L.getAsFunctionDecl();
+}
 
-  const FunctionDecl *funDecl = L.getAsFunctionDecl();
+StringRef CheckerContext::getCalleeName(const CallExpr *CE) const {
+  const FunctionDecl *funDecl = getCalleeDecl(CE);
   if (!funDecl)
     return StringRef();
   IdentifierInfo *funI = funDecl->getIdentifier();