MemRegion.h revision 250101353b711a409b075f1bc11070dddec7100b
1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==//
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//                     The LLVM Compiler Infrastructure
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
54a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// This file is distributed under the University of Illinois Open Source
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// License. See LICENSE.TXT for details.
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//===----------------------------------------------------------------------===//
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//  This file defines MemRegion and its subclasses.  MemRegion defines a
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//  partially-typed abstraction of memory useful for path-sensitive dataflow
124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch//  analyses.
134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch//
144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch//===----------------------------------------------------------------------===//
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef LLVM_CLANG_ANALYSIS_MEMREGION_H
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define LLVM_CLANG_ANALYSIS_MEMREGION_H
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "clang/AST/Decl.h"
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "clang/AST/DeclObjC.h"
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "clang/Analysis/PathSensitive/SymbolManager.h"
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "clang/Analysis/PathSensitive/SVals.h"
234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "clang/AST/ASTContext.h"
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "llvm/Support/Casting.h"
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "llvm/ADT/FoldingSet.h"
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "llvm/ADT/ImmutableList.h"
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "llvm/ADT/ImmutableMap.h"
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "llvm/Support/Allocator.h"
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string>
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace llvm { class raw_ostream; }
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace clang {
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MemRegionManager;
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/// MemRegion - The root abstract class for all memory regions.
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MemRegion : public llvm::FoldingSetNode {
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottpublic:
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  enum Kind { MemSpaceRegionKind,
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              SymbolicRegionKind,
434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              AllocaRegionKind,
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              // Typed regions.
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              BEG_TYPED_REGIONS,
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott               CodeTextRegionKind,
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott               CompoundLiteralRegionKind,
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott               StringRegionKind, ElementRegionKind,
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott               TypedViewRegionKind,
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott               // Decl Regions.
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                 BEG_DECL_REGIONS,
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                  VarRegionKind, FieldRegionKind,
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                  ObjCIvarRegionKind, ObjCObjectRegionKind,
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                 END_DECL_REGIONS,
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              END_TYPED_REGIONS };
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottprivate:
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const Kind kind;
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottprotected:
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MemRegion(Kind k) : kind(k) {}
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual ~MemRegion();
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottpublic:
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // virtual MemExtent getExtent(MemRegionManager& mrm) const = 0;
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string getString() const;
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void print(llvm::raw_ostream& os) const;
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Kind getKind() const { return kind; }
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template<typename RegionTy> const RegionTy* getAs() const;
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual bool isBoundable(ASTContext&) const { return true; }
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static bool classof(const MemRegion*) { return true; }
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/// MemSpaceRegion - A memory region that represents and "memory space";
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///  for example, the set of global variables, the stack frame, etc.
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MemSpaceRegion : public MemRegion {
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  friend class MemRegionManager;
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MemSpaceRegion() : MemRegion(MemSpaceRegionKind) {}
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottpublic:
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //RegionExtent getExtent() const { return UndefinedExtent(); }
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Profile(llvm::FoldingSetNodeID& ID) const;
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool isBoundable(ASTContext &) const { return false; }
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static bool classof(const MemRegion* R) {
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return R->getKind() == MemSpaceRegionKind;
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/// SubRegion - A region that subsets another larger region.  Most regions
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott///  are subclasses of SubRegion.
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass SubRegion : public MemRegion {
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottprotected:
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const MemRegion* superRegion;
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottpublic:
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const MemRegion* getSuperRegion() const {
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return superRegion;
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool isSubRegionOf(const MemRegion* R) const;
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
112  static bool classof(const MemRegion* R) {
113    return R->getKind() > MemSpaceRegionKind;
114  }
115};
116
117/// AllocaRegion - A region that represents an untyped blob of bytes created
118///  by a call to 'alloca'.
119class AllocaRegion : public SubRegion {
120  friend class MemRegionManager;
121protected:
122  unsigned Cnt; // Block counter.  Used to distinguish different pieces of
123                // memory allocated by alloca at the same call site.
124  const Expr* Ex;
125
126  AllocaRegion(const Expr* ex, unsigned cnt, const MemRegion* superRegion)
127    : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
128
129public:
130
131  const Expr* getExpr() const { return Ex; }
132
133  void Profile(llvm::FoldingSetNodeID& ID) const;
134
135  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex,
136                            unsigned Cnt);
137
138  void print(llvm::raw_ostream& os) const;
139
140  static bool classof(const MemRegion* R) {
141    return R->getKind() == AllocaRegionKind;
142  }
143};
144
145/// TypedRegion - An abstract class representing regions that are typed.
146class TypedRegion : public SubRegion {
147protected:
148  TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
149
150public:
151  virtual QualType getValueType(ASTContext &C) const = 0;
152
153  virtual QualType getLocationType(ASTContext& C) const {
154    // FIXME: We can possibly optimize this later to cache this value.
155    return C.getPointerType(getValueType(C));
156  }
157
158  QualType getDesugaredValueType(ASTContext& C) const {
159    QualType T = getValueType(C);
160    return T.getTypePtr() ? T->getDesugaredType() : T;
161  }
162
163  QualType getDesugaredLocationType(ASTContext& C) const {
164    return getLocationType(C)->getDesugaredType();
165  }
166
167  bool isBoundable(ASTContext &C) const {
168    return !getValueType(C).isNull();
169  }
170
171  static bool classof(const MemRegion* R) {
172    unsigned k = R->getKind();
173    return k > BEG_TYPED_REGIONS && k < END_TYPED_REGIONS;
174  }
175};
176
177/// CodeTextRegion - A region that represents code texts of a function. It wraps
178/// two kinds of code texts: real function and symbolic function. Real function
179/// is a function declared in the program. Symbolic function is a function
180/// pointer that we don't know which function it points to.
181class CodeTextRegion : public TypedRegion {
182public:
183  enum CodeKind { Declared, Symbolic };
184
185private:
186  // The function pointer kind that this CodeTextRegion represents.
187  CodeKind codekind;
188
189  // Data may be a SymbolRef or FunctionDecl*.
190  const void* Data;
191
192  // Cached function pointer type.
193  QualType LocationType;
194
195public:
196
197  CodeTextRegion(const FunctionDecl* fd, QualType t, const MemRegion* sreg)
198    : TypedRegion(sreg, CodeTextRegionKind),
199      codekind(Declared),
200      Data(fd),
201      LocationType(t) {}
202
203  CodeTextRegion(SymbolRef sym, QualType t, const MemRegion* sreg)
204    : TypedRegion(sreg, CodeTextRegionKind),
205      codekind(Symbolic),
206      Data(sym),
207      LocationType(t) {}
208
209  QualType getValueType(ASTContext &C) const {
210    // Do not get the object type of a CodeTextRegion.
211    assert(0);
212    return QualType();
213  }
214
215  QualType getLocationType(ASTContext &C) const {
216    return LocationType;
217  }
218
219  bool isDeclared() const { return codekind == Declared; }
220  bool isSymbolic() const { return codekind == Symbolic; }
221
222  const FunctionDecl* getDecl() const {
223    assert(codekind == Declared);
224    return static_cast<const FunctionDecl*>(Data);
225  }
226
227  SymbolRef getSymbol() const {
228    assert(codekind == Symbolic);
229    return const_cast<SymbolRef>(static_cast<const SymbolRef>(Data));
230  }
231
232  bool isBoundable(ASTContext&) const { return false; }
233
234  virtual void print(llvm::raw_ostream& os) const;
235
236  void Profile(llvm::FoldingSetNodeID& ID) const;
237
238  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
239                            const void* data, QualType t);
240
241  static bool classof(const MemRegion* R) {
242    return R->getKind() == CodeTextRegionKind;
243  }
244};
245
246/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
247///  clases, SymbolicRegion represents a region that serves as an alias for
248///  either a real region, a NULL pointer, etc.  It essentially is used to
249///  map the concept of symbolic values into the domain of regions.  Symbolic
250///  regions do not need to be typed.
251class SymbolicRegion : public SubRegion {
252protected:
253  const SymbolRef sym;
254
255public:
256  SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
257    : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
258
259  SymbolRef getSymbol() const {
260    return sym;
261  }
262
263  void Profile(llvm::FoldingSetNodeID& ID) const;
264
265  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
266                            SymbolRef sym,
267                            const MemRegion* superRegion);
268
269  void print(llvm::raw_ostream& os) const;
270
271  static bool classof(const MemRegion* R) {
272    return R->getKind() == SymbolicRegionKind;
273  }
274};
275
276/// StringRegion - Region associated with a StringLiteral.
277class StringRegion : public TypedRegion {
278  friend class MemRegionManager;
279  const StringLiteral* Str;
280protected:
281
282  StringRegion(const StringLiteral* str, const MemRegion* sreg)
283    : TypedRegion(sreg, StringRegionKind), Str(str) {}
284
285  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
286                            const StringLiteral* Str,
287                            const MemRegion* superRegion);
288
289public:
290
291  const StringLiteral* getStringLiteral() const { return Str; }
292
293  QualType getValueType(ASTContext& C) const {
294    return Str->getType();
295  }
296
297  void Profile(llvm::FoldingSetNodeID& ID) const {
298    ProfileRegion(ID, Str, superRegion);
299  }
300
301  void print(llvm::raw_ostream& os) const;
302
303  static bool classof(const MemRegion* R) {
304    return R->getKind() == StringRegionKind;
305  }
306};
307
308class TypedViewRegion : public TypedRegion {
309  friend class MemRegionManager;
310  QualType LValueType;
311
312  TypedViewRegion(QualType lvalueType, const MemRegion* sreg)
313    : TypedRegion(sreg, TypedViewRegionKind), LValueType(lvalueType) {}
314
315  static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
316                            const MemRegion* superRegion);
317
318public:
319
320  void print(llvm::raw_ostream& os) const;
321
322  QualType getLocationType(ASTContext&) const {
323    return LValueType;
324  }
325
326  QualType getValueType(ASTContext&) const {
327    const PointerType* PTy = LValueType->getAsPointerType();
328    assert(PTy);
329    return PTy->getPointeeType();
330  }
331
332  bool isBoundable(ASTContext &C) const {
333    return isa<PointerType>(LValueType);
334  }
335
336  void Profile(llvm::FoldingSetNodeID& ID) const {
337    ProfileRegion(ID, LValueType, superRegion);
338  }
339
340  static bool classof(const MemRegion* R) {
341    return R->getKind() == TypedViewRegionKind;
342  }
343
344  const MemRegion *removeViews() const;
345};
346
347
348/// CompoundLiteralRegion - A memory region representing a compound literal.
349///   Compound literals are essentially temporaries that are stack allocated
350///   or in the global constant pool.
351class CompoundLiteralRegion : public TypedRegion {
352private:
353  friend class MemRegionManager;
354  const CompoundLiteralExpr* CL;
355
356  CompoundLiteralRegion(const CompoundLiteralExpr* cl, const MemRegion* sReg)
357    : TypedRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
358
359  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
360                            const CompoundLiteralExpr* CL,
361                            const MemRegion* superRegion);
362public:
363  QualType getValueType(ASTContext& C) const {
364    return C.getCanonicalType(CL->getType());
365  }
366
367  void Profile(llvm::FoldingSetNodeID& ID) const;
368
369  void print(llvm::raw_ostream& os) const;
370
371  const CompoundLiteralExpr* getLiteralExpr() const { return CL; }
372
373  static bool classof(const MemRegion* R) {
374    return R->getKind() == CompoundLiteralRegionKind;
375  }
376};
377
378class DeclRegion : public TypedRegion {
379protected:
380  const Decl* D;
381
382  DeclRegion(const Decl* d, const MemRegion* sReg, Kind k)
383    : TypedRegion(sReg, k), D(d) {}
384
385  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
386                      const MemRegion* superRegion, Kind k);
387
388public:
389  const Decl* getDecl() const { return D; }
390  void Profile(llvm::FoldingSetNodeID& ID) const;
391
392  static bool classof(const MemRegion* R) {
393    unsigned k = R->getKind();
394    return k > BEG_DECL_REGIONS && k < END_DECL_REGIONS;
395  }
396};
397
398class VarRegion : public DeclRegion {
399  friend class MemRegionManager;
400
401  VarRegion(const VarDecl* vd, const MemRegion* sReg)
402    : DeclRegion(vd, sReg, VarRegionKind) {}
403
404  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD,
405                      const MemRegion* superRegion) {
406    DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
407  }
408
409public:
410  const VarDecl* getDecl() const { return cast<VarDecl>(D); }
411
412  QualType getValueType(ASTContext& C) const {
413    // FIXME: We can cache this if needed.
414    return C.getCanonicalType(getDecl()->getType());
415  }
416
417  void print(llvm::raw_ostream& os) const;
418
419  static bool classof(const MemRegion* R) {
420    return R->getKind() == VarRegionKind;
421  }
422};
423
424class FieldRegion : public DeclRegion {
425  friend class MemRegionManager;
426
427  FieldRegion(const FieldDecl* fd, const MemRegion* sReg)
428    : DeclRegion(fd, sReg, FieldRegionKind) {}
429
430public:
431
432  void print(llvm::raw_ostream& os) const;
433
434  const FieldDecl* getDecl() const { return cast<FieldDecl>(D); }
435
436  QualType getValueType(ASTContext& C) const {
437    // FIXME: We can cache this if needed.
438    return C.getCanonicalType(getDecl()->getType());
439  }
440
441  static void ProfileRegion(llvm::FoldingSetNodeID& ID, FieldDecl* FD,
442                      const MemRegion* superRegion) {
443    DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
444  }
445
446  static bool classof(const MemRegion* R) {
447    return R->getKind() == FieldRegionKind;
448  }
449};
450
451class ObjCObjectRegion : public DeclRegion {
452
453  friend class MemRegionManager;
454
455  ObjCObjectRegion(const ObjCInterfaceDecl* ivd, const MemRegion* sReg)
456  : DeclRegion(ivd, sReg, ObjCObjectRegionKind) {}
457
458  static void ProfileRegion(llvm::FoldingSetNodeID& ID, ObjCInterfaceDecl* ivd,
459                            const MemRegion* superRegion) {
460    DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCObjectRegionKind);
461  }
462
463public:
464  const ObjCInterfaceDecl* getInterface() const {
465    return cast<ObjCInterfaceDecl>(D);
466  }
467
468  QualType getValueType(ASTContext& C) const {
469    return C.getObjCInterfaceType(getInterface());
470  }
471
472  static bool classof(const MemRegion* R) {
473    return R->getKind() == ObjCObjectRegionKind;
474  }
475};
476
477class ObjCIvarRegion : public DeclRegion {
478
479  friend class MemRegionManager;
480
481  ObjCIvarRegion(const ObjCIvarDecl* ivd, const MemRegion* sReg)
482    : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
483
484  static void ProfileRegion(llvm::FoldingSetNodeID& ID, ObjCIvarDecl* ivd,
485                      const MemRegion* superRegion) {
486    DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
487  }
488
489public:
490  const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); }
491  QualType getValueType(ASTContext&) const { return getDecl()->getType(); }
492
493  static bool classof(const MemRegion* R) {
494    return R->getKind() == ObjCIvarRegionKind;
495  }
496};
497
498class ElementRegion : public TypedRegion {
499  friend class MemRegionManager;
500
501  QualType ElementType;
502  SVal Index;
503
504  ElementRegion(QualType elementType, SVal Idx, const MemRegion* sReg)
505    : TypedRegion(sReg, ElementRegionKind),
506      ElementType(elementType), Index(Idx) {
507    assert((!isa<nonloc::ConcreteInt>(&Idx) ||
508           cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
509           "The index must be signed");
510  }
511
512  static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
513                            SVal Idx, const MemRegion* superRegion);
514
515public:
516
517  SVal getIndex() const { return Index; }
518
519  QualType getValueType(ASTContext&) const {
520    return ElementType;
521  }
522
523  QualType getElementType() const {
524    return ElementType;
525  }
526
527  void print(llvm::raw_ostream& os) const;
528
529  void Profile(llvm::FoldingSetNodeID& ID) const;
530
531  static bool classof(const MemRegion* R) {
532    return R->getKind() == ElementRegionKind;
533  }
534};
535
536template<typename RegionTy>
537const RegionTy* MemRegion::getAs() const {
538  const MemRegion *R = this;
539
540  do {
541    if (const RegionTy* RT = dyn_cast<RegionTy>(R))
542      return RT;
543
544    if (const TypedViewRegion *TR = dyn_cast<TypedViewRegion>(R)) {
545      R = TR->getSuperRegion();
546      continue;
547    }
548
549    break;
550  }
551  while (R);
552
553  return 0;
554}
555
556//===----------------------------------------------------------------------===//
557// MemRegionManager - Factory object for creating regions.
558//===----------------------------------------------------------------------===//
559
560class MemRegionManager {
561  llvm::BumpPtrAllocator& A;
562  llvm::FoldingSet<MemRegion> Regions;
563
564  MemSpaceRegion* globals;
565  MemSpaceRegion* stack;
566  MemSpaceRegion* heap;
567  MemSpaceRegion* unknown;
568  MemSpaceRegion* code;
569
570public:
571  MemRegionManager(llvm::BumpPtrAllocator& a)
572    : A(a), globals(0), stack(0), heap(0), unknown(0), code(0) {}
573
574  ~MemRegionManager() {}
575
576  /// getStackRegion - Retrieve the memory region associated with the
577  ///  current stack frame.
578  MemSpaceRegion* getStackRegion();
579
580  /// getGlobalsRegion - Retrieve the memory region associated with
581  ///  all global variables.
582  MemSpaceRegion* getGlobalsRegion();
583
584  /// getHeapRegion - Retrieve the memory region associated with the
585  ///  generic "heap".
586  MemSpaceRegion* getHeapRegion();
587
588  /// getUnknownRegion - Retrieve the memory region associated with unknown
589  /// memory space.
590  MemSpaceRegion* getUnknownRegion();
591
592  MemSpaceRegion* getCodeRegion();
593
594  bool isGlobalsRegion(const MemRegion* R) {
595    assert(R);
596    return R == globals;
597  }
598
599  /// onStack - check if the region is allocated on the stack.
600  bool onStack(const MemRegion* R);
601
602  /// onHeap - check if the region is allocated on the heap, usually by malloc.
603  bool onHeap(const MemRegion* R);
604
605  bool hasStackStorage(const MemRegion* R);
606
607  /// getAllocaRegion - Retrieve a region associated with a call to alloca().
608  AllocaRegion* getAllocaRegion(const Expr* Ex, unsigned Cnt);
609
610  /// getCompoundLiteralRegion - Retrieve the region associated with a
611  ///  given CompoundLiteral.
612  CompoundLiteralRegion*
613  getCompoundLiteralRegion(const CompoundLiteralExpr* CL);
614
615  /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
616  SymbolicRegion* getSymbolicRegion(SymbolRef sym);
617
618  StringRegion* getStringRegion(const StringLiteral* Str);
619
620  /// getVarRegion - Retrieve or create the memory region associated with
621  ///  a specified VarDecl.
622  VarRegion* getVarRegion(const VarDecl* vd);
623
624  /// getElementRegion - Retrieve the memory region associated with the
625  ///  associated element type, index, and super region.
626  ElementRegion* getElementRegion(QualType elementType, SVal Idx,
627                                  const MemRegion* superRegion,ASTContext &Ctx);
628
629  /// getFieldRegion - Retrieve or create the memory region associated with
630  ///  a specified FieldDecl.  'superRegion' corresponds to the containing
631  ///  memory region (which typically represents the memory representing
632  ///  a structure or class).
633  FieldRegion* getFieldRegion(const FieldDecl* fd,
634                              const MemRegion* superRegion);
635
636  /// getObjCObjectRegion - Retrieve or create the memory region associated with
637  ///  the instance of a specified Objective-C class.
638  ObjCObjectRegion* getObjCObjectRegion(const ObjCInterfaceDecl* ID,
639                                  const MemRegion* superRegion);
640
641  /// getObjCIvarRegion - Retrieve or create the memory region associated with
642  ///   a specified Objective-c instance variable.  'superRegion' corresponds
643  ///   to the containing region (which typically represents the Objective-C
644  ///   object).
645  ObjCIvarRegion* getObjCIvarRegion(const ObjCIvarDecl* ivd,
646                                    const MemRegion* superRegion);
647
648  TypedViewRegion* getTypedViewRegion(QualType LValueType,
649                                      const MemRegion* superRegion);
650
651  CodeTextRegion* getCodeTextRegion(SymbolRef sym, QualType t);
652  CodeTextRegion* getCodeTextRegion(const FunctionDecl* fd, QualType t);
653
654  template <typename RegionTy, typename A1>
655  RegionTy* getRegion(const A1 a1);
656
657private:
658  MemSpaceRegion* LazyAllocate(MemSpaceRegion*& region);
659};
660
661//===----------------------------------------------------------------------===//
662// Out-of-line member template definitions.
663//===----------------------------------------------------------------------===//
664
665template<typename RegionTy> struct MemRegionManagerTrait;
666
667template <typename RegionTy, typename A1>
668RegionTy* MemRegionManager::getRegion(const A1 a1) {
669
670  const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
671    MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
672
673  llvm::FoldingSetNodeID ID;
674  RegionTy::ProfileRegion(ID, a1, superRegion);
675  void* InsertPos;
676  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
677                                                                   InsertPos));
678
679  if (!R) {
680    R = (RegionTy*) A.Allocate<RegionTy>();
681    new (R) RegionTy(a1, superRegion);
682    Regions.InsertNode(R, InsertPos);
683  }
684
685  return R;
686}
687
688//===----------------------------------------------------------------------===//
689// Traits for constructing regions.
690//===----------------------------------------------------------------------===//
691
692template <> struct MemRegionManagerTrait<CompoundLiteralRegion> {
693  typedef MemRegion SuperRegionTy;
694  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
695                                             const CompoundLiteralExpr *CL) {
696
697    return CL->isFileScope() ? MRMgr.getGlobalsRegion()
698                             : MRMgr.getStackRegion();
699  }
700};
701
702template <> struct MemRegionManagerTrait<StringRegion> {
703  typedef MemSpaceRegion SuperRegionTy;
704  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
705                                             const StringLiteral*) {
706    return MRMgr.getGlobalsRegion();
707  }
708};
709
710template <> struct MemRegionManagerTrait<VarRegion> {
711  typedef MemRegion SuperRegionTy;
712  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
713                                             const VarDecl *d) {
714    return d->hasLocalStorage() ? MRMgr.getStackRegion()
715                                : MRMgr.getGlobalsRegion();
716  }
717};
718
719template <> struct MemRegionManagerTrait<SymbolicRegion> {
720  typedef MemRegion SuperRegionTy;
721  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
722                                             SymbolRef) {
723    return MRMgr.getUnknownRegion();
724  }
725};
726
727
728} // end clang namespace
729
730//===----------------------------------------------------------------------===//
731// Pretty-printing regions.
732//===----------------------------------------------------------------------===//
733
734namespace llvm {
735static inline raw_ostream& operator<<(raw_ostream& O,
736                                      const clang::MemRegion* R) {
737  R->print(O);
738  return O;
739}
740} // end llvm namespace
741
742#endif
743