More code reshuffling.  No functionality change.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68157 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp
index 8a37d1a..1d1c2fa 100644
--- a/lib/Analysis/BugReporter.cpp
+++ b/lib/Analysis/BugReporter.cpp
@@ -31,7 +31,7 @@
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
-// static functions.
+// Helper routines for walking the ExplodedGraph and fetching statements.
 //===----------------------------------------------------------------------===//
 
 static inline Stmt* GetStmt(ProgramPoint P) {
@@ -99,7 +99,7 @@
 }
 
 //===----------------------------------------------------------------------===//
-// Diagnostics for 'execution continues on line XXX'.
+// PathDiagnosticBuilder and its associated routines and helper objects.
 //===----------------------------------------------------------------------===//
 
 typedef llvm::DenseMap<const ExplodedNode<GRState>*,
@@ -252,6 +252,469 @@
 }
 
 //===----------------------------------------------------------------------===//
+// ScanNotableSymbols: closure-like callback for scanning Store bindings.
+//===----------------------------------------------------------------------===//
+
+static const VarDecl*
+GetMostRecentVarDeclBinding(const ExplodedNode<GRState>* N,
+                            GRStateManager& VMgr, SVal X) {
+  
+  for ( ; N ; N = N->pred_empty() ? 0 : *N->pred_begin()) {
+    
+    ProgramPoint P = N->getLocation();
+    
+    if (!isa<PostStmt>(P))
+      continue;
+    
+    DeclRefExpr* DR = dyn_cast<DeclRefExpr>(cast<PostStmt>(P).getStmt());
+    
+    if (!DR)
+      continue;
+    
+    SVal Y = VMgr.GetSVal(N->getState(), DR);
+    
+    if (X != Y)
+      continue;
+    
+    VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl());
+    
+    if (!VD)
+      continue;
+    
+    return VD;
+  }
+  
+  return 0;
+}
+
+namespace {
+class VISIBILITY_HIDDEN NotableSymbolHandler 
+: public StoreManager::BindingsHandler {
+  
+  SymbolRef Sym;
+  const GRState* PrevSt;
+  const Stmt* S;
+  GRStateManager& VMgr;
+  const ExplodedNode<GRState>* Pred;
+  PathDiagnostic& PD; 
+  BugReporter& BR;
+  
+public:
+  
+  NotableSymbolHandler(SymbolRef sym, const GRState* prevst, const Stmt* s,
+                       GRStateManager& vmgr, const ExplodedNode<GRState>* pred,
+                       PathDiagnostic& pd, BugReporter& br)
+  : Sym(sym), PrevSt(prevst), S(s), VMgr(vmgr), Pred(pred), PD(pd), BR(br) {}
+  
+  bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
+                     SVal V) {
+    
+    SymbolRef ScanSym = V.getAsSymbol();
+    
+    if (ScanSym != Sym)
+      return true;
+    
+    // Check if the previous state has this binding.    
+    SVal X = VMgr.GetSVal(PrevSt, loc::MemRegionVal(R));
+    
+    if (X == V) // Same binding?
+      return true;
+    
+    // Different binding.  Only handle assignments for now.  We don't pull
+    // this check out of the loop because we will eventually handle other 
+    // cases.
+    
+    VarDecl *VD = 0;
+    
+    if (const BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
+      if (!B->isAssignmentOp())
+        return true;
+      
+      // What variable did we assign to?
+      DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParenCasts());
+      
+      if (!DR)
+        return true;
+      
+      VD = dyn_cast<VarDecl>(DR->getDecl());
+    }
+    else if (const DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
+      // FIXME: Eventually CFGs won't have DeclStmts.  Right now we
+      //  assume that each DeclStmt has a single Decl.  This invariant
+      //  holds by contruction in the CFG.
+      VD = dyn_cast<VarDecl>(*DS->decl_begin());
+    }
+    
+    if (!VD)
+      return true;
+    
+    // What is the most recently referenced variable with this binding?
+    const VarDecl* MostRecent = GetMostRecentVarDeclBinding(Pred, VMgr, V);
+    
+    if (!MostRecent)
+      return true;
+    
+    // Create the diagnostic.
+    FullSourceLoc L(S->getLocStart(), BR.getSourceManager());
+    
+    if (Loc::IsLocType(VD->getType())) {
+      std::string msg = "'" + std::string(VD->getNameAsString()) +
+      "' now aliases '" + MostRecent->getNameAsString() + "'";
+      
+      PD.push_front(new PathDiagnosticEventPiece(L, msg));
+    }
+    
+    return true;
+  }  
+};
+}
+
+static void HandleNotableSymbol(const ExplodedNode<GRState>* N,
+                                const Stmt* S,
+                                SymbolRef Sym, BugReporter& BR,
+                                PathDiagnostic& PD) {
+  
+  const ExplodedNode<GRState>* Pred = N->pred_empty() ? 0 : *N->pred_begin();
+  const GRState* PrevSt = Pred ? Pred->getState() : 0;
+  
+  if (!PrevSt)
+    return;
+  
+  // Look at the region bindings of the current state that map to the
+  // specified symbol.  Are any of them not in the previous state?
+  GRStateManager& VMgr = cast<GRBugReporter>(BR).getStateManager();
+  NotableSymbolHandler H(Sym, PrevSt, S, VMgr, Pred, PD, BR);
+  cast<GRBugReporter>(BR).getStateManager().iterBindings(N->getState(), H);
+}
+
+namespace {
+class VISIBILITY_HIDDEN ScanNotableSymbols
+: public StoreManager::BindingsHandler {
+  
+  llvm::SmallSet<SymbolRef, 10> AlreadyProcessed;
+  const ExplodedNode<GRState>* N;
+  Stmt* S;
+  GRBugReporter& BR;
+  PathDiagnostic& PD;
+  
+public:
+  ScanNotableSymbols(const ExplodedNode<GRState>* n, Stmt* s, GRBugReporter& br,
+                     PathDiagnostic& pd)
+  : N(n), S(s), BR(br), PD(pd) {}
+  
+  bool HandleBinding(StoreManager& SMgr, Store store,
+                     const MemRegion* R, SVal V) {
+    
+    SymbolRef ScanSym = V.getAsSymbol();
+    
+    if (!ScanSym)
+      return true;
+    
+    if (!BR.isNotable(ScanSym))
+      return true;
+    
+    if (AlreadyProcessed.count(ScanSym))
+      return true;
+    
+    AlreadyProcessed.insert(ScanSym);
+    
+    HandleNotableSymbol(N, S, ScanSym, BR, PD);
+    return true;
+  }
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// "Minimal" path diagnostic generation algorithm.
+//===----------------------------------------------------------------------===//
+
+static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
+                                          PathDiagnosticBuilder &PDB,
+                                          const ExplodedNode<GRState> *N) {
+  ASTContext& Ctx = PDB.getContext();
+  SourceManager& SMgr = PDB.getSourceManager();
+  const ExplodedNode<GRState>* NextNode = N->pred_empty() 
+                                        ? NULL : *(N->pred_begin());
+  while (NextNode) {
+    N = NextNode;    
+    NextNode = GetPredecessorNode(N);
+    
+    ProgramPoint P = N->getLocation();
+    
+    if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
+      CFGBlock* Src = BE->getSrc();
+      CFGBlock* Dst = BE->getDst();
+      Stmt* T = Src->getTerminator();
+      
+      if (!T)
+        continue;
+      
+      FullSourceLoc Start(T->getLocStart(), SMgr);
+      
+      switch (T->getStmtClass()) {
+        default:
+          break;
+          
+        case Stmt::GotoStmtClass:
+        case Stmt::IndirectGotoStmtClass: {          
+          Stmt* S = GetNextStmt(N);
+          
+          if (!S)
+            continue;
+          
+          std::string sbuf;
+          llvm::raw_string_ostream os(sbuf);          
+          const PathDiagnosticLocation &End = PDB.getEnclosingStmtLocation(S);
+          
+          os << "Control jumps to line "
+          << End.asLocation().getInstantiationLineNumber();
+          PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                           os.str()));
+          break;
+        }
+          
+        case Stmt::SwitchStmtClass: {          
+          // Figure out what case arm we took.
+          std::string sbuf;
+          llvm::raw_string_ostream os(sbuf);
+          
+          if (Stmt* S = Dst->getLabel()) {
+            PathDiagnosticLocation End(S, SMgr);
+            
+            switch (S->getStmtClass()) {
+              default:
+                os << "No cases match in the switch statement. "
+                "Control jumps to line "
+                << End.asLocation().getInstantiationLineNumber();
+                break;
+              case Stmt::DefaultStmtClass:
+                os << "Control jumps to the 'default' case at line "
+                << End.asLocation().getInstantiationLineNumber();
+                break;
+                
+              case Stmt::CaseStmtClass: {
+                os << "Control jumps to 'case ";              
+                CaseStmt* Case = cast<CaseStmt>(S);              
+                Expr* LHS = Case->getLHS()->IgnoreParenCasts();
+                
+                // Determine if it is an enum.              
+                bool GetRawInt = true;
+                
+                if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) {
+                  // FIXME: Maybe this should be an assertion.  Are there cases
+                  // were it is not an EnumConstantDecl?
+                  EnumConstantDecl* D =
+                  dyn_cast<EnumConstantDecl>(DR->getDecl());
+                  
+                  if (D) {
+                    GetRawInt = false;
+                    os << D->getNameAsString();
+                  }
+                }
+                
+                if (GetRawInt) {
+                  
+                  // Not an enum.
+                  Expr* CondE = cast<SwitchStmt>(T)->getCond();
+                  unsigned bits = Ctx.getTypeSize(CondE->getType());
+                  llvm::APSInt V(bits, false);
+                  
+                  if (!LHS->isIntegerConstantExpr(V, Ctx, 0, true)) {
+                    assert (false && "Case condition must be constant.");
+                    continue;
+                  }
+                  
+                  os << V;
+                }       
+                
+                os << ":'  at line "
+                << End.asLocation().getInstantiationLineNumber();
+                break;
+              }
+            }
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                             os.str()));
+          }
+          else {
+            os << "'Default' branch taken. ";
+            const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);            
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                             os.str()));
+          }
+          
+          break;
+        }
+          
+        case Stmt::BreakStmtClass:
+        case Stmt::ContinueStmtClass: {
+          std::string sbuf;
+          llvm::raw_string_ostream os(sbuf);
+          PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
+          PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                           os.str()));
+          break;
+        }
+          
+          // Determine control-flow for ternary '?'.
+        case Stmt::ConditionalOperatorClass: {
+          std::string sbuf;
+          llvm::raw_string_ostream os(sbuf);
+          os << "'?' condition is ";
+          
+          if (*(Src->succ_begin()+1) == Dst)
+            os << "false";
+          else
+            os << "true";
+          
+          PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+          
+          if (const Stmt *S = End.asStmt())
+            End = PDB.getEnclosingStmtLocation(S);
+          
+          PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                           os.str()));
+          break;
+        }
+          
+          // Determine control-flow for short-circuited '&&' and '||'.
+        case Stmt::BinaryOperatorClass: {
+          if (!PDB.supportsLogicalOpControlFlow())
+            break;
+          
+          BinaryOperator *B = cast<BinaryOperator>(T);
+          std::string sbuf;
+          llvm::raw_string_ostream os(sbuf);
+          os << "Left side of '";
+          
+          if (B->getOpcode() == BinaryOperator::LAnd) {
+            os << "&&" << "' is ";
+            
+            if (*(Src->succ_begin()+1) == Dst) {
+              os << "false";
+              PathDiagnosticLocation End(B->getLHS(), SMgr);
+              PathDiagnosticLocation Start(B->getOperatorLoc(), SMgr);
+              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                               os.str()));
+            }            
+            else {
+              os << "true";
+              PathDiagnosticLocation Start(B->getLHS(), SMgr);
+              PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                               os.str()));
+            }              
+          }
+          else {
+            assert(B->getOpcode() == BinaryOperator::LOr);
+            os << "||" << "' is ";
+            
+            if (*(Src->succ_begin()+1) == Dst) {
+              os << "false";
+              PathDiagnosticLocation Start(B->getLHS(), SMgr);
+              PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                               os.str()));              
+            }
+            else {
+              os << "true";
+              PathDiagnosticLocation End(B->getLHS(), SMgr);
+              PathDiagnosticLocation Start(B->getOperatorLoc(), SMgr);
+              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                               os.str()));                            
+            }
+          }
+          
+          break;
+        }
+          
+        case Stmt::DoStmtClass:  {          
+          if (*(Src->succ_begin()) == Dst) {
+            std::string sbuf;
+            llvm::raw_string_ostream os(sbuf);
+            
+            os << "Loop condition is true. ";
+            PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
+            
+            if (const Stmt *S = End.asStmt())
+              End = PDB.getEnclosingStmtLocation(S);
+            
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                             os.str()));
+          }
+          else {
+            PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+            
+            if (const Stmt *S = End.asStmt())
+              End = PDB.getEnclosingStmtLocation(S);
+            
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                              "Loop condition is false.  Exiting loop"));
+          }
+          
+          break;
+        }
+          
+        case Stmt::WhileStmtClass:
+        case Stmt::ForStmtClass: {          
+          if (*(Src->succ_begin()+1) == Dst) {
+            std::string sbuf;
+            llvm::raw_string_ostream os(sbuf);
+            
+            os << "Loop condition is false. ";
+            PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
+            if (const Stmt *S = End.asStmt())
+              End = PDB.getEnclosingStmtLocation(S);
+            
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                             os.str()));
+          }
+          else {
+            PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+            if (const Stmt *S = End.asStmt())
+              End = PDB.getEnclosingStmtLocation(S);
+            
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                             "Loop condition is true.  Entering loop body"));
+          }
+          
+          break;
+        }
+          
+        case Stmt::IfStmtClass: {
+          PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+          
+          if (const Stmt *S = End.asStmt())
+            End = PDB.getEnclosingStmtLocation(S);
+          
+          if (*(Src->succ_begin()+1) == Dst)
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                             "Taking false branch"));
+          else  
+            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                             "Taking true branch"));
+          
+          break;
+        }
+      }
+    }
+    
+    if (PathDiagnosticPiece* p =
+        PDB.getReport().VisitNode(N, NextNode, PDB.getGraph(),
+                                  PDB.getBugReporter(),
+                                  PDB.getNodeMapClosure())) {
+          PD.push_front(p);
+        }
+    
+    if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) {      
+      // Scan the region bindings, and see if a "notable" symbol has a new
+      // lval binding.
+      ScanNotableSymbols SNS(N, PS->getStmt(), PDB.getBugReporter(), PD);
+      PDB.getStateManager().iterBindings(N->getState(), SNS);
+    }
+  }
+}
+
+//===----------------------------------------------------------------------===//
 // Methods for BugType and subclasses.
 //===----------------------------------------------------------------------===//
 BugType::~BugType() {}
