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