blob: ac633060fddd1494bdfe02cd454bc6a1badd2cae [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
16#include "llvm/Support/raw_ostream.h"
17#include "clang/Analysis/PathSensitive/MemRegion.h"
Ted Kremenek19e1f0b2009-08-01 06:17:29 +000018#include "clang/Analysis/PathSensitive/ValueManager.h"
Ted Kremenek9e240492008-10-04 05:50:14 +000019
20using namespace clang;
21
Ted Kremenek25010132009-06-22 23:13:13 +000022//===----------------------------------------------------------------------===//
23// Basic methods.
24//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +000025
26MemRegion::~MemRegion() {}
27
Zhongxing Xu7e5d6ed2009-01-08 13:17:14 +000028bool SubRegion::isSubRegionOf(const MemRegion* R) const {
29 const MemRegion* r = getSuperRegion();
30 while (r != 0) {
31 if (r == R)
32 return true;
33 if (const SubRegion* sr = dyn_cast<SubRegion>(r))
34 r = sr->getSuperRegion();
35 else
36 break;
37 }
38 return false;
39}
40
Ted Kremeneka43484a2009-06-23 00:46:41 +000041
42MemRegionManager* SubRegion::getMemRegionManager() const {
43 const SubRegion* r = this;
44 do {
45 const MemRegion *superRegion = r->getSuperRegion();
46 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
47 r = sr;
48 continue;
49 }
50 return superRegion->getMemRegionManager();
51 } while (1);
52}
53
Ted Kremenek9e240492008-10-04 05:50:14 +000054void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
55 ID.AddInteger((unsigned)getKind());
56}
57
Zhongxing Xue9f4e542008-10-25 14:13:41 +000058void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
59 const StringLiteral* Str,
60 const MemRegion* superRegion) {
61 ID.AddInteger((unsigned) StringRegionKind);
62 ID.AddPointer(Str);
63 ID.AddPointer(superRegion);
64}
65
Ted Kremenek7090ae12008-11-02 00:34:33 +000066void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek7ae7ad92009-06-23 00:15:41 +000067 const Expr* Ex, unsigned cnt,
68 const MemRegion *) {
Ted Kremenek7090ae12008-11-02 00:34:33 +000069 ID.AddInteger((unsigned) AllocaRegionKind);
70 ID.AddPointer(Ex);
71 ID.AddInteger(cnt);
72}
73
74void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek7ae7ad92009-06-23 00:15:41 +000075 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenek7090ae12008-11-02 00:34:33 +000076}
77
Ted Kremenek329d6fd2008-10-27 20:57:58 +000078void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
79 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
80}
81
82void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
83 const CompoundLiteralExpr* CL,
84 const MemRegion* superRegion) {
85 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
86 ID.AddPointer(CL);
87 ID.AddPointer(superRegion);
88}
89
Ted Kremenek9e240492008-10-04 05:50:14 +000090void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
91 const MemRegion* superRegion, Kind k) {
92 ID.AddInteger((unsigned) k);
93 ID.AddPointer(D);
94 ID.AddPointer(superRegion);
95}
96
97void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
98 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
99}
100
Ted Kremenek25010132009-06-22 23:13:13 +0000101void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
102 const MemRegion *sreg) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000103 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek6d0e2d22008-12-05 02:39:38 +0000104 ID.Add(sym);
Ted Kremenek25010132009-06-22 23:13:13 +0000105 ID.AddPointer(sreg);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000106}
107
108void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek25010132009-06-22 23:13:13 +0000109 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000110}
111
Ted Kremenekf936f452009-05-04 06:18:28 +0000112void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
113 QualType ElementType, SVal Idx,
Zhongxing Xu511191c2008-10-21 05:27:10 +0000114 const MemRegion* superRegion) {
115 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekf936f452009-05-04 06:18:28 +0000116 ID.Add(ElementType);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000117 ID.AddPointer(superRegion);
118 Idx.Profile(ID);
119}
120
121void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf936f452009-05-04 06:18:28 +0000122 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000123}
Zhongxing Xu27b57062008-10-27 13:17:02 +0000124
Zhongxing Xuec13d922009-04-10 08:45:10 +0000125void CodeTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const void* data,
Zhongxing Xu0dea5242009-06-23 03:50:30 +0000126 QualType t, const MemRegion*) {
Zhongxing Xuec13d922009-04-10 08:45:10 +0000127 ID.AddInteger(MemRegion::CodeTextRegionKind);
128 ID.AddPointer(data);
129 ID.Add(t);
130}
131
132void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Zhongxing Xu0dea5242009-06-23 03:50:30 +0000133 CodeTextRegion::ProfileRegion(ID, Data, LocationType, superRegion);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000134}
135
Zhongxing Xu026c6632009-02-05 06:57:29 +0000136//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000137// Region pretty-printing.
138//===----------------------------------------------------------------------===//
139
Ted Kremenek8800ad42009-07-13 23:31:04 +0000140void MemRegion::dump() const {
141 dumpToStream(llvm::errs());
Ted Kremenek7f39d292009-07-02 17:24:10 +0000142}
143
Ted Kremenek9e240492008-10-04 05:50:14 +0000144std::string MemRegion::getString() const {
145 std::string s;
146 llvm::raw_string_ostream os(s);
Ted Kremenek8800ad42009-07-13 23:31:04 +0000147 dumpToStream(os);
Ted Kremenek9e240492008-10-04 05:50:14 +0000148 return os.str();
149}
150
Ted Kremenek8800ad42009-07-13 23:31:04 +0000151void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek9e240492008-10-04 05:50:14 +0000152 os << "<Unknown Region>";
153}
154
Ted Kremenek8800ad42009-07-13 23:31:04 +0000155void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000156 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
157}
158
Ted Kremenek8800ad42009-07-13 23:31:04 +0000159void CodeTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek72e03202009-04-21 19:56:58 +0000160 os << "code{";
161 if (isDeclared())
Ted Kremenek82539b02009-04-29 15:37:24 +0000162 os << getDecl()->getDeclName().getAsString();
Ted Kremenek72e03202009-04-21 19:56:58 +0000163 else
164 os << '$' << getSymbol();
165
166 os << '}';
167}
168
Ted Kremenek8800ad42009-07-13 23:31:04 +0000169void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000170 // FIXME: More elaborate pretty-printing.
171 os << "{ " << (void*) CL << " }";
172}
173
Ted Kremenek8800ad42009-07-13 23:31:04 +0000174void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000175 os << "element{" << superRegion << ','
176 << Index << ',' << getElementType().getAsString() << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000177}
178
Ted Kremenek8800ad42009-07-13 23:31:04 +0000179void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
180 os << superRegion << "->" << getDecl()->getNameAsString();
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000181}
182
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000183void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
184 os << "ivar{" << superRegion << ',' << getDecl()->getNameAsString() << '}';
185}
186
Ted Kremenekb27ed3d2009-07-19 20:38:24 +0000187void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
188 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000189}
190
Ted Kremenek8800ad42009-07-13 23:31:04 +0000191void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekaef5d222009-07-13 23:38:57 +0000192 os << "SymRegion{" << sym << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000193}
194
Ted Kremenek8800ad42009-07-13 23:31:04 +0000195void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
Chris Lattnerd9d22dd2008-11-24 05:29:24 +0000196 os << cast<VarDecl>(D)->getNameAsString();
Ted Kremenek9e240492008-10-04 05:50:14 +0000197}
198
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000199void RegionRawOffset::dump() const {
200 dumpToStream(llvm::errs());
201}
202
203void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
204 os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
205}
206
Ted Kremenek9e240492008-10-04 05:50:14 +0000207//===----------------------------------------------------------------------===//
208// MemRegionManager methods.
209//===----------------------------------------------------------------------===//
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000210
Ted Kremeneka43484a2009-06-23 00:46:41 +0000211MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
Ted Kremenek9e240492008-10-04 05:50:14 +0000212 if (!region) {
213 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
Ted Kremeneka43484a2009-06-23 00:46:41 +0000214 new (region) MemSpaceRegion(this);
Ted Kremenek9e240492008-10-04 05:50:14 +0000215 }
Ted Kremeneka43484a2009-06-23 00:46:41 +0000216
Ted Kremenek9e240492008-10-04 05:50:14 +0000217 return region;
218}
219
220MemSpaceRegion* MemRegionManager::getStackRegion() {
221 return LazyAllocate(stack);
222}
223
Ted Kremenekd05552a2009-07-02 18:14:59 +0000224MemSpaceRegion* MemRegionManager::getStackArgumentsRegion() {
225 return LazyAllocate(stackArguments);
226}
227
Ted Kremenek9e240492008-10-04 05:50:14 +0000228MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
229 return LazyAllocate(globals);
230}
231
232MemSpaceRegion* MemRegionManager::getHeapRegion() {
233 return LazyAllocate(heap);
234}
235
Zhongxing Xu17892752008-10-08 02:50:44 +0000236MemSpaceRegion* MemRegionManager::getUnknownRegion() {
237 return LazyAllocate(unknown);
238}
239
Zhongxing Xuec13d922009-04-10 08:45:10 +0000240MemSpaceRegion* MemRegionManager::getCodeRegion() {
241 return LazyAllocate(code);
242}
243
Ted Kremenek25010132009-06-22 23:13:13 +0000244//===----------------------------------------------------------------------===//
245// Constructing regions.
246//===----------------------------------------------------------------------===//
247
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000248StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremenek25010132009-06-22 23:13:13 +0000249 return getRegion<StringRegion>(Str);
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000250}
251
Ted Kremenek9a1f03a2008-10-27 21:01:26 +0000252VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
Ted Kremenek25010132009-06-22 23:13:13 +0000253 return getRegion<VarRegion>(d);
Ted Kremenek9e240492008-10-04 05:50:14 +0000254}
255
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000256CompoundLiteralRegion*
257MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
Ted Kremenek25010132009-06-22 23:13:13 +0000258 return getRegion<CompoundLiteralRegion>(CL);
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000259}
260
Ted Kremenekabb042f2008-12-13 19:24:37 +0000261ElementRegion*
Ted Kremenekf936f452009-05-04 06:18:28 +0000262MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Ted Kremenek46537392009-07-16 01:33:37 +0000263 const MemRegion* superRegion,
264 ASTContext& Ctx){
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000265
266 QualType T = Ctx.getCanonicalType(elementType);
Ted Kremenekabb042f2008-12-13 19:24:37 +0000267
Zhongxing Xu511191c2008-10-21 05:27:10 +0000268 llvm::FoldingSetNodeID ID;
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000269 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000270
271 void* InsertPos;
272 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
273 ElementRegion* R = cast_or_null<ElementRegion>(data);
274
275 if (!R) {
276 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000277 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000278 Regions.InsertNode(R, InsertPos);
279 }
280
281 return R;
282}
283
Zhongxing Xuec13d922009-04-10 08:45:10 +0000284CodeTextRegion* MemRegionManager::getCodeTextRegion(const FunctionDecl* fd,
285 QualType t) {
Zhongxing Xu0dea5242009-06-23 03:50:30 +0000286 return getRegion<CodeTextRegion>(fd, t);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000287}
288
289CodeTextRegion* MemRegionManager::getCodeTextRegion(SymbolRef sym, QualType t) {
Zhongxing Xu0dea5242009-06-23 03:50:30 +0000290 return getRegion<CodeTextRegion>(sym, t);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000291}
292
Ted Kremenek993f1c72008-10-17 20:28:54 +0000293/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000294SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek25010132009-06-22 23:13:13 +0000295 return getRegion<SymbolicRegion>(sym);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000296}
297
Ted Kremenek9e240492008-10-04 05:50:14 +0000298FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek993f1c72008-10-17 20:28:54 +0000299 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000300 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000301}
302
Ted Kremenek993f1c72008-10-17 20:28:54 +0000303ObjCIvarRegion*
304MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
305 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000306 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000307}
308
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000309ObjCObjectRegion*
310MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
Ted Kremenekded12212009-06-23 00:04:09 +0000311 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000312 return getSubRegion<ObjCObjectRegion>(d, superRegion);
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000313}
314
Ted Kremenek7090ae12008-11-02 00:34:33 +0000315AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000316 return getRegion<AllocaRegion>(E, cnt);
Ted Kremenek7090ae12008-11-02 00:34:33 +0000317}
318
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000319const MemSpaceRegion *MemRegion::getMemorySpace() const {
320 const MemRegion *R = this;
Ted Kremenekea20cd72009-06-23 18:05:21 +0000321 const SubRegion* SR = dyn_cast<SubRegion>(this);
Ted Kremenek9e240492008-10-04 05:50:14 +0000322
Ted Kremenek993f1c72008-10-17 20:28:54 +0000323 while (SR) {
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000324 R = SR->getSuperRegion();
325 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000326 }
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000327
328 return dyn_cast<MemSpaceRegion>(R);
329}
330
331bool MemRegion::hasStackStorage() const {
Ted Kremenekd05552a2009-07-02 18:14:59 +0000332 if (const MemSpaceRegion *MS = getMemorySpace()) {
333 MemRegionManager *Mgr = getMemRegionManager();
334 return MS == Mgr->getStackRegion() || MS == Mgr->getStackArgumentsRegion();
335 }
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000336
Ted Kremenek9e240492008-10-04 05:50:14 +0000337 return false;
338}
Ted Kremenek1670e402009-04-11 00:11:10 +0000339
Ted Kremenekea20cd72009-06-23 18:05:21 +0000340bool MemRegion::hasHeapStorage() const {
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000341 if (const MemSpaceRegion *MS = getMemorySpace())
342 return MS == getMemRegionManager()->getHeapRegion();
Zhongxing Xudd198f02009-06-23 02:51:21 +0000343
344 return false;
345}
Ted Kremenek1670e402009-04-11 00:11:10 +0000346
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000347bool MemRegion::hasHeapOrStackStorage() const {
348 if (const MemSpaceRegion *MS = getMemorySpace()) {
349 MemRegionManager *Mgr = getMemRegionManager();
Ted Kremenekd05552a2009-07-02 18:14:59 +0000350 return MS == Mgr->getHeapRegion()
351 || MS == Mgr->getStackRegion()
352 || MS == Mgr->getStackArgumentsRegion();
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000353 }
354 return false;
Ted Kremenek15086362009-07-02 18:25:09 +0000355}
356
357bool MemRegion::hasGlobalsStorage() const {
358 if (const MemSpaceRegion *MS = getMemorySpace())
359 return MS == getMemRegionManager()->getGlobalsRegion();
360
361 return false;
362}
363
Ted Kremenekdc147262009-07-02 22:02:15 +0000364bool MemRegion::hasParametersStorage() const {
365 if (const MemSpaceRegion *MS = getMemorySpace())
366 return MS == getMemRegionManager()->getStackArgumentsRegion();
367
368 return false;
369}
370
Ted Kremenek15086362009-07-02 18:25:09 +0000371bool MemRegion::hasGlobalsOrParametersStorage() const {
372 if (const MemSpaceRegion *MS = getMemorySpace()) {
373 MemRegionManager *Mgr = getMemRegionManager();
374 return MS == Mgr->getGlobalsRegion()
375 || MS == Mgr->getStackArgumentsRegion();
376 }
377 return false;
378}
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000379
Ted Kremenek1670e402009-04-11 00:11:10 +0000380//===----------------------------------------------------------------------===//
381// View handling.
382//===----------------------------------------------------------------------===//
383
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000384const MemRegion *MemRegion::getBaseRegion() const {
385 const MemRegion *R = this;
386 while (true) {
387 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
388 // FIXME: generalize. Essentially we want to strip away ElementRegions
389 // that were layered on a symbolic region because of casts. We only
390 // want to strip away ElementRegions, however, where the index is 0.
391 SVal index = ER->getIndex();
392 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000393 if (CI->getValue().getSExtValue() == 0) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000394 R = ER->getSuperRegion();
395 continue;
396 }
397 }
398 }
399 break;
400 }
401 return R;
402}
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000403
404// FIXME: Merge with the implementation of the same method in Store.cpp
405static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
406 if (const RecordType *RT = Ty->getAs<RecordType>()) {
407 const RecordDecl *D = RT->getDecl();
408 if (!D->getDefinition(Ctx))
409 return false;
410 }
411
412 return true;
413}
414
415RegionRawOffset ElementRegion::getAsRawOffset() const {
416 int64_t offset = 0;
417 const ElementRegion *ER = this;
418 const MemRegion *superR = NULL;
419 ASTContext &C = getContext();
420
421 // FIXME: Handle multi-dimensional arrays.
422
423 while (ER) {
424 superR = ER->getSuperRegion();
425
426 // FIXME: generalize to symbolic offsets.
427 SVal index = ER->getIndex();
428 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
429 // Update the offset.
430 int64_t i = CI->getValue().getSExtValue();
431
432 if (i != 0) {
433 QualType elemType = ER->getElementType();
434
435 // If we are pointing to an incomplete type, go no further.
436 if (!IsCompleteType(C, elemType)) {
437 superR = ER;
438 break;
439 }
440
441 int64_t size = (int64_t) (C.getTypeSize(elemType) / 8);
442 offset += (i * size);
443 }
444
445 // Go to the next ElementRegion (if any).
446 ER = dyn_cast<ElementRegion>(superR);
447 continue;
448 }
449
450 return NULL;
451 }
452
453 assert(superR && "super region cannot be NULL");
454 return RegionRawOffset(superR, offset);
455}
456