[analyzer] Improve readability of the dyn. dispatch bifurcation patch
r161552.

As per Jordan's feedback.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161603 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index 67bc142..5e008bd 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -68,15 +68,24 @@
   }
 };
 
+/// \brief Defines the runtime definition of the called function.
 class RuntimeDefinition {
+  /// The Declaration of the function which will be called at runtime.
+  /// 0 if not available.
   const Decl *D;
+
+  /// The region representing an object (ObjC/C++) on which the method is
+  /// called. With dynamic dispatch, the method definition depends on the
+  /// runtime type of this object. 0 when there is no dynamic dispatch.
   const MemRegion *R;
+
 public:
   RuntimeDefinition(): D(0), R(0) {}
   RuntimeDefinition(const Decl *InD): D(InD), R(0) {}
   RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {}
-  const Decl *getDecl() { return D;}
-  const MemRegion *getReg() {return R;}
+  const Decl *getDecl() { return D; }
+  const MemRegion *getDispatchRegion() { return R; }
+  bool mayHaveOtherDefinitions() { return R != 0; }
 };
 
 /// \brief Represents an abstract call to a function or method along a
@@ -170,8 +179,7 @@
   }
 
   /// \brief Returns the definition of the function or method that will be
-  /// called. Returns NULL if the definition cannot be found; ex: due to
-  /// dynamic dispatch in ObjC methods.
+  /// called.
   virtual RuntimeDefinition getRuntimeDefinition() const = 0;
 
   /// \brief Returns the expression whose value will be the result of this call.
@@ -351,7 +359,7 @@
     const FunctionDecl *FD = getDecl();
     // Note that hasBody() will fill FD with the definition FunctionDecl.
     if (FD && FD->hasBody(FD))
-      return RuntimeDefinition(FD, 0);
+      return RuntimeDefinition(FD);
     return RuntimeDefinition();
   }
 
@@ -557,7 +565,7 @@
   }
 
   virtual RuntimeDefinition getRuntimeDefinition() const {
-    return RuntimeDefinition(getBlockDecl(), 0);
+    return RuntimeDefinition(getBlockDecl());
   }
 
   virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index 8b96035..13bdaa7 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -389,7 +389,7 @@
 
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
   if (!MD->isVirtual())
-    return RuntimeDefinition(MD, 0);
+    return RuntimeDefinition(MD);
 
   // If the method is virtual, see if we can find the actual implementation
   // based on context-sensitivity.
@@ -398,7 +398,7 @@
   // 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, 0);
+    return RuntimeDefinition(Devirtualized);
 
   return RuntimeDefinition();
 }
@@ -519,7 +519,7 @@
 
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
   if (!MD->isVirtual())
-    return RuntimeDefinition(MD, 0);
+    return RuntimeDefinition(MD);
 
   // If the method is virtual, see if we can find the actual implementation
   // based on context-sensitivity.
@@ -528,7 +528,7 @@
   // 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, 0);
+    return RuntimeDefinition(Devirtualized);
 
   return RuntimeDefinition();
 }
@@ -695,7 +695,7 @@
     // class name.
     if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) {
       // Find/Return the method implementation.
-      return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel), 0);
+      return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel));
     }
   }
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index d3d097c..2b0ac1d 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -534,6 +534,10 @@
   ProgramStateRef State = Pred->getState();
   CallEventRef<> Call = CallTemplate.cloneWithState(State);
 
+  if (!getAnalysisManager().shouldInlineCall()) {
+    conservativeEvalCall(*Call, Bldr, Pred, State);
+    return;
+  }
   // Try to inline the call.
   // The origin expression here is just used as a kind of checksum;
   // this should still be safe even for CallEvents that don't come from exprs.
@@ -543,21 +547,19 @@
   if (InlinedFailedState) {
     // If we already tried once and failed, make sure we don't retry later.
     State = InlinedFailedState;
-  } else if (getAnalysisManager().shouldInlineCall()) {
+  } else {
     RuntimeDefinition RD = Call->getRuntimeDefinition();
     const Decl *D = RD.getDecl();
     if (D) {
       // Explore with and without inlining the call.
-      const MemRegion *BifurReg = RD.getReg();
-      if (BifurReg &&
+      if (RD.mayHaveOtherDefinitions() &&
           getAnalysisManager().IPAMode == DynamicDispatchBifurcate) {
-        BifurcateCall(BifurReg, *Call, D, Bldr, Pred);
+        BifurcateCall(RD.getDispatchRegion(), *Call, D, Bldr, Pred);
         return;
-      } else {
-        // We are not bifurcating and we do have a Decl, so just inline.
-        if (inlineCall(*Call, D, Bldr, Pred, State))
-          return;
       }
+      // We are not bifurcating and we do have a Decl, so just inline.
+      if (inlineCall(*Call, D, Bldr, Pred, State))
+        return;
     }
   }
 
@@ -573,20 +575,17 @@
   // Check if we've performed the split already - note, we only want
   // to split the path once per memory region.
   ProgramStateRef State = Pred->getState();
-  DynamicDispatchBifur BM = State->get<DynamicDispatchBifurcationMap>();
-  for (DynamicDispatchBifur::iterator I = BM.begin(),
-                                      E = BM.end(); I != E; ++I) {
-    if (I->first == BifurReg) {
-      // If we are on "inline path", keep inlining if possible.
-      if (I->second == true)
-        if (inlineCall(Call, D, Bldr, Pred, State))
-          return;
-      // If inline failed, or we are on the path where we assume we
-      // don't have enough info about the receiver to inline, conjure the
-      // return value and invalidate the regions.
-      conservativeEvalCall(Call, Bldr, Pred, State);
-      return;
-    }
+  const int *BState = State->get<DynamicDispatchBifurcationMap>(BifurReg);
+  if (BState) {
+    // If we are on "inline path", keep inlining if possible.
+    if (*BState == true)
+      if (inlineCall(Call, D, Bldr, Pred, State))
+        return;
+    // If inline failed, or we are on the path where we assume we
+    // don't have enough info about the receiver to inline, conjure the
+    // return value and invalidate the regions.
+    conservativeEvalCall(Call, Bldr, Pred, State);
+    return;
   }
 
   // If we got here, this is the first time we process a message to this