1218887Sdim//== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==//
2218887Sdim//
3218887Sdim//                     The LLVM Compiler Infrastructure
4218887Sdim//
5218887Sdim// This file is distributed under the University of Illinois Open Source
6218887Sdim// License. See LICENSE.TXT for details.
7218887Sdim//
8218887Sdim//===----------------------------------------------------------------------===//
9218887Sdim//
10218887Sdim//  This file defines MemRegion and its subclasses.  MemRegion defines a
11218887Sdim//  partially-typed abstraction of memory useful for path-sensitive dataflow
12218887Sdim//  analyses.
13218887Sdim//
14218887Sdim//===----------------------------------------------------------------------===//
15218887Sdim
16218887Sdim#ifndef LLVM_CLANG_GR_MEMREGION_H
17218887Sdim#define LLVM_CLANG_GR_MEMREGION_H
18218887Sdim
19239462Sdim#include "clang/AST/ASTContext.h"
20218887Sdim#include "clang/AST/CharUnits.h"
21218887Sdim#include "clang/AST/Decl.h"
22234353Sdim#include "clang/AST/ExprObjC.h"
23226633Sdim#include "clang/Basic/LLVM.h"
24218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
25249423Sdim#include "llvm/ADT/FoldingSet.h"
26218887Sdim#include "llvm/Support/ErrorHandling.h"
27218887Sdim#include <string>
28218887Sdim
29218887Sdimnamespace llvm {
30218887Sdimclass BumpPtrAllocator;
31218887Sdim}
32218887Sdim
33218887Sdimnamespace clang {
34218887Sdim
35218887Sdimclass LocationContext;
36218887Sdimclass StackFrameContext;
37218887Sdim
38218887Sdimnamespace ento {
39218887Sdim
40251662Sdimclass CodeTextRegion;
41218887Sdimclass MemRegionManager;
42218887Sdimclass MemSpaceRegion;
43218887Sdimclass SValBuilder;
44251662Sdimclass SymbolicRegion;
45218887Sdimclass VarRegion;
46218887Sdim
47218887Sdim/// Represent a region's offset within the top level base region.
48218887Sdimclass RegionOffset {
49218887Sdim  /// The base region.
50218887Sdim  const MemRegion *R;
51218887Sdim
52218887Sdim  /// The bit offset within the base region. It shouldn't be negative.
53218887Sdim  int64_t Offset;
54218887Sdim
55218887Sdimpublic:
56239462Sdim  // We're using a const instead of an enumeration due to the size required;
57239462Sdim  // Visual Studio will only create enumerations of size int, not long long.
58239462Sdim  static const int64_t Symbolic = INT64_MAX;
59239462Sdim
60239462Sdim  RegionOffset() : R(0) {}
61218887Sdim  RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
62218887Sdim
63218887Sdim  const MemRegion *getRegion() const { return R; }
64239462Sdim
65239462Sdim  bool hasSymbolicOffset() const { return Offset == Symbolic; }
66239462Sdim
67239462Sdim  int64_t getOffset() const {
68239462Sdim    assert(!hasSymbolicOffset());
69239462Sdim    return Offset;
70239462Sdim  }
71239462Sdim
72239462Sdim  bool isValid() const { return R; }
73218887Sdim};
74218887Sdim
75218887Sdim//===----------------------------------------------------------------------===//
76218887Sdim// Base region classes.
77218887Sdim//===----------------------------------------------------------------------===//
78218887Sdim
79218887Sdim/// MemRegion - The root abstract class for all memory regions.
80218887Sdimclass MemRegion : public llvm::FoldingSetNode {
81218887Sdim  friend class MemRegionManager;
82218887Sdimpublic:
83218887Sdim  enum Kind {
84218887Sdim    // Memory spaces.
85218887Sdim    GenericMemSpaceRegionKind,
86218887Sdim    StackLocalsSpaceRegionKind,
87218887Sdim    StackArgumentsSpaceRegionKind,
88218887Sdim    HeapSpaceRegionKind,
89218887Sdim    UnknownSpaceRegionKind,
90218887Sdim    StaticGlobalSpaceRegionKind,
91234353Sdim    GlobalInternalSpaceRegionKind,
92234353Sdim    GlobalSystemSpaceRegionKind,
93234353Sdim    GlobalImmutableSpaceRegionKind,
94234353Sdim    BEG_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind,
95234353Sdim    END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
96234353Sdim    BEG_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind,
97234353Sdim    END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
98218887Sdim    BEG_MEMSPACES = GenericMemSpaceRegionKind,
99234353Sdim    END_MEMSPACES = GlobalImmutableSpaceRegionKind,
100218887Sdim    // Untyped regions.
101218887Sdim    SymbolicRegionKind,
102218887Sdim    AllocaRegionKind,
103218887Sdim    // Typed regions.
104218887Sdim    BEG_TYPED_REGIONS,
105218887Sdim    FunctionTextRegionKind = BEG_TYPED_REGIONS,
106218887Sdim    BlockTextRegionKind,
107243830Sdim    BlockDataRegionKind,
108226633Sdim    BEG_TYPED_VALUE_REGIONS,
109226633Sdim    CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS,
110218887Sdim    CXXThisRegionKind,
111218887Sdim    StringRegionKind,
112234353Sdim    ObjCStringRegionKind,
113218887Sdim    ElementRegionKind,
114218887Sdim    // Decl Regions.
115218887Sdim    BEG_DECL_REGIONS,
116218887Sdim    VarRegionKind = BEG_DECL_REGIONS,
117218887Sdim    FieldRegionKind,
118218887Sdim    ObjCIvarRegionKind,
119218887Sdim    END_DECL_REGIONS = ObjCIvarRegionKind,
120218887Sdim    CXXTempObjectRegionKind,
121218887Sdim    CXXBaseObjectRegionKind,
122226633Sdim    END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind,
123218887Sdim    END_TYPED_REGIONS = CXXBaseObjectRegionKind
124218887Sdim  };
125218887Sdim
126218887Sdimprivate:
127218887Sdim  const Kind kind;
128218887Sdim
129218887Sdimprotected:
130218887Sdim  MemRegion(Kind k) : kind(k) {}
131218887Sdim  virtual ~MemRegion();
132218887Sdim
133218887Sdimpublic:
134218887Sdim  ASTContext &getContext() const;
135218887Sdim
136218887Sdim  virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
137218887Sdim
138218887Sdim  virtual MemRegionManager* getMemRegionManager() const = 0;
139218887Sdim
140218887Sdim  const MemSpaceRegion *getMemorySpace() const;
141218887Sdim
142218887Sdim  const MemRegion *getBaseRegion() const;
143218887Sdim
144243830Sdim  /// Check if the region is a subregion of the given region.
145243830Sdim  virtual bool isSubRegionOf(const MemRegion *R) const;
146243830Sdim
147239462Sdim  const MemRegion *StripCasts(bool StripBaseCasts = true) const;
148218887Sdim
149251662Sdim  /// \brief If this is a symbolic region, returns the region. Otherwise,
150251662Sdim  /// goes up the base chain looking for the first symbolic base region.
151251662Sdim  const SymbolicRegion *getSymbolicBase() const;
152251662Sdim
153218887Sdim  bool hasGlobalsOrParametersStorage() const;
154218887Sdim
155218887Sdim  bool hasStackStorage() const;
156218887Sdim
157218887Sdim  bool hasStackNonParametersStorage() const;
158218887Sdim
159218887Sdim  bool hasStackParametersStorage() const;
160218887Sdim
161218887Sdim  /// Compute the offset within the top level memory object.
162218887Sdim  RegionOffset getAsOffset() const;
163218887Sdim
164234353Sdim  /// \brief Get a string representation of a region for debug use.
165234353Sdim  std::string getString() const;
166234353Sdim
167226633Sdim  virtual void dumpToStream(raw_ostream &os) const;
168218887Sdim
169218887Sdim  void dump() const;
170218887Sdim
171239462Sdim  /// \brief Returns true if this region can be printed in a user-friendly way.
172239462Sdim  virtual bool canPrintPretty() const;
173239462Sdim
174234353Sdim  /// \brief Print the region for use in diagnostics.
175239462Sdim  virtual void printPretty(raw_ostream &os) const;
176234353Sdim
177251662Sdim  /// \brief Returns true if this region's textual representation can be used
178251662Sdim  /// as part of a larger expression.
179251662Sdim  virtual bool canPrintPrettyAsExpr() const;
180251662Sdim
181251662Sdim  /// \brief Print the region as expression.
182251662Sdim  ///
183251662Sdim  /// When this region represents a subexpression, the method is for printing
184251662Sdim  /// an expression containing it.
185251662Sdim  virtual void printPrettyAsExpr(raw_ostream &os) const;
186251662Sdim
187218887Sdim  Kind getKind() const { return kind; }
188218887Sdim
189218887Sdim  template<typename RegionTy> const RegionTy* getAs() const;
190218887Sdim
191218887Sdim  virtual bool isBoundable() const { return false; }
192218887Sdim};
193218887Sdim
194234353Sdim/// MemSpaceRegion - A memory region that represents a "memory space";
195218887Sdim///  for example, the set of global variables, the stack frame, etc.
196218887Sdimclass MemSpaceRegion : public MemRegion {
197218887Sdimprotected:
198218887Sdim  friend class MemRegionManager;
199218887Sdim
200218887Sdim  MemRegionManager *Mgr;
201218887Sdim
202218887Sdim  MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
203218887Sdim    : MemRegion(k), Mgr(mgr) {
204218887Sdim    assert(classof(this));
205218887Sdim  }
206218887Sdim
207218887Sdim  MemRegionManager* getMemRegionManager() const { return Mgr; }
208218887Sdim
209218887Sdimpublic:
210218887Sdim  bool isBoundable() const { return false; }
211218887Sdim
212218887Sdim  void Profile(llvm::FoldingSetNodeID &ID) const;
213218887Sdim
214218887Sdim  static bool classof(const MemRegion *R) {
215218887Sdim    Kind k = R->getKind();
216218887Sdim    return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
217218887Sdim  }
218218887Sdim};
219218887Sdim
220218887Sdimclass GlobalsSpaceRegion : public MemSpaceRegion {
221234353Sdim  virtual void anchor();
222218887Sdimprotected:
223218887Sdim  GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
224218887Sdim    : MemSpaceRegion(mgr, k) {}
225218887Sdimpublic:
226218887Sdim  static bool classof(const MemRegion *R) {
227218887Sdim    Kind k = R->getKind();
228218887Sdim    return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
229218887Sdim  }
230218887Sdim};
231234353Sdim
232239462Sdim/// \brief The region of the static variables within the current CodeTextRegion
233234353Sdim/// scope.
234239462Sdim///
235234353Sdim/// Currently, only the static locals are placed there, so we know that these
236234353Sdim/// variables do not get invalidated by calls to other functions.
237218887Sdimclass StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
238218887Sdim  friend class MemRegionManager;
239218887Sdim
240218887Sdim  const CodeTextRegion *CR;
241218887Sdim
242218887Sdim  StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
243218887Sdim    : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
244218887Sdim
245218887Sdimpublic:
246218887Sdim  void Profile(llvm::FoldingSetNodeID &ID) const;
247218887Sdim
248226633Sdim  void dumpToStream(raw_ostream &os) const;
249218887Sdim
250218887Sdim  const CodeTextRegion *getCodeRegion() const { return CR; }
251218887Sdim
252218887Sdim  static bool classof(const MemRegion *R) {
253218887Sdim    return R->getKind() == StaticGlobalSpaceRegionKind;
254218887Sdim  }
255218887Sdim};
256234353Sdim
257239462Sdim/// \brief The region for all the non-static global variables.
258234353Sdim///
259234353Sdim/// This class is further split into subclasses for efficient implementation of
260234353Sdim/// invalidating a set of related global values as is done in
261234353Sdim/// RegionStoreManager::invalidateRegions (instead of finding all the dependent
262234353Sdim/// globals, we invalidate the whole parent region).
263218887Sdimclass NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
264218887Sdim  friend class MemRegionManager;
265218887Sdim
266234353Sdimprotected:
267234353Sdim  NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
268234353Sdim    : GlobalsSpaceRegion(mgr, k) {}
269218887Sdim
270218887Sdimpublic:
271218887Sdim
272218887Sdim  static bool classof(const MemRegion *R) {
273234353Sdim    Kind k = R->getKind();
274234353Sdim    return k >= BEG_NON_STATIC_GLOBAL_MEMSPACES &&
275234353Sdim           k <= END_NON_STATIC_GLOBAL_MEMSPACES;
276218887Sdim  }
277218887Sdim};
278234353Sdim
279239462Sdim/// \brief The region containing globals which are defined in system/external
280234353Sdim/// headers and are considered modifiable by system calls (ex: errno).
281234353Sdimclass GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
282234353Sdim  friend class MemRegionManager;
283234353Sdim
284234353Sdim  GlobalSystemSpaceRegion(MemRegionManager *mgr)
285234353Sdim    : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
286234353Sdim
287234353Sdimpublic:
288234353Sdim
289234353Sdim  void dumpToStream(raw_ostream &os) const;
290234353Sdim
291234353Sdim  static bool classof(const MemRegion *R) {
292234353Sdim    return R->getKind() == GlobalSystemSpaceRegionKind;
293234353Sdim  }
294234353Sdim};
295234353Sdim
296239462Sdim/// \brief The region containing globals which are considered not to be modified
297234353Sdim/// or point to data which could be modified as a result of a function call
298234353Sdim/// (system or internal). Ex: Const global scalars would be modeled as part of
299234353Sdim/// this region. This region also includes most system globals since they have
300234353Sdim/// low chance of being modified.
301234353Sdimclass GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
302234353Sdim  friend class MemRegionManager;
303234353Sdim
304234353Sdim  GlobalImmutableSpaceRegion(MemRegionManager *mgr)
305234353Sdim    : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
306234353Sdim
307234353Sdimpublic:
308234353Sdim
309234353Sdim  void dumpToStream(raw_ostream &os) const;
310234353Sdim
311234353Sdim  static bool classof(const MemRegion *R) {
312234353Sdim    return R->getKind() == GlobalImmutableSpaceRegionKind;
313234353Sdim  }
314234353Sdim};
315234353Sdim
316239462Sdim/// \brief The region containing globals which can be modified by calls to
317234353Sdim/// "internally" defined functions - (for now just) functions other then system
318234353Sdim/// calls.
319234353Sdimclass GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
320234353Sdim  friend class MemRegionManager;
321234353Sdim
322234353Sdim  GlobalInternalSpaceRegion(MemRegionManager *mgr)
323234353Sdim    : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
324234353Sdim
325234353Sdimpublic:
326234353Sdim
327234353Sdim  void dumpToStream(raw_ostream &os) const;
328234353Sdim
329234353Sdim  static bool classof(const MemRegion *R) {
330234353Sdim    return R->getKind() == GlobalInternalSpaceRegionKind;
331234353Sdim  }
332234353Sdim};
333234353Sdim
334218887Sdimclass HeapSpaceRegion : public MemSpaceRegion {
335234353Sdim  virtual void anchor();
336218887Sdim  friend class MemRegionManager;
337218887Sdim
338218887Sdim  HeapSpaceRegion(MemRegionManager *mgr)
339218887Sdim    : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
340218887Sdimpublic:
341239462Sdim
342239462Sdim  void dumpToStream(raw_ostream &os) const;
343239462Sdim
344218887Sdim  static bool classof(const MemRegion *R) {
345218887Sdim    return R->getKind() == HeapSpaceRegionKind;
346218887Sdim  }
347218887Sdim};
348218887Sdim
349218887Sdimclass UnknownSpaceRegion : public MemSpaceRegion {
350234353Sdim  virtual void anchor();
351218887Sdim  friend class MemRegionManager;
352218887Sdim  UnknownSpaceRegion(MemRegionManager *mgr)
353218887Sdim    : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
354218887Sdimpublic:
355239462Sdim
356239462Sdim  void dumpToStream(raw_ostream &os) const;
357239462Sdim
358218887Sdim  static bool classof(const MemRegion *R) {
359218887Sdim    return R->getKind() == UnknownSpaceRegionKind;
360218887Sdim  }
361218887Sdim};
362218887Sdim
363218887Sdimclass StackSpaceRegion : public MemSpaceRegion {
364218887Sdimprivate:
365218887Sdim  const StackFrameContext *SFC;
366218887Sdim
367218887Sdimprotected:
368218887Sdim  StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
369218887Sdim    : MemSpaceRegion(mgr, k), SFC(sfc) {
370218887Sdim    assert(classof(this));
371218887Sdim  }
372218887Sdim
373218887Sdimpublic:
374218887Sdim  const StackFrameContext *getStackFrame() const { return SFC; }
375218887Sdim
376218887Sdim  void Profile(llvm::FoldingSetNodeID &ID) const;
377218887Sdim
378218887Sdim  static bool classof(const MemRegion *R) {
379218887Sdim    Kind k = R->getKind();
380218887Sdim    return k >= StackLocalsSpaceRegionKind &&
381218887Sdim           k <= StackArgumentsSpaceRegionKind;
382218887Sdim  }
383218887Sdim};
384218887Sdim
385218887Sdimclass StackLocalsSpaceRegion : public StackSpaceRegion {
386234353Sdim  virtual void anchor();
387218887Sdim  friend class MemRegionManager;
388218887Sdim  StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
389218887Sdim    : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
390218887Sdimpublic:
391239462Sdim
392239462Sdim  void dumpToStream(raw_ostream &os) const;
393239462Sdim
394218887Sdim  static bool classof(const MemRegion *R) {
395218887Sdim    return R->getKind() == StackLocalsSpaceRegionKind;
396218887Sdim  }
397218887Sdim};
398218887Sdim
399218887Sdimclass StackArgumentsSpaceRegion : public StackSpaceRegion {
400218887Sdimprivate:
401234353Sdim  virtual void anchor();
402218887Sdim  friend class MemRegionManager;
403218887Sdim  StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
404218887Sdim    : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
405218887Sdimpublic:
406239462Sdim
407239462Sdim  void dumpToStream(raw_ostream &os) const;
408239462Sdim
409218887Sdim  static bool classof(const MemRegion *R) {
410218887Sdim    return R->getKind() == StackArgumentsSpaceRegionKind;
411218887Sdim  }
412218887Sdim};
413218887Sdim
414218887Sdim
415218887Sdim/// SubRegion - A region that subsets another larger region.  Most regions
416218887Sdim///  are subclasses of SubRegion.
417218887Sdimclass SubRegion : public MemRegion {
418234353Sdimprivate:
419234353Sdim  virtual void anchor();
420218887Sdimprotected:
421218887Sdim  const MemRegion* superRegion;
422218887Sdim  SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
423218887Sdimpublic:
424218887Sdim  const MemRegion* getSuperRegion() const {
425218887Sdim    return superRegion;
426218887Sdim  }
427218887Sdim
428218887Sdim  /// getExtent - Returns the size of the region in bytes.
429218887Sdim  virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
430218887Sdim    return UnknownVal();
431218887Sdim  }
432218887Sdim
433218887Sdim  MemRegionManager* getMemRegionManager() const;
434218887Sdim
435243830Sdim  virtual bool isSubRegionOf(const MemRegion* R) const;
436218887Sdim
437218887Sdim  static bool classof(const MemRegion* R) {
438218887Sdim    return R->getKind() > END_MEMSPACES;
439218887Sdim  }
440218887Sdim};
441218887Sdim
442218887Sdim//===----------------------------------------------------------------------===//
443218887Sdim// MemRegion subclasses.
444218887Sdim//===----------------------------------------------------------------------===//
445218887Sdim
446218887Sdim/// AllocaRegion - A region that represents an untyped blob of bytes created
447218887Sdim///  by a call to 'alloca'.
448218887Sdimclass AllocaRegion : public SubRegion {
449218887Sdim  friend class MemRegionManager;
450218887Sdimprotected:
451218887Sdim  unsigned Cnt; // Block counter.  Used to distinguish different pieces of
452218887Sdim                // memory allocated by alloca at the same call site.
453226633Sdim  const Expr *Ex;
454218887Sdim
455226633Sdim  AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion)
456218887Sdim    : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
457218887Sdim
458218887Sdimpublic:
459218887Sdim
460226633Sdim  const Expr *getExpr() const { return Ex; }
461218887Sdim
462218887Sdim  bool isBoundable() const { return true; }
463218887Sdim
464218887Sdim  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
465218887Sdim
466218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
467218887Sdim
468226633Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
469218887Sdim                            unsigned Cnt, const MemRegion *superRegion);
470218887Sdim
471226633Sdim  void dumpToStream(raw_ostream &os) const;
472218887Sdim
473218887Sdim  static bool classof(const MemRegion* R) {
474218887Sdim    return R->getKind() == AllocaRegionKind;
475218887Sdim  }
476218887Sdim};
477218887Sdim
478218887Sdim/// TypedRegion - An abstract class representing regions that are typed.
479218887Sdimclass TypedRegion : public SubRegion {
480234353Sdimpublic:
481234353Sdim  virtual void anchor();
482218887Sdimprotected:
483218887Sdim  TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
484218887Sdim
485218887Sdimpublic:
486226633Sdim  virtual QualType getLocationType() const = 0;
487226633Sdim
488226633Sdim  QualType getDesugaredLocationType(ASTContext &Context) const {
489226633Sdim    return getLocationType().getDesugaredType(Context);
490226633Sdim  }
491226633Sdim
492226633Sdim  bool isBoundable() const { return true; }
493226633Sdim
494226633Sdim  static bool classof(const MemRegion* R) {
495226633Sdim    unsigned k = R->getKind();
496226633Sdim    return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
497226633Sdim  }
498226633Sdim};
499226633Sdim
500226633Sdim/// TypedValueRegion - An abstract class representing regions having a typed value.
501226633Sdimclass TypedValueRegion : public TypedRegion {
502234353Sdimpublic:
503234353Sdim  virtual void anchor();
504226633Sdimprotected:
505226633Sdim  TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
506226633Sdim
507226633Sdimpublic:
508218887Sdim  virtual QualType getValueType() const = 0;
509218887Sdim
510218887Sdim  virtual QualType getLocationType() const {
511218887Sdim    // FIXME: We can possibly optimize this later to cache this value.
512218887Sdim    QualType T = getValueType();
513218887Sdim    ASTContext &ctx = getContext();
514218887Sdim    if (T->getAs<ObjCObjectType>())
515218887Sdim      return ctx.getObjCObjectPointerType(T);
516218887Sdim    return ctx.getPointerType(getValueType());
517218887Sdim  }
518218887Sdim
519218887Sdim  QualType getDesugaredValueType(ASTContext &Context) const {
520218887Sdim    QualType T = getValueType();
521218887Sdim    return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
522218887Sdim  }
523218887Sdim
524239462Sdim  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
525239462Sdim
526218887Sdim  static bool classof(const MemRegion* R) {
527218887Sdim    unsigned k = R->getKind();
528226633Sdim    return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
529218887Sdim  }
530218887Sdim};
531218887Sdim
532218887Sdim
533218887Sdimclass CodeTextRegion : public TypedRegion {
534234353Sdimpublic:
535234353Sdim  virtual void anchor();
536218887Sdimprotected:
537218887Sdim  CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
538218887Sdimpublic:
539218887Sdim  bool isBoundable() const { return false; }
540218887Sdim
541218887Sdim  static bool classof(const MemRegion* R) {
542218887Sdim    Kind k = R->getKind();
543218887Sdim    return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
544218887Sdim  }
545218887Sdim};
546218887Sdim
547218887Sdim/// FunctionTextRegion - A region that represents code texts of function.
548218887Sdimclass FunctionTextRegion : public CodeTextRegion {
549243830Sdim  const NamedDecl *FD;
550218887Sdimpublic:
551243830Sdim  FunctionTextRegion(const NamedDecl *fd, const MemRegion* sreg)
552243830Sdim    : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {
553243830Sdim    assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
554243830Sdim  }
555218887Sdim
556218887Sdim  QualType getLocationType() const {
557243830Sdim    const ASTContext &Ctx = getContext();
558243830Sdim    if (const FunctionDecl *D = dyn_cast<FunctionDecl>(FD)) {
559243830Sdim      return Ctx.getPointerType(D->getType());
560243830Sdim    }
561243830Sdim
562243830Sdim    assert(isa<ObjCMethodDecl>(FD));
563243830Sdim    assert(false && "Getting the type of ObjCMethod is not supported yet");
564243830Sdim
565243830Sdim    // TODO: We might want to return a different type here (ex: id (*ty)(...))
566243830Sdim    //       depending on how it is used.
567243830Sdim    return QualType();
568218887Sdim  }
569243830Sdim
570243830Sdim  const NamedDecl *getDecl() const {
571218887Sdim    return FD;
572218887Sdim  }
573218887Sdim
574226633Sdim  virtual void dumpToStream(raw_ostream &os) const;
575218887Sdim
576218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
577218887Sdim
578243830Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
579218887Sdim                            const MemRegion*);
580218887Sdim
581218887Sdim  static bool classof(const MemRegion* R) {
582218887Sdim    return R->getKind() == FunctionTextRegionKind;
583218887Sdim  }
584218887Sdim};
585218887Sdim
586218887Sdim
587218887Sdim/// BlockTextRegion - A region that represents code texts of blocks (closures).
588218887Sdim///  Blocks are represented with two kinds of regions.  BlockTextRegions
589218887Sdim///  represent the "code", while BlockDataRegions represent instances of blocks,
590218887Sdim///  which correspond to "code+data".  The distinction is important, because
591218887Sdim///  like a closure a block captures the values of externally referenced
592218887Sdim///  variables.
593218887Sdimclass BlockTextRegion : public CodeTextRegion {
594218887Sdim  friend class MemRegionManager;
595218887Sdim
596218887Sdim  const BlockDecl *BD;
597234353Sdim  AnalysisDeclContext *AC;
598218887Sdim  CanQualType locTy;
599218887Sdim
600218887Sdim  BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
601234353Sdim                  AnalysisDeclContext *ac, const MemRegion* sreg)
602218887Sdim    : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
603218887Sdim
604218887Sdimpublic:
605218887Sdim  QualType getLocationType() const {
606218887Sdim    return locTy;
607218887Sdim  }
608218887Sdim
609218887Sdim  const BlockDecl *getDecl() const {
610218887Sdim    return BD;
611218887Sdim  }
612218887Sdim
613234353Sdim  AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
614218887Sdim
615226633Sdim  virtual void dumpToStream(raw_ostream &os) const;
616218887Sdim
617218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
618218887Sdim
619218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
620234353Sdim                            CanQualType, const AnalysisDeclContext*,
621218887Sdim                            const MemRegion*);
622218887Sdim
623218887Sdim  static bool classof(const MemRegion* R) {
624218887Sdim    return R->getKind() == BlockTextRegionKind;
625218887Sdim  }
626218887Sdim};
627218887Sdim
628218887Sdim/// BlockDataRegion - A region that represents a block instance.
629218887Sdim///  Blocks are represented with two kinds of regions.  BlockTextRegions
630218887Sdim///  represent the "code", while BlockDataRegions represent instances of blocks,
631218887Sdim///  which correspond to "code+data".  The distinction is important, because
632218887Sdim///  like a closure a block captures the values of externally referenced
633218887Sdim///  variables.
634243830Sdimclass BlockDataRegion : public TypedRegion {
635218887Sdim  friend class MemRegionManager;
636218887Sdim  const BlockTextRegion *BC;
637218887Sdim  const LocationContext *LC; // Can be null */
638218887Sdim  void *ReferencedVars;
639239462Sdim  void *OriginalVars;
640218887Sdim
641218887Sdim  BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
642218887Sdim                  const MemRegion *sreg)
643243830Sdim  : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
644239462Sdim    ReferencedVars(0), OriginalVars(0) {}
645218887Sdim
646239462Sdimpublic:
647218887Sdim  const BlockTextRegion *getCodeRegion() const { return BC; }
648218887Sdim
649218887Sdim  const BlockDecl *getDecl() const { return BC->getDecl(); }
650243830Sdim
651243830Sdim  QualType getLocationType() const { return BC->getLocationType(); }
652218887Sdim
653218887Sdim  class referenced_vars_iterator {
654218887Sdim    const MemRegion * const *R;
655239462Sdim    const MemRegion * const *OriginalR;
656218887Sdim  public:
657239462Sdim    explicit referenced_vars_iterator(const MemRegion * const *r,
658239462Sdim                                      const MemRegion * const *originalR)
659239462Sdim      : R(r), OriginalR(originalR) {}
660249423Sdim
661249423Sdim    const VarRegion *getCapturedRegion() const {
662249423Sdim      return cast<VarRegion>(*R);
663218887Sdim    }
664249423Sdim    const VarRegion *getOriginalRegion() const {
665249423Sdim      return cast<VarRegion>(*OriginalR);
666239462Sdim    }
667239462Sdim
668218887Sdim    bool operator==(const referenced_vars_iterator &I) const {
669249423Sdim      assert((R == 0) == (I.R == 0));
670218887Sdim      return I.R == R;
671218887Sdim    }
672218887Sdim    bool operator!=(const referenced_vars_iterator &I) const {
673249423Sdim      assert((R == 0) == (I.R == 0));
674218887Sdim      return I.R != R;
675218887Sdim    }
676226633Sdim    referenced_vars_iterator &operator++() {
677218887Sdim      ++R;
678239462Sdim      ++OriginalR;
679218887Sdim      return *this;
680218887Sdim    }
681218887Sdim  };
682249423Sdim
683249423Sdim  /// Return the original region for a captured region, if
684249423Sdim  /// one exists.
685249423Sdim  const VarRegion *getOriginalRegion(const VarRegion *VR) const;
686218887Sdim
687218887Sdim  referenced_vars_iterator referenced_vars_begin() const;
688218887Sdim  referenced_vars_iterator referenced_vars_end() const;
689218887Sdim
690226633Sdim  virtual void dumpToStream(raw_ostream &os) const;
691218887Sdim
692218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
693218887Sdim
694218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
695218887Sdim                            const LocationContext *, const MemRegion *);
696218887Sdim
697218887Sdim  static bool classof(const MemRegion* R) {
698218887Sdim    return R->getKind() == BlockDataRegionKind;
699218887Sdim  }
700218887Sdimprivate:
701218887Sdim  void LazyInitializeReferencedVars();
702249423Sdim  std::pair<const VarRegion *, const VarRegion *>
703249423Sdim  getCaptureRegions(const VarDecl *VD);
704218887Sdim};
705218887Sdim
706218887Sdim/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
707218887Sdim///  clases, SymbolicRegion represents a region that serves as an alias for
708218887Sdim///  either a real region, a NULL pointer, etc.  It essentially is used to
709218887Sdim///  map the concept of symbolic values into the domain of regions.  Symbolic
710218887Sdim///  regions do not need to be typed.
711218887Sdimclass SymbolicRegion : public SubRegion {
712218887Sdimprotected:
713218887Sdim  const SymbolRef sym;
714218887Sdim
715218887Sdimpublic:
716218887Sdim  SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
717218887Sdim    : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
718218887Sdim
719218887Sdim  SymbolRef getSymbol() const {
720218887Sdim    return sym;
721218887Sdim  }
722218887Sdim
723218887Sdim  bool isBoundable() const { return true; }
724218887Sdim
725218887Sdim  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
726218887Sdim
727218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
728218887Sdim
729218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
730218887Sdim                            SymbolRef sym,
731218887Sdim                            const MemRegion* superRegion);
732218887Sdim
733226633Sdim  void dumpToStream(raw_ostream &os) const;
734218887Sdim
735218887Sdim  static bool classof(const MemRegion* R) {
736218887Sdim    return R->getKind() == SymbolicRegionKind;
737218887Sdim  }
738218887Sdim};
739218887Sdim
740218887Sdim/// StringRegion - Region associated with a StringLiteral.
741226633Sdimclass StringRegion : public TypedValueRegion {
742218887Sdim  friend class MemRegionManager;
743218887Sdim  const StringLiteral* Str;
744218887Sdimprotected:
745218887Sdim
746218887Sdim  StringRegion(const StringLiteral* str, const MemRegion* sreg)
747226633Sdim    : TypedValueRegion(sreg, StringRegionKind), Str(str) {}
748218887Sdim
749218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
750218887Sdim                            const StringLiteral* Str,
751218887Sdim                            const MemRegion* superRegion);
752218887Sdim
753218887Sdimpublic:
754218887Sdim
755218887Sdim  const StringLiteral* getStringLiteral() const { return Str; }
756218887Sdim
757218887Sdim  QualType getValueType() const {
758218887Sdim    return Str->getType();
759218887Sdim  }
760218887Sdim
761218887Sdim  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
762218887Sdim
763218887Sdim  bool isBoundable() const { return false; }
764218887Sdim
765218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const {
766218887Sdim    ProfileRegion(ID, Str, superRegion);
767218887Sdim  }
768218887Sdim
769226633Sdim  void dumpToStream(raw_ostream &os) const;
770218887Sdim
771218887Sdim  static bool classof(const MemRegion* R) {
772218887Sdim    return R->getKind() == StringRegionKind;
773218887Sdim  }
774218887Sdim};
775234353Sdim
776234353Sdim/// The region associated with an ObjCStringLiteral.
777234353Sdimclass ObjCStringRegion : public TypedValueRegion {
778234353Sdim  friend class MemRegionManager;
779234353Sdim  const ObjCStringLiteral* Str;
780234353Sdimprotected:
781234353Sdim
782234353Sdim  ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg)
783234353Sdim  : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {}
784234353Sdim
785234353Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
786234353Sdim                            const ObjCStringLiteral* Str,
787234353Sdim                            const MemRegion* superRegion);
788234353Sdim
789234353Sdimpublic:
790234353Sdim
791234353Sdim  const ObjCStringLiteral* getObjCStringLiteral() const { return Str; }
792234353Sdim
793234353Sdim  QualType getValueType() const {
794234353Sdim    return Str->getType();
795234353Sdim  }
796234353Sdim
797234353Sdim  bool isBoundable() const { return false; }
798234353Sdim
799234353Sdim  void Profile(llvm::FoldingSetNodeID& ID) const {
800234353Sdim    ProfileRegion(ID, Str, superRegion);
801234353Sdim  }
802234353Sdim
803234353Sdim  void dumpToStream(raw_ostream &os) const;
804234353Sdim
805234353Sdim  static bool classof(const MemRegion* R) {
806234353Sdim    return R->getKind() == ObjCStringRegionKind;
807234353Sdim  }
808234353Sdim};
809218887Sdim
810218887Sdim/// CompoundLiteralRegion - A memory region representing a compound literal.
811218887Sdim///   Compound literals are essentially temporaries that are stack allocated
812218887Sdim///   or in the global constant pool.
813226633Sdimclass CompoundLiteralRegion : public TypedValueRegion {
814218887Sdimprivate:
815218887Sdim  friend class MemRegionManager;
816226633Sdim  const CompoundLiteralExpr *CL;
817218887Sdim
818226633Sdim  CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg)
819226633Sdim    : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
820218887Sdim
821218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
822226633Sdim                            const CompoundLiteralExpr *CL,
823218887Sdim                            const MemRegion* superRegion);
824218887Sdimpublic:
825218887Sdim  QualType getValueType() const {
826218887Sdim    return CL->getType();
827218887Sdim  }
828218887Sdim
829218887Sdim  bool isBoundable() const { return !CL->isFileScope(); }
830218887Sdim
831218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
832218887Sdim
833226633Sdim  void dumpToStream(raw_ostream &os) const;
834218887Sdim
835226633Sdim  const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
836218887Sdim
837218887Sdim  static bool classof(const MemRegion* R) {
838218887Sdim    return R->getKind() == CompoundLiteralRegionKind;
839218887Sdim  }
840218887Sdim};
841218887Sdim
842226633Sdimclass DeclRegion : public TypedValueRegion {
843218887Sdimprotected:
844226633Sdim  const Decl *D;
845218887Sdim
846226633Sdim  DeclRegion(const Decl *d, const MemRegion* sReg, Kind k)
847226633Sdim    : TypedValueRegion(sReg, k), D(d) {}
848218887Sdim
849226633Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
850218887Sdim                      const MemRegion* superRegion, Kind k);
851218887Sdim
852218887Sdimpublic:
853226633Sdim  const Decl *getDecl() const { return D; }
854218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
855218887Sdim
856218887Sdim  static bool classof(const MemRegion* R) {
857218887Sdim    unsigned k = R->getKind();
858218887Sdim    return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
859218887Sdim  }
860218887Sdim};
861218887Sdim
862218887Sdimclass VarRegion : public DeclRegion {
863218887Sdim  friend class MemRegionManager;
864218887Sdim
865218887Sdim  // Constructors and private methods.
866226633Sdim  VarRegion(const VarDecl *vd, const MemRegion* sReg)
867218887Sdim    : DeclRegion(vd, sReg, VarRegionKind) {}
868218887Sdim
869226633Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
870218887Sdim                            const MemRegion *superRegion) {
871218887Sdim    DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
872218887Sdim  }
873218887Sdim
874218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
875218887Sdim
876218887Sdimpublic:
877218887Sdim  const VarDecl *getDecl() const { return cast<VarDecl>(D); }
878218887Sdim
879218887Sdim  const StackFrameContext *getStackFrame() const;
880218887Sdim
881218887Sdim  QualType getValueType() const {
882218887Sdim    // FIXME: We can cache this if needed.
883218887Sdim    return getDecl()->getType();
884218887Sdim  }
885218887Sdim
886226633Sdim  void dumpToStream(raw_ostream &os) const;
887218887Sdim
888218887Sdim  static bool classof(const MemRegion* R) {
889218887Sdim    return R->getKind() == VarRegionKind;
890218887Sdim  }
891234353Sdim
892251662Sdim  bool canPrintPrettyAsExpr() const;
893251662Sdim
894251662Sdim  void printPrettyAsExpr(raw_ostream &os) const;
895218887Sdim};
896218887Sdim
897218887Sdim/// CXXThisRegion - Represents the region for the implicit 'this' parameter
898218887Sdim///  in a call to a C++ method.  This region doesn't represent the object
899218887Sdim///  referred to by 'this', but rather 'this' itself.
900226633Sdimclass CXXThisRegion : public TypedValueRegion {
901218887Sdim  friend class MemRegionManager;
902218887Sdim  CXXThisRegion(const PointerType *thisPointerTy,
903218887Sdim                const MemRegion *sReg)
904226633Sdim    : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
905218887Sdim
906218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
907218887Sdim                            const PointerType *PT,
908218887Sdim                            const MemRegion *sReg);
909218887Sdim
910218887Sdim  void Profile(llvm::FoldingSetNodeID &ID) const;
911218887Sdim
912218887Sdimpublic:
913218887Sdim  QualType getValueType() const {
914218887Sdim    return QualType(ThisPointerTy, 0);
915218887Sdim  }
916218887Sdim
917226633Sdim  void dumpToStream(raw_ostream &os) const;
918218887Sdim
919218887Sdim  static bool classof(const MemRegion* R) {
920218887Sdim    return R->getKind() == CXXThisRegionKind;
921218887Sdim  }
922218887Sdim
923218887Sdimprivate:
924218887Sdim  const PointerType *ThisPointerTy;
925218887Sdim};
926218887Sdim
927218887Sdimclass FieldRegion : public DeclRegion {
928218887Sdim  friend class MemRegionManager;
929218887Sdim
930226633Sdim  FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
931218887Sdim    : DeclRegion(fd, sReg, FieldRegionKind) {}
932218887Sdim
933218887Sdimpublic:
934226633Sdim  const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
935218887Sdim
936218887Sdim  QualType getValueType() const {
937218887Sdim    // FIXME: We can cache this if needed.
938218887Sdim    return getDecl()->getType();
939218887Sdim  }
940218887Sdim
941218887Sdim  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
942218887Sdim
943226633Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
944218887Sdim                            const MemRegion* superRegion) {
945218887Sdim    DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
946218887Sdim  }
947218887Sdim
948218887Sdim  static bool classof(const MemRegion* R) {
949218887Sdim    return R->getKind() == FieldRegionKind;
950218887Sdim  }
951234353Sdim
952234353Sdim  void dumpToStream(raw_ostream &os) const;
953239462Sdim
954239462Sdim  bool canPrintPretty() const;
955239462Sdim  void printPretty(raw_ostream &os) const;
956251662Sdim  bool canPrintPrettyAsExpr() const;
957251662Sdim  void printPrettyAsExpr(raw_ostream &os) const;
958218887Sdim};
959218887Sdim
960218887Sdimclass ObjCIvarRegion : public DeclRegion {
961218887Sdim
962218887Sdim  friend class MemRegionManager;
963218887Sdim
964234353Sdim  ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg);
965218887Sdim
966226633Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
967234353Sdim                            const MemRegion* superRegion);
968218887Sdim
969218887Sdimpublic:
970234353Sdim  const ObjCIvarDecl *getDecl() const;
971234353Sdim  QualType getValueType() const;
972218887Sdim
973251662Sdim  bool canPrintPrettyAsExpr() const;
974251662Sdim  void printPrettyAsExpr(raw_ostream &os) const;
975249423Sdim
976226633Sdim  void dumpToStream(raw_ostream &os) const;
977218887Sdim
978218887Sdim  static bool classof(const MemRegion* R) {
979218887Sdim    return R->getKind() == ObjCIvarRegionKind;
980218887Sdim  }
981218887Sdim};
982218887Sdim//===----------------------------------------------------------------------===//
983221345Sdim// Auxiliary data classes for use with MemRegions.
984218887Sdim//===----------------------------------------------------------------------===//
985218887Sdim
986218887Sdimclass ElementRegion;
987218887Sdim
988218887Sdimclass RegionRawOffset {
989218887Sdimprivate:
990218887Sdim  friend class ElementRegion;
991218887Sdim
992218887Sdim  const MemRegion *Region;
993218887Sdim  CharUnits Offset;
994218887Sdim
995218887Sdim  RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
996218887Sdim    : Region(reg), Offset(offset) {}
997218887Sdim
998218887Sdimpublic:
999218887Sdim  // FIXME: Eventually support symbolic offsets.
1000218887Sdim  CharUnits getOffset() const { return Offset; }
1001218887Sdim  const MemRegion *getRegion() const { return Region; }
1002218887Sdim
1003226633Sdim  void dumpToStream(raw_ostream &os) const;
1004218887Sdim  void dump() const;
1005218887Sdim};
1006218887Sdim
1007234353Sdim/// \brief ElementRegin is used to represent both array elements and casts.
1008226633Sdimclass ElementRegion : public TypedValueRegion {
1009218887Sdim  friend class MemRegionManager;
1010218887Sdim
1011218887Sdim  QualType ElementType;
1012218887Sdim  NonLoc Index;
1013218887Sdim
1014218887Sdim  ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
1015226633Sdim    : TypedValueRegion(sReg, ElementRegionKind),
1016218887Sdim      ElementType(elementType), Index(Idx) {
1017249423Sdim    assert((!Idx.getAs<nonloc::ConcreteInt>() ||
1018249423Sdim            Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
1019218887Sdim           "The index must be signed");
1020218887Sdim  }
1021218887Sdim
1022218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
1023218887Sdim                            SVal Idx, const MemRegion* superRegion);
1024218887Sdim
1025218887Sdimpublic:
1026218887Sdim
1027218887Sdim  NonLoc getIndex() const { return Index; }
1028218887Sdim
1029218887Sdim  QualType getValueType() const {
1030218887Sdim    return ElementType;
1031218887Sdim  }
1032218887Sdim
1033218887Sdim  QualType getElementType() const {
1034218887Sdim    return ElementType;
1035218887Sdim  }
1036218887Sdim  /// Compute the offset within the array. The array might also be a subobject.
1037218887Sdim  RegionRawOffset getAsArrayOffset() const;
1038218887Sdim
1039226633Sdim  void dumpToStream(raw_ostream &os) const;
1040218887Sdim
1041218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
1042218887Sdim
1043218887Sdim  static bool classof(const MemRegion* R) {
1044218887Sdim    return R->getKind() == ElementRegionKind;
1045218887Sdim  }
1046218887Sdim};
1047218887Sdim
1048218887Sdim// C++ temporary object associated with an expression.
1049226633Sdimclass CXXTempObjectRegion : public TypedValueRegion {
1050218887Sdim  friend class MemRegionManager;
1051218887Sdim
1052218887Sdim  Expr const *Ex;
1053218887Sdim
1054218887Sdim  CXXTempObjectRegion(Expr const *E, MemRegion const *sReg)
1055226633Sdim    : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {}
1056218887Sdim
1057218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1058218887Sdim                            Expr const *E, const MemRegion *sReg);
1059218887Sdim
1060218887Sdimpublic:
1061226633Sdim  const Expr *getExpr() const { return Ex; }
1062226633Sdim
1063218887Sdim  QualType getValueType() const {
1064218887Sdim    return Ex->getType();
1065218887Sdim  }
1066218887Sdim
1067226633Sdim  void dumpToStream(raw_ostream &os) const;
1068218887Sdim
1069218887Sdim  void Profile(llvm::FoldingSetNodeID &ID) const;
1070218887Sdim
1071218887Sdim  static bool classof(const MemRegion* R) {
1072218887Sdim    return R->getKind() == CXXTempObjectRegionKind;
1073218887Sdim  }
1074218887Sdim};
1075218887Sdim
1076218887Sdim// CXXBaseObjectRegion represents a base object within a C++ object. It is
1077218887Sdim// identified by the base class declaration and the region of its parent object.
1078226633Sdimclass CXXBaseObjectRegion : public TypedValueRegion {
1079218887Sdim  friend class MemRegionManager;
1080218887Sdim
1081249423Sdim  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
1082218887Sdim
1083249423Sdim  CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
1084249423Sdim                      const MemRegion *SReg)
1085249423Sdim    : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {}
1086218887Sdim
1087249423Sdim  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1088249423Sdim                            bool IsVirtual, const MemRegion *SReg);
1089218887Sdim
1090218887Sdimpublic:
1091249423Sdim  const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
1092249423Sdim  bool isVirtual() const { return Data.getInt(); }
1093218887Sdim
1094218887Sdim  QualType getValueType() const;
1095218887Sdim
1096226633Sdim  void dumpToStream(raw_ostream &os) const;
1097218887Sdim
1098218887Sdim  void Profile(llvm::FoldingSetNodeID &ID) const;
1099218887Sdim
1100218887Sdim  static bool classof(const MemRegion *region) {
1101218887Sdim    return region->getKind() == CXXBaseObjectRegionKind;
1102218887Sdim  }
1103251662Sdim
1104251662Sdim  bool canPrintPrettyAsExpr() const;
1105251662Sdim
1106251662Sdim  void printPrettyAsExpr(raw_ostream &os) const;
1107218887Sdim};
1108218887Sdim
1109218887Sdimtemplate<typename RegionTy>
1110218887Sdimconst RegionTy* MemRegion::getAs() const {
1111218887Sdim  if (const RegionTy* RT = dyn_cast<RegionTy>(this))
1112218887Sdim    return RT;
1113218887Sdim
1114218887Sdim  return NULL;
1115218887Sdim}
1116218887Sdim
1117218887Sdim//===----------------------------------------------------------------------===//
1118218887Sdim// MemRegionManager - Factory object for creating regions.
1119218887Sdim//===----------------------------------------------------------------------===//
1120218887Sdim
1121218887Sdimclass MemRegionManager {
1122218887Sdim  ASTContext &C;
1123218887Sdim  llvm::BumpPtrAllocator& A;
1124218887Sdim  llvm::FoldingSet<MemRegion> Regions;
1125218887Sdim
1126234353Sdim  GlobalInternalSpaceRegion *InternalGlobals;
1127234353Sdim  GlobalSystemSpaceRegion *SystemGlobals;
1128234353Sdim  GlobalImmutableSpaceRegion *ImmutableGlobals;
1129234353Sdim
1130218887Sdim
1131218887Sdim  llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1132218887Sdim    StackLocalsSpaceRegions;
1133218887Sdim  llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1134218887Sdim    StackArgumentsSpaceRegions;
1135218887Sdim  llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1136218887Sdim    StaticsGlobalSpaceRegions;
1137218887Sdim
1138218887Sdim  HeapSpaceRegion *heap;
1139218887Sdim  UnknownSpaceRegion *unknown;
1140218887Sdim  MemSpaceRegion *code;
1141218887Sdim
1142218887Sdimpublic:
1143218887Sdim  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
1144234353Sdim    : C(c), A(a), InternalGlobals(0), SystemGlobals(0), ImmutableGlobals(0),
1145234353Sdim      heap(0), unknown(0), code(0) {}
1146218887Sdim
1147218887Sdim  ~MemRegionManager();
1148218887Sdim
1149218887Sdim  ASTContext &getContext() { return C; }
1150218887Sdim
1151218887Sdim  llvm::BumpPtrAllocator &getAllocator() { return A; }
1152218887Sdim
1153218887Sdim  /// getStackLocalsRegion - Retrieve the memory region associated with the
1154218887Sdim  ///  specified stack frame.
1155218887Sdim  const StackLocalsSpaceRegion *
1156218887Sdim  getStackLocalsRegion(const StackFrameContext *STC);
1157218887Sdim
1158218887Sdim  /// getStackArgumentsRegion - Retrieve the memory region associated with
1159218887Sdim  ///  function/method arguments of the specified stack frame.
1160218887Sdim  const StackArgumentsSpaceRegion *
1161218887Sdim  getStackArgumentsRegion(const StackFrameContext *STC);
1162218887Sdim
1163218887Sdim  /// getGlobalsRegion - Retrieve the memory region associated with
1164218887Sdim  ///  global variables.
1165234353Sdim  const GlobalsSpaceRegion *getGlobalsRegion(
1166234353Sdim      MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1167234353Sdim      const CodeTextRegion *R = 0);
1168218887Sdim
1169218887Sdim  /// getHeapRegion - Retrieve the memory region associated with the
1170218887Sdim  ///  generic "heap".
1171218887Sdim  const HeapSpaceRegion *getHeapRegion();
1172218887Sdim
1173218887Sdim  /// getUnknownRegion - Retrieve the memory region associated with unknown
1174218887Sdim  /// memory space.
1175218887Sdim  const MemSpaceRegion *getUnknownRegion();
1176218887Sdim
1177218887Sdim  const MemSpaceRegion *getCodeRegion();
1178218887Sdim
1179218887Sdim  /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1180226633Sdim  const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1181218887Sdim                                      const LocationContext *LC);
1182218887Sdim
1183218887Sdim  /// getCompoundLiteralRegion - Retrieve the region associated with a
1184218887Sdim  ///  given CompoundLiteral.
1185218887Sdim  const CompoundLiteralRegion*
1186226633Sdim  getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1187218887Sdim                           const LocationContext *LC);
1188218887Sdim
1189221345Sdim  /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1190218887Sdim  ///  parameter 'this'.
1191218887Sdim  const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1192218887Sdim                                        const LocationContext *LC);
1193218887Sdim
1194239462Sdim  /// \brief Retrieve or create a "symbolic" memory region.
1195239462Sdim  const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
1196218887Sdim
1197239462Sdim  /// \brief Return a unique symbolic region belonging to heap memory space.
1198239462Sdim  const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
1199239462Sdim
1200234353Sdim  const StringRegion *getStringRegion(const StringLiteral* Str);
1201218887Sdim
1202234353Sdim  const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1203234353Sdim
1204218887Sdim  /// getVarRegion - Retrieve or create the memory region associated with
1205218887Sdim  ///  a specified VarDecl and LocationContext.
1206218887Sdim  const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
1207218887Sdim
1208218887Sdim  /// getVarRegion - Retrieve or create the memory region associated with
1209218887Sdim  ///  a specified VarDecl and super region.
1210218887Sdim  const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
1211218887Sdim
1212218887Sdim  /// getElementRegion - Retrieve the memory region associated with the
1213218887Sdim  ///  associated element type, index, and super region.
1214218887Sdim  const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1215218887Sdim                                        const MemRegion *superRegion,
1216218887Sdim                                        ASTContext &Ctx);
1217218887Sdim
1218218887Sdim  const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1219218887Sdim                                                 const MemRegion *superRegion) {
1220218887Sdim    return getElementRegion(ER->getElementType(), ER->getIndex(),
1221218887Sdim                            superRegion, ER->getContext());
1222218887Sdim  }
1223218887Sdim
1224218887Sdim  /// getFieldRegion - Retrieve or create the memory region associated with
1225218887Sdim  ///  a specified FieldDecl.  'superRegion' corresponds to the containing
1226218887Sdim  ///  memory region (which typically represents the memory representing
1227218887Sdim  ///  a structure or class).
1228226633Sdim  const FieldRegion *getFieldRegion(const FieldDecl *fd,
1229218887Sdim                                    const MemRegion* superRegion);
1230218887Sdim
1231218887Sdim  const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1232218887Sdim                                             const MemRegion *superRegion) {
1233218887Sdim    return getFieldRegion(FR->getDecl(), superRegion);
1234218887Sdim  }
1235218887Sdim
1236218887Sdim  /// getObjCIvarRegion - Retrieve or create the memory region associated with
1237218887Sdim  ///   a specified Objective-c instance variable.  'superRegion' corresponds
1238218887Sdim  ///   to the containing region (which typically represents the Objective-C
1239218887Sdim  ///   object).
1240226633Sdim  const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1241218887Sdim                                          const MemRegion* superRegion);
1242218887Sdim
1243218887Sdim  const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1244218887Sdim                                                    LocationContext const *LC);
1245218887Sdim
1246249423Sdim  /// Create a CXXBaseObjectRegion with the given base class for region
1247249423Sdim  /// \p Super.
1248249423Sdim  ///
1249249423Sdim  /// The type of \p Super is assumed be a class deriving from \p BaseClass.
1250249423Sdim  const CXXBaseObjectRegion *
1251249423Sdim  getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const MemRegion *Super,
1252249423Sdim                         bool IsVirtual);
1253218887Sdim
1254218887Sdim  /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1255218887Sdim  /// super region.
1256218887Sdim  const CXXBaseObjectRegion *
1257218887Sdim  getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1258218887Sdim                                  const MemRegion *superRegion) {
1259249423Sdim    return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
1260249423Sdim                                  baseReg->isVirtual());
1261218887Sdim  }
1262218887Sdim
1263243830Sdim  const FunctionTextRegion *getFunctionTextRegion(const NamedDecl *FD);
1264218887Sdim  const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
1265218887Sdim                                            CanQualType locTy,
1266234353Sdim                                            AnalysisDeclContext *AC);
1267218887Sdim
1268218887Sdim  /// getBlockDataRegion - Get the memory region associated with an instance
1269218887Sdim  ///  of a block.  Unlike many other MemRegions, the LocationContext*
1270218887Sdim  ///  argument is allowed to be NULL for cases where we have no known
1271218887Sdim  ///  context.
1272218887Sdim  const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
1273218887Sdim                                            const LocationContext *lc = NULL);
1274218887Sdim
1275218887Sdimprivate:
1276218887Sdim  template <typename RegionTy, typename A1>
1277218887Sdim  RegionTy* getRegion(const A1 a1);
1278218887Sdim
1279218887Sdim  template <typename RegionTy, typename A1>
1280218887Sdim  RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
1281218887Sdim
1282218887Sdim  template <typename RegionTy, typename A1, typename A2>
1283218887Sdim  RegionTy* getRegion(const A1 a1, const A2 a2);
1284218887Sdim
1285218887Sdim  template <typename RegionTy, typename A1, typename A2>
1286218887Sdim  RegionTy* getSubRegion(const A1 a1, const A2 a2,
1287218887Sdim                         const MemRegion* superRegion);
1288218887Sdim
1289218887Sdim  template <typename RegionTy, typename A1, typename A2, typename A3>
1290218887Sdim  RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
1291218887Sdim                         const MemRegion* superRegion);
1292218887Sdim
1293218887Sdim  template <typename REG>
1294218887Sdim  const REG* LazyAllocate(REG*& region);
1295218887Sdim
1296218887Sdim  template <typename REG, typename ARG>
1297218887Sdim  const REG* LazyAllocate(REG*& region, ARG a);
1298218887Sdim};
1299218887Sdim
1300218887Sdim//===----------------------------------------------------------------------===//
1301218887Sdim// Out-of-line member definitions.
1302218887Sdim//===----------------------------------------------------------------------===//
1303218887Sdim
1304226633Sdiminline ASTContext &MemRegion::getContext() const {
1305218887Sdim  return getMemRegionManager()->getContext();
1306218887Sdim}
1307218887Sdim
1308218887Sdim} // end GR namespace
1309218887Sdim
1310218887Sdim} // end clang namespace
1311218887Sdim
1312218887Sdim//===----------------------------------------------------------------------===//
1313218887Sdim// Pretty-printing regions.
1314218887Sdim//===----------------------------------------------------------------------===//
1315218887Sdim
1316218887Sdimnamespace llvm {
1317226633Sdimstatic inline raw_ostream &operator<<(raw_ostream &os,
1318218887Sdim                                      const clang::ento::MemRegion* R) {
1319218887Sdim  R->dumpToStream(os);
1320218887Sdim  return os;
1321218887Sdim}
1322218887Sdim} // end llvm namespace
1323218887Sdim
1324218887Sdim#endif
1325