blob: a4cb66be04b30c766df348311d47ba75a6bdb0f8 [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
Zhongxing Xu97ab3942009-07-30 01:17:21 +000036Stmt *AnalysisContext::getBody() {
Ted Kremenek23760022009-08-21 23:58:43 +000037 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Zhongxing Xu97ab3942009-07-30 01:17:21 +000038 return FD->getBody();
Ted Kremenek23760022009-08-21 23:58:43 +000039 else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Zhongxing Xu97ab3942009-07-30 01:17:21 +000040 return MD->getBody();
41
Mike Stump87a05f12009-07-31 01:10:29 +000042 llvm::llvm_unreachable("unknown code decl");
Zhongxing Xu97ab3942009-07-30 01:17:21 +000043}
44
Ted Kremenek82cd37c2009-08-21 23:25:54 +000045const ImplicitParamDecl *AnalysisContext::getSelfDecl() const {
46 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
47 return MD->getSelfDecl();
Mike Stump1eb44332009-09-09 15:08:12 +000048
Ted Kremenek82cd37c2009-08-21 23:25:54 +000049 return NULL;
50}
51
Zhongxing Xu97ab3942009-07-30 01:17:21 +000052CFG *AnalysisContext::getCFG() {
Mike Stump1eb44332009-09-09 15:08:12 +000053 if (!cfg)
Zhongxing Xu97ab3942009-07-30 01:17:21 +000054 cfg = CFG::buildCFG(getBody(), &D->getASTContext());
55 return cfg;
56}
57
58ParentMap &AnalysisContext::getParentMap() {
Mike Stump1eb44332009-09-09 15:08:12 +000059 if (!PM)
Zhongxing Xu97ab3942009-07-30 01:17:21 +000060 PM = new ParentMap(getBody());
61 return *PM;
62}
63
64LiveVariables *AnalysisContext::getLiveVariables() {
65 if (!liveness) {
66 CFG *c = getCFG();
67 if (!c)
68 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +000069
Zhongxing Xu97ab3942009-07-30 01:17:21 +000070 liveness = new LiveVariables(D->getASTContext(), *c);
71 liveness->runOnCFG(*c);
72 liveness->runOnAllBlocks(*c, 0, true);
73 }
Mike Stump1eb44332009-09-09 15:08:12 +000074
Zhongxing Xu97ab3942009-07-30 01:17:21 +000075 return liveness;
76}
77
Ted Kremenek23760022009-08-21 23:58:43 +000078AnalysisContext *AnalysisContextManager::getContext(const Decl *D) {
79 AnalysisContext *&AC = Contexts[D];
80 if (!AC)
81 AC = new AnalysisContext(D);
Mike Stump1eb44332009-09-09 15:08:12 +000082
Ted Kremenek23760022009-08-21 23:58:43 +000083 return AC;
Zhongxing Xu97ab3942009-07-30 01:17:21 +000084}
Zhongxing Xu18c7c062009-08-03 07:23:22 +000085
86void LocationContext::Profile(llvm::FoldingSetNodeID &ID, ContextKind k,
Ted Kremenek54c809b2009-08-21 23:39:58 +000087 AnalysisContext *ctx,
88 const LocationContext *parent) {
Zhongxing Xu18c7c062009-08-03 07:23:22 +000089 ID.AddInteger(k);
90 ID.AddPointer(ctx);
91 ID.AddPointer(parent);
92}
93
94void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID,AnalysisContext *ctx,
Ted Kremenek54c809b2009-08-21 23:39:58 +000095 const LocationContext *parent, const Stmt *s) {
Zhongxing Xu18c7c062009-08-03 07:23:22 +000096 LocationContext::Profile(ID, StackFrame, ctx, parent);
97 ID.AddPointer(s);
98}
99
100void ScopeContext::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, Scope, ctx, parent);
103 ID.AddPointer(s);
104}
105
Ted Kremenek54c809b2009-08-21 23:39:58 +0000106StackFrameContext*
Mike Stump1eb44332009-09-09 15:08:12 +0000107LocationContextManager::getStackFrame(AnalysisContext *ctx,
Ted Kremenek54c809b2009-08-21 23:39:58 +0000108 const LocationContext *parent,
109 const Stmt *s) {
Zhongxing Xu18c7c062009-08-03 07:23:22 +0000110 llvm::FoldingSetNodeID ID;
111 StackFrameContext::Profile(ID, ctx, parent, s);
112 void *InsertPos;
113
Mike Stump1eb44332009-09-09 15:08:12 +0000114 StackFrameContext *f =
Zhongxing Xu18c7c062009-08-03 07:23:22 +0000115 cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
116 if (!f) {
117 f = new StackFrameContext(ctx, parent, s);
118 Contexts.InsertNode(f, InsertPos);
119 }
120 return f;
121}
122
123ScopeContext *LocationContextManager::getScope(AnalysisContext *ctx,
Ted Kremenek54c809b2009-08-21 23:39:58 +0000124 const LocationContext *parent,
125 const Stmt *s) {
Zhongxing Xu18c7c062009-08-03 07:23:22 +0000126 llvm::FoldingSetNodeID ID;
127 ScopeContext::Profile(ID, ctx, parent, s);
128 void *InsertPos;
Mike Stump1eb44332009-09-09 15:08:12 +0000129
Zhongxing Xu18c7c062009-08-03 07:23:22 +0000130 ScopeContext *scope =
131 cast_or_null<ScopeContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
132
133 if (!scope) {
134 scope = new ScopeContext(ctx, parent, s);
135 Contexts.InsertNode(scope, InsertPos);
136 }
137 return scope;
138}