clang API Documentation

MemRegion.h
Go to the documentation of this file.
00001 //== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines MemRegion and its subclasses.  MemRegion defines a
00011 //  partially-typed abstraction of memory useful for path-sensitive dataflow
00012 //  analyses.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #ifndef LLVM_CLANG_GR_MEMREGION_H
00017 #define LLVM_CLANG_GR_MEMREGION_H
00018 
00019 #include "clang/AST/CharUnits.h"
00020 #include "clang/AST/Decl.h"
00021 #include "clang/AST/ExprObjC.h"
00022 #include "clang/Basic/LLVM.h"
00023 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
00024 #include "llvm/Support/ErrorHandling.h"
00025 #include "llvm/ADT/FoldingSet.h"
00026 #include <string>
00027 
00028 namespace llvm {
00029 class BumpPtrAllocator;
00030 }
00031 
00032 namespace clang {
00033 
00034 class LocationContext;
00035 class StackFrameContext;
00036 
00037 namespace ento {
00038 
00039 class MemRegionManager;
00040 class MemSpaceRegion;
00041 class SValBuilder;
00042 class VarRegion;
00043 class CodeTextRegion;
00044 
00045 /// Represent a region's offset within the top level base region.
00046 class RegionOffset {
00047   /// The base region.
00048   const MemRegion *R;
00049 
00050   /// The bit offset within the base region. It shouldn't be negative.
00051   int64_t Offset;
00052 
00053 public:
00054   RegionOffset(const MemRegion *r) : R(r), Offset(0) {}
00055   RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
00056 
00057   const MemRegion *getRegion() const { return R; }
00058   int64_t getOffset() const { return Offset; }
00059 };
00060 
00061 //===----------------------------------------------------------------------===//
00062 // Base region classes.
00063 //===----------------------------------------------------------------------===//
00064 
00065 /// MemRegion - The root abstract class for all memory regions.
00066 class MemRegion : public llvm::FoldingSetNode {
00067   friend class MemRegionManager;
00068 public:
00069   enum Kind {
00070     // Memory spaces.
00071     GenericMemSpaceRegionKind,
00072     StackLocalsSpaceRegionKind,
00073     StackArgumentsSpaceRegionKind,
00074     HeapSpaceRegionKind,
00075     UnknownSpaceRegionKind,
00076     StaticGlobalSpaceRegionKind,
00077     GlobalInternalSpaceRegionKind,
00078     GlobalSystemSpaceRegionKind,
00079     GlobalImmutableSpaceRegionKind,
00080     BEG_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind,
00081     END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
00082     BEG_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind,
00083     END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
00084     BEG_MEMSPACES = GenericMemSpaceRegionKind,
00085     END_MEMSPACES = GlobalImmutableSpaceRegionKind,
00086     // Untyped regions.
00087     SymbolicRegionKind,
00088     AllocaRegionKind,
00089     BlockDataRegionKind,
00090     // Typed regions.
00091     BEG_TYPED_REGIONS,
00092     FunctionTextRegionKind = BEG_TYPED_REGIONS,
00093     BlockTextRegionKind,
00094     BEG_TYPED_VALUE_REGIONS,
00095     CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS,
00096     CXXThisRegionKind,
00097     StringRegionKind,
00098     ObjCStringRegionKind,
00099     ElementRegionKind,
00100     // Decl Regions.
00101     BEG_DECL_REGIONS,
00102     VarRegionKind = BEG_DECL_REGIONS,
00103     FieldRegionKind,
00104     ObjCIvarRegionKind,
00105     END_DECL_REGIONS = ObjCIvarRegionKind,
00106     CXXTempObjectRegionKind,
00107     CXXBaseObjectRegionKind,
00108     END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind,
00109     END_TYPED_REGIONS = CXXBaseObjectRegionKind
00110   };
00111     
00112 private:
00113   const Kind kind;
00114 
00115 protected:
00116   MemRegion(Kind k) : kind(k) {}
00117   virtual ~MemRegion();
00118 
00119 public:
00120   ASTContext &getContext() const;
00121 
00122   virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
00123 
00124   virtual MemRegionManager* getMemRegionManager() const = 0;
00125 
00126   const MemSpaceRegion *getMemorySpace() const;
00127 
00128   const MemRegion *getBaseRegion() const;
00129 
00130   const MemRegion *StripCasts() const;
00131 
00132   bool hasGlobalsOrParametersStorage() const;
00133 
00134   bool hasStackStorage() const;
00135   
00136   bool hasStackNonParametersStorage() const;
00137   
00138   bool hasStackParametersStorage() const;
00139 
00140   /// Compute the offset within the top level memory object.
00141   RegionOffset getAsOffset() const;
00142 
00143   /// \brief Get a string representation of a region for debug use.
00144   std::string getString() const;
00145 
00146   virtual void dumpToStream(raw_ostream &os) const;
00147 
00148   void dump() const;
00149 
00150   /// \brief Print the region for use in diagnostics.
00151   virtual void dumpPretty(raw_ostream &os) const;
00152 
00153   Kind getKind() const { return kind; }
00154 
00155   template<typename RegionTy> const RegionTy* getAs() const;
00156 
00157   virtual bool isBoundable() const { return false; }
00158 
00159   static bool classof(const MemRegion*) { return true; }
00160 };
00161 
00162 /// MemSpaceRegion - A memory region that represents a "memory space";
00163 ///  for example, the set of global variables, the stack frame, etc.
00164 class MemSpaceRegion : public MemRegion {
00165 protected:
00166   friend class MemRegionManager;
00167   
00168   MemRegionManager *Mgr;
00169 
00170   MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
00171     : MemRegion(k), Mgr(mgr) {
00172     assert(classof(this));
00173   }
00174 
00175   MemRegionManager* getMemRegionManager() const { return Mgr; }
00176 
00177 public:
00178   bool isBoundable() const { return false; }
00179   
00180   void Profile(llvm::FoldingSetNodeID &ID) const;
00181 
00182   static bool classof(const MemRegion *R) {
00183     Kind k = R->getKind();
00184     return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
00185   }
00186 };
00187   
00188 class GlobalsSpaceRegion : public MemSpaceRegion {
00189   virtual void anchor();
00190 protected:
00191   GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
00192     : MemSpaceRegion(mgr, k) {}
00193 public:
00194   static bool classof(const MemRegion *R) {
00195     Kind k = R->getKind();
00196     return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
00197   }
00198 };
00199 
00200 /// \brief The region of the static variables within the current CodeTextRegion
00201 /// scope.
00202 ///
00203 /// Currently, only the static locals are placed there, so we know that these
00204 /// variables do not get invalidated by calls to other functions.
00205 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
00206   friend class MemRegionManager;
00207 
00208   const CodeTextRegion *CR;
00209   
00210   StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
00211     : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
00212 
00213 public:
00214   void Profile(llvm::FoldingSetNodeID &ID) const;
00215   
00216   void dumpToStream(raw_ostream &os) const;
00217 
00218   const CodeTextRegion *getCodeRegion() const { return CR; }
00219 
00220   static bool classof(const MemRegion *R) {
00221     return R->getKind() == StaticGlobalSpaceRegionKind;
00222   }
00223 };
00224 
00225 /// \brief The region for all the non-static global variables.
00226 ///
00227 /// This class is further split into subclasses for efficient implementation of
00228 /// invalidating a set of related global values as is done in
00229 /// RegionStoreManager::invalidateRegions (instead of finding all the dependent
00230 /// globals, we invalidate the whole parent region).
00231 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
00232   friend class MemRegionManager;
00233   
00234 protected:
00235   NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
00236     : GlobalsSpaceRegion(mgr, k) {}
00237   
00238 public:
00239 
00240   void dumpToStream(raw_ostream &os) const;
00241 
00242   static bool classof(const MemRegion *R) {
00243     Kind k = R->getKind();
00244     return k >= BEG_NON_STATIC_GLOBAL_MEMSPACES &&
00245            k <= END_NON_STATIC_GLOBAL_MEMSPACES;
00246   }
00247 };
00248 
00249 /// \brief The region containing globals which are defined in system/external
00250 /// headers and are considered modifiable by system calls (ex: errno).
00251 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
00252   friend class MemRegionManager;
00253 
00254   GlobalSystemSpaceRegion(MemRegionManager *mgr)
00255     : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
00256 
00257 public:
00258 
00259   void dumpToStream(raw_ostream &os) const;
00260 
00261   static bool classof(const MemRegion *R) {
00262     return R->getKind() == GlobalSystemSpaceRegionKind;
00263   }
00264 };
00265 
00266 /// \brief The region containing globals which are considered not to be modified
00267 /// or point to data which could be modified as a result of a function call
00268 /// (system or internal). Ex: Const global scalars would be modeled as part of
00269 /// this region. This region also includes most system globals since they have
00270 /// low chance of being modified.
00271 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
00272   friend class MemRegionManager;
00273 
00274   GlobalImmutableSpaceRegion(MemRegionManager *mgr)
00275     : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
00276 
00277 public:
00278 
00279   void dumpToStream(raw_ostream &os) const;
00280 
00281   static bool classof(const MemRegion *R) {
00282     return R->getKind() == GlobalImmutableSpaceRegionKind;
00283   }
00284 };
00285 
00286 /// \brief The region containing globals which can be modified by calls to
00287 /// "internally" defined functions - (for now just) functions other then system
00288 /// calls.
00289 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
00290   friend class MemRegionManager;
00291 
00292   GlobalInternalSpaceRegion(MemRegionManager *mgr)
00293     : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
00294 
00295 public:
00296 
00297   void dumpToStream(raw_ostream &os) const;
00298 
00299   static bool classof(const MemRegion *R) {
00300     return R->getKind() == GlobalInternalSpaceRegionKind;
00301   }
00302 };
00303 
00304 class HeapSpaceRegion : public MemSpaceRegion {
00305   virtual void anchor();
00306   friend class MemRegionManager;
00307   
00308   HeapSpaceRegion(MemRegionManager *mgr)
00309     : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
00310 public:
00311   static bool classof(const MemRegion *R) {
00312     return R->getKind() == HeapSpaceRegionKind;
00313   }
00314 };
00315   
00316 class UnknownSpaceRegion : public MemSpaceRegion {
00317   virtual void anchor();
00318   friend class MemRegionManager;
00319   UnknownSpaceRegion(MemRegionManager *mgr)
00320     : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
00321 public:
00322   static bool classof(const MemRegion *R) {
00323     return R->getKind() == UnknownSpaceRegionKind;
00324   }
00325 };
00326   
00327 class StackSpaceRegion : public MemSpaceRegion {
00328 private:
00329   const StackFrameContext *SFC;
00330 
00331 protected:
00332   StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
00333     : MemSpaceRegion(mgr, k), SFC(sfc) {
00334     assert(classof(this));
00335   }
00336 
00337 public:  
00338   const StackFrameContext *getStackFrame() const { return SFC; }
00339   
00340   void Profile(llvm::FoldingSetNodeID &ID) const;
00341 
00342   static bool classof(const MemRegion *R) {
00343     Kind k = R->getKind();
00344     return k >= StackLocalsSpaceRegionKind &&
00345            k <= StackArgumentsSpaceRegionKind;
00346   }  
00347 };
00348   
00349 class StackLocalsSpaceRegion : public StackSpaceRegion {
00350   virtual void anchor();
00351   friend class MemRegionManager;
00352   StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
00353     : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
00354 public:
00355   static bool classof(const MemRegion *R) {
00356     return R->getKind() == StackLocalsSpaceRegionKind;
00357   }
00358 };
00359 
00360 class StackArgumentsSpaceRegion : public StackSpaceRegion {
00361 private:
00362   virtual void anchor();
00363   friend class MemRegionManager;
00364   StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
00365     : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
00366 public:
00367   static bool classof(const MemRegion *R) {
00368     return R->getKind() == StackArgumentsSpaceRegionKind;
00369   }
00370 };
00371 
00372 
00373 /// SubRegion - A region that subsets another larger region.  Most regions
00374 ///  are subclasses of SubRegion.
00375 class SubRegion : public MemRegion {
00376 private:
00377   virtual void anchor();
00378 protected:
00379   const MemRegion* superRegion;
00380   SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
00381 public:
00382   const MemRegion* getSuperRegion() const {
00383     return superRegion;
00384   }
00385 
00386   /// getExtent - Returns the size of the region in bytes.
00387   virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
00388     return UnknownVal();
00389   }
00390 
00391   MemRegionManager* getMemRegionManager() const;
00392 
00393   bool isSubRegionOf(const MemRegion* R) const;
00394 
00395   static bool classof(const MemRegion* R) {
00396     return R->getKind() > END_MEMSPACES;
00397   }
00398 };
00399 
00400 //===----------------------------------------------------------------------===//
00401 // MemRegion subclasses.
00402 //===----------------------------------------------------------------------===//
00403 
00404 /// AllocaRegion - A region that represents an untyped blob of bytes created
00405 ///  by a call to 'alloca'.
00406 class AllocaRegion : public SubRegion {
00407   friend class MemRegionManager;
00408 protected:
00409   unsigned Cnt; // Block counter.  Used to distinguish different pieces of
00410                 // memory allocated by alloca at the same call site.
00411   const Expr *Ex;
00412 
00413   AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion)
00414     : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
00415 
00416 public:
00417 
00418   const Expr *getExpr() const { return Ex; }
00419 
00420   bool isBoundable() const { return true; }
00421 
00422   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
00423 
00424   void Profile(llvm::FoldingSetNodeID& ID) const;
00425 
00426   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
00427                             unsigned Cnt, const MemRegion *superRegion);
00428 
00429   void dumpToStream(raw_ostream &os) const;
00430 
00431   static bool classof(const MemRegion* R) {
00432     return R->getKind() == AllocaRegionKind;
00433   }
00434 };
00435 
00436 /// TypedRegion - An abstract class representing regions that are typed.
00437 class TypedRegion : public SubRegion {
00438 public:
00439   virtual void anchor();
00440 protected:
00441   TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
00442 
00443 public:
00444   virtual QualType getLocationType() const = 0;
00445 
00446   QualType getDesugaredLocationType(ASTContext &Context) const {
00447     return getLocationType().getDesugaredType(Context);
00448   }
00449 
00450   bool isBoundable() const { return true; }
00451 
00452   static bool classof(const MemRegion* R) {
00453     unsigned k = R->getKind();
00454     return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
00455   }
00456 };
00457 
00458 /// TypedValueRegion - An abstract class representing regions having a typed value.
00459 class TypedValueRegion : public TypedRegion {
00460 public:
00461   virtual void anchor();
00462 protected:
00463   TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
00464 
00465 public:
00466   virtual QualType getValueType() const = 0;
00467 
00468   virtual QualType getLocationType() const {
00469     // FIXME: We can possibly optimize this later to cache this value.
00470     QualType T = getValueType();
00471     ASTContext &ctx = getContext();
00472     if (T->getAs<ObjCObjectType>())
00473       return ctx.getObjCObjectPointerType(T);
00474     return ctx.getPointerType(getValueType());
00475   }
00476 
00477   QualType getDesugaredValueType(ASTContext &Context) const {
00478     QualType T = getValueType();
00479     return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
00480   }
00481 
00482   static bool classof(const MemRegion* R) {
00483     unsigned k = R->getKind();
00484     return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
00485   }
00486 };
00487 
00488 
00489 class CodeTextRegion : public TypedRegion {
00490 public:
00491   virtual void anchor();
00492 protected:
00493   CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
00494 public:
00495   bool isBoundable() const { return false; }
00496     
00497   static bool classof(const MemRegion* R) {
00498     Kind k = R->getKind();
00499     return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
00500   }
00501 };
00502 
00503 /// FunctionTextRegion - A region that represents code texts of function.
00504 class FunctionTextRegion : public CodeTextRegion {
00505   const FunctionDecl *FD;
00506 public:
00507   FunctionTextRegion(const FunctionDecl *fd, const MemRegion* sreg)
00508     : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {}
00509   
00510   QualType getLocationType() const {
00511     return getContext().getPointerType(FD->getType());
00512   }
00513   
00514   const FunctionDecl *getDecl() const {
00515     return FD;
00516   }
00517     
00518   virtual void dumpToStream(raw_ostream &os) const;
00519   
00520   void Profile(llvm::FoldingSetNodeID& ID) const;
00521   
00522   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD,
00523                             const MemRegion*);
00524   
00525   static bool classof(const MemRegion* R) {
00526     return R->getKind() == FunctionTextRegionKind;
00527   }
00528 };
00529   
00530   
00531 /// BlockTextRegion - A region that represents code texts of blocks (closures).
00532 ///  Blocks are represented with two kinds of regions.  BlockTextRegions
00533 ///  represent the "code", while BlockDataRegions represent instances of blocks,
00534 ///  which correspond to "code+data".  The distinction is important, because
00535 ///  like a closure a block captures the values of externally referenced
00536 ///  variables.
00537 class BlockTextRegion : public CodeTextRegion {
00538   friend class MemRegionManager;
00539 
00540   const BlockDecl *BD;
00541   AnalysisDeclContext *AC;
00542   CanQualType locTy;
00543 
00544   BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
00545                   AnalysisDeclContext *ac, const MemRegion* sreg)
00546     : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
00547 
00548 public:
00549   QualType getLocationType() const {
00550     return locTy;
00551   }
00552   
00553   const BlockDecl *getDecl() const {
00554     return BD;
00555   }
00556 
00557   AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
00558     
00559   virtual void dumpToStream(raw_ostream &os) const;
00560   
00561   void Profile(llvm::FoldingSetNodeID& ID) const;
00562   
00563   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
00564                             CanQualType, const AnalysisDeclContext*,
00565                             const MemRegion*);
00566   
00567   static bool classof(const MemRegion* R) {
00568     return R->getKind() == BlockTextRegionKind;
00569   }
00570 };
00571   
00572 /// BlockDataRegion - A region that represents a block instance.
00573 ///  Blocks are represented with two kinds of regions.  BlockTextRegions
00574 ///  represent the "code", while BlockDataRegions represent instances of blocks,
00575 ///  which correspond to "code+data".  The distinction is important, because
00576 ///  like a closure a block captures the values of externally referenced
00577 ///  variables.
00578 class BlockDataRegion : public SubRegion {
00579   friend class MemRegionManager;
00580   const BlockTextRegion *BC;
00581   const LocationContext *LC; // Can be null */
00582   void *ReferencedVars;
00583   void *OriginalVars;
00584 
00585   BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
00586                   const MemRegion *sreg)
00587   : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
00588     ReferencedVars(0), OriginalVars(0) {}
00589 
00590 public:
00591   const BlockTextRegion *getCodeRegion() const { return BC; }
00592   
00593   const BlockDecl *getDecl() const { return BC->getDecl(); }
00594   
00595   class referenced_vars_iterator {
00596     const MemRegion * const *R;
00597     const MemRegion * const *OriginalR;
00598   public:
00599     explicit referenced_vars_iterator(const MemRegion * const *r,
00600                                       const MemRegion * const *originalR)
00601       : R(r), OriginalR(originalR) {}
00602     
00603     operator const MemRegion * const *() const {
00604       return R;
00605     }
00606   
00607     const MemRegion *getCapturedRegion() const {
00608       return *R;
00609     }
00610     const MemRegion *getOriginalRegion() const {
00611       return *OriginalR;
00612     }
00613 
00614     const VarRegion* operator*() const {
00615       return cast<VarRegion>(*R);
00616     }
00617     
00618     bool operator==(const referenced_vars_iterator &I) const {
00619       return I.R == R;
00620     }
00621     bool operator!=(const referenced_vars_iterator &I) const {
00622       return I.R != R;
00623     }
00624     referenced_vars_iterator &operator++() {
00625       ++R;
00626       ++OriginalR;
00627       return *this;
00628     }
00629   };
00630       
00631   referenced_vars_iterator referenced_vars_begin() const;
00632   referenced_vars_iterator referenced_vars_end() const;  
00633     
00634   virtual void dumpToStream(raw_ostream &os) const;
00635     
00636   void Profile(llvm::FoldingSetNodeID& ID) const;
00637     
00638   static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
00639                             const LocationContext *, const MemRegion *);
00640     
00641   static bool classof(const MemRegion* R) {
00642     return R->getKind() == BlockDataRegionKind;
00643   }
00644 private:
00645   void LazyInitializeReferencedVars();
00646 };
00647 
00648 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region
00649 ///  clases, SymbolicRegion represents a region that serves as an alias for
00650 ///  either a real region, a NULL pointer, etc.  It essentially is used to
00651 ///  map the concept of symbolic values into the domain of regions.  Symbolic
00652 ///  regions do not need to be typed.
00653 class SymbolicRegion : public SubRegion {
00654 protected:
00655   const SymbolRef sym;
00656 
00657 public:
00658   SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
00659     : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
00660 
00661   SymbolRef getSymbol() const {
00662     return sym;
00663   }
00664 
00665   bool isBoundable() const { return true; }
00666 
00667   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
00668 
00669   void Profile(llvm::FoldingSetNodeID& ID) const;
00670 
00671   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
00672                             SymbolRef sym,
00673                             const MemRegion* superRegion);
00674 
00675   void dumpToStream(raw_ostream &os) const;
00676 
00677   static bool classof(const MemRegion* R) {
00678     return R->getKind() == SymbolicRegionKind;
00679   }
00680 };
00681 
00682 /// StringRegion - Region associated with a StringLiteral.
00683 class StringRegion : public TypedValueRegion {
00684   friend class MemRegionManager;
00685   const StringLiteral* Str;
00686 protected:
00687 
00688   StringRegion(const StringLiteral* str, const MemRegion* sreg)
00689     : TypedValueRegion(sreg, StringRegionKind), Str(str) {}
00690 
00691   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
00692                             const StringLiteral* Str,
00693                             const MemRegion* superRegion);
00694 
00695 public:
00696 
00697   const StringLiteral* getStringLiteral() const { return Str; }
00698 
00699   QualType getValueType() const {
00700     return Str->getType();
00701   }
00702 
00703   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
00704 
00705   bool isBoundable() const { return false; }
00706 
00707   void Profile(llvm::FoldingSetNodeID& ID) const {
00708     ProfileRegion(ID, Str, superRegion);
00709   }
00710 
00711   void dumpToStream(raw_ostream &os) const;
00712 
00713   static bool classof(const MemRegion* R) {
00714     return R->getKind() == StringRegionKind;
00715   }
00716 };
00717   
00718 /// The region associated with an ObjCStringLiteral.
00719 class ObjCStringRegion : public TypedValueRegion {
00720   friend class MemRegionManager;
00721   const ObjCStringLiteral* Str;
00722 protected:
00723   
00724   ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg)
00725   : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {}
00726   
00727   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
00728                             const ObjCStringLiteral* Str,
00729                             const MemRegion* superRegion);
00730   
00731 public:
00732   
00733   const ObjCStringLiteral* getObjCStringLiteral() const { return Str; }
00734   
00735   QualType getValueType() const {
00736     return Str->getType();
00737   }
00738   
00739   bool isBoundable() const { return false; }
00740   
00741   void Profile(llvm::FoldingSetNodeID& ID) const {
00742     ProfileRegion(ID, Str, superRegion);
00743   }
00744   
00745   void dumpToStream(raw_ostream &os) const;
00746   
00747   static bool classof(const MemRegion* R) {
00748     return R->getKind() == ObjCStringRegionKind;
00749   }
00750 };
00751 
00752 /// CompoundLiteralRegion - A memory region representing a compound literal.
00753 ///   Compound literals are essentially temporaries that are stack allocated
00754 ///   or in the global constant pool.
00755 class CompoundLiteralRegion : public TypedValueRegion {
00756 private:
00757   friend class MemRegionManager;
00758   const CompoundLiteralExpr *CL;
00759 
00760   CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg)
00761     : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
00762 
00763   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
00764                             const CompoundLiteralExpr *CL,
00765                             const MemRegion* superRegion);
00766 public:
00767   QualType getValueType() const {
00768     return CL->getType();
00769   }
00770 
00771   bool isBoundable() const { return !CL->isFileScope(); }
00772 
00773   void Profile(llvm::FoldingSetNodeID& ID) const;
00774 
00775   void dumpToStream(raw_ostream &os) const;
00776 
00777   const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
00778 
00779   static bool classof(const MemRegion* R) {
00780     return R->getKind() == CompoundLiteralRegionKind;
00781   }
00782 };
00783 
00784 class DeclRegion : public TypedValueRegion {
00785 protected:
00786   const Decl *D;
00787 
00788   DeclRegion(const Decl *d, const MemRegion* sReg, Kind k)
00789     : TypedValueRegion(sReg, k), D(d) {}
00790 
00791   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
00792                       const MemRegion* superRegion, Kind k);
00793 
00794 public:
00795   const Decl *getDecl() const { return D; }
00796   void Profile(llvm::FoldingSetNodeID& ID) const;
00797 
00798   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
00799 
00800   static bool classof(const MemRegion* R) {
00801     unsigned k = R->getKind();
00802     return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
00803   }
00804 };
00805 
00806 class VarRegion : public DeclRegion {
00807   friend class MemRegionManager;
00808 
00809   // Constructors and private methods.
00810   VarRegion(const VarDecl *vd, const MemRegion* sReg)
00811     : DeclRegion(vd, sReg, VarRegionKind) {}
00812 
00813   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
00814                             const MemRegion *superRegion) {
00815     DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
00816   }
00817 
00818   void Profile(llvm::FoldingSetNodeID& ID) const;
00819 
00820 public:
00821   const VarDecl *getDecl() const { return cast<VarDecl>(D); }
00822 
00823   const StackFrameContext *getStackFrame() const;
00824   
00825   QualType getValueType() const {
00826     // FIXME: We can cache this if needed.
00827     return getDecl()->getType();
00828   }
00829 
00830   void dumpToStream(raw_ostream &os) const;
00831 
00832   static bool classof(const MemRegion* R) {
00833     return R->getKind() == VarRegionKind;
00834   }
00835 
00836   void dumpPretty(raw_ostream &os) const;
00837 };
00838   
00839 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
00840 ///  in a call to a C++ method.  This region doesn't represent the object
00841 ///  referred to by 'this', but rather 'this' itself.
00842 class CXXThisRegion : public TypedValueRegion {
00843   friend class MemRegionManager;
00844   CXXThisRegion(const PointerType *thisPointerTy,
00845                 const MemRegion *sReg)
00846     : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
00847 
00848   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
00849                             const PointerType *PT,
00850                             const MemRegion *sReg);
00851 
00852   void Profile(llvm::FoldingSetNodeID &ID) const;
00853 
00854 public:  
00855   QualType getValueType() const {
00856     return QualType(ThisPointerTy, 0);
00857   }
00858 
00859   void dumpToStream(raw_ostream &os) const;
00860   
00861   static bool classof(const MemRegion* R) {
00862     return R->getKind() == CXXThisRegionKind;
00863   }
00864 
00865 private:
00866   const PointerType *ThisPointerTy;
00867 };
00868 
00869 class FieldRegion : public DeclRegion {
00870   friend class MemRegionManager;
00871 
00872   FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
00873     : DeclRegion(fd, sReg, FieldRegionKind) {}
00874 
00875 public:
00876   const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
00877 
00878   QualType getValueType() const {
00879     // FIXME: We can cache this if needed.
00880     return getDecl()->getType();
00881   }
00882 
00883   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
00884 
00885   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
00886                             const MemRegion* superRegion) {
00887     DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
00888   }
00889 
00890   static bool classof(const MemRegion* R) {
00891     return R->getKind() == FieldRegionKind;
00892   }
00893 
00894   void dumpToStream(raw_ostream &os) const;
00895   void dumpPretty(raw_ostream &os) const;
00896 };
00897 
00898 class ObjCIvarRegion : public DeclRegion {
00899 
00900   friend class MemRegionManager;
00901 
00902   ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg);
00903 
00904   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
00905                             const MemRegion* superRegion);
00906 
00907 public:
00908   const ObjCIvarDecl *getDecl() const;
00909   QualType getValueType() const;
00910 
00911   void dumpToStream(raw_ostream &os) const;
00912 
00913   static bool classof(const MemRegion* R) {
00914     return R->getKind() == ObjCIvarRegionKind;
00915   }
00916 };
00917 //===----------------------------------------------------------------------===//
00918 // Auxiliary data classes for use with MemRegions.
00919 //===----------------------------------------------------------------------===//
00920 
00921 class ElementRegion;
00922 
00923 class RegionRawOffset {
00924 private:
00925   friend class ElementRegion;
00926 
00927   const MemRegion *Region;
00928   CharUnits Offset;
00929 
00930   RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
00931     : Region(reg), Offset(offset) {}
00932 
00933 public:
00934   // FIXME: Eventually support symbolic offsets.
00935   CharUnits getOffset() const { return Offset; }
00936   const MemRegion *getRegion() const { return Region; }
00937 
00938   void dumpToStream(raw_ostream &os) const;
00939   void dump() const;
00940 };
00941 
00942 /// \brief ElementRegin is used to represent both array elements and casts.
00943 class ElementRegion : public TypedValueRegion {
00944   friend class MemRegionManager;
00945 
00946   QualType ElementType;
00947   NonLoc Index;
00948 
00949   ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
00950     : TypedValueRegion(sReg, ElementRegionKind),
00951       ElementType(elementType), Index(Idx) {
00952     assert((!isa<nonloc::ConcreteInt>(&Idx) ||
00953            cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
00954            "The index must be signed");
00955   }
00956 
00957   static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
00958                             SVal Idx, const MemRegion* superRegion);
00959 
00960 public:
00961 
00962   NonLoc getIndex() const { return Index; }
00963 
00964   QualType getValueType() const {
00965     return ElementType;
00966   }
00967 
00968   QualType getElementType() const {
00969     return ElementType;
00970   }
00971   /// Compute the offset within the array. The array might also be a subobject.
00972   RegionRawOffset getAsArrayOffset() const;
00973 
00974   void dumpToStream(raw_ostream &os) const;
00975 
00976   void Profile(llvm::FoldingSetNodeID& ID) const;
00977 
00978   static bool classof(const MemRegion* R) {
00979     return R->getKind() == ElementRegionKind;
00980   }
00981 };
00982 
00983 // C++ temporary object associated with an expression.
00984 class CXXTempObjectRegion : public TypedValueRegion {
00985   friend class MemRegionManager;
00986 
00987   Expr const *Ex;
00988 
00989   CXXTempObjectRegion(Expr const *E, MemRegion const *sReg) 
00990     : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {}
00991 
00992   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
00993                             Expr const *E, const MemRegion *sReg);
00994   
00995 public:
00996   const Expr *getExpr() const { return Ex; }
00997 
00998   QualType getValueType() const {
00999     return Ex->getType();
01000   }
01001 
01002   void dumpToStream(raw_ostream &os) const;
01003 
01004   void Profile(llvm::FoldingSetNodeID &ID) const;
01005 
01006   static bool classof(const MemRegion* R) {
01007     return R->getKind() == CXXTempObjectRegionKind;
01008   }
01009 };
01010 
01011 // CXXBaseObjectRegion represents a base object within a C++ object. It is 
01012 // identified by the base class declaration and the region of its parent object.
01013 class CXXBaseObjectRegion : public TypedValueRegion {
01014   friend class MemRegionManager;
01015 
01016   const CXXRecordDecl *decl;
01017 
01018   CXXBaseObjectRegion(const CXXRecordDecl *d, const MemRegion *sReg)
01019     : TypedValueRegion(sReg, CXXBaseObjectRegionKind), decl(d) {}
01020 
01021   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
01022                             const CXXRecordDecl *decl, const MemRegion *sReg);
01023 
01024 public:
01025   const CXXRecordDecl *getDecl() const { return decl; }
01026 
01027   QualType getValueType() const;
01028 
01029   void dumpToStream(raw_ostream &os) const;
01030 
01031   void Profile(llvm::FoldingSetNodeID &ID) const;
01032 
01033   static bool classof(const MemRegion *region) {
01034     return region->getKind() == CXXBaseObjectRegionKind;
01035   }
01036 };
01037 
01038 template<typename RegionTy>
01039 const RegionTy* MemRegion::getAs() const {
01040   if (const RegionTy* RT = dyn_cast<RegionTy>(this))
01041     return RT;
01042 
01043   return NULL;
01044 }
01045 
01046 //===----------------------------------------------------------------------===//
01047 // MemRegionManager - Factory object for creating regions.
01048 //===----------------------------------------------------------------------===//
01049 
01050 class MemRegionManager {
01051   ASTContext &C;
01052   llvm::BumpPtrAllocator& A;
01053   llvm::FoldingSet<MemRegion> Regions;
01054 
01055   GlobalInternalSpaceRegion *InternalGlobals;
01056   GlobalSystemSpaceRegion *SystemGlobals;
01057   GlobalImmutableSpaceRegion *ImmutableGlobals;
01058 
01059   
01060   llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> 
01061     StackLocalsSpaceRegions;
01062   llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
01063     StackArgumentsSpaceRegions;
01064   llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
01065     StaticsGlobalSpaceRegions;
01066 
01067   HeapSpaceRegion *heap;
01068   UnknownSpaceRegion *unknown;
01069   MemSpaceRegion *code;
01070 
01071 public:
01072   MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
01073     : C(c), A(a), InternalGlobals(0), SystemGlobals(0), ImmutableGlobals(0),
01074       heap(0), unknown(0), code(0) {}
01075 
01076   ~MemRegionManager();
01077 
01078   ASTContext &getContext() { return C; }
01079   
01080   llvm::BumpPtrAllocator &getAllocator() { return A; }
01081 
01082   /// getStackLocalsRegion - Retrieve the memory region associated with the
01083   ///  specified stack frame.
01084   const StackLocalsSpaceRegion *
01085   getStackLocalsRegion(const StackFrameContext *STC);
01086 
01087   /// getStackArgumentsRegion - Retrieve the memory region associated with
01088   ///  function/method arguments of the specified stack frame.
01089   const StackArgumentsSpaceRegion *
01090   getStackArgumentsRegion(const StackFrameContext *STC);
01091 
01092   /// getGlobalsRegion - Retrieve the memory region associated with
01093   ///  global variables.
01094   const GlobalsSpaceRegion *getGlobalsRegion(
01095       MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
01096       const CodeTextRegion *R = 0);
01097 
01098   /// getHeapRegion - Retrieve the memory region associated with the
01099   ///  generic "heap".
01100   const HeapSpaceRegion *getHeapRegion();
01101 
01102   /// getUnknownRegion - Retrieve the memory region associated with unknown
01103   /// memory space.
01104   const MemSpaceRegion *getUnknownRegion();
01105 
01106   const MemSpaceRegion *getCodeRegion();
01107 
01108   /// getAllocaRegion - Retrieve a region associated with a call to alloca().
01109   const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
01110                                       const LocationContext *LC);
01111 
01112   /// getCompoundLiteralRegion - Retrieve the region associated with a
01113   ///  given CompoundLiteral.
01114   const CompoundLiteralRegion*
01115   getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
01116                            const LocationContext *LC);
01117   
01118   /// getCXXThisRegion - Retrieve the [artificial] region associated with the
01119   ///  parameter 'this'.
01120   const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
01121                                         const LocationContext *LC);
01122 
01123   /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
01124   const SymbolicRegion* getSymbolicRegion(SymbolRef sym);
01125 
01126   const StringRegion *getStringRegion(const StringLiteral* Str);
01127 
01128   const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
01129 
01130   /// getVarRegion - Retrieve or create the memory region associated with
01131   ///  a specified VarDecl and LocationContext.
01132   const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
01133 
01134   /// getVarRegion - Retrieve or create the memory region associated with
01135   ///  a specified VarDecl and super region.
01136   const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
01137   
01138   /// getElementRegion - Retrieve the memory region associated with the
01139   ///  associated element type, index, and super region.
01140   const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
01141                                         const MemRegion *superRegion,
01142                                         ASTContext &Ctx);
01143 
01144   const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
01145                                                  const MemRegion *superRegion) {
01146     return getElementRegion(ER->getElementType(), ER->getIndex(),
01147                             superRegion, ER->getContext());
01148   }
01149 
01150   /// getFieldRegion - Retrieve or create the memory region associated with
01151   ///  a specified FieldDecl.  'superRegion' corresponds to the containing
01152   ///  memory region (which typically represents the memory representing
01153   ///  a structure or class).
01154   const FieldRegion *getFieldRegion(const FieldDecl *fd,
01155                                     const MemRegion* superRegion);
01156 
01157   const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
01158                                              const MemRegion *superRegion) {
01159     return getFieldRegion(FR->getDecl(), superRegion);
01160   }
01161 
01162   /// getObjCIvarRegion - Retrieve or create the memory region associated with
01163   ///   a specified Objective-c instance variable.  'superRegion' corresponds
01164   ///   to the containing region (which typically represents the Objective-C
01165   ///   object).
01166   const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
01167                                           const MemRegion* superRegion);
01168 
01169   const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
01170                                                     LocationContext const *LC);
01171 
01172   const CXXBaseObjectRegion *getCXXBaseObjectRegion(const CXXRecordDecl *decl,
01173                                                   const MemRegion *superRegion);
01174 
01175   /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
01176   /// super region.
01177   const CXXBaseObjectRegion *
01178   getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, 
01179                                   const MemRegion *superRegion) {
01180     return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion);
01181   }
01182 
01183   const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
01184   const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
01185                                             CanQualType locTy,
01186                                             AnalysisDeclContext *AC);
01187   
01188   /// getBlockDataRegion - Get the memory region associated with an instance
01189   ///  of a block.  Unlike many other MemRegions, the LocationContext*
01190   ///  argument is allowed to be NULL for cases where we have no known
01191   ///  context.
01192   const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
01193                                             const LocationContext *lc = NULL);
01194 
01195 private:
01196   template <typename RegionTy, typename A1>
01197   RegionTy* getRegion(const A1 a1);
01198 
01199   template <typename RegionTy, typename A1>
01200   RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
01201 
01202   template <typename RegionTy, typename A1, typename A2>
01203   RegionTy* getRegion(const A1 a1, const A2 a2);
01204 
01205   template <typename RegionTy, typename A1, typename A2>
01206   RegionTy* getSubRegion(const A1 a1, const A2 a2,
01207                          const MemRegion* superRegion);
01208 
01209   template <typename RegionTy, typename A1, typename A2, typename A3>
01210   RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
01211                          const MemRegion* superRegion);
01212   
01213   template <typename REG>
01214   const REG* LazyAllocate(REG*& region);
01215   
01216   template <typename REG, typename ARG>
01217   const REG* LazyAllocate(REG*& region, ARG a);
01218 };
01219 
01220 //===----------------------------------------------------------------------===//
01221 // Out-of-line member definitions.
01222 //===----------------------------------------------------------------------===//
01223 
01224 inline ASTContext &MemRegion::getContext() const {
01225   return getMemRegionManager()->getContext();
01226 }
01227   
01228 } // end GR namespace
01229 
01230 } // end clang namespace
01231 
01232 //===----------------------------------------------------------------------===//
01233 // Pretty-printing regions.
01234 //===----------------------------------------------------------------------===//
01235 
01236 namespace llvm {
01237 static inline raw_ostream &operator<<(raw_ostream &os,
01238                                       const clang::ento::MemRegion* R) {
01239   R->dumpToStream(os);
01240   return os;
01241 }
01242 } // end llvm namespace
01243 
01244 #endif