1 //== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines MemRegion and its subclasses. MemRegion defines a
11 // partially-typed abstraction of memory useful for path-sensitive dataflow
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_CLANG_GR_MEMREGION_H
17 #define LLVM_CLANG_GR_MEMREGION_H
19 #include "clang/AST/CharUnits.h"
20 #include "clang/AST/Decl.h"
21 #include "clang/AST/DeclObjC.h"
22 #include "clang/Basic/LLVM.h"
23 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/ADT/FoldingSet.h"
29 class BumpPtrAllocator;
34 class LocationContext;
35 class StackFrameContext;
39 class MemRegionManager;
45 /// Represent a region's offset within the top level base region.
50 /// The bit offset within the base region. It shouldn't be negative.
54 RegionOffset(const MemRegion *r) : R(r), Offset(0) {}
55 RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
57 const MemRegion *getRegion() const { return R; }
58 int64_t getOffset() const { return Offset; }
61 //===----------------------------------------------------------------------===//
62 // Base region classes.
63 //===----------------------------------------------------------------------===//
65 /// MemRegion - The root abstract class for all memory regions.
66 class MemRegion : public llvm::FoldingSetNode {
67 friend class MemRegionManager;
71 GenericMemSpaceRegionKind,
72 StackLocalsSpaceRegionKind,
73 StackArgumentsSpaceRegionKind,
75 UnknownSpaceRegionKind,
76 NonStaticGlobalSpaceRegionKind,
77 StaticGlobalSpaceRegionKind,
78 BEG_GLOBAL_MEMSPACES = NonStaticGlobalSpaceRegionKind,
79 END_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind,
80 BEG_MEMSPACES = GenericMemSpaceRegionKind,
81 END_MEMSPACES = StaticGlobalSpaceRegionKind,
88 FunctionTextRegionKind = BEG_TYPED_REGIONS,
90 BEG_TYPED_VALUE_REGIONS,
91 CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS,
97 VarRegionKind = BEG_DECL_REGIONS,
100 END_DECL_REGIONS = ObjCIvarRegionKind,
101 CXXTempObjectRegionKind,
102 CXXBaseObjectRegionKind,
103 END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind,
104 END_TYPED_REGIONS = CXXBaseObjectRegionKind
111 MemRegion(Kind k) : kind(k) {}
112 virtual ~MemRegion();
115 ASTContext &getContext() const;
117 virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
119 virtual MemRegionManager* getMemRegionManager() const = 0;
121 std::string getString() const;
123 const MemSpaceRegion *getMemorySpace() const;
125 const MemRegion *getBaseRegion() const;
127 const MemRegion *StripCasts() const;
129 bool hasGlobalsOrParametersStorage() const;
131 bool hasStackStorage() const;
133 bool hasStackNonParametersStorage() const;
135 bool hasStackParametersStorage() const;
137 /// Compute the offset within the top level memory object.
138 RegionOffset getAsOffset() const;
140 virtual void dumpToStream(raw_ostream &os) const;
144 Kind getKind() const { return kind; }
146 template<typename RegionTy> const RegionTy* getAs() const;
148 virtual bool isBoundable() const { return false; }
150 static bool classof(const MemRegion*) { return true; }
153 /// MemSpaceRegion - A memory region that represents and "memory space";
154 /// for example, the set of global variables, the stack frame, etc.
155 class MemSpaceRegion : public MemRegion {
157 friend class MemRegionManager;
159 MemRegionManager *Mgr;
161 MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
162 : MemRegion(k), Mgr(mgr) {
163 assert(classof(this));
166 MemRegionManager* getMemRegionManager() const { return Mgr; }
169 bool isBoundable() const { return false; }
171 void Profile(llvm::FoldingSetNodeID &ID) const;
173 static bool classof(const MemRegion *R) {
174 Kind k = R->getKind();
175 return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
179 class GlobalsSpaceRegion : public MemSpaceRegion {
181 GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
182 : MemSpaceRegion(mgr, k) {}
184 static bool classof(const MemRegion *R) {
185 Kind k = R->getKind();
186 return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
190 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
191 friend class MemRegionManager;
193 const CodeTextRegion *CR;
195 StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
196 : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
199 void Profile(llvm::FoldingSetNodeID &ID) const;
201 void dumpToStream(raw_ostream &os) const;
203 const CodeTextRegion *getCodeRegion() const { return CR; }
205 static bool classof(const MemRegion *R) {
206 return R->getKind() == StaticGlobalSpaceRegionKind;
210 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
211 friend class MemRegionManager;
213 NonStaticGlobalSpaceRegion(MemRegionManager *mgr)
214 : GlobalsSpaceRegion(mgr, NonStaticGlobalSpaceRegionKind) {}
218 void dumpToStream(raw_ostream &os) const;
220 static bool classof(const MemRegion *R) {
221 return R->getKind() == NonStaticGlobalSpaceRegionKind;
225 class HeapSpaceRegion : public MemSpaceRegion {
226 friend class MemRegionManager;
228 HeapSpaceRegion(MemRegionManager *mgr)
229 : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
231 static bool classof(const MemRegion *R) {
232 return R->getKind() == HeapSpaceRegionKind;
236 class UnknownSpaceRegion : public MemSpaceRegion {
237 friend class MemRegionManager;
238 UnknownSpaceRegion(MemRegionManager *mgr)
239 : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
241 static bool classof(const MemRegion *R) {
242 return R->getKind() == UnknownSpaceRegionKind;
246 class StackSpaceRegion : public MemSpaceRegion {
248 const StackFrameContext *SFC;
251 StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
252 : MemSpaceRegion(mgr, k), SFC(sfc) {
253 assert(classof(this));
257 const StackFrameContext *getStackFrame() const { return SFC; }
259 void Profile(llvm::FoldingSetNodeID &ID) const;
261 static bool classof(const MemRegion *R) {
262 Kind k = R->getKind();
263 return k >= StackLocalsSpaceRegionKind &&
264 k <= StackArgumentsSpaceRegionKind;
268 class StackLocalsSpaceRegion : public StackSpaceRegion {
270 friend class MemRegionManager;
271 StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
272 : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
274 static bool classof(const MemRegion *R) {
275 return R->getKind() == StackLocalsSpaceRegionKind;
279 class StackArgumentsSpaceRegion : public StackSpaceRegion {
281 friend class MemRegionManager;
282 StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
283 : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
285 static bool classof(const MemRegion *R) {
286 return R->getKind() == StackArgumentsSpaceRegionKind;
291 /// SubRegion - A region that subsets another larger region. Most regions
292 /// are subclasses of SubRegion.
293 class SubRegion : public MemRegion {
295 const MemRegion* superRegion;
296 SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
298 const MemRegion* getSuperRegion() const {
302 /// getExtent - Returns the size of the region in bytes.
303 virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
307 MemRegionManager* getMemRegionManager() const;
309 bool isSubRegionOf(const MemRegion* R) const;
311 static bool classof(const MemRegion* R) {
312 return R->getKind() > END_MEMSPACES;
316 //===----------------------------------------------------------------------===//
317 // MemRegion subclasses.
318 //===----------------------------------------------------------------------===//
320 /// AllocaRegion - A region that represents an untyped blob of bytes created
321 /// by a call to 'alloca'.
322 class AllocaRegion : public SubRegion {
323 friend class MemRegionManager;
325 unsigned Cnt; // Block counter. Used to distinguish different pieces of
326 // memory allocated by alloca at the same call site.
329 AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion)
330 : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
334 const Expr *getExpr() const { return Ex; }
336 bool isBoundable() const { return true; }
338 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
340 void Profile(llvm::FoldingSetNodeID& ID) const;
342 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
343 unsigned Cnt, const MemRegion *superRegion);
345 void dumpToStream(raw_ostream &os) const;
347 static bool classof(const MemRegion* R) {
348 return R->getKind() == AllocaRegionKind;
352 /// TypedRegion - An abstract class representing regions that are typed.
353 class TypedRegion : public SubRegion {
355 TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
358 virtual QualType getLocationType() const = 0;
360 QualType getDesugaredLocationType(ASTContext &Context) const {
361 return getLocationType().getDesugaredType(Context);
364 bool isBoundable() const { return true; }
366 static bool classof(const MemRegion* R) {
367 unsigned k = R->getKind();
368 return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
372 /// TypedValueRegion - An abstract class representing regions having a typed value.
373 class TypedValueRegion : public TypedRegion {
375 TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
378 virtual QualType getValueType() const = 0;
380 virtual QualType getLocationType() const {
381 // FIXME: We can possibly optimize this later to cache this value.
382 QualType T = getValueType();
383 ASTContext &ctx = getContext();
384 if (T->getAs<ObjCObjectType>())
385 return ctx.getObjCObjectPointerType(T);
386 return ctx.getPointerType(getValueType());
389 QualType getDesugaredValueType(ASTContext &Context) const {
390 QualType T = getValueType();
391 return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
394 static bool classof(const MemRegion* R) {
395 unsigned k = R->getKind();
396 return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
401 class CodeTextRegion : public TypedRegion {
403 CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
405 bool isBoundable() const { return false; }
407 static bool classof(const MemRegion* R) {
408 Kind k = R->getKind();
409 return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
413 /// FunctionTextRegion - A region that represents code texts of function.
414 class FunctionTextRegion : public CodeTextRegion {
415 const FunctionDecl *FD;
417 FunctionTextRegion(const FunctionDecl *fd, const MemRegion* sreg)
418 : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {}
420 QualType getLocationType() const {
421 return getContext().getPointerType(FD->getType());
424 const FunctionDecl *getDecl() const {
428 virtual void dumpToStream(raw_ostream &os) const;
430 void Profile(llvm::FoldingSetNodeID& ID) const;
432 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD,
435 static bool classof(const MemRegion* R) {
436 return R->getKind() == FunctionTextRegionKind;
441 /// BlockTextRegion - A region that represents code texts of blocks (closures).
442 /// Blocks are represented with two kinds of regions. BlockTextRegions
443 /// represent the "code", while BlockDataRegions represent instances of blocks,
444 /// which correspond to "code+data". The distinction is important, because
445 /// like a closure a block captures the values of externally referenced
447 class BlockTextRegion : public CodeTextRegion {
448 friend class MemRegionManager;
454 BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
455 AnalysisContext *ac, const MemRegion* sreg)
456 : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
459 QualType getLocationType() const {
463 const BlockDecl *getDecl() const {
467 AnalysisContext *getAnalysisContext() const { return AC; }
469 virtual void dumpToStream(raw_ostream &os) const;
471 void Profile(llvm::FoldingSetNodeID& ID) const;
473 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
474 CanQualType, const AnalysisContext*,
477 static bool classof(const MemRegion* R) {
478 return R->getKind() == BlockTextRegionKind;
482 /// BlockDataRegion - A region that represents a block instance.
483 /// Blocks are represented with two kinds of regions. BlockTextRegions
484 /// represent the "code", while BlockDataRegions represent instances of blocks,
485 /// which correspond to "code+data". The distinction is important, because
486 /// like a closure a block captures the values of externally referenced
488 class BlockDataRegion : public SubRegion {
489 friend class MemRegionManager;
490 const BlockTextRegion *BC;
491 const LocationContext *LC; // Can be null */
492 void *ReferencedVars;
494 BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
495 const MemRegion *sreg)
496 : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {}
499 const BlockTextRegion *getCodeRegion() const { return BC; }
501 const BlockDecl *getDecl() const { return BC->getDecl(); }
503 class referenced_vars_iterator {
504 const MemRegion * const *R;
506 explicit referenced_vars_iterator(const MemRegion * const *r) : R(r) {}
508 operator const MemRegion * const *() const {
512 const VarRegion* operator*() const {
513 return cast<VarRegion>(*R);
516 bool operator==(const referenced_vars_iterator &I) const {
519 bool operator!=(const referenced_vars_iterator &I) const {
522 referenced_vars_iterator &operator++() {
528 referenced_vars_iterator referenced_vars_begin() const;
529 referenced_vars_iterator referenced_vars_end() const;
531 virtual void dumpToStream(raw_ostream &os) const;
533 void Profile(llvm::FoldingSetNodeID& ID) const;
535 static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
536 const LocationContext *, const MemRegion *);
538 static bool classof(const MemRegion* R) {
539 return R->getKind() == BlockDataRegionKind;
542 void LazyInitializeReferencedVars();
545 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region
546 /// clases, SymbolicRegion represents a region that serves as an alias for
547 /// either a real region, a NULL pointer, etc. It essentially is used to
548 /// map the concept of symbolic values into the domain of regions. Symbolic
549 /// regions do not need to be typed.
550 class SymbolicRegion : public SubRegion {
555 SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
556 : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
558 SymbolRef getSymbol() const {
562 bool isBoundable() const { return true; }
564 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
566 void Profile(llvm::FoldingSetNodeID& ID) const;
568 static void ProfileRegion(llvm::FoldingSetNodeID& ID,
570 const MemRegion* superRegion);
572 void dumpToStream(raw_ostream &os) const;
574 static bool classof(const MemRegion* R) {
575 return R->getKind() == SymbolicRegionKind;
579 /// StringRegion - Region associated with a StringLiteral.
580 class StringRegion : public TypedValueRegion {
581 friend class MemRegionManager;
582 const StringLiteral* Str;
585 StringRegion(const StringLiteral* str, const MemRegion* sreg)
586 : TypedValueRegion(sreg, StringRegionKind), Str(str) {}
588 static void ProfileRegion(llvm::FoldingSetNodeID& ID,
589 const StringLiteral* Str,
590 const MemRegion* superRegion);
594 const StringLiteral* getStringLiteral() const { return Str; }
596 QualType getValueType() const {
597 return Str->getType();
600 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
602 bool isBoundable() const { return false; }
604 void Profile(llvm::FoldingSetNodeID& ID) const {
605 ProfileRegion(ID, Str, superRegion);
608 void dumpToStream(raw_ostream &os) const;
610 static bool classof(const MemRegion* R) {
611 return R->getKind() == StringRegionKind;
615 /// CompoundLiteralRegion - A memory region representing a compound literal.
616 /// Compound literals are essentially temporaries that are stack allocated
617 /// or in the global constant pool.
618 class CompoundLiteralRegion : public TypedValueRegion {
620 friend class MemRegionManager;
621 const CompoundLiteralExpr *CL;
623 CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg)
624 : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
626 static void ProfileRegion(llvm::FoldingSetNodeID& ID,
627 const CompoundLiteralExpr *CL,
628 const MemRegion* superRegion);
630 QualType getValueType() const {
631 return CL->getType();
634 bool isBoundable() const { return !CL->isFileScope(); }
636 void Profile(llvm::FoldingSetNodeID& ID) const;
638 void dumpToStream(raw_ostream &os) const;
640 const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
642 static bool classof(const MemRegion* R) {
643 return R->getKind() == CompoundLiteralRegionKind;
647 class DeclRegion : public TypedValueRegion {
651 DeclRegion(const Decl *d, const MemRegion* sReg, Kind k)
652 : TypedValueRegion(sReg, k), D(d) {}
654 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
655 const MemRegion* superRegion, Kind k);
658 const Decl *getDecl() const { return D; }
659 void Profile(llvm::FoldingSetNodeID& ID) const;
661 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
663 static bool classof(const MemRegion* R) {
664 unsigned k = R->getKind();
665 return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
669 class VarRegion : public DeclRegion {
670 friend class MemRegionManager;
672 // Constructors and private methods.
673 VarRegion(const VarDecl *vd, const MemRegion* sReg)
674 : DeclRegion(vd, sReg, VarRegionKind) {}
676 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
677 const MemRegion *superRegion) {
678 DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
681 void Profile(llvm::FoldingSetNodeID& ID) const;
684 const VarDecl *getDecl() const { return cast<VarDecl>(D); }
686 const StackFrameContext *getStackFrame() const;
688 QualType getValueType() const {
689 // FIXME: We can cache this if needed.
690 return getDecl()->getType();
693 void dumpToStream(raw_ostream &os) const;
695 static bool classof(const MemRegion* R) {
696 return R->getKind() == VarRegionKind;
700 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
701 /// in a call to a C++ method. This region doesn't represent the object
702 /// referred to by 'this', but rather 'this' itself.
703 class CXXThisRegion : public TypedValueRegion {
704 friend class MemRegionManager;
705 CXXThisRegion(const PointerType *thisPointerTy,
706 const MemRegion *sReg)
707 : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
709 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
710 const PointerType *PT,
711 const MemRegion *sReg);
713 void Profile(llvm::FoldingSetNodeID &ID) const;
716 QualType getValueType() const {
717 return QualType(ThisPointerTy, 0);
720 void dumpToStream(raw_ostream &os) const;
722 static bool classof(const MemRegion* R) {
723 return R->getKind() == CXXThisRegionKind;
727 const PointerType *ThisPointerTy;
730 class FieldRegion : public DeclRegion {
731 friend class MemRegionManager;
733 FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
734 : DeclRegion(fd, sReg, FieldRegionKind) {}
738 void dumpToStream(raw_ostream &os) const;
740 const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
742 QualType getValueType() const {
743 // FIXME: We can cache this if needed.
744 return getDecl()->getType();
747 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
749 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
750 const MemRegion* superRegion) {
751 DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
754 static bool classof(const MemRegion* R) {
755 return R->getKind() == FieldRegionKind;
759 class ObjCIvarRegion : public DeclRegion {
761 friend class MemRegionManager;
763 ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg)
764 : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
766 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
767 const MemRegion* superRegion) {
768 DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
772 const ObjCIvarDecl *getDecl() const { return cast<ObjCIvarDecl>(D); }
773 QualType getValueType() const { return getDecl()->getType(); }
775 void dumpToStream(raw_ostream &os) const;
777 static bool classof(const MemRegion* R) {
778 return R->getKind() == ObjCIvarRegionKind;
781 //===----------------------------------------------------------------------===//
782 // Auxiliary data classes for use with MemRegions.
783 //===----------------------------------------------------------------------===//
787 class RegionRawOffset {
789 friend class ElementRegion;
791 const MemRegion *Region;
794 RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
795 : Region(reg), Offset(offset) {}
798 // FIXME: Eventually support symbolic offsets.
799 CharUnits getOffset() const { return Offset; }
800 const MemRegion *getRegion() const { return Region; }
802 void dumpToStream(raw_ostream &os) const;
806 class ElementRegion : public TypedValueRegion {
807 friend class MemRegionManager;
809 QualType ElementType;
812 ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
813 : TypedValueRegion(sReg, ElementRegionKind),
814 ElementType(elementType), Index(Idx) {
815 assert((!isa<nonloc::ConcreteInt>(&Idx) ||
816 cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
817 "The index must be signed");
820 static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
821 SVal Idx, const MemRegion* superRegion);
825 NonLoc getIndex() const { return Index; }
827 QualType getValueType() const {
831 QualType getElementType() const {
834 /// Compute the offset within the array. The array might also be a subobject.
835 RegionRawOffset getAsArrayOffset() const;
837 void dumpToStream(raw_ostream &os) const;
839 void Profile(llvm::FoldingSetNodeID& ID) const;
841 static bool classof(const MemRegion* R) {
842 return R->getKind() == ElementRegionKind;
846 // C++ temporary object associated with an expression.
847 class CXXTempObjectRegion : public TypedValueRegion {
848 friend class MemRegionManager;
852 CXXTempObjectRegion(Expr const *E, MemRegion const *sReg)
853 : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {}
855 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
856 Expr const *E, const MemRegion *sReg);
859 const Expr *getExpr() const { return Ex; }
861 QualType getValueType() const {
862 return Ex->getType();
865 void dumpToStream(raw_ostream &os) const;
867 void Profile(llvm::FoldingSetNodeID &ID) const;
869 static bool classof(const MemRegion* R) {
870 return R->getKind() == CXXTempObjectRegionKind;
874 // CXXBaseObjectRegion represents a base object within a C++ object. It is
875 // identified by the base class declaration and the region of its parent object.
876 class CXXBaseObjectRegion : public TypedValueRegion {
877 friend class MemRegionManager;
879 const CXXRecordDecl *decl;
881 CXXBaseObjectRegion(const CXXRecordDecl *d, const MemRegion *sReg)
882 : TypedValueRegion(sReg, CXXBaseObjectRegionKind), decl(d) {}
884 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
885 const CXXRecordDecl *decl, const MemRegion *sReg);
888 const CXXRecordDecl *getDecl() const { return decl; }
890 QualType getValueType() const;
892 void dumpToStream(raw_ostream &os) const;
894 void Profile(llvm::FoldingSetNodeID &ID) const;
896 static bool classof(const MemRegion *region) {
897 return region->getKind() == CXXBaseObjectRegionKind;
901 template<typename RegionTy>
902 const RegionTy* MemRegion::getAs() const {
903 if (const RegionTy* RT = dyn_cast<RegionTy>(this))
909 //===----------------------------------------------------------------------===//
910 // MemRegionManager - Factory object for creating regions.
911 //===----------------------------------------------------------------------===//
913 class MemRegionManager {
915 llvm::BumpPtrAllocator& A;
916 llvm::FoldingSet<MemRegion> Regions;
918 NonStaticGlobalSpaceRegion *globals;
920 llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
921 StackLocalsSpaceRegions;
922 llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
923 StackArgumentsSpaceRegions;
924 llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
925 StaticsGlobalSpaceRegions;
927 HeapSpaceRegion *heap;
928 UnknownSpaceRegion *unknown;
929 MemSpaceRegion *code;
932 MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
933 : C(c), A(a), globals(0), heap(0), unknown(0), code(0) {}
937 ASTContext &getContext() { return C; }
939 llvm::BumpPtrAllocator &getAllocator() { return A; }
941 /// getStackLocalsRegion - Retrieve the memory region associated with the
942 /// specified stack frame.
943 const StackLocalsSpaceRegion *
944 getStackLocalsRegion(const StackFrameContext *STC);
946 /// getStackArgumentsRegion - Retrieve the memory region associated with
947 /// function/method arguments of the specified stack frame.
948 const StackArgumentsSpaceRegion *
949 getStackArgumentsRegion(const StackFrameContext *STC);
951 /// getGlobalsRegion - Retrieve the memory region associated with
952 /// global variables.
953 const GlobalsSpaceRegion *getGlobalsRegion(const CodeTextRegion *R = 0);
955 /// getHeapRegion - Retrieve the memory region associated with the
957 const HeapSpaceRegion *getHeapRegion();
959 /// getUnknownRegion - Retrieve the memory region associated with unknown
961 const MemSpaceRegion *getUnknownRegion();
963 const MemSpaceRegion *getCodeRegion();
965 /// getAllocaRegion - Retrieve a region associated with a call to alloca().
966 const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
967 const LocationContext *LC);
969 /// getCompoundLiteralRegion - Retrieve the region associated with a
970 /// given CompoundLiteral.
971 const CompoundLiteralRegion*
972 getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
973 const LocationContext *LC);
975 /// getCXXThisRegion - Retrieve the [artificial] region associated with the
976 /// parameter 'this'.
977 const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
978 const LocationContext *LC);
980 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
981 const SymbolicRegion* getSymbolicRegion(SymbolRef sym);
983 const StringRegion* getStringRegion(const StringLiteral* Str);
985 /// getVarRegion - Retrieve or create the memory region associated with
986 /// a specified VarDecl and LocationContext.
987 const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
989 /// getVarRegion - Retrieve or create the memory region associated with
990 /// a specified VarDecl and super region.
991 const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
993 /// getElementRegion - Retrieve the memory region associated with the
994 /// associated element type, index, and super region.
995 const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
996 const MemRegion *superRegion,
999 const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1000 const MemRegion *superRegion) {
1001 return getElementRegion(ER->getElementType(), ER->getIndex(),
1002 superRegion, ER->getContext());
1005 /// getFieldRegion - Retrieve or create the memory region associated with
1006 /// a specified FieldDecl. 'superRegion' corresponds to the containing
1007 /// memory region (which typically represents the memory representing
1008 /// a structure or class).
1009 const FieldRegion *getFieldRegion(const FieldDecl *fd,
1010 const MemRegion* superRegion);
1012 const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1013 const MemRegion *superRegion) {
1014 return getFieldRegion(FR->getDecl(), superRegion);
1017 /// getObjCIvarRegion - Retrieve or create the memory region associated with
1018 /// a specified Objective-c instance variable. 'superRegion' corresponds
1019 /// to the containing region (which typically represents the Objective-C
1021 const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1022 const MemRegion* superRegion);
1024 const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1025 LocationContext const *LC);
1027 const CXXBaseObjectRegion *getCXXBaseObjectRegion(const CXXRecordDecl *decl,
1028 const MemRegion *superRegion);
1030 /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1032 const CXXBaseObjectRegion *
1033 getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1034 const MemRegion *superRegion) {
1035 return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion);
1038 const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
1039 const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
1041 AnalysisContext *AC);
1043 /// getBlockDataRegion - Get the memory region associated with an instance
1044 /// of a block. Unlike many other MemRegions, the LocationContext*
1045 /// argument is allowed to be NULL for cases where we have no known
1047 const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
1048 const LocationContext *lc = NULL);
1050 bool isGlobalsRegion(const MemRegion* R) {
1052 return R == globals;
1056 template <typename RegionTy, typename A1>
1057 RegionTy* getRegion(const A1 a1);
1059 template <typename RegionTy, typename A1>
1060 RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
1062 template <typename RegionTy, typename A1, typename A2>
1063 RegionTy* getRegion(const A1 a1, const A2 a2);
1065 template <typename RegionTy, typename A1, typename A2>
1066 RegionTy* getSubRegion(const A1 a1, const A2 a2,
1067 const MemRegion* superRegion);
1069 template <typename RegionTy, typename A1, typename A2, typename A3>
1070 RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
1071 const MemRegion* superRegion);
1073 template <typename REG>
1074 const REG* LazyAllocate(REG*& region);
1076 template <typename REG, typename ARG>
1077 const REG* LazyAllocate(REG*& region, ARG a);
1080 //===----------------------------------------------------------------------===//
1081 // Out-of-line member definitions.
1082 //===----------------------------------------------------------------------===//
1084 inline ASTContext &MemRegion::getContext() const {
1085 return getMemRegionManager()->getContext();
1088 } // end GR namespace
1090 } // end clang namespace
1092 //===----------------------------------------------------------------------===//
1093 // Pretty-printing regions.
1094 //===----------------------------------------------------------------------===//
1097 static inline raw_ostream &operator<<(raw_ostream &os,
1098 const clang::ento::MemRegion* R) {
1099 R->dumpToStream(os);
1102 } // end llvm namespace