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_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 
     32 namespace clang {
     33 
     34 class LocationContext;
     35 class StackFrameContext;
     36 
     37 namespace ento {
     38 
     39 class CodeTextRegion;
     40 class MemRegionManager;
     41 class MemSpaceRegion;
     42 class SValBuilder;
     43 class SymbolicRegion;
     44 class VarRegion;
     45 
     46 /// Represent a region's offset within the top level base region.
     47 class 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 
     54 public:
     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.
     79 class MemRegion : public llvm::FoldingSetNode {
     80 public:
     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 
     87 private:
     88   const Kind kind;
     89 
     90 protected:
     91   MemRegion(Kind k) : kind(k) {}
     92   virtual ~MemRegion();
     93 
     94 public:
     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.
    179 class MemSpaceRegion : public MemRegion {
    180 protected:
    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 
    189 public:
    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.
    202 class CodeSpaceRegion : public MemSpaceRegion {
    203   friend class MemRegionManager;
    204 
    205   CodeSpaceRegion(MemRegionManager *mgr)
    206       : MemSpaceRegion(mgr, CodeSpaceRegionKind) {}
    207 
    208 public:
    209   void dumpToStream(raw_ostream &os) const override;
    210 
    211   static bool classof(const MemRegion *R) {
    212     return R->getKind() == CodeSpaceRegionKind;
    213   }
    214 };
    215 
    216 class GlobalsSpaceRegion : public MemSpaceRegion {
    217   virtual void anchor();
    218 protected:
    219   GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
    220     : MemSpaceRegion(mgr, k) {}
    221 public:
    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.
    233 class 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 
    241 public:
    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).
    259 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
    260 protected:
    261   NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
    262     : GlobalsSpaceRegion(mgr, k) {}
    263 
    264 public:
    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).
    275 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
    276   friend class MemRegionManager;
    277 
    278   GlobalSystemSpaceRegion(MemRegionManager *mgr)
    279     : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
    280 
    281 public:
    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.
    295 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
    296   friend class MemRegionManager;
    297 
    298   GlobalImmutableSpaceRegion(MemRegionManager *mgr)
    299     : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
    300 
    301 public:
    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.
    313 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
    314   friend class MemRegionManager;
    315 
    316   GlobalInternalSpaceRegion(MemRegionManager *mgr)
    317     : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
    318 
    319 public:
    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 
    328 class HeapSpaceRegion : public MemSpaceRegion {
    329   virtual void anchor();
    330   friend class MemRegionManager;
    331 
    332   HeapSpaceRegion(MemRegionManager *mgr)
    333     : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
    334 public:
    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 
    343 class UnknownSpaceRegion : public MemSpaceRegion {
    344   virtual void anchor();
    345   friend class MemRegionManager;
    346   UnknownSpaceRegion(MemRegionManager *mgr)
    347     : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
    348 public:
    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 
    357 class StackSpaceRegion : public MemSpaceRegion {
    358 private:
    359   const StackFrameContext *SFC;
    360 
    361 protected:
    362   StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
    363     : MemSpaceRegion(mgr, k), SFC(sfc) {
    364     assert(classof(this));
    365   }
    366 
    367 public:
    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 
    378 class StackLocalsSpaceRegion : public StackSpaceRegion {
    379   virtual void anchor();
    380   friend class MemRegionManager;
    381   StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
    382     : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
    383 public:
    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 
    392 class StackArgumentsSpaceRegion : public StackSpaceRegion {
    393 private:
    394   virtual void anchor();
    395   friend class MemRegionManager;
    396   StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
    397     : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
    398 public:
    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.
    410 class SubRegion : public MemRegion {
    411 private:
    412   virtual void anchor();
    413 protected:
    414   const MemRegion* superRegion;
    415   SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
    416 public:
    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'.
    441 class AllocaRegion : public SubRegion {
    442   friend class MemRegionManager;
    443 protected:
    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 
    451 public:
    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.
    472 class TypedRegion : public SubRegion {
    473 public:
    474   void anchor() override;
    475 protected:
    476   TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
    477 
    478 public:
    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.
    494 class TypedValueRegion : public TypedRegion {
    495 public:
    496   void anchor() override;
    497 protected:
    498   TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
    499 
    500 public:
    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 
    526 class CodeTextRegion : public TypedRegion {
    527 public:
    528   void anchor() override;
    529 protected:
    530   CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
    531 public:
    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.
    541 class FunctionCodeRegion : public CodeTextRegion {
    542   const NamedDecl *FD;
    543 public:
    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.
    586 class 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 
    597 public:
    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.
    627 class 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 
    641 public:
    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   }
    696 private:
    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.
    707 class SymbolicRegion : public SubRegion {
    708 protected:
    709   const SymbolRef sym;
    710 
    711 public:
    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.
    737 class StringRegion : public TypedValueRegion {
    738   friend class MemRegionManager;
    739   const StringLiteral* Str;
    740 protected:
    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 
    749 public:
    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.
    773 class ObjCStringRegion : public TypedValueRegion {
    774   friend class MemRegionManager;
    775   const ObjCStringLiteral* Str;
    776 protected:
    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 
    785 public:
    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.
    809 class CompoundLiteralRegion : public TypedValueRegion {
    810 private:
    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);
    820 public:
    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 
    838 class DeclRegion : public TypedValueRegion {
    839 protected:
    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 
    848 public:
    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 
    858 class 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 
    872 public:
    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.
    896 class 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 
    908 public:
    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 
    919 private:
    920   const PointerType *ThisPointerTy;
    921 };
    922 
    923 class FieldRegion : public DeclRegion {
    924   friend class MemRegionManager;
    925 
    926   FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
    927     : DeclRegion(fd, sReg, FieldRegionKind) {}
    928 
    929 public:
    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 
    956 class 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 
    965 public:
    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 
    982 class ElementRegion;
    983 
    984 class RegionRawOffset {
    985 private:
    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 
    994 public:
    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.
   1004 class 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 
   1021 public:
   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.
   1045 class 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 
   1056 public:
   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.
   1074 class 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 
   1086 public:
   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 
   1105 template<typename RegionTy>
   1106 const 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 
   1117 class 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 
   1138 public:
   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 
   1278 private:
   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 
   1307 inline 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.
   1316 class 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 
   1326 public:
   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 
   1357 namespace llvm {
   1358 static 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