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_ANALYSIS_MEMREGION_H
17 #define LLVM_CLANG_ANALYSIS_MEMREGION_H
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclObjC.h"
21 #include "clang/GR/PathSensitive/SVals.h"
22 #include "llvm/Support/Casting.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/ADT/FoldingSet.h"
28 class BumpPtrAllocator
;
34 class MemRegionManager
;
36 class LocationContext
;
37 class StackFrameContext
;
42 /// Represent a region's offset within the top level base region.
47 /// The bit offset within the base region. It shouldn't be negative.
51 RegionOffset(const MemRegion
*r
) : R(r
), Offset(0) {}
52 RegionOffset(const MemRegion
*r
, int64_t off
) : R(r
), Offset(off
) {}
54 const MemRegion
*getRegion() const { return R
; }
55 int64_t getOffset() const { return Offset
; }
58 //===----------------------------------------------------------------------===//
59 // Base region classes.
60 //===----------------------------------------------------------------------===//
62 /// MemRegion - The root abstract class for all memory regions.
63 class MemRegion
: public llvm::FoldingSetNode
{
64 friend class MemRegionManager
;
68 GenericMemSpaceRegionKind
,
69 StackLocalsSpaceRegionKind
,
70 StackArgumentsSpaceRegionKind
,
72 UnknownSpaceRegionKind
,
73 NonStaticGlobalSpaceRegionKind
,
74 StaticGlobalSpaceRegionKind
,
75 BEG_GLOBAL_MEMSPACES
= NonStaticGlobalSpaceRegionKind
,
76 END_GLOBAL_MEMSPACES
= StaticGlobalSpaceRegionKind
,
77 BEG_MEMSPACES
= GenericMemSpaceRegionKind
,
78 END_MEMSPACES
= StaticGlobalSpaceRegionKind
,
84 FunctionTextRegionKind
= BEG_TYPED_REGIONS
,
87 CompoundLiteralRegionKind
,
93 VarRegionKind
= BEG_DECL_REGIONS
,
96 END_DECL_REGIONS
= ObjCIvarRegionKind
,
97 CXXTempObjectRegionKind
,
98 CXXBaseObjectRegionKind
,
99 END_TYPED_REGIONS
= CXXBaseObjectRegionKind
106 MemRegion(Kind k
) : kind(k
) {}
107 virtual ~MemRegion();
110 ASTContext
&getContext() const;
112 virtual void Profile(llvm::FoldingSetNodeID
& ID
) const = 0;
114 virtual MemRegionManager
* getMemRegionManager() const = 0;
116 std::string
getString() const;
118 const MemSpaceRegion
*getMemorySpace() const;
120 const MemRegion
*getBaseRegion() const;
122 const MemRegion
*StripCasts() const;
124 bool hasGlobalsOrParametersStorage() const;
126 bool hasStackStorage() const;
128 bool hasStackNonParametersStorage() const;
130 bool hasStackParametersStorage() const;
132 /// Compute the offset within the top level memory object.
133 RegionOffset
getAsOffset() const;
135 virtual void dumpToStream(llvm::raw_ostream
& os
) const;
139 Kind
getKind() const { return kind
; }
141 template<typename RegionTy
> const RegionTy
* getAs() const;
143 virtual bool isBoundable() const { return false; }
145 static bool classof(const MemRegion
*) { return true; }
148 /// MemSpaceRegion - A memory region that represents and "memory space";
149 /// for example, the set of global variables, the stack frame, etc.
150 class MemSpaceRegion
: public MemRegion
{
152 friend class MemRegionManager
;
154 MemRegionManager
*Mgr
;
156 MemSpaceRegion(MemRegionManager
*mgr
, Kind k
= GenericMemSpaceRegionKind
)
157 : MemRegion(k
), Mgr(mgr
) {
158 assert(classof(this));
161 MemRegionManager
* getMemRegionManager() const { return Mgr
; }
164 bool isBoundable() const { return false; }
166 void Profile(llvm::FoldingSetNodeID
&ID
) const;
168 static bool classof(const MemRegion
*R
) {
169 Kind k
= R
->getKind();
170 return k
>= BEG_MEMSPACES
&& k
<= END_MEMSPACES
;
174 class GlobalsSpaceRegion
: public MemSpaceRegion
{
176 GlobalsSpaceRegion(MemRegionManager
*mgr
, Kind k
)
177 : MemSpaceRegion(mgr
, k
) {}
179 static bool classof(const MemRegion
*R
) {
180 Kind k
= R
->getKind();
181 return k
>= BEG_GLOBAL_MEMSPACES
&& k
<= END_GLOBAL_MEMSPACES
;
185 class StaticGlobalSpaceRegion
: public GlobalsSpaceRegion
{
186 friend class MemRegionManager
;
188 const CodeTextRegion
*CR
;
190 StaticGlobalSpaceRegion(MemRegionManager
*mgr
, const CodeTextRegion
*cr
)
191 : GlobalsSpaceRegion(mgr
, StaticGlobalSpaceRegionKind
), CR(cr
) {}
194 void Profile(llvm::FoldingSetNodeID
&ID
) const;
196 void dumpToStream(llvm::raw_ostream
& os
) const;
198 const CodeTextRegion
*getCodeRegion() const { return CR
; }
200 static bool classof(const MemRegion
*R
) {
201 return R
->getKind() == StaticGlobalSpaceRegionKind
;
205 class NonStaticGlobalSpaceRegion
: public GlobalsSpaceRegion
{
206 friend class MemRegionManager
;
208 NonStaticGlobalSpaceRegion(MemRegionManager
*mgr
)
209 : GlobalsSpaceRegion(mgr
, NonStaticGlobalSpaceRegionKind
) {}
213 void dumpToStream(llvm::raw_ostream
& os
) const;
215 static bool classof(const MemRegion
*R
) {
216 return R
->getKind() == NonStaticGlobalSpaceRegionKind
;
220 class HeapSpaceRegion
: public MemSpaceRegion
{
221 friend class MemRegionManager
;
223 HeapSpaceRegion(MemRegionManager
*mgr
)
224 : MemSpaceRegion(mgr
, HeapSpaceRegionKind
) {}
226 static bool classof(const MemRegion
*R
) {
227 return R
->getKind() == HeapSpaceRegionKind
;
231 class UnknownSpaceRegion
: public MemSpaceRegion
{
232 friend class MemRegionManager
;
233 UnknownSpaceRegion(MemRegionManager
*mgr
)
234 : MemSpaceRegion(mgr
, UnknownSpaceRegionKind
) {}
236 static bool classof(const MemRegion
*R
) {
237 return R
->getKind() == UnknownSpaceRegionKind
;
241 class StackSpaceRegion
: public MemSpaceRegion
{
243 const StackFrameContext
*SFC
;
246 StackSpaceRegion(MemRegionManager
*mgr
, Kind k
, const StackFrameContext
*sfc
)
247 : MemSpaceRegion(mgr
, k
), SFC(sfc
) {
248 assert(classof(this));
252 const StackFrameContext
*getStackFrame() const { return SFC
; }
254 void Profile(llvm::FoldingSetNodeID
&ID
) const;
256 static bool classof(const MemRegion
*R
) {
257 Kind k
= R
->getKind();
258 return k
>= StackLocalsSpaceRegionKind
&&
259 k
<= StackArgumentsSpaceRegionKind
;
263 class StackLocalsSpaceRegion
: public StackSpaceRegion
{
265 friend class MemRegionManager
;
266 StackLocalsSpaceRegion(MemRegionManager
*mgr
, const StackFrameContext
*sfc
)
267 : StackSpaceRegion(mgr
, StackLocalsSpaceRegionKind
, sfc
) {}
269 static bool classof(const MemRegion
*R
) {
270 return R
->getKind() == StackLocalsSpaceRegionKind
;
274 class StackArgumentsSpaceRegion
: public StackSpaceRegion
{
276 friend class MemRegionManager
;
277 StackArgumentsSpaceRegion(MemRegionManager
*mgr
, const StackFrameContext
*sfc
)
278 : StackSpaceRegion(mgr
, StackArgumentsSpaceRegionKind
, sfc
) {}
280 static bool classof(const MemRegion
*R
) {
281 return R
->getKind() == StackArgumentsSpaceRegionKind
;
286 /// SubRegion - A region that subsets another larger region. Most regions
287 /// are subclasses of SubRegion.
288 class SubRegion
: public MemRegion
{
290 const MemRegion
* superRegion
;
291 SubRegion(const MemRegion
* sReg
, Kind k
) : MemRegion(k
), superRegion(sReg
) {}
293 const MemRegion
* getSuperRegion() const {
297 /// getExtent - Returns the size of the region in bytes.
298 virtual DefinedOrUnknownSVal
getExtent(SValBuilder
&svalBuilder
) const {
302 MemRegionManager
* getMemRegionManager() const;
304 bool isSubRegionOf(const MemRegion
* R
) const;
306 static bool classof(const MemRegion
* R
) {
307 return R
->getKind() > END_MEMSPACES
;
311 //===----------------------------------------------------------------------===//
312 // MemRegion subclasses.
313 //===----------------------------------------------------------------------===//
315 /// AllocaRegion - A region that represents an untyped blob of bytes created
316 /// by a call to 'alloca'.
317 class AllocaRegion
: public SubRegion
{
318 friend class MemRegionManager
;
320 unsigned Cnt
; // Block counter. Used to distinguish different pieces of
321 // memory allocated by alloca at the same call site.
324 AllocaRegion(const Expr
* ex
, unsigned cnt
, const MemRegion
*superRegion
)
325 : SubRegion(superRegion
, AllocaRegionKind
), Cnt(cnt
), Ex(ex
) {}
329 const Expr
* getExpr() const { return Ex
; }
331 bool isBoundable() const { return true; }
333 DefinedOrUnknownSVal
getExtent(SValBuilder
&svalBuilder
) const;
335 void Profile(llvm::FoldingSetNodeID
& ID
) const;
337 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const Expr
* Ex
,
338 unsigned Cnt
, const MemRegion
*superRegion
);
340 void dumpToStream(llvm::raw_ostream
& os
) const;
342 static bool classof(const MemRegion
* R
) {
343 return R
->getKind() == AllocaRegionKind
;
347 /// TypedRegion - An abstract class representing regions that are typed.
348 class TypedRegion
: public SubRegion
{
350 TypedRegion(const MemRegion
* sReg
, Kind k
) : SubRegion(sReg
, k
) {}
353 virtual QualType
getValueType() const = 0;
355 virtual QualType
getLocationType() const {
356 // FIXME: We can possibly optimize this later to cache this value.
357 return getContext().getPointerType(getValueType());
360 QualType
getDesugaredValueType(ASTContext
&Context
) const {
361 QualType T
= getValueType();
362 return T
.getTypePtrOrNull() ? T
.getDesugaredType(Context
) : T
;
365 QualType
getDesugaredLocationType(ASTContext
&Context
) const {
366 return getLocationType().getDesugaredType(Context
);
369 bool isBoundable() const { return true; }
371 static bool classof(const MemRegion
* R
) {
372 unsigned k
= R
->getKind();
373 return k
>= BEG_TYPED_REGIONS
&& k
<= END_TYPED_REGIONS
;
378 class CodeTextRegion
: public TypedRegion
{
380 CodeTextRegion(const MemRegion
*sreg
, Kind k
) : TypedRegion(sreg
, k
) {}
382 QualType
getValueType() const {
383 assert(0 && "Do not get the object type of a CodeTextRegion.");
387 bool isBoundable() const { return false; }
389 static bool classof(const MemRegion
* R
) {
390 Kind k
= R
->getKind();
391 return k
>= FunctionTextRegionKind
&& k
<= BlockTextRegionKind
;
395 /// FunctionTextRegion - A region that represents code texts of function.
396 class FunctionTextRegion
: public CodeTextRegion
{
397 const FunctionDecl
*FD
;
399 FunctionTextRegion(const FunctionDecl
* fd
, const MemRegion
* sreg
)
400 : CodeTextRegion(sreg
, FunctionTextRegionKind
), FD(fd
) {}
402 QualType
getLocationType() const {
403 return getContext().getPointerType(FD
->getType());
406 const FunctionDecl
*getDecl() const {
410 virtual void dumpToStream(llvm::raw_ostream
& os
) const;
412 void Profile(llvm::FoldingSetNodeID
& ID
) const;
414 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const FunctionDecl
*FD
,
417 static bool classof(const MemRegion
* R
) {
418 return R
->getKind() == FunctionTextRegionKind
;
423 /// BlockTextRegion - A region that represents code texts of blocks (closures).
424 /// Blocks are represented with two kinds of regions. BlockTextRegions
425 /// represent the "code", while BlockDataRegions represent instances of blocks,
426 /// which correspond to "code+data". The distinction is important, because
427 /// like a closure a block captures the values of externally referenced
429 class BlockTextRegion
: public CodeTextRegion
{
430 friend class MemRegionManager
;
436 BlockTextRegion(const BlockDecl
*bd
, CanQualType lTy
,
437 AnalysisContext
*ac
, const MemRegion
* sreg
)
438 : CodeTextRegion(sreg
, BlockTextRegionKind
), BD(bd
), AC(ac
), locTy(lTy
) {}
441 QualType
getLocationType() const {
445 const BlockDecl
*getDecl() const {
449 AnalysisContext
*getAnalysisContext() const { return AC
; }
451 virtual void dumpToStream(llvm::raw_ostream
& os
) const;
453 void Profile(llvm::FoldingSetNodeID
& ID
) const;
455 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const BlockDecl
*BD
,
456 CanQualType
, const AnalysisContext
*,
459 static bool classof(const MemRegion
* R
) {
460 return R
->getKind() == BlockTextRegionKind
;
464 /// BlockDataRegion - A region that represents a block instance.
465 /// Blocks are represented with two kinds of regions. BlockTextRegions
466 /// represent the "code", while BlockDataRegions represent instances of blocks,
467 /// which correspond to "code+data". The distinction is important, because
468 /// like a closure a block captures the values of externally referenced
470 class BlockDataRegion
: public SubRegion
{
471 friend class MemRegionManager
;
472 const BlockTextRegion
*BC
;
473 const LocationContext
*LC
; // Can be null */
474 void *ReferencedVars
;
476 BlockDataRegion(const BlockTextRegion
*bc
, const LocationContext
*lc
,
477 const MemRegion
*sreg
)
478 : SubRegion(sreg
, BlockDataRegionKind
), BC(bc
), LC(lc
), ReferencedVars(0) {}
481 const BlockTextRegion
*getCodeRegion() const { return BC
; }
483 const BlockDecl
*getDecl() const { return BC
->getDecl(); }
485 class referenced_vars_iterator
{
486 const MemRegion
* const *R
;
488 explicit referenced_vars_iterator(const MemRegion
* const *r
) : R(r
) {}
490 operator const MemRegion
* const *() const {
494 const VarRegion
* operator*() const {
495 return cast
<VarRegion
>(*R
);
498 bool operator==(const referenced_vars_iterator
&I
) const {
501 bool operator!=(const referenced_vars_iterator
&I
) const {
504 referenced_vars_iterator
& operator++() {
510 referenced_vars_iterator
referenced_vars_begin() const;
511 referenced_vars_iterator
referenced_vars_end() const;
513 virtual void dumpToStream(llvm::raw_ostream
& os
) const;
515 void Profile(llvm::FoldingSetNodeID
& ID
) const;
517 static void ProfileRegion(llvm::FoldingSetNodeID
&, const BlockTextRegion
*,
518 const LocationContext
*, const MemRegion
*);
520 static bool classof(const MemRegion
* R
) {
521 return R
->getKind() == BlockDataRegionKind
;
524 void LazyInitializeReferencedVars();
527 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region
528 /// clases, SymbolicRegion represents a region that serves as an alias for
529 /// either a real region, a NULL pointer, etc. It essentially is used to
530 /// map the concept of symbolic values into the domain of regions. Symbolic
531 /// regions do not need to be typed.
532 class SymbolicRegion
: public SubRegion
{
537 SymbolicRegion(const SymbolRef s
, const MemRegion
* sreg
)
538 : SubRegion(sreg
, SymbolicRegionKind
), sym(s
) {}
540 SymbolRef
getSymbol() const {
544 bool isBoundable() const { return true; }
546 DefinedOrUnknownSVal
getExtent(SValBuilder
&svalBuilder
) const;
548 void Profile(llvm::FoldingSetNodeID
& ID
) const;
550 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
,
552 const MemRegion
* superRegion
);
554 void dumpToStream(llvm::raw_ostream
& os
) const;
556 static bool classof(const MemRegion
* R
) {
557 return R
->getKind() == SymbolicRegionKind
;
561 /// StringRegion - Region associated with a StringLiteral.
562 class StringRegion
: public TypedRegion
{
563 friend class MemRegionManager
;
564 const StringLiteral
* Str
;
567 StringRegion(const StringLiteral
* str
, const MemRegion
* sreg
)
568 : TypedRegion(sreg
, StringRegionKind
), Str(str
) {}
570 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
,
571 const StringLiteral
* Str
,
572 const MemRegion
* superRegion
);
576 const StringLiteral
* getStringLiteral() const { return Str
; }
578 QualType
getValueType() const {
579 return Str
->getType();
582 DefinedOrUnknownSVal
getExtent(SValBuilder
&svalBuilder
) const;
584 bool isBoundable() const { return false; }
586 void Profile(llvm::FoldingSetNodeID
& ID
) const {
587 ProfileRegion(ID
, Str
, superRegion
);
590 void dumpToStream(llvm::raw_ostream
& os
) const;
592 static bool classof(const MemRegion
* R
) {
593 return R
->getKind() == StringRegionKind
;
597 /// CompoundLiteralRegion - A memory region representing a compound literal.
598 /// Compound literals are essentially temporaries that are stack allocated
599 /// or in the global constant pool.
600 class CompoundLiteralRegion
: public TypedRegion
{
602 friend class MemRegionManager
;
603 const CompoundLiteralExpr
* CL
;
605 CompoundLiteralRegion(const CompoundLiteralExpr
* cl
, const MemRegion
* sReg
)
606 : TypedRegion(sReg
, CompoundLiteralRegionKind
), CL(cl
) {}
608 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
,
609 const CompoundLiteralExpr
* CL
,
610 const MemRegion
* superRegion
);
612 QualType
getValueType() const {
613 return CL
->getType();
616 bool isBoundable() const { return !CL
->isFileScope(); }
618 void Profile(llvm::FoldingSetNodeID
& ID
) const;
620 void dumpToStream(llvm::raw_ostream
& os
) const;
622 const CompoundLiteralExpr
* getLiteralExpr() const { return CL
; }
624 static bool classof(const MemRegion
* R
) {
625 return R
->getKind() == CompoundLiteralRegionKind
;
629 class DeclRegion
: public TypedRegion
{
633 DeclRegion(const Decl
* d
, const MemRegion
* sReg
, Kind k
)
634 : TypedRegion(sReg
, k
), D(d
) {}
636 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const Decl
* D
,
637 const MemRegion
* superRegion
, Kind k
);
640 const Decl
* getDecl() const { return D
; }
641 void Profile(llvm::FoldingSetNodeID
& ID
) const;
643 DefinedOrUnknownSVal
getExtent(SValBuilder
&svalBuilder
) const;
645 static bool classof(const MemRegion
* R
) {
646 unsigned k
= R
->getKind();
647 return k
>= BEG_DECL_REGIONS
&& k
<= END_DECL_REGIONS
;
651 class VarRegion
: public DeclRegion
{
652 friend class MemRegionManager
;
654 // Constructors and private methods.
655 VarRegion(const VarDecl
* vd
, const MemRegion
* sReg
)
656 : DeclRegion(vd
, sReg
, VarRegionKind
) {}
658 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const VarDecl
* VD
,
659 const MemRegion
*superRegion
) {
660 DeclRegion::ProfileRegion(ID
, VD
, superRegion
, VarRegionKind
);
663 void Profile(llvm::FoldingSetNodeID
& ID
) const;
666 const VarDecl
*getDecl() const { return cast
<VarDecl
>(D
); }
668 const StackFrameContext
*getStackFrame() const;
670 QualType
getValueType() const {
671 // FIXME: We can cache this if needed.
672 return getDecl()->getType();
675 void dumpToStream(llvm::raw_ostream
& os
) const;
677 static bool classof(const MemRegion
* R
) {
678 return R
->getKind() == VarRegionKind
;
682 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
683 /// in a call to a C++ method. This region doesn't represent the object
684 /// referred to by 'this', but rather 'this' itself.
685 class CXXThisRegion
: public TypedRegion
{
686 friend class MemRegionManager
;
687 CXXThisRegion(const PointerType
*thisPointerTy
,
688 const MemRegion
*sReg
)
689 : TypedRegion(sReg
, CXXThisRegionKind
), ThisPointerTy(thisPointerTy
) {}
691 static void ProfileRegion(llvm::FoldingSetNodeID
&ID
,
692 const PointerType
*PT
,
693 const MemRegion
*sReg
);
695 void Profile(llvm::FoldingSetNodeID
&ID
) const;
698 QualType
getValueType() const {
699 return QualType(ThisPointerTy
, 0);
702 void dumpToStream(llvm::raw_ostream
& os
) const;
704 static bool classof(const MemRegion
* R
) {
705 return R
->getKind() == CXXThisRegionKind
;
709 const PointerType
*ThisPointerTy
;
712 class FieldRegion
: public DeclRegion
{
713 friend class MemRegionManager
;
715 FieldRegion(const FieldDecl
* fd
, const MemRegion
* sReg
)
716 : DeclRegion(fd
, sReg
, FieldRegionKind
) {}
720 void dumpToStream(llvm::raw_ostream
& os
) const;
722 const FieldDecl
* getDecl() const { return cast
<FieldDecl
>(D
); }
724 QualType
getValueType() const {
725 // FIXME: We can cache this if needed.
726 return getDecl()->getType();
729 DefinedOrUnknownSVal
getExtent(SValBuilder
&svalBuilder
) const;
731 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const FieldDecl
* FD
,
732 const MemRegion
* superRegion
) {
733 DeclRegion::ProfileRegion(ID
, FD
, superRegion
, FieldRegionKind
);
736 static bool classof(const MemRegion
* R
) {
737 return R
->getKind() == FieldRegionKind
;
741 class ObjCIvarRegion
: public DeclRegion
{
743 friend class MemRegionManager
;
745 ObjCIvarRegion(const ObjCIvarDecl
* ivd
, const MemRegion
* sReg
)
746 : DeclRegion(ivd
, sReg
, ObjCIvarRegionKind
) {}
748 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const ObjCIvarDecl
* ivd
,
749 const MemRegion
* superRegion
) {
750 DeclRegion::ProfileRegion(ID
, ivd
, superRegion
, ObjCIvarRegionKind
);
754 const ObjCIvarDecl
* getDecl() const { return cast
<ObjCIvarDecl
>(D
); }
755 QualType
getValueType() const { return getDecl()->getType(); }
757 void dumpToStream(llvm::raw_ostream
& os
) const;
759 static bool classof(const MemRegion
* R
) {
760 return R
->getKind() == ObjCIvarRegionKind
;
763 //===----------------------------------------------------------------------===//
764 // Auxillary data classes for use with MemRegions.
765 //===----------------------------------------------------------------------===//
769 class RegionRawOffset
{
771 friend class ElementRegion
;
773 const MemRegion
*Region
;
776 RegionRawOffset(const MemRegion
* reg
, int64_t offset
= 0)
777 : Region(reg
), Offset(offset
) {}
780 // FIXME: Eventually support symbolic offsets.
781 int64_t getByteOffset() const { return Offset
; }
782 const MemRegion
*getRegion() const { return Region
; }
784 void dumpToStream(llvm::raw_ostream
& os
) const;
788 class ElementRegion
: public TypedRegion
{
789 friend class MemRegionManager
;
791 QualType ElementType
;
794 ElementRegion(QualType elementType
, NonLoc Idx
, const MemRegion
* sReg
)
795 : TypedRegion(sReg
, ElementRegionKind
),
796 ElementType(elementType
), Index(Idx
) {
797 assert((!isa
<nonloc::ConcreteInt
>(&Idx
) ||
798 cast
<nonloc::ConcreteInt
>(&Idx
)->getValue().isSigned()) &&
799 "The index must be signed");
802 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, QualType elementType
,
803 SVal Idx
, const MemRegion
* superRegion
);
807 NonLoc
getIndex() const { return Index
; }
809 QualType
getValueType() const {
813 QualType
getElementType() const {
816 /// Compute the offset within the array. The array might also be a subobject.
817 RegionRawOffset
getAsArrayOffset() const;
819 void dumpToStream(llvm::raw_ostream
& os
) const;
821 void Profile(llvm::FoldingSetNodeID
& ID
) const;
823 static bool classof(const MemRegion
* R
) {
824 return R
->getKind() == ElementRegionKind
;
828 // C++ temporary object associated with an expression.
829 class CXXTempObjectRegion
: public TypedRegion
{
830 friend class MemRegionManager
;
834 CXXTempObjectRegion(Expr
const *E
, MemRegion
const *sReg
)
835 : TypedRegion(sReg
, CXXTempObjectRegionKind
), Ex(E
) {}
837 static void ProfileRegion(llvm::FoldingSetNodeID
&ID
,
838 Expr
const *E
, const MemRegion
*sReg
);
841 QualType
getValueType() const {
842 return Ex
->getType();
845 void dumpToStream(llvm::raw_ostream
& os
) const;
847 void Profile(llvm::FoldingSetNodeID
&ID
) const;
849 static bool classof(const MemRegion
* R
) {
850 return R
->getKind() == CXXTempObjectRegionKind
;
854 // CXXBaseObjectRegion represents a base object within a C++ object. It is
855 // identified by the base class declaration and the region of its parent object.
856 class CXXBaseObjectRegion
: public TypedRegion
{
857 friend class MemRegionManager
;
859 const CXXRecordDecl
*decl
;
861 CXXBaseObjectRegion(const CXXRecordDecl
*d
, const MemRegion
*sReg
)
862 : TypedRegion(sReg
, CXXBaseObjectRegionKind
), decl(d
) {}
864 static void ProfileRegion(llvm::FoldingSetNodeID
&ID
,
865 const CXXRecordDecl
*decl
, const MemRegion
*sReg
);
868 QualType
getValueType() const;
870 void dumpToStream(llvm::raw_ostream
& os
) const;
872 void Profile(llvm::FoldingSetNodeID
&ID
) const;
874 static bool classof(const MemRegion
*region
) {
875 return region
->getKind() == CXXBaseObjectRegionKind
;
879 template<typename RegionTy
>
880 const RegionTy
* MemRegion::getAs() const {
881 if (const RegionTy
* RT
= dyn_cast
<RegionTy
>(this))
887 //===----------------------------------------------------------------------===//
888 // MemRegionManager - Factory object for creating regions.
889 //===----------------------------------------------------------------------===//
891 class MemRegionManager
{
893 llvm::BumpPtrAllocator
& A
;
894 llvm::FoldingSet
<MemRegion
> Regions
;
896 NonStaticGlobalSpaceRegion
*globals
;
898 llvm::DenseMap
<const StackFrameContext
*, StackLocalsSpaceRegion
*>
899 StackLocalsSpaceRegions
;
900 llvm::DenseMap
<const StackFrameContext
*, StackArgumentsSpaceRegion
*>
901 StackArgumentsSpaceRegions
;
902 llvm::DenseMap
<const CodeTextRegion
*, StaticGlobalSpaceRegion
*>
903 StaticsGlobalSpaceRegions
;
905 HeapSpaceRegion
*heap
;
906 UnknownSpaceRegion
*unknown
;
907 MemSpaceRegion
*code
;
910 MemRegionManager(ASTContext
&c
, llvm::BumpPtrAllocator
& a
)
911 : C(c
), A(a
), globals(0), heap(0), unknown(0), code(0) {}
915 ASTContext
&getContext() { return C
; }
917 llvm::BumpPtrAllocator
&getAllocator() { return A
; }
919 /// getStackLocalsRegion - Retrieve the memory region associated with the
920 /// specified stack frame.
921 const StackLocalsSpaceRegion
*
922 getStackLocalsRegion(const StackFrameContext
*STC
);
924 /// getStackArgumentsRegion - Retrieve the memory region associated with
925 /// function/method arguments of the specified stack frame.
926 const StackArgumentsSpaceRegion
*
927 getStackArgumentsRegion(const StackFrameContext
*STC
);
929 /// getGlobalsRegion - Retrieve the memory region associated with
930 /// global variables.
931 const GlobalsSpaceRegion
*getGlobalsRegion(const CodeTextRegion
*R
= 0);
933 /// getHeapRegion - Retrieve the memory region associated with the
935 const HeapSpaceRegion
*getHeapRegion();
937 /// getUnknownRegion - Retrieve the memory region associated with unknown
939 const MemSpaceRegion
*getUnknownRegion();
941 const MemSpaceRegion
*getCodeRegion();
943 /// getAllocaRegion - Retrieve a region associated with a call to alloca().
944 const AllocaRegion
*getAllocaRegion(const Expr
* Ex
, unsigned Cnt
,
945 const LocationContext
*LC
);
947 /// getCompoundLiteralRegion - Retrieve the region associated with a
948 /// given CompoundLiteral.
949 const CompoundLiteralRegion
*
950 getCompoundLiteralRegion(const CompoundLiteralExpr
* CL
,
951 const LocationContext
*LC
);
953 /// getCXXThisRegion - Retrieve the [artifical] region associated with the
954 /// parameter 'this'.
955 const CXXThisRegion
*getCXXThisRegion(QualType thisPointerTy
,
956 const LocationContext
*LC
);
958 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
959 const SymbolicRegion
* getSymbolicRegion(SymbolRef sym
);
961 const StringRegion
* getStringRegion(const StringLiteral
* Str
);
963 /// getVarRegion - Retrieve or create the memory region associated with
964 /// a specified VarDecl and LocationContext.
965 const VarRegion
* getVarRegion(const VarDecl
*D
, const LocationContext
*LC
);
967 /// getVarRegion - Retrieve or create the memory region associated with
968 /// a specified VarDecl and super region.
969 const VarRegion
* getVarRegion(const VarDecl
*D
, const MemRegion
*superR
);
971 /// getElementRegion - Retrieve the memory region associated with the
972 /// associated element type, index, and super region.
973 const ElementRegion
*getElementRegion(QualType elementType
, NonLoc Idx
,
974 const MemRegion
*superRegion
,
977 const ElementRegion
*getElementRegionWithSuper(const ElementRegion
*ER
,
978 const MemRegion
*superRegion
) {
979 return getElementRegion(ER
->getElementType(), ER
->getIndex(),
980 superRegion
, ER
->getContext());
983 /// getFieldRegion - Retrieve or create the memory region associated with
984 /// a specified FieldDecl. 'superRegion' corresponds to the containing
985 /// memory region (which typically represents the memory representing
986 /// a structure or class).
987 const FieldRegion
*getFieldRegion(const FieldDecl
* fd
,
988 const MemRegion
* superRegion
);
990 const FieldRegion
*getFieldRegionWithSuper(const FieldRegion
*FR
,
991 const MemRegion
*superRegion
) {
992 return getFieldRegion(FR
->getDecl(), superRegion
);
995 /// getObjCIvarRegion - Retrieve or create the memory region associated with
996 /// a specified Objective-c instance variable. 'superRegion' corresponds
997 /// to the containing region (which typically represents the Objective-C
999 const ObjCIvarRegion
*getObjCIvarRegion(const ObjCIvarDecl
* ivd
,
1000 const MemRegion
* superRegion
);
1002 const CXXTempObjectRegion
*getCXXTempObjectRegion(Expr
const *Ex
,
1003 LocationContext
const *LC
);
1005 const CXXBaseObjectRegion
*getCXXBaseObjectRegion(const CXXRecordDecl
*decl
,
1006 const MemRegion
*superRegion
);
1008 const FunctionTextRegion
*getFunctionTextRegion(const FunctionDecl
*FD
);
1009 const BlockTextRegion
*getBlockTextRegion(const BlockDecl
*BD
,
1011 AnalysisContext
*AC
);
1013 /// getBlockDataRegion - Get the memory region associated with an instance
1014 /// of a block. Unlike many other MemRegions, the LocationContext*
1015 /// argument is allowed to be NULL for cases where we have no known
1017 const BlockDataRegion
*getBlockDataRegion(const BlockTextRegion
*bc
,
1018 const LocationContext
*lc
= NULL
);
1020 bool isGlobalsRegion(const MemRegion
* R
) {
1022 return R
== globals
;
1026 template <typename RegionTy
, typename A1
>
1027 RegionTy
* getRegion(const A1 a1
);
1029 template <typename RegionTy
, typename A1
>
1030 RegionTy
* getSubRegion(const A1 a1
, const MemRegion
* superRegion
);
1032 template <typename RegionTy
, typename A1
, typename A2
>
1033 RegionTy
* getRegion(const A1 a1
, const A2 a2
);
1035 template <typename RegionTy
, typename A1
, typename A2
>
1036 RegionTy
* getSubRegion(const A1 a1
, const A2 a2
,
1037 const MemRegion
* superRegion
);
1039 template <typename RegionTy
, typename A1
, typename A2
, typename A3
>
1040 RegionTy
* getSubRegion(const A1 a1
, const A2 a2
, const A3 a3
,
1041 const MemRegion
* superRegion
);
1043 template <typename REG
>
1044 const REG
* LazyAllocate(REG
*& region
);
1046 template <typename REG
, typename ARG
>
1047 const REG
* LazyAllocate(REG
*& region
, ARG a
);
1050 //===----------------------------------------------------------------------===//
1051 // Out-of-line member definitions.
1052 //===----------------------------------------------------------------------===//
1054 inline ASTContext
& MemRegion::getContext() const {
1055 return getMemRegionManager()->getContext();
1058 } // end clang namespace
1060 //===----------------------------------------------------------------------===//
1061 // Pretty-printing regions.
1062 //===----------------------------------------------------------------------===//
1065 static inline raw_ostream
& operator<<(raw_ostream
& os
,
1066 const clang::MemRegion
* R
) {
1067 R
->dumpToStream(os
);
1070 } // end llvm namespace