MemRegion.cpp revision 6dc5c33fd4334ccf4a661c331f86e23829e51d55
1//== MemRegion.cpp - Abstract memory regions for static analysis --*- C++ -*--//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines MemRegion and its subclasses.  MemRegion defines a
11//  partially-typed abstraction of memory useful for path-sensitive dataflow
12//  analyses.
13//
14//===----------------------------------------------------------------------===//
15
16#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
17#include "clang/AST/Attr.h"
18#include "clang/AST/CharUnits.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/AST/RecordLayout.h"
21#include "clang/Analysis/AnalysisContext.h"
22#include "clang/Analysis/Support/BumpVector.h"
23#include "clang/Basic/SourceManager.h"
24#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
25#include "llvm/Support/raw_ostream.h"
26
27using namespace clang;
28using namespace ento;
29
30//===----------------------------------------------------------------------===//
31// MemRegion Construction.
32//===----------------------------------------------------------------------===//
33
34template<typename RegionTy> struct MemRegionManagerTrait;
35
36template <typename RegionTy, typename A1>
37RegionTy* MemRegionManager::getRegion(const A1 a1) {
38
39  const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
40  MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
41
42  llvm::FoldingSetNodeID ID;
43  RegionTy::ProfileRegion(ID, a1, superRegion);
44  void *InsertPos;
45  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
46                                                                   InsertPos));
47
48  if (!R) {
49    R = (RegionTy*) A.Allocate<RegionTy>();
50    new (R) RegionTy(a1, superRegion);
51    Regions.InsertNode(R, InsertPos);
52  }
53
54  return R;
55}
56
57template <typename RegionTy, typename A1>
58RegionTy* MemRegionManager::getSubRegion(const A1 a1,
59                                         const MemRegion *superRegion) {
60  llvm::FoldingSetNodeID ID;
61  RegionTy::ProfileRegion(ID, a1, superRegion);
62  void *InsertPos;
63  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
64                                                                   InsertPos));
65
66  if (!R) {
67    R = (RegionTy*) A.Allocate<RegionTy>();
68    new (R) RegionTy(a1, superRegion);
69    Regions.InsertNode(R, InsertPos);
70  }
71
72  return R;
73}
74
75template <typename RegionTy, typename A1, typename A2>
76RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
77
78  const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
79  MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
80
81  llvm::FoldingSetNodeID ID;
82  RegionTy::ProfileRegion(ID, a1, a2, superRegion);
83  void *InsertPos;
84  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
85                                                                   InsertPos));
86
87  if (!R) {
88    R = (RegionTy*) A.Allocate<RegionTy>();
89    new (R) RegionTy(a1, a2, superRegion);
90    Regions.InsertNode(R, InsertPos);
91  }
92
93  return R;
94}
95
96template <typename RegionTy, typename A1, typename A2>
97RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
98                                         const MemRegion *superRegion) {
99
100  llvm::FoldingSetNodeID ID;
101  RegionTy::ProfileRegion(ID, a1, a2, superRegion);
102  void *InsertPos;
103  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
104                                                                   InsertPos));
105
106  if (!R) {
107    R = (RegionTy*) A.Allocate<RegionTy>();
108    new (R) RegionTy(a1, a2, superRegion);
109    Regions.InsertNode(R, InsertPos);
110  }
111
112  return R;
113}
114
115template <typename RegionTy, typename A1, typename A2, typename A3>
116RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
117                                         const MemRegion *superRegion) {
118
119  llvm::FoldingSetNodeID ID;
120  RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
121  void *InsertPos;
122  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
123                                                                   InsertPos));
124
125  if (!R) {
126    R = (RegionTy*) A.Allocate<RegionTy>();
127    new (R) RegionTy(a1, a2, a3, superRegion);
128    Regions.InsertNode(R, InsertPos);
129  }
130
131  return R;
132}
133
134//===----------------------------------------------------------------------===//
135// Object destruction.
136//===----------------------------------------------------------------------===//
137
138MemRegion::~MemRegion() {}
139
140MemRegionManager::~MemRegionManager() {
141  // All regions and their data are BumpPtrAllocated.  No need to call
142  // their destructors.
143}
144
145//===----------------------------------------------------------------------===//
146// Basic methods.
147//===----------------------------------------------------------------------===//
148
149bool SubRegion::isSubRegionOf(const MemRegion* R) const {
150  const MemRegion* r = getSuperRegion();
151  while (r != 0) {
152    if (r == R)
153      return true;
154    if (const SubRegion* sr = dyn_cast<SubRegion>(r))
155      r = sr->getSuperRegion();
156    else
157      break;
158  }
159  return false;
160}
161
162MemRegionManager* SubRegion::getMemRegionManager() const {
163  const SubRegion* r = this;
164  do {
165    const MemRegion *superRegion = r->getSuperRegion();
166    if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
167      r = sr;
168      continue;
169    }
170    return superRegion->getMemRegionManager();
171  } while (1);
172}
173
174const StackFrameContext *VarRegion::getStackFrame() const {
175  const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
176  return SSR ? SSR->getStackFrame() : NULL;
177}
178
179//===----------------------------------------------------------------------===//
180// Region extents.
181//===----------------------------------------------------------------------===//
182
183DefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const {
184  ASTContext &Ctx = svalBuilder.getContext();
185  QualType T = getDesugaredValueType(Ctx);
186
187  if (isa<VariableArrayType>(T))
188    return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
189  if (isa<IncompleteArrayType>(T))
190    return UnknownVal();
191
192  CharUnits size = Ctx.getTypeSizeInChars(T);
193  QualType sizeTy = svalBuilder.getArrayIndexType();
194  return svalBuilder.makeIntVal(size.getQuantity(), sizeTy);
195}
196
197DefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const {
198  DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder);
199
200  // A zero-length array at the end of a struct often stands for dynamically-
201  // allocated extra memory.
202  if (Extent.isZeroConstant()) {
203    QualType T = getDesugaredValueType(svalBuilder.getContext());
204
205    if (isa<ConstantArrayType>(T))
206      return UnknownVal();
207  }
208
209  return Extent;
210}
211
212DefinedOrUnknownSVal AllocaRegion::getExtent(SValBuilder &svalBuilder) const {
213  return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
214}
215
216DefinedOrUnknownSVal SymbolicRegion::getExtent(SValBuilder &svalBuilder) const {
217  return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
218}
219
220DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const {
221  return svalBuilder.makeIntVal(getStringLiteral()->getByteLength()+1,
222                                svalBuilder.getArrayIndexType());
223}
224
225ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg)
226  : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
227
228const ObjCIvarDecl *ObjCIvarRegion::getDecl() const {
229  return cast<ObjCIvarDecl>(D);
230}
231
232QualType ObjCIvarRegion::getValueType() const {
233  return getDecl()->getType();
234}
235
236QualType CXXBaseObjectRegion::getValueType() const {
237  return QualType(getDecl()->getTypeForDecl(), 0);
238}
239
240//===----------------------------------------------------------------------===//
241// FoldingSet profiling.
242//===----------------------------------------------------------------------===//
243
244void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
245  ID.AddInteger((unsigned)getKind());
246}
247
248void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
249  ID.AddInteger((unsigned)getKind());
250  ID.AddPointer(getStackFrame());
251}
252
253void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
254  ID.AddInteger((unsigned)getKind());
255  ID.AddPointer(getCodeRegion());
256}
257
258void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
259                                 const StringLiteral* Str,
260                                 const MemRegion* superRegion) {
261  ID.AddInteger((unsigned) StringRegionKind);
262  ID.AddPointer(Str);
263  ID.AddPointer(superRegion);
264}
265
266void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
267                                     const ObjCStringLiteral* Str,
268                                     const MemRegion* superRegion) {
269  ID.AddInteger((unsigned) ObjCStringRegionKind);
270  ID.AddPointer(Str);
271  ID.AddPointer(superRegion);
272}
273
274void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
275                                 const Expr *Ex, unsigned cnt,
276                                 const MemRegion *superRegion) {
277  ID.AddInteger((unsigned) AllocaRegionKind);
278  ID.AddPointer(Ex);
279  ID.AddInteger(cnt);
280  ID.AddPointer(superRegion);
281}
282
283void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
284  ProfileRegion(ID, Ex, Cnt, superRegion);
285}
286
287void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
288  CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
289}
290
291void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
292                                          const CompoundLiteralExpr *CL,
293                                          const MemRegion* superRegion) {
294  ID.AddInteger((unsigned) CompoundLiteralRegionKind);
295  ID.AddPointer(CL);
296  ID.AddPointer(superRegion);
297}
298
299void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
300                                  const PointerType *PT,
301                                  const MemRegion *sRegion) {
302  ID.AddInteger((unsigned) CXXThisRegionKind);
303  ID.AddPointer(PT);
304  ID.AddPointer(sRegion);
305}
306
307void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
308  CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
309}
310
311void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
312                                   const ObjCIvarDecl *ivd,
313                                   const MemRegion* superRegion) {
314  DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
315}
316
317void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
318                               const MemRegion* superRegion, Kind k) {
319  ID.AddInteger((unsigned) k);
320  ID.AddPointer(D);
321  ID.AddPointer(superRegion);
322}
323
324void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
325  DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
326}
327
328void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
329  VarRegion::ProfileRegion(ID, getDecl(), superRegion);
330}
331
332void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
333                                   const MemRegion *sreg) {
334  ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
335  ID.Add(sym);
336  ID.AddPointer(sreg);
337}
338
339void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
340  SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
341}
342
343void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
344                                  QualType ElementType, SVal Idx,
345                                  const MemRegion* superRegion) {
346  ID.AddInteger(MemRegion::ElementRegionKind);
347  ID.Add(ElementType);
348  ID.AddPointer(superRegion);
349  Idx.Profile(ID);
350}
351
352void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
353  ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
354}
355
356void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
357                                       const NamedDecl *FD,
358                                       const MemRegion*) {
359  ID.AddInteger(MemRegion::FunctionTextRegionKind);
360  ID.AddPointer(FD);
361}
362
363void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
364  FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
365}
366
367void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
368                                    const BlockDecl *BD, CanQualType,
369                                    const AnalysisDeclContext *AC,
370                                    const MemRegion*) {
371  ID.AddInteger(MemRegion::BlockTextRegionKind);
372  ID.AddPointer(BD);
373}
374
375void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
376  BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
377}
378
379void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
380                                    const BlockTextRegion *BC,
381                                    const LocationContext *LC,
382                                    const MemRegion *sReg) {
383  ID.AddInteger(MemRegion::BlockDataRegionKind);
384  ID.AddPointer(BC);
385  ID.AddPointer(LC);
386  ID.AddPointer(sReg);
387}
388
389void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
390  BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
391}
392
393void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
394                                        Expr const *Ex,
395                                        const MemRegion *sReg) {
396  ID.AddPointer(Ex);
397  ID.AddPointer(sReg);
398}
399
400void CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
401  ProfileRegion(ID, Ex, getSuperRegion());
402}
403
404void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
405                                        const CXXRecordDecl *RD,
406                                        bool IsVirtual,
407                                        const MemRegion *SReg) {
408  ID.AddPointer(RD);
409  ID.AddBoolean(IsVirtual);
410  ID.AddPointer(SReg);
411}
412
413void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
414  ProfileRegion(ID, getDecl(), isVirtual(), superRegion);
415}
416
417//===----------------------------------------------------------------------===//
418// Region anchors.
419//===----------------------------------------------------------------------===//
420
421void GlobalsSpaceRegion::anchor() { }
422void HeapSpaceRegion::anchor() { }
423void UnknownSpaceRegion::anchor() { }
424void StackLocalsSpaceRegion::anchor() { }
425void StackArgumentsSpaceRegion::anchor() { }
426void TypedRegion::anchor() { }
427void TypedValueRegion::anchor() { }
428void CodeTextRegion::anchor() { }
429void SubRegion::anchor() { }
430
431//===----------------------------------------------------------------------===//
432// Region pretty-printing.
433//===----------------------------------------------------------------------===//
434
435void MemRegion::dump() const {
436  dumpToStream(llvm::errs());
437}
438
439std::string MemRegion::getString() const {
440  std::string s;
441  llvm::raw_string_ostream os(s);
442  dumpToStream(os);
443  return os.str();
444}
445
446void MemRegion::dumpToStream(raw_ostream &os) const {
447  os << "<Unknown Region>";
448}
449
450void AllocaRegion::dumpToStream(raw_ostream &os) const {
451  os << "alloca{" << (const void*) Ex << ',' << Cnt << '}';
452}
453
454void FunctionTextRegion::dumpToStream(raw_ostream &os) const {
455  os << "code{" << getDecl()->getDeclName().getAsString() << '}';
456}
457
458void BlockTextRegion::dumpToStream(raw_ostream &os) const {
459  os << "block_code{" << (const void*) this << '}';
460}
461
462void BlockDataRegion::dumpToStream(raw_ostream &os) const {
463  os << "block_data{" << BC << '}';
464}
465
466void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {
467  // FIXME: More elaborate pretty-printing.
468  os << "{ " << (const void*) CL <<  " }";
469}
470
471void CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {
472  os << "temp_object{" << getValueType().getAsString() << ','
473     << (const void*) Ex << '}';
474}
475
476void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
477  os << "base{" << superRegion << ',' << getDecl()->getName() << '}';
478}
479
480void CXXThisRegion::dumpToStream(raw_ostream &os) const {
481  os << "this";
482}
483
484void ElementRegion::dumpToStream(raw_ostream &os) const {
485  os << "element{" << superRegion << ','
486     << Index << ',' << getElementType().getAsString() << '}';
487}
488
489void FieldRegion::dumpToStream(raw_ostream &os) const {
490  os << superRegion << "->" << *getDecl();
491}
492
493void ObjCIvarRegion::dumpToStream(raw_ostream &os) const {
494  os << "ivar{" << superRegion << ',' << *getDecl() << '}';
495}
496
497void StringRegion::dumpToStream(raw_ostream &os) const {
498  Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts()));
499}
500
501void ObjCStringRegion::dumpToStream(raw_ostream &os) const {
502  Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts()));
503}
504
505void SymbolicRegion::dumpToStream(raw_ostream &os) const {
506  os << "SymRegion{" << sym << '}';
507}
508
509void VarRegion::dumpToStream(raw_ostream &os) const {
510  os << *cast<VarDecl>(D);
511}
512
513void RegionRawOffset::dump() const {
514  dumpToStream(llvm::errs());
515}
516
517void RegionRawOffset::dumpToStream(raw_ostream &os) const {
518  os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}';
519}
520
521void StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const {
522  os << "StaticGlobalsMemSpace{" << CR << '}';
523}
524
525void GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const {
526  os << "GlobalInternalSpaceRegion";
527}
528
529void GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const {
530  os << "GlobalSystemSpaceRegion";
531}
532
533void GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const {
534  os << "GlobalImmutableSpaceRegion";
535}
536
537void HeapSpaceRegion::dumpToStream(raw_ostream &os) const {
538  os << "HeapSpaceRegion";
539}
540
541void UnknownSpaceRegion::dumpToStream(raw_ostream &os) const {
542  os << "UnknownSpaceRegion";
543}
544
545void StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const {
546  os << "StackArgumentsSpaceRegion";
547}
548
549void StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const {
550  os << "StackLocalsSpaceRegion";
551}
552
553bool MemRegion::canPrintPretty() const {
554  return false;
555}
556
557void MemRegion::printPretty(raw_ostream &os) const {
558  return;
559}
560
561bool VarRegion::canPrintPretty() const {
562  return true;
563}
564
565void VarRegion::printPretty(raw_ostream &os) const {
566  os << getDecl()->getName();
567}
568
569bool ObjCIvarRegion::canPrintPretty() const {
570  return true;
571}
572
573void ObjCIvarRegion::printPretty(raw_ostream &os) const {
574  os << getDecl()->getName();
575}
576
577bool FieldRegion::canPrintPretty() const {
578  return superRegion->canPrintPretty();
579}
580
581void FieldRegion::printPretty(raw_ostream &os) const {
582  superRegion->printPretty(os);
583  os << "." << getDecl()->getName();
584}
585
586//===----------------------------------------------------------------------===//
587// MemRegionManager methods.
588//===----------------------------------------------------------------------===//
589
590template <typename REG>
591const REG *MemRegionManager::LazyAllocate(REG*& region) {
592  if (!region) {
593    region = (REG*) A.Allocate<REG>();
594    new (region) REG(this);
595  }
596
597  return region;
598}
599
600template <typename REG, typename ARG>
601const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
602  if (!region) {
603    region = (REG*) A.Allocate<REG>();
604    new (region) REG(this, a);
605  }
606
607  return region;
608}
609
610const StackLocalsSpaceRegion*
611MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
612  assert(STC);
613  StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
614
615  if (R)
616    return R;
617
618  R = A.Allocate<StackLocalsSpaceRegion>();
619  new (R) StackLocalsSpaceRegion(this, STC);
620  return R;
621}
622
623const StackArgumentsSpaceRegion *
624MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
625  assert(STC);
626  StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
627
628  if (R)
629    return R;
630
631  R = A.Allocate<StackArgumentsSpaceRegion>();
632  new (R) StackArgumentsSpaceRegion(this, STC);
633  return R;
634}
635
636const GlobalsSpaceRegion
637*MemRegionManager::getGlobalsRegion(MemRegion::Kind K,
638                                    const CodeTextRegion *CR) {
639  if (!CR) {
640    if (K == MemRegion::GlobalSystemSpaceRegionKind)
641      return LazyAllocate(SystemGlobals);
642    if (K == MemRegion::GlobalImmutableSpaceRegionKind)
643      return LazyAllocate(ImmutableGlobals);
644    assert(K == MemRegion::GlobalInternalSpaceRegionKind);
645    return LazyAllocate(InternalGlobals);
646  }
647
648  assert(K == MemRegion::StaticGlobalSpaceRegionKind);
649  StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
650  if (R)
651    return R;
652
653  R = A.Allocate<StaticGlobalSpaceRegion>();
654  new (R) StaticGlobalSpaceRegion(this, CR);
655  return R;
656}
657
658const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
659  return LazyAllocate(heap);
660}
661
662const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
663  return LazyAllocate(unknown);
664}
665
666const MemSpaceRegion *MemRegionManager::getCodeRegion() {
667  return LazyAllocate(code);
668}
669
670//===----------------------------------------------------------------------===//
671// Constructing regions.
672//===----------------------------------------------------------------------===//
673const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
674  return getSubRegion<StringRegion>(Str, getGlobalsRegion());
675}
676
677const ObjCStringRegion *
678MemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){
679  return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion());
680}
681
682/// Look through a chain of LocationContexts to either find the
683/// StackFrameContext that matches a DeclContext, or find a VarRegion
684/// for a variable captured by a block.
685static llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
686getStackOrCaptureRegionForDeclContext(const LocationContext *LC,
687                                      const DeclContext *DC,
688                                      const VarDecl *VD) {
689  while (LC) {
690    if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) {
691      if (cast<DeclContext>(SFC->getDecl()) == DC)
692        return SFC;
693    }
694    if (const BlockInvocationContext *BC =
695        dyn_cast<BlockInvocationContext>(LC)) {
696      const BlockDataRegion *BR =
697        static_cast<const BlockDataRegion*>(BC->getContextData());
698      // FIXME: This can be made more efficient.
699      for (BlockDataRegion::referenced_vars_iterator
700           I = BR->referenced_vars_begin(),
701           E = BR->referenced_vars_end(); I != E; ++I) {
702        if (const VarRegion *VR = dyn_cast<VarRegion>(I.getOriginalRegion()))
703          if (VR->getDecl() == VD)
704            return cast<VarRegion>(I.getCapturedRegion());
705      }
706    }
707
708    LC = LC->getParent();
709  }
710  return (const StackFrameContext*)0;
711}
712
713const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
714                                                const LocationContext *LC) {
715  const MemRegion *sReg = 0;
716
717  if (D->hasGlobalStorage() && !D->isStaticLocal()) {
718
719    // First handle the globals defined in system headers.
720    if (C.getSourceManager().isInSystemHeader(D->getLocation())) {
721      // Whitelist the system globals which often DO GET modified, assume the
722      // rest are immutable.
723      if (D->getName().find("errno") != StringRef::npos)
724        sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
725      else
726        sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
727
728    // Treat other globals as GlobalInternal unless they are constants.
729    } else {
730      QualType GQT = D->getType();
731      const Type *GT = GQT.getTypePtrOrNull();
732      // TODO: We could walk the complex types here and see if everything is
733      // constified.
734      if (GT && GQT.isConstQualified() && GT->isArithmeticType())
735        sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
736      else
737        sReg = getGlobalsRegion();
738    }
739
740  // Finally handle static locals.
741  } else {
742    // FIXME: Once we implement scope handling, we will need to properly lookup
743    // 'D' to the proper LocationContext.
744    const DeclContext *DC = D->getDeclContext();
745    llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
746      getStackOrCaptureRegionForDeclContext(LC, DC, D);
747
748    if (V.is<const VarRegion*>())
749      return V.get<const VarRegion*>();
750
751    const StackFrameContext *STC = V.get<const StackFrameContext*>();
752
753    if (!STC)
754      sReg = getUnknownRegion();
755    else {
756      if (D->hasLocalStorage()) {
757        sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
758               ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
759               : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
760      }
761      else {
762        assert(D->isStaticLocal());
763        const Decl *STCD = STC->getDecl();
764        if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
765          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
766                                  getFunctionTextRegion(cast<NamedDecl>(STCD)));
767        else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
768          const BlockTextRegion *BTR =
769            getBlockTextRegion(BD,
770                     C.getCanonicalType(BD->getSignatureAsWritten()->getType()),
771                     STC->getAnalysisDeclContext());
772          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
773                                  BTR);
774        }
775        else {
776          sReg = getGlobalsRegion();
777        }
778      }
779    }
780  }
781
782  return getSubRegion<VarRegion>(D, sReg);
783}
784
785const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
786                                                const MemRegion *superR) {
787  return getSubRegion<VarRegion>(D, superR);
788}
789
790const BlockDataRegion *
791MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
792                                     const LocationContext *LC) {
793  const MemRegion *sReg = 0;
794  const BlockDecl *BD = BC->getDecl();
795  if (!BD->hasCaptures()) {
796    // This handles 'static' blocks.
797    sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
798  }
799  else {
800    if (LC) {
801      // FIXME: Once we implement scope handling, we want the parent region
802      // to be the scope.
803      const StackFrameContext *STC = LC->getCurrentStackFrame();
804      assert(STC);
805      sReg = getStackLocalsRegion(STC);
806    }
807    else {
808      // We allow 'LC' to be NULL for cases where want BlockDataRegions
809      // without context-sensitivity.
810      sReg = getUnknownRegion();
811    }
812  }
813
814  return getSubRegion<BlockDataRegion>(BC, LC, sReg);
815}
816
817const CompoundLiteralRegion*
818MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
819                                           const LocationContext *LC) {
820
821  const MemRegion *sReg = 0;
822
823  if (CL->isFileScope())
824    sReg = getGlobalsRegion();
825  else {
826    const StackFrameContext *STC = LC->getCurrentStackFrame();
827    assert(STC);
828    sReg = getStackLocalsRegion(STC);
829  }
830
831  return getSubRegion<CompoundLiteralRegion>(CL, sReg);
832}
833
834const ElementRegion*
835MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
836                                   const MemRegion* superRegion,
837                                   ASTContext &Ctx){
838
839  QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
840
841  llvm::FoldingSetNodeID ID;
842  ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
843
844  void *InsertPos;
845  MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
846  ElementRegion* R = cast_or_null<ElementRegion>(data);
847
848  if (!R) {
849    R = (ElementRegion*) A.Allocate<ElementRegion>();
850    new (R) ElementRegion(T, Idx, superRegion);
851    Regions.InsertNode(R, InsertPos);
852  }
853
854  return R;
855}
856
857const FunctionTextRegion *
858MemRegionManager::getFunctionTextRegion(const NamedDecl *FD) {
859  return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
860}
861
862const BlockTextRegion *
863MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
864                                     AnalysisDeclContext *AC) {
865  return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
866}
867
868
869/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
870const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
871  return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
872}
873
874const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {
875  return getSubRegion<SymbolicRegion>(Sym, getHeapRegion());
876}
877
878const FieldRegion*
879MemRegionManager::getFieldRegion(const FieldDecl *d,
880                                 const MemRegion* superRegion){
881  return getSubRegion<FieldRegion>(d, superRegion);
882}
883
884const ObjCIvarRegion*
885MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
886                                    const MemRegion* superRegion) {
887  return getSubRegion<ObjCIvarRegion>(d, superRegion);
888}
889
890const CXXTempObjectRegion*
891MemRegionManager::getCXXTempObjectRegion(Expr const *E,
892                                         LocationContext const *LC) {
893  const StackFrameContext *SFC = LC->getCurrentStackFrame();
894  assert(SFC);
895  return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC));
896}
897
898/// Checks whether \p BaseClass is a valid virtual or direct non-virtual base
899/// class of the type of \p Super.
900static bool isValidBaseClass(const CXXRecordDecl *BaseClass,
901                             const TypedValueRegion *Super,
902                             bool IsVirtual) {
903  BaseClass = BaseClass->getCanonicalDecl();
904
905  const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl();
906  if (!Class)
907    return true;
908
909  if (IsVirtual)
910    return Class->isVirtuallyDerivedFrom(BaseClass);
911
912  for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
913                                                E = Class->bases_end();
914       I != E; ++I) {
915    if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
916      return true;
917  }
918
919  return false;
920}
921
922const CXXBaseObjectRegion *
923MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
924                                         const MemRegion *Super,
925                                         bool IsVirtual) {
926  if (isa<TypedValueRegion>(Super)) {
927    assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual));
928    (void)isValidBaseClass;
929
930    if (IsVirtual) {
931      // Virtual base regions should not be layered, since the layout rules
932      // are different.
933      while (const CXXBaseObjectRegion *Base =
934               dyn_cast<CXXBaseObjectRegion>(Super)) {
935        Super = Base->getSuperRegion();
936      }
937      assert(Super && !isa<MemSpaceRegion>(Super));
938    }
939  }
940
941  return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
942}
943
944const CXXThisRegion*
945MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
946                                   const LocationContext *LC) {
947  const StackFrameContext *STC = LC->getCurrentStackFrame();
948  assert(STC);
949  const PointerType *PT = thisPointerTy->getAs<PointerType>();
950  assert(PT);
951  return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
952}
953
954const AllocaRegion*
955MemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt,
956                                  const LocationContext *LC) {
957  const StackFrameContext *STC = LC->getCurrentStackFrame();
958  assert(STC);
959  return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
960}
961
962const MemSpaceRegion *MemRegion::getMemorySpace() const {
963  const MemRegion *R = this;
964  const SubRegion* SR = dyn_cast<SubRegion>(this);
965
966  while (SR) {
967    R = SR->getSuperRegion();
968    SR = dyn_cast<SubRegion>(R);
969  }
970
971  return dyn_cast<MemSpaceRegion>(R);
972}
973
974bool MemRegion::hasStackStorage() const {
975  return isa<StackSpaceRegion>(getMemorySpace());
976}
977
978bool MemRegion::hasStackNonParametersStorage() const {
979  return isa<StackLocalsSpaceRegion>(getMemorySpace());
980}
981
982bool MemRegion::hasStackParametersStorage() const {
983  return isa<StackArgumentsSpaceRegion>(getMemorySpace());
984}
985
986bool MemRegion::hasGlobalsOrParametersStorage() const {
987  const MemSpaceRegion *MS = getMemorySpace();
988  return isa<StackArgumentsSpaceRegion>(MS) ||
989         isa<GlobalsSpaceRegion>(MS);
990}
991
992// getBaseRegion strips away all elements and fields, and get the base region
993// of them.
994const MemRegion *MemRegion::getBaseRegion() const {
995  const MemRegion *R = this;
996  while (true) {
997    switch (R->getKind()) {
998      case MemRegion::ElementRegionKind:
999      case MemRegion::FieldRegionKind:
1000      case MemRegion::ObjCIvarRegionKind:
1001      case MemRegion::CXXBaseObjectRegionKind:
1002        R = cast<SubRegion>(R)->getSuperRegion();
1003        continue;
1004      default:
1005        break;
1006    }
1007    break;
1008  }
1009  return R;
1010}
1011
1012bool MemRegion::isSubRegionOf(const MemRegion *R) const {
1013  return false;
1014}
1015
1016//===----------------------------------------------------------------------===//
1017// View handling.
1018//===----------------------------------------------------------------------===//
1019
1020const MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const {
1021  const MemRegion *R = this;
1022  while (true) {
1023    switch (R->getKind()) {
1024    case ElementRegionKind: {
1025      const ElementRegion *ER = cast<ElementRegion>(R);
1026      if (!ER->getIndex().isZeroConstant())
1027        return R;
1028      R = ER->getSuperRegion();
1029      break;
1030    }
1031    case CXXBaseObjectRegionKind:
1032      if (!StripBaseCasts)
1033        return R;
1034      R = cast<CXXBaseObjectRegion>(R)->getSuperRegion();
1035      break;
1036    default:
1037      return R;
1038    }
1039  }
1040}
1041
1042// FIXME: Merge with the implementation of the same method in Store.cpp
1043static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
1044  if (const RecordType *RT = Ty->getAs<RecordType>()) {
1045    const RecordDecl *D = RT->getDecl();
1046    if (!D->getDefinition())
1047      return false;
1048  }
1049
1050  return true;
1051}
1052
1053RegionRawOffset ElementRegion::getAsArrayOffset() const {
1054  CharUnits offset = CharUnits::Zero();
1055  const ElementRegion *ER = this;
1056  const MemRegion *superR = NULL;
1057  ASTContext &C = getContext();
1058
1059  // FIXME: Handle multi-dimensional arrays.
1060
1061  while (ER) {
1062    superR = ER->getSuperRegion();
1063
1064    // FIXME: generalize to symbolic offsets.
1065    SVal index = ER->getIndex();
1066    if (Optional<nonloc::ConcreteInt> CI = index.getAs<nonloc::ConcreteInt>()) {
1067      // Update the offset.
1068      int64_t i = CI->getValue().getSExtValue();
1069
1070      if (i != 0) {
1071        QualType elemType = ER->getElementType();
1072
1073        // If we are pointing to an incomplete type, go no further.
1074        if (!IsCompleteType(C, elemType)) {
1075          superR = ER;
1076          break;
1077        }
1078
1079        CharUnits size = C.getTypeSizeInChars(elemType);
1080        offset += (i * size);
1081      }
1082
1083      // Go to the next ElementRegion (if any).
1084      ER = dyn_cast<ElementRegion>(superR);
1085      continue;
1086    }
1087
1088    return NULL;
1089  }
1090
1091  assert(superR && "super region cannot be NULL");
1092  return RegionRawOffset(superR, offset);
1093}
1094
1095
1096/// Returns true if \p Base is an immediate base class of \p Child
1097static bool isImmediateBase(const CXXRecordDecl *Child,
1098                            const CXXRecordDecl *Base) {
1099  // Note that we do NOT canonicalize the base class here, because
1100  // ASTRecordLayout doesn't either. If that leads us down the wrong path,
1101  // so be it; at least we won't crash.
1102  for (CXXRecordDecl::base_class_const_iterator I = Child->bases_begin(),
1103                                                E = Child->bases_end();
1104       I != E; ++I) {
1105    if (I->getType()->getAsCXXRecordDecl() == Base)
1106      return true;
1107  }
1108
1109  return false;
1110}
1111
1112RegionOffset MemRegion::getAsOffset() const {
1113  const MemRegion *R = this;
1114  const MemRegion *SymbolicOffsetBase = 0;
1115  int64_t Offset = 0;
1116
1117  while (1) {
1118    switch (R->getKind()) {
1119    case GenericMemSpaceRegionKind:
1120    case StackLocalsSpaceRegionKind:
1121    case StackArgumentsSpaceRegionKind:
1122    case HeapSpaceRegionKind:
1123    case UnknownSpaceRegionKind:
1124    case StaticGlobalSpaceRegionKind:
1125    case GlobalInternalSpaceRegionKind:
1126    case GlobalSystemSpaceRegionKind:
1127    case GlobalImmutableSpaceRegionKind:
1128      // Stores can bind directly to a region space to set a default value.
1129      assert(Offset == 0 && !SymbolicOffsetBase);
1130      goto Finish;
1131
1132    case FunctionTextRegionKind:
1133    case BlockTextRegionKind:
1134    case BlockDataRegionKind:
1135      // These will never have bindings, but may end up having values requested
1136      // if the user does some strange casting.
1137      if (Offset != 0)
1138        SymbolicOffsetBase = R;
1139      goto Finish;
1140
1141    case SymbolicRegionKind:
1142    case AllocaRegionKind:
1143    case CompoundLiteralRegionKind:
1144    case CXXThisRegionKind:
1145    case StringRegionKind:
1146    case ObjCStringRegionKind:
1147    case VarRegionKind:
1148    case CXXTempObjectRegionKind:
1149      // Usual base regions.
1150      goto Finish;
1151
1152    case ObjCIvarRegionKind:
1153      // This is a little strange, but it's a compromise between
1154      // ObjCIvarRegions having unknown compile-time offsets (when using the
1155      // non-fragile runtime) and yet still being distinct, non-overlapping
1156      // regions. Thus we treat them as "like" base regions for the purposes
1157      // of computing offsets.
1158      goto Finish;
1159
1160    case CXXBaseObjectRegionKind: {
1161      const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R);
1162      R = BOR->getSuperRegion();
1163
1164      QualType Ty;
1165      bool RootIsSymbolic = false;
1166      if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) {
1167        Ty = TVR->getDesugaredValueType(getContext());
1168      } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
1169        // If our base region is symbolic, we don't know what type it really is.
1170        // Pretend the type of the symbol is the true dynamic type.
1171        // (This will at least be self-consistent for the life of the symbol.)
1172        Ty = SR->getSymbol()->getType()->getPointeeType();
1173        RootIsSymbolic = true;
1174      }
1175
1176      const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
1177      if (!Child) {
1178        // We cannot compute the offset of the base class.
1179        SymbolicOffsetBase = R;
1180      }
1181
1182      if (RootIsSymbolic) {
1183        // Base layers on symbolic regions may not be type-correct.
1184        // Double-check the inheritance here, and revert to a symbolic offset
1185        // if it's invalid (e.g. due to a reinterpret_cast).
1186        if (BOR->isVirtual()) {
1187          if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
1188            SymbolicOffsetBase = R;
1189        } else {
1190          if (!isImmediateBase(Child, BOR->getDecl()))
1191            SymbolicOffsetBase = R;
1192        }
1193      }
1194
1195      // Don't bother calculating precise offsets if we already have a
1196      // symbolic offset somewhere in the chain.
1197      if (SymbolicOffsetBase)
1198        continue;
1199
1200      CharUnits BaseOffset;
1201      const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child);
1202      if (BOR->isVirtual())
1203        BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl());
1204      else
1205        BaseOffset = Layout.getBaseClassOffset(BOR->getDecl());
1206
1207      // The base offset is in chars, not in bits.
1208      Offset += BaseOffset.getQuantity() * getContext().getCharWidth();
1209      break;
1210    }
1211    case ElementRegionKind: {
1212      const ElementRegion *ER = cast<ElementRegion>(R);
1213      R = ER->getSuperRegion();
1214
1215      QualType EleTy = ER->getValueType();
1216      if (!IsCompleteType(getContext(), EleTy)) {
1217        // We cannot compute the offset of the base class.
1218        SymbolicOffsetBase = R;
1219        continue;
1220      }
1221
1222      SVal Index = ER->getIndex();
1223      if (Optional<nonloc::ConcreteInt> CI =
1224              Index.getAs<nonloc::ConcreteInt>()) {
1225        // Don't bother calculating precise offsets if we already have a
1226        // symbolic offset somewhere in the chain.
1227        if (SymbolicOffsetBase)
1228          continue;
1229
1230        int64_t i = CI->getValue().getSExtValue();
1231        // This type size is in bits.
1232        Offset += i * getContext().getTypeSize(EleTy);
1233      } else {
1234        // We cannot compute offset for non-concrete index.
1235        SymbolicOffsetBase = R;
1236      }
1237      break;
1238    }
1239    case FieldRegionKind: {
1240      const FieldRegion *FR = cast<FieldRegion>(R);
1241      R = FR->getSuperRegion();
1242
1243      const RecordDecl *RD = FR->getDecl()->getParent();
1244      if (RD->isUnion() || !RD->isCompleteDefinition()) {
1245        // We cannot compute offset for incomplete type.
1246        // For unions, we could treat everything as offset 0, but we'd rather
1247        // treat each field as a symbolic offset so they aren't stored on top
1248        // of each other, since we depend on things in typed regions actually
1249        // matching their types.
1250        SymbolicOffsetBase = R;
1251      }
1252
1253      // Don't bother calculating precise offsets if we already have a
1254      // symbolic offset somewhere in the chain.
1255      if (SymbolicOffsetBase)
1256        continue;
1257
1258      // Get the field number.
1259      unsigned idx = 0;
1260      for (RecordDecl::field_iterator FI = RD->field_begin(),
1261             FE = RD->field_end(); FI != FE; ++FI, ++idx)
1262        if (FR->getDecl() == *FI)
1263          break;
1264
1265      const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
1266      // This is offset in bits.
1267      Offset += Layout.getFieldOffset(idx);
1268      break;
1269    }
1270    }
1271  }
1272
1273 Finish:
1274  if (SymbolicOffsetBase)
1275    return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
1276  return RegionOffset(R, Offset);
1277}
1278
1279//===----------------------------------------------------------------------===//
1280// BlockDataRegion
1281//===----------------------------------------------------------------------===//
1282
1283std::pair<const VarRegion *, const VarRegion *>
1284BlockDataRegion::getCaptureRegions(const VarDecl *VD) {
1285  MemRegionManager &MemMgr = *getMemRegionManager();
1286  const VarRegion *VR = 0;
1287  const VarRegion *OriginalVR = 0;
1288
1289  if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage()) {
1290    VR = MemMgr.getVarRegion(VD, this);
1291    OriginalVR = MemMgr.getVarRegion(VD, LC);
1292  }
1293  else {
1294    if (LC) {
1295      VR = MemMgr.getVarRegion(VD, LC);
1296      OriginalVR = VR;
1297    }
1298    else {
1299      VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
1300      OriginalVR = MemMgr.getVarRegion(VD, LC);
1301    }
1302  }
1303  return std::make_pair(VR, OriginalVR);
1304}
1305
1306void BlockDataRegion::LazyInitializeReferencedVars() {
1307  if (ReferencedVars)
1308    return;
1309
1310  AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext();
1311  AnalysisDeclContext::referenced_decls_iterator I, E;
1312  llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
1313
1314  if (I == E) {
1315    ReferencedVars = (void*) 0x1;
1316    return;
1317  }
1318
1319  MemRegionManager &MemMgr = *getMemRegionManager();
1320  llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
1321  BumpVectorContext BC(A);
1322
1323  typedef BumpVector<const MemRegion*> VarVec;
1324  VarVec *BV = (VarVec*) A.Allocate<VarVec>();
1325  new (BV) VarVec(BC, E - I);
1326  VarVec *BVOriginal = (VarVec*) A.Allocate<VarVec>();
1327  new (BVOriginal) VarVec(BC, E - I);
1328
1329  for ( ; I != E; ++I) {
1330    const VarRegion *VR = 0;
1331    const VarRegion *OriginalVR = 0;
1332    llvm::tie(VR, OriginalVR) = getCaptureRegions(*I);
1333    assert(VR);
1334    assert(OriginalVR);
1335    BV->push_back(VR, BC);
1336    BVOriginal->push_back(OriginalVR, BC);
1337  }
1338
1339  ReferencedVars = BV;
1340  OriginalVars = BVOriginal;
1341}
1342
1343BlockDataRegion::referenced_vars_iterator
1344BlockDataRegion::referenced_vars_begin() const {
1345  const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1346
1347  BumpVector<const MemRegion*> *Vec =
1348    static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
1349
1350  if (Vec == (void*) 0x1)
1351    return BlockDataRegion::referenced_vars_iterator(0, 0);
1352
1353  BumpVector<const MemRegion*> *VecOriginal =
1354    static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
1355
1356  return BlockDataRegion::referenced_vars_iterator(Vec->begin(),
1357                                                   VecOriginal->begin());
1358}
1359
1360BlockDataRegion::referenced_vars_iterator
1361BlockDataRegion::referenced_vars_end() const {
1362  const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
1363
1364  BumpVector<const MemRegion*> *Vec =
1365    static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
1366
1367  if (Vec == (void*) 0x1)
1368    return BlockDataRegion::referenced_vars_iterator(0, 0);
1369
1370  BumpVector<const MemRegion*> *VecOriginal =
1371    static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
1372
1373  return BlockDataRegion::referenced_vars_iterator(Vec->end(),
1374                                                   VecOriginal->end());
1375}
1376
1377const VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const {
1378  for (referenced_vars_iterator I = referenced_vars_begin(),
1379                                E = referenced_vars_end();
1380       I != E; ++I) {
1381    if (I.getCapturedRegion() == R)
1382      return I.getOriginalRegion();
1383  }
1384  return 0;
1385}
1386