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"
17249423Sdim#include "clang/AST/Attr.h"
18218887Sdim#include "clang/AST/CharUnits.h"
19234353Sdim#include "clang/AST/DeclObjC.h"
20218887Sdim#include "clang/AST/RecordLayout.h"
21249423Sdim#include "clang/Analysis/AnalysisContext.h"
22249423Sdim#include "clang/Analysis/Support/BumpVector.h"
23234353Sdim#include "clang/Basic/SourceManager.h"
24249423Sdim#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);
44226633Sdim  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);
62226633Sdim  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);
83226633Sdim  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);
102226633Sdim  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);
121226633Sdim  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
183239462SdimDefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const {
184226633Sdim  ASTContext &Ctx = svalBuilder.getContext();
185218887Sdim  QualType T = getDesugaredValueType(Ctx);
186218887Sdim
187218887Sdim  if (isa<VariableArrayType>(T))
188218887Sdim    return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
189263508Sdim  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 {
198249423Sdim  // Force callers to deal with bitfields explicitly.
199249423Sdim  if (getDecl()->isBitField())
200249423Sdim    return UnknownVal();
201249423Sdim
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
229234353SdimObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg)
230234353Sdim  : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
231234353Sdim
232234353Sdimconst ObjCIvarDecl *ObjCIvarRegion::getDecl() const {
233234353Sdim  return cast<ObjCIvarDecl>(D);
234234353Sdim}
235234353Sdim
236234353SdimQualType ObjCIvarRegion::getValueType() const {
237234353Sdim  return getDecl()->getType();
238234353Sdim}
239234353Sdim
240218887SdimQualType CXXBaseObjectRegion::getValueType() const {
241249423Sdim  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
270234353Sdimvoid ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
271234353Sdim                                     const ObjCStringLiteral* Str,
272234353Sdim                                     const MemRegion* superRegion) {
273234353Sdim  ID.AddInteger((unsigned) ObjCStringRegionKind);
274234353Sdim  ID.AddPointer(Str);
275234353Sdim  ID.AddPointer(superRegion);
276234353Sdim}
277234353Sdim
278218887Sdimvoid AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
279226633Sdim                                 const Expr *Ex, unsigned cnt,
280249423Sdim                                 const MemRegion *superRegion) {
281218887Sdim  ID.AddInteger((unsigned) AllocaRegionKind);
282218887Sdim  ID.AddPointer(Ex);
283218887Sdim  ID.AddInteger(cnt);
284249423Sdim  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,
296226633Sdim                                          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
315234353Sdimvoid ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
316234353Sdim                                   const ObjCIvarDecl *ivd,
317234353Sdim                                   const MemRegion* superRegion) {
318234353Sdim  DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
319234353Sdim}
320234353Sdim
321226633Sdimvoid 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,
361243830Sdim                                       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,
373234353Sdim                                    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,
386263508Sdim                                    unsigned BlkCount,
387218887Sdim                                    const MemRegion *sReg) {
388218887Sdim  ID.AddInteger(MemRegion::BlockDataRegionKind);
389218887Sdim  ID.AddPointer(BC);
390218887Sdim  ID.AddPointer(LC);
391263508Sdim  ID.AddInteger(BlkCount);
392218887Sdim  ID.AddPointer(sReg);
393218887Sdim}
394218887Sdim
395218887Sdimvoid BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
396263508Sdim  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,
411249423Sdim                                        const CXXRecordDecl *RD,
412249423Sdim                                        bool IsVirtual,
413249423Sdim                                        const MemRegion *SReg) {
414249423Sdim  ID.AddPointer(RD);
415249423Sdim  ID.AddBoolean(IsVirtual);
416249423Sdim  ID.AddPointer(SReg);
417218887Sdim}
418218887Sdim
419218887Sdimvoid CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
420249423Sdim  ProfileRegion(ID, getDecl(), isVirtual(), superRegion);
421218887Sdim}
422218887Sdim
423218887Sdim//===----------------------------------------------------------------------===//
424234353Sdim// Region anchors.
425234353Sdim//===----------------------------------------------------------------------===//
426234353Sdim
427234353Sdimvoid GlobalsSpaceRegion::anchor() { }
428234353Sdimvoid HeapSpaceRegion::anchor() { }
429234353Sdimvoid UnknownSpaceRegion::anchor() { }
430234353Sdimvoid StackLocalsSpaceRegion::anchor() { }
431234353Sdimvoid StackArgumentsSpaceRegion::anchor() { }
432234353Sdimvoid TypedRegion::anchor() { }
433234353Sdimvoid TypedValueRegion::anchor() { }
434234353Sdimvoid CodeTextRegion::anchor() { }
435234353Sdimvoid SubRegion::anchor() { }
436234353Sdim
437234353Sdim//===----------------------------------------------------------------------===//
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
452226633Sdimvoid MemRegion::dumpToStream(raw_ostream &os) const {
453218887Sdim  os << "<Unknown Region>";
454218887Sdim}
455218887Sdim
456226633Sdimvoid AllocaRegion::dumpToStream(raw_ostream &os) const {
457243830Sdim  os << "alloca{" << (const void*) Ex << ',' << Cnt << '}';
458218887Sdim}
459218887Sdim
460226633Sdimvoid FunctionTextRegion::dumpToStream(raw_ostream &os) const {
461218887Sdim  os << "code{" << getDecl()->getDeclName().getAsString() << '}';
462218887Sdim}
463218887Sdim
464226633Sdimvoid BlockTextRegion::dumpToStream(raw_ostream &os) const {
465243830Sdim  os << "block_code{" << (const void*) this << '}';
466218887Sdim}
467218887Sdim
468226633Sdimvoid BlockDataRegion::dumpToStream(raw_ostream &os) const {
469263508Sdim  os << "block_data{" << BC;
470263508Sdim  os << "; ";
471263508Sdim  for (BlockDataRegion::referenced_vars_iterator
472263508Sdim         I = referenced_vars_begin(),
473263508Sdim         E = referenced_vars_end(); I != E; ++I)
474263508Sdim    os << "(" << I.getCapturedRegion() << "," <<
475263508Sdim                 I.getOriginalRegion() << ") ";
476263508Sdim  os << '}';
477218887Sdim}
478218887Sdim
479226633Sdimvoid CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {
480218887Sdim  // FIXME: More elaborate pretty-printing.
481243830Sdim  os << "{ " << (const void*) CL <<  " }";
482218887Sdim}
483218887Sdim
484226633Sdimvoid CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {
485226633Sdim  os << "temp_object{" << getValueType().getAsString() << ','
486243830Sdim     << (const void*) Ex << '}';
487218887Sdim}
488218887Sdim
489226633Sdimvoid CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
490249423Sdim  os << "base{" << superRegion << ',' << getDecl()->getName() << '}';
491218887Sdim}
492218887Sdim
493226633Sdimvoid CXXThisRegion::dumpToStream(raw_ostream &os) const {
494218887Sdim  os << "this";
495218887Sdim}
496218887Sdim
497226633Sdimvoid ElementRegion::dumpToStream(raw_ostream &os) const {
498218887Sdim  os << "element{" << superRegion << ','
499218887Sdim     << Index << ',' << getElementType().getAsString() << '}';
500218887Sdim}
501218887Sdim
502226633Sdimvoid FieldRegion::dumpToStream(raw_ostream &os) const {
503226633Sdim  os << superRegion << "->" << *getDecl();
504218887Sdim}
505218887Sdim
506226633Sdimvoid ObjCIvarRegion::dumpToStream(raw_ostream &os) const {
507226633Sdim  os << "ivar{" << superRegion << ',' << *getDecl() << '}';
508218887Sdim}
509218887Sdim
510226633Sdimvoid StringRegion::dumpToStream(raw_ostream &os) const {
511234353Sdim  Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts()));
512218887Sdim}
513218887Sdim
514234353Sdimvoid ObjCStringRegion::dumpToStream(raw_ostream &os) const {
515234353Sdim  Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts()));
516234353Sdim}
517234353Sdim
518226633Sdimvoid SymbolicRegion::dumpToStream(raw_ostream &os) const {
519218887Sdim  os << "SymRegion{" << sym << '}';
520218887Sdim}
521218887Sdim
522226633Sdimvoid VarRegion::dumpToStream(raw_ostream &os) const {
523226633Sdim  os << *cast<VarDecl>(D);
524218887Sdim}
525218887Sdim
526218887Sdimvoid RegionRawOffset::dump() const {
527218887Sdim  dumpToStream(llvm::errs());
528218887Sdim}
529218887Sdim
530226633Sdimvoid RegionRawOffset::dumpToStream(raw_ostream &os) const {
531218887Sdim  os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}';
532218887Sdim}
533218887Sdim
534226633Sdimvoid StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const {
535218887Sdim  os << "StaticGlobalsMemSpace{" << CR << '}';
536218887Sdim}
537218887Sdim
538234353Sdimvoid GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const {
539234353Sdim  os << "GlobalInternalSpaceRegion";
540234353Sdim}
541234353Sdim
542234353Sdimvoid GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const {
543234353Sdim  os << "GlobalSystemSpaceRegion";
544234353Sdim}
545234353Sdim
546234353Sdimvoid GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const {
547234353Sdim  os << "GlobalImmutableSpaceRegion";
548234353Sdim}
549234353Sdim
550239462Sdimvoid HeapSpaceRegion::dumpToStream(raw_ostream &os) const {
551239462Sdim  os << "HeapSpaceRegion";
552239462Sdim}
553239462Sdim
554239462Sdimvoid UnknownSpaceRegion::dumpToStream(raw_ostream &os) const {
555239462Sdim  os << "UnknownSpaceRegion";
556239462Sdim}
557239462Sdim
558239462Sdimvoid StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const {
559239462Sdim  os << "StackArgumentsSpaceRegion";
560239462Sdim}
561239462Sdim
562239462Sdimvoid StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const {
563239462Sdim  os << "StackLocalsSpaceRegion";
564239462Sdim}
565239462Sdim
566239462Sdimbool MemRegion::canPrintPretty() const {
567251662Sdim  return canPrintPrettyAsExpr();
568251662Sdim}
569251662Sdim
570251662Sdimbool MemRegion::canPrintPrettyAsExpr() const {
571239462Sdim  return false;
572239462Sdim}
573239462Sdim
574239462Sdimvoid MemRegion::printPretty(raw_ostream &os) const {
575251662Sdim  assert(canPrintPretty() && "This region cannot be printed pretty.");
576251662Sdim  os << "'";
577251662Sdim  printPrettyAsExpr(os);
578251662Sdim  os << "'";
579234353Sdim  return;
580234353Sdim}
581234353Sdim
582251662Sdimvoid MemRegion::printPrettyAsExpr(raw_ostream &os) const {
583251662Sdim  llvm_unreachable("This region cannot be printed pretty.");
584251662Sdim  return;
585251662Sdim}
586251662Sdim
587251662Sdimbool VarRegion::canPrintPrettyAsExpr() const {
588239462Sdim  return true;
589239462Sdim}
590239462Sdim
591251662Sdimvoid VarRegion::printPrettyAsExpr(raw_ostream &os) const {
592234353Sdim  os << getDecl()->getName();
593234353Sdim}
594234353Sdim
595251662Sdimbool ObjCIvarRegion::canPrintPrettyAsExpr() const {
596249423Sdim  return true;
597249423Sdim}
598249423Sdim
599251662Sdimvoid ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const {
600249423Sdim  os << getDecl()->getName();
601249423Sdim}
602249423Sdim
603239462Sdimbool FieldRegion::canPrintPretty() const {
604251662Sdim  return true;
605234353Sdim}
606234353Sdim
607251662Sdimbool FieldRegion::canPrintPrettyAsExpr() const {
608251662Sdim  return superRegion->canPrintPrettyAsExpr();
609251662Sdim}
610251662Sdim
611251662Sdimvoid FieldRegion::printPrettyAsExpr(raw_ostream &os) const {
612251662Sdim  assert(canPrintPrettyAsExpr());
613251662Sdim  superRegion->printPrettyAsExpr(os);
614239462Sdim  os << "." << getDecl()->getName();
615239462Sdim}
616239462Sdim
617251662Sdimvoid FieldRegion::printPretty(raw_ostream &os) const {
618251662Sdim  if (canPrintPrettyAsExpr()) {
619251662Sdim    os << "\'";
620251662Sdim    printPrettyAsExpr(os);
621251662Sdim    os << "'";
622251662Sdim  } else {
623251662Sdim    os << "field " << "\'" << getDecl()->getName() << "'";
624251662Sdim  }
625251662Sdim  return;
626251662Sdim}
627251662Sdim
628251662Sdimbool CXXBaseObjectRegion::canPrintPrettyAsExpr() const {
629251662Sdim  return superRegion->canPrintPrettyAsExpr();
630251662Sdim}
631251662Sdim
632251662Sdimvoid CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
633251662Sdim  superRegion->printPrettyAsExpr(os);
634251662Sdim}
635251662Sdim
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
687234353Sdim*MemRegionManager::getGlobalsRegion(MemRegion::Kind K,
688234353Sdim                                    const CodeTextRegion *CR) {
689234353Sdim  if (!CR) {
690234353Sdim    if (K == MemRegion::GlobalSystemSpaceRegionKind)
691234353Sdim      return LazyAllocate(SystemGlobals);
692234353Sdim    if (K == MemRegion::GlobalImmutableSpaceRegionKind)
693234353Sdim      return LazyAllocate(ImmutableGlobals);
694234353Sdim    assert(K == MemRegion::GlobalInternalSpaceRegionKind);
695234353Sdim    return LazyAllocate(InternalGlobals);
696234353Sdim  }
697218887Sdim
698234353Sdim  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
727234353Sdimconst ObjCStringRegion *
728234353SdimMemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){
729234353Sdim  return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion());
730234353Sdim}
731234353Sdim
732239462Sdim/// Look through a chain of LocationContexts to either find the
733239462Sdim/// StackFrameContext that matches a DeclContext, or find a VarRegion
734239462Sdim/// for a variable captured by a block.
735239462Sdimstatic llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
736239462SdimgetStackOrCaptureRegionForDeclContext(const LocationContext *LC,
737239462Sdim                                      const DeclContext *DC,
738239462Sdim                                      const VarDecl *VD) {
739239462Sdim  while (LC) {
740239462Sdim    if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) {
741239462Sdim      if (cast<DeclContext>(SFC->getDecl()) == DC)
742239462Sdim        return SFC;
743239462Sdim    }
744239462Sdim    if (const BlockInvocationContext *BC =
745239462Sdim        dyn_cast<BlockInvocationContext>(LC)) {
746239462Sdim      const BlockDataRegion *BR =
747239462Sdim        static_cast<const BlockDataRegion*>(BC->getContextData());
748239462Sdim      // FIXME: This can be made more efficient.
749239462Sdim      for (BlockDataRegion::referenced_vars_iterator
750239462Sdim           I = BR->referenced_vars_begin(),
751239462Sdim           E = BR->referenced_vars_end(); I != E; ++I) {
752239462Sdim        if (const VarRegion *VR = dyn_cast<VarRegion>(I.getOriginalRegion()))
753239462Sdim          if (VR->getDecl() == VD)
754239462Sdim            return cast<VarRegion>(I.getCapturedRegion());
755239462Sdim      }
756239462Sdim    }
757239462Sdim
758239462Sdim    LC = LC->getParent();
759239462Sdim  }
760239462Sdim  return (const StackFrameContext*)0;
761239462Sdim}
762239462Sdim
763218887Sdimconst VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
764218887Sdim                                                const LocationContext *LC) {
765218887Sdim  const MemRegion *sReg = 0;
766218887Sdim
767234353Sdim  if (D->hasGlobalStorage() && !D->isStaticLocal()) {
768234353Sdim
769234353Sdim    // First handle the globals defined in system headers.
770234353Sdim    if (C.getSourceManager().isInSystemHeader(D->getLocation())) {
771234353Sdim      // Whitelist the system globals which often DO GET modified, assume the
772234353Sdim      // rest are immutable.
773234353Sdim      if (D->getName().find("errno") != StringRef::npos)
774234353Sdim        sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
775234353Sdim      else
776234353Sdim        sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
777234353Sdim
778234353Sdim    // Treat other globals as GlobalInternal unless they are constants.
779234353Sdim    } else {
780234353Sdim      QualType GQT = D->getType();
781234353Sdim      const Type *GT = GQT.getTypePtrOrNull();
782234353Sdim      // TODO: We could walk the complex types here and see if everything is
783234353Sdim      // constified.
784234353Sdim      if (GT && GQT.isConstQualified() && GT->isArithmeticType())
785234353Sdim        sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
786234353Sdim      else
787234353Sdim        sReg = getGlobalsRegion();
788234353Sdim    }
789234353Sdim
790234353Sdim  // Finally handle static locals.
791234353Sdim  } 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();
795239462Sdim    llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
796239462Sdim      getStackOrCaptureRegionForDeclContext(LC, DC, D);
797239462Sdim
798239462Sdim    if (V.is<const VarRegion*>())
799239462Sdim      return V.get<const VarRegion*>();
800239462Sdim
801239462Sdim    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());
813243830Sdim        const Decl *STCD = STC->getDecl();
814243830Sdim        if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
815234353Sdim          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
816243830Sdim                                  getFunctionTextRegion(cast<NamedDecl>(STCD)));
817243830Sdim        else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
818263508Sdim          // FIXME: The fallback type here is totally bogus -- though it should
819263508Sdim          // never be queried, it will prevent uniquing with the real
820263508Sdim          // BlockTextRegion. Ideally we'd fix the AST so that we always had a
821263508Sdim          // signature.
822263508Sdim          QualType T;
823263508Sdim          if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
824263508Sdim            T = TSI->getType();
825263508Sdim          else
826263508Sdim            T = getContext().getFunctionNoProtoType(getContext().VoidTy);
827263508Sdim
828218887Sdim          const BlockTextRegion *BTR =
829263508Sdim            getBlockTextRegion(BD, C.getCanonicalType(T),
830263508Sdim                               STC->getAnalysisDeclContext());
831234353Sdim          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
832234353Sdim                                  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,
851263508Sdim                                     const LocationContext *LC,
852263508Sdim                                     unsigned blockCount) {
853218887Sdim  const MemRegion *sReg = 0;
854234353Sdim  const BlockDecl *BD = BC->getDecl();
855234353Sdim  if (!BD->hasCaptures()) {
856234353Sdim    // This handles 'static' blocks.
857234353Sdim    sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
858218887Sdim  }
859218887Sdim  else {
860234353Sdim    if (LC) {
861234353Sdim      // FIXME: Once we implement scope handling, we want the parent region
862234353Sdim      // to be the scope.
863234353Sdim      const StackFrameContext *STC = LC->getCurrentStackFrame();
864234353Sdim      assert(STC);
865234353Sdim      sReg = getStackLocalsRegion(STC);
866234353Sdim    }
867234353Sdim    else {
868234353Sdim      // We allow 'LC' to be NULL for cases where want BlockDataRegions
869234353Sdim      // without context-sensitivity.
870234353Sdim      sReg = getUnknownRegion();
871234353Sdim    }
872218887Sdim  }
873218887Sdim
874263508Sdim  return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg);
875218887Sdim}
876218887Sdim
877263508Sdimconst CXXTempObjectRegion *
878263508SdimMemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) {
879263508Sdim  return getSubRegion<CXXTempObjectRegion>(
880263508Sdim      Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, NULL));
881263508Sdim}
882263508Sdim
883218887Sdimconst CompoundLiteralRegion*
884226633SdimMemRegionManager::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,
903226633Sdim                                   ASTContext &Ctx){
904218887Sdim
905218887Sdim  QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
906218887Sdim
907218887Sdim  llvm::FoldingSetNodeID ID;
908218887Sdim  ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
909218887Sdim
910226633Sdim  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 *
924243830SdimMemRegionManager::getFunctionTextRegion(const NamedDecl *FD) {
925218887Sdim  return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
926218887Sdim}
927218887Sdim
928218887Sdimconst BlockTextRegion *
929218887SdimMemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
930234353Sdim                                     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
940239462Sdimconst SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {
941239462Sdim  return getSubRegion<SymbolicRegion>(Sym, getHeapRegion());
942239462Sdim}
943239462Sdim
944218887Sdimconst FieldRegion*
945226633SdimMemRegionManager::getFieldRegion(const FieldDecl *d,
946218887Sdim                                 const MemRegion* superRegion){
947218887Sdim  return getSubRegion<FieldRegion>(d, superRegion);
948218887Sdim}
949218887Sdim
950218887Sdimconst ObjCIvarRegion*
951226633SdimMemRegionManager::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
964249423Sdim/// Checks whether \p BaseClass is a valid virtual or direct non-virtual base
965249423Sdim/// class of the type of \p Super.
966249423Sdimstatic bool isValidBaseClass(const CXXRecordDecl *BaseClass,
967249423Sdim                             const TypedValueRegion *Super,
968249423Sdim                             bool IsVirtual) {
969249423Sdim  BaseClass = BaseClass->getCanonicalDecl();
970249423Sdim
971249423Sdim  const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl();
972249423Sdim  if (!Class)
973249423Sdim    return true;
974249423Sdim
975249423Sdim  if (IsVirtual)
976249423Sdim    return Class->isVirtuallyDerivedFrom(BaseClass);
977249423Sdim
978249423Sdim  for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
979249423Sdim                                                E = Class->bases_end();
980249423Sdim       I != E; ++I) {
981249423Sdim    if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
982249423Sdim      return true;
983249423Sdim  }
984249423Sdim
985249423Sdim  return false;
986249423Sdim}
987249423Sdim
988218887Sdimconst CXXBaseObjectRegion *
989249423SdimMemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
990249423Sdim                                         const MemRegion *Super,
991249423Sdim                                         bool IsVirtual) {
992249423Sdim  if (isa<TypedValueRegion>(Super)) {
993249423Sdim    assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual));
994263508Sdim    (void)&isValidBaseClass;
995239462Sdim
996249423Sdim    if (IsVirtual) {
997249423Sdim      // Virtual base regions should not be layered, since the layout rules
998249423Sdim      // are different.
999249423Sdim      while (const CXXBaseObjectRegion *Base =
1000249423Sdim               dyn_cast<CXXBaseObjectRegion>(Super)) {
1001249423Sdim        Super = Base->getSuperRegion();
1002239462Sdim      }
1003249423Sdim      assert(Super && !isa<MemSpaceRegion>(Super));
1004239462Sdim    }
1005239462Sdim  }
1006239462Sdim
1007249423Sdim  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*
1021226633SdimMemRegionManager::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
1078243830Sdimbool MemRegion::isSubRegionOf(const MemRegion *R) const {
1079243830Sdim  return false;
1080243830Sdim}
1081243830Sdim
1082218887Sdim//===----------------------------------------------------------------------===//
1083218887Sdim// View handling.
1084218887Sdim//===----------------------------------------------------------------------===//
1085218887Sdim
1086239462Sdimconst MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const {
1087218887Sdim  const MemRegion *R = this;
1088218887Sdim  while (true) {
1089239462Sdim    switch (R->getKind()) {
1090239462Sdim    case ElementRegionKind: {
1091239462Sdim      const ElementRegion *ER = cast<ElementRegion>(R);
1092239462Sdim      if (!ER->getIndex().isZeroConstant())
1093239462Sdim        return R;
1094239462Sdim      R = ER->getSuperRegion();
1095239462Sdim      break;
1096218887Sdim    }
1097239462Sdim    case CXXBaseObjectRegionKind:
1098239462Sdim      if (!StripBaseCasts)
1099239462Sdim        return R;
1100239462Sdim      R = cast<CXXBaseObjectRegion>(R)->getSuperRegion();
1101239462Sdim      break;
1102239462Sdim    default:
1103239462Sdim      return R;
1104239462Sdim    }
1105218887Sdim  }
1106218887Sdim}
1107218887Sdim
1108251662Sdimconst SymbolicRegion *MemRegion::getSymbolicBase() const {
1109251662Sdim  const SubRegion *SubR = dyn_cast<SubRegion>(this);
1110251662Sdim
1111251662Sdim  while (SubR) {
1112251662Sdim    if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR))
1113251662Sdim      return SymR;
1114251662Sdim    SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
1115251662Sdim  }
1116251662Sdim  return 0;
1117251662Sdim}
1118251662Sdim
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();
1143249423Sdim    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
1172249423Sdim
1173249423Sdim/// Returns true if \p Base is an immediate base class of \p Child
1174249423Sdimstatic bool isImmediateBase(const CXXRecordDecl *Child,
1175249423Sdim                            const CXXRecordDecl *Base) {
1176249423Sdim  // Note that we do NOT canonicalize the base class here, because
1177249423Sdim  // ASTRecordLayout doesn't either. If that leads us down the wrong path,
1178249423Sdim  // so be it; at least we won't crash.
1179249423Sdim  for (CXXRecordDecl::base_class_const_iterator I = Child->bases_begin(),
1180249423Sdim                                                E = Child->bases_end();
1181249423Sdim       I != E; ++I) {
1182249423Sdim    if (I->getType()->getAsCXXRecordDecl() == Base)
1183249423Sdim      return true;
1184249423Sdim  }
1185249423Sdim
1186249423Sdim  return false;
1187249423Sdim}
1188249423Sdim
1189218887SdimRegionOffset MemRegion::getAsOffset() const {
1190218887Sdim  const MemRegion *R = this;
1191239462Sdim  const MemRegion *SymbolicOffsetBase = 0;
1192218887Sdim  int64_t Offset = 0;
1193218887Sdim
1194218887Sdim  while (1) {
1195218887Sdim    switch (R->getKind()) {
1196249423Sdim    case GenericMemSpaceRegionKind:
1197249423Sdim    case StackLocalsSpaceRegionKind:
1198249423Sdim    case StackArgumentsSpaceRegionKind:
1199249423Sdim    case HeapSpaceRegionKind:
1200249423Sdim    case UnknownSpaceRegionKind:
1201249423Sdim    case StaticGlobalSpaceRegionKind:
1202249423Sdim    case GlobalInternalSpaceRegionKind:
1203249423Sdim    case GlobalSystemSpaceRegionKind:
1204249423Sdim    case GlobalImmutableSpaceRegionKind:
1205249423Sdim      // Stores can bind directly to a region space to set a default value.
1206249423Sdim      assert(Offset == 0 && !SymbolicOffsetBase);
1207249423Sdim      goto Finish;
1208239462Sdim
1209249423Sdim    case FunctionTextRegionKind:
1210249423Sdim    case BlockTextRegionKind:
1211249423Sdim    case BlockDataRegionKind:
1212249423Sdim      // These will never have bindings, but may end up having values requested
1213249423Sdim      // if the user does some strange casting.
1214249423Sdim      if (Offset != 0)
1215249423Sdim        SymbolicOffsetBase = R;
1216249423Sdim      goto Finish;
1217249423Sdim
1218218887Sdim    case SymbolicRegionKind:
1219218887Sdim    case AllocaRegionKind:
1220218887Sdim    case CompoundLiteralRegionKind:
1221218887Sdim    case CXXThisRegionKind:
1222218887Sdim    case StringRegionKind:
1223249423Sdim    case ObjCStringRegionKind:
1224218887Sdim    case VarRegionKind:
1225218887Sdim    case CXXTempObjectRegionKind:
1226249423Sdim      // Usual base regions.
1227218887Sdim      goto Finish;
1228239462Sdim
1229239462Sdim    case ObjCIvarRegionKind:
1230239462Sdim      // This is a little strange, but it's a compromise between
1231239462Sdim      // ObjCIvarRegions having unknown compile-time offsets (when using the
1232239462Sdim      // non-fragile runtime) and yet still being distinct, non-overlapping
1233239462Sdim      // regions. Thus we treat them as "like" base regions for the purposes
1234239462Sdim      // of computing offsets.
1235239462Sdim      goto Finish;
1236239462Sdim
1237239462Sdim    case CXXBaseObjectRegionKind: {
1238239462Sdim      const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R);
1239239462Sdim      R = BOR->getSuperRegion();
1240239462Sdim
1241239462Sdim      QualType Ty;
1242249423Sdim      bool RootIsSymbolic = false;
1243239462Sdim      if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) {
1244239462Sdim        Ty = TVR->getDesugaredValueType(getContext());
1245239462Sdim      } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
1246239462Sdim        // If our base region is symbolic, we don't know what type it really is.
1247239462Sdim        // Pretend the type of the symbol is the true dynamic type.
1248239462Sdim        // (This will at least be self-consistent for the life of the symbol.)
1249243830Sdim        Ty = SR->getSymbol()->getType()->getPointeeType();
1250249423Sdim        RootIsSymbolic = true;
1251239462Sdim      }
1252239462Sdim
1253239462Sdim      const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
1254239462Sdim      if (!Child) {
1255239462Sdim        // We cannot compute the offset of the base class.
1256239462Sdim        SymbolicOffsetBase = R;
1257239462Sdim      }
1258239462Sdim
1259249423Sdim      if (RootIsSymbolic) {
1260249423Sdim        // Base layers on symbolic regions may not be type-correct.
1261249423Sdim        // Double-check the inheritance here, and revert to a symbolic offset
1262249423Sdim        // if it's invalid (e.g. due to a reinterpret_cast).
1263249423Sdim        if (BOR->isVirtual()) {
1264249423Sdim          if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
1265249423Sdim            SymbolicOffsetBase = R;
1266249423Sdim        } else {
1267249423Sdim          if (!isImmediateBase(Child, BOR->getDecl()))
1268249423Sdim            SymbolicOffsetBase = R;
1269249423Sdim        }
1270249423Sdim      }
1271249423Sdim
1272239462Sdim      // Don't bother calculating precise offsets if we already have a
1273239462Sdim      // symbolic offset somewhere in the chain.
1274239462Sdim      if (SymbolicOffsetBase)
1275239462Sdim        continue;
1276239462Sdim
1277249423Sdim      CharUnits BaseOffset;
1278239462Sdim      const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child);
1279249423Sdim      if (BOR->isVirtual())
1280249423Sdim        BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl());
1281239462Sdim      else
1282249423Sdim        BaseOffset = Layout.getBaseClassOffset(BOR->getDecl());
1283239462Sdim
1284239462Sdim      // The base offset is in chars, not in bits.
1285239462Sdim      Offset += BaseOffset.getQuantity() * getContext().getCharWidth();
1286239462Sdim      break;
1287239462Sdim    }
1288218887Sdim    case ElementRegionKind: {
1289218887Sdim      const ElementRegion *ER = cast<ElementRegion>(R);
1290239462Sdim      R = ER->getSuperRegion();
1291239462Sdim
1292218887Sdim      QualType EleTy = ER->getValueType();
1293239462Sdim      if (!IsCompleteType(getContext(), EleTy)) {
1294239462Sdim        // We cannot compute the offset of the base class.
1295239462Sdim        SymbolicOffsetBase = R;
1296239462Sdim        continue;
1297239462Sdim      }
1298218887Sdim
1299218887Sdim      SVal Index = ER->getIndex();
1300249423Sdim      if (Optional<nonloc::ConcreteInt> CI =
1301249423Sdim              Index.getAs<nonloc::ConcreteInt>()) {
1302239462Sdim        // Don't bother calculating precise offsets if we already have a
1303239462Sdim        // symbolic offset somewhere in the chain.
1304239462Sdim        if (SymbolicOffsetBase)
1305239462Sdim          continue;
1306239462Sdim
1307218887Sdim        int64_t i = CI->getValue().getSExtValue();
1308239462Sdim        // This type size is in bits.
1309239462Sdim        Offset += i * getContext().getTypeSize(EleTy);
1310218887Sdim      } else {
1311218887Sdim        // We cannot compute offset for non-concrete index.
1312239462Sdim        SymbolicOffsetBase = R;
1313218887Sdim      }
1314218887Sdim      break;
1315218887Sdim    }
1316218887Sdim    case FieldRegionKind: {
1317218887Sdim      const FieldRegion *FR = cast<FieldRegion>(R);
1318239462Sdim      R = FR->getSuperRegion();
1319239462Sdim
1320218887Sdim      const RecordDecl *RD = FR->getDecl()->getParent();
1321243830Sdim      if (RD->isUnion() || !RD->isCompleteDefinition()) {
1322218887Sdim        // We cannot compute offset for incomplete type.
1323243830Sdim        // For unions, we could treat everything as offset 0, but we'd rather
1324243830Sdim        // treat each field as a symbolic offset so they aren't stored on top
1325243830Sdim        // of each other, since we depend on things in typed regions actually
1326243830Sdim        // matching their types.
1327239462Sdim        SymbolicOffsetBase = R;
1328239462Sdim      }
1329239462Sdim
1330239462Sdim      // Don't bother calculating precise offsets if we already have a
1331239462Sdim      // symbolic offset somewhere in the chain.
1332239462Sdim      if (SymbolicOffsetBase)
1333239462Sdim        continue;
1334239462Sdim
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:
1351239462Sdim  if (SymbolicOffsetBase)
1352239462Sdim    return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
1353218887Sdim  return RegionOffset(R, Offset);
1354218887Sdim}
1355218887Sdim
1356218887Sdim//===----------------------------------------------------------------------===//
1357218887Sdim// BlockDataRegion
1358218887Sdim//===----------------------------------------------------------------------===//
1359218887Sdim
1360249423Sdimstd::pair<const VarRegion *, const VarRegion *>
1361249423SdimBlockDataRegion::getCaptureRegions(const VarDecl *VD) {
1362249423Sdim  MemRegionManager &MemMgr = *getMemRegionManager();
1363249423Sdim  const VarRegion *VR = 0;
1364249423Sdim  const VarRegion *OriginalVR = 0;
1365249423Sdim
1366249423Sdim  if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage()) {
1367249423Sdim    VR = MemMgr.getVarRegion(VD, this);
1368249423Sdim    OriginalVR = MemMgr.getVarRegion(VD, LC);
1369249423Sdim  }
1370249423Sdim  else {
1371249423Sdim    if (LC) {
1372249423Sdim      VR = MemMgr.getVarRegion(VD, LC);
1373249423Sdim      OriginalVR = VR;
1374249423Sdim    }
1375249423Sdim    else {
1376249423Sdim      VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
1377249423Sdim      OriginalVR = MemMgr.getVarRegion(VD, LC);
1378249423Sdim    }
1379249423Sdim  }
1380249423Sdim  return std::make_pair(VR, OriginalVR);
1381249423Sdim}
1382249423Sdim
1383218887Sdimvoid BlockDataRegion::LazyInitializeReferencedVars() {
1384218887Sdim  if (ReferencedVars)
1385218887Sdim    return;
1386218887Sdim
1387234353Sdim  AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext();
1388234353Sdim  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);
1403239462Sdim  VarVec *BVOriginal = (VarVec*) A.Allocate<VarVec>();
1404239462Sdim  new (BVOriginal) VarVec(BC, E - I);
1405218887Sdim
1406218887Sdim  for ( ; I != E; ++I) {
1407218887Sdim    const VarRegion *VR = 0;
1408239462Sdim    const VarRegion *OriginalVR = 0;
1409249423Sdim    llvm::tie(VR, OriginalVR) = getCaptureRegions(*I);
1410218887Sdim    assert(VR);
1411239462Sdim    assert(OriginalVR);
1412218887Sdim    BV->push_back(VR, BC);
1413239462Sdim    BVOriginal->push_back(OriginalVR, BC);
1414218887Sdim  }
1415218887Sdim
1416218887Sdim  ReferencedVars = BV;
1417239462Sdim  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
1427239462Sdim  if (Vec == (void*) 0x1)
1428239462Sdim    return BlockDataRegion::referenced_vars_iterator(0, 0);
1429239462Sdim
1430239462Sdim  BumpVector<const MemRegion*> *VecOriginal =
1431239462Sdim    static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
1432239462Sdim
1433239462Sdim  return BlockDataRegion::referenced_vars_iterator(Vec->begin(),
1434239462Sdim                                                   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
1444239462Sdim  if (Vec == (void*) 0x1)
1445239462Sdim    return BlockDataRegion::referenced_vars_iterator(0, 0);
1446239462Sdim
1447239462Sdim  BumpVector<const MemRegion*> *VecOriginal =
1448239462Sdim    static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
1449239462Sdim
1450239462Sdim  return BlockDataRegion::referenced_vars_iterator(Vec->end(),
1451239462Sdim                                                   VecOriginal->end());
1452218887Sdim}
1453249423Sdim
1454249423Sdimconst VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const {
1455249423Sdim  for (referenced_vars_iterator I = referenced_vars_begin(),
1456249423Sdim                                E = referenced_vars_end();
1457249423Sdim       I != E; ++I) {
1458249423Sdim    if (I.getCapturedRegion() == R)
1459249423Sdim      return I.getOriginalRegion();
1460249423Sdim  }
1461249423Sdim  return 0;
1462249423Sdim}
1463263508Sdim
1464263508Sdim//===----------------------------------------------------------------------===//
1465263508Sdim// RegionAndSymbolInvalidationTraits
1466263508Sdim//===----------------------------------------------------------------------===//
1467263508Sdim
1468263508Sdimvoid RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym,
1469263508Sdim                                                 InvalidationKinds IK) {
1470263508Sdim  SymTraitsMap[Sym] |= IK;
1471263508Sdim}
1472263508Sdim
1473263508Sdimvoid RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR,
1474263508Sdim                                                 InvalidationKinds IK) {
1475263508Sdim  assert(MR);
1476263508Sdim  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
1477263508Sdim    setTrait(SR->getSymbol(), IK);
1478263508Sdim  else
1479263508Sdim    MRTraitsMap[MR] |= IK;
1480263508Sdim}
1481263508Sdim
1482263508Sdimbool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym,
1483263508Sdim                                                 InvalidationKinds IK) {
1484263508Sdim  const_symbol_iterator I = SymTraitsMap.find(Sym);
1485263508Sdim  if (I != SymTraitsMap.end())
1486263508Sdim    return I->second & IK;
1487263508Sdim
1488263508Sdim  return false;
1489263508Sdim}
1490263508Sdim
1491263508Sdimbool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR,
1492263508Sdim                                                 InvalidationKinds IK) {
1493263508Sdim  if (!MR)
1494263508Sdim    return false;
1495263508Sdim
1496263508Sdim  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
1497263508Sdim    return hasTrait(SR->getSymbol(), IK);
1498263508Sdim
1499263508Sdim  const_region_iterator I = MRTraitsMap.find(MR);
1500263508Sdim  if (I != MRTraitsMap.end())
1501263508Sdim    return I->second & IK;
1502263508Sdim
1503263508Sdim  return false;
1504263508Sdim}
1505