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