 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
0.0% |
0 / 18 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
0.0% |
0 / 18 |
| |
|
Line Coverage: |
0.0% |
0 / 45 |
| |
 |
|
 |
1 : //===--- CallInliner.cpp - Transfer function that inlines callee ----------===//
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 implements the callee inlining transfer function.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/Checker/PathSensitive/CheckerVisitor.h"
15 : #include "clang/Checker/PathSensitive/GRState.h"
16 : #include "clang/Checker/Checkers/LocalCheckers.h"
17 :
18 : using namespace clang;
19 :
20 : namespace {
0: branch 2 not taken
0: branch 3 not taken
0: branch 6 not taken
0: branch 7 not taken
21 0: class CallInliner : public Checker {
22 : public:
23 0: static void *getTag() {
24 : static int x;
25 0: return &x;
26 : }
27 :
28 : virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
29 : virtual void EvalEndPath(GREndPathNodeBuilder &B,void *tag,GRExprEngine &Eng);
30 : };
31 : }
32 :
33 0: void clang::RegisterCallInliner(GRExprEngine &Eng) {
34 0: Eng.registerCheck(new CallInliner());
35 0: }
36 :
37 0: bool CallInliner::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
38 0: const GRState *state = C.getState();
39 0: const Expr *Callee = CE->getCallee();
40 0: SVal L = state->getSVal(Callee);
41 :
42 0: const FunctionDecl *FD = L.getAsFunctionDecl();
0: branch 0 not taken
0: branch 1 not taken
43 0: if (!FD)
44 0: return false;
45 :
0: branch 1 not taken
0: branch 2 not taken
46 0: if (!FD->isThisDeclarationADefinition())
47 0: return false;
48 :
49 0: GRStmtNodeBuilder &Builder = C.getNodeBuilder();
50 : // Make a new LocationContext.
51 : const StackFrameContext *LocCtx = C.getAnalysisManager().getStackFrame(FD,
52 : C.getPredecessor()->getLocationContext(), CE,
53 0: Builder.getBlock(), Builder.getIndex());
54 :
55 0: CFGBlock const *Entry = &(LocCtx->getCFG()->getEntry());
56 :
0: branch 1 not taken
0: branch 2 not taken
57 0: assert (Entry->empty() && "Entry block must be empty.");
58 :
0: branch 1 not taken
0: branch 2 not taken
59 0: assert (Entry->succ_size() == 1 && "Entry block must have 1 successor.");
60 :
61 : // Get the solitary successor.
62 0: CFGBlock const *SuccB = *(Entry->succ_begin());
63 :
64 : // Construct an edge representing the starting location in the function.
65 0: BlockEdge Loc(Entry, SuccB, LocCtx);
66 :
67 0: state = C.getStoreManager().EnterStackFrame(state, LocCtx);
68 : // This is a hack. We really should not use the GRStmtNodeBuilder.
69 : bool isNew;
70 0: GRExprEngine &Eng = C.getEngine();
71 0: ExplodedNode *Pred = C.getPredecessor();
72 :
73 :
74 0: ExplodedNode *SuccN = Eng.getGraph().getNode(Loc, state, &isNew);
75 0: SuccN->addPredecessor(Pred, Eng.getGraph());
76 0: C.getNodeBuilder().Deferred.erase(Pred);
77 :
0: branch 0 not taken
0: branch 1 not taken
78 0: if (isNew)
79 0: Builder.getWorkList()->Enqueue(SuccN);
80 :
81 0: Builder.HasGeneratedNode = true;
82 :
83 0: return true;
84 : }
85 :
86 : void CallInliner::EvalEndPath(GREndPathNodeBuilder &B, void *tag,
87 0: GRExprEngine &Eng) {
88 0: const GRState *state = B.getState();
89 0: ExplodedNode *Pred = B.getPredecessor();
90 : const StackFrameContext *LocCtx =
91 0: cast<StackFrameContext>(Pred->getLocationContext());
92 :
93 0: const Stmt *CE = LocCtx->getCallSite();
94 :
95 : // Check if this is the top level stack frame.
0: branch 1 not taken
0: branch 2 not taken
96 0: if (!LocCtx->getParent())
97 0: return;
98 :
99 0: PostStmt NodeLoc(CE, LocCtx->getParent());
100 :
101 : bool isNew;
102 0: ExplodedNode *Succ = Eng.getGraph().getNode(NodeLoc, state, &isNew);
103 0: Succ->addPredecessor(Pred, Eng.getGraph());
104 :
105 : // When creating the new work list unit, increment the statement index to
106 : // point to the statement after the CallExpr.
0: branch 0 not taken
0: branch 1 not taken
107 0: if (isNew)
108 : B.getWorkList().Enqueue(Succ,
109 : *const_cast<CFGBlock*>(LocCtx->getCallSiteBlock()),
110 0: LocCtx->getIndex() + 1);
111 :
112 0: B.HasGeneratedNode = true;
113 : }
Generated: 2010-02-10 01:31 by zcov