blob: 7c2af428d368429f6ba8f55ba2c4973adf201452 [file] [log] [blame]
Ted Kremenekb15eba42008-10-04 05:50:14 +00001//== MemRegion.cpp - Abstract memory regions for static 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 MemRegion and its subclasses. MemRegion defines a
11// partially-typed abstraction of memory useful for path-sensitive dataflow
12// analyses.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/Support/raw_ostream.h"
17#include "clang/Analysis/PathSensitive/MemRegion.h"
18
19using namespace clang;
20
21
22MemRegion::~MemRegion() {}
23
24void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
25 ID.AddInteger((unsigned)getKind());
26}
27
28void AnonTypedRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
29 const MemRegion* superRegion) {
30 ID.AddInteger((unsigned) AnonTypedRegionKind);
31 ID.Add(T);
32 ID.AddPointer(superRegion);
33}
34
35void AnonTypedRegion::Profile(llvm::FoldingSetNodeID& ID) const {
36 AnonTypedRegion::ProfileRegion(ID, T, superRegion);
37}
38
39void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
40 const MemRegion* superRegion, Kind k) {
41 ID.AddInteger((unsigned) k);
42 ID.AddPointer(D);
43 ID.AddPointer(superRegion);
44}
45
46void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
47 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
48}
49
50//===----------------------------------------------------------------------===//
51// Region pretty-printing.
52//===----------------------------------------------------------------------===//
53
54std::string MemRegion::getString() const {
55 std::string s;
56 llvm::raw_string_ostream os(s);
57 print(os);
58 return os.str();
59}
60
61void MemRegion::print(llvm::raw_ostream& os) const {
62 os << "<Unknown Region>";
63}
64
65void VarRegion::print(llvm::raw_ostream& os) const {
66 os << cast<VarDecl>(D)->getName();
67}
68
69//===----------------------------------------------------------------------===//
70// MemRegionManager methods.
71//===----------------------------------------------------------------------===//
72
73MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
74
75 if (!region) {
76 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
77 new (region) MemSpaceRegion();
78 }
79
80 return region;
81}
82
83MemSpaceRegion* MemRegionManager::getStackRegion() {
84 return LazyAllocate(stack);
85}
86
87MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
88 return LazyAllocate(globals);
89}
90
91MemSpaceRegion* MemRegionManager::getHeapRegion() {
92 return LazyAllocate(heap);
93}
94
95VarRegion* MemRegionManager::getVarRegion(const VarDecl* d,
96 MemRegion* superRegion) {
97 llvm::FoldingSetNodeID ID;
98 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind);
99
100 void* InsertPos;
101 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
102 VarRegion* R = cast_or_null<VarRegion>(data);
103
104 if (!R) {
105 R = (VarRegion*) A.Allocate<VarRegion>();
106 new (R) VarRegion(d, superRegion);
107 Regions.InsertNode(R, InsertPos);
108 }
109
110 return R;
111}
112
113FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
114 MemRegion* superRegion) {
115 llvm::FoldingSetNodeID ID;
116 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::FieldRegionKind);
117
118 void* InsertPos;
119 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
120 FieldRegion* R = cast_or_null<FieldRegion>(data);
121
122 if (!R) {
123 R = (FieldRegion*) A.Allocate<FieldRegion>();
124 new (R) FieldRegion(d, superRegion);
125 Regions.InsertNode(R, InsertPos);
126 }
127
128 return R;
129}
130
131ObjCIvarRegion* MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
132 MemRegion* superRegion) {
133 llvm::FoldingSetNodeID ID;
134 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::ObjCIvarRegionKind);
135
136 void* InsertPos;
137 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
138 ObjCIvarRegion* R = cast_or_null<ObjCIvarRegion>(data);
139
140 if (!R) {
141 R = (ObjCIvarRegion*) A.Allocate<FieldRegion>();
142 new (R) FieldRegion(d, superRegion);
143 Regions.InsertNode(R, InsertPos);
144 }
145
146 return R;
147}
148
149bool MemRegionManager::hasStackStorage(const MemRegion* R) {
150 MemSpaceRegion* S = getStackRegion();
151
152 while (R) {
153 if (R == S) return true;
154 R = R->getSuperRegion();
155 }
156
157 return false;
158}