More boilerplate for handling specialized-transfer function logic for dead symbols.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50233 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index a287e54..0438059 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -42,7 +42,7 @@
     BasicVals(StateMgr.getBasicValueFactory()),
     TF(NULL), // FIXME
     SymMgr(StateMgr.getSymbolManager()),
-    StmtEntryNode(NULL), CleanedState(NULL), CurrentStmt(NULL) {
+    CurrentStmt(NULL) {
   
   // Compute liveness information.
   Liveness.runOnCFG(G.getCFG());
@@ -167,9 +167,8 @@
 void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
   
   Builder = &builder;
-  StmtEntryNode = builder.getLastNode();
+  EntryNode = builder.getLastNode();
   CurrentStmt = S;
-  NodeSet Dst;
   
   // Set up our simple checks.
   
@@ -187,49 +186,53 @@
   
   // Create the cleaned state.
   
-  CleanedState = StateMgr.RemoveDeadBindings(StmtEntryNode->getState(),
-                                             CurrentStmt, Liveness,
-                                             DeadSymbols);
+  CleanedState = StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt,
+                                             Liveness, DeadSymbols);
   
   // Process any special transfer function for dead symbols.
   
   NodeSet Tmp;
   
   if (DeadSymbols.empty())
-    Tmp.Add(StmtEntryNode);
+    Tmp.Add(EntryNode);
   else {
     SaveAndRestore<bool> OldSink(Builder->BuildSinks);
-/*      
-    FIXME: Will hook this up next.
- 
-    TF->EvalDeadSymbols(Tmp, *this, *Builder, StmtEntryNode->getLocation(), Pred,
-                        CleanedState, DeadSymbols);
-*/
-    if (!Builder->BuildSinks && Tmp.empty() && !Builder->HasGeneratedNode)
-      Tmp.Add(StmtEntryNode);
+    SaveOr OldHasGen(Builder->HasGeneratedNode);
+
+    TF->EvalDeadSymbols(Tmp, *this, *Builder, EntryNode->getLocation(),
+                        EntryNode, CleanedState, DeadSymbols);
+
+    if (!Builder->BuildSinks && !Builder->HasGeneratedNode)
+      Tmp.Add(EntryNode);
   }
-      
+  
+  bool HasAutoGenerated = false;
+
   for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+
+    NodeSet Dst;
+    
     // Set the cleaned state.  
-    Builder->SetCleanedState(*I == StmtEntryNode ? CleanedState : (*I)->getState());
-  
+    Builder->SetCleanedState(*I == EntryNode ? CleanedState : GetState(*I));
+    
     // Visit the statement.  
-    Visit(S, StmtEntryNode, Dst);
+    Visit(S, *I, Dst);
+
+    // Do we need to auto-generate a node?  We only need to do this to generate
+    // a node with a "cleaned" state; GRCoreEngine will actually handle
+    // auto-transitions for other cases.    
+    if (Dst.size() == 1 && *Dst.begin() == EntryNode
+        && !Builder->HasGeneratedNode && !HasAutoGenerated) {
+      HasAutoGenerated = true;
+      builder.generateNode(S, GetState(EntryNode), *I);
+    }
   }
   
-  // If no nodes were generated, generate a new node that has all the
-  // dead mappings removed.
-  
-  if (Dst.size() == 1 && *Dst.begin() == StmtEntryNode && 
-      !Builder->HasGeneratedNode)
-    builder.generateNode(S, GetState(StmtEntryNode), StmtEntryNode);
-  
   // NULL out these variables to cleanup.
-  
-  CurrentStmt = NULL;
-  StmtEntryNode = NULL;
-  Builder = NULL;
   CleanedState = NULL;
+  EntryNode = NULL;
+  CurrentStmt = NULL;
+  Builder = NULL;
 }
 
 void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) {