MemRegion.h revision 234353
1194676Sthompsa//== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==//
2194676Sthompsa//
3194676Sthompsa//                     The LLVM Compiler Infrastructure
4194676Sthompsa//
5194676Sthompsa// This file is distributed under the University of Illinois Open Source
6194676Sthompsa// License. See LICENSE.TXT for details.
7194676Sthompsa//
8194676Sthompsa//===----------------------------------------------------------------------===//
9194676Sthompsa//
10194676Sthompsa//  This file defines MemRegion and its subclasses.  MemRegion defines a
11194676Sthompsa//  partially-typed abstraction of memory useful for path-sensitive dataflow
12194676Sthompsa//  analyses.
13194676Sthompsa//
14194676Sthompsa//===----------------------------------------------------------------------===//
15194676Sthompsa
16194676Sthompsa#ifndef LLVM_CLANG_GR_MEMREGION_H
17194676Sthompsa#define LLVM_CLANG_GR_MEMREGION_H
18194676Sthompsa
19194676Sthompsa#include "clang/AST/CharUnits.h"
20194676Sthompsa#include "clang/AST/Decl.h"
21194676Sthompsa#include "clang/AST/ExprObjC.h"
22194676Sthompsa#include "clang/Basic/LLVM.h"
23194676Sthompsa#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
24194676Sthompsa#include "llvm/Support/ErrorHandling.h"
25194676Sthompsa#include "llvm/ADT/FoldingSet.h"
26194676Sthompsa#include <string>
27248236Shselasky
28248236Shselaskynamespace llvm {
29248236Shselaskyclass BumpPtrAllocator;
30203815Swkoszek}
31194676Sthompsa
32194676Sthompsanamespace clang {
33203815Swkoszek
34203815Swkoszekclass LocationContext;
35248236Shselaskyclass StackFrameContext;
36194676Sthompsa
37203815Swkoszeknamespace ento {
38248236Shselasky
39248236Shselaskyclass MemRegionManager;
40248236Shselaskyclass MemSpaceRegion;
41194676Sthompsaclass SValBuilder;
42208020Sthompsaclass VarRegion;
43208020Sthompsaclass CodeTextRegion;
44194676Sthompsa
45194676Sthompsa/// Represent a region's offset within the top level base region.
46194676Sthompsaclass RegionOffset {
47194676Sthompsa  /// The base region.
48194676Sthompsa  const MemRegion *R;
49194676Sthompsa
50195957Salfred  /// The bit offset within the base region. It shouldn't be negative.
51195957Salfred  int64_t Offset;
52195957Salfred
53195560Sthompsapublic:
54195560Sthompsa  RegionOffset(const MemRegion *r) : R(r), Offset(0) {}
55195957Salfred  RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
56195560Sthompsa
57195957Salfred  const MemRegion *getRegion() const { return R; }
58195957Salfred  int64_t getOffset() const { return Offset; }
59195957Salfred};
60195957Salfred
61195957Salfred//===----------------------------------------------------------------------===//
62195957Salfred// Base region classes.
63195957Salfred//===----------------------------------------------------------------------===//
64195560Sthompsa
65195560Sthompsa/// MemRegion - The root abstract class for all memory regions.
66195560Sthompsaclass MemRegion : public llvm::FoldingSetNode {
67195957Salfred  friend class MemRegionManager;
68195957Salfredpublic:
69195957Salfred  enum Kind {
70195560Sthompsa    // Memory spaces.
71195560Sthompsa    GenericMemSpaceRegionKind,
72195560Sthompsa    StackLocalsSpaceRegionKind,
73195560Sthompsa    StackArgumentsSpaceRegionKind,
74195560Sthompsa    HeapSpaceRegionKind,
75195560Sthompsa    UnknownSpaceRegionKind,
76195957Salfred    StaticGlobalSpaceRegionKind,
77195560Sthompsa    GlobalInternalSpaceRegionKind,
78195957Salfred    GlobalSystemSpaceRegionKind,
79195957Salfred    GlobalImmutableSpaceRegionKind,
80195560Sthompsa    BEG_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind,
81195957Salfred    END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
82195957Salfred    BEG_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind,
83195560Sthompsa    END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
84195957Salfred    BEG_MEMSPACES = GenericMemSpaceRegionKind,
85195957Salfred    END_MEMSPACES = GlobalImmutableSpaceRegionKind,
86195957Salfred    // Untyped regions.
87195957Salfred    SymbolicRegionKind,
88195560Sthompsa    AllocaRegionKind,
89195560Sthompsa    BlockDataRegionKind,
90195957Salfred    // Typed regions.
91195560Sthompsa    BEG_TYPED_REGIONS,
92195560Sthompsa    FunctionTextRegionKind = BEG_TYPED_REGIONS,
93195957Salfred    BlockTextRegionKind,
94195560Sthompsa    BEG_TYPED_VALUE_REGIONS,
95195957Salfred    CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS,
96195957Salfred    CXXThisRegionKind,
97195560Sthompsa    StringRegionKind,
98195957Salfred    ObjCStringRegionKind,
99195957Salfred    ElementRegionKind,
100195957Salfred    // Decl Regions.
101195957Salfred    BEG_DECL_REGIONS,
102195957Salfred    VarRegionKind = BEG_DECL_REGIONS,
103194676Sthompsa    FieldRegionKind,
104194676Sthompsa    ObjCIvarRegionKind,
105194676Sthompsa    END_DECL_REGIONS = ObjCIvarRegionKind,
106194676Sthompsa    CXXTempObjectRegionKind,
107195957Salfred    CXXBaseObjectRegionKind,
108194676Sthompsa    END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind,
109195957Salfred    END_TYPED_REGIONS = CXXBaseObjectRegionKind
110195957Salfred  };
111194676Sthompsa
112195957Salfredprivate:
113195957Salfred  const Kind kind;
114195957Salfred
115194676Sthompsaprotected:
116195560Sthompsa  MemRegion(Kind k) : kind(k) {}
117194676Sthompsa  virtual ~MemRegion();
118194676Sthompsa
119194676Sthompsapublic:
120195957Salfred  ASTContext &getContext() const;
121195957Salfred
122195957Salfred  virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
123195957Salfred
124195957Salfred  virtual MemRegionManager* getMemRegionManager() const = 0;
125195957Salfred
126195957Salfred  const MemSpaceRegion *getMemorySpace() const;
127195957Salfred
128195957Salfred  const MemRegion *getBaseRegion() const;
129195957Salfred
130195957Salfred  const MemRegion *StripCasts() const;
131194676Sthompsa
132194676Sthompsa  bool hasGlobalsOrParametersStorage() const;
133194676Sthompsa
134195957Salfred  bool hasStackStorage() const;
135195957Salfred
136195957Salfred  bool hasStackNonParametersStorage() const;
137195957Salfred
138194676Sthompsa  bool hasStackParametersStorage() const;
139195957Salfred
140195957Salfred  /// Compute the offset within the top level memory object.
141195957Salfred  RegionOffset getAsOffset() const;
142194676Sthompsa
143195957Salfred  /// \brief Get a string representation of a region for debug use.
144195957Salfred  std::string getString() const;
145195957Salfred
146195957Salfred  virtual void dumpToStream(raw_ostream &os) const;
147194676Sthompsa
148195957Salfred  void dump() const;
149213849Shselasky
150195957Salfred  /// \brief Print the region for use in diagnostics.
151195957Salfred  virtual void dumpPretty(raw_ostream &os) const;
152195957Salfred
153195957Salfred  Kind getKind() const { return kind; }
154195957Salfred
155194676Sthompsa  template<typename RegionTy> const RegionTy* getAs() const;
156195957Salfred
157194676Sthompsa  virtual bool isBoundable() const { return false; }
158213849Shselasky
159195957Salfred  static bool classof(const MemRegion*) { return true; }
160195957Salfred};
161194676Sthompsa
162199055Sthompsa/// MemSpaceRegion - A memory region that represents a "memory space";
163199055Sthompsa///  for example, the set of global variables, the stack frame, etc.
164199055Sthompsaclass MemSpaceRegion : public MemRegion {
165199055Sthompsaprotected:
166199055Sthompsa  friend class MemRegionManager;
167195957Salfred
168195957Salfred  MemRegionManager *Mgr;
169195957Salfred
170199055Sthompsa  MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
171199055Sthompsa    : MemRegion(k), Mgr(mgr) {
172195957Salfred    assert(classof(this));
173195957Salfred  }
174195957Salfred
175195957Salfred  MemRegionManager* getMemRegionManager() const { return Mgr; }
176195957Salfred
177194676Sthompsapublic:
178195957Salfred  bool isBoundable() const { return false; }
179195957Salfred
180194676Sthompsa  void Profile(llvm::FoldingSetNodeID &ID) const;
181195957Salfred
182195957Salfred  static bool classof(const MemRegion *R) {
183195957Salfred    Kind k = R->getKind();
184195957Salfred    return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
185194676Sthompsa  }
186195957Salfred};
187194676Sthompsa
188195957Salfredclass GlobalsSpaceRegion : public MemSpaceRegion {
189194676Sthompsa  virtual void anchor();
190195957Salfredprotected:
191194676Sthompsa  GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
192195957Salfred    : MemSpaceRegion(mgr, k) {}
193194676Sthompsapublic:
194195957Salfred  static bool classof(const MemRegion *R) {
195215253Shselasky    Kind k = R->getKind();
196215253Shselasky    return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
197195957Salfred  }
198195957Salfred};
199194676Sthompsa
200195957Salfred/// \class The region of the static variables within the current CodeTextRegion
201195957Salfred/// scope.
202195957Salfred/// Currently, only the static locals are placed there, so we know that these
203195957Salfred/// variables do not get invalidated by calls to other functions.
204195957Salfredclass StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
205195957Salfred  friend class MemRegionManager;
206195957Salfred
207215253Shselasky  const CodeTextRegion *CR;
208215253Shselasky
209215253Shselasky  StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
210195957Salfred    : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
211195957Salfred
212195957Salfredpublic:
213215253Shselasky  void Profile(llvm::FoldingSetNodeID &ID) const;
214215253Shselasky
215195957Salfred  void dumpToStream(raw_ostream &os) const;
216195957Salfred
217195957Salfred  const CodeTextRegion *getCodeRegion() const { return CR; }
218195957Salfred
219195957Salfred  static bool classof(const MemRegion *R) {
220195957Salfred    return R->getKind() == StaticGlobalSpaceRegionKind;
221194676Sthompsa  }
222194676Sthompsa};
223195957Salfred
224195957Salfred/// \class The region for all the non-static global variables.
225194676Sthompsa///
226195957Salfred/// This class is further split into subclasses for efficient implementation of
227194676Sthompsa/// invalidating a set of related global values as is done in
228194676Sthompsa/// RegionStoreManager::invalidateRegions (instead of finding all the dependent
229194676Sthompsa/// globals, we invalidate the whole parent region).
230194676Sthompsaclass NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
231194676Sthompsa  friend class MemRegionManager;
232195957Salfred
233194676Sthompsaprotected:
234195957Salfred  NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
235194676Sthompsa    : GlobalsSpaceRegion(mgr, k) {}
236195957Salfred
237195957Salfredpublic:
238194676Sthompsa
239194676Sthompsa  void dumpToStream(raw_ostream &os) const;
240195957Salfred
241195957Salfred  static bool classof(const MemRegion *R) {
242194676Sthompsa    Kind k = R->getKind();
243194676Sthompsa    return k >= BEG_NON_STATIC_GLOBAL_MEMSPACES &&
244195957Salfred           k <= END_NON_STATIC_GLOBAL_MEMSPACES;
245195957Salfred  }
246195957Salfred};
247195957Salfred
248195957Salfred/// \class The region containing globals which are defined in system/external
249195957Salfred/// headers and are considered modifiable by system calls (ex: errno).
250195957Salfredclass GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
251194676Sthompsa  friend class MemRegionManager;
252194676Sthompsa
253194676Sthompsa  GlobalSystemSpaceRegion(MemRegionManager *mgr)
254195957Salfred    : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
255194676Sthompsa
256195957Salfredpublic:
257195957Salfred
258195957Salfred  void dumpToStream(raw_ostream &os) const;
259195957Salfred
260194676Sthompsa  static bool classof(const MemRegion *R) {
261194676Sthompsa    return R->getKind() == GlobalSystemSpaceRegionKind;
262194676Sthompsa  }
263195957Salfred};
264194676Sthompsa
265195957Salfred/// \class The region containing globals which are considered not to be modified
266195957Salfred/// or point to data which could be modified as a result of a function call
267195957Salfred/// (system or internal). Ex: Const global scalars would be modeled as part of
268195957Salfred/// this region. This region also includes most system globals since they have
269195957Salfred/// low chance of being modified.
270195957Salfredclass GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
271194676Sthompsa  friend class MemRegionManager;
272194676Sthompsa
273194676Sthompsa  GlobalImmutableSpaceRegion(MemRegionManager *mgr)
274195957Salfred    : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
275194676Sthompsa
276195957Salfredpublic:
277195957Salfred
278194676Sthompsa  void dumpToStream(raw_ostream &os) const;
279194676Sthompsa
280194676Sthompsa  static bool classof(const MemRegion *R) {
281195957Salfred    return R->getKind() == GlobalImmutableSpaceRegionKind;
282194676Sthompsa  }
283195957Salfred};
284195957Salfred
285194676Sthompsa/// \class The region containing globals which can be modified by calls to
286194676Sthompsa/// "internally" defined functions - (for now just) functions other then system
287194676Sthompsa/// calls.
288195957Salfredclass GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
289194676Sthompsa  friend class MemRegionManager;
290195957Salfred
291195957Salfred  GlobalInternalSpaceRegion(MemRegionManager *mgr)
292194676Sthompsa    : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
293194676Sthompsa
294194676Sthompsapublic:
295195957Salfred
296194676Sthompsa  void dumpToStream(raw_ostream &os) const;
297195957Salfred
298195957Salfred  static bool classof(const MemRegion *R) {
299194676Sthompsa    return R->getKind() == GlobalInternalSpaceRegionKind;
300194676Sthompsa  }
301194676Sthompsa};
302195957Salfred
303194676Sthompsaclass HeapSpaceRegion : public MemSpaceRegion {
304194676Sthompsa  virtual void anchor();
305195957Salfred  friend class MemRegionManager;
306194676Sthompsa
307195957Salfred  HeapSpaceRegion(MemRegionManager *mgr)
308195560Sthompsa    : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
309194676Sthompsapublic:
310194676Sthompsa  static bool classof(const MemRegion *R) {
311195957Salfred    return R->getKind() == HeapSpaceRegionKind;
312195957Salfred  }
313194676Sthompsa};
314194676Sthompsa
315236944Shselaskyclass UnknownSpaceRegion : public MemSpaceRegion {
316195957Salfred  virtual void anchor();
317194676Sthompsa  friend class MemRegionManager;
318194676Sthompsa  UnknownSpaceRegion(MemRegionManager *mgr)
319236944Shselasky    : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
320236944Shselaskypublic:
321236944Shselasky  static bool classof(const MemRegion *R) {
322236944Shselasky    return R->getKind() == UnknownSpaceRegionKind;
323236944Shselasky  }
324236944Shselasky};
325195957Salfred
326194676Sthompsaclass StackSpaceRegion : public MemSpaceRegion {
327194676Sthompsaprivate:
328194676Sthompsa  const StackFrameContext *SFC;
329195957Salfred
330195957Salfredprotected:
331194676Sthompsa  StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
332195957Salfred    : MemSpaceRegion(mgr, k), SFC(sfc) {
333194676Sthompsa    assert(classof(this));
334194676Sthompsa  }
335194676Sthompsa
336194676Sthompsapublic:
337194676Sthompsa  const StackFrameContext *getStackFrame() const { return SFC; }
338194676Sthompsa
339261482Shselasky  void Profile(llvm::FoldingSetNodeID &ID) const;
340261482Shselasky
341194676Sthompsa  static bool classof(const MemRegion *R) {
342261482Shselasky    Kind k = R->getKind();
343195957Salfred    return k >= StackLocalsSpaceRegionKind &&
344195957Salfred           k <= StackArgumentsSpaceRegionKind;
345195957Salfred  }
346261482Shselasky};
347194676Sthompsa
348195957Salfredclass StackLocalsSpaceRegion : public StackSpaceRegion {
349194676Sthompsa  virtual void anchor();
350261482Shselasky  friend class MemRegionManager;
351261482Shselasky  StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
352261482Shselasky    : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
353261482Shselaskypublic:
354261482Shselasky  static bool classof(const MemRegion *R) {
355261482Shselasky    return R->getKind() == StackLocalsSpaceRegionKind;
356261482Shselasky  }
357261482Shselasky};
358261482Shselasky
359194676Sthompsaclass StackArgumentsSpaceRegion : public StackSpaceRegion {
360195957Salfredprivate:
361194676Sthompsa  virtual void anchor();
362261482Shselasky  friend class MemRegionManager;
363195957Salfred  StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
364195957Salfred    : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
365194676Sthompsapublic:
366194676Sthompsa  static bool classof(const MemRegion *R) {
367194676Sthompsa    return R->getKind() == StackArgumentsSpaceRegionKind;
368261482Shselasky  }
369261482Shselasky};
370261482Shselasky
371261482Shselasky
372261482Shselasky/// SubRegion - A region that subsets another larger region.  Most regions
373261482Shselasky///  are subclasses of SubRegion.
374261482Shselaskyclass SubRegion : public MemRegion {
375261482Shselaskyprivate:
376261482Shselasky  virtual void anchor();
377261482Shselaskyprotected:
378261482Shselasky  const MemRegion* superRegion;
379261482Shselasky  SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
380195957Salfredpublic:
381194676Sthompsa  const MemRegion* getSuperRegion() const {
382261482Shselasky    return superRegion;
383194676Sthompsa  }
384194676Sthompsa
385194676Sthompsa  /// getExtent - Returns the size of the region in bytes.
386195957Salfred  virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
387194676Sthompsa    return UnknownVal();
388195957Salfred  }
389194676Sthompsa
390195957Salfred  MemRegionManager* getMemRegionManager() const;
391194676Sthompsa
392195957Salfred  bool isSubRegionOf(const MemRegion* R) const;
393195957Salfred
394195957Salfred  static bool classof(const MemRegion* R) {
395261482Shselasky    return R->getKind() > END_MEMSPACES;
396261482Shselasky  }
397261482Shselasky};
398194676Sthompsa
399195957Salfred//===----------------------------------------------------------------------===//
400194676Sthompsa// MemRegion subclasses.
401194676Sthompsa//===----------------------------------------------------------------------===//
402194676Sthompsa
403195957Salfred/// AllocaRegion - A region that represents an untyped blob of bytes created
404194676Sthompsa///  by a call to 'alloca'.
405195957Salfredclass AllocaRegion : public SubRegion {
406195957Salfred  friend class MemRegionManager;
407195957Salfredprotected:
408194676Sthompsa  unsigned Cnt; // Block counter.  Used to distinguish different pieces of
409194676Sthompsa                // memory allocated by alloca at the same call site.
410194676Sthompsa  const Expr *Ex;
411195957Salfred
412194676Sthompsa  AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion)
413194676Sthompsa    : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
414194676Sthompsa
415195957Salfredpublic:
416194676Sthompsa
417194676Sthompsa  const Expr *getExpr() const { return Ex; }
418194676Sthompsa
419194676Sthompsa  bool isBoundable() const { return true; }
420194676Sthompsa
421194676Sthompsa  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
422250335Semaste
423195957Salfred  void Profile(llvm::FoldingSetNodeID& ID) const;
424194676Sthompsa
425195957Salfred  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
426194676Sthompsa                            unsigned Cnt, const MemRegion *superRegion);
427194676Sthompsa
428194676Sthompsa  void dumpToStream(raw_ostream &os) const;
429195957Salfred
430194676Sthompsa  static bool classof(const MemRegion* R) {
431195957Salfred    return R->getKind() == AllocaRegionKind;
432195957Salfred  }
433194676Sthompsa};
434195957Salfred
435195957Salfred/// TypedRegion - An abstract class representing regions that are typed.
436194676Sthompsaclass TypedRegion : public SubRegion {
437195957Salfredpublic:
438195957Salfred  virtual void anchor();
439195957Salfredprotected:
440194676Sthompsa  TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
441194676Sthompsa
442195957Salfredpublic:
443195957Salfred  virtual QualType getLocationType() const = 0;
444194676Sthompsa
445194676Sthompsa  QualType getDesugaredLocationType(ASTContext &Context) const {
446195957Salfred    return getLocationType().getDesugaredType(Context);
447195957Salfred  }
448250335Semaste
449194676Sthompsa  bool isBoundable() const { return true; }
450194676Sthompsa
451194676Sthompsa  static bool classof(const MemRegion* R) {
452194676Sthompsa    unsigned k = R->getKind();
453194676Sthompsa    return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
454194676Sthompsa  }
455195957Salfred};
456194676Sthompsa
457195957Salfred/// TypedValueRegion - An abstract class representing regions having a typed value.
458194676Sthompsaclass TypedValueRegion : public TypedRegion {
459195957Salfredpublic:
460195957Salfred  virtual void anchor();
461195957Salfredprotected:
462194676Sthompsa  TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
463195957Salfred
464195957Salfredpublic:
465194676Sthompsa  virtual QualType getValueType() const = 0;
466195957Salfred
467195957Salfred  virtual QualType getLocationType() const {
468194676Sthompsa    // FIXME: We can possibly optimize this later to cache this value.
469195957Salfred    QualType T = getValueType();
470194676Sthompsa    ASTContext &ctx = getContext();
471195957Salfred    if (T->getAs<ObjCObjectType>())
472195957Salfred      return ctx.getObjCObjectPointerType(T);
473195957Salfred    return ctx.getPointerType(getValueType());
474195957Salfred  }
475195957Salfred
476194676Sthompsa  QualType getDesugaredValueType(ASTContext &Context) const {
477195957Salfred    QualType T = getValueType();
478195957Salfred    return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
479194676Sthompsa  }
480195957Salfred
481195957Salfred  static bool classof(const MemRegion* R) {
482195957Salfred    unsigned k = R->getKind();
483195957Salfred    return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
484195957Salfred  }
485195957Salfred};
486194676Sthompsa
487195957Salfred
488195957Salfredclass CodeTextRegion : public TypedRegion {
489194676Sthompsapublic:
490195957Salfred  virtual void anchor();
491195957Salfredprotected:
492195957Salfred  CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
493195957Salfredpublic:
494195957Salfred  bool isBoundable() const { return false; }
495194676Sthompsa
496195957Salfred  static bool classof(const MemRegion* R) {
497194676Sthompsa    Kind k = R->getKind();
498195957Salfred    return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
499194676Sthompsa  }
500195957Salfred};
501195957Salfred
502194676Sthompsa/// FunctionTextRegion - A region that represents code texts of function.
503194676Sthompsaclass FunctionTextRegion : public CodeTextRegion {
504195957Salfred  const FunctionDecl *FD;
505195957Salfredpublic:
506195957Salfred  FunctionTextRegion(const FunctionDecl *fd, const MemRegion* sreg)
507195957Salfred    : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {}
508194676Sthompsa
509195957Salfred  QualType getLocationType() const {
510195957Salfred    return getContext().getPointerType(FD->getType());
511194676Sthompsa  }
512194676Sthompsa
513195957Salfred  const FunctionDecl *getDecl() const {
514194676Sthompsa    return FD;
515234491Shselasky  }
516194676Sthompsa
517194676Sthompsa  virtual void dumpToStream(raw_ostream &os) const;
518195957Salfred
519195957Salfred  void Profile(llvm::FoldingSetNodeID& ID) const;
520194676Sthompsa
521195957Salfred  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD,
522195957Salfred                            const MemRegion*);
523195957Salfred
524194676Sthompsa  static bool classof(const MemRegion* R) {
525194676Sthompsa    return R->getKind() == FunctionTextRegionKind;
526194676Sthompsa  }
527194676Sthompsa};
528195957Salfred
529194676Sthompsa
530194676Sthompsa/// BlockTextRegion - A region that represents code texts of blocks (closures).
531194676Sthompsa///  Blocks are represented with two kinds of regions.  BlockTextRegions
532194676Sthompsa///  represent the "code", while BlockDataRegions represent instances of blocks,
533194676Sthompsa///  which correspond to "code+data".  The distinction is important, because
534194676Sthompsa///  like a closure a block captures the values of externally referenced
535194676Sthompsa///  variables.
536234491Shselaskyclass BlockTextRegion : public CodeTextRegion {
537195957Salfred  friend class MemRegionManager;
538234491Shselasky
539194676Sthompsa  const BlockDecl *BD;
540194676Sthompsa  AnalysisDeclContext *AC;
541194676Sthompsa  CanQualType locTy;
542194676Sthompsa
543194676Sthompsa  BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
544234491Shselasky                  AnalysisDeclContext *ac, const MemRegion* sreg)
545194676Sthompsa    : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
546194676Sthompsa
547195957Salfredpublic:
548194676Sthompsa  QualType getLocationType() const {
549194676Sthompsa    return locTy;
550194676Sthompsa  }
551194676Sthompsa
552195957Salfred  const BlockDecl *getDecl() const {
553194676Sthompsa    return BD;
554194676Sthompsa  }
555195957Salfred
556194676Sthompsa  AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
557194676Sthompsa
558195957Salfred  virtual void dumpToStream(raw_ostream &os) const;
559195957Salfred
560194676Sthompsa  void Profile(llvm::FoldingSetNodeID& ID) const;
561195957Salfred
562195957Salfred  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
563194676Sthompsa                            CanQualType, const AnalysisDeclContext*,
564195957Salfred                            const MemRegion*);
565195957Salfred
566194676Sthompsa  static bool classof(const MemRegion* R) {
567195957Salfred    return R->getKind() == BlockTextRegionKind;
568194676Sthompsa  }
569194676Sthompsa};
570194676Sthompsa
571195957Salfred/// BlockDataRegion - A region that represents a block instance.
572194676Sthompsa///  Blocks are represented with two kinds of regions.  BlockTextRegions
573194676Sthompsa///  represent the "code", while BlockDataRegions represent instances of blocks,
574194676Sthompsa///  which correspond to "code+data".  The distinction is important, because
575194676Sthompsa///  like a closure a block captures the values of externally referenced
576194676Sthompsa///  variables.
577194676Sthompsaclass BlockDataRegion : public SubRegion {
578194676Sthompsa  friend class MemRegionManager;
579195957Salfred  const BlockTextRegion *BC;
580195957Salfred  const LocationContext *LC; // Can be null */
581194676Sthompsa  void *ReferencedVars;
582194676Sthompsa
583194676Sthompsa  BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
584194676Sthompsa                  const MemRegion *sreg)
585195957Salfred  : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {}
586195957Salfred
587195560Sthompsapublic:
588194676Sthompsa  const BlockTextRegion *getCodeRegion() const { return BC; }
589195957Salfred
590194676Sthompsa  const BlockDecl *getDecl() const { return BC->getDecl(); }
591194676Sthompsa
592195560Sthompsa  class referenced_vars_iterator {
593194676Sthompsa    const MemRegion * const *R;
594194676Sthompsa  public:
595194676Sthompsa    explicit referenced_vars_iterator(const MemRegion * const *r) : R(r) {}
596194676Sthompsa
597195957Salfred    operator const MemRegion * const *() const {
598195957Salfred      return R;
599194676Sthompsa    }
600194676Sthompsa
601194676Sthompsa    const VarRegion* operator*() const {
602194676Sthompsa      return cast<VarRegion>(*R);
603194676Sthompsa    }
604195957Salfred
605195560Sthompsa    bool operator==(const referenced_vars_iterator &I) const {
606194676Sthompsa      return I.R == R;
607195957Salfred    }
608194676Sthompsa    bool operator!=(const referenced_vars_iterator &I) const {
609194676Sthompsa      return I.R != R;
610195560Sthompsa    }
611194676Sthompsa    referenced_vars_iterator &operator++() {
612194676Sthompsa      ++R;
613199055Sthompsa      return *this;
614199055Sthompsa    }
615234491Shselasky  };
616199055Sthompsa
617199055Sthompsa  referenced_vars_iterator referenced_vars_begin() const;
618199055Sthompsa  referenced_vars_iterator referenced_vars_end() const;
619199055Sthompsa
620199055Sthompsa  virtual void dumpToStream(raw_ostream &os) const;
621199055Sthompsa
622199055Sthompsa  void Profile(llvm::FoldingSetNodeID& ID) const;
623234491Shselasky
624199055Sthompsa  static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
625199055Sthompsa                            const LocationContext *, const MemRegion *);
626199055Sthompsa
627199055Sthompsa  static bool classof(const MemRegion* R) {
628199055Sthompsa    return R->getKind() == BlockDataRegionKind;
629199055Sthompsa  }
630234491Shselaskyprivate:
631199055Sthompsa  void LazyInitializeReferencedVars();
632199055Sthompsa};
633199055Sthompsa
634199055Sthompsa/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
635199055Sthompsa///  clases, SymbolicRegion represents a region that serves as an alias for
636199055Sthompsa///  either a real region, a NULL pointer, etc.  It essentially is used to
637234491Shselasky///  map the concept of symbolic values into the domain of regions.  Symbolic
638199055Sthompsa///  regions do not need to be typed.
639199055Sthompsaclass SymbolicRegion : public SubRegion {
640199055Sthompsaprotected:
641199055Sthompsa  const SymbolRef sym;
642199055Sthompsa
643199055Sthompsapublic:
644234491Shselasky  SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
645199055Sthompsa    : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
646199055Sthompsa
647199055Sthompsa  SymbolRef getSymbol() const {
648199055Sthompsa    return sym;
649199055Sthompsa  }
650199055Sthompsa
651234491Shselasky  bool isBoundable() const { return true; }
652199055Sthompsa
653199055Sthompsa  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
654199055Sthompsa
655199055Sthompsa  void Profile(llvm::FoldingSetNodeID& ID) const;
656199055Sthompsa
657199055Sthompsa  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
658199055Sthompsa                            SymbolRef sym,
659199055Sthompsa                            const MemRegion* superRegion);
660199055Sthompsa
661199055Sthompsa  void dumpToStream(raw_ostream &os) const;
662199055Sthompsa
663199055Sthompsa  static bool classof(const MemRegion* R) {
664199055Sthompsa    return R->getKind() == SymbolicRegionKind;
665199055Sthompsa  }
666199055Sthompsa};
667199055Sthompsa
668199055Sthompsa/// StringRegion - Region associated with a StringLiteral.
669199055Sthompsaclass StringRegion : public TypedValueRegion {
670199055Sthompsa  friend class MemRegionManager;
671199055Sthompsa  const StringLiteral* Str;
672199055Sthompsaprotected:
673199055Sthompsa
674199055Sthompsa  StringRegion(const StringLiteral* str, const MemRegion* sreg)
675199055Sthompsa    : TypedValueRegion(sreg, StringRegionKind), Str(str) {}
676199055Sthompsa
677199055Sthompsa  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
678199055Sthompsa                            const StringLiteral* Str,
679199055Sthompsa                            const MemRegion* superRegion);
680199055Sthompsa
681199055Sthompsapublic:
682199055Sthompsa
683199055Sthompsa  const StringLiteral* getStringLiteral() const { return Str; }
684199055Sthompsa
685199055Sthompsa  QualType getValueType() const {
686199055Sthompsa    return Str->getType();
687199055Sthompsa  }
688199055Sthompsa
689199055Sthompsa  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
690199055Sthompsa
691199055Sthompsa  bool isBoundable() const { return false; }
692199055Sthompsa
693199055Sthompsa  void Profile(llvm::FoldingSetNodeID& ID) const {
694199055Sthompsa    ProfileRegion(ID, Str, superRegion);
695199055Sthompsa  }
696199055Sthompsa
697199055Sthompsa  void dumpToStream(raw_ostream &os) const;
698199055Sthompsa
699199055Sthompsa  static bool classof(const MemRegion* R) {
700199055Sthompsa    return R->getKind() == StringRegionKind;
701199055Sthompsa  }
702199055Sthompsa};
703199055Sthompsa
704199055Sthompsa/// The region associated with an ObjCStringLiteral.
705199055Sthompsaclass ObjCStringRegion : public TypedValueRegion {
706199055Sthompsa  friend class MemRegionManager;
707199055Sthompsa  const ObjCStringLiteral* Str;
708199055Sthompsaprotected:
709199055Sthompsa
710199055Sthompsa  ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg)
711199055Sthompsa  : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {}
712199055Sthompsa
713199055Sthompsa  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
714199055Sthompsa                            const ObjCStringLiteral* Str,
715199055Sthompsa                            const MemRegion* superRegion);
716199055Sthompsa
717199055Sthompsapublic:
718199055Sthompsa
719199055Sthompsa  const ObjCStringLiteral* getObjCStringLiteral() const { return Str; }
720199055Sthompsa
721199055Sthompsa  QualType getValueType() const {
722199055Sthompsa    return Str->getType();
723199055Sthompsa  }
724199055Sthompsa
725199055Sthompsa  bool isBoundable() const { return false; }
726199055Sthompsa
727199055Sthompsa  void Profile(llvm::FoldingSetNodeID& ID) const {
728199055Sthompsa    ProfileRegion(ID, Str, superRegion);
729199055Sthompsa  }
730199055Sthompsa
731199055Sthompsa  void dumpToStream(raw_ostream &os) const;
732199055Sthompsa
733199055Sthompsa  static bool classof(const MemRegion* R) {
734199055Sthompsa    return R->getKind() == ObjCStringRegionKind;
735199055Sthompsa  }
736199055Sthompsa};
737199055Sthompsa
738199055Sthompsa/// CompoundLiteralRegion - A memory region representing a compound literal.
739199055Sthompsa///   Compound literals are essentially temporaries that are stack allocated
740199055Sthompsa///   or in the global constant pool.
741199055Sthompsaclass CompoundLiteralRegion : public TypedValueRegion {
742199055Sthompsaprivate:
743199055Sthompsa  friend class MemRegionManager;
744199055Sthompsa  const CompoundLiteralExpr *CL;
745199055Sthompsa
746199055Sthompsa  CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg)
747199055Sthompsa    : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
748199055Sthompsa
749199055Sthompsa  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
750199055Sthompsa                            const CompoundLiteralExpr *CL,
751199055Sthompsa                            const MemRegion* superRegion);
752199055Sthompsapublic:
753199055Sthompsa  QualType getValueType() const {
754199055Sthompsa    return CL->getType();
755199055Sthompsa  }
756199055Sthompsa
757199055Sthompsa  bool isBoundable() const { return !CL->isFileScope(); }
758199055Sthompsa
759199055Sthompsa  void Profile(llvm::FoldingSetNodeID& ID) const;
760199055Sthompsa
761199055Sthompsa  void dumpToStream(raw_ostream &os) const;
762199055Sthompsa
763199055Sthompsa  const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
764199055Sthompsa
765199055Sthompsa  static bool classof(const MemRegion* R) {
766199055Sthompsa    return R->getKind() == CompoundLiteralRegionKind;
767199055Sthompsa  }
768199055Sthompsa};
769199055Sthompsa
770class DeclRegion : public TypedValueRegion {
771protected:
772  const Decl *D;
773
774  DeclRegion(const Decl *d, const MemRegion* sReg, Kind k)
775    : TypedValueRegion(sReg, k), D(d) {}
776
777  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
778                      const MemRegion* superRegion, Kind k);
779
780public:
781  const Decl *getDecl() const { return D; }
782  void Profile(llvm::FoldingSetNodeID& ID) const;
783
784  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
785
786  static bool classof(const MemRegion* R) {
787    unsigned k = R->getKind();
788    return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
789  }
790};
791
792class VarRegion : public DeclRegion {
793  friend class MemRegionManager;
794
795  // Constructors and private methods.
796  VarRegion(const VarDecl *vd, const MemRegion* sReg)
797    : DeclRegion(vd, sReg, VarRegionKind) {}
798
799  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
800                            const MemRegion *superRegion) {
801    DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
802  }
803
804  void Profile(llvm::FoldingSetNodeID& ID) const;
805
806public:
807  const VarDecl *getDecl() const { return cast<VarDecl>(D); }
808
809  const StackFrameContext *getStackFrame() const;
810
811  QualType getValueType() const {
812    // FIXME: We can cache this if needed.
813    return getDecl()->getType();
814  }
815
816  void dumpToStream(raw_ostream &os) const;
817
818  static bool classof(const MemRegion* R) {
819    return R->getKind() == VarRegionKind;
820  }
821
822  void dumpPretty(raw_ostream &os) const;
823};
824
825/// CXXThisRegion - Represents the region for the implicit 'this' parameter
826///  in a call to a C++ method.  This region doesn't represent the object
827///  referred to by 'this', but rather 'this' itself.
828class CXXThisRegion : public TypedValueRegion {
829  friend class MemRegionManager;
830  CXXThisRegion(const PointerType *thisPointerTy,
831                const MemRegion *sReg)
832    : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
833
834  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
835                            const PointerType *PT,
836                            const MemRegion *sReg);
837
838  void Profile(llvm::FoldingSetNodeID &ID) const;
839
840public:
841  QualType getValueType() const {
842    return QualType(ThisPointerTy, 0);
843  }
844
845  void dumpToStream(raw_ostream &os) const;
846
847  static bool classof(const MemRegion* R) {
848    return R->getKind() == CXXThisRegionKind;
849  }
850
851private:
852  const PointerType *ThisPointerTy;
853};
854
855class FieldRegion : public DeclRegion {
856  friend class MemRegionManager;
857
858  FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
859    : DeclRegion(fd, sReg, FieldRegionKind) {}
860
861public:
862  const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
863
864  QualType getValueType() const {
865    // FIXME: We can cache this if needed.
866    return getDecl()->getType();
867  }
868
869  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
870
871  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
872                            const MemRegion* superRegion) {
873    DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
874  }
875
876  static bool classof(const MemRegion* R) {
877    return R->getKind() == FieldRegionKind;
878  }
879
880  void dumpToStream(raw_ostream &os) const;
881  void dumpPretty(raw_ostream &os) const;
882};
883
884class ObjCIvarRegion : public DeclRegion {
885
886  friend class MemRegionManager;
887
888  ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg);
889
890  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
891                            const MemRegion* superRegion);
892
893public:
894  const ObjCIvarDecl *getDecl() const;
895  QualType getValueType() const;
896
897  void dumpToStream(raw_ostream &os) const;
898
899  static bool classof(const MemRegion* R) {
900    return R->getKind() == ObjCIvarRegionKind;
901  }
902};
903//===----------------------------------------------------------------------===//
904// Auxiliary data classes for use with MemRegions.
905//===----------------------------------------------------------------------===//
906
907class ElementRegion;
908
909class RegionRawOffset {
910private:
911  friend class ElementRegion;
912
913  const MemRegion *Region;
914  CharUnits Offset;
915
916  RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
917    : Region(reg), Offset(offset) {}
918
919public:
920  // FIXME: Eventually support symbolic offsets.
921  CharUnits getOffset() const { return Offset; }
922  const MemRegion *getRegion() const { return Region; }
923
924  void dumpToStream(raw_ostream &os) const;
925  void dump() const;
926};
927
928/// \brief ElementRegin is used to represent both array elements and casts.
929class ElementRegion : public TypedValueRegion {
930  friend class MemRegionManager;
931
932  QualType ElementType;
933  NonLoc Index;
934
935  ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
936    : TypedValueRegion(sReg, ElementRegionKind),
937      ElementType(elementType), Index(Idx) {
938    assert((!isa<nonloc::ConcreteInt>(&Idx) ||
939           cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
940           "The index must be signed");
941  }
942
943  static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
944                            SVal Idx, const MemRegion* superRegion);
945
946public:
947
948  NonLoc getIndex() const { return Index; }
949
950  QualType getValueType() const {
951    return ElementType;
952  }
953
954  QualType getElementType() const {
955    return ElementType;
956  }
957  /// Compute the offset within the array. The array might also be a subobject.
958  RegionRawOffset getAsArrayOffset() const;
959
960  void dumpToStream(raw_ostream &os) const;
961
962  void Profile(llvm::FoldingSetNodeID& ID) const;
963
964  static bool classof(const MemRegion* R) {
965    return R->getKind() == ElementRegionKind;
966  }
967};
968
969// C++ temporary object associated with an expression.
970class CXXTempObjectRegion : public TypedValueRegion {
971  friend class MemRegionManager;
972
973  Expr const *Ex;
974
975  CXXTempObjectRegion(Expr const *E, MemRegion const *sReg)
976    : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {}
977
978  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
979                            Expr const *E, const MemRegion *sReg);
980
981public:
982  const Expr *getExpr() const { return Ex; }
983
984  QualType getValueType() const {
985    return Ex->getType();
986  }
987
988  void dumpToStream(raw_ostream &os) const;
989
990  void Profile(llvm::FoldingSetNodeID &ID) const;
991
992  static bool classof(const MemRegion* R) {
993    return R->getKind() == CXXTempObjectRegionKind;
994  }
995};
996
997// CXXBaseObjectRegion represents a base object within a C++ object. It is
998// identified by the base class declaration and the region of its parent object.
999class CXXBaseObjectRegion : public TypedValueRegion {
1000  friend class MemRegionManager;
1001
1002  const CXXRecordDecl *decl;
1003
1004  CXXBaseObjectRegion(const CXXRecordDecl *d, const MemRegion *sReg)
1005    : TypedValueRegion(sReg, CXXBaseObjectRegionKind), decl(d) {}
1006
1007  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1008                            const CXXRecordDecl *decl, const MemRegion *sReg);
1009
1010public:
1011  const CXXRecordDecl *getDecl() const { return decl; }
1012
1013  QualType getValueType() const;
1014
1015  void dumpToStream(raw_ostream &os) const;
1016
1017  void Profile(llvm::FoldingSetNodeID &ID) const;
1018
1019  static bool classof(const MemRegion *region) {
1020    return region->getKind() == CXXBaseObjectRegionKind;
1021  }
1022};
1023
1024template<typename RegionTy>
1025const RegionTy* MemRegion::getAs() const {
1026  if (const RegionTy* RT = dyn_cast<RegionTy>(this))
1027    return RT;
1028
1029  return NULL;
1030}
1031
1032//===----------------------------------------------------------------------===//
1033// MemRegionManager - Factory object for creating regions.
1034//===----------------------------------------------------------------------===//
1035
1036class MemRegionManager {
1037  ASTContext &C;
1038  llvm::BumpPtrAllocator& A;
1039  llvm::FoldingSet<MemRegion> Regions;
1040
1041  GlobalInternalSpaceRegion *InternalGlobals;
1042  GlobalSystemSpaceRegion *SystemGlobals;
1043  GlobalImmutableSpaceRegion *ImmutableGlobals;
1044
1045
1046  llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1047    StackLocalsSpaceRegions;
1048  llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1049    StackArgumentsSpaceRegions;
1050  llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1051    StaticsGlobalSpaceRegions;
1052
1053  HeapSpaceRegion *heap;
1054  UnknownSpaceRegion *unknown;
1055  MemSpaceRegion *code;
1056
1057public:
1058  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
1059    : C(c), A(a), InternalGlobals(0), SystemGlobals(0), ImmutableGlobals(0),
1060      heap(0), unknown(0), code(0) {}
1061
1062  ~MemRegionManager();
1063
1064  ASTContext &getContext() { return C; }
1065
1066  llvm::BumpPtrAllocator &getAllocator() { return A; }
1067
1068  /// getStackLocalsRegion - Retrieve the memory region associated with the
1069  ///  specified stack frame.
1070  const StackLocalsSpaceRegion *
1071  getStackLocalsRegion(const StackFrameContext *STC);
1072
1073  /// getStackArgumentsRegion - Retrieve the memory region associated with
1074  ///  function/method arguments of the specified stack frame.
1075  const StackArgumentsSpaceRegion *
1076  getStackArgumentsRegion(const StackFrameContext *STC);
1077
1078  /// getGlobalsRegion - Retrieve the memory region associated with
1079  ///  global variables.
1080  const GlobalsSpaceRegion *getGlobalsRegion(
1081      MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1082      const CodeTextRegion *R = 0);
1083
1084  /// getHeapRegion - Retrieve the memory region associated with the
1085  ///  generic "heap".
1086  const HeapSpaceRegion *getHeapRegion();
1087
1088  /// getUnknownRegion - Retrieve the memory region associated with unknown
1089  /// memory space.
1090  const MemSpaceRegion *getUnknownRegion();
1091
1092  const MemSpaceRegion *getCodeRegion();
1093
1094  /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1095  const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1096                                      const LocationContext *LC);
1097
1098  /// getCompoundLiteralRegion - Retrieve the region associated with a
1099  ///  given CompoundLiteral.
1100  const CompoundLiteralRegion*
1101  getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1102                           const LocationContext *LC);
1103
1104  /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1105  ///  parameter 'this'.
1106  const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1107                                        const LocationContext *LC);
1108
1109  /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
1110  const SymbolicRegion* getSymbolicRegion(SymbolRef sym);
1111
1112  const StringRegion *getStringRegion(const StringLiteral* Str);
1113
1114  const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1115
1116  /// getVarRegion - Retrieve or create the memory region associated with
1117  ///  a specified VarDecl and LocationContext.
1118  const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
1119
1120  /// getVarRegion - Retrieve or create the memory region associated with
1121  ///  a specified VarDecl and super region.
1122  const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
1123
1124  /// getElementRegion - Retrieve the memory region associated with the
1125  ///  associated element type, index, and super region.
1126  const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1127                                        const MemRegion *superRegion,
1128                                        ASTContext &Ctx);
1129
1130  const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1131                                                 const MemRegion *superRegion) {
1132    return getElementRegion(ER->getElementType(), ER->getIndex(),
1133                            superRegion, ER->getContext());
1134  }
1135
1136  /// getFieldRegion - Retrieve or create the memory region associated with
1137  ///  a specified FieldDecl.  'superRegion' corresponds to the containing
1138  ///  memory region (which typically represents the memory representing
1139  ///  a structure or class).
1140  const FieldRegion *getFieldRegion(const FieldDecl *fd,
1141                                    const MemRegion* superRegion);
1142
1143  const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1144                                             const MemRegion *superRegion) {
1145    return getFieldRegion(FR->getDecl(), superRegion);
1146  }
1147
1148  /// getObjCIvarRegion - Retrieve or create the memory region associated with
1149  ///   a specified Objective-c instance variable.  'superRegion' corresponds
1150  ///   to the containing region (which typically represents the Objective-C
1151  ///   object).
1152  const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1153                                          const MemRegion* superRegion);
1154
1155  const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1156                                                    LocationContext const *LC);
1157
1158  const CXXBaseObjectRegion *getCXXBaseObjectRegion(const CXXRecordDecl *decl,
1159                                                  const MemRegion *superRegion);
1160
1161  /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1162  /// super region.
1163  const CXXBaseObjectRegion *
1164  getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1165                                  const MemRegion *superRegion) {
1166    return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion);
1167  }
1168
1169  const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
1170  const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
1171                                            CanQualType locTy,
1172                                            AnalysisDeclContext *AC);
1173
1174  /// getBlockDataRegion - Get the memory region associated with an instance
1175  ///  of a block.  Unlike many other MemRegions, the LocationContext*
1176  ///  argument is allowed to be NULL for cases where we have no known
1177  ///  context.
1178  const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
1179                                            const LocationContext *lc = NULL);
1180
1181private:
1182  template <typename RegionTy, typename A1>
1183  RegionTy* getRegion(const A1 a1);
1184
1185  template <typename RegionTy, typename A1>
1186  RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
1187
1188  template <typename RegionTy, typename A1, typename A2>
1189  RegionTy* getRegion(const A1 a1, const A2 a2);
1190
1191  template <typename RegionTy, typename A1, typename A2>
1192  RegionTy* getSubRegion(const A1 a1, const A2 a2,
1193                         const MemRegion* superRegion);
1194
1195  template <typename RegionTy, typename A1, typename A2, typename A3>
1196  RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
1197                         const MemRegion* superRegion);
1198
1199  template <typename REG>
1200  const REG* LazyAllocate(REG*& region);
1201
1202  template <typename REG, typename ARG>
1203  const REG* LazyAllocate(REG*& region, ARG a);
1204};
1205
1206//===----------------------------------------------------------------------===//
1207// Out-of-line member definitions.
1208//===----------------------------------------------------------------------===//
1209
1210inline ASTContext &MemRegion::getContext() const {
1211  return getMemRegionManager()->getContext();
1212}
1213
1214} // end GR namespace
1215
1216} // end clang namespace
1217
1218//===----------------------------------------------------------------------===//
1219// Pretty-printing regions.
1220//===----------------------------------------------------------------------===//
1221
1222namespace llvm {
1223static inline raw_ostream &operator<<(raw_ostream &os,
1224                                      const clang::ento::MemRegion* R) {
1225  R->dumpToStream(os);
1226  return os;
1227}
1228} // end llvm namespace
1229
1230#endif
1231