]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / clang / include / clang / StaticAnalyzer / Core / PathSensitive / ExprEngine.h
1 //===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- 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 meta-engine for path-sensitive dataflow analysis that
11 //  is built on CoreEngine, but provides the boilerplate to execute transfer
12 //  functions and build the ExplodedGraph at the expression level.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_CLANG_GR_EXPRENGINE
17 #define LLVM_CLANG_GR_EXPRENGINE
18
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/Type.h"
21 #include "clang/Analysis/DomainSpecific/ObjCNoReturn.h"
22 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
23 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
24 #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
25 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
26 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
27 #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
28
29 namespace clang {
30
31 class AnalysisDeclContextManager;
32 class CXXCatchStmt;
33 class CXXConstructExpr;
34 class CXXDeleteExpr;
35 class CXXNewExpr;
36 class CXXTemporaryObjectExpr;
37 class CXXThisExpr;
38 class MaterializeTemporaryExpr;
39 class ObjCAtSynchronizedStmt;
40 class ObjCForCollectionStmt;
41   
42 namespace ento {
43
44 class AnalysisManager;
45 class CallEvent;
46 class SimpleCall;
47 class CXXConstructorCall;
48
49 class ExprEngine : public SubEngine {
50 public:
51   /// The modes of inlining, which override the default analysis-wide settings.
52   enum InliningModes {
53     /// Follow the default settings for inlining callees.
54     Inline_Regular = 0,
55     /// Do minimal inlining of callees.
56     Inline_Minimal = 0x1
57   };
58
59 private:
60   AnalysisManager &AMgr;
61   
62   AnalysisDeclContextManager &AnalysisDeclContexts;
63
64   CoreEngine Engine;
65
66   /// G - the simulation graph.
67   ExplodedGraph& G;
68
69   /// StateMgr - Object that manages the data for all created states.
70   ProgramStateManager StateMgr;
71
72   /// SymMgr - Object that manages the symbol information.
73   SymbolManager& SymMgr;
74
75   /// svalBuilder - SValBuilder object that creates SVals from expressions.
76   SValBuilder &svalBuilder;
77
78   unsigned int currStmtIdx;
79   const NodeBuilderContext *currBldrCtx;
80   
81   /// Helper object to determine if an Objective-C message expression
82   /// implicitly never returns.
83   ObjCNoReturn ObjCNoRet;
84   
85   /// Whether or not GC is enabled in this analysis.
86   bool ObjCGCEnabled;
87
88   /// The BugReporter associated with this engine.  It is important that
89   ///  this object be placed at the very end of member variables so that its
90   ///  destructor is called before the rest of the ExprEngine is destroyed.
91   GRBugReporter BR;
92
93   /// The functions which have been analyzed through inlining. This is owned by
94   /// AnalysisConsumer. It can be null.
95   SetOfConstDecls *VisitedCallees;
96
97   /// The flag, which specifies the mode of inlining for the engine.
98   InliningModes HowToInline;
99
100 public:
101   ExprEngine(AnalysisManager &mgr, bool gcEnabled,
102              SetOfConstDecls *VisitedCalleesIn,
103              FunctionSummariesTy *FS,
104              InliningModes HowToInlineIn);
105
106   ~ExprEngine();
107
108   /// Returns true if there is still simulation state on the worklist.
109   bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
110     return Engine.ExecuteWorkList(L, Steps, 0);
111   }
112
113   /// Execute the work list with an initial state. Nodes that reaches the exit
114   /// of the function are added into the Dst set, which represent the exit
115   /// state of the function call. Returns true if there is still simulation
116   /// state on the worklist.
117   bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
118                                        ProgramStateRef InitState, 
119                                        ExplodedNodeSet &Dst) {
120     return Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst);
121   }
122
123   /// getContext - Return the ASTContext associated with this analysis.
124   ASTContext &getContext() const { return AMgr.getASTContext(); }
125
126   virtual AnalysisManager &getAnalysisManager() { return AMgr; }
127
128   CheckerManager &getCheckerManager() const {
129     return *AMgr.getCheckerManager();
130   }
131
132   SValBuilder &getSValBuilder() { return svalBuilder; }
133
134   BugReporter& getBugReporter() { return BR; }
135
136   const NodeBuilderContext &getBuilderContext() {
137     assert(currBldrCtx);
138     return *currBldrCtx;
139   }
140
141   bool isObjCGCEnabled() { return ObjCGCEnabled; }
142
143   const Stmt *getStmt() const;
144
145   void GenerateAutoTransition(ExplodedNode *N);
146   void enqueueEndOfPath(ExplodedNodeSet &S);
147   void GenerateCallExitNode(ExplodedNode *N);
148
149   /// Visualize the ExplodedGraph created by executing the simulation.
150   void ViewGraph(bool trim = false);
151
152   /// Visualize a trimmed ExplodedGraph that only contains paths to the given
153   /// nodes.
154   void ViewGraph(ArrayRef<const ExplodedNode*> Nodes);
155
156   /// getInitialState - Return the initial state used for the root vertex
157   ///  in the ExplodedGraph.
158   ProgramStateRef getInitialState(const LocationContext *InitLoc);
159
160   ExplodedGraph& getGraph() { return G; }
161   const ExplodedGraph& getGraph() const { return G; }
162
163   /// \brief Run the analyzer's garbage collection - remove dead symbols and
164   /// bindings from the state.
165   ///
166   /// Checkers can participate in this process with two callbacks:
167   /// \c checkLiveSymbols and \c checkDeadSymbols. See the CheckerDocumentation
168   /// class for more information.
169   ///
170   /// \param Node The predecessor node, from which the processing should start.
171   /// \param Out The returned set of output nodes.
172   /// \param ReferenceStmt The statement which is about to be processed.
173   ///        Everything needed for this statement should be considered live.
174   ///        A null statement means that everything in child LocationContexts
175   ///        is dead.
176   /// \param LC The location context of the \p ReferenceStmt. A null location
177   ///        context means that we have reached the end of analysis and that
178   ///        all statements and local variables should be considered dead.
179   /// \param DiagnosticStmt Used as a location for any warnings that should
180   ///        occur while removing the dead (e.g. leaks). By default, the
181   ///        \p ReferenceStmt is used.
182   /// \param K Denotes whether this is a pre- or post-statement purge. This
183   ///        must only be ProgramPoint::PostStmtPurgeDeadSymbolsKind if an
184   ///        entire location context is being cleared, in which case the
185   ///        \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise,
186   ///        it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default)
187   ///        and \p ReferenceStmt must be valid (non-null).
188   void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out,
189             const Stmt *ReferenceStmt, const LocationContext *LC,
190             const Stmt *DiagnosticStmt = 0,
191             ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind);
192
193   /// processCFGElement - Called by CoreEngine. Used to generate new successor
194   ///  nodes by processing the 'effects' of a CFG element.
195   void processCFGElement(const CFGElement E, ExplodedNode *Pred,
196                          unsigned StmtIdx, NodeBuilderContext *Ctx);
197
198   void ProcessStmt(const CFGStmt S, ExplodedNode *Pred);
199
200   void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred);
201
202   void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred);
203
204   void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, 
205                                ExplodedNode *Pred, ExplodedNodeSet &Dst);
206   void ProcessDeleteDtor(const CFGDeleteDtor D,
207                          ExplodedNode *Pred, ExplodedNodeSet &Dst);
208   void ProcessBaseDtor(const CFGBaseDtor D,
209                        ExplodedNode *Pred, ExplodedNodeSet &Dst);
210   void ProcessMemberDtor(const CFGMemberDtor D,
211                          ExplodedNode *Pred, ExplodedNodeSet &Dst);
212   void ProcessTemporaryDtor(const CFGTemporaryDtor D, 
213                             ExplodedNode *Pred, ExplodedNodeSet &Dst);
214
215   /// Called by CoreEngine when processing the entrance of a CFGBlock.
216   virtual void processCFGBlockEntrance(const BlockEdge &L,
217                                        NodeBuilderWithSinks &nodeBuilder,
218                                        ExplodedNode *Pred);
219   
220   /// ProcessBranch - Called by CoreEngine.  Used to generate successor
221   ///  nodes by processing the 'effects' of a branch condition.
222   void processBranch(const Stmt *Condition, const Stmt *Term, 
223                      NodeBuilderContext& BuilderCtx,
224                      ExplodedNode *Pred,
225                      ExplodedNodeSet &Dst,
226                      const CFGBlock *DstT,
227                      const CFGBlock *DstF);
228
229   /// Called by CoreEngine.  Used to processing branching behavior
230   /// at static initalizers.
231   void processStaticInitializer(const DeclStmt *DS,
232                                 NodeBuilderContext& BuilderCtx,
233                                 ExplodedNode *Pred,
234                                 ExplodedNodeSet &Dst,
235                                 const CFGBlock *DstT,
236                                 const CFGBlock *DstF);
237
238   /// processIndirectGoto - Called by CoreEngine.  Used to generate successor
239   ///  nodes by processing the 'effects' of a computed goto jump.
240   void processIndirectGoto(IndirectGotoNodeBuilder& builder);
241
242   /// ProcessSwitch - Called by CoreEngine.  Used to generate successor
243   ///  nodes by processing the 'effects' of a switch statement.
244   void processSwitch(SwitchNodeBuilder& builder);
245
246   /// Called by CoreEngine.  Used to generate end-of-path
247   /// nodes when the control reaches the end of a function.
248   void processEndOfFunction(NodeBuilderContext& BC,
249                             ExplodedNode *Pred);
250
251   /// Remove dead bindings/symbols before exiting a function.
252   void removeDeadOnEndOfFunction(NodeBuilderContext& BC,
253                                  ExplodedNode *Pred,
254                                  ExplodedNodeSet &Dst);
255
256   /// Generate the entry node of the callee.
257   void processCallEnter(CallEnter CE, ExplodedNode *Pred);
258
259   /// Generate the sequence of nodes that simulate the call exit and the post
260   /// visit for CallExpr.
261   void processCallExit(ExplodedNode *Pred);
262
263   /// Called by CoreEngine when the analysis worklist has terminated.
264   void processEndWorklist(bool hasWorkRemaining);
265
266   /// evalAssume - Callback function invoked by the ConstraintManager when
267   ///  making assumptions about state values.
268   ProgramStateRef processAssume(ProgramStateRef state, SVal cond,bool assumption);
269
270   /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
271   ///  region change should trigger a processRegionChanges update.
272   bool wantsRegionChangeUpdate(ProgramStateRef state);
273
274   /// processRegionChanges - Called by ProgramStateManager whenever a change is made
275   ///  to the store. Used to update checkers that track region values.
276   ProgramStateRef 
277   processRegionChanges(ProgramStateRef state,
278                        const InvalidatedSymbols *invalidated,
279                        ArrayRef<const MemRegion *> ExplicitRegions,
280                        ArrayRef<const MemRegion *> Regions,
281                        const CallEvent *Call);
282
283   /// printState - Called by ProgramStateManager to print checker-specific data.
284   void printState(raw_ostream &Out, ProgramStateRef State,
285                   const char *NL, const char *Sep);
286
287   virtual ProgramStateManager& getStateManager() { return StateMgr; }
288
289   StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
290
291   ConstraintManager& getConstraintManager() {
292     return StateMgr.getConstraintManager();
293   }
294
295   // FIXME: Remove when we migrate over to just using SValBuilder.
296   BasicValueFactory& getBasicVals() {
297     return StateMgr.getBasicVals();
298   }
299
300   // FIXME: Remove when we migrate over to just using ValueManager.
301   SymbolManager& getSymbolManager() { return SymMgr; }
302   const SymbolManager& getSymbolManager() const { return SymMgr; }
303
304   // Functions for external checking of whether we have unfinished work
305   bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
306   bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
307   bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); }
308
309   const CoreEngine &getCoreEngine() const { return Engine; }
310
311 public:
312   /// Visit - Transfer function logic for all statements.  Dispatches to
313   ///  other functions that handle specific kinds of statements.
314   void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst);
315
316   /// VisitArraySubscriptExpr - Transfer function for array accesses.
317   void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *Ex,
318                                    ExplodedNode *Pred,
319                                    ExplodedNodeSet &Dst);
320
321   /// VisitGCCAsmStmt - Transfer function logic for inline asm.
322   void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
323                        ExplodedNodeSet &Dst);
324
325   /// VisitMSAsmStmt - Transfer function logic for MS inline asm.
326   void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
327                       ExplodedNodeSet &Dst);
328
329   /// VisitBlockExpr - Transfer function logic for BlockExprs.
330   void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 
331                       ExplodedNodeSet &Dst);
332
333   /// VisitBinaryOperator - Transfer function logic for binary operators.
334   void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, 
335                            ExplodedNodeSet &Dst);
336
337
338   /// VisitCall - Transfer function for function calls.
339   void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
340                      ExplodedNodeSet &Dst);
341
342   /// VisitCast - Transfer function logic for all casts (implicit and explicit).
343   void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
344                 ExplodedNodeSet &Dst);
345
346   /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
347   void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, 
348                                 ExplodedNode *Pred, ExplodedNodeSet &Dst);
349
350   /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
351   void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D,
352                               ExplodedNode *Pred, ExplodedNodeSet &Dst);
353   
354   /// VisitDeclStmt - Transfer function logic for DeclStmts.
355   void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, 
356                      ExplodedNodeSet &Dst);
357
358   /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
359   void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, 
360                         ExplodedNode *Pred, ExplodedNodeSet &Dst);
361   
362   void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred,
363                          ExplodedNodeSet &Dst);
364
365   /// VisitLogicalExpr - Transfer function logic for '&&', '||'
366   void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
367                         ExplodedNodeSet &Dst);
368
369   /// VisitMemberExpr - Transfer function for member expressions.
370   void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, 
371                            ExplodedNodeSet &Dst);
372
373   /// Transfer function logic for ObjCAtSynchronizedStmts.
374   void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S,
375                                    ExplodedNode *Pred, ExplodedNodeSet &Dst);
376
377   /// Transfer function logic for computing the lvalue of an Objective-C ivar.
378   void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred,
379                                 ExplodedNodeSet &Dst);
380
381   /// VisitObjCForCollectionStmt - Transfer function logic for
382   ///  ObjCForCollectionStmt.
383   void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, 
384                                   ExplodedNode *Pred, ExplodedNodeSet &Dst);
385
386   void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred,
387                         ExplodedNodeSet &Dst);
388
389   /// VisitReturnStmt - Transfer function logic for return statements.
390   void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, 
391                        ExplodedNodeSet &Dst);
392   
393   /// VisitOffsetOfExpr - Transfer function for offsetof.
394   void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred,
395                          ExplodedNodeSet &Dst);
396
397   /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
398   void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
399                               ExplodedNode *Pred, ExplodedNodeSet &Dst);
400
401   /// VisitUnaryOperator - Transfer function logic for unary operators.
402   void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred, 
403                           ExplodedNodeSet &Dst);
404
405   /// Handle ++ and -- (both pre- and post-increment).
406   void VisitIncrementDecrementOperator(const UnaryOperator* U,
407                                        ExplodedNode *Pred,
408                                        ExplodedNodeSet &Dst);
409   
410   void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
411                          ExplodedNodeSet &Dst);
412
413   void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 
414                         ExplodedNodeSet & Dst);
415
416   void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred,
417                              ExplodedNodeSet &Dst);
418
419   void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest,
420                           const Stmt *S, bool IsBaseDtor,
421                           ExplodedNode *Pred, ExplodedNodeSet &Dst);
422
423   void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
424                        ExplodedNodeSet &Dst);
425
426   void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
427                           ExplodedNodeSet &Dst);
428
429   /// Create a C++ temporary object for an rvalue.
430   void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
431                                 ExplodedNode *Pred, 
432                                 ExplodedNodeSet &Dst);
433   
434   /// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic
435   ///  expressions of the form 'x != 0' and generate new nodes (stored in Dst)
436   ///  with those assumptions.
437   void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 
438                          const Expr *Ex);
439   
440   std::pair<const ProgramPointTag *, const ProgramPointTag*>
441     geteagerlyAssumeBinOpBifurcationTags();
442
443   SVal evalMinus(SVal X) {
444     return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X;
445   }
446
447   SVal evalComplement(SVal X) {
448     return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X;
449   }
450
451 public:
452
453   SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
454                  NonLoc L, NonLoc R, QualType T) {
455     return svalBuilder.evalBinOpNN(state, op, L, R, T);
456   }
457
458   SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
459                  NonLoc L, SVal R, QualType T) {
460     return R.isValid() ? svalBuilder.evalBinOpNN(state, op, L,
461                                                  R.castAs<NonLoc>(), T) : R;
462   }
463
464   SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
465                  SVal LHS, SVal RHS, QualType T) {
466     return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
467   }
468   
469 protected:
470   /// evalBind - Handle the semantics of binding a value to a specific location.
471   ///  This method is used by evalStore, VisitDeclStmt, and others.
472   void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred,
473                 SVal location, SVal Val, bool atDeclInit = false,
474                 const ProgramPoint *PP = 0);
475
476   /// Call PointerEscape callback when a value escapes as a result of bind.
477   ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State,
478                                               SVal Loc, SVal Val);
479   /// Call PointerEscape callback when a value escapes as a result of
480   /// region invalidation.
481   /// \param[in] ITraits Specifies invalidation traits for regions/symbols.
482   ProgramStateRef notifyCheckersOfPointerEscape(
483                             ProgramStateRef State,
484                             const InvalidatedSymbols *Invalidated,
485                             ArrayRef<const MemRegion *> ExplicitRegions,
486                             ArrayRef<const MemRegion *> Regions,
487                             const CallEvent *Call,
488                             RegionAndSymbolInvalidationTraits &ITraits);
489
490 public:
491   // FIXME: 'tag' should be removed, and a LocationContext should be used
492   // instead.
493   // FIXME: Comment on the meaning of the arguments, when 'St' may not
494   // be the same as Pred->state, and when 'location' may not be the
495   // same as state->getLValue(Ex).
496   /// Simulate a read of the result of Ex.
497   void evalLoad(ExplodedNodeSet &Dst,
498                 const Expr *NodeEx,  /* Eventually will be a CFGStmt */
499                 const Expr *BoundExpr,
500                 ExplodedNode *Pred,
501                 ProgramStateRef St,
502                 SVal location,
503                 const ProgramPointTag *tag = 0,
504                 QualType LoadTy = QualType());
505
506   // FIXME: 'tag' should be removed, and a LocationContext should be used
507   // instead.
508   void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
509                  ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val,
510                  const ProgramPointTag *tag = 0);
511
512   /// \brief Create a new state in which the call return value is binded to the
513   /// call origin expression.
514   ProgramStateRef bindReturnValue(const CallEvent &Call,
515                                   const LocationContext *LCtx,
516                                   ProgramStateRef State);
517
518   /// Evaluate a call, running pre- and post-call checks and allowing checkers
519   /// to be responsible for handling the evaluation of the call itself.
520   void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
521                 const CallEvent &Call);
522
523   /// \brief Default implementation of call evaluation.
524   void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred,
525                        const CallEvent &Call);
526 private:
527   void evalLoadCommon(ExplodedNodeSet &Dst,
528                       const Expr *NodeEx,  /* Eventually will be a CFGStmt */
529                       const Expr *BoundEx,
530                       ExplodedNode *Pred,
531                       ProgramStateRef St,
532                       SVal location,
533                       const ProgramPointTag *tag,
534                       QualType LoadTy);
535
536   // FIXME: 'tag' should be removed, and a LocationContext should be used
537   // instead.
538   void evalLocation(ExplodedNodeSet &Dst,
539                     const Stmt *NodeEx, /* This will eventually be a CFGStmt */
540                     const Stmt *BoundEx,
541                     ExplodedNode *Pred,
542                     ProgramStateRef St, SVal location,
543                     const ProgramPointTag *tag, bool isLoad);
544
545   /// Count the stack depth and determine if the call is recursive.
546   void examineStackFrames(const Decl *D, const LocationContext *LCtx,
547                           bool &IsRecursive, unsigned &StackDepth);
548
549   /// Checks our policies and decides weither the given call should be inlined.
550   bool shouldInlineCall(const CallEvent &Call, const Decl *D,
551                         const ExplodedNode *Pred);
552
553   bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
554                   ExplodedNode *Pred, ProgramStateRef State);
555
556   /// \brief Conservatively evaluate call by invalidating regions and binding
557   /// a conjured return value.
558   void conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
559                             ExplodedNode *Pred, ProgramStateRef State);
560
561   /// \brief Either inline or process the call conservatively (or both), based
562   /// on DynamicDispatchBifurcation data.
563   void BifurcateCall(const MemRegion *BifurReg,
564                      const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
565                      ExplodedNode *Pred);
566
567   bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC);
568
569   /// Models a trivial copy or move constructor or trivial assignment operator
570   /// call with a simple bind.
571   void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
572                           const CallEvent &Call);
573
574   /// If the value of the given expression is a NonLoc, copy it into a new
575   /// temporary object region, and replace the value of the expression with
576   /// that.
577   ///
578   /// If \p ResultE is provided, the new region will be bound to this expression
579   /// instead of \p E.
580   ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
581                                                 const LocationContext *LC,
582                                                 const Expr *E,
583                                                 const Expr *ResultE = 0);
584 };
585
586 /// Traits for storing the call processing policy inside GDM.
587 /// The GDM stores the corresponding CallExpr pointer.
588 // FIXME: This does not use the nice trait macros because it must be accessible
589 // from multiple translation units.
590 struct ReplayWithoutInlining{};
591 template <>
592 struct ProgramStateTrait<ReplayWithoutInlining> :
593   public ProgramStatePartialTrait<const void*> {
594   static void *GDMIndex() { static int index = 0; return &index; }
595 };
596
597 } // end ento namespace
598
599 } // end clang namespace
600
601 #endif