Home | History | Annotate | Download | only in PathSensitive
      1 //== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file defines MemRegion and its subclasses.  MemRegion defines a
     11 //  partially-typed abstraction of memory useful for path-sensitive dataflow
     12 //  analyses.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #ifndef LLVM_CLANG_GR_MEMREGION_H
     17 #define LLVM_CLANG_GR_MEMREGION_H
     18 
     19 #include "clang/AST/CharUnits.h"
     20 #include "clang/AST/Decl.h"
     21 #include "clang/AST/DeclObjC.h"
     22 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
     23 #include "llvm/Support/Casting.h"
     24 #include "llvm/Support/ErrorHandling.h"
     25 #include "llvm/ADT/FoldingSet.h"
     26 #include <string>
     27 
     28 namespace llvm {
     29 class BumpPtrAllocator;
     30 class raw_ostream;
     31 }
     32 
     33 namespace clang {
     34 
     35 class LocationContext;
     36 class StackFrameContext;
     37 
     38 namespace ento {
     39 
     40 class MemRegionManager;
     41 class MemSpaceRegion;
     42 class SValBuilder;
     43 class VarRegion;
     44 class CodeTextRegion;
     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. It shouldn't be negative.
     52   int64_t Offset;
     53 
     54 public:
     55   RegionOffset(const MemRegion *r) : R(r), Offset(0) {}
     56   RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
     57 
     58   const MemRegion *getRegion() const { return R; }
     59   int64_t getOffset() const { return Offset; }
     60 };
     61 
     62 //===----------------------------------------------------------------------===//
     63 // Base region classes.
     64 //===----------------------------------------------------------------------===//
     65 
     66 /// MemRegion - The root abstract class for all memory regions.
     67 class MemRegion : public llvm::FoldingSetNode {
     68   friend class MemRegionManager;
     69 public:
     70   enum Kind {
     71     // Memory spaces.
     72     GenericMemSpaceRegionKind,
     73     StackLocalsSpaceRegionKind,
     74     StackArgumentsSpaceRegionKind,
     75     HeapSpaceRegionKind,
     76     UnknownSpaceRegionKind,
     77     NonStaticGlobalSpaceRegionKind,
     78     StaticGlobalSpaceRegionKind,
     79     BEG_GLOBAL_MEMSPACES = NonStaticGlobalSpaceRegionKind,
     80     END_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind,
     81     BEG_MEMSPACES = GenericMemSpaceRegionKind,
     82     END_MEMSPACES = StaticGlobalSpaceRegionKind,
     83     // Untyped regions.
     84     SymbolicRegionKind,
     85     AllocaRegionKind,
     86     // Typed regions.
     87     BEG_TYPED_REGIONS,
     88     FunctionTextRegionKind = BEG_TYPED_REGIONS,
     89     BlockTextRegionKind,
     90     BlockDataRegionKind,
     91     CompoundLiteralRegionKind,
     92     CXXThisRegionKind,
     93     StringRegionKind,
     94     ElementRegionKind,
     95     // Decl Regions.
     96     BEG_DECL_REGIONS,
     97     VarRegionKind = BEG_DECL_REGIONS,
     98     FieldRegionKind,
     99     ObjCIvarRegionKind,
    100     END_DECL_REGIONS = ObjCIvarRegionKind,
    101     CXXTempObjectRegionKind,
    102     CXXBaseObjectRegionKind,
    103     END_TYPED_REGIONS = CXXBaseObjectRegionKind
    104   };
    105 
    106 private:
    107   const Kind kind;
    108 
    109 protected:
    110   MemRegion(Kind k) : kind(k) {}
    111   virtual ~MemRegion();
    112 
    113 public:
    114   ASTContext &getContext() const;
    115 
    116   virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
    117 
    118   virtual MemRegionManager* getMemRegionManager() const = 0;
    119 
    120   std::string getString() const;
    121 
    122   const MemSpaceRegion *getMemorySpace() const;
    123 
    124   const MemRegion *getBaseRegion() const;
    125 
    126   const MemRegion *StripCasts() const;
    127 
    128   bool hasGlobalsOrParametersStorage() const;
    129 
    130   bool hasStackStorage() const;
    131 
    132   bool hasStackNonParametersStorage() const;
    133 
    134   bool hasStackParametersStorage() const;
    135 
    136   /// Compute the offset within the top level memory object.
    137   RegionOffset getAsOffset() const;
    138 
    139   virtual void dumpToStream(llvm::raw_ostream& os) const;
    140 
    141   void dump() const;
    142 
    143   Kind getKind() const { return kind; }
    144 
    145   template<typename RegionTy> const RegionTy* getAs() const;
    146 
    147   virtual bool isBoundable() const { return false; }
    148 
    149   static bool classof(const MemRegion*) { return true; }
    150 };
    151 
    152 /// MemSpaceRegion - A memory region that represents and "memory space";
    153 ///  for example, the set of global variables, the stack frame, etc.
    154 class MemSpaceRegion : public MemRegion {
    155 protected:
    156   friend class MemRegionManager;
    157 
    158   MemRegionManager *Mgr;
    159 
    160   MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
    161     : MemRegion(k), Mgr(mgr) {
    162     assert(classof(this));
    163   }
    164 
    165   MemRegionManager* getMemRegionManager() const { return Mgr; }
    166 
    167 public:
    168   bool isBoundable() const { return false; }
    169 
    170   void Profile(llvm::FoldingSetNodeID &ID) const;
    171 
    172   static bool classof(const MemRegion *R) {
    173     Kind k = R->getKind();
    174     return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
    175   }
    176 };
    177 
    178 class GlobalsSpaceRegion : public MemSpaceRegion {
    179 protected:
    180   GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
    181     : MemSpaceRegion(mgr, k) {}
    182 public:
    183   static bool classof(const MemRegion *R) {
    184     Kind k = R->getKind();
    185     return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
    186   }
    187 };
    188 
    189 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
    190   friend class MemRegionManager;
    191 
    192   const CodeTextRegion *CR;
    193 
    194   StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
    195     : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
    196 
    197 public:
    198   void Profile(llvm::FoldingSetNodeID &ID) const;
    199 
    200   void dumpToStream(llvm::raw_ostream& os) const;
    201 
    202   const CodeTextRegion *getCodeRegion() const { return CR; }
    203 
    204   static bool classof(const MemRegion *R) {
    205     return R->getKind() == StaticGlobalSpaceRegionKind;
    206   }
    207 };
    208 
    209 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
    210   friend class MemRegionManager;
    211 
    212   NonStaticGlobalSpaceRegion(MemRegionManager *mgr)
    213     : GlobalsSpaceRegion(mgr, NonStaticGlobalSpaceRegionKind) {}
    214 
    215 public:
    216 
    217   void dumpToStream(llvm::raw_ostream& os) const;
    218 
    219   static bool classof(const MemRegion *R) {
    220     return R->getKind() == NonStaticGlobalSpaceRegionKind;
    221   }
    222 };
    223 
    224 class HeapSpaceRegion : public MemSpaceRegion {
    225   friend class MemRegionManager;
    226 
    227   HeapSpaceRegion(MemRegionManager *mgr)
    228     : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
    229 public:
    230   static bool classof(const MemRegion *R) {
    231     return R->getKind() == HeapSpaceRegionKind;
    232   }
    233 };
    234 
    235 class UnknownSpaceRegion : public MemSpaceRegion {
    236   friend class MemRegionManager;
    237   UnknownSpaceRegion(MemRegionManager *mgr)
    238     : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
    239 public:
    240   static bool classof(const MemRegion *R) {
    241     return R->getKind() == UnknownSpaceRegionKind;
    242   }
    243 };
    244 
    245 class StackSpaceRegion : public MemSpaceRegion {
    246 private:
    247   const StackFrameContext *SFC;
    248 
    249 protected:
    250   StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
    251     : MemSpaceRegion(mgr, k), SFC(sfc) {
    252     assert(classof(this));
    253   }
    254 
    255 public:
    256   const StackFrameContext *getStackFrame() const { return SFC; }
    257 
    258   void Profile(llvm::FoldingSetNodeID &ID) const;
    259 
    260   static bool classof(const MemRegion *R) {
    261     Kind k = R->getKind();
    262     return k >= StackLocalsSpaceRegionKind &&
    263            k <= StackArgumentsSpaceRegionKind;
    264   }
    265 };
    266 
    267 class StackLocalsSpaceRegion : public StackSpaceRegion {
    268 private:
    269   friend class MemRegionManager;
    270   StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
    271     : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
    272 public:
    273   static bool classof(const MemRegion *R) {
    274     return R->getKind() == StackLocalsSpaceRegionKind;
    275   }
    276 };
    277 
    278 class StackArgumentsSpaceRegion : public StackSpaceRegion {
    279 private:
    280   friend class MemRegionManager;
    281   StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
    282     : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
    283 public:
    284   static bool classof(const MemRegion *R) {
    285     return R->getKind() == StackArgumentsSpaceRegionKind;
    286   }
    287 };
    288 
    289 
    290 /// SubRegion - A region that subsets another larger region.  Most regions
    291 ///  are subclasses of SubRegion.
    292 class SubRegion : public MemRegion {
    293 protected:
    294   const MemRegion* superRegion;
    295   SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
    296 public:
    297   const MemRegion* getSuperRegion() const {
    298     return superRegion;
    299   }
    300 
    301   /// getExtent - Returns the size of the region in bytes.
    302   virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
    303     return UnknownVal();
    304   }
    305 
    306   MemRegionManager* getMemRegionManager() const;
    307 
    308   bool isSubRegionOf(const MemRegion* R) const;
    309 
    310   static bool classof(const MemRegion* R) {
    311     return R->getKind() > END_MEMSPACES;
    312   }
    313 };
    314 
    315 //===----------------------------------------------------------------------===//
    316 // MemRegion subclasses.
    317 //===----------------------------------------------------------------------===//
    318 
    319 /// AllocaRegion - A region that represents an untyped blob of bytes created
    320 ///  by a call to 'alloca'.
    321 class AllocaRegion : public SubRegion {
    322   friend class MemRegionManager;
    323 protected:
    324   unsigned Cnt; // Block counter.  Used to distinguish different pieces of
    325                 // memory allocated by alloca at the same call site.
    326   const Expr* Ex;
    327 
    328   AllocaRegion(const Expr* ex, unsigned cnt, const MemRegion *superRegion)
    329     : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
    330 
    331 public:
    332 
    333   const Expr* getExpr() const { return Ex; }
    334 
    335   bool isBoundable() const { return true; }
    336 
    337   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
    338 
    339   void Profile(llvm::FoldingSetNodeID& ID) const;
    340 
    341   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex,
    342                             unsigned Cnt, const MemRegion *superRegion);
    343 
    344   void dumpToStream(llvm::raw_ostream& os) const;
    345 
    346   static bool classof(const MemRegion* R) {
    347     return R->getKind() == AllocaRegionKind;
    348   }
    349 };
    350 
    351 /// TypedRegion - An abstract class representing regions that are typed.
    352 class TypedRegion : public SubRegion {
    353 protected:
    354   TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
    355 
    356 public:
    357   virtual QualType getValueType() const = 0;
    358 
    359   virtual QualType getLocationType() const {
    360     // FIXME: We can possibly optimize this later to cache this value.
    361     QualType T = getValueType();
    362     ASTContext &ctx = getContext();
    363     if (T->getAs<ObjCObjectType>())
    364       return ctx.getObjCObjectPointerType(T);
    365     return ctx.getPointerType(getValueType());
    366   }
    367 
    368   QualType getDesugaredValueType(ASTContext &Context) const {
    369     QualType T = getValueType();
    370     return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
    371   }
    372 
    373   QualType getDesugaredLocationType(ASTContext &Context) const {
    374     return getLocationType().getDesugaredType(Context);
    375   }
    376 
    377   bool isBoundable() const { return true; }
    378 
    379   static bool classof(const MemRegion* R) {
    380     unsigned k = R->getKind();
    381     return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
    382   }
    383 };
    384 
    385 
    386 class CodeTextRegion : public TypedRegion {
    387 protected:
    388   CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
    389 public:
    390   QualType getValueType() const {
    391     assert(0 && "Do not get the object type of a CodeTextRegion.");
    392     return QualType();
    393   }
    394 
    395   bool isBoundable() const { return false; }
    396 
    397   static bool classof(const MemRegion* R) {
    398     Kind k = R->getKind();
    399     return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
    400   }
    401 };
    402 
    403 /// FunctionTextRegion - A region that represents code texts of function.
    404 class FunctionTextRegion : public CodeTextRegion {
    405   const FunctionDecl *FD;
    406 public:
    407   FunctionTextRegion(const FunctionDecl* fd, const MemRegion* sreg)
    408     : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {}
    409 
    410   QualType getLocationType() const {
    411     return getContext().getPointerType(FD->getType());
    412   }
    413 
    414   const FunctionDecl *getDecl() const {
    415     return FD;
    416   }
    417 
    418   virtual void dumpToStream(llvm::raw_ostream& os) const;
    419 
    420   void Profile(llvm::FoldingSetNodeID& ID) const;
    421 
    422   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD,
    423                             const MemRegion*);
    424 
    425   static bool classof(const MemRegion* R) {
    426     return R->getKind() == FunctionTextRegionKind;
    427   }
    428 };
    429 
    430 
    431 /// BlockTextRegion - A region that represents code texts of blocks (closures).
    432 ///  Blocks are represented with two kinds of regions.  BlockTextRegions
    433 ///  represent the "code", while BlockDataRegions represent instances of blocks,
    434 ///  which correspond to "code+data".  The distinction is important, because
    435 ///  like a closure a block captures the values of externally referenced
    436 ///  variables.
    437 class BlockTextRegion : public CodeTextRegion {
    438   friend class MemRegionManager;
    439 
    440   const BlockDecl *BD;
    441   AnalysisContext *AC;
    442   CanQualType locTy;
    443 
    444   BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
    445                   AnalysisContext *ac, const MemRegion* sreg)
    446     : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
    447 
    448 public:
    449   QualType getLocationType() const {
    450     return locTy;
    451   }
    452 
    453   const BlockDecl *getDecl() const {
    454     return BD;
    455   }
    456 
    457   AnalysisContext *getAnalysisContext() const { return AC; }
    458 
    459   virtual void dumpToStream(llvm::raw_ostream& os) const;
    460 
    461   void Profile(llvm::FoldingSetNodeID& ID) const;
    462 
    463   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
    464                             CanQualType, const AnalysisContext*,
    465                             const MemRegion*);
    466 
    467   static bool classof(const MemRegion* R) {
    468     return R->getKind() == BlockTextRegionKind;
    469   }
    470 };
    471 
    472 /// BlockDataRegion - A region that represents a block instance.
    473 ///  Blocks are represented with two kinds of regions.  BlockTextRegions
    474 ///  represent the "code", while BlockDataRegions represent instances of blocks,
    475 ///  which correspond to "code+data".  The distinction is important, because
    476 ///  like a closure a block captures the values of externally referenced
    477 ///  variables.
    478 class BlockDataRegion : public SubRegion {
    479   friend class MemRegionManager;
    480   const BlockTextRegion *BC;
    481   const LocationContext *LC; // Can be null */
    482   void *ReferencedVars;
    483 
    484   BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
    485                   const MemRegion *sreg)
    486   : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {}
    487 
    488 public:
    489   const BlockTextRegion *getCodeRegion() const { return BC; }
    490 
    491   const BlockDecl *getDecl() const { return BC->getDecl(); }
    492 
    493   class referenced_vars_iterator {
    494     const MemRegion * const *R;
    495   public:
    496     explicit referenced_vars_iterator(const MemRegion * const *r) : R(r) {}
    497 
    498     operator const MemRegion * const *() const {
    499       return R;
    500     }
    501 
    502     const VarRegion* operator*() const {
    503       return cast<VarRegion>(*R);
    504     }
    505 
    506     bool operator==(const referenced_vars_iterator &I) const {
    507       return I.R == R;
    508     }
    509     bool operator!=(const referenced_vars_iterator &I) const {
    510       return I.R != R;
    511     }
    512     referenced_vars_iterator& operator++() {
    513       ++R;
    514       return *this;
    515     }
    516   };
    517 
    518   referenced_vars_iterator referenced_vars_begin() const;
    519   referenced_vars_iterator referenced_vars_end() const;
    520 
    521   virtual void dumpToStream(llvm::raw_ostream& os) const;
    522 
    523   void Profile(llvm::FoldingSetNodeID& ID) const;
    524 
    525   static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
    526                             const LocationContext *, const MemRegion *);
    527 
    528   static bool classof(const MemRegion* R) {
    529     return R->getKind() == BlockDataRegionKind;
    530   }
    531 private:
    532   void LazyInitializeReferencedVars();
    533 };
    534 
    535 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region
    536 ///  clases, SymbolicRegion represents a region that serves as an alias for
    537 ///  either a real region, a NULL pointer, etc.  It essentially is used to
    538 ///  map the concept of symbolic values into the domain of regions.  Symbolic
    539 ///  regions do not need to be typed.
    540 class SymbolicRegion : public SubRegion {
    541 protected:
    542   const SymbolRef sym;
    543 
    544 public:
    545   SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
    546     : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
    547 
    548   SymbolRef getSymbol() const {
    549     return sym;
    550   }
    551 
    552   bool isBoundable() const { return true; }
    553 
    554   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
    555 
    556   void Profile(llvm::FoldingSetNodeID& ID) const;
    557 
    558   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
    559                             SymbolRef sym,
    560                             const MemRegion* superRegion);
    561 
    562   void dumpToStream(llvm::raw_ostream& os) const;
    563 
    564   static bool classof(const MemRegion* R) {
    565     return R->getKind() == SymbolicRegionKind;
    566   }
    567 };
    568 
    569 /// StringRegion - Region associated with a StringLiteral.
    570 class StringRegion : public TypedRegion {
    571   friend class MemRegionManager;
    572   const StringLiteral* Str;
    573 protected:
    574 
    575   StringRegion(const StringLiteral* str, const MemRegion* sreg)
    576     : TypedRegion(sreg, StringRegionKind), Str(str) {}
    577 
    578   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
    579                             const StringLiteral* Str,
    580                             const MemRegion* superRegion);
    581 
    582 public:
    583 
    584   const StringLiteral* getStringLiteral() const { return Str; }
    585 
    586   QualType getValueType() const {
    587     return Str->getType();
    588   }
    589 
    590   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
    591 
    592   bool isBoundable() const { return false; }
    593 
    594   void Profile(llvm::FoldingSetNodeID& ID) const {
    595     ProfileRegion(ID, Str, superRegion);
    596   }
    597 
    598   void dumpToStream(llvm::raw_ostream& os) const;
    599 
    600   static bool classof(const MemRegion* R) {
    601     return R->getKind() == StringRegionKind;
    602   }
    603 };
    604 
    605 /// CompoundLiteralRegion - A memory region representing a compound literal.
    606 ///   Compound literals are essentially temporaries that are stack allocated
    607 ///   or in the global constant pool.
    608 class CompoundLiteralRegion : public TypedRegion {
    609 private:
    610   friend class MemRegionManager;
    611   const CompoundLiteralExpr* CL;
    612 
    613   CompoundLiteralRegion(const CompoundLiteralExpr* cl, const MemRegion* sReg)
    614     : TypedRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
    615 
    616   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
    617                             const CompoundLiteralExpr* CL,
    618                             const MemRegion* superRegion);
    619 public:
    620   QualType getValueType() const {
    621     return CL->getType();
    622   }
    623 
    624   bool isBoundable() const { return !CL->isFileScope(); }
    625 
    626   void Profile(llvm::FoldingSetNodeID& ID) const;
    627 
    628   void dumpToStream(llvm::raw_ostream& os) const;
    629 
    630   const CompoundLiteralExpr* getLiteralExpr() const { return CL; }
    631 
    632   static bool classof(const MemRegion* R) {
    633     return R->getKind() == CompoundLiteralRegionKind;
    634   }
    635 };
    636 
    637 class DeclRegion : public TypedRegion {
    638 protected:
    639   const Decl* D;
    640 
    641   DeclRegion(const Decl* d, const MemRegion* sReg, Kind k)
    642     : TypedRegion(sReg, k), D(d) {}
    643 
    644   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
    645                       const MemRegion* superRegion, Kind k);
    646 
    647 public:
    648   const Decl* getDecl() const { return D; }
    649   void Profile(llvm::FoldingSetNodeID& ID) const;
    650 
    651   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
    652 
    653   static bool classof(const MemRegion* R) {
    654     unsigned k = R->getKind();
    655     return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
    656   }
    657 };
    658 
    659 class VarRegion : public DeclRegion {
    660   friend class MemRegionManager;
    661 
    662   // Constructors and private methods.
    663   VarRegion(const VarDecl* vd, const MemRegion* sReg)
    664     : DeclRegion(vd, sReg, VarRegionKind) {}
    665 
    666   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD,
    667                             const MemRegion *superRegion) {
    668     DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
    669   }
    670 
    671   void Profile(llvm::FoldingSetNodeID& ID) const;
    672 
    673 public:
    674   const VarDecl *getDecl() const { return cast<VarDecl>(D); }
    675 
    676   const StackFrameContext *getStackFrame() const;
    677 
    678   QualType getValueType() const {
    679     // FIXME: We can cache this if needed.
    680     return getDecl()->getType();
    681   }
    682 
    683   void dumpToStream(llvm::raw_ostream& os) const;
    684 
    685   static bool classof(const MemRegion* R) {
    686     return R->getKind() == VarRegionKind;
    687   }
    688 };
    689 
    690 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
    691 ///  in a call to a C++ method.  This region doesn't represent the object
    692 ///  referred to by 'this', but rather 'this' itself.
    693 class CXXThisRegion : public TypedRegion {
    694   friend class MemRegionManager;
    695   CXXThisRegion(const PointerType *thisPointerTy,
    696                 const MemRegion *sReg)
    697     : TypedRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
    698 
    699   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
    700                             const PointerType *PT,
    701                             const MemRegion *sReg);
    702 
    703   void Profile(llvm::FoldingSetNodeID &ID) const;
    704 
    705 public:
    706   QualType getValueType() const {
    707     return QualType(ThisPointerTy, 0);
    708   }
    709 
    710   void dumpToStream(llvm::raw_ostream& os) const;
    711 
    712   static bool classof(const MemRegion* R) {
    713     return R->getKind() == CXXThisRegionKind;
    714   }
    715 
    716 private:
    717   const PointerType *ThisPointerTy;
    718 };
    719 
    720 class FieldRegion : public DeclRegion {
    721   friend class MemRegionManager;
    722 
    723   FieldRegion(const FieldDecl* fd, const MemRegion* sReg)
    724     : DeclRegion(fd, sReg, FieldRegionKind) {}
    725 
    726 public:
    727 
    728   void dumpToStream(llvm::raw_ostream& os) const;
    729 
    730   const FieldDecl* getDecl() const { return cast<FieldDecl>(D); }
    731 
    732   QualType getValueType() const {
    733     // FIXME: We can cache this if needed.
    734     return getDecl()->getType();
    735   }
    736 
    737   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
    738 
    739   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl* FD,
    740                             const MemRegion* superRegion) {
    741     DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
    742   }
    743 
    744   static bool classof(const MemRegion* R) {
    745     return R->getKind() == FieldRegionKind;
    746   }
    747 };
    748 
    749 class ObjCIvarRegion : public DeclRegion {
    750 
    751   friend class MemRegionManager;
    752 
    753   ObjCIvarRegion(const ObjCIvarDecl* ivd, const MemRegion* sReg)
    754     : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
    755 
    756   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl* ivd,
    757                             const MemRegion* superRegion) {
    758     DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
    759   }
    760 
    761 public:
    762   const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); }
    763   QualType getValueType() const { return getDecl()->getType(); }
    764 
    765   void dumpToStream(llvm::raw_ostream& os) const;
    766 
    767   static bool classof(const MemRegion* R) {
    768     return R->getKind() == ObjCIvarRegionKind;
    769   }
    770 };
    771 //===----------------------------------------------------------------------===//
    772 // Auxiliary data classes for use with MemRegions.
    773 //===----------------------------------------------------------------------===//
    774 
    775 class ElementRegion;
    776 
    777 class RegionRawOffset {
    778 private:
    779   friend class ElementRegion;
    780 
    781   const MemRegion *Region;
    782   CharUnits Offset;
    783 
    784   RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
    785     : Region(reg), Offset(offset) {}
    786 
    787 public:
    788   // FIXME: Eventually support symbolic offsets.
    789   CharUnits getOffset() const { return Offset; }
    790   const MemRegion *getRegion() const { return Region; }
    791 
    792   void dumpToStream(llvm::raw_ostream& os) const;
    793   void dump() const;
    794 };
    795 
    796 class ElementRegion : public TypedRegion {
    797   friend class MemRegionManager;
    798 
    799   QualType ElementType;
    800   NonLoc Index;
    801 
    802   ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
    803     : TypedRegion(sReg, ElementRegionKind),
    804       ElementType(elementType), Index(Idx) {
    805     assert((!isa<nonloc::ConcreteInt>(&Idx) ||
    806            cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
    807            "The index must be signed");
    808   }
    809 
    810   static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
    811                             SVal Idx, const MemRegion* superRegion);
    812 
    813 public:
    814 
    815   NonLoc getIndex() const { return Index; }
    816 
    817   QualType getValueType() const {
    818     return ElementType;
    819   }
    820 
    821   QualType getElementType() const {
    822     return ElementType;
    823   }
    824   /// Compute the offset within the array. The array might also be a subobject.
    825   RegionRawOffset getAsArrayOffset() const;
    826 
    827   void dumpToStream(llvm::raw_ostream& os) const;
    828 
    829   void Profile(llvm::FoldingSetNodeID& ID) const;
    830 
    831   static bool classof(const MemRegion* R) {
    832     return R->getKind() == ElementRegionKind;
    833   }
    834 };
    835 
    836 // C++ temporary object associated with an expression.
    837 class CXXTempObjectRegion : public TypedRegion {
    838   friend class MemRegionManager;
    839 
    840   Expr const *Ex;
    841 
    842   CXXTempObjectRegion(Expr const *E, MemRegion const *sReg)
    843     : TypedRegion(sReg, CXXTempObjectRegionKind), Ex(E) {}
    844 
    845   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
    846                             Expr const *E, const MemRegion *sReg);
    847 
    848 public:
    849   QualType getValueType() const {
    850     return Ex->getType();
    851   }
    852 
    853   void dumpToStream(llvm::raw_ostream& os) const;
    854 
    855   void Profile(llvm::FoldingSetNodeID &ID) const;
    856 
    857   static bool classof(const MemRegion* R) {
    858     return R->getKind() == CXXTempObjectRegionKind;
    859   }
    860 };
    861 
    862 // CXXBaseObjectRegion represents a base object within a C++ object. It is
    863 // identified by the base class declaration and the region of its parent object.
    864 class CXXBaseObjectRegion : public TypedRegion {
    865   friend class MemRegionManager;
    866 
    867   const CXXRecordDecl *decl;
    868 
    869   CXXBaseObjectRegion(const CXXRecordDecl *d, const MemRegion *sReg)
    870     : TypedRegion(sReg, CXXBaseObjectRegionKind), decl(d) {}
    871 
    872   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
    873                             const CXXRecordDecl *decl, const MemRegion *sReg);
    874 
    875 public:
    876   const CXXRecordDecl *getDecl() const { return decl; }
    877 
    878   QualType getValueType() const;
    879 
    880   void dumpToStream(llvm::raw_ostream& os) const;
    881 
    882   void Profile(llvm::FoldingSetNodeID &ID) const;
    883 
    884   static bool classof(const MemRegion *region) {
    885     return region->getKind() == CXXBaseObjectRegionKind;
    886   }
    887 };
    888 
    889 template<typename RegionTy>
    890 const RegionTy* MemRegion::getAs() const {
    891   if (const RegionTy* RT = dyn_cast<RegionTy>(this))
    892     return RT;
    893 
    894   return NULL;
    895 }
    896 
    897 //===----------------------------------------------------------------------===//
    898 // MemRegionManager - Factory object for creating regions.
    899 //===----------------------------------------------------------------------===//
    900 
    901 class MemRegionManager {
    902   ASTContext &C;
    903   llvm::BumpPtrAllocator& A;
    904   llvm::FoldingSet<MemRegion> Regions;
    905 
    906   NonStaticGlobalSpaceRegion *globals;
    907 
    908   llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
    909     StackLocalsSpaceRegions;
    910   llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
    911     StackArgumentsSpaceRegions;
    912   llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
    913     StaticsGlobalSpaceRegions;
    914 
    915   HeapSpaceRegion *heap;
    916   UnknownSpaceRegion *unknown;
    917   MemSpaceRegion *code;
    918 
    919 public:
    920   MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
    921     : C(c), A(a), globals(0), heap(0), unknown(0), code(0) {}
    922 
    923   ~MemRegionManager();
    924 
    925   ASTContext &getContext() { return C; }
    926 
    927   llvm::BumpPtrAllocator &getAllocator() { return A; }
    928 
    929   /// getStackLocalsRegion - Retrieve the memory region associated with the
    930   ///  specified stack frame.
    931   const StackLocalsSpaceRegion *
    932   getStackLocalsRegion(const StackFrameContext *STC);
    933 
    934   /// getStackArgumentsRegion - Retrieve the memory region associated with
    935   ///  function/method arguments of the specified stack frame.
    936   const StackArgumentsSpaceRegion *
    937   getStackArgumentsRegion(const StackFrameContext *STC);
    938 
    939   /// getGlobalsRegion - Retrieve the memory region associated with
    940   ///  global variables.
    941   const GlobalsSpaceRegion *getGlobalsRegion(const CodeTextRegion *R = 0);
    942 
    943   /// getHeapRegion - Retrieve the memory region associated with the
    944   ///  generic "heap".
    945   const HeapSpaceRegion *getHeapRegion();
    946 
    947   /// getUnknownRegion - Retrieve the memory region associated with unknown
    948   /// memory space.
    949   const MemSpaceRegion *getUnknownRegion();
    950 
    951   const MemSpaceRegion *getCodeRegion();
    952 
    953   /// getAllocaRegion - Retrieve a region associated with a call to alloca().
    954   const AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt,
    955                                       const LocationContext *LC);
    956 
    957   /// getCompoundLiteralRegion - Retrieve the region associated with a
    958   ///  given CompoundLiteral.
    959   const CompoundLiteralRegion*
    960   getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
    961                            const LocationContext *LC);
    962 
    963   /// getCXXThisRegion - Retrieve the [artificial] region associated with the
    964   ///  parameter 'this'.
    965   const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
    966                                         const LocationContext *LC);
    967 
    968   /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
    969   const SymbolicRegion* getSymbolicRegion(SymbolRef sym);
    970 
    971   const StringRegion* getStringRegion(const StringLiteral* Str);
    972 
    973   /// getVarRegion - Retrieve or create the memory region associated with
    974   ///  a specified VarDecl and LocationContext.
    975   const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
    976 
    977   /// getVarRegion - Retrieve or create the memory region associated with
    978   ///  a specified VarDecl and super region.
    979   const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
    980 
    981   /// getElementRegion - Retrieve the memory region associated with the
    982   ///  associated element type, index, and super region.
    983   const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
    984                                         const MemRegion *superRegion,
    985                                         ASTContext &Ctx);
    986 
    987   const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
    988                                                  const MemRegion *superRegion) {
    989     return getElementRegion(ER->getElementType(), ER->getIndex(),
    990                             superRegion, ER->getContext());
    991   }
    992 
    993   /// getFieldRegion - Retrieve or create the memory region associated with
    994   ///  a specified FieldDecl.  'superRegion' corresponds to the containing
    995   ///  memory region (which typically represents the memory representing
    996   ///  a structure or class).
    997   const FieldRegion *getFieldRegion(const FieldDecl* fd,
    998                                     const MemRegion* superRegion);
    999 
   1000   const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
   1001                                              const MemRegion *superRegion) {
   1002     return getFieldRegion(FR->getDecl(), superRegion);
   1003   }
   1004 
   1005   /// getObjCIvarRegion - Retrieve or create the memory region associated with
   1006   ///   a specified Objective-c instance variable.  'superRegion' corresponds
   1007   ///   to the containing region (which typically represents the Objective-C
   1008   ///   object).
   1009   const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd,
   1010                                           const MemRegion* superRegion);
   1011 
   1012   const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
   1013                                                     LocationContext const *LC);
   1014 
   1015   const CXXBaseObjectRegion *getCXXBaseObjectRegion(const CXXRecordDecl *decl,
   1016                                                   const MemRegion *superRegion);
   1017 
   1018   /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
   1019   /// super region.
   1020   const CXXBaseObjectRegion *
   1021   getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
   1022                                   const MemRegion *superRegion) {
   1023     return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion);
   1024   }
   1025 
   1026   const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
   1027   const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
   1028                                             CanQualType locTy,
   1029                                             AnalysisContext *AC);
   1030 
   1031   /// getBlockDataRegion - Get the memory region associated with an instance
   1032   ///  of a block.  Unlike many other MemRegions, the LocationContext*
   1033   ///  argument is allowed to be NULL for cases where we have no known
   1034   ///  context.
   1035   const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
   1036                                             const LocationContext *lc = NULL);
   1037 
   1038   bool isGlobalsRegion(const MemRegion* R) {
   1039     assert(R);
   1040     return R == globals;
   1041   }
   1042 
   1043 private:
   1044   template <typename RegionTy, typename A1>
   1045   RegionTy* getRegion(const A1 a1);
   1046 
   1047   template <typename RegionTy, typename A1>
   1048   RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
   1049 
   1050   template <typename RegionTy, typename A1, typename A2>
   1051   RegionTy* getRegion(const A1 a1, const A2 a2);
   1052 
   1053   template <typename RegionTy, typename A1, typename A2>
   1054   RegionTy* getSubRegion(const A1 a1, const A2 a2,
   1055                          const MemRegion* superRegion);
   1056 
   1057   template <typename RegionTy, typename A1, typename A2, typename A3>
   1058   RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
   1059                          const MemRegion* superRegion);
   1060 
   1061   template <typename REG>
   1062   const REG* LazyAllocate(REG*& region);
   1063 
   1064   template <typename REG, typename ARG>
   1065   const REG* LazyAllocate(REG*& region, ARG a);
   1066 };
   1067 
   1068 //===----------------------------------------------------------------------===//
   1069 // Out-of-line member definitions.
   1070 //===----------------------------------------------------------------------===//
   1071 
   1072 inline ASTContext& MemRegion::getContext() const {
   1073   return getMemRegionManager()->getContext();
   1074 }
   1075 
   1076 } // end GR namespace
   1077 
   1078 } // end clang namespace
   1079 
   1080 //===----------------------------------------------------------------------===//
   1081 // Pretty-printing regions.
   1082 //===----------------------------------------------------------------------===//
   1083 
   1084 namespace llvm {
   1085 static inline raw_ostream& operator<<(raw_ostream& os,
   1086                                       const clang::ento::MemRegion* R) {
   1087   R->dumpToStream(os);
   1088   return os;
   1089 }
   1090 } // end llvm namespace
   1091 
   1092 #endif
   1093