blob: 66d2a419148628057236fc968fb614f1e7a7a623 [file] [log] [blame]
Ted Kremenek9e240492008-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
Ted Kremenek1309f9a2010-01-25 04:41:41 +000016#include "clang/Checker/PathSensitive/MemRegion.h"
Benjamin Kramer5e2d2c22010-03-27 21:19:47 +000017#include "clang/Analysis/AnalysisContext.h"
18#include "clang/Analysis/Support/BumpVector.h"
Ken Dyck199c3d62010-01-11 17:06:35 +000019#include "clang/AST/CharUnits.h"
Ted Kremenek1309f9a2010-01-25 04:41:41 +000020#include "llvm/Support/raw_ostream.h"
Ted Kremenek9e240492008-10-04 05:50:14 +000021
22using namespace clang;
23
Ted Kremenek25010132009-06-22 23:13:13 +000024//===----------------------------------------------------------------------===//
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000025// MemRegion Construction.
26//===----------------------------------------------------------------------===//
27
28template<typename RegionTy> struct MemRegionManagerTrait;
29
30template <typename RegionTy, typename A1>
31RegionTy* MemRegionManager::getRegion(const A1 a1) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000032
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000033 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
34 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000035
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000036 llvm::FoldingSetNodeID ID;
37 RegionTy::ProfileRegion(ID, a1, superRegion);
38 void* InsertPos;
39 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
40 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000041
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000042 if (!R) {
43 R = (RegionTy*) A.Allocate<RegionTy>();
44 new (R) RegionTy(a1, superRegion);
45 Regions.InsertNode(R, InsertPos);
46 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000047
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000048 return R;
49}
50
51template <typename RegionTy, typename A1>
52RegionTy* MemRegionManager::getSubRegion(const A1 a1,
53 const MemRegion *superRegion) {
54 llvm::FoldingSetNodeID ID;
55 RegionTy::ProfileRegion(ID, a1, superRegion);
56 void* InsertPos;
57 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
58 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000059
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000060 if (!R) {
61 R = (RegionTy*) A.Allocate<RegionTy>();
62 new (R) RegionTy(a1, superRegion);
63 Regions.InsertNode(R, InsertPos);
64 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000065
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000066 return R;
67}
68
69template <typename RegionTy, typename A1, typename A2>
70RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000071
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000072 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
73 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000074
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000075 llvm::FoldingSetNodeID ID;
76 RegionTy::ProfileRegion(ID, a1, a2, superRegion);
77 void* InsertPos;
78 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
79 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000080
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000081 if (!R) {
82 R = (RegionTy*) A.Allocate<RegionTy>();
83 new (R) RegionTy(a1, a2, superRegion);
84 Regions.InsertNode(R, InsertPos);
85 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000086
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000087 return R;
88}
89
90template <typename RegionTy, typename A1, typename A2>
91RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
92 const MemRegion *superRegion) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000093
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000094 llvm::FoldingSetNodeID ID;
95 RegionTy::ProfileRegion(ID, a1, a2, superRegion);
96 void* InsertPos;
97 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
98 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000099
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000100 if (!R) {
101 R = (RegionTy*) A.Allocate<RegionTy>();
102 new (R) RegionTy(a1, a2, superRegion);
103 Regions.InsertNode(R, InsertPos);
104 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000105
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000106 return R;
107}
108
Ted Kremenek67d12872009-12-07 22:05:27 +0000109template <typename RegionTy, typename A1, typename A2, typename A3>
110RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
111 const MemRegion *superRegion) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000112
Ted Kremenek67d12872009-12-07 22:05:27 +0000113 llvm::FoldingSetNodeID ID;
114 RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
115 void* InsertPos;
116 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
117 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000118
Ted Kremenek67d12872009-12-07 22:05:27 +0000119 if (!R) {
120 R = (RegionTy*) A.Allocate<RegionTy>();
121 new (R) RegionTy(a1, a2, a3, superRegion);
122 Regions.InsertNode(R, InsertPos);
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000123 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000124
Ted Kremenek67d12872009-12-07 22:05:27 +0000125 return R;
126}
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000127
128//===----------------------------------------------------------------------===//
Ted Kremenek42400962009-11-26 02:34:36 +0000129// Object destruction.
Ted Kremenek25010132009-06-22 23:13:13 +0000130//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000131
132MemRegion::~MemRegion() {}
133
Ted Kremenek42400962009-11-26 02:34:36 +0000134MemRegionManager::~MemRegionManager() {
135 // All regions and their data are BumpPtrAllocated. No need to call
136 // their destructors.
137}
138
139//===----------------------------------------------------------------------===//
140// Basic methods.
141//===----------------------------------------------------------------------===//
142
Zhongxing Xu7e5d6ed2009-01-08 13:17:14 +0000143bool SubRegion::isSubRegionOf(const MemRegion* R) const {
144 const MemRegion* r = getSuperRegion();
145 while (r != 0) {
146 if (r == R)
147 return true;
148 if (const SubRegion* sr = dyn_cast<SubRegion>(r))
149 r = sr->getSuperRegion();
150 else
151 break;
152 }
153 return false;
154}
155
Ted Kremeneka43484a2009-06-23 00:46:41 +0000156MemRegionManager* SubRegion::getMemRegionManager() const {
157 const SubRegion* r = this;
158 do {
159 const MemRegion *superRegion = r->getSuperRegion();
160 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
161 r = sr;
162 continue;
163 }
164 return superRegion->getMemRegionManager();
165 } while (1);
166}
167
Ted Kremenek5348f942009-12-14 22:15:06 +0000168const StackFrameContext *VarRegion::getStackFrame() const {
169 const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
170 return SSR ? SSR->getStackFrame() : NULL;
171}
172
173//===----------------------------------------------------------------------===//
174// FoldingSet profiling.
175//===----------------------------------------------------------------------===//
176
Ted Kremenek9e240492008-10-04 05:50:14 +0000177void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
178 ID.AddInteger((unsigned)getKind());
179}
180
Ted Kremenek67d12872009-12-07 22:05:27 +0000181void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
182 ID.AddInteger((unsigned)getKind());
183 ID.AddPointer(getStackFrame());
184}
185
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000186void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
187 ID.AddInteger((unsigned)getKind());
188 ID.AddPointer(getCodeRegion());
189}
190
Mike Stump1eb44332009-09-09 15:08:12 +0000191void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
192 const StringLiteral* Str,
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000193 const MemRegion* superRegion) {
194 ID.AddInteger((unsigned) StringRegionKind);
195 ID.AddPointer(Str);
196 ID.AddPointer(superRegion);
197}
198
Ted Kremenek7090ae12008-11-02 00:34:33 +0000199void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000200 const Expr* Ex, unsigned cnt,
201 const MemRegion *) {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000202 ID.AddInteger((unsigned) AllocaRegionKind);
203 ID.AddPointer(Ex);
204 ID.AddInteger(cnt);
205}
206
207void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000208 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenek7090ae12008-11-02 00:34:33 +0000209}
210
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000211void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
212 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
213}
214
215void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
216 const CompoundLiteralExpr* CL,
217 const MemRegion* superRegion) {
218 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
219 ID.AddPointer(CL);
220 ID.AddPointer(superRegion);
221}
222
Ted Kremenekde0d2632010-01-05 02:18:06 +0000223void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
224 const PointerType *PT,
225 const MemRegion *sRegion) {
226 ID.AddInteger((unsigned) CXXThisRegionKind);
227 ID.AddPointer(PT);
228 ID.AddPointer(sRegion);
229}
230
231void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
232 CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
233}
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000234
Ted Kremenek9e240492008-10-04 05:50:14 +0000235void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
236 const MemRegion* superRegion, Kind k) {
237 ID.AddInteger((unsigned) k);
238 ID.AddPointer(D);
239 ID.AddPointer(superRegion);
240}
241
242void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
243 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
244}
245
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000246void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000247 VarRegion::ProfileRegion(ID, getDecl(), superRegion);
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000248}
249
Ted Kremenek25010132009-06-22 23:13:13 +0000250void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
251 const MemRegion *sreg) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000252 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek6d0e2d22008-12-05 02:39:38 +0000253 ID.Add(sym);
Ted Kremenek25010132009-06-22 23:13:13 +0000254 ID.AddPointer(sreg);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000255}
256
257void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek25010132009-06-22 23:13:13 +0000258 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000259}
260
Ted Kremenekf936f452009-05-04 06:18:28 +0000261void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Mike Stump1eb44332009-09-09 15:08:12 +0000262 QualType ElementType, SVal Idx,
Zhongxing Xu511191c2008-10-21 05:27:10 +0000263 const MemRegion* superRegion) {
264 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekf936f452009-05-04 06:18:28 +0000265 ID.Add(ElementType);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000266 ID.AddPointer(superRegion);
267 Idx.Profile(ID);
268}
269
270void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf936f452009-05-04 06:18:28 +0000271 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000272}
Zhongxing Xu27b57062008-10-27 13:17:02 +0000273
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000274void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
275 const FunctionDecl *FD,
276 const MemRegion*) {
277 ID.AddInteger(MemRegion::FunctionTextRegionKind);
Ted Kremenekabd46e12009-08-28 04:49:15 +0000278 ID.AddPointer(FD);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000279}
280
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000281void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
282 FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
283}
284
285void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek67d12872009-12-07 22:05:27 +0000286 const BlockDecl *BD, CanQualType,
287 const AnalysisContext *AC,
288 const MemRegion*) {
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000289 ID.AddInteger(MemRegion::BlockTextRegionKind);
290 ID.AddPointer(BD);
291}
292
293void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000294 BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000295}
296
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000297void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
298 const BlockTextRegion *BC,
299 const LocationContext *LC,
Ted Kremenek67d12872009-12-07 22:05:27 +0000300 const MemRegion *sReg) {
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000301 ID.AddInteger(MemRegion::BlockDataRegionKind);
302 ID.AddPointer(BC);
303 ID.AddPointer(LC);
Ted Kremenek67d12872009-12-07 22:05:27 +0000304 ID.AddPointer(sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000305}
306
307void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000308 BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000309}
310
Zhongxing Xubb141212009-12-16 11:27:52 +0000311void CXXObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000312 Expr const *Ex,
Zhongxing Xubb141212009-12-16 11:27:52 +0000313 const MemRegion *sReg) {
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000314 ID.AddPointer(Ex);
Zhongxing Xubb141212009-12-16 11:27:52 +0000315 ID.AddPointer(sReg);
316}
317
318void CXXObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000319 ProfileRegion(ID, Ex, getSuperRegion());
Zhongxing Xubb141212009-12-16 11:27:52 +0000320}
321
Zhongxing Xu026c6632009-02-05 06:57:29 +0000322//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000323// Region pretty-printing.
324//===----------------------------------------------------------------------===//
325
Ted Kremenek8800ad42009-07-13 23:31:04 +0000326void MemRegion::dump() const {
327 dumpToStream(llvm::errs());
Ted Kremenek7f39d292009-07-02 17:24:10 +0000328}
329
Ted Kremenek9e240492008-10-04 05:50:14 +0000330std::string MemRegion::getString() const {
331 std::string s;
332 llvm::raw_string_ostream os(s);
Ted Kremenek8800ad42009-07-13 23:31:04 +0000333 dumpToStream(os);
Ted Kremenek9e240492008-10-04 05:50:14 +0000334 return os.str();
335}
336
Ted Kremenek8800ad42009-07-13 23:31:04 +0000337void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek9e240492008-10-04 05:50:14 +0000338 os << "<Unknown Region>";
339}
340
Ted Kremenek8800ad42009-07-13 23:31:04 +0000341void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000342 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
343}
344
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000345void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekabd46e12009-08-28 04:49:15 +0000346 os << "code{" << getDecl()->getDeclName().getAsString() << '}';
Ted Kremenek72e03202009-04-21 19:56:58 +0000347}
348
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000349void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000350 os << "block_code{" << (void*) this << '}';
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000351}
352
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000353void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
354 os << "block_data{" << BC << '}';
355}
356
357
Ted Kremenek8800ad42009-07-13 23:31:04 +0000358void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000359 // FIXME: More elaborate pretty-printing.
360 os << "{ " << (void*) CL << " }";
361}
362
Ted Kremenekde0d2632010-01-05 02:18:06 +0000363void CXXThisRegion::dumpToStream(llvm::raw_ostream &os) const {
364 os << "this";
365}
366
Ted Kremenek8800ad42009-07-13 23:31:04 +0000367void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000368 os << "element{" << superRegion << ','
369 << Index << ',' << getElementType().getAsString() << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000370}
371
Ted Kremenek8800ad42009-07-13 23:31:04 +0000372void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000373 os << superRegion << "->" << getDecl();
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000374}
375
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000376void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000377 os << "ivar{" << superRegion << ',' << getDecl() << '}';
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000378}
379
Mike Stump1eb44332009-09-09 15:08:12 +0000380void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekb27ed3d2009-07-19 20:38:24 +0000381 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000382}
383
Ted Kremenek8800ad42009-07-13 23:31:04 +0000384void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekaef5d222009-07-13 23:38:57 +0000385 os << "SymRegion{" << sym << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000386}
387
Ted Kremenek8800ad42009-07-13 23:31:04 +0000388void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000389 os << cast<VarDecl>(D);
Ted Kremenek9e240492008-10-04 05:50:14 +0000390}
391
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000392void RegionRawOffset::dump() const {
393 dumpToStream(llvm::errs());
394}
395
396void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
397 os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
398}
399
Ted Kremenek9e240492008-10-04 05:50:14 +0000400//===----------------------------------------------------------------------===//
401// MemRegionManager methods.
402//===----------------------------------------------------------------------===//
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000403
Ted Kremenek67d12872009-12-07 22:05:27 +0000404template <typename REG>
405const REG *MemRegionManager::LazyAllocate(REG*& region) {
Mike Stump1eb44332009-09-09 15:08:12 +0000406 if (!region) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000407 region = (REG*) A.Allocate<REG>();
408 new (region) REG(this);
Ted Kremenek9e240492008-10-04 05:50:14 +0000409 }
Ted Kremeneka43484a2009-06-23 00:46:41 +0000410
Ted Kremenek9e240492008-10-04 05:50:14 +0000411 return region;
412}
413
Ted Kremenek67d12872009-12-07 22:05:27 +0000414template <typename REG, typename ARG>
415const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
416 if (!region) {
417 region = (REG*) A.Allocate<REG>();
418 new (region) REG(this, a);
419 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000420
Ted Kremenek67d12872009-12-07 22:05:27 +0000421 return region;
Ted Kremenek9e240492008-10-04 05:50:14 +0000422}
423
Ted Kremenek67d12872009-12-07 22:05:27 +0000424const StackLocalsSpaceRegion*
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000425MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
426 assert(STC);
Zhongxing Xuc30470d2010-02-17 08:46:50 +0000427 StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
428
429 if (R)
430 return R;
431
432 R = A.Allocate<StackLocalsSpaceRegion>();
433 new (R) StackLocalsSpaceRegion(this, STC);
434 return R;
Ted Kremenekd05552a2009-07-02 18:14:59 +0000435}
436
Ted Kremenek67d12872009-12-07 22:05:27 +0000437const StackArgumentsSpaceRegion *
438MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000439 assert(STC);
Zhongxing Xuc30470d2010-02-17 08:46:50 +0000440 StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
441
442 if (R)
443 return R;
444
445 R = A.Allocate<StackArgumentsSpaceRegion>();
446 new (R) StackArgumentsSpaceRegion(this, STC);
447 return R;
Ted Kremenek67d12872009-12-07 22:05:27 +0000448}
449
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000450const GlobalsSpaceRegion
451*MemRegionManager::getGlobalsRegion(const CodeTextRegion *CR) {
452 if (!CR)
453 return LazyAllocate(globals);
454
455 StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
456 if (R)
457 return R;
458
459 R = A.Allocate<StaticGlobalSpaceRegion>();
460 new (R) StaticGlobalSpaceRegion(this, CR);
461 return R;
Ted Kremenek9e240492008-10-04 05:50:14 +0000462}
463
Ted Kremenek67d12872009-12-07 22:05:27 +0000464const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
Ted Kremenek9e240492008-10-04 05:50:14 +0000465 return LazyAllocate(heap);
466}
467
Ted Kremenekb48ad642009-12-04 00:26:31 +0000468const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
Zhongxing Xu17892752008-10-08 02:50:44 +0000469 return LazyAllocate(unknown);
470}
471
Ted Kremenekb48ad642009-12-04 00:26:31 +0000472const MemSpaceRegion *MemRegionManager::getCodeRegion() {
Zhongxing Xuec13d922009-04-10 08:45:10 +0000473 return LazyAllocate(code);
474}
475
Ted Kremenek25010132009-06-22 23:13:13 +0000476//===----------------------------------------------------------------------===//
477// Constructing regions.
478//===----------------------------------------------------------------------===//
479
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000480const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
Ted Kremenek67d12872009-12-07 22:05:27 +0000481 return getSubRegion<StringRegion>(Str, getGlobalsRegion());
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000482}
483
Ted Kremenekb48ad642009-12-04 00:26:31 +0000484const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
485 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000486 const MemRegion *sReg = 0;
Mike Stump1eb44332009-09-09 15:08:12 +0000487
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000488 if (D->hasGlobalStorage() && !D->isStaticLocal())
489 sReg = getGlobalsRegion();
490 else {
Ted Kremenek67d12872009-12-07 22:05:27 +0000491 // FIXME: Once we implement scope handling, we will need to properly lookup
492 // 'D' to the proper LocationContext.
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000493 const DeclContext *DC = D->getDeclContext();
494 const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
Mike Stump1eb44332009-09-09 15:08:12 +0000495
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000496 if (!STC)
497 sReg = getUnknownRegion();
498 else {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000499 if (D->hasLocalStorage()) {
500 sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
501 ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
502 : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
503 }
504 else {
505 assert(D->isStaticLocal());
506 const Decl *D = STC->getDecl();
507 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
508 sReg = getGlobalsRegion(getFunctionTextRegion(FD));
509 else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
510 const BlockTextRegion *BTR =
511 getBlockTextRegion(BD,
512 C.getCanonicalType(BD->getSignatureAsWritten()->getType()),
513 STC->getAnalysisContext());
514 sReg = getGlobalsRegion(BTR);
515 }
516 else {
517 // FIXME: For ObjC-methods, we need a new CodeTextRegion. For now
518 // just use the main global memspace.
519 sReg = getGlobalsRegion();
520 }
521 }
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000522 }
Ted Kremenek67d12872009-12-07 22:05:27 +0000523 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000524
Ted Kremenek67d12872009-12-07 22:05:27 +0000525 return getSubRegion<VarRegion>(D, sReg);
526}
527
528const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
529 const MemRegion *superR) {
530 return getSubRegion<VarRegion>(D, superR);
Ted Kremenek9e240492008-10-04 05:50:14 +0000531}
532
Ted Kremenekb48ad642009-12-04 00:26:31 +0000533const BlockDataRegion *
534MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
535 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000536 const MemRegion *sReg = 0;
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000537
538 if (LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000539 // FIXME: Once we implement scope handling, we want the parent region
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000540 // to be the scope.
Ted Kremenek67d12872009-12-07 22:05:27 +0000541 const StackFrameContext *STC = LC->getCurrentStackFrame();
542 assert(STC);
543 sReg = getStackLocalsRegion(STC);
544 }
545 else {
546 // We allow 'LC' to be NULL for cases where want BlockDataRegions
547 // without context-sensitivity.
548 sReg = getUnknownRegion();
549 }
550
551 return getSubRegion<BlockDataRegion>(BC, LC, sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000552}
553
Ted Kremenekb48ad642009-12-04 00:26:31 +0000554const CompoundLiteralRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000555MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
556 const LocationContext *LC) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000557
Ted Kremenek67d12872009-12-07 22:05:27 +0000558 const MemRegion *sReg = 0;
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000559
Ted Kremenek67d12872009-12-07 22:05:27 +0000560 if (CL->isFileScope())
561 sReg = getGlobalsRegion();
562 else {
563 const StackFrameContext *STC = LC->getCurrentStackFrame();
564 assert(STC);
565 sReg = getStackLocalsRegion(STC);
566 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000567
Ted Kremenek67d12872009-12-07 22:05:27 +0000568 return getSubRegion<CompoundLiteralRegion>(CL, sReg);
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000569}
570
Ted Kremenekb48ad642009-12-04 00:26:31 +0000571const ElementRegion*
Ted Kremenekf936f452009-05-04 06:18:28 +0000572MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Ted Kremenek46537392009-07-16 01:33:37 +0000573 const MemRegion* superRegion,
574 ASTContext& Ctx){
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000575
Ted Kremenek32f90102010-05-27 00:29:00 +0000576 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
Ted Kremenekabb042f2008-12-13 19:24:37 +0000577
Zhongxing Xu511191c2008-10-21 05:27:10 +0000578 llvm::FoldingSetNodeID ID;
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000579 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000580
581 void* InsertPos;
582 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
583 ElementRegion* R = cast_or_null<ElementRegion>(data);
584
585 if (!R) {
586 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000587 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000588 Regions.InsertNode(R, InsertPos);
589 }
590
591 return R;
592}
593
Ted Kremenekb48ad642009-12-04 00:26:31 +0000594const FunctionTextRegion *
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000595MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000596 return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
Zhongxing Xuec13d922009-04-10 08:45:10 +0000597}
598
Ted Kremenekb48ad642009-12-04 00:26:31 +0000599const BlockTextRegion *
Ted Kremenek67d12872009-12-07 22:05:27 +0000600MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
601 AnalysisContext *AC) {
602 return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000603}
604
605
Ted Kremenek993f1c72008-10-17 20:28:54 +0000606/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenekb48ad642009-12-04 00:26:31 +0000607const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000608 return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000609}
610
Ted Kremenekde0d2632010-01-05 02:18:06 +0000611const FieldRegion*
Ted Kremenekb48ad642009-12-04 00:26:31 +0000612MemRegionManager::getFieldRegion(const FieldDecl* d,
613 const MemRegion* superRegion){
Ted Kremenekeeea4562009-07-10 16:51:45 +0000614 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000615}
616
Ted Kremenekb48ad642009-12-04 00:26:31 +0000617const ObjCIvarRegion*
Ted Kremenek993f1c72008-10-17 20:28:54 +0000618MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
619 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000620 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000621}
622
Ted Kremenekde0d2632010-01-05 02:18:06 +0000623const CXXObjectRegion*
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000624MemRegionManager::getCXXObjectRegion(Expr const *E,
625 LocationContext const *LC) {
626 const StackFrameContext *SFC = LC->getCurrentStackFrame();
627 assert(SFC);
628 return getSubRegion<CXXObjectRegion>(E, getStackLocalsRegion(SFC));
Zhongxing Xubb141212009-12-16 11:27:52 +0000629}
630
Ted Kremenekde0d2632010-01-05 02:18:06 +0000631const CXXThisRegion*
632MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
633 const LocationContext *LC) {
634 const StackFrameContext *STC = LC->getCurrentStackFrame();
635 assert(STC);
636 const PointerType *PT = thisPointerTy->getAs<PointerType>();
637 assert(PT);
638 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
639}
640
Ted Kremenekb48ad642009-12-04 00:26:31 +0000641const AllocaRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000642MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
643 const LocationContext *LC) {
644 const StackFrameContext *STC = LC->getCurrentStackFrame();
645 assert(STC);
646 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
Ted Kremenek7090ae12008-11-02 00:34:33 +0000647}
648
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000649const MemSpaceRegion *MemRegion::getMemorySpace() const {
650 const MemRegion *R = this;
Ted Kremenekea20cd72009-06-23 18:05:21 +0000651 const SubRegion* SR = dyn_cast<SubRegion>(this);
Mike Stump1eb44332009-09-09 15:08:12 +0000652
Ted Kremenek993f1c72008-10-17 20:28:54 +0000653 while (SR) {
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000654 R = SR->getSuperRegion();
655 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000656 }
Mike Stump1eb44332009-09-09 15:08:12 +0000657
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000658 return dyn_cast<MemSpaceRegion>(R);
659}
660
661bool MemRegion::hasStackStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000662 return isa<StackSpaceRegion>(getMemorySpace());
Ted Kremenek9e240492008-10-04 05:50:14 +0000663}
Ted Kremenek1670e402009-04-11 00:11:10 +0000664
Ted Kremenekde0d2632010-01-05 02:18:06 +0000665bool MemRegion::hasStackNonParametersStorage() const {
666 return isa<StackLocalsSpaceRegion>(getMemorySpace());
Zhongxing Xudd198f02009-06-23 02:51:21 +0000667}
Ted Kremenek1670e402009-04-11 00:11:10 +0000668
Ted Kremenekde0d2632010-01-05 02:18:06 +0000669bool MemRegion::hasStackParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000670 return isa<StackArgumentsSpaceRegion>(getMemorySpace());
Ted Kremenekdc147262009-07-02 22:02:15 +0000671}
672
Ted Kremenek15086362009-07-02 18:25:09 +0000673bool MemRegion::hasGlobalsOrParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000674 const MemSpaceRegion *MS = getMemorySpace();
675 return isa<StackArgumentsSpaceRegion>(MS) ||
676 isa<GlobalsSpaceRegion>(MS);
Ted Kremenek15086362009-07-02 18:25:09 +0000677}
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000678
Zhongxing Xuadca2712009-11-10 02:37:53 +0000679// getBaseRegion strips away all elements and fields, and get the base region
680// of them.
681const MemRegion *MemRegion::getBaseRegion() const {
682 const MemRegion *R = this;
683 while (true) {
Ted Kremenek68b9a592010-04-06 22:06:03 +0000684 switch (R->getKind()) {
685 case MemRegion::ElementRegionKind:
686 case MemRegion::FieldRegionKind:
687 case MemRegion::ObjCIvarRegionKind:
688 R = cast<SubRegion>(R)->getSuperRegion();
689 continue;
690 default:
691 break;
Zhongxing Xuadca2712009-11-10 02:37:53 +0000692 }
693 break;
694 }
695 return R;
696}
697
Ted Kremenek1670e402009-04-11 00:11:10 +0000698//===----------------------------------------------------------------------===//
699// View handling.
700//===----------------------------------------------------------------------===//
701
Zhongxing Xu479529e2009-11-10 02:17:20 +0000702const MemRegion *MemRegion::StripCasts() const {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000703 const MemRegion *R = this;
704 while (true) {
Mike Stump1eb44332009-09-09 15:08:12 +0000705 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000706 // FIXME: generalize. Essentially we want to strip away ElementRegions
707 // that were layered on a symbolic region because of casts. We only
708 // want to strip away ElementRegions, however, where the index is 0.
709 SVal index = ER->getIndex();
710 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000711 if (CI->getValue().getSExtValue() == 0) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000712 R = ER->getSuperRegion();
713 continue;
714 }
715 }
716 }
717 break;
718 }
719 return R;
720}
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000721
722// FIXME: Merge with the implementation of the same method in Store.cpp
723static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
724 if (const RecordType *RT = Ty->getAs<RecordType>()) {
725 const RecordDecl *D = RT->getDecl();
Douglas Gregor952b0172010-02-11 01:04:33 +0000726 if (!D->getDefinition())
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000727 return false;
728 }
729
730 return true;
731}
732
733RegionRawOffset ElementRegion::getAsRawOffset() const {
Ken Dyck199c3d62010-01-11 17:06:35 +0000734 CharUnits offset = CharUnits::Zero();
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000735 const ElementRegion *ER = this;
736 const MemRegion *superR = NULL;
737 ASTContext &C = getContext();
Mike Stump1eb44332009-09-09 15:08:12 +0000738
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000739 // FIXME: Handle multi-dimensional arrays.
740
741 while (ER) {
742 superR = ER->getSuperRegion();
Mike Stump1eb44332009-09-09 15:08:12 +0000743
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000744 // FIXME: generalize to symbolic offsets.
745 SVal index = ER->getIndex();
746 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
747 // Update the offset.
748 int64_t i = CI->getValue().getSExtValue();
Mike Stump1eb44332009-09-09 15:08:12 +0000749
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000750 if (i != 0) {
751 QualType elemType = ER->getElementType();
Mike Stump1eb44332009-09-09 15:08:12 +0000752
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000753 // If we are pointing to an incomplete type, go no further.
754 if (!IsCompleteType(C, elemType)) {
755 superR = ER;
756 break;
757 }
Mike Stump1eb44332009-09-09 15:08:12 +0000758
Ken Dyck199c3d62010-01-11 17:06:35 +0000759 CharUnits size = C.getTypeSizeInChars(elemType);
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000760 offset += (i * size);
761 }
762
763 // Go to the next ElementRegion (if any).
764 ER = dyn_cast<ElementRegion>(superR);
765 continue;
766 }
Mike Stump1eb44332009-09-09 15:08:12 +0000767
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000768 return NULL;
769 }
Mike Stump1eb44332009-09-09 15:08:12 +0000770
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000771 assert(superR && "super region cannot be NULL");
Ken Dyck199c3d62010-01-11 17:06:35 +0000772 return RegionRawOffset(superR, offset.getQuantity());
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000773}
774
Ted Kremenek42400962009-11-26 02:34:36 +0000775//===----------------------------------------------------------------------===//
776// BlockDataRegion
777//===----------------------------------------------------------------------===//
778
779void BlockDataRegion::LazyInitializeReferencedVars() {
780 if (ReferencedVars)
781 return;
782
Ted Kremenek67d12872009-12-07 22:05:27 +0000783 AnalysisContext *AC = getCodeRegion()->getAnalysisContext();
Ted Kremenek42400962009-11-26 02:34:36 +0000784 AnalysisContext::referenced_decls_iterator I, E;
785 llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000786
Ted Kremenek42400962009-11-26 02:34:36 +0000787 if (I == E) {
788 ReferencedVars = (void*) 0x1;
789 return;
790 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000791
Ted Kremenek42400962009-11-26 02:34:36 +0000792 MemRegionManager &MemMgr = *getMemRegionManager();
793 llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
794 BumpVectorContext BC(A);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000795
Ted Kremenek42400962009-11-26 02:34:36 +0000796 typedef BumpVector<const MemRegion*> VarVec;
797 VarVec *BV = (VarVec*) A.Allocate<VarVec>();
Ted Kremenek02b1df62009-12-01 22:12:34 +0000798 new (BV) VarVec(BC, E - I);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000799
Ted Kremenek67d12872009-12-07 22:05:27 +0000800 for ( ; I != E; ++I) {
801 const VarDecl *VD = *I;
802 const VarRegion *VR = 0;
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000803
Ted Kremenek85248732010-02-06 00:30:00 +0000804 if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage())
Ted Kremenek67d12872009-12-07 22:05:27 +0000805 VR = MemMgr.getVarRegion(VD, this);
806 else {
807 if (LC)
808 VR = MemMgr.getVarRegion(VD, LC);
809 else {
810 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
811 }
812 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000813
Ted Kremenek67d12872009-12-07 22:05:27 +0000814 assert(VR);
815 BV->push_back(VR, BC);
816 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000817
Ted Kremenek42400962009-11-26 02:34:36 +0000818 ReferencedVars = BV;
819}
820
821BlockDataRegion::referenced_vars_iterator
822BlockDataRegion::referenced_vars_begin() const {
823 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
824
825 BumpVector<const MemRegion*> *Vec =
826 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000827
Ted Kremenek81cef582009-12-03 08:09:21 +0000828 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
829 NULL : Vec->begin());
Ted Kremenek42400962009-11-26 02:34:36 +0000830}
831
832BlockDataRegion::referenced_vars_iterator
833BlockDataRegion::referenced_vars_end() const {
834 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
835
836 BumpVector<const MemRegion*> *Vec =
837 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000838
Ted Kremenek81cef582009-12-03 08:09:21 +0000839 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
840 NULL : Vec->end());
Ted Kremenek42400962009-11-26 02:34:36 +0000841}