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