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