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