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