@@ -516,175 +979,6 @@
                         std::make_pair(First, NodeIndex));
 }
 
-static const VarDecl*
-GetMostRecentVarDeclBinding(const ExplodedNode<GRState>* N,
-                            GRStateManager& VMgr, SVal X) {
-  
-  for ( ; N ; N = N->pred_empty() ? 0 : *N->pred_begin()) {
-    
-    ProgramPoint P = N->getLocation();
-    
-    if (!isa<PostStmt>(P))
-      continue;
-    
-    DeclRefExpr* DR = dyn_cast<DeclRefExpr>(cast<PostStmt>(P).getStmt());
-    
-    if (!DR)
-      continue;
-    
-    SVal Y = VMgr.GetSVal(N->getState(), DR);
-    
-    if (X != Y)
-      continue;
-    
-    VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl());
-    
-    if (!VD)
-      continue;
-    
-    return VD;
-  }
-  
-  return 0;
-}
-
-namespace {
-class VISIBILITY_HIDDEN NotableSymbolHandler 
-  : public StoreManager::BindingsHandler {
-    
-  SymbolRef Sym;
-  const GRState* PrevSt;
-  const Stmt* S;
-  GRStateManager& VMgr;
-  const ExplodedNode<GRState>* Pred;
-  PathDiagnostic& PD; 
-  BugReporter& BR;
-    
-public:
-  
-  NotableSymbolHandler(SymbolRef sym, const GRState* prevst, const Stmt* s,
-                       GRStateManager& vmgr, const ExplodedNode<GRState>* pred,
-                       PathDiagnostic& pd, BugReporter& br)
-    : Sym(sym), PrevSt(prevst), S(s), VMgr(vmgr), Pred(pred), PD(pd), BR(br) {}
-                        
-  bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
-                     SVal V) {
-
-    SymbolRef ScanSym = V.getAsSymbol();
-
-    if (ScanSym != Sym)
-      return true;
-    
-    // Check if the previous state has this binding.    
-    SVal X = VMgr.GetSVal(PrevSt, loc::MemRegionVal(R));
-    
-    if (X == V) // Same binding?
-      return true;
-    
-    // Different binding.  Only handle assignments for now.  We don't pull
-    // this check out of the loop because we will eventually handle other 
-    // cases.
-    
-    VarDecl *VD = 0;
-    
-    if (const BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
-      if (!B->isAssignmentOp())
-        return true;
-      
-      // What variable did we assign to?
-      DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParenCasts());
-      
-      if (!DR)
-        return true;
-      
-      VD = dyn_cast<VarDecl>(DR->getDecl());
-    }
-    else if (const DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
-      // FIXME: Eventually CFGs won't have DeclStmts.  Right now we
-      //  assume that each DeclStmt has a single Decl.  This invariant
-      //  holds by contruction in the CFG.
-      VD = dyn_cast<VarDecl>(*DS->decl_begin());
-    }
-    
-    if (!VD)
-      return true;
-    
-    // What is the most recently referenced variable with this binding?
-    const VarDecl* MostRecent = GetMostRecentVarDeclBinding(Pred, VMgr, V);
-    
-    if (!MostRecent)
-      return true;
-    
-    // Create the diagnostic.
-    FullSourceLoc L(S->getLocStart(), BR.getSourceManager());
-    
-    if (Loc::IsLocType(VD->getType())) {
-      std::string msg = "'" + std::string(VD->getNameAsString()) +
-      "' now aliases '" + MostRecent->getNameAsString() + "'";
-      
-      PD.push_front(new PathDiagnosticEventPiece(L, msg));
-    }
-    
-    return true;
-  }  
-};
-}
-
-static void HandleNotableSymbol(const ExplodedNode<GRState>* N,
-                                const Stmt* S,
-                                SymbolRef Sym, BugReporter& BR,
-                                PathDiagnostic& PD) {
-  
-  const ExplodedNode<GRState>* Pred = N->pred_empty() ? 0 : *N->pred_begin();
-  const GRState* PrevSt = Pred ? Pred->getState() : 0;
-  
-  if (!PrevSt)
-    return;
-  
-  // Look at the region bindings of the current state that map to the
-  // specified symbol.  Are any of them not in the previous state?
-  GRStateManager& VMgr = cast<GRBugReporter>(BR).getStateManager();
-  NotableSymbolHandler H(Sym, PrevSt, S, VMgr, Pred, PD, BR);
-  cast<GRBugReporter>(BR).getStateManager().iterBindings(N->getState(), H);
-}
-
-namespace {
-class VISIBILITY_HIDDEN ScanNotableSymbols
-  : public StoreManager::BindingsHandler {
-    
-  llvm::SmallSet<SymbolRef, 10> AlreadyProcessed;
-  const ExplodedNode<GRState>* N;
-  Stmt* S;
-  GRBugReporter& BR;
-  PathDiagnostic& PD;
-    
-public:
-  ScanNotableSymbols(const ExplodedNode<GRState>* n, Stmt* s, GRBugReporter& br,
-                     PathDiagnostic& pd)
-    : N(n), S(s), BR(br), PD(pd) {}
-  
-  bool HandleBinding(StoreManager& SMgr, Store store,
-                     const MemRegion* R, SVal V) {
-
-    SymbolRef ScanSym = V.getAsSymbol();
-
-    if (!ScanSym)
-      return true;
-  
-    if (!BR.isNotable(ScanSym))
-      return true;
-  
-    if (AlreadyProcessed.count(ScanSym))
-      return true;
-  
-    AlreadyProcessed.insert(ScanSym);
-  
-    HandleNotableSymbol(N, S, ScanSym, BR, PD);
-    return true;
-  }
-};
-} // end anonymous namespace
-
 /// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
 ///  and collapses PathDiagosticPieces that are expanded by macros.
 static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) {
@@ -777,10 +1071,6 @@
   }
 }
 
