blob: 996d5c879acba19a238e0419cfe9872609e8e2ae [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
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 Stump87a05f12009-07-31 01:10:29 +000037 llvm::llvm_unreachable("unknown code decl");
Zhongxing Xu97ab3942009-07-30 01:17:21 +000038}
39
40CFG *AnalysisContext::getCFG() {
41 if (!cfg)
42 cfg = CFG::buildCFG(getBody(), &D->getASTContext());
43 return cfg;
44}
45
46ParentMap &AnalysisContext::getParentMap() {
47 if (!PM)
48 PM = new ParentMap(getBody());
49 return *PM;
50}
51
52LiveVariables *AnalysisContext::getLiveVariables() {
53 if (!liveness) {
54 CFG *c = getCFG();
55 if (!c)
56 return 0;
57
58 liveness = new LiveVariables(D->getASTContext(), *c);
59 liveness->runOnCFG(*c);
60 liveness->runOnAllBlocks(*c, 0, true);
61 }
62
63 return liveness;
64}
65
66AnalysisContext *AnalysisContextManager::getContext(Decl *D) {
67 iterator I = Contexts.find(D);
68 if (I != Contexts.end())
69 return &(I->second);
70
71 AnalysisContext &Ctx = Contexts[D];
72 Ctx.setDecl(D);
73 return &Ctx;
74}
Zhongxing Xu18c7c062009-08-03 07:23:22 +000075
76void LocationContext::Profile(llvm::FoldingSetNodeID &ID, ContextKind k,
77 AnalysisContext *ctx, LocationContext *parent) {
78 ID.AddInteger(k);
79 ID.AddPointer(ctx);
80 ID.AddPointer(parent);
81}
82
83void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID,AnalysisContext *ctx,
84 LocationContext *parent, Stmt *s) {
85 LocationContext::Profile(ID, StackFrame, ctx, parent);
86 ID.AddPointer(s);
87}
88
89void ScopeContext::Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
90 LocationContext *parent, Stmt *s) {
91 LocationContext::Profile(ID, Scope, ctx, parent);
92 ID.AddPointer(s);
93}
94
95StackFrameContext *LocationContextManager::getStackFrame(AnalysisContext *ctx,
96 LocationContext *parent, Stmt *s) {
97 llvm::FoldingSetNodeID ID;
98 StackFrameContext::Profile(ID, ctx, parent, s);
99 void *InsertPos;
100
101 StackFrameContext *f =
102 cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
103 if (!f) {
104 f = new StackFrameContext(ctx, parent, s);
105 Contexts.InsertNode(f, InsertPos);
106 }
107 return f;
108}
109
110ScopeContext *LocationContextManager::getScope(AnalysisContext *ctx,
111 LocationContext *parent, Stmt *s) {
112 llvm::FoldingSetNodeID ID;
113 ScopeContext::Profile(ID, ctx, parent, s);
114 void *InsertPos;
115
116 ScopeContext *scope =
117 cast_or_null<ScopeContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
118
119 if (!scope) {
120 scope = new ScopeContext(ctx, parent, s);
121 Contexts.InsertNode(scope, InsertPos);
122 }
123 return scope;
124}