blob: 6a60a61bfabe6e522cb73c8ad0aba94fb077e8e6 [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"
Jordy Rose32f26562010-07-04 00:00:41 +000017#include "clang/Checker/PathSensitive/ValueManager.h"
Benjamin Kramer5e2d2c22010-03-27 21:19:47 +000018#include "clang/Analysis/AnalysisContext.h"
19#include "clang/Analysis/Support/BumpVector.h"
Ken Dyck199c3d62010-01-11 17:06:35 +000020#include "clang/AST/CharUnits.h"
Ted Kremenek1309f9a2010-01-25 04:41:41 +000021#include "llvm/Support/raw_ostream.h"
Ted Kremenek9e240492008-10-04 05:50:14 +000022
23using namespace clang;
24
Ted Kremenek25010132009-06-22 23:13:13 +000025//===----------------------------------------------------------------------===//
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000026// MemRegion Construction.
27//===----------------------------------------------------------------------===//
28
29template<typename RegionTy> struct MemRegionManagerTrait;
30
31template <typename RegionTy, typename A1>
32RegionTy* MemRegionManager::getRegion(const A1 a1) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000033
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000034 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
35 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000036
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000037 llvm::FoldingSetNodeID ID;
38 RegionTy::ProfileRegion(ID, a1, superRegion);
39 void* InsertPos;
40 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
41 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000042
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000043 if (!R) {
44 R = (RegionTy*) A.Allocate<RegionTy>();
45 new (R) RegionTy(a1, superRegion);
46 Regions.InsertNode(R, InsertPos);
47 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000048
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000049 return R;
50}
51
52template <typename RegionTy, typename A1>
53RegionTy* MemRegionManager::getSubRegion(const A1 a1,
54 const MemRegion *superRegion) {
55 llvm::FoldingSetNodeID ID;
56 RegionTy::ProfileRegion(ID, a1, superRegion);
57 void* InsertPos;
58 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
59 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000060
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000061 if (!R) {
62 R = (RegionTy*) A.Allocate<RegionTy>();
63 new (R) RegionTy(a1, superRegion);
64 Regions.InsertNode(R, InsertPos);
65 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000066
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000067 return R;
68}
69
70template <typename RegionTy, typename A1, typename A2>
71RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000072
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000073 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
74 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000075
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000076 llvm::FoldingSetNodeID ID;
77 RegionTy::ProfileRegion(ID, a1, a2, superRegion);
78 void* InsertPos;
79 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
80 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000081
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000082 if (!R) {
83 R = (RegionTy*) A.Allocate<RegionTy>();
84 new (R) RegionTy(a1, a2, superRegion);
85 Regions.InsertNode(R, InsertPos);
86 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000087
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000088 return R;
89}
90
91template <typename RegionTy, typename A1, typename A2>
92RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
93 const MemRegion *superRegion) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000094
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000095 llvm::FoldingSetNodeID ID;
96 RegionTy::ProfileRegion(ID, a1, a2, superRegion);
97 void* InsertPos;
98 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
99 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000100
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000101 if (!R) {
102 R = (RegionTy*) A.Allocate<RegionTy>();
103 new (R) RegionTy(a1, a2, superRegion);
104 Regions.InsertNode(R, InsertPos);
105 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000106
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000107 return R;
108}
109
Ted Kremenek67d12872009-12-07 22:05:27 +0000110template <typename RegionTy, typename A1, typename A2, typename A3>
111RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
112 const MemRegion *superRegion) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000113
Ted Kremenek67d12872009-12-07 22:05:27 +0000114 llvm::FoldingSetNodeID ID;
115 RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
116 void* InsertPos;
117 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
118 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000119
Ted Kremenek67d12872009-12-07 22:05:27 +0000120 if (!R) {
121 R = (RegionTy*) A.Allocate<RegionTy>();
122 new (R) RegionTy(a1, a2, a3, superRegion);
123 Regions.InsertNode(R, InsertPos);
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000124 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000125
Ted Kremenek67d12872009-12-07 22:05:27 +0000126 return R;
127}
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000128
129//===----------------------------------------------------------------------===//
Ted Kremenek42400962009-11-26 02:34:36 +0000130// Object destruction.
Ted Kremenek25010132009-06-22 23:13:13 +0000131//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000132
133MemRegion::~MemRegion() {}
134
Ted Kremenek42400962009-11-26 02:34:36 +0000135MemRegionManager::~MemRegionManager() {
136 // All regions and their data are BumpPtrAllocated. No need to call
137 // their destructors.
138}
139
140//===----------------------------------------------------------------------===//
141// Basic methods.
142//===----------------------------------------------------------------------===//
143
Zhongxing Xu7e5d6ed2009-01-08 13:17:14 +0000144bool SubRegion::isSubRegionOf(const MemRegion* R) const {
145 const MemRegion* r = getSuperRegion();
146 while (r != 0) {
147 if (r == R)
148 return true;
149 if (const SubRegion* sr = dyn_cast<SubRegion>(r))
150 r = sr->getSuperRegion();
151 else
152 break;
153 }
154 return false;
155}
156
Ted Kremeneka43484a2009-06-23 00:46:41 +0000157MemRegionManager* SubRegion::getMemRegionManager() const {
158 const SubRegion* r = this;
159 do {
160 const MemRegion *superRegion = r->getSuperRegion();
161 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
162 r = sr;
163 continue;
164 }
165 return superRegion->getMemRegionManager();
166 } while (1);
167}
168
Ted Kremenek5348f942009-12-14 22:15:06 +0000169const StackFrameContext *VarRegion::getStackFrame() const {
170 const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
171 return SSR ? SSR->getStackFrame() : NULL;
172}
173
174//===----------------------------------------------------------------------===//
Jordy Rose32f26562010-07-04 00:00:41 +0000175// Region extents.
176//===----------------------------------------------------------------------===//
177
178DefinedOrUnknownSVal DeclRegion::getExtent(ValueManager& ValMgr) const {
179 ASTContext& Ctx = ValMgr.getContext();
180 QualType T = getDesugaredValueType(Ctx);
181
182 // FIXME: Handle variable-length arrays.
183 if (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T))
184 return UnknownVal();
185
186 CharUnits Size = Ctx.getTypeSizeInChars(T);
187 QualType SizeTy = Ctx.getSizeType();
188 return ValMgr.makeIntVal(Size.getQuantity(), SizeTy);
189}
190
191DefinedOrUnknownSVal FieldRegion::getExtent(ValueManager& ValMgr) const {
192 DefinedOrUnknownSVal Extent = DeclRegion::getExtent(ValMgr);
193
194 // A zero-length array at the end of a struct often stands for dynamically-
195 // allocated extra memory.
196 if (Extent.isZeroConstant()) {
197 ASTContext& Ctx = ValMgr.getContext();
198 QualType T = getDesugaredValueType(Ctx);
199
200 if (isa<ConstantArrayType>(T))
201 return UnknownVal();
202 }
203
204 return Extent;
205}
206
207DefinedOrUnknownSVal AllocaRegion::getExtent(ValueManager& ValMgr) const {
208 return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this));
209}
210
211DefinedOrUnknownSVal SymbolicRegion::getExtent(ValueManager& ValMgr) const {
212 return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this));
213}
214
215DefinedOrUnknownSVal StringRegion::getExtent(ValueManager& ValMgr) const {
216 QualType SizeTy = ValMgr.getContext().getSizeType();
217 return ValMgr.makeIntVal(getStringLiteral()->getByteLength()+1, SizeTy);
218}
219
220//===----------------------------------------------------------------------===//
Ted Kremenek5348f942009-12-14 22:15:06 +0000221// FoldingSet profiling.
222//===----------------------------------------------------------------------===//
223
Ted Kremenek9e240492008-10-04 05:50:14 +0000224void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
225 ID.AddInteger((unsigned)getKind());
226}
227
Ted Kremenek67d12872009-12-07 22:05:27 +0000228void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
229 ID.AddInteger((unsigned)getKind());
230 ID.AddPointer(getStackFrame());
231}
232
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000233void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
234 ID.AddInteger((unsigned)getKind());
235 ID.AddPointer(getCodeRegion());
236}
237
Mike Stump1eb44332009-09-09 15:08:12 +0000238void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
239 const StringLiteral* Str,
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000240 const MemRegion* superRegion) {
241 ID.AddInteger((unsigned) StringRegionKind);
242 ID.AddPointer(Str);
243 ID.AddPointer(superRegion);
244}
245
Ted Kremenek7090ae12008-11-02 00:34:33 +0000246void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000247 const Expr* Ex, unsigned cnt,
248 const MemRegion *) {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000249 ID.AddInteger((unsigned) AllocaRegionKind);
250 ID.AddPointer(Ex);
251 ID.AddInteger(cnt);
252}
253
254void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000255 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenek7090ae12008-11-02 00:34:33 +0000256}
257
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000258void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
259 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
260}
261
262void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
263 const CompoundLiteralExpr* CL,
264 const MemRegion* superRegion) {
265 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
266 ID.AddPointer(CL);
267 ID.AddPointer(superRegion);
268}
269
Ted Kremenekde0d2632010-01-05 02:18:06 +0000270void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
271 const PointerType *PT,
272 const MemRegion *sRegion) {
273 ID.AddInteger((unsigned) CXXThisRegionKind);
274 ID.AddPointer(PT);
275 ID.AddPointer(sRegion);
276}
277
278void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
279 CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
280}
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000281
Ted Kremenek9e240492008-10-04 05:50:14 +0000282void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
283 const MemRegion* superRegion, Kind k) {
284 ID.AddInteger((unsigned) k);
285 ID.AddPointer(D);
286 ID.AddPointer(superRegion);
287}
288
289void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
290 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
291}
292
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000293void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000294 VarRegion::ProfileRegion(ID, getDecl(), superRegion);
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000295}
296
Ted Kremenek25010132009-06-22 23:13:13 +0000297void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
298 const MemRegion *sreg) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000299 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek6d0e2d22008-12-05 02:39:38 +0000300 ID.Add(sym);
Ted Kremenek25010132009-06-22 23:13:13 +0000301 ID.AddPointer(sreg);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000302}
303
304void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek25010132009-06-22 23:13:13 +0000305 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000306}
307
Ted Kremenekf936f452009-05-04 06:18:28 +0000308void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Mike Stump1eb44332009-09-09 15:08:12 +0000309 QualType ElementType, SVal Idx,
Zhongxing Xu511191c2008-10-21 05:27:10 +0000310 const MemRegion* superRegion) {
311 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekf936f452009-05-04 06:18:28 +0000312 ID.Add(ElementType);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000313 ID.AddPointer(superRegion);
314 Idx.Profile(ID);
315}
316
317void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf936f452009-05-04 06:18:28 +0000318 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000319}
Zhongxing Xu27b57062008-10-27 13:17:02 +0000320
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000321void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
322 const FunctionDecl *FD,
323 const MemRegion*) {
324 ID.AddInteger(MemRegion::FunctionTextRegionKind);
Ted Kremenekabd46e12009-08-28 04:49:15 +0000325 ID.AddPointer(FD);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000326}
327
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000328void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
329 FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
330}
331
332void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek67d12872009-12-07 22:05:27 +0000333 const BlockDecl *BD, CanQualType,
334 const AnalysisContext *AC,
335 const MemRegion*) {
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000336 ID.AddInteger(MemRegion::BlockTextRegionKind);
337 ID.AddPointer(BD);
338}
339
340void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000341 BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000342}
343
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000344void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
345 const BlockTextRegion *BC,
346 const LocationContext *LC,
Ted Kremenek67d12872009-12-07 22:05:27 +0000347 const MemRegion *sReg) {
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000348 ID.AddInteger(MemRegion::BlockDataRegionKind);
349 ID.AddPointer(BC);
350 ID.AddPointer(LC);
Ted Kremenek67d12872009-12-07 22:05:27 +0000351 ID.AddPointer(sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000352}
353
354void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000355 BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000356}
357
Zhongxing Xubb141212009-12-16 11:27:52 +0000358void CXXObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000359 Expr const *Ex,
Zhongxing Xubb141212009-12-16 11:27:52 +0000360 const MemRegion *sReg) {
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000361 ID.AddPointer(Ex);
Zhongxing Xubb141212009-12-16 11:27:52 +0000362 ID.AddPointer(sReg);
363}
364
365void CXXObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000366 ProfileRegion(ID, Ex, getSuperRegion());
Zhongxing Xubb141212009-12-16 11:27:52 +0000367}
368
Zhongxing Xu026c6632009-02-05 06:57:29 +0000369//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000370// Region pretty-printing.
371//===----------------------------------------------------------------------===//
372
Ted Kremenek8800ad42009-07-13 23:31:04 +0000373void MemRegion::dump() const {
374 dumpToStream(llvm::errs());
Ted Kremenek7f39d292009-07-02 17:24:10 +0000375}
376
Ted Kremenek9e240492008-10-04 05:50:14 +0000377std::string MemRegion::getString() const {
378 std::string s;
379 llvm::raw_string_ostream os(s);
Ted Kremenek8800ad42009-07-13 23:31:04 +0000380 dumpToStream(os);
Ted Kremenek9e240492008-10-04 05:50:14 +0000381 return os.str();
382}
383
Ted Kremenek8800ad42009-07-13 23:31:04 +0000384void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek9e240492008-10-04 05:50:14 +0000385 os << "<Unknown Region>";
386}
387
Ted Kremenek8800ad42009-07-13 23:31:04 +0000388void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000389 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
390}
391
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000392void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekabd46e12009-08-28 04:49:15 +0000393 os << "code{" << getDecl()->getDeclName().getAsString() << '}';
Ted Kremenek72e03202009-04-21 19:56:58 +0000394}
395
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000396void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000397 os << "block_code{" << (void*) this << '}';
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000398}
399
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000400void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
401 os << "block_data{" << BC << '}';
402}
403
404
Ted Kremenek8800ad42009-07-13 23:31:04 +0000405void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000406 // FIXME: More elaborate pretty-printing.
407 os << "{ " << (void*) CL << " }";
408}
409
Ted Kremenekde0d2632010-01-05 02:18:06 +0000410void CXXThisRegion::dumpToStream(llvm::raw_ostream &os) const {
411 os << "this";
412}
413
Ted Kremenek8800ad42009-07-13 23:31:04 +0000414void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000415 os << "element{" << superRegion << ','
416 << Index << ',' << getElementType().getAsString() << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000417}
418
Ted Kremenek8800ad42009-07-13 23:31:04 +0000419void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000420 os << superRegion << "->" << getDecl();
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000421}
422
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000423void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000424 os << "ivar{" << superRegion << ',' << getDecl() << '}';
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000425}
426
Mike Stump1eb44332009-09-09 15:08:12 +0000427void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekb27ed3d2009-07-19 20:38:24 +0000428 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000429}
430
Ted Kremenek8800ad42009-07-13 23:31:04 +0000431void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekaef5d222009-07-13 23:38:57 +0000432 os << "SymRegion{" << sym << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000433}
434
Ted Kremenek8800ad42009-07-13 23:31:04 +0000435void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000436 os << cast<VarDecl>(D);
Ted Kremenek9e240492008-10-04 05:50:14 +0000437}
438
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000439void RegionRawOffset::dump() const {
440 dumpToStream(llvm::errs());
441}
442
443void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
444 os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
445}
446
Ted Kremenek9e240492008-10-04 05:50:14 +0000447//===----------------------------------------------------------------------===//
448// MemRegionManager methods.
449//===----------------------------------------------------------------------===//
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000450
Ted Kremenek67d12872009-12-07 22:05:27 +0000451template <typename REG>
452const REG *MemRegionManager::LazyAllocate(REG*& region) {
Mike Stump1eb44332009-09-09 15:08:12 +0000453 if (!region) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000454 region = (REG*) A.Allocate<REG>();
455 new (region) REG(this);
Ted Kremenek9e240492008-10-04 05:50:14 +0000456 }
Ted Kremeneka43484a2009-06-23 00:46:41 +0000457
Ted Kremenek9e240492008-10-04 05:50:14 +0000458 return region;
459}
460
Ted Kremenek67d12872009-12-07 22:05:27 +0000461template <typename REG, typename ARG>
462const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
463 if (!region) {
464 region = (REG*) A.Allocate<REG>();
465 new (region) REG(this, a);
466 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000467
Ted Kremenek67d12872009-12-07 22:05:27 +0000468 return region;
Ted Kremenek9e240492008-10-04 05:50:14 +0000469}
470
Ted Kremenek67d12872009-12-07 22:05:27 +0000471const StackLocalsSpaceRegion*
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000472MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
473 assert(STC);
Zhongxing Xuc30470d2010-02-17 08:46:50 +0000474 StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
475
476 if (R)
477 return R;
478
479 R = A.Allocate<StackLocalsSpaceRegion>();
480 new (R) StackLocalsSpaceRegion(this, STC);
481 return R;
Ted Kremenekd05552a2009-07-02 18:14:59 +0000482}
483
Ted Kremenek67d12872009-12-07 22:05:27 +0000484const StackArgumentsSpaceRegion *
485MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000486 assert(STC);
Zhongxing Xuc30470d2010-02-17 08:46:50 +0000487 StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
488
489 if (R)
490 return R;
491
492 R = A.Allocate<StackArgumentsSpaceRegion>();
493 new (R) StackArgumentsSpaceRegion(this, STC);
494 return R;
Ted Kremenek67d12872009-12-07 22:05:27 +0000495}
496
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000497const GlobalsSpaceRegion
498*MemRegionManager::getGlobalsRegion(const CodeTextRegion *CR) {
499 if (!CR)
500 return LazyAllocate(globals);
501
502 StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
503 if (R)
504 return R;
505
506 R = A.Allocate<StaticGlobalSpaceRegion>();
507 new (R) StaticGlobalSpaceRegion(this, CR);
508 return R;
Ted Kremenek9e240492008-10-04 05:50:14 +0000509}
510
Ted Kremenek67d12872009-12-07 22:05:27 +0000511const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
Ted Kremenek9e240492008-10-04 05:50:14 +0000512 return LazyAllocate(heap);
513}
514
Ted Kremenekb48ad642009-12-04 00:26:31 +0000515const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
Zhongxing Xu17892752008-10-08 02:50:44 +0000516 return LazyAllocate(unknown);
517}
518
Ted Kremenekb48ad642009-12-04 00:26:31 +0000519const MemSpaceRegion *MemRegionManager::getCodeRegion() {
Zhongxing Xuec13d922009-04-10 08:45:10 +0000520 return LazyAllocate(code);
521}
522
Ted Kremenek25010132009-06-22 23:13:13 +0000523//===----------------------------------------------------------------------===//
524// Constructing regions.
525//===----------------------------------------------------------------------===//
526
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000527const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
Ted Kremenek67d12872009-12-07 22:05:27 +0000528 return getSubRegion<StringRegion>(Str, getGlobalsRegion());
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000529}
530
Ted Kremenekb48ad642009-12-04 00:26:31 +0000531const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
532 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000533 const MemRegion *sReg = 0;
Mike Stump1eb44332009-09-09 15:08:12 +0000534
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000535 if (D->hasGlobalStorage() && !D->isStaticLocal())
536 sReg = getGlobalsRegion();
537 else {
Ted Kremenek67d12872009-12-07 22:05:27 +0000538 // FIXME: Once we implement scope handling, we will need to properly lookup
539 // 'D' to the proper LocationContext.
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000540 const DeclContext *DC = D->getDeclContext();
541 const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
Mike Stump1eb44332009-09-09 15:08:12 +0000542
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000543 if (!STC)
544 sReg = getUnknownRegion();
545 else {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000546 if (D->hasLocalStorage()) {
547 sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
548 ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
549 : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
550 }
551 else {
552 assert(D->isStaticLocal());
553 const Decl *D = STC->getDecl();
554 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
555 sReg = getGlobalsRegion(getFunctionTextRegion(FD));
556 else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
557 const BlockTextRegion *BTR =
558 getBlockTextRegion(BD,
559 C.getCanonicalType(BD->getSignatureAsWritten()->getType()),
560 STC->getAnalysisContext());
561 sReg = getGlobalsRegion(BTR);
562 }
563 else {
564 // FIXME: For ObjC-methods, we need a new CodeTextRegion. For now
565 // just use the main global memspace.
566 sReg = getGlobalsRegion();
567 }
568 }
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000569 }
Ted Kremenek67d12872009-12-07 22:05:27 +0000570 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000571
Ted Kremenek67d12872009-12-07 22:05:27 +0000572 return getSubRegion<VarRegion>(D, sReg);
573}
574
575const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
576 const MemRegion *superR) {
577 return getSubRegion<VarRegion>(D, superR);
Ted Kremenek9e240492008-10-04 05:50:14 +0000578}
579
Ted Kremenekb48ad642009-12-04 00:26:31 +0000580const BlockDataRegion *
581MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
582 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000583 const MemRegion *sReg = 0;
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000584
585 if (LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000586 // FIXME: Once we implement scope handling, we want the parent region
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000587 // to be the scope.
Ted Kremenek67d12872009-12-07 22:05:27 +0000588 const StackFrameContext *STC = LC->getCurrentStackFrame();
589 assert(STC);
590 sReg = getStackLocalsRegion(STC);
591 }
592 else {
593 // We allow 'LC' to be NULL for cases where want BlockDataRegions
594 // without context-sensitivity.
595 sReg = getUnknownRegion();
596 }
597
598 return getSubRegion<BlockDataRegion>(BC, LC, sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000599}
600
Ted Kremenekb48ad642009-12-04 00:26:31 +0000601const CompoundLiteralRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000602MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
603 const LocationContext *LC) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000604
Ted Kremenek67d12872009-12-07 22:05:27 +0000605 const MemRegion *sReg = 0;
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000606
Ted Kremenek67d12872009-12-07 22:05:27 +0000607 if (CL->isFileScope())
608 sReg = getGlobalsRegion();
609 else {
610 const StackFrameContext *STC = LC->getCurrentStackFrame();
611 assert(STC);
612 sReg = getStackLocalsRegion(STC);
613 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000614
Ted Kremenek67d12872009-12-07 22:05:27 +0000615 return getSubRegion<CompoundLiteralRegion>(CL, sReg);
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000616}
617
Ted Kremenekb48ad642009-12-04 00:26:31 +0000618const ElementRegion*
Ted Kremenekf936f452009-05-04 06:18:28 +0000619MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Ted Kremenek46537392009-07-16 01:33:37 +0000620 const MemRegion* superRegion,
621 ASTContext& Ctx){
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000622
Ted Kremenek32f90102010-05-27 00:29:00 +0000623 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
Ted Kremenekabb042f2008-12-13 19:24:37 +0000624
Zhongxing Xu511191c2008-10-21 05:27:10 +0000625 llvm::FoldingSetNodeID ID;
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000626 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000627
628 void* InsertPos;
629 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
630 ElementRegion* R = cast_or_null<ElementRegion>(data);
631
632 if (!R) {
633 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000634 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000635 Regions.InsertNode(R, InsertPos);
636 }
637
638 return R;
639}
640
Ted Kremenekb48ad642009-12-04 00:26:31 +0000641const FunctionTextRegion *
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000642MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000643 return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
Zhongxing Xuec13d922009-04-10 08:45:10 +0000644}
645
Ted Kremenekb48ad642009-12-04 00:26:31 +0000646const BlockTextRegion *
Ted Kremenek67d12872009-12-07 22:05:27 +0000647MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
648 AnalysisContext *AC) {
649 return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000650}
651
652
Ted Kremenek993f1c72008-10-17 20:28:54 +0000653/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenekb48ad642009-12-04 00:26:31 +0000654const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000655 return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000656}
657
Ted Kremenekde0d2632010-01-05 02:18:06 +0000658const FieldRegion*
Ted Kremenekb48ad642009-12-04 00:26:31 +0000659MemRegionManager::getFieldRegion(const FieldDecl* d,
660 const MemRegion* superRegion){
Ted Kremenekeeea4562009-07-10 16:51:45 +0000661 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000662}
663
Ted Kremenekb48ad642009-12-04 00:26:31 +0000664const ObjCIvarRegion*
Ted Kremenek993f1c72008-10-17 20:28:54 +0000665MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
666 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000667 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000668}
669
Ted Kremenekde0d2632010-01-05 02:18:06 +0000670const CXXObjectRegion*
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000671MemRegionManager::getCXXObjectRegion(Expr const *E,
672 LocationContext const *LC) {
673 const StackFrameContext *SFC = LC->getCurrentStackFrame();
674 assert(SFC);
675 return getSubRegion<CXXObjectRegion>(E, getStackLocalsRegion(SFC));
Zhongxing Xubb141212009-12-16 11:27:52 +0000676}
677
Ted Kremenekde0d2632010-01-05 02:18:06 +0000678const CXXThisRegion*
679MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
680 const LocationContext *LC) {
681 const StackFrameContext *STC = LC->getCurrentStackFrame();
682 assert(STC);
683 const PointerType *PT = thisPointerTy->getAs<PointerType>();
684 assert(PT);
685 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
686}
687
Ted Kremenekb48ad642009-12-04 00:26:31 +0000688const AllocaRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000689MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
690 const LocationContext *LC) {
691 const StackFrameContext *STC = LC->getCurrentStackFrame();
692 assert(STC);
693 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
Ted Kremenek7090ae12008-11-02 00:34:33 +0000694}
695
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000696const MemSpaceRegion *MemRegion::getMemorySpace() const {
697 const MemRegion *R = this;
Ted Kremenekea20cd72009-06-23 18:05:21 +0000698 const SubRegion* SR = dyn_cast<SubRegion>(this);
Mike Stump1eb44332009-09-09 15:08:12 +0000699
Ted Kremenek993f1c72008-10-17 20:28:54 +0000700 while (SR) {
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000701 R = SR->getSuperRegion();
702 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000703 }
Mike Stump1eb44332009-09-09 15:08:12 +0000704
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000705 return dyn_cast<MemSpaceRegion>(R);
706}
707
708bool MemRegion::hasStackStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000709 return isa<StackSpaceRegion>(getMemorySpace());
Ted Kremenek9e240492008-10-04 05:50:14 +0000710}
Ted Kremenek1670e402009-04-11 00:11:10 +0000711
Ted Kremenekde0d2632010-01-05 02:18:06 +0000712bool MemRegion::hasStackNonParametersStorage() const {
713 return isa<StackLocalsSpaceRegion>(getMemorySpace());
Zhongxing Xudd198f02009-06-23 02:51:21 +0000714}
Ted Kremenek1670e402009-04-11 00:11:10 +0000715
Ted Kremenekde0d2632010-01-05 02:18:06 +0000716bool MemRegion::hasStackParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000717 return isa<StackArgumentsSpaceRegion>(getMemorySpace());
Ted Kremenekdc147262009-07-02 22:02:15 +0000718}
719
Ted Kremenek15086362009-07-02 18:25:09 +0000720bool MemRegion::hasGlobalsOrParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000721 const MemSpaceRegion *MS = getMemorySpace();
722 return isa<StackArgumentsSpaceRegion>(MS) ||
723 isa<GlobalsSpaceRegion>(MS);
Ted Kremenek15086362009-07-02 18:25:09 +0000724}
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000725
Zhongxing Xuadca2712009-11-10 02:37:53 +0000726// getBaseRegion strips away all elements and fields, and get the base region
727// of them.
728const MemRegion *MemRegion::getBaseRegion() const {
729 const MemRegion *R = this;
730 while (true) {
Ted Kremenek68b9a592010-04-06 22:06:03 +0000731 switch (R->getKind()) {
732 case MemRegion::ElementRegionKind:
733 case MemRegion::FieldRegionKind:
734 case MemRegion::ObjCIvarRegionKind:
735 R = cast<SubRegion>(R)->getSuperRegion();
736 continue;
737 default:
738 break;
Zhongxing Xuadca2712009-11-10 02:37:53 +0000739 }
740 break;
741 }
742 return R;
743}
744
Ted Kremenek1670e402009-04-11 00:11:10 +0000745//===----------------------------------------------------------------------===//
746// View handling.
747//===----------------------------------------------------------------------===//
748
Zhongxing Xu479529e2009-11-10 02:17:20 +0000749const MemRegion *MemRegion::StripCasts() const {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000750 const MemRegion *R = this;
751 while (true) {
Mike Stump1eb44332009-09-09 15:08:12 +0000752 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000753 // FIXME: generalize. Essentially we want to strip away ElementRegions
754 // that were layered on a symbolic region because of casts. We only
755 // want to strip away ElementRegions, however, where the index is 0.
756 SVal index = ER->getIndex();
757 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000758 if (CI->getValue().getSExtValue() == 0) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000759 R = ER->getSuperRegion();
760 continue;
761 }
762 }
763 }
764 break;
765 }
766 return R;
767}
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000768
769// FIXME: Merge with the implementation of the same method in Store.cpp
770static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
771 if (const RecordType *RT = Ty->getAs<RecordType>()) {
772 const RecordDecl *D = RT->getDecl();
Douglas Gregor952b0172010-02-11 01:04:33 +0000773 if (!D->getDefinition())
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000774 return false;
775 }
776
777 return true;
778}
779
780RegionRawOffset ElementRegion::getAsRawOffset() const {
Ken Dyck199c3d62010-01-11 17:06:35 +0000781 CharUnits offset = CharUnits::Zero();
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000782 const ElementRegion *ER = this;
783 const MemRegion *superR = NULL;
784 ASTContext &C = getContext();
Mike Stump1eb44332009-09-09 15:08:12 +0000785
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000786 // FIXME: Handle multi-dimensional arrays.
787
788 while (ER) {
789 superR = ER->getSuperRegion();
Mike Stump1eb44332009-09-09 15:08:12 +0000790
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000791 // FIXME: generalize to symbolic offsets.
792 SVal index = ER->getIndex();
793 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
794 // Update the offset.
795 int64_t i = CI->getValue().getSExtValue();
Mike Stump1eb44332009-09-09 15:08:12 +0000796
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000797 if (i != 0) {
798 QualType elemType = ER->getElementType();
Mike Stump1eb44332009-09-09 15:08:12 +0000799
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000800 // If we are pointing to an incomplete type, go no further.
801 if (!IsCompleteType(C, elemType)) {
802 superR = ER;
803 break;
804 }
Mike Stump1eb44332009-09-09 15:08:12 +0000805
Ken Dyck199c3d62010-01-11 17:06:35 +0000806 CharUnits size = C.getTypeSizeInChars(elemType);
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000807 offset += (i * size);
808 }
809
810 // Go to the next ElementRegion (if any).
811 ER = dyn_cast<ElementRegion>(superR);
812 continue;
813 }
Mike Stump1eb44332009-09-09 15:08:12 +0000814
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000815 return NULL;
816 }
Mike Stump1eb44332009-09-09 15:08:12 +0000817
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000818 assert(superR && "super region cannot be NULL");
Ken Dyck199c3d62010-01-11 17:06:35 +0000819 return RegionRawOffset(superR, offset.getQuantity());
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000820}
821
Ted Kremenek42400962009-11-26 02:34:36 +0000822//===----------------------------------------------------------------------===//
823// BlockDataRegion
824//===----------------------------------------------------------------------===//
825
826void BlockDataRegion::LazyInitializeReferencedVars() {
827 if (ReferencedVars)
828 return;
829
Ted Kremenek67d12872009-12-07 22:05:27 +0000830 AnalysisContext *AC = getCodeRegion()->getAnalysisContext();
Ted Kremenek42400962009-11-26 02:34:36 +0000831 AnalysisContext::referenced_decls_iterator I, E;
832 llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000833
Ted Kremenek42400962009-11-26 02:34:36 +0000834 if (I == E) {
835 ReferencedVars = (void*) 0x1;
836 return;
837 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000838
Ted Kremenek42400962009-11-26 02:34:36 +0000839 MemRegionManager &MemMgr = *getMemRegionManager();
840 llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
841 BumpVectorContext BC(A);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000842
Ted Kremenek42400962009-11-26 02:34:36 +0000843 typedef BumpVector<const MemRegion*> VarVec;
844 VarVec *BV = (VarVec*) A.Allocate<VarVec>();
Ted Kremenek02b1df62009-12-01 22:12:34 +0000845 new (BV) VarVec(BC, E - I);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000846
Ted Kremenek67d12872009-12-07 22:05:27 +0000847 for ( ; I != E; ++I) {
848 const VarDecl *VD = *I;
849 const VarRegion *VR = 0;
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000850
Ted Kremenek85248732010-02-06 00:30:00 +0000851 if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage())
Ted Kremenek67d12872009-12-07 22:05:27 +0000852 VR = MemMgr.getVarRegion(VD, this);
853 else {
854 if (LC)
855 VR = MemMgr.getVarRegion(VD, LC);
856 else {
857 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
858 }
859 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000860
Ted Kremenek67d12872009-12-07 22:05:27 +0000861 assert(VR);
862 BV->push_back(VR, BC);
863 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000864
Ted Kremenek42400962009-11-26 02:34:36 +0000865 ReferencedVars = BV;
866}
867
868BlockDataRegion::referenced_vars_iterator
869BlockDataRegion::referenced_vars_begin() const {
870 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
871
872 BumpVector<const MemRegion*> *Vec =
873 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000874
Ted Kremenek81cef582009-12-03 08:09:21 +0000875 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
876 NULL : Vec->begin());
Ted Kremenek42400962009-11-26 02:34:36 +0000877}
878
879BlockDataRegion::referenced_vars_iterator
880BlockDataRegion::referenced_vars_end() const {
881 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
882
883 BumpVector<const MemRegion*> *Vec =
884 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000885
Ted Kremenek81cef582009-12-03 08:09:21 +0000886 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
887 NULL : Vec->end());
Ted Kremenek42400962009-11-26 02:34:36 +0000888}