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