blob: 324fdf2dce817f3ffbf05fefa55343f8cc30c6cb [file] [log] [blame]
Zhongxing Xu22f30422009-07-30 01:17:21 +00001//== AnalysisContext.cpp - Analysis context for Path Sens analysis -*- 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 AnalysisContext, a class that manages the analysis context
11// data for path sensitive analysis.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Analysis/PathSensitive/AnalysisContext.h"
16#include "clang/Analysis/Analyses/LiveVariables.h"
17#include "clang/Analysis/CFG.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/AST/ParentMap.h"
Mike Stump5749db22009-07-31 01:10:29 +000021#include "llvm/Support/ErrorHandling.h"
Zhongxing Xu22f30422009-07-30 01:17:21 +000022
23using namespace clang;
24
25AnalysisContext::~AnalysisContext() {
26 delete cfg;
27 delete liveness;
28 delete PM;
29}
30
31Stmt *AnalysisContext::getBody() {
32 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
33 return FD->getBody();
34 else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
35 return MD->getBody();
36
Mike Stump5749db22009-07-31 01:10:29 +000037 llvm::llvm_unreachable("unknown code decl");
Zhongxing Xu22f30422009-07-30 01:17:21 +000038}
39
Ted Kremenek22e45e82009-08-21 23:25:54 +000040const ImplicitParamDecl *AnalysisContext::getSelfDecl() const {
41 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
42 return MD->getSelfDecl();
43
44 return NULL;
45}
46
Zhongxing Xu22f30422009-07-30 01:17:21 +000047CFG *AnalysisContext::getCFG() {
48 if (!cfg)
49 cfg = CFG::buildCFG(getBody(), &D->getASTContext());
50 return cfg;
51}
52
53ParentMap &AnalysisContext::getParentMap() {
54 if (!PM)
55 PM = new ParentMap(getBody());
56 return *PM;
57}
58
59LiveVariables *AnalysisContext::getLiveVariables() {
60 if (!liveness) {
61 CFG *c = getCFG();
62 if (!c)
63 return 0;
64
65 liveness = new LiveVariables(D->getASTContext(), *c);
66 liveness->runOnCFG(*c);
67 liveness->runOnAllBlocks(*c, 0, true);
68 }
69
70 return liveness;
71}
72
73AnalysisContext *AnalysisContextManager::getContext(Decl *D) {
74 iterator I = Contexts.find(D);
75 if (I != Contexts.end())
76 return &(I->second);
77
78 AnalysisContext &Ctx = Contexts[D];
79 Ctx.setDecl(D);
80 return &Ctx;
81}
Zhongxing Xu462d7a22009-08-03 07:23:22 +000082
83void LocationContext::Profile(llvm::FoldingSetNodeID &ID, ContextKind k,
84 AnalysisContext *ctx, LocationContext *parent) {
85 ID.AddInteger(k);
86 ID.AddPointer(ctx);
87 ID.AddPointer(parent);
88}
89
90void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID,AnalysisContext *ctx,
91 LocationContext *parent, Stmt *s) {
92 LocationContext::Profile(ID, StackFrame, ctx, parent);
93 ID.AddPointer(s);
94}
95
96void ScopeContext::Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
97 LocationContext *parent, Stmt *s) {
98 LocationContext::Profile(ID, Scope, ctx, parent);
99 ID.AddPointer(s);
100}
101
102StackFrameContext *LocationContextManager::getStackFrame(AnalysisContext *ctx,
103 LocationContext *parent, Stmt *s) {
104 llvm::FoldingSetNodeID ID;
105 StackFrameContext::Profile(ID, ctx, parent, s);
106 void *InsertPos;
107
108 StackFrameContext *f =
109 cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
110 if (!f) {
111 f = new StackFrameContext(ctx, parent, s);
112 Contexts.InsertNode(f, InsertPos);
113 }
114 return f;
115}
116
117ScopeContext *LocationContextManager::getScope(AnalysisContext *ctx,
118 LocationContext *parent, Stmt *s) {
119 llvm::FoldingSetNodeID ID;
120 ScopeContext::Profile(ID, ctx, parent, s);
121 void *InsertPos;
122
123 ScopeContext *scope =
124 cast_or_null<ScopeContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
125
126 if (!scope) {
127 scope = new ScopeContext(ctx, parent, s);
128 Contexts.InsertNode(scope, InsertPos);
129 }
130 return scope;
131}