1218887Sdim//== MemRegion.cpp - Abstract memory regions for static analysis --*- C++ -*--//
2218887Sdim//
3218887Sdim//                     The LLVM Compiler Infrastructure
4218887Sdim//
5218887Sdim// This file is distributed under the University of Illinois Open Source
6218887Sdim// License. See LICENSE.TXT for details.
7218887Sdim//
8218887Sdim//===----------------------------------------------------------------------===//
9218887Sdim//
10218887Sdim//  This file defines MemRegion and its subclasses.  MemRegion defines a
11218887Sdim//  partially-typed abstraction of memory useful for path-sensitive dataflow
12218887Sdim//  analyses.
13218887Sdim//
14218887Sdim//===----------------------------------------------------------------------===//
15218887Sdim
16218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
17252723Sdim#include "clang/AST/Attr.h"
18218887Sdim#include "clang/AST/CharUnits.h"
19235633Sdim#include "clang/AST/DeclObjC.h"
20218887Sdim#include "clang/AST/RecordLayout.h"
21252723Sdim#include "clang/Analysis/AnalysisContext.h"
22252723Sdim#include "clang/Analysis/Support/BumpVector.h"
23235633Sdim#include "clang/Basic/SourceManager.h"
24252723Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
25218887Sdim#include "llvm/Support/raw_ostream.h"
26218887Sdim
27218887Sdimusing namespace clang;
28218887Sdimusing namespace ento;
29218887Sdim
30218887Sdim//===----------------------------------------------------------------------===//
31218887Sdim// MemRegion Construction.
32218887Sdim//===----------------------------------------------------------------------===//
33218887Sdim
34218887Sdimtemplate<typename RegionTy> struct MemRegionManagerTrait;
35218887Sdim
36218887Sdimtemplate <typename RegionTy, typename A1>
37218887SdimRegionTy* MemRegionManager::getRegion(const A1 a1) {
38218887Sdim
39218887Sdim  const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
40218887Sdim  MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
41218887Sdim
42218887Sdim  llvm::FoldingSetNodeID ID;
43218887Sdim  RegionTy::ProfileRegion(ID, a1, superRegion);
44226890Sdim  void *InsertPos;
45218887Sdim  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
46218887Sdim                                                                   InsertPos));
47218887Sdim
48218887Sdim  if (!R) {
49218887Sdim    R = (RegionTy*) A.Allocate<RegionTy>();
50218887Sdim    new (R) RegionTy(a1, superRegion);
51218887Sdim    Regions.InsertNode(R, InsertPos);
52218887Sdim  }
53218887Sdim
54218887Sdim  return R;
55218887Sdim}
56218887Sdim
57218887Sdimtemplate <typename RegionTy, typename A1>
58218887SdimRegionTy* MemRegionManager::getSubRegion(const A1 a1,
59218887Sdim                                         const MemRegion *superRegion) {
60218887Sdim  llvm::FoldingSetNodeID ID;
61218887Sdim  RegionTy::ProfileRegion(ID, a1, superRegion);
62226890Sdim  void *InsertPos;
63218887Sdim  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
64218887Sdim                                                                   InsertPos));
65218887Sdim
66218887Sdim  if (!R) {
67218887Sdim    R = (RegionTy*) A.Allocate<RegionTy>();
68218887Sdim    new (R) RegionTy(a1, superRegion);
69218887Sdim    Regions.InsertNode(R, InsertPos);
70218887Sdim  }
71218887Sdim
72218887Sdim  return R;
73218887Sdim}
74218887Sdim
75218887Sdimtemplate <typename RegionTy, typename A1, typename A2>
76218887SdimRegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
77218887Sdim
78218887Sdim  const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
79218887Sdim  MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
80218887Sdim
81218887Sdim  llvm::FoldingSetNodeID ID;
82218887Sdim  RegionTy::ProfileRegion(ID, a1, a2, superRegion);
83226890Sdim  void *InsertPos;
84218887Sdim  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
85218887Sdim                                                                   InsertPos));
86218887Sdim
87218887Sdim  if (!R) {
88218887Sdim    R = (RegionTy*) A.Allocate<RegionTy>();
89218887Sdim    new (R) RegionTy(a1, a2, superRegion);
90218887Sdim    Regions.InsertNode(R, InsertPos);
91218887Sdim  }
92218887Sdim
93218887Sdim  return R;
94218887Sdim}
95218887Sdim
96218887Sdimtemplate <typename RegionTy, typename A1, typename A2>
97218887SdimRegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
98218887Sdim                                         const MemRegion *superRegion) {
99218887Sdim
100218887Sdim  llvm::FoldingSetNodeID ID;
101218887Sdim  RegionTy::ProfileRegion(ID, a1, a2, superRegion);
102226890Sdim  void *InsertPos;
103218887Sdim  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
104218887Sdim                                                                   InsertPos));
105218887Sdim
106218887Sdim  if (!R) {
107218887Sdim    R = (RegionTy*) A.Allocate<RegionTy>();
108218887Sdim    new (R) RegionTy(a1, a2, superRegion);
109218887Sdim    Regions.InsertNode(R, InsertPos);
110218887Sdim  }
111218887Sdim
112218887Sdim  return R;
113218887Sdim}
114218887Sdim
115218887Sdimtemplate <typename RegionTy, typename A1, typename A2, typename A3>
116218887SdimRegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
117218887Sdim                                         const MemRegion *superRegion) {
118218887Sdim
119218887Sdim  llvm::FoldingSetNodeID ID;
120218887Sdim  RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
121226890Sdim  void *InsertPos;
122218887Sdim  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
123218887Sdim                                                                   InsertPos));
124218887Sdim
125218887Sdim  if (!R) {
126218887Sdim    R = (RegionTy*) A.Allocate<RegionTy>();
127218887Sdim    new (R) RegionTy(a1, a2, a3, superRegion);
128218887Sdim    Regions.InsertNode(R, InsertPos);
129218887Sdim  }
130218887Sdim
131218887Sdim  return R;
132218887Sdim}
133218887Sdim
134218887Sdim//===----------------------------------------------------------------------===//
135218887Sdim// Object destruction.
136218887Sdim//===----------------------------------------------------------------------===//
137218887Sdim
138218887SdimMemRegion::~MemRegion() {}
139218887Sdim
140218887SdimMemRegionManager::~MemRegionManager() {
141218887Sdim  // All regions and their data are BumpPtrAllocated.  No need to call
142218887Sdim  // their destructors.
143218887Sdim}
144218887Sdim
145218887Sdim//===----------------------------------------------------------------------===//
146218887Sdim// Basic methods.
147218887Sdim//===----------------------------------------------------------------------===//
148218887Sdim
149218887Sdimbool SubRegion::isSubRegionOf(const MemRegion* R) const {
150218887Sdim  const MemRegion* r = getSuperRegion();
151218887Sdim  while (r != 0) {
152218887Sdim    if (r == R)
153218887Sdim      return true;
154218887Sdim    if (const SubRegion* sr = dyn_cast<SubRegion>(r))
155218887Sdim      r = sr->getSuperRegion();
156218887Sdim    else
157218887Sdim      break;
158218887Sdim  }
159218887Sdim  return false;
160218887Sdim}
161218887Sdim
162218887SdimMemRegionManager* SubRegion::getMemRegionManager() const {
163218887Sdim  const SubRegion* r = this;
164218887Sdim  do {
165218887Sdim    const MemRegion *superRegion = r->getSuperRegion();
166218887Sdim    if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
167218887Sdim      r = sr;
168218887Sdim      continue;
169218887Sdim    }
170218887Sdim    return superRegion->getMemRegionManager();
171218887Sdim  } while (1);
172218887Sdim}
173218887Sdim
174218887Sdimconst StackFrameContext *VarRegion::getStackFrame() const {
175218887Sdim  const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
176218887Sdim  return SSR ? SSR->getStackFrame() : NULL;
177218887Sdim}
178218887Sdim
179218887Sdim//===----------------------------------------------------------------------===//
180218887Sdim// Region extents.
181218887Sdim//===----------------------------------------------------------------------===//
182218887Sdim
183245431SdimDefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const {
184226890Sdim  ASTContext &Ctx = svalBuilder.getContext();
185218887Sdim  QualType T = getDesugaredValueType(Ctx);
186218887Sdim
187218887Sdim  if (isa<VariableArrayType>(T))
188218887Sdim    return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
189263509Sdim  if (T->isIncompleteType())
190218887Sdim    return UnknownVal();
191218887Sdim
192218887Sdim  CharUnits size = Ctx.getTypeSizeInChars(T);
193218887Sdim  QualType sizeTy = svalBuilder.getArrayIndexType();
194218887Sdim  return svalBuilder.makeIntVal(size.getQuantity(), sizeTy);
195218887Sdim}
196218887Sdim
197218887SdimDefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const {
198252723Sdim  // Force callers to deal with bitfields explicitly.
199252723Sdim  if (getDecl()->isBitField())
200252723Sdim    return UnknownVal();
201252723Sdim
202218887Sdim  DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder);
203218887Sdim
204218887Sdim  // A zero-length array at the end of a struct often stands for dynamically-
205218887Sdim  // allocated extra memory.
206218887Sdim  if (Extent.isZeroConstant()) {
207218887Sdim    QualType T = getDesugaredValueType(svalBuilder.getContext());
208218887Sdim
209218887Sdim    if (isa<ConstantArrayType>(T))
210218887Sdim      return UnknownVal();
211218887Sdim  }
212218887Sdim
213218887Sdim  return Extent;
214218887Sdim}
215218887Sdim
216218887SdimDefinedOrUnknownSVal AllocaRegion::getExtent(SValBuilder &svalBuilder) const {
217218887Sdim  return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
218218887Sdim}
219218887Sdim
220218887SdimDefinedOrUnknownSVal SymbolicRegion::getExtent(SValBuilder &svalBuilder) const {
221218887Sdim  return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
222218887Sdim}
223218887Sdim
224218887SdimDefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const {
225218887Sdim  return svalBuilder.makeIntVal(getStringLiteral()->getByteLength()+1,
226218887Sdim                                svalBuilder.getArrayIndexType());
227218887Sdim}
228218887Sdim
229235633SdimObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg)
230235633Sdim  : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
231235633Sdim
232235633Sdimconst ObjCIvarDecl *ObjCIvarRegion::getDecl() const {
233235633Sdim  return cast<ObjCIvarDecl>(D);
234235633Sdim}
235235633Sdim
236235633SdimQualType ObjCIvarRegion::getValueType() const {
237235633Sdim  return getDecl()->getType();
238235633Sdim}
239235633Sdim
240218887SdimQualType CXXBaseObjectRegion::getValueType() const {
241252723Sdim  return QualType(getDecl()->getTypeForDecl(), 0);
242218887Sdim}
243218887Sdim
244218887Sdim//===----------------------------------------------------------------------===//
245218887Sdim// FoldingSet profiling.
246218887Sdim//===----------------------------------------------------------------------===//
247218887Sdim
248218887Sdimvoid MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
249218887Sdim  ID.AddInteger((unsigned)getKind());
250218887Sdim}
251218887Sdim
252218887Sdimvoid StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
253218887Sdim  ID.AddInteger((unsigned)getKind());
254218887Sdim  ID.AddPointer(getStackFrame());
255218887Sdim}
256218887Sdim
257218887Sdimvoid StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
258218887Sdim  ID.AddInteger((unsigned)getKind());
259218887Sdim  ID.AddPointer(getCodeRegion());
260218887Sdim}
261218887Sdim
262218887Sdimvoid StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
263218887Sdim                                 const StringLiteral* Str,
264218887Sdim                                 const MemRegion* superRegion) {
265218887Sdim  ID.AddInteger((unsigned) StringRegionKind);
266218887Sdim  ID.AddPointer(Str);
267218887Sdim  ID.AddPointer(superRegion);
268218887Sdim}
269218887Sdim
270235633Sdimvoid ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
271235633Sdim                                     const ObjCStringLiteral* Str,
272235633Sdim                                     const MemRegion* superRegion) {
273235633Sdim  ID.AddInteger((unsigned) ObjCStringRegionKind);
274235633Sdim  ID.AddPointer(Str);
275235633Sdim  ID.AddPointer(superRegion);
276235633Sdim}
277235633Sdim
278218887Sdimvoid AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
279226890Sdim                                 const Expr *Ex, unsigned cnt,
280252723Sdim                                 const MemRegion *superRegion) {
281218887Sdim  ID.AddInteger((unsigned) AllocaRegionKind);
282218887Sdim  ID.AddPointer(Ex);
283218887Sdim  ID.AddInteger(cnt);
284252723Sdim  ID.AddPointer(superRegion);
285218887Sdim}
286218887Sdim
287218887Sdimvoid AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
288218887Sdim  ProfileRegion(ID, Ex, Cnt, superRegion);
289218887Sdim}
290218887Sdim
291218887Sdimvoid CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
292218887Sdim  CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
293218887Sdim}
294218887Sdim
295218887Sdimvoid CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
296226890Sdim                                          const CompoundLiteralExpr *CL,
297218887Sdim                                          const MemRegion* superRegion) {
298218887Sdim  ID.AddInteger((unsigned) CompoundLiteralRegionKind);
299218887Sdim  ID.AddPointer(CL);
300218887Sdim  ID.AddPointer(superRegion);
301218887Sdim}
302218887Sdim
303218887Sdimvoid CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
304218887Sdim                                  const PointerType *PT,
305218887Sdim                                  const MemRegion *sRegion) {
306218887Sdim  ID.AddInteger((unsigned) CXXThisRegionKind);
307218887Sdim  ID.AddPointer(PT);
308218887Sdim  ID.AddPointer(sRegion);
309218887Sdim}
310218887Sdim
311218887Sdimvoid CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
312218887Sdim  CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
313218887Sdim}
314218887Sdim
315235633Sdimvoid ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
316235633Sdim                                   const ObjCIvarDecl *ivd,
317235633Sdim                                   const MemRegion* superRegion) {
318235633Sdim  DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
319235633Sdim}
320235633Sdim
321226890Sdimvoid DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
322218887Sdim                               const MemRegion* superRegion, Kind k) {
323218887Sdim  ID.AddInteger((unsigned) k);
324218887Sdim  ID.AddPointer(D);
325218887Sdim  ID.AddPointer(superRegion);
326218887Sdim}
327218887Sdim
328218887Sdimvoid DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
329218887Sdim  DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
330218887Sdim}
331218887Sdim
332218887Sdimvoid VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
333218887Sdim  VarRegion::ProfileRegion(ID, getDecl(), superRegion);
334218887Sdim}
335218887Sdim
336218887Sdimvoid SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
337218887Sdim                                   const MemRegion *sreg) {
338218887Sdim  ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
339218887Sdim  ID.Add(sym);
340218887Sdim  ID.AddPointer(sreg);
341218887Sdim}
342218887Sdim
343218887Sdimvoid SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
344218887Sdim  SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
345218887Sdim}
346218887Sdim
347218887Sdimvoid ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
348218887Sdim                                  QualType ElementType, SVal Idx,
349218887Sdim                                  const MemRegion* superRegion) {
350218887Sdim  ID.AddInteger(MemRegion::ElementRegionKind);
351218887Sdim  ID.Add(ElementType);
352218887Sdim  ID.AddPointer(superRegion);
353218887Sdim  Idx.Profile(ID);
354218887Sdim}
355218887Sdim
356218887Sdimvoid ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
357218887Sdim  ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
358218887Sdim}
359218887Sdim
360218887Sdimvoid FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
361245431Sdim                                       const NamedDecl *FD,
362218887Sdim                                       const MemRegion*) {
363218887Sdim  ID.AddInteger(MemRegion::FunctionTextRegionKind);
364218887Sdim  ID.AddPointer(FD);
365218887Sdim}
366218887Sdim
367218887Sdimvoid FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
368218887Sdim  FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
369218887Sdim}
370218887Sdim
371218887Sdimvoid BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
372218887Sdim                                    const BlockDecl *BD, CanQualType,
373235633Sdim                                    const AnalysisDeclContext *AC,
374218887Sdim                                    const MemRegion*) {
375218887Sdim  ID.AddInteger(MemRegion::BlockTextRegionKind);
376218887Sdim  ID.AddPointer(BD);
377218887Sdim}
378218887Sdim
379218887Sdimvoid BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
380218887Sdim  BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
381218887Sdim}
382218887Sdim
383218887Sdimvoid BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
384218887Sdim                                    const BlockTextRegion *BC,
385218887Sdim                                    const LocationContext *LC,
386263509Sdim                                    unsigned BlkCount,
387218887Sdim                                    const MemRegion *sReg) {
388218887Sdim  ID.AddInteger(MemRegion::BlockDataRegionKind);
389218887Sdim  ID.AddPointer(BC);
390218887Sdim  ID.AddPointer(LC);
391263509Sdim  ID.AddInteger(BlkCount);
392218887Sdim  ID.AddPointer(sReg);
393218887Sdim}
394218887Sdim
395218887Sdimvoid BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
396263509Sdim  BlockDataRegion::ProfileRegion(ID, BC, LC, BlockCount, getSuperRegion());
397218887Sdim}
398218887Sdim
399218887Sdimvoid CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
400218887Sdim                                        Expr const *Ex,
401218887Sdim                                        const MemRegion *sReg) {
402218887Sdim  ID.AddPointer(Ex);
403218887Sdim  ID.AddPointer(sReg);
404218887Sdim}
405218887Sdim
406218887Sdimvoid CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
407218887Sdim  ProfileRegion(ID, Ex, getSuperRegion());
408218887Sdim}
409218887Sdim
410218887Sdimvoid CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
411252723Sdim                                        const CXXRecordDecl *RD,
412252723Sdim                                        bool IsVirtual,
413252723Sdim                                        const MemRegion *SReg) {
414252723Sdim  ID.AddPointer(RD);
415252723Sdim  ID.AddBoolean(IsVirtual);
416252723Sdim  ID.AddPointer(SReg);
417218887Sdim}
418218887Sdim
419218887Sdimvoid CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
420252723Sdim  ProfileRegion(ID, getDecl(), isVirtual(), superRegion);
421218887Sdim}
422218887Sdim
423218887Sdim//===----------------------------------------------------------------------===//
424235633Sdim// Region anchors.
425235633Sdim//===----------------------------------------------------------------------===//
426235633Sdim
427235633Sdimvoid GlobalsSpaceRegion::anchor() { }
428235633Sdimvoid HeapSpaceRegion::anchor() { }
429235633Sdimvoid UnknownSpaceRegion::anchor() { }
430235633Sdimvoid StackLocalsSpaceRegion::anchor() { }
431235633Sdimvoid StackArgumentsSpaceRegion::anchor() { }
432235633Sdimvoid TypedRegion::anchor() { }
433235633Sdimvoid TypedValueRegion::anchor() { }
434235633Sdimvoid CodeTextRegion::anchor() { }
435235633Sdimvoid SubRegion::anchor() { }
436235633Sdim
437235633Sdim//===----------------------------------------------------------------------===//
438218887Sdim// Region pretty-printing.
439218887Sdim//===----------------------------------------------------------------------===//
440218887Sdim
441218887Sdimvoid MemRegion::dump() const {
442218887Sdim  dumpToStream(llvm::errs());
443218887Sdim}
444218887Sdim
445218887Sdimstd::string MemRegion::getString() const {
446218887Sdim  std::string s;
447218887Sdim  llvm::raw_string_ostream os(s);
448218887Sdim  dumpToStream(os);
449218887Sdim  return os.str();
450218887Sdim}
451218887Sdim
452226890Sdimvoid MemRegion::dumpToStream(raw_ostream &os) const {
453218887Sdim  os << "<Unknown Region>";
454218887Sdim}
455218887Sdim
456226890Sdimvoid AllocaRegion::dumpToStream(raw_ostream &os) const {
457245431Sdim  os << "alloca{" << (const void*) Ex << ',' << Cnt << '}';
458218887Sdim}
459218887Sdim
460226890Sdimvoid FunctionTextRegion::dumpToStream(raw_ostream &os) const {
461218887Sdim  os << "code{" << getDecl()->getDeclName().getAsString() << '}';
462218887Sdim}
463218887Sdim
464226890Sdimvoid BlockTextRegion::dumpToStream(raw_ostream &os) const {
465245431Sdim  os << "block_code{" << (const void*) this << '}';
466218887Sdim}
467218887Sdim
468226890Sdimvoid BlockDataRegion::dumpToStream(raw_ostream &os) const {
469263509Sdim  os << "block_data{" << BC;
470263509Sdim  os << "; ";
471263509Sdim  for (BlockDataRegion::referenced_vars_iterator
472263509Sdim         I = referenced_vars_begin(),
473263509Sdim         E = referenced_vars_end(); I != E; ++I)
474263509Sdim    os << "(" << I.getCapturedRegion() << "," <<
475263509Sdim                 I.getOriginalRegion() << ") ";
476263509Sdim  os << '}';
477218887Sdim}
478218887Sdim
479226890Sdimvoid CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {
480218887Sdim  // FIXME: More elaborate pretty-printing.
481245431Sdim  os << "{ " << (const void*) CL <<  " }";
482218887Sdim}
483218887Sdim
484226890Sdimvoid CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {
485226890Sdim  os << "temp_object{" << getValueType().getAsString() << ','
486245431Sdim     << (const void*) Ex << '}';
487218887Sdim}
488218887Sdim
489226890Sdimvoid CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
490252723Sdim  os << "base{" << superRegion << ',' << getDecl()->getName() << '}';
491218887Sdim}
492218887Sdim
493226890Sdimvoid CXXThisRegion::dumpToStream(raw_ostream &os) const {
494218887Sdim  os << "this";
495218887Sdim}
496218887Sdim
497226890Sdimvoid ElementRegion::dumpToStream(raw_ostream &os) const {
498218887Sdim  os << "element{" << superRegion << ','
499218887Sdim     << Index << ',' << getElementType().getAsString() << '}';
500218887Sdim}
501218887Sdim
502226890Sdimvoid FieldRegion::dumpToStream(raw_ostream &os) const {
503226890Sdim  os << superRegion << "->" << *getDecl();
504218887Sdim}
505218887Sdim
506226890Sdimvoid ObjCIvarRegion::dumpToStream(raw_ostream &os) const {
507226890Sdim  os << "ivar{" << superRegion << ',' << *getDecl() << '}';
508218887Sdim}
509218887Sdim
510226890Sdimvoid StringRegion::dumpToStream(raw_ostream &os) const {
511235633Sdim  Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts()));
512218887Sdim}
513218887Sdim
514235633Sdimvoid ObjCStringRegion::dumpToStream(raw_ostream &os) const {
515235633Sdim  Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts()));
516235633Sdim}
517235633Sdim
518226890Sdimvoid SymbolicRegion::dumpToStream(raw_ostream &os) const {
519218887Sdim  os << "SymRegion{" << sym << '}';
520218887Sdim}
521218887Sdim
522226890Sdimvoid VarRegion::dumpToStream(raw_ostream &os) const {
523226890Sdim  os << *cast<VarDecl>(D);
524218887Sdim}
525218887Sdim
526218887Sdimvoid RegionRawOffset::dump() const {
527218887Sdim  dumpToStream(llvm::errs());
528218887Sdim}
529218887Sdim
530226890Sdimvoid RegionRawOffset::dumpToStream(raw_ostream &os) const {
531218887Sdim  os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}';
532218887Sdim}
533218887Sdim
534226890Sdimvoid StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const {
535218887Sdim  os << "StaticGlobalsMemSpace{" << CR << '}';
536218887Sdim}
537218887Sdim
538235633Sdimvoid GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const {
539235633Sdim  os << "GlobalInternalSpaceRegion";
540235633Sdim}
541235633Sdim
542235633Sdimvoid GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const {
543235633Sdim  os << "GlobalSystemSpaceRegion";
544235633Sdim}
545235633Sdim
546235633Sdimvoid GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const {
547235633Sdim  os << "GlobalImmutableSpaceRegion";
548235633Sdim}
549235633Sdim
550245431Sdimvoid HeapSpaceRegion::dumpToStream(raw_ostream &os) const {
551245431Sdim  os << "HeapSpaceRegion";
552245431Sdim}
553245431Sdim
554245431Sdimvoid UnknownSpaceRegion::dumpToStream(raw_ostream &os) const {
555245431Sdim  os << "UnknownSpaceRegion";
556245431Sdim}
557245431Sdim
558245431Sdimvoid StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const {
559245431Sdim  os << "StackArgumentsSpaceRegion";
560245431Sdim}
561245431Sdim
562245431Sdimvoid StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const {
563245431Sdim  os << "StackLocalsSpaceRegion";
564245431Sdim}
565245431Sdim
566245431Sdimbool MemRegion::canPrintPretty() const {
567252723Sdim  return canPrintPrettyAsExpr();
568252723Sdim}
569252723Sdim
570252723Sdimbool MemRegion::canPrintPrettyAsExpr() const {
571245431Sdim  return false;
572245431Sdim}
573245431Sdim
574245431Sdimvoid MemRegion::printPretty(raw_ostream &os) const {
575252723Sdim  assert(canPrintPretty() && "This region cannot be printed pretty.");
576252723Sdim  os << "'";
577252723Sdim  printPrettyAsExpr(os);
578252723Sdim  os << "'";
579235633Sdim  return;
580235633Sdim}
581235633Sdim
582252723Sdimvoid MemRegion::printPrettyAsExpr(raw_ostream &os) const {
583252723Sdim  llvm_unreachable("This region cannot be printed pretty.");
584252723Sdim  return;
585252723Sdim}
586252723Sdim
587252723Sdimbool VarRegion::canPrintPrettyAsExpr() const {
588245431Sdim  return true;
589245431Sdim}
590245431Sdim
591252723Sdimvoid VarRegion::printPrettyAsExpr(raw_ostream &os) const {
592235633Sdim  os << getDecl()->getName();
593235633Sdim}
594235633Sdim
595252723Sdimbool ObjCIvarRegion::canPrintPrettyAsExpr() const {
596252723Sdim  return true;
597252723Sdim}
598252723Sdim
599252723Sdimvoid ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const {
600252723Sdim  os << getDecl()->getName();
601252723Sdim}
602252723Sdim
603245431Sdimbool FieldRegion::canPrintPretty() const {
604252723Sdim  return true;
605235633Sdim}
606235633Sdim
607252723Sdimbool FieldRegion::canPrintPrettyAsExpr() const {
608252723Sdim  return superRegion->canPrintPrettyAsExpr();
609252723Sdim}
610252723Sdim
611252723Sdimvoid FieldRegion::printPrettyAsExpr(raw_ostream &os) const {
612252723Sdim  assert(canPrintPrettyAsExpr());
613252723Sdim  superRegion->printPrettyAsExpr(os);
614245431Sdim  os << "." << getDecl()->getName();
615245431Sdim}
616245431Sdim
617252723Sdimvoid FieldRegion::printPretty(raw_ostream &os) const {
618252723Sdim  if (canPrintPrettyAsExpr()) {
619252723Sdim    os << "\'";
620252723Sdim    printPrettyAsExpr(os);
621252723Sdim    os << "'";
622252723Sdim  } else {
623252723Sdim    os << "field " << "\'" << getDecl()->getName() << "'";
624252723Sdim  }
625252723Sdim  return;
626252723Sdim}
627252723Sdim
628252723Sdimbool CXXBaseObjectRegion::canPrintPrettyAsExpr() const {
629252723Sdim  return superRegion->canPrintPrettyAsExpr();
630252723Sdim}
631252723Sdim
632252723Sdimvoid CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
633252723Sdim  superRegion->printPrettyAsExpr(os);
634252723Sdim}
635252723Sdim
636218887Sdim//===----------------------------------------------------------------------===//
637218887Sdim// MemRegionManager methods.
638218887Sdim//===----------------------------------------------------------------------===//
639218887Sdim
640218887Sdimtemplate <typename REG>
641218887Sdimconst REG *MemRegionManager::LazyAllocate(REG*& region) {
642218887Sdim  if (!region) {
643218887Sdim    region = (REG*) A.Allocate<REG>();
644218887Sdim    new (region) REG(this);
645218887Sdim  }
646218887Sdim
647218887Sdim  return region;
648218887Sdim}
649218887Sdim
650218887Sdimtemplate <typename REG, typename ARG>
651218887Sdimconst REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
652218887Sdim  if (!region) {
653218887Sdim    region = (REG*) A.Allocate<REG>();
654218887Sdim    new (region) REG(this, a);
655218887Sdim  }
656218887Sdim
657218887Sdim  return region;
658218887Sdim}
659218887Sdim
660218887Sdimconst StackLocalsSpaceRegion*
661218887SdimMemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
662218887Sdim  assert(STC);
663218887Sdim  StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
664218887Sdim
665218887Sdim  if (R)
666218887Sdim    return R;
667218887Sdim
668218887Sdim  R = A.Allocate<StackLocalsSpaceRegion>();
669218887Sdim  new (R) StackLocalsSpaceRegion(this, STC);
670218887Sdim  return R;
671218887Sdim}
672218887Sdim
673218887Sdimconst StackArgumentsSpaceRegion *
674218887SdimMemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
675218887Sdim  assert(STC);
676218887Sdim  StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
677218887Sdim
678218887Sdim  if (R)
679218887Sdim    return R;
680218887Sdim
681218887Sdim  R = A.Allocate<StackArgumentsSpaceRegion>();
682218887Sdim  new (R) StackArgumentsSpaceRegion(this, STC);
683218887Sdim  return R;
684218887Sdim}
685218887Sdim
686218887Sdimconst GlobalsSpaceRegion
687235633Sdim*MemRegionManager::getGlobalsRegion(MemRegion::Kind K,
688235633Sdim                                    const CodeTextRegion *CR) {
689235633Sdim  if (!CR) {
690235633Sdim    if (K == MemRegion::GlobalSystemSpaceRegionKind)
691235633Sdim      return LazyAllocate(SystemGlobals);
692235633Sdim    if (K == MemRegion::GlobalImmutableSpaceRegionKind)
693235633Sdim      return LazyAllocate(ImmutableGlobals);
694235633Sdim    assert(K == MemRegion::GlobalInternalSpaceRegionKind);
695235633Sdim    return LazyAllocate(InternalGlobals);
696235633Sdim  }
697218887Sdim
698235633Sdim  assert(K == MemRegion::StaticGlobalSpaceRegionKind);
699218887Sdim  StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
700218887Sdim  if (R)
701218887Sdim    return R;
702218887Sdim
703218887Sdim  R = A.Allocate<StaticGlobalSpaceRegion>();
704218887Sdim  new (R) StaticGlobalSpaceRegion(this, CR);
705218887Sdim  return R;
706218887Sdim}
707218887Sdim
708218887Sdimconst HeapSpaceRegion *MemRegionManager::getHeapRegion() {
709218887Sdim  return LazyAllocate(heap);
710218887Sdim}
711218887Sdim
712218887Sdimconst MemSpaceRegion *MemRegionManager::getUnknownRegion() {
713218887Sdim  return LazyAllocate(unknown);
714218887Sdim}
715218887Sdim
716218887Sdimconst MemSpaceRegion *MemRegionManager::getCodeRegion() {
717218887Sdim  return LazyAllocate(code);
718218887Sdim}
719218887Sdim
720218887Sdim//===----------------------------------------------------------------------===//
721218887Sdim// Constructing regions.
722218887Sdim//===----------------------------------------------------------------------===//
723218887Sdimconst StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
724218887Sdim  return getSubRegion<StringRegion>(Str, getGlobalsRegion());
725218887Sdim}
726218887Sdim
727235633Sdimconst ObjCStringRegion *
728235633SdimMemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){
729235633Sdim  return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion());
730235633Sdim}
731235633Sdim
732245431Sdim/// Look through a chain of LocationContexts to either find the
733245431Sdim/// StackFrameContext that matches a DeclContext, or find a VarRegion
734245431Sdim/// for a variable captured by a block.
735245431Sdimstatic llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
736245431SdimgetStackOrCaptureRegionForDeclContext(const LocationContext *LC,
737245431Sdim                                      const DeclContext *DC,
738245431Sdim                                      const VarDecl *VD) {
739245431Sdim  while (LC) {
740245431Sdim    if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) {
741245431Sdim      if (cast<DeclContext>(SFC->getDecl()) == DC)
742245431Sdim        return SFC;
743245431Sdim    }
744245431Sdim    if (const BlockInvocationContext *BC =
745245431Sdim        dyn_cast<BlockInvocationContext>(LC)) {
746245431Sdim      const BlockDataRegion *BR =
747245431Sdim        static_cast<const BlockDataRegion*>(BC->getContextData());
748245431Sdim      // FIXME: This can be made more efficient.
749245431Sdim      for (BlockDataRegion::referenced_vars_iterator
750245431Sdim           I = BR->referenced_vars_begin(),
751245431Sdim           E = BR->referenced_vars_end(); I != E; ++I) {
752245431Sdim        if (const VarRegion *VR = dyn_cast<VarRegion>(I.getOriginalRegion()))
753245431Sdim          if (VR->getDecl() == VD)
754245431Sdim            return cast<VarRegion>(I.getCapturedRegion());
755245431Sdim      }
756245431Sdim    }
757245431Sdim
758245431Sdim    LC = LC->getParent();
759245431Sdim  }
760245431Sdim  return (const StackFrameContext*)0;
761245431Sdim}
762245431Sdim
763218887Sdimconst VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
764218887Sdim                                                const LocationContext *LC) {
765218887Sdim  const MemRegion *sReg = 0;
766218887Sdim
767235633Sdim  if (D->hasGlobalStorage() && !D->isStaticLocal()) {
768235633Sdim
769235633Sdim    // First handle the globals defined in system headers.
770235633Sdim    if (C.getSourceManager().isInSystemHeader(D->getLocation())) {
771235633Sdim      // Whitelist the system globals which often DO GET modified, assume the
772235633Sdim      // rest are immutable.
773235633Sdim      if (D->getName().find("errno") != StringRef::npos)
774235633Sdim        sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
775235633Sdim      else
776235633Sdim        sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
777235633Sdim
778235633Sdim    // Treat other globals as GlobalInternal unless they are constants.
779235633Sdim    } else {
780235633Sdim      QualType GQT = D->getType();
781235633Sdim      const Type *GT = GQT.getTypePtrOrNull();
782235633Sdim      // TODO: We could walk the complex types here and see if everything is
783235633Sdim      // constified.
784235633Sdim      if (GT && GQT.isConstQualified() && GT->isArithmeticType())
785235633Sdim        sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
786235633Sdim      else
787235633Sdim        sReg = getGlobalsRegion();
788235633Sdim    }
789235633Sdim
790235633Sdim  // Finally handle static locals.
791235633Sdim  } else {
792218887Sdim    // FIXME: Once we implement scope handling, we will need to properly lookup
793218887Sdim    // 'D' to the proper LocationContext.
794218887Sdim    const DeclContext *DC = D->getDeclContext();
795245431Sdim    llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
796245431Sdim      getStackOrCaptureRegionForDeclContext(LC, DC, D);
797245431Sdim
798245431Sdim    if (V.is<const VarRegion*>())
799245431Sdim      return V.get<const VarRegion*>();
800245431Sdim
801245431Sdim    const StackFrameContext *STC = V.get<const StackFrameContext*>();
802218887Sdim
803218887Sdim    if (!STC)
804218887Sdim      sReg = getUnknownRegion();
805218887Sdim    else {
806218887Sdim      if (D->hasLocalStorage()) {
807218887Sdim        sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
808218887Sdim               ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
809218887Sdim               : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
810218887Sdim      }
811218887Sdim      else {
812218887Sdim        assert(D->isStaticLocal());
813245431Sdim        const Decl *STCD = STC->getDecl();
814245431Sdim        if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
815235633Sdim          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
816245431Sdim                                  getFunctionTextRegion(cast<NamedDecl>(STCD)));
817245431Sdim        else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
818263509Sdim          // FIXME: The fallback type here is totally bogus -- though it should
819263509Sdim          // never be queried, it will prevent uniquing with the real
820263509Sdim          // BlockTextRegion. Ideally we'd fix the AST so that we always had a
821263509Sdim          // signature.
822263509Sdim          QualType T;
823263509Sdim          if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
824263509Sdim            T = TSI->getType();
825263509Sdim          else
826263509Sdim            T = getContext().getFunctionNoProtoType(getContext().VoidTy);
827263509Sdim
828218887Sdim          const BlockTextRegion *BTR =
829263509Sdim            getBlockTextRegion(BD, C.getCanonicalType(T),
830263509Sdim                               STC->getAnalysisDeclContext());
831235633Sdim          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
832235633Sdim                                  BTR);
833218887Sdim        }
834218887Sdim        else {
835218887Sdim          sReg = getGlobalsRegion();
836218887Sdim        }
837218887Sdim      }
838218887Sdim    }
839218887Sdim  }
840218887Sdim
841218887Sdim  return getSubRegion<VarRegion>(D, sReg);
842218887Sdim}
843218887Sdim
844218887Sdimconst VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
845218887Sdim                                                const MemRegion *superR) {
846218887Sdim  return getSubRegion<VarRegion>(D, superR);
847218887Sdim}
848218887Sdim
849218887Sdimconst BlockDataRegion *
850218887SdimMemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
851263509Sdim                                     const LocationContext *LC,
852263509Sdim                                     unsigned blockCount) {
853218887Sdim  const MemRegion *sReg = 0;
854235633Sdim  const BlockDecl *BD = BC->getDecl();
855235633Sdim  if (!BD->hasCaptures()) {
856235633Sdim    // This handles 'static' blocks.
857235633Sdim    sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
858218887Sdim  }
859218887Sdim  else {
860235633Sdim    if (LC) {
861235633Sdim      // FIXME: Once we implement scope handling, we want the parent region
862235633Sdim      // to be the scope.
863235633Sdim      const StackFrameContext *STC = LC->getCurrentStackFrame();
864235633Sdim      assert(STC);
865235633Sdim      sReg = getStackLocalsRegion(STC);
866235633Sdim    }
867235633Sdim    else {
868235633Sdim      // We allow 'LC' to be NULL for cases where want BlockDataRegions
869235633Sdim      // without context-sensitivity.
870235633Sdim      sReg = getUnknownRegion();
871235633Sdim    }
872218887Sdim  }
873218887Sdim
874263509Sdim  return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg);
875218887Sdim}
876218887Sdim
877263509Sdimconst CXXTempObjectRegion *
878263509SdimMemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) {
879263509Sdim  return getSubRegion<CXXTempObjectRegion>(
880263509Sdim      Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, NULL));
881263509Sdim}
882263509Sdim
883218887Sdimconst CompoundLiteralRegion*
884226890SdimMemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
885218887Sdim                                           const LocationContext *LC) {
886218887Sdim
887218887Sdim  const MemRegion *sReg = 0;
888218887Sdim
889218887Sdim  if (CL->isFileScope())
890218887Sdim    sReg = getGlobalsRegion();
891218887Sdim  else {
892218887Sdim    const StackFrameContext *STC = LC->getCurrentStackFrame();
893218887Sdim    assert(STC);
894218887Sdim    sReg = getStackLocalsRegion(STC);
895218887Sdim  }
896218887Sdim
897218887Sdim  return getSubRegion<CompoundLiteralRegion>(CL, sReg);
898218887Sdim}
899218887Sdim
900218887Sdimconst ElementRegion*
901218887SdimMemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
902218887Sdim                                   const MemRegion* superRegion,
903226890Sdim                                   ASTContext &Ctx){
904218887Sdim
905218887Sdim  QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
906218887Sdim
907218887Sdim  llvm::FoldingSetNodeID ID;
908218887Sdim  ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
909218887Sdim
910226890Sdim  void *InsertPos;
911218887Sdim  MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
912218887Sdim  ElementRegion* R = cast_or_null<ElementRegion>(data);
913218887Sdim
914218887Sdim  if (!R) {
915218887Sdim    R = (ElementRegion*) A.Allocate<ElementRegion>();
916218887Sdim    new (R) ElementRegion(T, Idx, superRegion);
917218887Sdim    Regions.InsertNode(R, InsertPos);
918218887Sdim  }
919218887Sdim
920218887Sdim  return R;
921218887Sdim}
922218887Sdim
923218887Sdimconst FunctionTextRegion *
924245431SdimMemRegionManager::getFunctionTextRegion(const NamedDecl *FD) {
925218887Sdim  return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
926218887Sdim}
927218887Sdim
928218887Sdimconst BlockTextRegion *
929218887SdimMemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
930235633Sdim                                     AnalysisDeclContext *AC) {
931218887Sdim  return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
932218887Sdim}
933218887Sdim
934218887Sdim
935218887Sdim/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
936218887Sdimconst SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
937218887Sdim  return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
938218887Sdim}
939218887Sdim
940245431Sdimconst SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {
941245431Sdim  return getSubRegion<SymbolicRegion>(Sym, getHeapRegion());
942245431Sdim}
943245431Sdim
944218887Sdimconst FieldRegion*
945226890SdimMemRegionManager::getFieldRegion(const FieldDecl *d,
946218887Sdim                                 const MemRegion* superRegion){
947218887Sdim  return getSubRegion<FieldRegion>(d, superRegion);
948218887Sdim}
949218887Sdim
950218887Sdimconst ObjCIvarRegion*
951226890SdimMemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
952218887Sdim                                    const MemRegion* superRegion) {
953218887Sdim  return getSubRegion<ObjCIvarRegion>(d, superRegion);
954218887Sdim}
955218887Sdim
956218887Sdimconst CXXTempObjectRegion*
957218887SdimMemRegionManager::getCXXTempObjectRegion(Expr const *E,
958218887Sdim                                         LocationContext const *LC) {
959218887Sdim  const StackFrameContext *SFC = LC->getCurrentStackFrame();
960218887Sdim  assert(SFC);
961218887Sdim  return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC));
962218887Sdim}
963218887Sdim
964252723Sdim/// Checks whether \p BaseClass is a valid virtual or direct non-virtual base
965252723Sdim/// class of the type of \p Super.
966252723Sdimstatic bool isValidBaseClass(const CXXRecordDecl *BaseClass,
967252723Sdim                             const TypedValueRegion *Super,
968252723Sdim                             bool IsVirtual) {
969252723Sdim  BaseClass = BaseClass->getCanonicalDecl();
970252723Sdim
971252723Sdim  const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl();
972252723Sdim  if (!Class)
973252723Sdim    return true;
974252723Sdim
975252723Sdim  if (IsVirtual)
976252723Sdim    return Class->isVirtuallyDerivedFrom(BaseClass);
977252723Sdim
978252723Sdim  for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
979252723Sdim                                                E = Class->bases_end();
980252723Sdim       I != E; ++I) {
981252723Sdim    if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
982252723Sdim      return true;
983252723Sdim  }
984252723Sdim
985252723Sdim  return false;
986252723Sdim}
987252723Sdim
988218887Sdimconst CXXBaseObjectRegion *
989252723SdimMemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
990252723Sdim                                         const MemRegion *Super,
991252723Sdim                                         bool IsVirtual) {
992252723Sdim  if (isa<TypedValueRegion>(Super)) {
993252723Sdim    assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual));
994263509Sdim    (void)&isValidBaseClass;
995245431Sdim
996252723Sdim    if (IsVirtual) {
997252723Sdim      // Virtual base regions should not be layered, since the layout rules
998252723Sdim      // are different.
999252723Sdim      while (const CXXBaseObjectRegion *Base =
1000252723Sdim               dyn_cast<CXXBaseObjectRegion>(Super)) {
1001252723Sdim        Super = Base->getSuperRegion();
1002245431Sdim      }
1003252723Sdim      assert(Super && !isa<MemSpaceRegion>(Super));
1004245431Sdim    }
1005245431Sdim  }
1006245431Sdim
1007252723Sdim  return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
1008218887Sdim}
1009218887Sdim
1010218887Sdimconst CXXThisRegion*
1011218887SdimMemRegionManager::getCXXThisRegion(QualType thisPointerTy,
1012218887Sdim                                   const LocationContext *LC) {
1013218887Sdim  const StackFrameContext *STC = LC->getCurrentStackFrame();
1014218887Sdim  assert(STC);
1015218887Sdim  const PointerType *PT = thisPointerTy->getAs<PointerType>();
1016218887Sdim  assert(PT);
1017218887Sdim  return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
1018218887Sdim}
1019218887Sdim
1020218887Sdimconst AllocaRegion*
1021226890SdimMemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt,
1022218887Sdim                                  const LocationContext *LC) {
1023218887Sdim  const StackFrameContext *STC = LC->getCurrentStackFrame();
1024218887Sdim  assert(STC);
1025218887Sdim  return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
1026218887Sdim}
1027218887Sdim
1028218887Sdimconst MemSpaceRegion *MemRegion::getMemorySpace() const {
1029218887Sdim  const MemRegion *R = this;
1030218887Sdim  const SubRegion* SR = dyn_cast<SubRegion>(this);
1031218887Sdim
1032218887Sdim  while (SR) {
1033218887Sdim    R = SR->getSuperRegion();
1034218887Sdim    SR = dyn_cast<SubRegion>(R);
1035218887Sdim  }
1036218887Sdim
1037218887Sdim  return dyn_cast<MemSpaceRegion>(R);
1038218887Sdim}
1039218887Sdim
1040218887Sdimbool MemRegion::hasStackStorage() const {
1041218887Sdim  return isa<StackSpaceRegion>(getMemorySpace());
1042218887Sdim}
1043218887Sdim
1044218887Sdimbool MemRegion::hasStackNonParametersStorage() const {
1045218887Sdim  return isa<StackLocalsSpaceRegion>(getMemorySpace());
1046218887Sdim}
1047218887Sdim
1048218887Sdimbool MemRegion::hasStackParametersStorage() const {
1049218887Sdim  return isa<StackArgumentsSpaceRegion>(getMemorySpace());
1050218887Sdim}
1051218887Sdim
1052218887Sdimbool MemRegion::hasGlobalsOrParametersStorage() const {
1053218887Sdim  const MemSpaceRegion *MS = getMemorySpace();
1054218887Sdim  return isa<StackArgumentsSpaceRegion>(MS) ||
1055218887Sdim         isa<GlobalsSpaceRegion>(MS);
1056218887Sdim}
1057218887Sdim
1058218887Sdim// getBaseRegion strips away all elements and fields, and get the base region
1059218887Sdim// of them.
1060218887Sdimconst MemRegion *MemRegion::getBaseRegion() const {
1061218887Sdim  const MemRegion *R = this;
1062218887Sdim  while (true) {
1063218887Sdim    switch (R->getKind()) {
1064218887Sdim      case MemRegion::ElementRegionKind:
1065218887Sdim      case MemRegion::FieldRegionKind:
1066218887Sdim      case MemRegion::ObjCIvarRegionKind:
1067218887Sdim      case MemRegion::CXXBaseObjectRegionKind:
1068218887Sdim        R = cast<SubRegion>(R)->getSuperRegion();
1069218887Sdim        continue;
1070218887Sdim      default:
1071218887Sdim        break;
1072218887Sdim    }
1073218887Sdim    break;
1074218887Sdim  }
1075218887Sdim  return R;
1076218887Sdim}
1077218887Sdim
1078245431Sdimbool MemRegion::isSubRegionOf(const MemRegion *R) const {
1079245431Sdim  return false;
1080245431Sdim}
1081245431Sdim
1082218887Sdim//===----------------------------------------------------------------------===//
1083218887Sdim// View handling.
1084218887Sdim//===----------------------------------------------------------------------===//
1085218887Sdim
1086245431Sdimconst MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const {
1087218887Sdim  const MemRegion *R = this;
1088218887Sdim  while (true) {
1089245431Sdim    switch (R->getKind()) {
1090245431Sdim    case ElementRegionKind: {
1091245431Sdim      const ElementRegion *ER = cast<ElementRegion>(R);
1092245431Sdim      if (!ER->getIndex().isZeroConstant())
1093245431Sdim        return R;
1094245431Sdim      R = ER->getSuperRegion();
1095245431Sdim      break;
1096218887Sdim    }
1097245431Sdim    case CXXBaseObjectRegionKind:
1098245431Sdim      if (!StripBaseCasts)
1099245431Sdim        return R;
1100245431Sdim      R = cast<CXXBaseObjectRegion>(R)->getSuperRegion();
1101245431Sdim      break;
1102245431Sdim    default:
1103245431Sdim      return R;
1104245431Sdim    }
1105218887Sdim  }
1106218887Sdim}
1107218887Sdim
1108252723Sdimconst SymbolicRegion *MemRegion::getSymbolicBase() const {
1109252723Sdim  const SubRegion *SubR = dyn_cast<SubRegion>(this);
1110252723Sdim
1111252723Sdim  while (SubR) {
1112252723Sdim    if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR))
1113252723Sdim      return SymR;
1114252723Sdim    SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
1115252723Sdim  }
1116252723Sdim  return 0;
1117252723Sdim}
1118252723Sdim
1119218887Sdim// FIXME: Merge with the implementation of the same method in Store.cpp
1120218887Sdimstatic bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
1121218887Sdim  if (const RecordType *RT = Ty->getAs<RecordType>()) {
1122218887Sdim    const RecordDecl *D = RT->getDecl();
1123218887Sdim    if (!D->getDefinition())
1124218887Sdim      return false;
1125218887Sdim  }
1126218887Sdim
1127218887Sdim  return true;
1128218887Sdim}
1129218887Sdim
1130218887SdimRegionRawOffset ElementRegion::getAsArrayOffset() const {
1131218887Sdim  CharUnits offset = CharUnits::Zero();
1132218887Sdim  const ElementRegion *ER = this;
1133218887Sdim  const MemRegion *superR = NULL;
1134218887Sdim  ASTContext &C = getContext();
1135218887Sdim
1136218887Sdim  // FIXME: Handle multi-dimensional arrays.
1137218887Sdim
1138218887Sdim  while (ER) {
1139218887Sdim    superR = ER->getSuperRegion();
1140218887Sdim
1141218887Sdim    // FIXME: generalize to symbolic offsets.
1142218887Sdim    SVal index = ER->getIndex();
1143252723Sdim    if (Optional<nonloc::ConcreteInt> CI = index.getAs<nonloc::ConcreteInt>()) {
1144218887Sdim      // Update the offset.
1145218887Sdim      int64_t i = CI->getValue().getSExtValue();
1146218887Sdim
1147218887Sdim      if (i != 0) {
1148218887Sdim        QualType elemType = ER->getElementType();
1149218887Sdim
1150218887Sdim        // If we are pointing to an incomplete type, go no further.
1151218887Sdim        if (!IsCompleteType(C, elemType)) {
1152218887Sdim          superR = ER;
1153218887Sdim          break;
1154218887Sdim        }
1155218887Sdim
1156218887Sdim        CharUnits size = C.getTypeSizeInChars(elemType);
1157218887Sdim        offset += (i * size);
1158218887Sdim      }
1159218887Sdim
1160218887Sdim      // Go to the next ElementRegion (if any).
1161218887Sdim      ER = dyn_cast<ElementRegion>(superR);
1162218887Sdim      continue;
1163218887Sdim    }
1164218887Sdim
1165218887Sdim    return NULL;
1166218887Sdim  }
1167218887Sdim
1168218887Sdim  assert(superR && "super region cannot be NULL");
1169218887Sdim  return RegionRawOffset(superR, offset);
1170218887Sdim}
1171218887Sdim
1172252723Sdim
1173252723Sdim/// Returns true if \p Base is an immediate base class of \p Child
1174252723Sdimstatic bool isImmediateBase(const CXXRecordDecl *Child,
1175252723Sdim                            const CXXRecordDecl *Base) {
1176252723Sdim  // Note that we do NOT canonicalize the base class here, because
1177252723Sdim  // ASTRecordLayout doesn't either. If that leads us down the wrong path,
1178252723Sdim  // so be it; at least we won't crash.
1179252723Sdim  for (CXXRecordDecl::base_class_const_iterator I = Child->bases_begin(),
1180252723Sdim                                                E = Child->bases_end();
1181252723Sdim       I != E; ++I) {
1182252723Sdim    if (I->getType()->getAsCXXRecordDecl() == Base)
1183252723Sdim      return true;
1184252723Sdim  }
1185252723Sdim
1186252723Sdim  return false;
1187252723Sdim}
1188252723Sdim
1189218887SdimRegionOffset MemRegion::getAsOffset() const {
1190218887Sdim  const MemRegion *R = this;
1191245431Sdim  const MemRegion *SymbolicOffsetBase = 0;
1192218887Sdim  int64_t Offset = 0;
1193218887Sdim
1194218887Sdim  while (1) {
1195218887Sdim    switch (R->getKind()) {
1196252723Sdim    case GenericMemSpaceRegionKind:
1197252723Sdim    case StackLocalsSpaceRegionKind:
1198252723Sdim    case StackArgumentsSpaceRegionKind:
1199252723Sdim    case HeapSpaceRegionKind:
1200252723Sdim    case UnknownSpaceRegionKind:
1201252723Sdim    case StaticGlobalSpaceRegionKind:
1202252723Sdim    case GlobalInternalSpaceRegionKind:
1203252723Sdim    case GlobalSystemSpaceRegionKind:
1204252723Sdim    case GlobalImmutableSpaceRegionKind:
1205252723Sdim      // Stores can bind directly to a region space to set a default value.
1206252723Sdim      assert(Offset == 0 && !SymbolicOffsetBase);
1207252723Sdim      goto Finish;
1208245431Sdim
1209252723Sdim    case FunctionTextRegionKind:
1210252723Sdim    case BlockTextRegionKind:
1211252723Sdim    case BlockDataRegionKind:
1212252723Sdim      // These will never have bindings, but may end up having values requested
1213252723Sdim      // if the user does some strange casting.
1214252723Sdim      if (Offset != 0)
1215252723Sdim        SymbolicOffsetBase = R;
1216252723Sdim      goto Finish;
1217252723Sdim
1218218887Sdim    case SymbolicRegionKind:
1219218887Sdim    case AllocaRegionKind:
1220218887Sdim    case CompoundLiteralRegionKind:
1221218887Sdim    case CXXThisRegionKind:
1222218887Sdim    case StringRegionKind:
1223252723Sdim    case ObjCStringRegionKind:
1224218887Sdim    case VarRegionKind:
1225218887Sdim    case CXXTempObjectRegionKind:
1226252723Sdim      // Usual base regions.
1227218887Sdim      goto Finish;
1228245431Sdim
1229245431Sdim    case ObjCIvarRegionKind:
1230245431Sdim      // This is a little strange, but it's a compromise between
1231245431Sdim      // ObjCIvarRegions having unknown compile-time offsets (when using the
1232245431Sdim      // non-fragile runtime) and yet still being distinct, non-overlapping
1233245431Sdim      // regions. Thus we treat them as "like" base regions for the purposes
1234245431Sdim      // of computing offsets.
1235245431Sdim      goto Finish;
1236245431Sdim
1237245431Sdim    case CXXBaseObjectRegionKind: {
1238245431Sdim      const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R);
1239245431Sdim      R = BOR->getSuperRegion();
1240245431Sdim
1241245431Sdim      QualType Ty;
1242252723Sdim      bool RootIsSymbolic = false;
1243245431Sdim      if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) {
1244245431Sdim        Ty = TVR->getDesugaredValueType(getContext());
1245245431Sdim      } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
1246245431Sdim        // If our base region is symbolic, we don't know what type it really is.
1247245431Sdim        // Pretend the type of the symbol is the true dynamic type.
1248245431Sdim        // (This will at least be self-consistent for the life of the symbol.)
1249245431Sdim        Ty = SR->getSymbol()->getType()->getPointeeType();
1250252723Sdim        RootIsSymbolic = true;
1251245431Sdim      }
1252245431Sdim
1253245431Sdim      const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
1254245431Sdim      if (!Child) {
1255245431Sdim        // We cannot compute the offset of the base class.
1256245431Sdim        SymbolicOffsetBase = R;
1257245431Sdim      }
1258245431Sdim
1259252723Sdim      if (RootIsSymbolic) {
1260252723Sdim        // Base layers on symbolic regions may not be type-correct.
1261252723Sdim        // Double-check the inheritance here, and revert to a symbolic offset
1262252723Sdim        // if it's invalid (e.g. due to a reinterpret_cast).
1263252723Sdim        if (BOR->isVirtual()) {
1264252723Sdim          if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
1265252723Sdim            SymbolicOffsetBase = R;
1266252723Sdim        } else {
1267252723Sdim          if (!isImmediateBase(Child, BOR->getDecl()))
1268252723Sdim            SymbolicOffsetBase = R;
1269252723Sdim        }
1270252723Sdim      }
1271252723Sdim
1272245431Sdim      // Don't bother calculating precise offsets if we already have a
1273245431Sdim      // symbolic offset somewhere in the chain.
1274245431Sdim      if (SymbolicOffsetBase)
1275245431Sdim        continue;
1276245431Sdim
1277252723Sdim      CharUnits BaseOffset;
1278245431Sdim      const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child);
1279252723Sdim      if (BOR->isVirtual())
1280252723Sdim        BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl());
1281245431Sdim      else
1282252723Sdim        BaseOffset = Layout.getBaseClassOffset(BOR->getDecl());
1283245431Sdim
1284245431Sdim      // The base offset is in chars, not in bits.
1285245431Sdim      Offset += BaseOffset.getQuantity() * getContext().getCharWidth();
1286245431Sdim      break;
1287245431Sdim    }
1288218887Sdim    case ElementRegionKind: {
1289218887Sdim      const ElementRegion *ER = cast<ElementRegion>(R);
1290245431Sdim      R = ER->getSuperRegion();
1291245431Sdim
1292218887Sdim      QualType EleTy = ER->getValueType();
1293245431Sdim      if (!IsCompleteType(getContext(), EleTy)) {
1294245431Sdim        // We cannot compute the offset of the base class.
1295245431Sdim        SymbolicOffsetBase = R;
1296245431Sdim        continue;
1297245431Sdim      }
1298218887Sdim
1299218887Sdim      SVal Index = ER->getIndex();
1300252723Sdim      if (Optional<nonloc::ConcreteInt> CI =
1301252723Sdim              Index.getAs<nonloc::ConcreteInt>()) {
1302245431Sdim        // Don't bother calculating precise offsets if we already have a
1303245431Sdim        // symbolic offset somewhere in the chain.
1304245431Sdim        if (SymbolicOffsetBase)
1305245431Sdim          continue;
1306245431Sdim
1307218887Sdim        int64_t i = CI->getValue().getSExtValue();
1308245431Sdim        // This type size is in bits.
1309245431Sdim        Offset += i * getContext().getTypeSize(EleTy);
1310218887Sdim      } else {
1311218887Sdim        // We cannot compute offset for non-concrete index.
1312245431Sdim        SymbolicOffsetBase = R;
1313218887Sdim      }
1314218887Sdim      break;
1315218887Sdim    }
1316218887Sdim    case FieldRegionKind: {
1317218887Sdim      const FieldRegion *FR = cast<FieldRegion>(R);
1318245431Sdim      R = FR->getSuperRegion();
1319245431Sdim
1320218887Sdim      const RecordDecl *RD = FR->getDecl()->getParent();
1321245431Sdim      if (RD->isUnion() || !RD->isCompleteDefinition()) {
1322218887Sdim        // We cannot compute offset for incomplete type.
1323245431Sdim        // For unions, we could treat everything as offset 0, but we'd rather
1324245431Sdim        // treat each field as a symbolic offset so they aren't stored on top
1325245431Sdim        // of each other, since we depend on things in typed regions actually
1326245431Sdim        // matching their types.
1327245431Sdim        SymbolicOffsetBase = R;
1328245431Sdim      }
1329245431Sdim
1330245431Sdim      // Don't bother calculating precise offsets if we already have a
1331245431Sdim      // symbolic offset somewhere in the chain.
1332245431Sdim      if (SymbolicOffsetBase)
1333245431Sdim        continue;
1334245431Sdim
1335218887Sdim      // Get the field number.
1336218887Sdim      unsigned idx = 0;
1337218887Sdim      for (RecordDecl::field_iterator FI = RD->field_begin(),
1338218887Sdim             FE = RD->field_end(); FI != FE; ++FI, ++idx)
1339218887Sdim        if (FR->getDecl() == *FI)
1340218887Sdim          break;
1341218887Sdim
1342218887Sdim      const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
1343218887Sdim      // This is offset in bits.
1344218887Sdim      Offset += Layout.getFieldOffset(idx);
1345218887Sdim      break;
1346218887Sdim    }
1347218887Sdim    }
1348218887Sdim  }
1349218887Sdim
1350218887Sdim Finish:
1351245431Sdim  if (SymbolicOffsetBase)
1352245431Sdim    return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
1353218887Sdim  return RegionOffset(R, Offset);
1354218887Sdim}
1355218887Sdim
1356218887Sdim//===----------------------------------------------------------------------===//
1357218887Sdim// BlockDataRegion
1358218887Sdim//===----------------------------------------------------------------------===//
1359218887Sdim
1360252723Sdimstd::pair<const VarRegion *, const VarRegion *>
1361252723SdimBlockDataRegion::getCaptureRegions(const VarDecl *VD) {
1362252723Sdim  MemRegionManager &MemMgr = *getMemRegionManager();
1363252723Sdim  const VarRegion *VR = 0;
1364252723Sdim  const VarRegion *OriginalVR = 0;
1365252723Sdim
1366252723Sdim  if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage()) {
1367252723Sdim    VR = MemMgr.getVarRegion(VD, this);
1368252723Sdim    OriginalVR = MemMgr.getVarRegion(VD, LC);
1369252723Sdim  }
1370252723Sdim  else {
1371252723Sdim    if (LC) {
1372252723Sdim      VR = MemMgr.getVarRegion(VD, LC);
1373252723Sdim      OriginalVR = VR;
1374252723Sdim    }
1375252723Sdim    else {
1376252723Sdim      VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
1377252723Sdim      OriginalVR = MemMgr.getVarRegion(VD, LC);
1378252723Sdim    }
1379252723Sdim  }
1380252723Sdim  return std::make_pair(VR, OriginalVR);
1381252723Sdim}
1382252723Sdim
1383218887Sdimvoid BlockDataRegion::LazyInitializeReferencedVars() {
1384218887Sdim  if (ReferencedVars)
1385218887Sdim    return;
1386218887Sdim
1387235633Sdim  AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext();
1388235633Sdim  AnalysisDeclContext::referenced_decls_iterator I, E;
1389218887Sdim  llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
1390218887Sdim
1391218887Sdim  if (I == E) {
1392218887Sdim    ReferencedVars = (void*) 0x1;
1393218887Sdim    return;
1394218887Sdim  }
1395218887Sdim
1396218887Sdim  MemRegionManager &MemMgr = *getMemRegionManager();
1397218887Sdim  llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
1398218887Sdim  BumpVectorContext BC(A);
1399218887Sdim
1400218887Sdim  typedef BumpVector<const MemRegion*> VarVec;
1401218887Sdim  VarVec *BV = (VarVec*) A.Allocate<VarVec>();
1402218887Sdim  new (BV) VarVec(BC, E - I);
1403245431Sdim  VarVec *BVOriginal = (VarVec*) A.Allocate<VarVec>();
1404245431Sdim  new (BVOriginal) VarVec(BC, E - I);
1405218887Sdim
1406218887Sdim  for ( ; I != E; ++I) {
1407218887Sdim    const VarRegion *VR = 0;
1408245431Sdim    const VarRegion *OriginalVR = 0;
1409252723Sdim    llvm::tie(VR, OriginalVR) = getCaptureRegions(*I);
1410218887Sdim    assert(VR);
1411245431Sdim    assert(OriginalVR);
1412218887Sdim    BV->push_back(VR, BC);
1413245431Sdim    BVOriginal->push_back(OriginalVR, BC);
1414218887Sdim  }
1415218887Sdim
1416218887Sdim  ReferencedVars = BV;
1417245431Sdim  OriginalVars = BVOriginal;
1418218887Sdim}
1419218887Sdim
1420218887SdimBlockDataRegion::referenced_vars_iterator
1421218887SdimBlockDataRegion::referenced_vars_begin() const {
1422218887Sdim  const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1423218887Sdim
1424218887Sdim  BumpVector<const MemRegion*> *Vec =
1425218887Sdim    static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
1426218887Sdim
1427245431Sdim  if (Vec == (void*) 0x1)
1428245431Sdim    return BlockDataRegion::referenced_vars_iterator(0, 0);
1429245431Sdim
1430245431Sdim  BumpVector<const MemRegion*> *VecOriginal =
1431245431Sdim    static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
1432245431Sdim
1433245431Sdim  return BlockDataRegion::referenced_vars_iterator(Vec->begin(),
1434245431Sdim                                                   VecOriginal->begin());
1435218887Sdim}
1436218887Sdim
1437218887SdimBlockDataRegion::referenced_vars_iterator
1438218887SdimBlockDataRegion::referenced_vars_end() const {
1439218887Sdim  const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1440218887Sdim
1441218887Sdim  BumpVector<const MemRegion*> *Vec =
1442218887Sdim    static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
1443218887Sdim
1444245431Sdim  if (Vec == (void*) 0x1)
1445245431Sdim    return BlockDataRegion::referenced_vars_iterator(0, 0);
1446245431Sdim
1447245431Sdim  BumpVector<const MemRegion*> *VecOriginal =
1448245431Sdim    static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
1449245431Sdim
1450245431Sdim  return BlockDataRegion::referenced_vars_iterator(Vec->end(),
1451245431Sdim                                                   VecOriginal->end());
1452218887Sdim}
1453252723Sdim
1454252723Sdimconst VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const {
1455252723Sdim  for (referenced_vars_iterator I = referenced_vars_begin(),
1456252723Sdim                                E = referenced_vars_end();
1457252723Sdim       I != E; ++I) {
1458252723Sdim    if (I.getCapturedRegion() == R)
1459252723Sdim      return I.getOriginalRegion();
1460252723Sdim  }
1461252723Sdim  return 0;
1462252723Sdim}
1463263509Sdim
1464263509Sdim//===----------------------------------------------------------------------===//
1465263509Sdim// RegionAndSymbolInvalidationTraits
1466263509Sdim//===----------------------------------------------------------------------===//
1467263509Sdim
1468263509Sdimvoid RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym,
1469263509Sdim                                                 InvalidationKinds IK) {
1470263509Sdim  SymTraitsMap[Sym] |= IK;
1471263509Sdim}
1472263509Sdim
1473263509Sdimvoid RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR,
1474263509Sdim                                                 InvalidationKinds IK) {
1475263509Sdim  assert(MR);
1476263509Sdim  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
1477263509Sdim    setTrait(SR->getSymbol(), IK);
1478263509Sdim  else
1479263509Sdim    MRTraitsMap[MR] |= IK;
1480263509Sdim}
1481263509Sdim
1482263509Sdimbool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym,
1483263509Sdim                                                 InvalidationKinds IK) {
1484263509Sdim  const_symbol_iterator I = SymTraitsMap.find(Sym);
1485263509Sdim  if (I != SymTraitsMap.end())
1486263509Sdim    return I->second & IK;
1487263509Sdim
1488263509Sdim  return false;
1489263509Sdim}
1490263509Sdim
1491263509Sdimbool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR,
1492263509Sdim                                                 InvalidationKinds IK) {
1493263509Sdim  if (!MR)
1494263509Sdim    return false;
1495263509Sdim
1496263509Sdim  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
1497263509Sdim    return hasTrait(SR->getSymbol(), IK);
1498263509Sdim
1499263509Sdim  const_region_iterator I = MRTraitsMap.find(MR);
1500263509Sdim  if (I != MRTraitsMap.end())
1501263509Sdim    return I->second & IK;
1502263509Sdim
1503263509Sdim  return false;
1504263509Sdim}
1505