blob: 640912ad6b39de79aed52e41d00924e802576fd2 [file] [log] [blame]
Zhongxing Xu97ab3942009-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 Stump87a05f12009-07-31 01:10:29 +000021#include "llvm/Support/ErrorHandling.h"
Zhongxing Xu97ab3942009-07-30 01:17:21 +000022
23using namespace clang;
24
25AnalysisContext::~AnalysisContext() {
26 delete cfg;
27 delete liveness;
28 delete PM;
29}
30
Ted Kremenek23760022009-08-21 23:58:43 +000031AnalysisContextManager::~AnalysisContextManager() {
32 for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
33 delete I->second;
34}
35
Ted Kremenek58f5ec72009-10-20 21:39:41 +000036void AnalysisContextManager::clear() {
37 for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
38 delete I->second;
39 Contexts.clear();
40}
41
Zhongxing Xu97ab3942009-07-30 01:17:21 +000042Stmt *AnalysisContext::getBody() {
Ted Kremenek23760022009-08-21 23:58:43 +000043 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Zhongxing Xu97ab3942009-07-30 01:17:21 +000044 return FD->getBody();
Ted Kremenek23760022009-08-21 23:58:43 +000045 else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Zhongxing Xu97ab3942009-07-30 01:17:21 +000046 return MD->getBody();
47
Mike Stump87a05f12009-07-31 01:10:29 +000048 llvm::llvm_unreachable("unknown code decl");
Zhongxing Xu97ab3942009-07-30 01:17:21 +000049}
50
Ted Kremenek82cd37c2009-08-21 23:25:54 +000051const ImplicitParamDecl *AnalysisContext::getSelfDecl() const {
52 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
53 return MD->getSelfDecl();
Mike Stump1eb44332009-09-09 15:08:12 +000054
Ted Kremenek82cd37c2009-08-21 23:25:54 +000055 return NULL;
56}
57
Zhongxing Xu97ab3942009-07-30 01:17:21 +000058CFG *AnalysisContext::getCFG() {
Mike Stump1eb44332009-09-09 15:08:12 +000059 if (!cfg)
Zhongxing Xu97ab3942009-07-30 01:17:21 +000060 cfg = CFG::buildCFG(getBody(), &D->getASTContext());
61 return cfg;
62}
63
64ParentMap &AnalysisContext::getParentMap() {
Mike Stump1eb44332009-09-09 15:08:12 +000065 if (!PM)
Zhongxing Xu97ab3942009-07-30 01:17:21 +000066 PM = new ParentMap(getBody());
67 return *PM;
68}
69
70LiveVariables *AnalysisContext::getLiveVariables() {
71 if (!liveness) {
72 CFG *c = getCFG();
73 if (!c)
74 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +000075
Zhongxing Xu97ab3942009-07-30 01:17:21 +000076 liveness = new LiveVariables(D->getASTContext(), *c);
77 liveness->runOnCFG(*c);
78 liveness->runOnAllBlocks(*c, 0, true);
79 }
Mike Stump1eb44332009-09-09 15:08:12 +000080
Zhongxing Xu97ab3942009-07-30 01:17:21 +000081 return liveness;
82}
83
Ted Kremenek23760022009-08-21 23:58:43 +000084AnalysisContext *AnalysisContextManager::getContext(const Decl *D) {
85 AnalysisContext *&AC = Contexts[D];
86 if (!AC)
87 AC = new AnalysisContext(D);
Mike Stump1eb44332009-09-09 15:08:12 +000088
Ted Kremenek23760022009-08-21 23:58:43 +000089 return AC;
Zhongxing Xu97ab3942009-07-30 01:17:21 +000090}
Zhongxing Xu18c7c062009-08-03 07:23:22 +000091
92void LocationContext::Profile(llvm::FoldingSetNodeID &ID, ContextKind k,
Ted Kremenek54c809b2009-08-21 23:39:58 +000093 AnalysisContext *ctx,
94 const LocationContext *parent) {
Zhongxing Xu18c7c062009-08-03 07:23:22 +000095 ID.AddInteger(k);
96 ID.AddPointer(ctx);
97 ID.AddPointer(parent);
98}
99
100void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID,AnalysisContext *ctx,
Ted Kremenek54c809b2009-08-21 23:39:58 +0000101 const LocationContext *parent, const Stmt *s) {
Zhongxing Xu18c7c062009-08-03 07:23:22 +0000102 LocationContext::Profile(ID, StackFrame, ctx, parent);
103 ID.AddPointer(s);
104}
105
106void ScopeContext::Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
Ted Kremenek54c809b2009-08-21 23:39:58 +0000107 const LocationContext *parent, const Stmt *s) {
Zhongxing Xu18c7c062009-08-03 07:23:22 +0000108 LocationContext::Profile(ID, Scope, ctx, parent);
109 ID.AddPointer(s);
110}
111
Ted Kremenek58f5ec72009-10-20 21:39:41 +0000112LocationContextManager::~LocationContextManager() {
113 clear();
114}
115
116void LocationContextManager::clear() {
117 for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
118 E = Contexts.end(); I != E; ) {
119 LocationContext *LC = &*I;
120 ++I;
121 delete LC;
122 }
123
124 Contexts.clear();
125}
126
Ted Kremenek54c809b2009-08-21 23:39:58 +0000127StackFrameContext*
Mike Stump1eb44332009-09-09 15:08:12 +0000128LocationContextManager::getStackFrame(AnalysisContext *ctx,
Ted Kremenek54c809b2009-08-21 23:39:58 +0000129 const LocationContext *parent,
130 const Stmt *s) {
Zhongxing Xu18c7c062009-08-03 07:23:22 +0000131 llvm::FoldingSetNodeID ID;
132 StackFrameContext::Profile(ID, ctx, parent, s);
133 void *InsertPos;
134
Mike Stump1eb44332009-09-09 15:08:12 +0000135 StackFrameContext *f =
Zhongxing Xu18c7c062009-08-03 07:23:22 +0000136 cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
137 if (!f) {
138 f = new StackFrameContext(ctx, parent, s);
139 Contexts.InsertNode(f, InsertPos);
140 }
141 return f;
142}
143
144ScopeContext *LocationContextManager::getScope(AnalysisContext *ctx,
Ted Kremenek54c809b2009-08-21 23:39:58 +0000145 const LocationContext *parent,
146 const Stmt *s) {
Zhongxing Xu18c7c062009-08-03 07:23:22 +0000147 llvm::FoldingSetNodeID ID;
148 ScopeContext::Profile(ID, ctx, parent, s);
149 void *InsertPos;
Mike Stump1eb44332009-09-09 15:08:12 +0000150
Zhongxing Xu18c7c062009-08-03 07:23:22 +0000151 ScopeContext *scope =
152 cast_or_null<ScopeContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
153
154 if (!scope) {
155 scope = new ScopeContext(ctx, parent, s);
156 Contexts.InsertNode(scope, InsertPos);
157 }
158 return scope;
159}