]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / lib / StaticAnalyzer / Core / CoreEngine.cpp
1 //==- CoreEngine.cpp - Path-Sensitive Dataflow Engine ------------*- C++ -*-//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines a generic engine for intraprocedural, path-sensitive,
11 //  dataflow analysis via graph reachability engine.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
16 #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
17 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
18 #include "clang/Index/TranslationUnit.h"
19 #include "clang/AST/Expr.h"
20 #include "llvm/Support/Casting.h"
21 #include "llvm/ADT/DenseMap.h"
22
23 using llvm::cast;
24 using llvm::isa;
25 using namespace clang;
26 using namespace ento;
27
28 // This should be removed in the future.
29 namespace clang {
30 namespace ento {
31 TransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
32                                   const LangOptions& lopts);
33 }
34 }
35
36 //===----------------------------------------------------------------------===//
37 // Worklist classes for exploration of reachable states.
38 //===----------------------------------------------------------------------===//
39
40 WorkList::Visitor::~Visitor() {}
41
42 namespace {
43 class DFS : public WorkList {
44   llvm::SmallVector<WorkListUnit,20> Stack;
45 public:
46   virtual bool hasWork() const {
47     return !Stack.empty();
48   }
49
50   virtual void enqueue(const WorkListUnit& U) {
51     Stack.push_back(U);
52   }
53
54   virtual WorkListUnit dequeue() {
55     assert (!Stack.empty());
56     const WorkListUnit& U = Stack.back();
57     Stack.pop_back(); // This technically "invalidates" U, but we are fine.
58     return U;
59   }
60   
61   virtual bool visitItemsInWorkList(Visitor &V) {
62     for (llvm::SmallVectorImpl<WorkListUnit>::iterator
63          I = Stack.begin(), E = Stack.end(); I != E; ++I) {
64       if (V.visit(*I))
65         return true;
66     }
67     return false;
68   }
69 };
70
71 class BFS : public WorkList {
72   std::deque<WorkListUnit> Queue;
73 public:
74   virtual bool hasWork() const {
75     return !Queue.empty();
76   }
77
78   virtual void enqueue(const WorkListUnit& U) {
79     Queue.push_front(U);
80   }
81
82   virtual WorkListUnit dequeue() {
83     WorkListUnit U = Queue.front();
84     Queue.pop_front();
85     return U;
86   }
87   
88   virtual bool visitItemsInWorkList(Visitor &V) {
89     for (std::deque<WorkListUnit>::iterator
90          I = Queue.begin(), E = Queue.end(); I != E; ++I) {
91       if (V.visit(*I))
92         return true;
93     }
94     return false;
95   }
96 };
97
98 } // end anonymous namespace
99
100 // Place the dstor for WorkList here because it contains virtual member
101 // functions, and we the code for the dstor generated in one compilation unit.
102 WorkList::~WorkList() {}
103
104 WorkList *WorkList::makeDFS() { return new DFS(); }
105 WorkList *WorkList::makeBFS() { return new BFS(); }
106
107 namespace {
108   class BFSBlockDFSContents : public WorkList {
109     std::deque<WorkListUnit> Queue;
110     llvm::SmallVector<WorkListUnit,20> Stack;
111   public:
112     virtual bool hasWork() const {
113       return !Queue.empty() || !Stack.empty();
114     }
115
116     virtual void enqueue(const WorkListUnit& U) {
117       if (isa<BlockEntrance>(U.getNode()->getLocation()))
118         Queue.push_front(U);
119       else
120         Stack.push_back(U);
121     }
122
123     virtual WorkListUnit dequeue() {
124       // Process all basic blocks to completion.
125       if (!Stack.empty()) {
126         const WorkListUnit& U = Stack.back();
127         Stack.pop_back(); // This technically "invalidates" U, but we are fine.
128         return U;
129       }
130
131       assert(!Queue.empty());
132       // Don't use const reference.  The subsequent pop_back() might make it
133       // unsafe.
134       WorkListUnit U = Queue.front();
135       Queue.pop_front();
136       return U;
137     }
138     virtual bool visitItemsInWorkList(Visitor &V) {
139       for (llvm::SmallVectorImpl<WorkListUnit>::iterator
140            I = Stack.begin(), E = Stack.end(); I != E; ++I) {
141         if (V.visit(*I))
142           return true;
143       }
144       for (std::deque<WorkListUnit>::iterator
145            I = Queue.begin(), E = Queue.end(); I != E; ++I) {
146         if (V.visit(*I))
147           return true;
148       }
149       return false;
150     }
151
152   };
153 } // end anonymous namespace
154
155 WorkList* WorkList::makeBFSBlockDFSContents() {
156   return new BFSBlockDFSContents();
157 }
158
159 //===----------------------------------------------------------------------===//
160 // Core analysis engine.
161 //===----------------------------------------------------------------------===//
162
163 /// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
164 bool CoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps,
165                                    const GRState *InitState) {
166
167   if (G->num_roots() == 0) { // Initialize the analysis by constructing
168     // the root if none exists.
169
170     const CFGBlock* Entry = &(L->getCFG()->getEntry());
171
172     assert (Entry->empty() &&
173             "Entry block must be empty.");
174
175     assert (Entry->succ_size() == 1 &&
176             "Entry block must have 1 successor.");
177
178     // Get the solitary successor.
179     const CFGBlock* Succ = *(Entry->succ_begin());
180
181     // Construct an edge representing the
182     // starting location in the function.
183     BlockEdge StartLoc(Entry, Succ, L);
184
185     // Set the current block counter to being empty.
186     WList->setBlockCounter(BCounterFactory.GetEmptyCounter());
187
188     if (!InitState)
189       // Generate the root.
190       generateNode(StartLoc, SubEng.getInitialState(L), 0);
191     else
192       generateNode(StartLoc, InitState, 0);
193   }
194
195   // Check if we have a steps limit
196   bool UnlimitedSteps = Steps == 0;
197
198   while (WList->hasWork()) {
199     if (!UnlimitedSteps) {
200       if (Steps == 0)
201         break;
202       --Steps;
203     }
204
205     const WorkListUnit& WU = WList->dequeue();
206
207     // Set the current block counter.
208     WList->setBlockCounter(WU.getBlockCounter());
209
210     // Retrieve the node.
211     ExplodedNode* Node = WU.getNode();
212
213     // Dispatch on the location type.
214     switch (Node->getLocation().getKind()) {
215       case ProgramPoint::BlockEdgeKind:
216         HandleBlockEdge(cast<BlockEdge>(Node->getLocation()), Node);
217         break;
218
219       case ProgramPoint::BlockEntranceKind:
220         HandleBlockEntrance(cast<BlockEntrance>(Node->getLocation()), Node);
221         break;
222
223       case ProgramPoint::BlockExitKind:
224         assert (false && "BlockExit location never occur in forward analysis.");
225         break;
226
227       case ProgramPoint::CallEnterKind:
228         HandleCallEnter(cast<CallEnter>(Node->getLocation()), WU.getBlock(), 
229                         WU.getIndex(), Node);
230         break;
231
232       case ProgramPoint::CallExitKind:
233         HandleCallExit(cast<CallExit>(Node->getLocation()), Node);
234         break;
235
236       default:
237         assert(isa<PostStmt>(Node->getLocation()) || 
238                isa<PostInitializer>(Node->getLocation()));
239         HandlePostStmt(WU.getBlock(), WU.getIndex(), Node);
240         break;
241     }
242   }
243
244   SubEng.processEndWorklist(hasWorkRemaining());
245   return WList->hasWork();
246 }
247
248 void CoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L, 
249                                                    unsigned Steps,
250                                                    const GRState *InitState, 
251                                                    ExplodedNodeSet &Dst) {
252   ExecuteWorkList(L, Steps, InitState);
253   for (llvm::SmallVectorImpl<ExplodedNode*>::iterator I = G->EndNodes.begin(), 
254                                            E = G->EndNodes.end(); I != E; ++I) {
255     Dst.Add(*I);
256   }
257 }
258
259 void CoreEngine::HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
260                                    unsigned Index, ExplodedNode *Pred) {
261   CallEnterNodeBuilder Builder(*this, Pred, L.getCallExpr(), 
262                                  L.getCalleeContext(), Block, Index);
263   SubEng.processCallEnter(Builder);
264 }
265
266 void CoreEngine::HandleCallExit(const CallExit &L, ExplodedNode *Pred) {
267   CallExitNodeBuilder Builder(*this, Pred);
268   SubEng.processCallExit(Builder);
269 }
270
271 void CoreEngine::HandleBlockEdge(const BlockEdge& L, ExplodedNode* Pred) {
272
273   const CFGBlock* Blk = L.getDst();
274
275   // Check if we are entering the EXIT block.
276   if (Blk == &(L.getLocationContext()->getCFG()->getExit())) {
277
278     assert (L.getLocationContext()->getCFG()->getExit().size() == 0
279             && "EXIT block cannot contain Stmts.");
280
281     // Process the final state transition.
282     EndOfFunctionNodeBuilder Builder(Blk, Pred, this);
283     SubEng.processEndOfFunction(Builder);
284
285     // This path is done. Don't enqueue any more nodes.
286     return;
287   }
288
289   // Call into the subengine to process entering the CFGBlock.
290   ExplodedNodeSet dstNodes;
291   BlockEntrance BE(Blk, Pred->getLocationContext());
292   GenericNodeBuilder<BlockEntrance> nodeBuilder(*this, Pred, BE);
293   SubEng.processCFGBlockEntrance(dstNodes, nodeBuilder);
294
295   if (dstNodes.empty()) {
296     if (!nodeBuilder.hasGeneratedNode) {
297       // Auto-generate a node and enqueue it to the worklist.
298       generateNode(BE, Pred->State, Pred);    
299     }
300   }
301   else {
302     for (ExplodedNodeSet::iterator I = dstNodes.begin(), E = dstNodes.end();
303          I != E; ++I) {
304       WList->enqueue(*I);
305     }
306   }
307
308   for (llvm::SmallVectorImpl<ExplodedNode*>::const_iterator
309        I = nodeBuilder.sinks().begin(), E = nodeBuilder.sinks().end();
310        I != E; ++I) {
311     blocksExhausted.push_back(std::make_pair(L, *I));
312   }
313 }
314
315 void CoreEngine::HandleBlockEntrance(const BlockEntrance& L,
316                                        ExplodedNode* Pred) {
317
318   // Increment the block counter.
319   BlockCounter Counter = WList->getBlockCounter();
320   Counter = BCounterFactory.IncrementCount(Counter, 
321                              Pred->getLocationContext()->getCurrentStackFrame(),
322                                            L.getBlock()->getBlockID());
323   WList->setBlockCounter(Counter);
324
325   // Process the entrance of the block.
326   if (CFGElement E = L.getFirstElement()) {
327     StmtNodeBuilder Builder(L.getBlock(), 0, Pred, this,
328                               SubEng.getStateManager());
329     SubEng.processCFGElement(E, Builder);
330   }
331   else
332     HandleBlockExit(L.getBlock(), Pred);
333 }
334
335 void CoreEngine::HandleBlockExit(const CFGBlock * B, ExplodedNode* Pred) {
336
337   if (const Stmt* Term = B->getTerminator()) {
338     switch (Term->getStmtClass()) {
339       default:
340         assert(false && "Analysis for this terminator not implemented.");
341         break;
342
343       case Stmt::BinaryOperatorClass: // '&&' and '||'
344         HandleBranch(cast<BinaryOperator>(Term)->getLHS(), Term, B, Pred);
345         return;
346
347       case Stmt::BinaryConditionalOperatorClass:
348       case Stmt::ConditionalOperatorClass:
349         HandleBranch(cast<AbstractConditionalOperator>(Term)->getCond(),
350                      Term, B, Pred);
351         return;
352
353         // FIXME: Use constant-folding in CFG construction to simplify this
354         // case.
355
356       case Stmt::ChooseExprClass:
357         HandleBranch(cast<ChooseExpr>(Term)->getCond(), Term, B, Pred);
358         return;
359
360       case Stmt::DoStmtClass:
361         HandleBranch(cast<DoStmt>(Term)->getCond(), Term, B, Pred);
362         return;
363
364       case Stmt::ForStmtClass:
365         HandleBranch(cast<ForStmt>(Term)->getCond(), Term, B, Pred);
366         return;
367
368       case Stmt::ContinueStmtClass:
369       case Stmt::BreakStmtClass:
370       case Stmt::GotoStmtClass:
371         break;
372
373       case Stmt::IfStmtClass:
374         HandleBranch(cast<IfStmt>(Term)->getCond(), Term, B, Pred);
375         return;
376
377       case Stmt::IndirectGotoStmtClass: {
378         // Only 1 successor: the indirect goto dispatch block.
379         assert (B->succ_size() == 1);
380
381         IndirectGotoNodeBuilder
382            builder(Pred, B, cast<IndirectGotoStmt>(Term)->getTarget(),
383                    *(B->succ_begin()), this);
384
385         SubEng.processIndirectGoto(builder);
386         return;
387       }
388
389       case Stmt::ObjCForCollectionStmtClass: {
390         // In the case of ObjCForCollectionStmt, it appears twice in a CFG:
391         //
392         //  (1) inside a basic block, which represents the binding of the
393         //      'element' variable to a value.
394         //  (2) in a terminator, which represents the branch.
395         //
396         // For (1), subengines will bind a value (i.e., 0 or 1) indicating
397         // whether or not collection contains any more elements.  We cannot
398         // just test to see if the element is nil because a container can
399         // contain nil elements.
400         HandleBranch(Term, Term, B, Pred);
401         return;
402       }
403
404       case Stmt::SwitchStmtClass: {
405         SwitchNodeBuilder builder(Pred, B, cast<SwitchStmt>(Term)->getCond(),
406                                     this);
407
408         SubEng.processSwitch(builder);
409         return;
410       }
411
412       case Stmt::WhileStmtClass:
413         HandleBranch(cast<WhileStmt>(Term)->getCond(), Term, B, Pred);
414         return;
415     }
416   }
417
418   assert (B->succ_size() == 1 &&
419           "Blocks with no terminator should have at most 1 successor.");
420
421   generateNode(BlockEdge(B, *(B->succ_begin()), Pred->getLocationContext()),
422                Pred->State, Pred);
423 }
424
425 void CoreEngine::HandleBranch(const Stmt* Cond, const Stmt* Term, 
426                                 const CFGBlock * B, ExplodedNode* Pred) {
427   assert(B->succ_size() == 2);
428   BranchNodeBuilder Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
429                             Pred, this);
430   SubEng.processBranch(Cond, Term, Builder);
431 }
432
433 void CoreEngine::HandlePostStmt(const CFGBlock* B, unsigned StmtIdx, 
434                                   ExplodedNode* Pred) {
435   assert (!B->empty());
436
437   if (StmtIdx == B->size())
438     HandleBlockExit(B, Pred);
439   else {
440     StmtNodeBuilder Builder(B, StmtIdx, Pred, this,
441                               SubEng.getStateManager());
442     SubEng.processCFGElement((*B)[StmtIdx], Builder);
443   }
444 }
445
446 /// generateNode - Utility method to generate nodes, hook up successors,
447 ///  and add nodes to the worklist.
448 void CoreEngine::generateNode(const ProgramPoint& Loc,
449                               const GRState* State, ExplodedNode* Pred) {
450
451   bool IsNew;
452   ExplodedNode* Node = G->getNode(Loc, State, &IsNew);
453
454   if (Pred)
455     Node->addPredecessor(Pred, *G);  // Link 'Node' with its predecessor.
456   else {
457     assert (IsNew);
458     G->addRoot(Node);  // 'Node' has no predecessor.  Make it a root.
459   }
460
461   // Only add 'Node' to the worklist if it was freshly generated.
462   if (IsNew) WList->enqueue(Node);
463 }
464
465 ExplodedNode *
466 GenericNodeBuilderImpl::generateNodeImpl(const GRState *state,
467                                          ExplodedNode *pred,
468                                          ProgramPoint programPoint,
469                                          bool asSink) {
470   
471   hasGeneratedNode = true;
472   bool isNew;
473   ExplodedNode *node = engine.getGraph().getNode(programPoint, state, &isNew);
474   if (pred)
475     node->addPredecessor(pred, engine.getGraph());
476   if (isNew) {
477     if (asSink) {
478       node->markAsSink();
479       sinksGenerated.push_back(node);
480     }
481     return node;
482   }
483   return 0;
484 }
485
486 StmtNodeBuilder::StmtNodeBuilder(const CFGBlock* b, unsigned idx,
487                                      ExplodedNode* N, CoreEngine* e,
488                                      GRStateManager &mgr)
489   : Eng(*e), B(*b), Idx(idx), Pred(N), Mgr(mgr),
490     PurgingDeadSymbols(false), BuildSinks(false), hasGeneratedNode(false),
491     PointKind(ProgramPoint::PostStmtKind), Tag(0) {
492   Deferred.insert(N);
493   CleanedState = Pred->getState();
494 }
495
496 StmtNodeBuilder::~StmtNodeBuilder() {
497   for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
498     if (!(*I)->isSink())
499       GenerateAutoTransition(*I);
500 }
501
502 void StmtNodeBuilder::GenerateAutoTransition(ExplodedNode* N) {
503   assert (!N->isSink());
504
505   // Check if this node entered a callee.
506   if (isa<CallEnter>(N->getLocation())) {
507     // Still use the index of the CallExpr. It's needed to create the callee
508     // StackFrameContext.
509     Eng.WList->enqueue(N, &B, Idx);
510     return;
511   }
512
513   // Do not create extra nodes. Move to the next CFG element.
514   if (isa<PostInitializer>(N->getLocation())) {
515     Eng.WList->enqueue(N, &B, Idx+1);
516     return;
517   }
518
519   PostStmt Loc(getStmt(), N->getLocationContext());
520
521   if (Loc == N->getLocation()) {
522     // Note: 'N' should be a fresh node because otherwise it shouldn't be
523     // a member of Deferred.
524     Eng.WList->enqueue(N, &B, Idx+1);
525     return;
526   }
527
528   bool IsNew;
529   ExplodedNode* Succ = Eng.G->getNode(Loc, N->State, &IsNew);
530   Succ->addPredecessor(N, *Eng.G);
531
532   if (IsNew)
533     Eng.WList->enqueue(Succ, &B, Idx+1);
534 }
535
536 ExplodedNode* StmtNodeBuilder::MakeNode(ExplodedNodeSet& Dst, const Stmt* S, 
537                                           ExplodedNode* Pred, const GRState* St,
538                                           ProgramPoint::Kind K) {
539
540   ExplodedNode* N = generateNode(S, St, Pred, K);
541
542   if (N) {
543     if (BuildSinks)
544       N->markAsSink();
545     else
546       Dst.Add(N);
547   }
548   
549   return N;
550 }
551
552 static ProgramPoint GetProgramPoint(const Stmt *S, ProgramPoint::Kind K,
553                                     const LocationContext *LC, const void *tag){
554   switch (K) {
555     default:
556       assert(false && "Unhandled ProgramPoint kind");    
557     case ProgramPoint::PreStmtKind:
558       return PreStmt(S, LC, tag);
559     case ProgramPoint::PostStmtKind:
560       return PostStmt(S, LC, tag);
561     case ProgramPoint::PreLoadKind:
562       return PreLoad(S, LC, tag);
563     case ProgramPoint::PostLoadKind:
564       return PostLoad(S, LC, tag);
565     case ProgramPoint::PreStoreKind:
566       return PreStore(S, LC, tag);
567     case ProgramPoint::PostStoreKind:
568       return PostStore(S, LC, tag);
569     case ProgramPoint::PostLValueKind:
570       return PostLValue(S, LC, tag);
571     case ProgramPoint::PostPurgeDeadSymbolsKind:
572       return PostPurgeDeadSymbols(S, LC, tag);
573   }
574 }
575
576 ExplodedNode*
577 StmtNodeBuilder::generateNodeInternal(const Stmt* S, const GRState* state,
578                                         ExplodedNode* Pred,
579                                         ProgramPoint::Kind K,
580                                         const void *tag) {
581   
582   const ProgramPoint &L = GetProgramPoint(S, K, Pred->getLocationContext(),tag);
583   return generateNodeInternal(L, state, Pred);
584 }
585
586 ExplodedNode*
587 StmtNodeBuilder::generateNodeInternal(const ProgramPoint &Loc,
588                                         const GRState* State,
589                                         ExplodedNode* Pred) {
590   bool IsNew;
591   ExplodedNode* N = Eng.G->getNode(Loc, State, &IsNew);
592   N->addPredecessor(Pred, *Eng.G);
593   Deferred.erase(Pred);
594
595   if (IsNew) {
596     Deferred.insert(N);
597     return N;
598   }
599
600   return NULL;
601 }
602
603 // This function generate a new ExplodedNode but not a new branch(block edge).
604 ExplodedNode* BranchNodeBuilder::generateNode(const Stmt* Condition,
605                                               const GRState* State) {
606   bool IsNew;
607   
608   ExplodedNode* Succ 
609     = Eng.G->getNode(PostCondition(Condition, Pred->getLocationContext()), State,
610                      &IsNew);
611   
612   Succ->addPredecessor(Pred, *Eng.G);
613   
614   Pred = Succ;
615   
616   if (IsNew) 
617     return Succ;
618   
619   return NULL;
620 }
621
622 ExplodedNode* BranchNodeBuilder::generateNode(const GRState* State,
623                                                 bool branch) {
624
625   // If the branch has been marked infeasible we should not generate a node.
626   if (!isFeasible(branch))
627     return NULL;
628
629   bool IsNew;
630
631   ExplodedNode* Succ =
632     Eng.G->getNode(BlockEdge(Src,branch ? DstT:DstF,Pred->getLocationContext()),
633                    State, &IsNew);
634
635   Succ->addPredecessor(Pred, *Eng.G);
636
637   if (branch)
638     GeneratedTrue = true;
639   else
640     GeneratedFalse = true;
641
642   if (IsNew) {
643     Deferred.push_back(Succ);
644     return Succ;
645   }
646
647   return NULL;
648 }
649
650 BranchNodeBuilder::~BranchNodeBuilder() {
651   if (!GeneratedTrue) generateNode(Pred->State, true);
652   if (!GeneratedFalse) generateNode(Pred->State, false);
653
654   for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
655     if (!(*I)->isSink()) Eng.WList->enqueue(*I);
656 }
657
658
659 ExplodedNode*
660 IndirectGotoNodeBuilder::generateNode(const iterator& I, const GRState* St,
661                                         bool isSink) {
662   bool IsNew;
663
664   ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
665                                       Pred->getLocationContext()), St, &IsNew);
666
667   Succ->addPredecessor(Pred, *Eng.G);
668
669   if (IsNew) {
670
671     if (isSink)
672       Succ->markAsSink();
673     else
674       Eng.WList->enqueue(Succ);
675
676     return Succ;
677   }
678
679   return NULL;
680 }
681
682
683 ExplodedNode*
684 SwitchNodeBuilder::generateCaseStmtNode(const iterator& I, const GRState* St){
685
686   bool IsNew;
687
688   ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
689                                        Pred->getLocationContext()), St, &IsNew);
690   Succ->addPredecessor(Pred, *Eng.G);
691
692   if (IsNew) {
693     Eng.WList->enqueue(Succ);
694     return Succ;
695   }
696
697   return NULL;
698 }
699
700
701 ExplodedNode*
702 SwitchNodeBuilder::generateDefaultCaseNode(const GRState* St, bool isSink) {
703
704   // Get the block for the default case.
705   assert (Src->succ_rbegin() != Src->succ_rend());
706   CFGBlock* DefaultBlock = *Src->succ_rbegin();
707
708   bool IsNew;
709
710   ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock,
711                                        Pred->getLocationContext()), St, &IsNew);
712   Succ->addPredecessor(Pred, *Eng.G);
713
714   if (IsNew) {
715     if (isSink)
716       Succ->markAsSink();
717     else
718       Eng.WList->enqueue(Succ);
719
720     return Succ;
721   }
722
723   return NULL;
724 }
725
726 EndOfFunctionNodeBuilder::~EndOfFunctionNodeBuilder() {
727   // Auto-generate an EOP node if one has not been generated.
728   if (!hasGeneratedNode) {
729     // If we are in an inlined call, generate CallExit node.
730     if (Pred->getLocationContext()->getParent())
731       GenerateCallExitNode(Pred->State);
732     else
733       generateNode(Pred->State);
734   }
735 }
736
737 ExplodedNode*
738 EndOfFunctionNodeBuilder::generateNode(const GRState* State,
739                                        ExplodedNode* P, const void *tag) {
740   hasGeneratedNode = true;
741   bool IsNew;
742
743   ExplodedNode* Node = Eng.G->getNode(BlockEntrance(&B,
744                                Pred->getLocationContext(), tag ? tag : Tag),
745                                State, &IsNew);
746
747   Node->addPredecessor(P ? P : Pred, *Eng.G);
748
749   if (IsNew) {
750     Eng.G->addEndOfPath(Node);
751     return Node;
752   }
753
754   return NULL;
755 }
756
757 void EndOfFunctionNodeBuilder::GenerateCallExitNode(const GRState *state) {
758   hasGeneratedNode = true;
759   // Create a CallExit node and enqueue it.
760   const StackFrameContext *LocCtx
761                          = cast<StackFrameContext>(Pred->getLocationContext());
762   const Stmt *CE = LocCtx->getCallSite();
763
764   // Use the the callee location context.
765   CallExit Loc(CE, LocCtx);
766
767   bool isNew;
768   ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
769   Node->addPredecessor(Pred, *Eng.G);
770
771   if (isNew)
772     Eng.WList->enqueue(Node);
773 }
774                                                 
775
776 void CallEnterNodeBuilder::generateNode(const GRState *state) {
777   // Check if the callee is in the same translation unit.
778   if (CalleeCtx->getTranslationUnit() != 
779       Pred->getLocationContext()->getTranslationUnit()) {
780     // Create a new engine. We must be careful that the new engine should not
781     // reference data structures owned by the old engine.
782
783     AnalysisManager &OldMgr = Eng.SubEng.getAnalysisManager();
784     
785     // Get the callee's translation unit.
786     idx::TranslationUnit *TU = CalleeCtx->getTranslationUnit();
787
788     // Create a new AnalysisManager with components of the callee's
789     // TranslationUnit.
790     // The Diagnostic is actually shared when we create ASTUnits from AST files.
791     AnalysisManager AMgr(TU->getASTContext(), TU->getDiagnostic(), 
792                          OldMgr.getLangOptions(), 
793                          OldMgr.getPathDiagnosticClient(),
794                          OldMgr.getStoreManagerCreator(),
795                          OldMgr.getConstraintManagerCreator(),
796                          OldMgr.getCheckerManager(),
797                          OldMgr.getIndexer(),
798                          OldMgr.getMaxNodes(), OldMgr.getMaxVisit(),
799                          OldMgr.shouldVisualizeGraphviz(),
800                          OldMgr.shouldVisualizeUbigraph(),
801                          OldMgr.shouldPurgeDead(),
802                          OldMgr.shouldEagerlyAssume(),
803                          OldMgr.shouldTrimGraph(),
804                          OldMgr.shouldInlineCall(),
805                      OldMgr.getAnalysisContextManager().getUseUnoptimizedCFG(),
806                      OldMgr.getAnalysisContextManager().getAddImplicitDtors(),
807                      OldMgr.getAnalysisContextManager().getAddInitializers(),
808                      OldMgr.shouldEagerlyTrimExplodedGraph());
809     llvm::OwningPtr<TransferFuncs> TF(MakeCFRefCountTF(AMgr.getASTContext(),
810                                                          /* GCEnabled */ false,
811                                                         AMgr.getLangOptions()));
812     // Create the new engine.
813     ExprEngine NewEng(AMgr, TF.take());
814
815     // Create the new LocationContext.
816     AnalysisContext *NewAnaCtx = AMgr.getAnalysisContext(CalleeCtx->getDecl(), 
817                                                CalleeCtx->getTranslationUnit());
818     const StackFrameContext *OldLocCtx = CalleeCtx;
819     const StackFrameContext *NewLocCtx = AMgr.getStackFrame(NewAnaCtx, 
820                                                OldLocCtx->getParent(),
821                                                OldLocCtx->getCallSite(),
822                                                OldLocCtx->getCallSiteBlock(), 
823                                                OldLocCtx->getIndex());
824
825     // Now create an initial state for the new engine.
826     const GRState *NewState = NewEng.getStateManager().MarshalState(state,
827                                                                     NewLocCtx);
828     ExplodedNodeSet ReturnNodes;
829     NewEng.ExecuteWorkListWithInitialState(NewLocCtx, AMgr.getMaxNodes(), 
830                                            NewState, ReturnNodes);
831     return;
832   }
833
834   // Get the callee entry block.
835   const CFGBlock *Entry = &(CalleeCtx->getCFG()->getEntry());
836   assert(Entry->empty());
837   assert(Entry->succ_size() == 1);
838
839   // Get the solitary successor.
840   const CFGBlock *SuccB = *(Entry->succ_begin());
841
842   // Construct an edge representing the starting location in the callee.
843   BlockEdge Loc(Entry, SuccB, CalleeCtx);
844
845   bool isNew;
846   ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
847   Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G);
848
849   if (isNew)
850     Eng.WList->enqueue(Node);
851 }
852
853 void CallExitNodeBuilder::generateNode(const GRState *state) {
854   // Get the callee's location context.
855   const StackFrameContext *LocCtx 
856                          = cast<StackFrameContext>(Pred->getLocationContext());
857   // When exiting an implicit automatic obj dtor call, the callsite is the Stmt
858   // that triggers the dtor.
859   PostStmt Loc(LocCtx->getCallSite(), LocCtx->getParent());
860   bool isNew;
861   ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
862   Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G);
863   if (isNew)
864     Eng.WList->enqueue(Node, LocCtx->getCallSiteBlock(),
865                        LocCtx->getIndex() + 1);
866 }