• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //== MemRegion.h - 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 #ifndef LLVM_CLANG_GR_MEMREGION_H
17 #define LLVM_CLANG_GR_MEMREGION_H
18 
19 #include "clang/AST/CharUnits.h"
20 #include "clang/AST/Decl.h"
21 #include "clang/AST/ExprObjC.h"
22 #include "clang/Basic/LLVM.h"
23 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/ADT/FoldingSet.h"
26 #include <string>
27 
28 namespace llvm {
29 class BumpPtrAllocator;
30 }
31 
32 namespace clang {
33 
34 class LocationContext;
35 class StackFrameContext;
36 
37 namespace ento {
38 
39 class MemRegionManager;
40 class MemSpaceRegion;
41 class SValBuilder;
42 class VarRegion;
43 class CodeTextRegion;
44 
45 /// Represent a region's offset within the top level base region.
46 class RegionOffset {
47   /// The base region.
48   const MemRegion *R;
49 
50   /// The bit offset within the base region. It shouldn't be negative.
51   int64_t Offset;
52 
53 public:
RegionOffset(const MemRegion * r)54   RegionOffset(const MemRegion *r) : R(r), Offset(0) {}
RegionOffset(const MemRegion * r,int64_t off)55   RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
56 
getRegion()57   const MemRegion *getRegion() const { return R; }
getOffset()58   int64_t getOffset() const { return Offset; }
59 };
60 
61 //===----------------------------------------------------------------------===//
62 // Base region classes.
63 //===----------------------------------------------------------------------===//
64 
65 /// MemRegion - The root abstract class for all memory regions.
66 class MemRegion : public llvm::FoldingSetNode {
67   friend class MemRegionManager;
68 public:
69   enum Kind {
70     // Memory spaces.
71     GenericMemSpaceRegionKind,
72     StackLocalsSpaceRegionKind,
73     StackArgumentsSpaceRegionKind,
74     HeapSpaceRegionKind,
75     UnknownSpaceRegionKind,
76     StaticGlobalSpaceRegionKind,
77     GlobalInternalSpaceRegionKind,
78     GlobalSystemSpaceRegionKind,
79     GlobalImmutableSpaceRegionKind,
80     BEG_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind,
81     END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
82     BEG_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind,
83     END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
84     BEG_MEMSPACES = GenericMemSpaceRegionKind,
85     END_MEMSPACES = GlobalImmutableSpaceRegionKind,
86     // Untyped regions.
87     SymbolicRegionKind,
88     AllocaRegionKind,
89     BlockDataRegionKind,
90     // Typed regions.
91     BEG_TYPED_REGIONS,
92     FunctionTextRegionKind = BEG_TYPED_REGIONS,
93     BlockTextRegionKind,
94     BEG_TYPED_VALUE_REGIONS,
95     CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS,
96     CXXThisRegionKind,
97     StringRegionKind,
98     ObjCStringRegionKind,
99     ElementRegionKind,
100     // Decl Regions.
101     BEG_DECL_REGIONS,
102     VarRegionKind = BEG_DECL_REGIONS,
103     FieldRegionKind,
104     ObjCIvarRegionKind,
105     END_DECL_REGIONS = ObjCIvarRegionKind,
106     CXXTempObjectRegionKind,
107     CXXBaseObjectRegionKind,
108     END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind,
109     END_TYPED_REGIONS = CXXBaseObjectRegionKind
110   };
111 
112 private:
113   const Kind kind;
114 
115 protected:
MemRegion(Kind k)116   MemRegion(Kind k) : kind(k) {}
117   virtual ~MemRegion();
118 
119 public:
120   ASTContext &getContext() const;
121 
122   virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
123 
124   virtual MemRegionManager* getMemRegionManager() const = 0;
125 
126   const MemSpaceRegion *getMemorySpace() const;
127 
128   const MemRegion *getBaseRegion() const;
129 
130   const MemRegion *StripCasts() const;
131 
132   bool hasGlobalsOrParametersStorage() const;
133 
134   bool hasStackStorage() const;
135 
136   bool hasStackNonParametersStorage() const;
137 
138   bool hasStackParametersStorage() const;
139 
140   /// Compute the offset within the top level memory object.
141   RegionOffset getAsOffset() const;
142 
143   /// \brief Get a string representation of a region for debug use.
144   std::string getString() const;
145 
146   virtual void dumpToStream(raw_ostream &os) const;
147 
148   void dump() const;
149 
150   /// \brief Print the region for use in diagnostics.
151   virtual void dumpPretty(raw_ostream &os) const;
152 
getKind()153   Kind getKind() const { return kind; }
154 
155   template<typename RegionTy> const RegionTy* getAs() const;
156 
isBoundable()157   virtual bool isBoundable() const { return false; }
158 
classof(const MemRegion *)159   static bool classof(const MemRegion*) { return true; }
160 };
161 
162 /// MemSpaceRegion - A memory region that represents a "memory space";
163 ///  for example, the set of global variables, the stack frame, etc.
164 class MemSpaceRegion : public MemRegion {
165 protected:
166   friend class MemRegionManager;
167 
168   MemRegionManager *Mgr;
169 
170   MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
MemRegion(k)171     : MemRegion(k), Mgr(mgr) {
172     assert(classof(this));
173   }
174 
getMemRegionManager()175   MemRegionManager* getMemRegionManager() const { return Mgr; }
176 
177 public:
isBoundable()178   bool isBoundable() const { return false; }
179 
180   void Profile(llvm::FoldingSetNodeID &ID) const;
181 
classof(const MemRegion * R)182   static bool classof(const MemRegion *R) {
183     Kind k = R->getKind();
184     return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
185   }
186 };
187 
188 class GlobalsSpaceRegion : public MemSpaceRegion {
189   virtual void anchor();
190 protected:
GlobalsSpaceRegion(MemRegionManager * mgr,Kind k)191   GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
192     : MemSpaceRegion(mgr, k) {}
193 public:
classof(const MemRegion * R)194   static bool classof(const MemRegion *R) {
195     Kind k = R->getKind();
196     return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
197   }
198 };
199 
200 /// \class The region of the static variables within the current CodeTextRegion
201 /// scope.
202 /// Currently, only the static locals are placed there, so we know that these
203 /// variables do not get invalidated by calls to other functions.
204 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
205   friend class MemRegionManager;
206 
207   const CodeTextRegion *CR;
208 
StaticGlobalSpaceRegion(MemRegionManager * mgr,const CodeTextRegion * cr)209   StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
210     : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
211 
212 public:
213   void Profile(llvm::FoldingSetNodeID &ID) const;
214 
215   void dumpToStream(raw_ostream &os) const;
216 
getCodeRegion()217   const CodeTextRegion *getCodeRegion() const { return CR; }
218 
classof(const MemRegion * R)219   static bool classof(const MemRegion *R) {
220     return R->getKind() == StaticGlobalSpaceRegionKind;
221   }
222 };
223 
224 /// \class The region for all the non-static global variables.
225 ///
226 /// This class is further split into subclasses for efficient implementation of
227 /// invalidating a set of related global values as is done in
228 /// RegionStoreManager::invalidateRegions (instead of finding all the dependent
229 /// globals, we invalidate the whole parent region).
230 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
231   friend class MemRegionManager;
232 
233 protected:
NonStaticGlobalSpaceRegion(MemRegionManager * mgr,Kind k)234   NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
235     : GlobalsSpaceRegion(mgr, k) {}
236 
237 public:
238 
239   void dumpToStream(raw_ostream &os) const;
240 
classof(const MemRegion * R)241   static bool classof(const MemRegion *R) {
242     Kind k = R->getKind();
243     return k >= BEG_NON_STATIC_GLOBAL_MEMSPACES &&
244            k <= END_NON_STATIC_GLOBAL_MEMSPACES;
245   }
246 };
247 
248 /// \class The region containing globals which are defined in system/external
249 /// headers and are considered modifiable by system calls (ex: errno).
250 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
251   friend class MemRegionManager;
252 
GlobalSystemSpaceRegion(MemRegionManager * mgr)253   GlobalSystemSpaceRegion(MemRegionManager *mgr)
254     : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
255 
256 public:
257 
258   void dumpToStream(raw_ostream &os) const;
259 
classof(const MemRegion * R)260   static bool classof(const MemRegion *R) {
261     return R->getKind() == GlobalSystemSpaceRegionKind;
262   }
263 };
264 
265 /// \class The region containing globals which are considered not to be modified
266 /// or point to data which could be modified as a result of a function call
267 /// (system or internal). Ex: Const global scalars would be modeled as part of
268 /// this region. This region also includes most system globals since they have
269 /// low chance of being modified.
270 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
271   friend class MemRegionManager;
272 
GlobalImmutableSpaceRegion(MemRegionManager * mgr)273   GlobalImmutableSpaceRegion(MemRegionManager *mgr)
274     : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
275 
276 public:
277 
278   void dumpToStream(raw_ostream &os) const;
279 
classof(const MemRegion * R)280   static bool classof(const MemRegion *R) {
281     return R->getKind() == GlobalImmutableSpaceRegionKind;
282   }
283 };
284 
285 /// \class The region containing globals which can be modified by calls to
286 /// "internally" defined functions - (for now just) functions other then system
287 /// calls.
288 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
289   friend class MemRegionManager;
290 
GlobalInternalSpaceRegion(MemRegionManager * mgr)291   GlobalInternalSpaceRegion(MemRegionManager *mgr)
292     : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
293 
294 public:
295 
296   void dumpToStream(raw_ostream &os) const;
297 
classof(const MemRegion * R)298   static bool classof(const MemRegion *R) {
299     return R->getKind() == GlobalInternalSpaceRegionKind;
300   }
301 };
302 
303 class HeapSpaceRegion : public MemSpaceRegion {
304   virtual void anchor();
305   friend class MemRegionManager;
306 
HeapSpaceRegion(MemRegionManager * mgr)307   HeapSpaceRegion(MemRegionManager *mgr)
308     : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
309 public:
classof(const MemRegion * R)310   static bool classof(const MemRegion *R) {
311     return R->getKind() == HeapSpaceRegionKind;
312   }
313 };
314 
315 class UnknownSpaceRegion : public MemSpaceRegion {
316   virtual void anchor();
317   friend class MemRegionManager;
UnknownSpaceRegion(MemRegionManager * mgr)318   UnknownSpaceRegion(MemRegionManager *mgr)
319     : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
320 public:
classof(const MemRegion * R)321   static bool classof(const MemRegion *R) {
322     return R->getKind() == UnknownSpaceRegionKind;
323   }
324 };
325 
326 class StackSpaceRegion : public MemSpaceRegion {
327 private:
328   const StackFrameContext *SFC;
329 
330 protected:
StackSpaceRegion(MemRegionManager * mgr,Kind k,const StackFrameContext * sfc)331   StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
332     : MemSpaceRegion(mgr, k), SFC(sfc) {
333     assert(classof(this));
334   }
335 
336 public:
getStackFrame()337   const StackFrameContext *getStackFrame() const { return SFC; }
338 
339   void Profile(llvm::FoldingSetNodeID &ID) const;
340 
classof(const MemRegion * R)341   static bool classof(const MemRegion *R) {
342     Kind k = R->getKind();
343     return k >= StackLocalsSpaceRegionKind &&
344            k <= StackArgumentsSpaceRegionKind;
345   }
346 };
347 
348 class StackLocalsSpaceRegion : public StackSpaceRegion {
349   virtual void anchor();
350   friend class MemRegionManager;
StackLocalsSpaceRegion(MemRegionManager * mgr,const StackFrameContext * sfc)351   StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
352     : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
353 public:
classof(const MemRegion * R)354   static bool classof(const MemRegion *R) {
355     return R->getKind() == StackLocalsSpaceRegionKind;
356   }
357 };
358 
359 class StackArgumentsSpaceRegion : public StackSpaceRegion {
360 private:
361   virtual void anchor();
362   friend class MemRegionManager;
StackArgumentsSpaceRegion(MemRegionManager * mgr,const StackFrameContext * sfc)363   StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
364     : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
365 public:
classof(const MemRegion * R)366   static bool classof(const MemRegion *R) {
367     return R->getKind() == StackArgumentsSpaceRegionKind;
368   }
369 };
370 
371 
372 /// SubRegion - A region that subsets another larger region.  Most regions
373 ///  are subclasses of SubRegion.
374 class SubRegion : public MemRegion {
375 private:
376   virtual void anchor();
377 protected:
378   const MemRegion* superRegion;
SubRegion(const MemRegion * sReg,Kind k)379   SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
380 public:
getSuperRegion()381   const MemRegion* getSuperRegion() const {
382     return superRegion;
383   }
384 
385   /// getExtent - Returns the size of the region in bytes.
getExtent(SValBuilder & svalBuilder)386   virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
387     return UnknownVal();
388   }
389 
390   MemRegionManager* getMemRegionManager() const;
391 
392   bool isSubRegionOf(const MemRegion* R) const;
393 
classof(const MemRegion * R)394   static bool classof(const MemRegion* R) {
395     return R->getKind() > END_MEMSPACES;
396   }
397 };
398 
399 //===----------------------------------------------------------------------===//
400 // MemRegion subclasses.
401 //===----------------------------------------------------------------------===//
402 
403 /// AllocaRegion - A region that represents an untyped blob of bytes created
404 ///  by a call to 'alloca'.
405 class AllocaRegion : public SubRegion {
406   friend class MemRegionManager;
407 protected:
408   unsigned Cnt; // Block counter.  Used to distinguish different pieces of
409                 // memory allocated by alloca at the same call site.
410   const Expr *Ex;
411 
AllocaRegion(const Expr * ex,unsigned cnt,const MemRegion * superRegion)412   AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion)
413     : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
414 
415 public:
416 
getExpr()417   const Expr *getExpr() const { return Ex; }
418 
isBoundable()419   bool isBoundable() const { return true; }
420 
421   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
422 
423   void Profile(llvm::FoldingSetNodeID& ID) const;
424 
425   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
426                             unsigned Cnt, const MemRegion *superRegion);
427 
428   void dumpToStream(raw_ostream &os) const;
429 
classof(const MemRegion * R)430   static bool classof(const MemRegion* R) {
431     return R->getKind() == AllocaRegionKind;
432   }
433 };
434 
435 /// TypedRegion - An abstract class representing regions that are typed.
436 class TypedRegion : public SubRegion {
437 public:
438   virtual void anchor();
439 protected:
TypedRegion(const MemRegion * sReg,Kind k)440   TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
441 
442 public:
443   virtual QualType getLocationType() const = 0;
444 
getDesugaredLocationType(ASTContext & Context)445   QualType getDesugaredLocationType(ASTContext &Context) const {
446     return getLocationType().getDesugaredType(Context);
447   }
448 
isBoundable()449   bool isBoundable() const { return true; }
450 
classof(const MemRegion * R)451   static bool classof(const MemRegion* R) {
452     unsigned k = R->getKind();
453     return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
454   }
455 };
456 
457 /// TypedValueRegion - An abstract class representing regions having a typed value.
458 class TypedValueRegion : public TypedRegion {
459 public:
460   virtual void anchor();
461 protected:
TypedValueRegion(const MemRegion * sReg,Kind k)462   TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
463 
464 public:
465   virtual QualType getValueType() const = 0;
466 
getLocationType()467   virtual QualType getLocationType() const {
468     // FIXME: We can possibly optimize this later to cache this value.
469     QualType T = getValueType();
470     ASTContext &ctx = getContext();
471     if (T->getAs<ObjCObjectType>())
472       return ctx.getObjCObjectPointerType(T);
473     return ctx.getPointerType(getValueType());
474   }
475 
getDesugaredValueType(ASTContext & Context)476   QualType getDesugaredValueType(ASTContext &Context) const {
477     QualType T = getValueType();
478     return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
479   }
480 
classof(const MemRegion * R)481   static bool classof(const MemRegion* R) {
482     unsigned k = R->getKind();
483     return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
484   }
485 };
486 
487 
488 class CodeTextRegion : public TypedRegion {
489 public:
490   virtual void anchor();
491 protected:
CodeTextRegion(const MemRegion * sreg,Kind k)492   CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
493 public:
isBoundable()494   bool isBoundable() const { return false; }
495 
classof(const MemRegion * R)496   static bool classof(const MemRegion* R) {
497     Kind k = R->getKind();
498     return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
499   }
500 };
501 
502 /// FunctionTextRegion - A region that represents code texts of function.
503 class FunctionTextRegion : public CodeTextRegion {
504   const FunctionDecl *FD;
505 public:
FunctionTextRegion(const FunctionDecl * fd,const MemRegion * sreg)506   FunctionTextRegion(const FunctionDecl *fd, const MemRegion* sreg)
507     : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {}
508 
getLocationType()509   QualType getLocationType() const {
510     return getContext().getPointerType(FD->getType());
511   }
512 
getDecl()513   const FunctionDecl *getDecl() const {
514     return FD;
515   }
516 
517   virtual void dumpToStream(raw_ostream &os) const;
518 
519   void Profile(llvm::FoldingSetNodeID& ID) const;
520 
521   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD,
522                             const MemRegion*);
523 
classof(const MemRegion * R)524   static bool classof(const MemRegion* R) {
525     return R->getKind() == FunctionTextRegionKind;
526   }
527 };
528 
529 
530 /// BlockTextRegion - A region that represents code texts of blocks (closures).
531 ///  Blocks are represented with two kinds of regions.  BlockTextRegions
532 ///  represent the "code", while BlockDataRegions represent instances of blocks,
533 ///  which correspond to "code+data".  The distinction is important, because
534 ///  like a closure a block captures the values of externally referenced
535 ///  variables.
536 class BlockTextRegion : public CodeTextRegion {
537   friend class MemRegionManager;
538 
539   const BlockDecl *BD;
540   AnalysisDeclContext *AC;
541   CanQualType locTy;
542 
BlockTextRegion(const BlockDecl * bd,CanQualType lTy,AnalysisDeclContext * ac,const MemRegion * sreg)543   BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
544                   AnalysisDeclContext *ac, const MemRegion* sreg)
545     : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
546 
547 public:
getLocationType()548   QualType getLocationType() const {
549     return locTy;
550   }
551 
getDecl()552   const BlockDecl *getDecl() const {
553     return BD;
554   }
555 
getAnalysisDeclContext()556   AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
557 
558   virtual void dumpToStream(raw_ostream &os) const;
559 
560   void Profile(llvm::FoldingSetNodeID& ID) const;
561 
562   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
563                             CanQualType, const AnalysisDeclContext*,
564                             const MemRegion*);
565 
classof(const MemRegion * R)566   static bool classof(const MemRegion* R) {
567     return R->getKind() == BlockTextRegionKind;
568   }
569 };
570 
571 /// BlockDataRegion - A region that represents a block instance.
572 ///  Blocks are represented with two kinds of regions.  BlockTextRegions
573 ///  represent the "code", while BlockDataRegions represent instances of blocks,
574 ///  which correspond to "code+data".  The distinction is important, because
575 ///  like a closure a block captures the values of externally referenced
576 ///  variables.
577 class BlockDataRegion : public SubRegion {
578   friend class MemRegionManager;
579   const BlockTextRegion *BC;
580   const LocationContext *LC; // Can be null */
581   void *ReferencedVars;
582 
BlockDataRegion(const BlockTextRegion * bc,const LocationContext * lc,const MemRegion * sreg)583   BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
584                   const MemRegion *sreg)
585   : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {}
586 
587 public:
getCodeRegion()588   const BlockTextRegion *getCodeRegion() const { return BC; }
589 
getDecl()590   const BlockDecl *getDecl() const { return BC->getDecl(); }
591 
592   class referenced_vars_iterator {
593     const MemRegion * const *R;
594   public:
referenced_vars_iterator(const MemRegion * const * r)595     explicit referenced_vars_iterator(const MemRegion * const *r) : R(r) {}
596 
597     operator const MemRegion * const *() const {
598       return R;
599     }
600 
601     const VarRegion* operator*() const {
602       return cast<VarRegion>(*R);
603     }
604 
605     bool operator==(const referenced_vars_iterator &I) const {
606       return I.R == R;
607     }
608     bool operator!=(const referenced_vars_iterator &I) const {
609       return I.R != R;
610     }
611     referenced_vars_iterator &operator++() {
612       ++R;
613       return *this;
614     }
615   };
616 
617   referenced_vars_iterator referenced_vars_begin() const;
618   referenced_vars_iterator referenced_vars_end() const;
619 
620   virtual void dumpToStream(raw_ostream &os) const;
621 
622   void Profile(llvm::FoldingSetNodeID& ID) const;
623 
624   static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
625                             const LocationContext *, const MemRegion *);
626 
classof(const MemRegion * R)627   static bool classof(const MemRegion* R) {
628     return R->getKind() == BlockDataRegionKind;
629   }
630 private:
631   void LazyInitializeReferencedVars();
632 };
633 
634 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region
635 ///  clases, SymbolicRegion represents a region that serves as an alias for
636 ///  either a real region, a NULL pointer, etc.  It essentially is used to
637 ///  map the concept of symbolic values into the domain of regions.  Symbolic
638 ///  regions do not need to be typed.
639 class SymbolicRegion : public SubRegion {
640 protected:
641   const SymbolRef sym;
642 
643 public:
SymbolicRegion(const SymbolRef s,const MemRegion * sreg)644   SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
645     : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
646 
getSymbol()647   SymbolRef getSymbol() const {
648     return sym;
649   }
650 
isBoundable()651   bool isBoundable() const { return true; }
652 
653   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
654 
655   void Profile(llvm::FoldingSetNodeID& ID) const;
656 
657   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
658                             SymbolRef sym,
659                             const MemRegion* superRegion);
660 
661   void dumpToStream(raw_ostream &os) const;
662 
classof(const MemRegion * R)663   static bool classof(const MemRegion* R) {
664     return R->getKind() == SymbolicRegionKind;
665   }
666 };
667 
668 /// StringRegion - Region associated with a StringLiteral.
669 class StringRegion : public TypedValueRegion {
670   friend class MemRegionManager;
671   const StringLiteral* Str;
672 protected:
673 
StringRegion(const StringLiteral * str,const MemRegion * sreg)674   StringRegion(const StringLiteral* str, const MemRegion* sreg)
675     : TypedValueRegion(sreg, StringRegionKind), Str(str) {}
676 
677   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
678                             const StringLiteral* Str,
679                             const MemRegion* superRegion);
680 
681 public:
682 
getStringLiteral()683   const StringLiteral* getStringLiteral() const { return Str; }
684 
getValueType()685   QualType getValueType() const {
686     return Str->getType();
687   }
688 
689   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
690 
isBoundable()691   bool isBoundable() const { return false; }
692 
Profile(llvm::FoldingSetNodeID & ID)693   void Profile(llvm::FoldingSetNodeID& ID) const {
694     ProfileRegion(ID, Str, superRegion);
695   }
696 
697   void dumpToStream(raw_ostream &os) const;
698 
classof(const MemRegion * R)699   static bool classof(const MemRegion* R) {
700     return R->getKind() == StringRegionKind;
701   }
702 };
703 
704 /// The region associated with an ObjCStringLiteral.
705 class ObjCStringRegion : public TypedValueRegion {
706   friend class MemRegionManager;
707   const ObjCStringLiteral* Str;
708 protected:
709 
ObjCStringRegion(const ObjCStringLiteral * str,const MemRegion * sreg)710   ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg)
711   : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {}
712 
713   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
714                             const ObjCStringLiteral* Str,
715                             const MemRegion* superRegion);
716 
717 public:
718 
getObjCStringLiteral()719   const ObjCStringLiteral* getObjCStringLiteral() const { return Str; }
720 
getValueType()721   QualType getValueType() const {
722     return Str->getType();
723   }
724 
isBoundable()725   bool isBoundable() const { return false; }
726 
Profile(llvm::FoldingSetNodeID & ID)727   void Profile(llvm::FoldingSetNodeID& ID) const {
728     ProfileRegion(ID, Str, superRegion);
729   }
730 
731   void dumpToStream(raw_ostream &os) const;
732 
classof(const MemRegion * R)733   static bool classof(const MemRegion* R) {
734     return R->getKind() == ObjCStringRegionKind;
735   }
736 };
737 
738 /// CompoundLiteralRegion - A memory region representing a compound literal.
739 ///   Compound literals are essentially temporaries that are stack allocated
740 ///   or in the global constant pool.
741 class CompoundLiteralRegion : public TypedValueRegion {
742 private:
743   friend class MemRegionManager;
744   const CompoundLiteralExpr *CL;
745 
CompoundLiteralRegion(const CompoundLiteralExpr * cl,const MemRegion * sReg)746   CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg)
747     : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
748 
749   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
750                             const CompoundLiteralExpr *CL,
751                             const MemRegion* superRegion);
752 public:
getValueType()753   QualType getValueType() const {
754     return CL->getType();
755   }
756 
isBoundable()757   bool isBoundable() const { return !CL->isFileScope(); }
758 
759   void Profile(llvm::FoldingSetNodeID& ID) const;
760 
761   void dumpToStream(raw_ostream &os) const;
762 
getLiteralExpr()763   const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
764 
classof(const MemRegion * R)765   static bool classof(const MemRegion* R) {
766     return R->getKind() == CompoundLiteralRegionKind;
767   }
768 };
769 
770 class DeclRegion : public TypedValueRegion {
771 protected:
772   const Decl *D;
773 
DeclRegion(const Decl * d,const MemRegion * sReg,Kind k)774   DeclRegion(const Decl *d, const MemRegion* sReg, Kind k)
775     : TypedValueRegion(sReg, k), D(d) {}
776 
777   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
778                       const MemRegion* superRegion, Kind k);
779 
780 public:
getDecl()781   const Decl *getDecl() const { return D; }
782   void Profile(llvm::FoldingSetNodeID& ID) const;
783 
784   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
785 
classof(const MemRegion * R)786   static bool classof(const MemRegion* R) {
787     unsigned k = R->getKind();
788     return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
789   }
790 };
791 
792 class VarRegion : public DeclRegion {
793   friend class MemRegionManager;
794 
795   // Constructors and private methods.
VarRegion(const VarDecl * vd,const MemRegion * sReg)796   VarRegion(const VarDecl *vd, const MemRegion* sReg)
797     : DeclRegion(vd, sReg, VarRegionKind) {}
798 
ProfileRegion(llvm::FoldingSetNodeID & ID,const VarDecl * VD,const MemRegion * superRegion)799   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
800                             const MemRegion *superRegion) {
801     DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
802   }
803 
804   void Profile(llvm::FoldingSetNodeID& ID) const;
805 
806 public:
getDecl()807   const VarDecl *getDecl() const { return cast<VarDecl>(D); }
808 
809   const StackFrameContext *getStackFrame() const;
810 
getValueType()811   QualType getValueType() const {
812     // FIXME: We can cache this if needed.
813     return getDecl()->getType();
814   }
815 
816   void dumpToStream(raw_ostream &os) const;
817 
classof(const MemRegion * R)818   static bool classof(const MemRegion* R) {
819     return R->getKind() == VarRegionKind;
820   }
821 
822   void dumpPretty(raw_ostream &os) const;
823 };
824 
825 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
826 ///  in a call to a C++ method.  This region doesn't represent the object
827 ///  referred to by 'this', but rather 'this' itself.
828 class CXXThisRegion : public TypedValueRegion {
829   friend class MemRegionManager;
CXXThisRegion(const PointerType * thisPointerTy,const MemRegion * sReg)830   CXXThisRegion(const PointerType *thisPointerTy,
831                 const MemRegion *sReg)
832     : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
833 
834   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
835                             const PointerType *PT,
836                             const MemRegion *sReg);
837 
838   void Profile(llvm::FoldingSetNodeID &ID) const;
839 
840 public:
getValueType()841   QualType getValueType() const {
842     return QualType(ThisPointerTy, 0);
843   }
844 
845   void dumpToStream(raw_ostream &os) const;
846 
classof(const MemRegion * R)847   static bool classof(const MemRegion* R) {
848     return R->getKind() == CXXThisRegionKind;
849   }
850 
851 private:
852   const PointerType *ThisPointerTy;
853 };
854 
855 class FieldRegion : public DeclRegion {
856   friend class MemRegionManager;
857 
FieldRegion(const FieldDecl * fd,const MemRegion * sReg)858   FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
859     : DeclRegion(fd, sReg, FieldRegionKind) {}
860 
861 public:
getDecl()862   const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
863 
getValueType()864   QualType getValueType() const {
865     // FIXME: We can cache this if needed.
866     return getDecl()->getType();
867   }
868 
869   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
870 
ProfileRegion(llvm::FoldingSetNodeID & ID,const FieldDecl * FD,const MemRegion * superRegion)871   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
872                             const MemRegion* superRegion) {
873     DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
874   }
875 
classof(const MemRegion * R)876   static bool classof(const MemRegion* R) {
877     return R->getKind() == FieldRegionKind;
878   }
879 
880   void dumpToStream(raw_ostream &os) const;
881   void dumpPretty(raw_ostream &os) const;
882 };
883 
884 class ObjCIvarRegion : public DeclRegion {
885 
886   friend class MemRegionManager;
887 
888   ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg);
889 
890   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
891                             const MemRegion* superRegion);
892 
893 public:
894   const ObjCIvarDecl *getDecl() const;
895   QualType getValueType() const;
896 
897   void dumpToStream(raw_ostream &os) const;
898 
classof(const MemRegion * R)899   static bool classof(const MemRegion* R) {
900     return R->getKind() == ObjCIvarRegionKind;
901   }
902 };
903 //===----------------------------------------------------------------------===//
904 // Auxiliary data classes for use with MemRegions.
905 //===----------------------------------------------------------------------===//
906 
907 class ElementRegion;
908 
909 class RegionRawOffset {
910 private:
911   friend class ElementRegion;
912 
913   const MemRegion *Region;
914   CharUnits Offset;
915 
916   RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
Region(reg)917     : Region(reg), Offset(offset) {}
918 
919 public:
920   // FIXME: Eventually support symbolic offsets.
getOffset()921   CharUnits getOffset() const { return Offset; }
getRegion()922   const MemRegion *getRegion() const { return Region; }
923 
924   void dumpToStream(raw_ostream &os) const;
925   void dump() const;
926 };
927 
928 /// \brief ElementRegin is used to represent both array elements and casts.
929 class ElementRegion : public TypedValueRegion {
930   friend class MemRegionManager;
931 
932   QualType ElementType;
933   NonLoc Index;
934 
ElementRegion(QualType elementType,NonLoc Idx,const MemRegion * sReg)935   ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
936     : TypedValueRegion(sReg, ElementRegionKind),
937       ElementType(elementType), Index(Idx) {
938     assert((!isa<nonloc::ConcreteInt>(&Idx) ||
939            cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
940            "The index must be signed");
941   }
942 
943   static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
944                             SVal Idx, const MemRegion* superRegion);
945 
946 public:
947 
getIndex()948   NonLoc getIndex() const { return Index; }
949 
getValueType()950   QualType getValueType() const {
951     return ElementType;
952   }
953 
getElementType()954   QualType getElementType() const {
955     return ElementType;
956   }
957   /// Compute the offset within the array. The array might also be a subobject.
958   RegionRawOffset getAsArrayOffset() const;
959 
960   void dumpToStream(raw_ostream &os) const;
961 
962   void Profile(llvm::FoldingSetNodeID& ID) const;
963 
classof(const MemRegion * R)964   static bool classof(const MemRegion* R) {
965     return R->getKind() == ElementRegionKind;
966   }
967 };
968 
969 // C++ temporary object associated with an expression.
970 class CXXTempObjectRegion : public TypedValueRegion {
971   friend class MemRegionManager;
972 
973   Expr const *Ex;
974 
CXXTempObjectRegion(Expr const * E,MemRegion const * sReg)975   CXXTempObjectRegion(Expr const *E, MemRegion const *sReg)
976     : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {}
977 
978   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
979                             Expr const *E, const MemRegion *sReg);
980 
981 public:
getExpr()982   const Expr *getExpr() const { return Ex; }
983 
getValueType()984   QualType getValueType() const {
985     return Ex->getType();
986   }
987 
988   void dumpToStream(raw_ostream &os) const;
989 
990   void Profile(llvm::FoldingSetNodeID &ID) const;
991 
classof(const MemRegion * R)992   static bool classof(const MemRegion* R) {
993     return R->getKind() == CXXTempObjectRegionKind;
994   }
995 };
996 
997 // CXXBaseObjectRegion represents a base object within a C++ object. It is
998 // identified by the base class declaration and the region of its parent object.
999 class CXXBaseObjectRegion : public TypedValueRegion {
1000   friend class MemRegionManager;
1001 
1002   const CXXRecordDecl *decl;
1003 
CXXBaseObjectRegion(const CXXRecordDecl * d,const MemRegion * sReg)1004   CXXBaseObjectRegion(const CXXRecordDecl *d, const MemRegion *sReg)
1005     : TypedValueRegion(sReg, CXXBaseObjectRegionKind), decl(d) {}
1006 
1007   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1008                             const CXXRecordDecl *decl, const MemRegion *sReg);
1009 
1010 public:
getDecl()1011   const CXXRecordDecl *getDecl() const { return decl; }
1012 
1013   QualType getValueType() const;
1014 
1015   void dumpToStream(raw_ostream &os) const;
1016 
1017   void Profile(llvm::FoldingSetNodeID &ID) const;
1018 
classof(const MemRegion * region)1019   static bool classof(const MemRegion *region) {
1020     return region->getKind() == CXXBaseObjectRegionKind;
1021   }
1022 };
1023 
1024 template<typename RegionTy>
getAs()1025 const RegionTy* MemRegion::getAs() const {
1026   if (const RegionTy* RT = dyn_cast<RegionTy>(this))
1027     return RT;
1028 
1029   return NULL;
1030 }
1031 
1032 //===----------------------------------------------------------------------===//
1033 // MemRegionManager - Factory object for creating regions.
1034 //===----------------------------------------------------------------------===//
1035 
1036 class MemRegionManager {
1037   ASTContext &C;
1038   llvm::BumpPtrAllocator& A;
1039   llvm::FoldingSet<MemRegion> Regions;
1040 
1041   GlobalInternalSpaceRegion *InternalGlobals;
1042   GlobalSystemSpaceRegion *SystemGlobals;
1043   GlobalImmutableSpaceRegion *ImmutableGlobals;
1044 
1045 
1046   llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1047     StackLocalsSpaceRegions;
1048   llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1049     StackArgumentsSpaceRegions;
1050   llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1051     StaticsGlobalSpaceRegions;
1052 
1053   HeapSpaceRegion *heap;
1054   UnknownSpaceRegion *unknown;
1055   MemSpaceRegion *code;
1056 
1057 public:
MemRegionManager(ASTContext & c,llvm::BumpPtrAllocator & a)1058   MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
1059     : C(c), A(a), InternalGlobals(0), SystemGlobals(0), ImmutableGlobals(0),
1060       heap(0), unknown(0), code(0) {}
1061 
1062   ~MemRegionManager();
1063 
getContext()1064   ASTContext &getContext() { return C; }
1065 
getAllocator()1066   llvm::BumpPtrAllocator &getAllocator() { return A; }
1067 
1068   /// getStackLocalsRegion - Retrieve the memory region associated with the
1069   ///  specified stack frame.
1070   const StackLocalsSpaceRegion *
1071   getStackLocalsRegion(const StackFrameContext *STC);
1072 
1073   /// getStackArgumentsRegion - Retrieve the memory region associated with
1074   ///  function/method arguments of the specified stack frame.
1075   const StackArgumentsSpaceRegion *
1076   getStackArgumentsRegion(const StackFrameContext *STC);
1077 
1078   /// getGlobalsRegion - Retrieve the memory region associated with
1079   ///  global variables.
1080   const GlobalsSpaceRegion *getGlobalsRegion(
1081       MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1082       const CodeTextRegion *R = 0);
1083 
1084   /// getHeapRegion - Retrieve the memory region associated with the
1085   ///  generic "heap".
1086   const HeapSpaceRegion *getHeapRegion();
1087 
1088   /// getUnknownRegion - Retrieve the memory region associated with unknown
1089   /// memory space.
1090   const MemSpaceRegion *getUnknownRegion();
1091 
1092   const MemSpaceRegion *getCodeRegion();
1093 
1094   /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1095   const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1096                                       const LocationContext *LC);
1097 
1098   /// getCompoundLiteralRegion - Retrieve the region associated with a
1099   ///  given CompoundLiteral.
1100   const CompoundLiteralRegion*
1101   getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1102                            const LocationContext *LC);
1103 
1104   /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1105   ///  parameter 'this'.
1106   const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1107                                         const LocationContext *LC);
1108 
1109   /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
1110   const SymbolicRegion* getSymbolicRegion(SymbolRef sym);
1111 
1112   const StringRegion *getStringRegion(const StringLiteral* Str);
1113 
1114   const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1115 
1116   /// getVarRegion - Retrieve or create the memory region associated with
1117   ///  a specified VarDecl and LocationContext.
1118   const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
1119 
1120   /// getVarRegion - Retrieve or create the memory region associated with
1121   ///  a specified VarDecl and super region.
1122   const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
1123 
1124   /// getElementRegion - Retrieve the memory region associated with the
1125   ///  associated element type, index, and super region.
1126   const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1127                                         const MemRegion *superRegion,
1128                                         ASTContext &Ctx);
1129 
getElementRegionWithSuper(const ElementRegion * ER,const MemRegion * superRegion)1130   const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1131                                                  const MemRegion *superRegion) {
1132     return getElementRegion(ER->getElementType(), ER->getIndex(),
1133                             superRegion, ER->getContext());
1134   }
1135 
1136   /// getFieldRegion - Retrieve or create the memory region associated with
1137   ///  a specified FieldDecl.  'superRegion' corresponds to the containing
1138   ///  memory region (which typically represents the memory representing
1139   ///  a structure or class).
1140   const FieldRegion *getFieldRegion(const FieldDecl *fd,
1141                                     const MemRegion* superRegion);
1142 
getFieldRegionWithSuper(const FieldRegion * FR,const MemRegion * superRegion)1143   const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1144                                              const MemRegion *superRegion) {
1145     return getFieldRegion(FR->getDecl(), superRegion);
1146   }
1147 
1148   /// getObjCIvarRegion - Retrieve or create the memory region associated with
1149   ///   a specified Objective-c instance variable.  'superRegion' corresponds
1150   ///   to the containing region (which typically represents the Objective-C
1151   ///   object).
1152   const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1153                                           const MemRegion* superRegion);
1154 
1155   const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1156                                                     LocationContext const *LC);
1157 
1158   const CXXBaseObjectRegion *getCXXBaseObjectRegion(const CXXRecordDecl *decl,
1159                                                   const MemRegion *superRegion);
1160 
1161   /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1162   /// super region.
1163   const CXXBaseObjectRegion *
getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion * baseReg,const MemRegion * superRegion)1164   getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1165                                   const MemRegion *superRegion) {
1166     return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion);
1167   }
1168 
1169   const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
1170   const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
1171                                             CanQualType locTy,
1172                                             AnalysisDeclContext *AC);
1173 
1174   /// getBlockDataRegion - Get the memory region associated with an instance
1175   ///  of a block.  Unlike many other MemRegions, the LocationContext*
1176   ///  argument is allowed to be NULL for cases where we have no known
1177   ///  context.
1178   const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
1179                                             const LocationContext *lc = NULL);
1180 
1181 private:
1182   template <typename RegionTy, typename A1>
1183   RegionTy* getRegion(const A1 a1);
1184 
1185   template <typename RegionTy, typename A1>
1186   RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
1187 
1188   template <typename RegionTy, typename A1, typename A2>
1189   RegionTy* getRegion(const A1 a1, const A2 a2);
1190 
1191   template <typename RegionTy, typename A1, typename A2>
1192   RegionTy* getSubRegion(const A1 a1, const A2 a2,
1193                          const MemRegion* superRegion);
1194 
1195   template <typename RegionTy, typename A1, typename A2, typename A3>
1196   RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
1197                          const MemRegion* superRegion);
1198 
1199   template <typename REG>
1200   const REG* LazyAllocate(REG*& region);
1201 
1202   template <typename REG, typename ARG>
1203   const REG* LazyAllocate(REG*& region, ARG a);
1204 };
1205 
1206 //===----------------------------------------------------------------------===//
1207 // Out-of-line member definitions.
1208 //===----------------------------------------------------------------------===//
1209 
getContext()1210 inline ASTContext &MemRegion::getContext() const {
1211   return getMemRegionManager()->getContext();
1212 }
1213 
1214 } // end GR namespace
1215 
1216 } // end clang namespace
1217 
1218 //===----------------------------------------------------------------------===//
1219 // Pretty-printing regions.
1220 //===----------------------------------------------------------------------===//
1221 
1222 namespace llvm {
1223 static inline raw_ostream &operator<<(raw_ostream &os,
1224                                       const clang::ento::MemRegion* R) {
1225   R->dumpToStream(os);
1226   return os;
1227 }
1228 } // end llvm namespace
1229 
1230 #endif
1231