blob: ef47ece70ed2d712b0ca6fe0b66340448e2f609f [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,
Ted Kremenek698edee2009-08-21 23:39:58 +000084 AnalysisContext *ctx,
85 const LocationContext *parent) {
Zhongxing Xu462d7a22009-08-03 07:23:22 +000086 ID.AddInteger(k);
87 ID.AddPointer(ctx);
88 ID.AddPointer(parent);
89}
90
91void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID,AnalysisContext *ctx,
Ted Kremenek698edee2009-08-21 23:39:58 +000092 const LocationContext *parent, const Stmt *s) {
Zhongxing Xu462d7a22009-08-03 07:23:22 +000093 LocationContext::Profile(ID, StackFrame, ctx, parent);
94 ID.AddPointer(s);
95}
96
97void ScopeContext::Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
Ted Kremenek698edee2009-08-21 23:39:58 +000098 const LocationContext *parent, const Stmt *s) {
Zhongxing Xu462d7a22009-08-03 07:23:22 +000099 LocationContext::Profile(ID, Scope, ctx, parent);
100 ID.AddPointer(s);
101}
102
Ted Kremenek698edee2009-08-21 23:39:58 +0000103StackFrameContext*
104LocationContextManager::getStackFrame(AnalysisContext *ctx,
105 const LocationContext *parent,
106 const Stmt *s) {
Zhongxing Xu462d7a22009-08-03 07:23:22 +0000107 llvm::FoldingSetNodeID ID;
108 StackFrameContext::Profile(ID, ctx, parent, s);
109 void *InsertPos;
110
111 StackFrameContext *f =
112 cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
113 if (!f) {
114 f = new StackFrameContext(ctx, parent, s);
115 Contexts.InsertNode(f, InsertPos);
116 }
117 return f;
118}
119
120ScopeContext *LocationContextManager::getScope(AnalysisContext *ctx,
Ted Kremenek698edee2009-08-21 23:39:58 +0000121 const LocationContext *parent,
122 const Stmt *s) {
Zhongxing Xu462d7a22009-08-03 07:23:22 +0000123 llvm::FoldingSetNodeID ID;
124 ScopeContext::Profile(ID, ctx, parent, s);
125 void *InsertPos;
126
127 ScopeContext *scope =
128 cast_or_null<ScopeContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
129
130 if (!scope) {
131 scope = new ScopeContext(ctx, parent, s);
132 Contexts.InsertNode(scope, InsertPos);
133 }
134 return scope;
135}