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