Added support to GRCoreEngine/GRExprEngine for processing control-flow
from switch...case...default statements.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47100 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Analysis/GRCoreEngine.cpp b/Analysis/GRCoreEngine.cpp
index 5a4ae81..0e8be29 100644
--- a/Analysis/GRCoreEngine.cpp
+++ b/Analysis/GRCoreEngine.cpp
@@ -213,6 +213,15 @@
         return;
       }
         
+      case Stmt::SwitchStmtClass: {
+        GRSwitchNodeBuilderImpl builder(Pred, B,
+                                        cast<SwitchStmt>(Term)->getCond(),
+                                        this);
+        
+        ProcessSwitch(builder);
+        return;
+      }
+        
       case Stmt::WhileStmtClass:
         HandleBranch(cast<WhileStmt>(Term)->getCond(), Term, B, Pred);
         return;
@@ -386,3 +395,49 @@
                        
   return NULL;
 }
+
+
+ExplodedNodeImpl*
+GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I, void* St) {
+
+  bool IsNew;
+  
+  ExplodedNodeImpl* Succ = Eng.G->getNodeImpl(BlockEdge(Eng.getCFG(), Src,
+                                                        I.getBlock()),
+                                              St, &IsNew);  
+  Succ->addPredecessor(Pred);
+  
+  if (IsNew) {
+    Eng.WList->Enqueue(Succ);
+    return Succ;
+  }
+  
+  return NULL;
+}
+
+
+ExplodedNodeImpl*
+GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(void* St, bool isSink) {
+  
+  // Get the block for the default case.
+  assert (Src->succ_rbegin() != Src->succ_rend());
+  CFGBlock* DefaultBlock = *Src->succ_rbegin();
+  
+  bool IsNew;
+  
+  ExplodedNodeImpl* Succ = Eng.G->getNodeImpl(BlockEdge(Eng.getCFG(), Src,
+                                                        DefaultBlock),
+                                              St, &IsNew);  
+  Succ->addPredecessor(Pred);
+  
+  if (IsNew) {
+    if (isSink)
+      Succ->markAsSink();
+    else
+      Eng.WList->Enqueue(Succ);
+    
+    return Succ;
+  }
+  
+  return NULL;
+}