-static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
-                                          PathDiagnosticBuilder &PDB,
-                                          const ExplodedNode<GRState> *N);
-
 void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
                                           BugReportEquivClass& EQ) {
  
@@ -834,296 +1124,6 @@
   CompactPathDiagnostic(PD, PDB.getSourceManager());  
 }
 
-static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
-                                          PathDiagnosticBuilder &PDB,
-                                          const ExplodedNode<GRState> *N) {
-  
-
-  ASTContext& Ctx = PDB.getContext();
-  SourceManager& SMgr = PDB.getSourceManager();
-  const ExplodedNode<GRState>* NextNode = N->pred_empty() 
-                                          ? NULL : *(N->pred_begin());
-
-  while (NextNode) {
-    N = NextNode;    
-    NextNode = GetPredecessorNode(N);
-    
-    ProgramPoint P = N->getLocation();
-    
-    if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
-      CFGBlock* Src = BE->getSrc();
-      CFGBlock* Dst = BE->getDst();
-      Stmt* T = Src->getTerminator();
-      
-      if (!T)
-        continue;
-      
-      FullSourceLoc Start(T->getLocStart(), SMgr);
-      
-      switch (T->getStmtClass()) {
-        default:
-          break;
-          
-        case Stmt::GotoStmtClass:
-        case Stmt::IndirectGotoStmtClass: {          
-          Stmt* S = GetNextStmt(N);
-          
-          if (!S)
-            continue;
-          
-          std::string sbuf;
-          llvm::raw_string_ostream os(sbuf);          
-          const PathDiagnosticLocation &End = PDB.getEnclosingStmtLocation(S);
-          
-          os << "Control jumps to line "
-             << End.asLocation().getInstantiationLineNumber();
-          PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                           os.str()));
-          break;
-        }
-          
-        case Stmt::SwitchStmtClass: {          
-          // Figure out what case arm we took.
-          std::string sbuf;
-          llvm::raw_string_ostream os(sbuf);
-
-          if (Stmt* S = Dst->getLabel()) {
-            PathDiagnosticLocation End(S, SMgr);
-          
-            switch (S->getStmtClass()) {
-              default:
-                os << "No cases match in the switch statement. "
-                      "Control jumps to line "
-                   << End.asLocation().getInstantiationLineNumber();
-                break;
-              case Stmt::DefaultStmtClass:
-                os << "Control jumps to the 'default' case at line "
-                   << End.asLocation().getInstantiationLineNumber();
-                break;
-                
-              case Stmt::CaseStmtClass: {
-                os << "Control jumps to 'case ";              
-                CaseStmt* Case = cast<CaseStmt>(S);              
-                Expr* LHS = Case->getLHS()->IgnoreParenCasts();
-                
-                // Determine if it is an enum.              
-                bool GetRawInt = true;
-                
-                if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) {
-                  // FIXME: Maybe this should be an assertion.  Are there cases
-                  // were it is not an EnumConstantDecl?
-                  EnumConstantDecl* D =
-                    dyn_cast<EnumConstantDecl>(DR->getDecl());
-
-                  if (D) {
-                    GetRawInt = false;
-                    os << D->getNameAsString();
-                  }
-                }
-
-                if (GetRawInt) {
-                
-                  // Not an enum.
-                  Expr* CondE = cast<SwitchStmt>(T)->getCond();
-                  unsigned bits = Ctx.getTypeSize(CondE->getType());
-                  llvm::APSInt V(bits, false);
-                  
-                  if (!LHS->isIntegerConstantExpr(V, Ctx, 0, true)) {
-                    assert (false && "Case condition must be constant.");
-                    continue;
-                  }
-                  
-                  os << V;
-                }       
-                
-                os << ":'  at line "
-                   << End.asLocation().getInstantiationLineNumber();
-                break;
-              }
-            }
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                             os.str()));
-          }
-          else {
-            os << "'Default' branch taken. ";
-            const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);            
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                             os.str()));
-          }
-          
-          break;
-        }
-          
-        case Stmt::BreakStmtClass:
-        case Stmt::ContinueStmtClass: {
-          std::string sbuf;
-          llvm::raw_string_ostream os(sbuf);
-          PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
-          PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                           os.str()));
-          break;
-        }
-
-        // Determine control-flow for ternary '?'.
-        case Stmt::ConditionalOperatorClass: {
-          std::string sbuf;
-          llvm::raw_string_ostream os(sbuf);
-          os << "'?' condition is ";
-
-          if (*(Src->succ_begin()+1) == Dst)
-            os << "false";
-          else
-            os << "true";
-          
-          PathDiagnosticLocation End = PDB.ExecutionContinues(N);
-          
-          if (const Stmt *S = End.asStmt())
-            End = PDB.getEnclosingStmtLocation(S);
-          
-          PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                           os.str()));
-          break;
-        }
-          
-        // Determine control-flow for short-circuited '&&' and '||'.
-        case Stmt::BinaryOperatorClass: {
-          if (!PDB.supportsLogicalOpControlFlow())
-            break;
-          
-          BinaryOperator *B = cast<BinaryOperator>(T);
-          std::string sbuf;
-          llvm::raw_string_ostream os(sbuf);
-          os << "Left side of '";
-
-          if (B->getOpcode() == BinaryOperator::LAnd) {
-            os << "&&" << "' is ";
-            
-            if (*(Src->succ_begin()+1) == Dst) {
-              os << "false";
-              PathDiagnosticLocation End(B->getLHS(), SMgr);
-              PathDiagnosticLocation Start(B->getOperatorLoc(), SMgr);
-              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                               os.str()));
-            }            
-            else {
-              os << "true";
-              PathDiagnosticLocation Start(B->getLHS(), SMgr);
-              PathDiagnosticLocation End = PDB.ExecutionContinues(N);
-              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                               os.str()));
-            }              
-          }
-          else {
-            assert(B->getOpcode() == BinaryOperator::LOr);
-            os << "||" << "' is ";
-            
-            if (*(Src->succ_begin()+1) == Dst) {
-              os << "false";
-              PathDiagnosticLocation Start(B->getLHS(), SMgr);
-              PathDiagnosticLocation End = PDB.ExecutionContinues(N);
-              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                               os.str()));              
-            }
-            else {
-              os << "true";
-              PathDiagnosticLocation End(B->getLHS(), SMgr);
-              PathDiagnosticLocation Start(B->getOperatorLoc(), SMgr);
-              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                               os.str()));                            
-            }
-          }
-
-          break;
-        }
-          
-        case Stmt::DoStmtClass:  {          
-          if (*(Src->succ_begin()) == Dst) {
-            std::string sbuf;
-            llvm::raw_string_ostream os(sbuf);
-            
-            os << "Loop condition is true. ";
-            PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
-
-            if (const Stmt *S = End.asStmt())
-              End = PDB.getEnclosingStmtLocation(S);
-            
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                             os.str()));
-          }
-          else {
-            PathDiagnosticLocation End = PDB.ExecutionContinues(N);
-            
-            if (const Stmt *S = End.asStmt())
-              End = PDB.getEnclosingStmtLocation(S);
-
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                    "Loop condition is false.  Exiting loop"));
-          }
-          
-          break;
-        }
-          
-        case Stmt::WhileStmtClass:
-        case Stmt::ForStmtClass: {          
-          if (*(Src->succ_begin()+1) == Dst) {
-            std::string sbuf;
-            llvm::raw_string_ostream os(sbuf);
-
-            os << "Loop condition is false. ";
-            PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
-            if (const Stmt *S = End.asStmt())
-              End = PDB.getEnclosingStmtLocation(S);
-
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                             os.str()));
-          }
-          else {
-            PathDiagnosticLocation End = PDB.ExecutionContinues(N);
-            if (const Stmt *S = End.asStmt())
-              End = PDB.getEnclosingStmtLocation(S);
-            
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                               "Loop condition is true.  Entering loop body"));
-          }
-          
-          break;
-        }
-          
-        case Stmt::IfStmtClass: {
-          PathDiagnosticLocation End = PDB.ExecutionContinues(N);
-
-          if (const Stmt *S = End.asStmt())
-            End = PDB.getEnclosingStmtLocation(S);
-          
-          if (*(Src->succ_begin()+1) == Dst)
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                       "Taking false branch"));
-          else  
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                       "Taking true branch"));
-          
-          break;
-        }
-      }
-    }
-
-    if (PathDiagnosticPiece* p =
-          PDB.getReport().VisitNode(N, NextNode, PDB.getGraph(),
-                                        PDB.getBugReporter(),
-                                        PDB.getNodeMapClosure())) {
-      PD.push_front(p);
-    }
-    
-    if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) {      
-      // Scan the region bindings, and see if a "notable" symbol has a new
-      // lval binding.
-      ScanNotableSymbols SNS(N, PS->getStmt(), PDB.getBugReporter(), PD);
-      PDB.getStateManager().iterBindings(N->getState(), SNS);
-    }
-  }
-}
-
-
 void BugReporter::Register(BugType *BT) {
   BugTypes = F.Add(BugTypes, BT);
 }