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 */
638263508Sdim  unsigned BlockCount;
639218887Sdim  void *ReferencedVars;
640239462Sdim  void *OriginalVars;
641218887Sdim
642218887Sdim  BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
643263508Sdim                  unsigned count, const MemRegion *sreg)
644243830Sdim  : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
645263508Sdim     BlockCount(count),
646239462Sdim    ReferencedVars(0), OriginalVars(0) {}
647218887Sdim
648239462Sdimpublic:
649218887Sdim  const BlockTextRegion *getCodeRegion() const { return BC; }
650218887Sdim
651218887Sdim  const BlockDecl *getDecl() const { return BC->getDecl(); }
652243830Sdim
653243830Sdim  QualType getLocationType() const { return BC->getLocationType(); }
654218887Sdim
655218887Sdim  class referenced_vars_iterator {
656218887Sdim    const MemRegion * const *R;
657239462Sdim    const MemRegion * const *OriginalR;
658218887Sdim  public:
659239462Sdim    explicit referenced_vars_iterator(const MemRegion * const *r,
660239462Sdim                                      const MemRegion * const *originalR)
661239462Sdim      : R(r), OriginalR(originalR) {}
662249423Sdim
663249423Sdim    const VarRegion *getCapturedRegion() const {
664249423Sdim      return cast<VarRegion>(*R);
665218887Sdim    }
666249423Sdim    const VarRegion *getOriginalRegion() const {
667249423Sdim      return cast<VarRegion>(*OriginalR);
668239462Sdim    }
669239462Sdim
670218887Sdim    bool operator==(const referenced_vars_iterator &I) const {
671249423Sdim      assert((R == 0) == (I.R == 0));
672218887Sdim      return I.R == R;
673218887Sdim    }
674218887Sdim    bool operator!=(const referenced_vars_iterator &I) const {
675249423Sdim      assert((R == 0) == (I.R == 0));
676218887Sdim      return I.R != R;
677218887Sdim    }
678226633Sdim    referenced_vars_iterator &operator++() {
679218887Sdim      ++R;
680239462Sdim      ++OriginalR;
681218887Sdim      return *this;
682218887Sdim    }
683218887Sdim  };
684249423Sdim
685249423Sdim  /// Return the original region for a captured region, if
686249423Sdim  /// one exists.
687249423Sdim  const VarRegion *getOriginalRegion(const VarRegion *VR) const;
688218887Sdim
689218887Sdim  referenced_vars_iterator referenced_vars_begin() const;
690218887Sdim  referenced_vars_iterator referenced_vars_end() const;
691218887Sdim
692226633Sdim  virtual void dumpToStream(raw_ostream &os) const;
693218887Sdim
694218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
695218887Sdim
696218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
697263508Sdim                            const LocationContext *, unsigned,
698263508Sdim                            const MemRegion *);
699218887Sdim
700218887Sdim  static bool classof(const MemRegion* R) {
701218887Sdim    return R->getKind() == BlockDataRegionKind;
702218887Sdim  }
703218887Sdimprivate:
704218887Sdim  void LazyInitializeReferencedVars();
705249423Sdim  std::pair<const VarRegion *, const VarRegion *>
706249423Sdim  getCaptureRegions(const VarDecl *VD);
707218887Sdim};
708218887Sdim
709218887Sdim/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
710218887Sdim///  clases, SymbolicRegion represents a region that serves as an alias for
711218887Sdim///  either a real region, a NULL pointer, etc.  It essentially is used to
712218887Sdim///  map the concept of symbolic values into the domain of regions.  Symbolic
713218887Sdim///  regions do not need to be typed.
714218887Sdimclass SymbolicRegion : public SubRegion {
715218887Sdimprotected:
716218887Sdim  const SymbolRef sym;
717218887Sdim
718218887Sdimpublic:
719218887Sdim  SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
720218887Sdim    : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
721218887Sdim
722218887Sdim  SymbolRef getSymbol() const {
723218887Sdim    return sym;
724218887Sdim  }
725218887Sdim
726218887Sdim  bool isBoundable() const { return true; }
727218887Sdim
728218887Sdim  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
729218887Sdim
730218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
731218887Sdim
732218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
733218887Sdim                            SymbolRef sym,
734218887Sdim                            const MemRegion* superRegion);
735218887Sdim
736226633Sdim  void dumpToStream(raw_ostream &os) const;
737218887Sdim
738218887Sdim  static bool classof(const MemRegion* R) {
739218887Sdim    return R->getKind() == SymbolicRegionKind;
740218887Sdim  }
741218887Sdim};
742218887Sdim
743218887Sdim/// StringRegion - Region associated with a StringLiteral.
744226633Sdimclass StringRegion : public TypedValueRegion {
745218887Sdim  friend class MemRegionManager;
746218887Sdim  const StringLiteral* Str;
747218887Sdimprotected:
748218887Sdim
749218887Sdim  StringRegion(const StringLiteral* str, const MemRegion* sreg)
750226633Sdim    : TypedValueRegion(sreg, StringRegionKind), Str(str) {}
751218887Sdim
752218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
753218887Sdim                            const StringLiteral* Str,
754218887Sdim                            const MemRegion* superRegion);
755218887Sdim
756218887Sdimpublic:
757218887Sdim
758218887Sdim  const StringLiteral* getStringLiteral() const { return Str; }
759218887Sdim
760218887Sdim  QualType getValueType() const {
761218887Sdim    return Str->getType();
762218887Sdim  }
763218887Sdim
764218887Sdim  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
765218887Sdim
766218887Sdim  bool isBoundable() const { return false; }
767218887Sdim
768218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const {
769218887Sdim    ProfileRegion(ID, Str, superRegion);
770218887Sdim  }
771218887Sdim
772226633Sdim  void dumpToStream(raw_ostream &os) const;
773218887Sdim
774218887Sdim  static bool classof(const MemRegion* R) {
775218887Sdim    return R->getKind() == StringRegionKind;
776218887Sdim  }
777218887Sdim};
778234353Sdim
779234353Sdim/// The region associated with an ObjCStringLiteral.
780234353Sdimclass ObjCStringRegion : public TypedValueRegion {
781234353Sdim  friend class MemRegionManager;
782234353Sdim  const ObjCStringLiteral* Str;
783234353Sdimprotected:
784234353Sdim
785234353Sdim  ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg)
786234353Sdim  : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {}
787234353Sdim
788234353Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
789234353Sdim                            const ObjCStringLiteral* Str,
790234353Sdim                            const MemRegion* superRegion);
791234353Sdim
792234353Sdimpublic:
793234353Sdim
794234353Sdim  const ObjCStringLiteral* getObjCStringLiteral() const { return Str; }
795234353Sdim
796234353Sdim  QualType getValueType() const {
797234353Sdim    return Str->getType();
798234353Sdim  }
799234353Sdim
800234353Sdim  bool isBoundable() const { return false; }
801234353Sdim
802234353Sdim  void Profile(llvm::FoldingSetNodeID& ID) const {
803234353Sdim    ProfileRegion(ID, Str, superRegion);
804234353Sdim  }
805234353Sdim
806234353Sdim  void dumpToStream(raw_ostream &os) const;
807234353Sdim
808234353Sdim  static bool classof(const MemRegion* R) {
809234353Sdim    return R->getKind() == ObjCStringRegionKind;
810234353Sdim  }
811234353Sdim};
812218887Sdim
813218887Sdim/// CompoundLiteralRegion - A memory region representing a compound literal.
814218887Sdim///   Compound literals are essentially temporaries that are stack allocated
815218887Sdim///   or in the global constant pool.
816226633Sdimclass CompoundLiteralRegion : public TypedValueRegion {
817218887Sdimprivate:
818218887Sdim  friend class MemRegionManager;
819226633Sdim  const CompoundLiteralExpr *CL;
820218887Sdim
821226633Sdim  CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg)
822226633Sdim    : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
823218887Sdim
824218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
825226633Sdim                            const CompoundLiteralExpr *CL,
826218887Sdim                            const MemRegion* superRegion);
827218887Sdimpublic:
828218887Sdim  QualType getValueType() const {
829218887Sdim    return CL->getType();
830218887Sdim  }
831218887Sdim
832218887Sdim  bool isBoundable() const { return !CL->isFileScope(); }
833218887Sdim
834218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
835218887Sdim
836226633Sdim  void dumpToStream(raw_ostream &os) const;
837218887Sdim
838226633Sdim  const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
839218887Sdim
840218887Sdim  static bool classof(const MemRegion* R) {
841218887Sdim    return R->getKind() == CompoundLiteralRegionKind;
842218887Sdim  }
843218887Sdim};
844218887Sdim
845226633Sdimclass DeclRegion : public TypedValueRegion {
846218887Sdimprotected:
847226633Sdim  const Decl *D;
848218887Sdim
849226633Sdim  DeclRegion(const Decl *d, const MemRegion* sReg, Kind k)
850226633Sdim    : TypedValueRegion(sReg, k), D(d) {}
851218887Sdim
852226633Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
853218887Sdim                      const MemRegion* superRegion, Kind k);
854218887Sdim
855218887Sdimpublic:
856226633Sdim  const Decl *getDecl() const { return D; }
857218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
858218887Sdim
859218887Sdim  static bool classof(const MemRegion* R) {
860218887Sdim    unsigned k = R->getKind();
861218887Sdim    return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
862218887Sdim  }
863218887Sdim};
864218887Sdim
865218887Sdimclass VarRegion : public DeclRegion {
866218887Sdim  friend class MemRegionManager;
867218887Sdim
868218887Sdim  // Constructors and private methods.
869226633Sdim  VarRegion(const VarDecl *vd, const MemRegion* sReg)
870218887Sdim    : DeclRegion(vd, sReg, VarRegionKind) {}
871218887Sdim
872226633Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
873218887Sdim                            const MemRegion *superRegion) {
874218887Sdim    DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
875218887Sdim  }
876218887Sdim
877218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
878218887Sdim
879218887Sdimpublic:
880218887Sdim  const VarDecl *getDecl() const { return cast<VarDecl>(D); }
881218887Sdim
882218887Sdim  const StackFrameContext *getStackFrame() const;
883218887Sdim
884218887Sdim  QualType getValueType() const {
885218887Sdim    // FIXME: We can cache this if needed.
886218887Sdim    return getDecl()->getType();
887218887Sdim  }
888218887Sdim
889226633Sdim  void dumpToStream(raw_ostream &os) const;
890218887Sdim
891218887Sdim  static bool classof(const MemRegion* R) {
892218887Sdim    return R->getKind() == VarRegionKind;
893218887Sdim  }
894234353Sdim
895251662Sdim  bool canPrintPrettyAsExpr() const;
896251662Sdim
897251662Sdim  void printPrettyAsExpr(raw_ostream &os) const;
898218887Sdim};
899218887Sdim
900218887Sdim/// CXXThisRegion - Represents the region for the implicit 'this' parameter
901218887Sdim///  in a call to a C++ method.  This region doesn't represent the object
902218887Sdim///  referred to by 'this', but rather 'this' itself.
903226633Sdimclass CXXThisRegion : public TypedValueRegion {
904218887Sdim  friend class MemRegionManager;
905218887Sdim  CXXThisRegion(const PointerType *thisPointerTy,
906218887Sdim                const MemRegion *sReg)
907226633Sdim    : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
908218887Sdim
909218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
910218887Sdim                            const PointerType *PT,
911218887Sdim                            const MemRegion *sReg);
912218887Sdim
913218887Sdim  void Profile(llvm::FoldingSetNodeID &ID) const;
914218887Sdim
915218887Sdimpublic:
916218887Sdim  QualType getValueType() const {
917218887Sdim    return QualType(ThisPointerTy, 0);
918218887Sdim  }
919218887Sdim
920226633Sdim  void dumpToStream(raw_ostream &os) const;
921218887Sdim
922218887Sdim  static bool classof(const MemRegion* R) {
923218887Sdim    return R->getKind() == CXXThisRegionKind;
924218887Sdim  }
925218887Sdim
926218887Sdimprivate:
927218887Sdim  const PointerType *ThisPointerTy;
928218887Sdim};
929218887Sdim
930218887Sdimclass FieldRegion : public DeclRegion {
931218887Sdim  friend class MemRegionManager;
932218887Sdim
933226633Sdim  FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
934218887Sdim    : DeclRegion(fd, sReg, FieldRegionKind) {}
935218887Sdim
936218887Sdimpublic:
937226633Sdim  const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
938218887Sdim
939218887Sdim  QualType getValueType() const {
940218887Sdim    // FIXME: We can cache this if needed.
941218887Sdim    return getDecl()->getType();
942218887Sdim  }
943218887Sdim
944218887Sdim  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
945218887Sdim
946226633Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
947218887Sdim                            const MemRegion* superRegion) {
948218887Sdim    DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
949218887Sdim  }
950218887Sdim
951218887Sdim  static bool classof(const MemRegion* R) {
952218887Sdim    return R->getKind() == FieldRegionKind;
953218887Sdim  }
954234353Sdim
955234353Sdim  void dumpToStream(raw_ostream &os) const;
956239462Sdim
957239462Sdim  bool canPrintPretty() const;
958239462Sdim  void printPretty(raw_ostream &os) const;
959251662Sdim  bool canPrintPrettyAsExpr() const;
960251662Sdim  void printPrettyAsExpr(raw_ostream &os) const;
961218887Sdim};
962218887Sdim
963218887Sdimclass ObjCIvarRegion : public DeclRegion {
964218887Sdim
965218887Sdim  friend class MemRegionManager;
966218887Sdim
967234353Sdim  ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg);
968218887Sdim
969226633Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
970234353Sdim                            const MemRegion* superRegion);
971218887Sdim
972218887Sdimpublic:
973234353Sdim  const ObjCIvarDecl *getDecl() const;
974234353Sdim  QualType getValueType() const;
975218887Sdim
976251662Sdim  bool canPrintPrettyAsExpr() const;
977251662Sdim  void printPrettyAsExpr(raw_ostream &os) const;
978249423Sdim
979226633Sdim  void dumpToStream(raw_ostream &os) const;
980218887Sdim
981218887Sdim  static bool classof(const MemRegion* R) {
982218887Sdim    return R->getKind() == ObjCIvarRegionKind;
983218887Sdim  }
984218887Sdim};
985218887Sdim//===----------------------------------------------------------------------===//
986221345Sdim// Auxiliary data classes for use with MemRegions.
987218887Sdim//===----------------------------------------------------------------------===//
988218887Sdim
989218887Sdimclass ElementRegion;
990218887Sdim
991218887Sdimclass RegionRawOffset {
992218887Sdimprivate:
993218887Sdim  friend class ElementRegion;
994218887Sdim
995218887Sdim  const MemRegion *Region;
996218887Sdim  CharUnits Offset;
997218887Sdim
998218887Sdim  RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
999218887Sdim    : Region(reg), Offset(offset) {}
1000218887Sdim
1001218887Sdimpublic:
1002218887Sdim  // FIXME: Eventually support symbolic offsets.
1003218887Sdim  CharUnits getOffset() const { return Offset; }
1004218887Sdim  const MemRegion *getRegion() const { return Region; }
1005218887Sdim
1006226633Sdim  void dumpToStream(raw_ostream &os) const;
1007218887Sdim  void dump() const;
1008218887Sdim};
1009218887Sdim
1010234353Sdim/// \brief ElementRegin is used to represent both array elements and casts.
1011226633Sdimclass ElementRegion : public TypedValueRegion {
1012218887Sdim  friend class MemRegionManager;
1013218887Sdim
1014218887Sdim  QualType ElementType;
1015218887Sdim  NonLoc Index;
1016218887Sdim
1017218887Sdim  ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
1018226633Sdim    : TypedValueRegion(sReg, ElementRegionKind),
1019218887Sdim      ElementType(elementType), Index(Idx) {
1020249423Sdim    assert((!Idx.getAs<nonloc::ConcreteInt>() ||
1021249423Sdim            Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
1022218887Sdim           "The index must be signed");
1023218887Sdim  }
1024218887Sdim
1025218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
1026218887Sdim                            SVal Idx, const MemRegion* superRegion);
1027218887Sdim
1028218887Sdimpublic:
1029218887Sdim
1030218887Sdim  NonLoc getIndex() const { return Index; }
1031218887Sdim
1032218887Sdim  QualType getValueType() const {
1033218887Sdim    return ElementType;
1034218887Sdim  }
1035218887Sdim
1036218887Sdim  QualType getElementType() const {
1037218887Sdim    return ElementType;
1038218887Sdim  }
1039218887Sdim  /// Compute the offset within the array. The array might also be a subobject.
1040218887Sdim  RegionRawOffset getAsArrayOffset() const;
1041218887Sdim
1042226633Sdim  void dumpToStream(raw_ostream &os) const;
1043218887Sdim
1044218887Sdim  void Profile(llvm::FoldingSetNodeID& ID) const;
1045218887Sdim
1046218887Sdim  static bool classof(const MemRegion* R) {
1047218887Sdim    return R->getKind() == ElementRegionKind;
1048218887Sdim  }
1049218887Sdim};
1050218887Sdim
1051218887Sdim// C++ temporary object associated with an expression.
1052226633Sdimclass CXXTempObjectRegion : public TypedValueRegion {
1053218887Sdim  friend class MemRegionManager;
1054218887Sdim
1055218887Sdim  Expr const *Ex;
1056218887Sdim
1057218887Sdim  CXXTempObjectRegion(Expr const *E, MemRegion const *sReg)
1058226633Sdim    : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {}
1059218887Sdim
1060218887Sdim  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1061218887Sdim                            Expr const *E, const MemRegion *sReg);
1062218887Sdim
1063218887Sdimpublic:
1064226633Sdim  const Expr *getExpr() const { return Ex; }
1065226633Sdim
1066218887Sdim  QualType getValueType() const {
1067218887Sdim    return Ex->getType();
1068218887Sdim  }
1069218887Sdim
1070226633Sdim  void dumpToStream(raw_ostream &os) const;
1071218887Sdim
1072218887Sdim  void Profile(llvm::FoldingSetNodeID &ID) const;
1073218887Sdim
1074218887Sdim  static bool classof(const MemRegion* R) {
1075218887Sdim    return R->getKind() == CXXTempObjectRegionKind;
1076218887Sdim  }
1077218887Sdim};
1078218887Sdim
1079218887Sdim// CXXBaseObjectRegion represents a base object within a C++ object. It is
1080218887Sdim// identified by the base class declaration and the region of its parent object.
1081226633Sdimclass CXXBaseObjectRegion : public TypedValueRegion {
1082218887Sdim  friend class MemRegionManager;
1083218887Sdim
1084249423Sdim  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
1085218887Sdim
1086249423Sdim  CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
1087249423Sdim                      const MemRegion *SReg)
1088249423Sdim    : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {}
1089218887Sdim
1090249423Sdim  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1091249423Sdim                            bool IsVirtual, const MemRegion *SReg);
1092218887Sdim
1093218887Sdimpublic:
1094249423Sdim  const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
1095249423Sdim  bool isVirtual() const { return Data.getInt(); }
1096218887Sdim
1097218887Sdim  QualType getValueType() const;
1098218887Sdim
1099226633Sdim  void dumpToStream(raw_ostream &os) const;
1100218887Sdim
1101218887Sdim  void Profile(llvm::FoldingSetNodeID &ID) const;
1102218887Sdim
1103218887Sdim  static bool classof(const MemRegion *region) {
1104218887Sdim    return region->getKind() == CXXBaseObjectRegionKind;
1105218887Sdim  }
1106251662Sdim
1107251662Sdim  bool canPrintPrettyAsExpr() const;
1108251662Sdim
1109251662Sdim  void printPrettyAsExpr(raw_ostream &os) const;
1110218887Sdim};
1111218887Sdim
1112218887Sdimtemplate<typename RegionTy>
1113218887Sdimconst RegionTy* MemRegion::getAs() const {
1114218887Sdim  if (const RegionTy* RT = dyn_cast<RegionTy>(this))
1115218887Sdim    return RT;
1116218887Sdim
1117218887Sdim  return NULL;
1118218887Sdim}
1119218887Sdim
1120218887Sdim//===----------------------------------------------------------------------===//
1121218887Sdim// MemRegionManager - Factory object for creating regions.
1122218887Sdim//===----------------------------------------------------------------------===//
1123218887Sdim
1124218887Sdimclass MemRegionManager {
1125218887Sdim  ASTContext &C;
1126218887Sdim  llvm::BumpPtrAllocator& A;
1127218887Sdim  llvm::FoldingSet<MemRegion> Regions;
1128218887Sdim
1129234353Sdim  GlobalInternalSpaceRegion *InternalGlobals;
1130234353Sdim  GlobalSystemSpaceRegion *SystemGlobals;
1131234353Sdim  GlobalImmutableSpaceRegion *ImmutableGlobals;
1132234353Sdim
1133218887Sdim
1134218887Sdim  llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1135218887Sdim    StackLocalsSpaceRegions;
1136218887Sdim  llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1137218887Sdim    StackArgumentsSpaceRegions;
1138218887Sdim  llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1139218887Sdim    StaticsGlobalSpaceRegions;
1140218887Sdim
1141218887Sdim  HeapSpaceRegion *heap;
1142218887Sdim  UnknownSpaceRegion *unknown;
1143218887Sdim  MemSpaceRegion *code;
1144218887Sdim
1145218887Sdimpublic:
1146218887Sdim  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
1147234353Sdim    : C(c), A(a), InternalGlobals(0), SystemGlobals(0), ImmutableGlobals(0),
1148234353Sdim      heap(0), unknown(0), code(0) {}
1149218887Sdim
1150218887Sdim  ~MemRegionManager();
1151218887Sdim
1152218887Sdim  ASTContext &getContext() { return C; }
1153218887Sdim
1154218887Sdim  llvm::BumpPtrAllocator &getAllocator() { return A; }
1155218887Sdim
1156218887Sdim  /// getStackLocalsRegion - Retrieve the memory region associated with the
1157218887Sdim  ///  specified stack frame.
1158218887Sdim  const StackLocalsSpaceRegion *
1159218887Sdim  getStackLocalsRegion(const StackFrameContext *STC);
1160218887Sdim
1161218887Sdim  /// getStackArgumentsRegion - Retrieve the memory region associated with
1162218887Sdim  ///  function/method arguments of the specified stack frame.
1163218887Sdim  const StackArgumentsSpaceRegion *
1164218887Sdim  getStackArgumentsRegion(const StackFrameContext *STC);
1165218887Sdim
1166218887Sdim  /// getGlobalsRegion - Retrieve the memory region associated with
1167218887Sdim  ///  global variables.
1168234353Sdim  const GlobalsSpaceRegion *getGlobalsRegion(
1169234353Sdim      MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1170234353Sdim      const CodeTextRegion *R = 0);
1171218887Sdim
1172218887Sdim  /// getHeapRegion - Retrieve the memory region associated with the
1173218887Sdim  ///  generic "heap".
1174218887Sdim  const HeapSpaceRegion *getHeapRegion();
1175218887Sdim
1176218887Sdim  /// getUnknownRegion - Retrieve the memory region associated with unknown
1177218887Sdim  /// memory space.
1178218887Sdim  const MemSpaceRegion *getUnknownRegion();
1179218887Sdim
1180218887Sdim  const MemSpaceRegion *getCodeRegion();
1181218887Sdim
1182218887Sdim  /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1183226633Sdim  const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1184218887Sdim                                      const LocationContext *LC);
1185218887Sdim
1186218887Sdim  /// getCompoundLiteralRegion - Retrieve the region associated with a
1187218887Sdim  ///  given CompoundLiteral.
1188218887Sdim  const CompoundLiteralRegion*
1189226633Sdim  getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1190218887Sdim                           const LocationContext *LC);
1191218887Sdim
1192221345Sdim  /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1193218887Sdim  ///  parameter 'this'.
1194218887Sdim  const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1195218887Sdim                                        const LocationContext *LC);
1196218887Sdim
1197239462Sdim  /// \brief Retrieve or create a "symbolic" memory region.
1198239462Sdim  const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
1199218887Sdim
1200239462Sdim  /// \brief Return a unique symbolic region belonging to heap memory space.
1201239462Sdim  const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
1202239462Sdim
1203234353Sdim  const StringRegion *getStringRegion(const StringLiteral* Str);
1204218887Sdim
1205234353Sdim  const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1206234353Sdim
1207218887Sdim  /// getVarRegion - Retrieve or create the memory region associated with
1208218887Sdim  ///  a specified VarDecl and LocationContext.
1209218887Sdim  const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
1210218887Sdim
1211218887Sdim  /// getVarRegion - Retrieve or create the memory region associated with
1212218887Sdim  ///  a specified VarDecl and super region.
1213218887Sdim  const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
1214218887Sdim
1215218887Sdim  /// getElementRegion - Retrieve the memory region associated with the
1216218887Sdim  ///  associated element type, index, and super region.
1217218887Sdim  const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1218218887Sdim                                        const MemRegion *superRegion,
1219218887Sdim                                        ASTContext &Ctx);
1220218887Sdim
1221218887Sdim  const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1222218887Sdim                                                 const MemRegion *superRegion) {
1223218887Sdim    return getElementRegion(ER->getElementType(), ER->getIndex(),
1224218887Sdim                            superRegion, ER->getContext());
1225218887Sdim  }
1226218887Sdim
1227218887Sdim  /// getFieldRegion - Retrieve or create the memory region associated with
1228218887Sdim  ///  a specified FieldDecl.  'superRegion' corresponds to the containing
1229218887Sdim  ///  memory region (which typically represents the memory representing
1230218887Sdim  ///  a structure or class).
1231226633Sdim  const FieldRegion *getFieldRegion(const FieldDecl *fd,
1232218887Sdim                                    const MemRegion* superRegion);
1233218887Sdim
1234218887Sdim  const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1235218887Sdim                                             const MemRegion *superRegion) {
1236218887Sdim    return getFieldRegion(FR->getDecl(), superRegion);
1237218887Sdim  }
1238218887Sdim
1239218887Sdim  /// getObjCIvarRegion - Retrieve or create the memory region associated with
1240218887Sdim  ///   a specified Objective-c instance variable.  'superRegion' corresponds
1241218887Sdim  ///   to the containing region (which typically represents the Objective-C
1242218887Sdim  ///   object).
1243226633Sdim  const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1244218887Sdim                                          const MemRegion* superRegion);
1245218887Sdim
1246218887Sdim  const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1247218887Sdim                                                    LocationContext const *LC);
1248218887Sdim
1249249423Sdim  /// Create a CXXBaseObjectRegion with the given base class for region
1250249423Sdim  /// \p Super.
1251249423Sdim  ///
1252249423Sdim  /// The type of \p Super is assumed be a class deriving from \p BaseClass.
1253249423Sdim  const CXXBaseObjectRegion *
1254249423Sdim  getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const MemRegion *Super,
1255249423Sdim                         bool IsVirtual);
1256218887Sdim
1257218887Sdim  /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1258218887Sdim  /// super region.
1259218887Sdim  const CXXBaseObjectRegion *
1260218887Sdim  getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1261218887Sdim                                  const MemRegion *superRegion) {
1262249423Sdim    return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
1263249423Sdim                                  baseReg->isVirtual());
1264218887Sdim  }
1265218887Sdim
1266243830Sdim  const FunctionTextRegion *getFunctionTextRegion(const NamedDecl *FD);
1267218887Sdim  const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
1268218887Sdim                                            CanQualType locTy,
1269234353Sdim                                            AnalysisDeclContext *AC);
1270218887Sdim
1271218887Sdim  /// getBlockDataRegion - Get the memory region associated with an instance
1272218887Sdim  ///  of a block.  Unlike many other MemRegions, the LocationContext*
1273218887Sdim  ///  argument is allowed to be NULL for cases where we have no known
1274218887Sdim  ///  context.
1275218887Sdim  const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
1276263508Sdim                                            const LocationContext *lc,
1277263508Sdim                                            unsigned blockCount);
1278218887Sdim
1279263508Sdim  /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
1280263508Sdim  /// by static references. This differs from getCXXTempObjectRegion in the
1281263508Sdim  /// super-region used.
1282263508Sdim  const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
1283263508Sdim
1284218887Sdimprivate:
1285218887Sdim  template <typename RegionTy, typename A1>
1286218887Sdim  RegionTy* getRegion(const A1 a1);
1287218887Sdim
1288218887Sdim  template <typename RegionTy, typename A1>
1289218887Sdim  RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
1290218887Sdim
1291218887Sdim  template <typename RegionTy, typename A1, typename A2>
1292218887Sdim  RegionTy* getRegion(const A1 a1, const A2 a2);
1293218887Sdim
1294218887Sdim  template <typename RegionTy, typename A1, typename A2>
1295218887Sdim  RegionTy* getSubRegion(const A1 a1, const A2 a2,
1296218887Sdim                         const MemRegion* superRegion);
1297218887Sdim
1298218887Sdim  template <typename RegionTy, typename A1, typename A2, typename A3>
1299218887Sdim  RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
1300218887Sdim                         const MemRegion* superRegion);
1301218887Sdim
1302218887Sdim  template <typename REG>
1303218887Sdim  const REG* LazyAllocate(REG*& region);
1304218887Sdim
1305218887Sdim  template <typename REG, typename ARG>
1306218887Sdim  const REG* LazyAllocate(REG*& region, ARG a);
1307218887Sdim};
1308218887Sdim
1309218887Sdim//===----------------------------------------------------------------------===//
1310218887Sdim// Out-of-line member definitions.
1311218887Sdim//===----------------------------------------------------------------------===//
1312218887Sdim
1313226633Sdiminline ASTContext &MemRegion::getContext() const {
1314218887Sdim  return getMemRegionManager()->getContext();
1315218887Sdim}
1316263508Sdim
1317263508Sdim//===----------------------------------------------------------------------===//
1318263508Sdim// Means for storing region/symbol handling traits.
1319263508Sdim//===----------------------------------------------------------------------===//
1320263508Sdim
1321263508Sdim/// Information about invalidation for a particular region/symbol.
1322263508Sdimclass RegionAndSymbolInvalidationTraits {
1323263508Sdim  typedef unsigned char StorageTypeForKinds;
1324263508Sdim  llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
1325263508Sdim  llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
1326263508Sdim
1327263508Sdim  typedef llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator
1328263508Sdim      const_region_iterator;
1329263508Sdim  typedef llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator
1330263508Sdim      const_symbol_iterator;
1331263508Sdim
1332263508Sdimpublic:
1333263508Sdim  /// \brief Describes different invalidation traits.
1334263508Sdim  enum InvalidationKinds {
1335263508Sdim    /// Tells that a region's contents is not changed.
1336263508Sdim    TK_PreserveContents = 0x1,
1337263508Sdim    /// Suppress pointer-escaping of a region.
1338263508Sdim    TK_SuppressEscape = 0x2
1339263508Sdim
1340263508Sdim    // Do not forget to extend StorageTypeForKinds if number of traits exceed
1341263508Sdim    // the number of bits StorageTypeForKinds can store.
1342263508Sdim  };
1343263508Sdim
1344263508Sdim  void setTrait(SymbolRef Sym, InvalidationKinds IK);
1345263508Sdim  void setTrait(const MemRegion *MR, InvalidationKinds IK);
1346263508Sdim  bool hasTrait(SymbolRef Sym, InvalidationKinds IK);
1347263508Sdim  bool hasTrait(const MemRegion *MR, InvalidationKinds IK);
1348263508Sdim};
1349218887Sdim
1350218887Sdim} // end GR namespace
1351218887Sdim
1352218887Sdim} // end clang namespace
1353218887Sdim
1354218887Sdim//===----------------------------------------------------------------------===//
1355218887Sdim// Pretty-printing regions.
1356218887Sdim//===----------------------------------------------------------------------===//
1357218887Sdim
1358218887Sdimnamespace llvm {
1359226633Sdimstatic inline raw_ostream &operator<<(raw_ostream &os,
1360218887Sdim                                      const clang::ento::MemRegion* R) {
1361218887Sdim  R->dumpToStream(os);
1362218887Sdim  return os;
1363218887Sdim}
1364218887Sdim} // end llvm namespace
1365218887Sdim
1366218887Sdim#endif
1367