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