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