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/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 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
,
87 FunctionTextRegionKind
= BEG_TYPED_REGIONS
,
90 CompoundLiteralRegionKind
,
96 VarRegionKind
= BEG_DECL_REGIONS
,
99 END_DECL_REGIONS
= ObjCIvarRegionKind
,
100 CXXTempObjectRegionKind
,
101 CXXBaseObjectRegionKind
,
102 END_TYPED_REGIONS
= CXXBaseObjectRegionKind
109 MemRegion(Kind k
) : kind(k
) {}
110 virtual ~MemRegion();
113 ASTContext
&getContext() const;
115 virtual void Profile(llvm::FoldingSetNodeID
& ID
) const = 0;
117 virtual MemRegionManager
* getMemRegionManager() const = 0;
119 std::string
getString() const;
121 const MemSpaceRegion
*getMemorySpace() const;
123 const MemRegion
*getBaseRegion() const;
125 const MemRegion
*StripCasts() const;
127 bool hasGlobalsOrParametersStorage() const;
129 bool hasStackStorage() const;
131 bool hasStackNonParametersStorage() const;
133 bool hasStackParametersStorage() const;
135 /// Compute the offset within the top level memory object.
136 RegionOffset
getAsOffset() const;
138 virtual void dumpToStream(llvm::raw_ostream
& os
) const;
142 Kind
getKind() const { return kind
; }
144 template<typename RegionTy
> const RegionTy
* getAs() const;
146 virtual bool isBoundable() const { return false; }
148 static bool classof(const MemRegion
*) { return true; }
151 /// MemSpaceRegion - A memory region that represents and "memory space";
152 /// for example, the set of global variables, the stack frame, etc.
153 class MemSpaceRegion
: public MemRegion
{
155 friend class MemRegionManager
;
157 MemRegionManager
*Mgr
;
159 MemSpaceRegion(MemRegionManager
*mgr
, Kind k
= GenericMemSpaceRegionKind
)
160 : MemRegion(k
), Mgr(mgr
) {
161 assert(classof(this));
164 MemRegionManager
* getMemRegionManager() const { return Mgr
; }
167 bool isBoundable() const { return false; }
169 void Profile(llvm::FoldingSetNodeID
&ID
) const;
171 static bool classof(const MemRegion
*R
) {
172 Kind k
= R
->getKind();
173 return k
>= BEG_MEMSPACES
&& k
<= END_MEMSPACES
;
177 class GlobalsSpaceRegion
: public MemSpaceRegion
{
179 GlobalsSpaceRegion(MemRegionManager
*mgr
, Kind k
)
180 : MemSpaceRegion(mgr
, k
) {}
182 static bool classof(const MemRegion
*R
) {
183 Kind k
= R
->getKind();
184 return k
>= BEG_GLOBAL_MEMSPACES
&& k
<= END_GLOBAL_MEMSPACES
;
188 class StaticGlobalSpaceRegion
: public GlobalsSpaceRegion
{
189 friend class MemRegionManager
;
191 const CodeTextRegion
*CR
;
193 StaticGlobalSpaceRegion(MemRegionManager
*mgr
, const CodeTextRegion
*cr
)
194 : GlobalsSpaceRegion(mgr
, StaticGlobalSpaceRegionKind
), CR(cr
) {}
197 void Profile(llvm::FoldingSetNodeID
&ID
) const;
199 void dumpToStream(llvm::raw_ostream
& os
) const;
201 const CodeTextRegion
*getCodeRegion() const { return CR
; }
203 static bool classof(const MemRegion
*R
) {
204 return R
->getKind() == StaticGlobalSpaceRegionKind
;
208 class NonStaticGlobalSpaceRegion
: public GlobalsSpaceRegion
{
209 friend class MemRegionManager
;
211 NonStaticGlobalSpaceRegion(MemRegionManager
*mgr
)
212 : GlobalsSpaceRegion(mgr
, NonStaticGlobalSpaceRegionKind
) {}
216 void dumpToStream(llvm::raw_ostream
& os
) const;
218 static bool classof(const MemRegion
*R
) {
219 return R
->getKind() == NonStaticGlobalSpaceRegionKind
;
223 class HeapSpaceRegion
: public MemSpaceRegion
{
224 friend class MemRegionManager
;
226 HeapSpaceRegion(MemRegionManager
*mgr
)
227 : MemSpaceRegion(mgr
, HeapSpaceRegionKind
) {}
229 static bool classof(const MemRegion
*R
) {
230 return R
->getKind() == HeapSpaceRegionKind
;
234 class UnknownSpaceRegion
: public MemSpaceRegion
{
235 friend class MemRegionManager
;
236 UnknownSpaceRegion(MemRegionManager
*mgr
)
237 : MemSpaceRegion(mgr
, UnknownSpaceRegionKind
) {}
239 static bool classof(const MemRegion
*R
) {
240 return R
->getKind() == UnknownSpaceRegionKind
;
244 class StackSpaceRegion
: public MemSpaceRegion
{
246 const StackFrameContext
*SFC
;
249 StackSpaceRegion(MemRegionManager
*mgr
, Kind k
, const StackFrameContext
*sfc
)
250 : MemSpaceRegion(mgr
, k
), SFC(sfc
) {
251 assert(classof(this));
255 const StackFrameContext
*getStackFrame() const { return SFC
; }
257 void Profile(llvm::FoldingSetNodeID
&ID
) const;
259 static bool classof(const MemRegion
*R
) {
260 Kind k
= R
->getKind();
261 return k
>= StackLocalsSpaceRegionKind
&&
262 k
<= StackArgumentsSpaceRegionKind
;
266 class StackLocalsSpaceRegion
: public StackSpaceRegion
{
268 friend class MemRegionManager
;
269 StackLocalsSpaceRegion(MemRegionManager
*mgr
, const StackFrameContext
*sfc
)
270 : StackSpaceRegion(mgr
, StackLocalsSpaceRegionKind
, sfc
) {}
272 static bool classof(const MemRegion
*R
) {
273 return R
->getKind() == StackLocalsSpaceRegionKind
;
277 class StackArgumentsSpaceRegion
: public StackSpaceRegion
{
279 friend class MemRegionManager
;
280 StackArgumentsSpaceRegion(MemRegionManager
*mgr
, const StackFrameContext
*sfc
)
281 : StackSpaceRegion(mgr
, StackArgumentsSpaceRegionKind
, sfc
) {}
283 static bool classof(const MemRegion
*R
) {
284 return R
->getKind() == StackArgumentsSpaceRegionKind
;
289 /// SubRegion - A region that subsets another larger region. Most regions
290 /// are subclasses of SubRegion.
291 class SubRegion
: public MemRegion
{
293 const MemRegion
* superRegion
;
294 SubRegion(const MemRegion
* sReg
, Kind k
) : MemRegion(k
), superRegion(sReg
) {}
296 const MemRegion
* getSuperRegion() const {
300 /// getExtent - Returns the size of the region in bytes.
301 virtual DefinedOrUnknownSVal
getExtent(SValBuilder
&svalBuilder
) const {
305 MemRegionManager
* getMemRegionManager() const;
307 bool isSubRegionOf(const MemRegion
* R
) const;
309 static bool classof(const MemRegion
* R
) {
310 return R
->getKind() > END_MEMSPACES
;
314 //===----------------------------------------------------------------------===//
315 // MemRegion subclasses.
316 //===----------------------------------------------------------------------===//
318 /// AllocaRegion - A region that represents an untyped blob of bytes created
319 /// by a call to 'alloca'.
320 class AllocaRegion
: public SubRegion
{
321 friend class MemRegionManager
;
323 unsigned Cnt
; // Block counter. Used to distinguish different pieces of
324 // memory allocated by alloca at the same call site.
327 AllocaRegion(const Expr
* ex
, unsigned cnt
, const MemRegion
*superRegion
)
328 : SubRegion(superRegion
, AllocaRegionKind
), Cnt(cnt
), Ex(ex
) {}
332 const Expr
* getExpr() const { return Ex
; }
334 bool isBoundable() const { return true; }
336 DefinedOrUnknownSVal
getExtent(SValBuilder
&svalBuilder
) const;
338 void Profile(llvm::FoldingSetNodeID
& ID
) const;
340 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const Expr
* Ex
,
341 unsigned Cnt
, const MemRegion
*superRegion
);
343 void dumpToStream(llvm::raw_ostream
& os
) const;
345 static bool classof(const MemRegion
* R
) {
346 return R
->getKind() == AllocaRegionKind
;
350 /// TypedRegion - An abstract class representing regions that are typed.
351 class TypedRegion
: public SubRegion
{
353 TypedRegion(const MemRegion
* sReg
, Kind k
) : SubRegion(sReg
, k
) {}
356 virtual QualType
getValueType() const = 0;
358 virtual QualType
getLocationType() const {
359 // FIXME: We can possibly optimize this later to cache this value.
360 return getContext().getPointerType(getValueType());
363 QualType
getDesugaredValueType(ASTContext
&Context
) const {
364 QualType T
= getValueType();
365 return T
.getTypePtrOrNull() ? T
.getDesugaredType(Context
) : T
;
368 QualType
getDesugaredLocationType(ASTContext
&Context
) const {
369 return getLocationType().getDesugaredType(Context
);
372 bool isBoundable() const { return true; }
374 static bool classof(const MemRegion
* R
) {
375 unsigned k
= R
->getKind();
376 return k
>= BEG_TYPED_REGIONS
&& k
<= END_TYPED_REGIONS
;
381 class CodeTextRegion
: public TypedRegion
{
383 CodeTextRegion(const MemRegion
*sreg
, Kind k
) : TypedRegion(sreg
, k
) {}
385 QualType
getValueType() const {
386 assert(0 && "Do not get the object type of a CodeTextRegion.");
390 bool isBoundable() const { return false; }
392 static bool classof(const MemRegion
* R
) {
393 Kind k
= R
->getKind();
394 return k
>= FunctionTextRegionKind
&& k
<= BlockTextRegionKind
;
398 /// FunctionTextRegion - A region that represents code texts of function.
399 class FunctionTextRegion
: public CodeTextRegion
{
400 const FunctionDecl
*FD
;
402 FunctionTextRegion(const FunctionDecl
* fd
, const MemRegion
* sreg
)
403 : CodeTextRegion(sreg
, FunctionTextRegionKind
), FD(fd
) {}
405 QualType
getLocationType() const {
406 return getContext().getPointerType(FD
->getType());
409 const FunctionDecl
*getDecl() const {
413 virtual void dumpToStream(llvm::raw_ostream
& os
) const;
415 void Profile(llvm::FoldingSetNodeID
& ID
) const;
417 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const FunctionDecl
*FD
,
420 static bool classof(const MemRegion
* R
) {
421 return R
->getKind() == FunctionTextRegionKind
;
426 /// BlockTextRegion - A region that represents code texts of blocks (closures).
427 /// Blocks are represented with two kinds of regions. BlockTextRegions
428 /// represent the "code", while BlockDataRegions represent instances of blocks,
429 /// which correspond to "code+data". The distinction is important, because
430 /// like a closure a block captures the values of externally referenced
432 class BlockTextRegion
: public CodeTextRegion
{
433 friend class MemRegionManager
;
439 BlockTextRegion(const BlockDecl
*bd
, CanQualType lTy
,
440 AnalysisContext
*ac
, const MemRegion
* sreg
)
441 : CodeTextRegion(sreg
, BlockTextRegionKind
), BD(bd
), AC(ac
), locTy(lTy
) {}
444 QualType
getLocationType() const {
448 const BlockDecl
*getDecl() const {
452 AnalysisContext
*getAnalysisContext() const { return AC
; }
454 virtual void dumpToStream(llvm::raw_ostream
& os
) const;
456 void Profile(llvm::FoldingSetNodeID
& ID
) const;
458 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const BlockDecl
*BD
,
459 CanQualType
, const AnalysisContext
*,
462 static bool classof(const MemRegion
* R
) {
463 return R
->getKind() == BlockTextRegionKind
;
467 /// BlockDataRegion - A region that represents a block instance.
468 /// Blocks are represented with two kinds of regions. BlockTextRegions
469 /// represent the "code", while BlockDataRegions represent instances of blocks,
470 /// which correspond to "code+data". The distinction is important, because
471 /// like a closure a block captures the values of externally referenced
473 class BlockDataRegion
: public SubRegion
{
474 friend class MemRegionManager
;
475 const BlockTextRegion
*BC
;
476 const LocationContext
*LC
; // Can be null */
477 void *ReferencedVars
;
479 BlockDataRegion(const BlockTextRegion
*bc
, const LocationContext
*lc
,
480 const MemRegion
*sreg
)
481 : SubRegion(sreg
, BlockDataRegionKind
), BC(bc
), LC(lc
), ReferencedVars(0) {}
484 const BlockTextRegion
*getCodeRegion() const { return BC
; }
486 const BlockDecl
*getDecl() const { return BC
->getDecl(); }
488 class referenced_vars_iterator
{
489 const MemRegion
* const *R
;
491 explicit referenced_vars_iterator(const MemRegion
* const *r
) : R(r
) {}
493 operator const MemRegion
* const *() const {
497 const VarRegion
* operator*() const {
498 return cast
<VarRegion
>(*R
);
501 bool operator==(const referenced_vars_iterator
&I
) const {
504 bool operator!=(const referenced_vars_iterator
&I
) const {
507 referenced_vars_iterator
& operator++() {
513 referenced_vars_iterator
referenced_vars_begin() const;
514 referenced_vars_iterator
referenced_vars_end() const;
516 virtual void dumpToStream(llvm::raw_ostream
& os
) const;
518 void Profile(llvm::FoldingSetNodeID
& ID
) const;
520 static void ProfileRegion(llvm::FoldingSetNodeID
&, const BlockTextRegion
*,
521 const LocationContext
*, const MemRegion
*);
523 static bool classof(const MemRegion
* R
) {
524 return R
->getKind() == BlockDataRegionKind
;
527 void LazyInitializeReferencedVars();
530 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region
531 /// clases, SymbolicRegion represents a region that serves as an alias for
532 /// either a real region, a NULL pointer, etc. It essentially is used to
533 /// map the concept of symbolic values into the domain of regions. Symbolic
534 /// regions do not need to be typed.
535 class SymbolicRegion
: public SubRegion
{
540 SymbolicRegion(const SymbolRef s
, const MemRegion
* sreg
)
541 : SubRegion(sreg
, SymbolicRegionKind
), sym(s
) {}
543 SymbolRef
getSymbol() const {
547 bool isBoundable() const { return true; }
549 DefinedOrUnknownSVal
getExtent(SValBuilder
&svalBuilder
) const;
551 void Profile(llvm::FoldingSetNodeID
& ID
) const;
553 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
,
555 const MemRegion
* superRegion
);
557 void dumpToStream(llvm::raw_ostream
& os
) const;
559 static bool classof(const MemRegion
* R
) {
560 return R
->getKind() == SymbolicRegionKind
;
564 /// StringRegion - Region associated with a StringLiteral.
565 class StringRegion
: public TypedRegion
{
566 friend class MemRegionManager
;
567 const StringLiteral
* Str
;
570 StringRegion(const StringLiteral
* str
, const MemRegion
* sreg
)
571 : TypedRegion(sreg
, StringRegionKind
), Str(str
) {}
573 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
,
574 const StringLiteral
* Str
,
575 const MemRegion
* superRegion
);
579 const StringLiteral
* getStringLiteral() const { return Str
; }
581 QualType
getValueType() const {
582 return Str
->getType();
585 DefinedOrUnknownSVal
getExtent(SValBuilder
&svalBuilder
) const;
587 bool isBoundable() const { return false; }
589 void Profile(llvm::FoldingSetNodeID
& ID
) const {
590 ProfileRegion(ID
, Str
, superRegion
);
593 void dumpToStream(llvm::raw_ostream
& os
) const;
595 static bool classof(const MemRegion
* R
) {
596 return R
->getKind() == StringRegionKind
;
600 /// CompoundLiteralRegion - A memory region representing a compound literal.
601 /// Compound literals are essentially temporaries that are stack allocated
602 /// or in the global constant pool.
603 class CompoundLiteralRegion
: public TypedRegion
{
605 friend class MemRegionManager
;
606 const CompoundLiteralExpr
* CL
;
608 CompoundLiteralRegion(const CompoundLiteralExpr
* cl
, const MemRegion
* sReg
)
609 : TypedRegion(sReg
, CompoundLiteralRegionKind
), CL(cl
) {}
611 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
,
612 const CompoundLiteralExpr
* CL
,
613 const MemRegion
* superRegion
);
615 QualType
getValueType() const {
616 return CL
->getType();
619 bool isBoundable() const { return !CL
->isFileScope(); }
621 void Profile(llvm::FoldingSetNodeID
& ID
) const;
623 void dumpToStream(llvm::raw_ostream
& os
) const;
625 const CompoundLiteralExpr
* getLiteralExpr() const { return CL
; }
627 static bool classof(const MemRegion
* R
) {
628 return R
->getKind() == CompoundLiteralRegionKind
;
632 class DeclRegion
: public TypedRegion
{
636 DeclRegion(const Decl
* d
, const MemRegion
* sReg
, Kind k
)
637 : TypedRegion(sReg
, k
), D(d
) {}
639 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const Decl
* D
,
640 const MemRegion
* superRegion
, Kind k
);
643 const Decl
* getDecl() const { return D
; }
644 void Profile(llvm::FoldingSetNodeID
& ID
) const;
646 DefinedOrUnknownSVal
getExtent(SValBuilder
&svalBuilder
) const;
648 static bool classof(const MemRegion
* R
) {
649 unsigned k
= R
->getKind();
650 return k
>= BEG_DECL_REGIONS
&& k
<= END_DECL_REGIONS
;
654 class VarRegion
: public DeclRegion
{
655 friend class MemRegionManager
;
657 // Constructors and private methods.
658 VarRegion(const VarDecl
* vd
, const MemRegion
* sReg
)
659 : DeclRegion(vd
, sReg
, VarRegionKind
) {}
661 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const VarDecl
* VD
,
662 const MemRegion
*superRegion
) {
663 DeclRegion::ProfileRegion(ID
, VD
, superRegion
, VarRegionKind
);
666 void Profile(llvm::FoldingSetNodeID
& ID
) const;
669 const VarDecl
*getDecl() const { return cast
<VarDecl
>(D
); }
671 const StackFrameContext
*getStackFrame() const;
673 QualType
getValueType() const {
674 // FIXME: We can cache this if needed.
675 return getDecl()->getType();
678 void dumpToStream(llvm::raw_ostream
& os
) const;
680 static bool classof(const MemRegion
* R
) {
681 return R
->getKind() == VarRegionKind
;
685 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
686 /// in a call to a C++ method. This region doesn't represent the object
687 /// referred to by 'this', but rather 'this' itself.
688 class CXXThisRegion
: public TypedRegion
{
689 friend class MemRegionManager
;
690 CXXThisRegion(const PointerType
*thisPointerTy
,
691 const MemRegion
*sReg
)
692 : TypedRegion(sReg
, CXXThisRegionKind
), ThisPointerTy(thisPointerTy
) {}
694 static void ProfileRegion(llvm::FoldingSetNodeID
&ID
,
695 const PointerType
*PT
,
696 const MemRegion
*sReg
);
698 void Profile(llvm::FoldingSetNodeID
&ID
) const;
701 QualType
getValueType() const {
702 return QualType(ThisPointerTy
, 0);
705 void dumpToStream(llvm::raw_ostream
& os
) const;
707 static bool classof(const MemRegion
* R
) {
708 return R
->getKind() == CXXThisRegionKind
;
712 const PointerType
*ThisPointerTy
;
715 class FieldRegion
: public DeclRegion
{
716 friend class MemRegionManager
;
718 FieldRegion(const FieldDecl
* fd
, const MemRegion
* sReg
)
719 : DeclRegion(fd
, sReg
, FieldRegionKind
) {}
723 void dumpToStream(llvm::raw_ostream
& os
) const;
725 const FieldDecl
* getDecl() const { return cast
<FieldDecl
>(D
); }
727 QualType
getValueType() const {
728 // FIXME: We can cache this if needed.
729 return getDecl()->getType();
732 DefinedOrUnknownSVal
getExtent(SValBuilder
&svalBuilder
) const;
734 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const FieldDecl
* FD
,
735 const MemRegion
* superRegion
) {
736 DeclRegion::ProfileRegion(ID
, FD
, superRegion
, FieldRegionKind
);
739 static bool classof(const MemRegion
* R
) {
740 return R
->getKind() == FieldRegionKind
;
744 class ObjCIvarRegion
: public DeclRegion
{
746 friend class MemRegionManager
;
748 ObjCIvarRegion(const ObjCIvarDecl
* ivd
, const MemRegion
* sReg
)
749 : DeclRegion(ivd
, sReg
, ObjCIvarRegionKind
) {}
751 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, const ObjCIvarDecl
* ivd
,
752 const MemRegion
* superRegion
) {
753 DeclRegion::ProfileRegion(ID
, ivd
, superRegion
, ObjCIvarRegionKind
);
757 const ObjCIvarDecl
* getDecl() const { return cast
<ObjCIvarDecl
>(D
); }
758 QualType
getValueType() const { return getDecl()->getType(); }
760 void dumpToStream(llvm::raw_ostream
& os
) const;
762 static bool classof(const MemRegion
* R
) {
763 return R
->getKind() == ObjCIvarRegionKind
;
766 //===----------------------------------------------------------------------===//
767 // Auxillary data classes for use with MemRegions.
768 //===----------------------------------------------------------------------===//
772 class RegionRawOffset
{
774 friend class ElementRegion
;
776 const MemRegion
*Region
;
779 RegionRawOffset(const MemRegion
* reg
, int64_t offset
= 0)
780 : Region(reg
), Offset(offset
) {}
783 // FIXME: Eventually support symbolic offsets.
784 int64_t getByteOffset() const { return Offset
; }
785 const MemRegion
*getRegion() const { return Region
; }
787 void dumpToStream(llvm::raw_ostream
& os
) const;
791 class ElementRegion
: public TypedRegion
{
792 friend class MemRegionManager
;
794 QualType ElementType
;
797 ElementRegion(QualType elementType
, NonLoc Idx
, const MemRegion
* sReg
)
798 : TypedRegion(sReg
, ElementRegionKind
),
799 ElementType(elementType
), Index(Idx
) {
800 assert((!isa
<nonloc::ConcreteInt
>(&Idx
) ||
801 cast
<nonloc::ConcreteInt
>(&Idx
)->getValue().isSigned()) &&
802 "The index must be signed");
805 static void ProfileRegion(llvm::FoldingSetNodeID
& ID
, QualType elementType
,
806 SVal Idx
, const MemRegion
* superRegion
);
810 NonLoc
getIndex() const { return Index
; }
812 QualType
getValueType() const {
816 QualType
getElementType() const {
819 /// Compute the offset within the array. The array might also be a subobject.
820 RegionRawOffset
getAsArrayOffset() const;
822 void dumpToStream(llvm::raw_ostream
& os
) const;
824 void Profile(llvm::FoldingSetNodeID
& ID
) const;
826 static bool classof(const MemRegion
* R
) {
827 return R
->getKind() == ElementRegionKind
;
831 // C++ temporary object associated with an expression.
832 class CXXTempObjectRegion
: public TypedRegion
{
833 friend class MemRegionManager
;
837 CXXTempObjectRegion(Expr
const *E
, MemRegion
const *sReg
)
838 : TypedRegion(sReg
, CXXTempObjectRegionKind
), Ex(E
) {}
840 static void ProfileRegion(llvm::FoldingSetNodeID
&ID
,
841 Expr
const *E
, const MemRegion
*sReg
);
844 QualType
getValueType() const {
845 return Ex
->getType();
848 void dumpToStream(llvm::raw_ostream
& os
) const;
850 void Profile(llvm::FoldingSetNodeID
&ID
) const;
852 static bool classof(const MemRegion
* R
) {
853 return R
->getKind() == CXXTempObjectRegionKind
;
857 // CXXBaseObjectRegion represents a base object within a C++ object. It is
858 // identified by the base class declaration and the region of its parent object.
859 class CXXBaseObjectRegion
: public TypedRegion
{
860 friend class MemRegionManager
;
862 const CXXRecordDecl
*decl
;
864 CXXBaseObjectRegion(const CXXRecordDecl
*d
, const MemRegion
*sReg
)
865 : TypedRegion(sReg
, CXXBaseObjectRegionKind
), decl(d
) {}
867 static void ProfileRegion(llvm::FoldingSetNodeID
&ID
,
868 const CXXRecordDecl
*decl
, const MemRegion
*sReg
);
871 QualType
getValueType() const;
873 void dumpToStream(llvm::raw_ostream
& os
) const;
875 void Profile(llvm::FoldingSetNodeID
&ID
) const;
877 static bool classof(const MemRegion
*region
) {
878 return region
->getKind() == CXXBaseObjectRegionKind
;
882 template<typename RegionTy
>
883 const RegionTy
* MemRegion::getAs() const {
884 if (const RegionTy
* RT
= dyn_cast
<RegionTy
>(this))
890 //===----------------------------------------------------------------------===//
891 // MemRegionManager - Factory object for creating regions.
892 //===----------------------------------------------------------------------===//
894 class MemRegionManager
{
896 llvm::BumpPtrAllocator
& A
;
897 llvm::FoldingSet
<MemRegion
> Regions
;
899 NonStaticGlobalSpaceRegion
*globals
;
901 llvm::DenseMap
<const StackFrameContext
*, StackLocalsSpaceRegion
*>
902 StackLocalsSpaceRegions
;
903 llvm::DenseMap
<const StackFrameContext
*, StackArgumentsSpaceRegion
*>
904 StackArgumentsSpaceRegions
;
905 llvm::DenseMap
<const CodeTextRegion
*, StaticGlobalSpaceRegion
*>
906 StaticsGlobalSpaceRegions
;
908 HeapSpaceRegion
*heap
;
909 UnknownSpaceRegion
*unknown
;
910 MemSpaceRegion
*code
;
913 MemRegionManager(ASTContext
&c
, llvm::BumpPtrAllocator
& a
)
914 : C(c
), A(a
), globals(0), heap(0), unknown(0), code(0) {}
918 ASTContext
&getContext() { return C
; }
920 llvm::BumpPtrAllocator
&getAllocator() { return A
; }
922 /// getStackLocalsRegion - Retrieve the memory region associated with the
923 /// specified stack frame.
924 const StackLocalsSpaceRegion
*
925 getStackLocalsRegion(const StackFrameContext
*STC
);
927 /// getStackArgumentsRegion - Retrieve the memory region associated with
928 /// function/method arguments of the specified stack frame.
929 const StackArgumentsSpaceRegion
*
930 getStackArgumentsRegion(const StackFrameContext
*STC
);
932 /// getGlobalsRegion - Retrieve the memory region associated with
933 /// global variables.
934 const GlobalsSpaceRegion
*getGlobalsRegion(const CodeTextRegion
*R
= 0);
936 /// getHeapRegion - Retrieve the memory region associated with the
938 const HeapSpaceRegion
*getHeapRegion();
940 /// getUnknownRegion - Retrieve the memory region associated with unknown
942 const MemSpaceRegion
*getUnknownRegion();
944 const MemSpaceRegion
*getCodeRegion();
946 /// getAllocaRegion - Retrieve a region associated with a call to alloca().
947 const AllocaRegion
*getAllocaRegion(const Expr
* Ex
, unsigned Cnt
,
948 const LocationContext
*LC
);
950 /// getCompoundLiteralRegion - Retrieve the region associated with a
951 /// given CompoundLiteral.
952 const CompoundLiteralRegion
*
953 getCompoundLiteralRegion(const CompoundLiteralExpr
* CL
,
954 const LocationContext
*LC
);
956 /// getCXXThisRegion - Retrieve the [artifical] region associated with the
957 /// parameter 'this'.
958 const CXXThisRegion
*getCXXThisRegion(QualType thisPointerTy
,
959 const LocationContext
*LC
);
961 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
962 const SymbolicRegion
* getSymbolicRegion(SymbolRef sym
);
964 const StringRegion
* getStringRegion(const StringLiteral
* Str
);
966 /// getVarRegion - Retrieve or create the memory region associated with
967 /// a specified VarDecl and LocationContext.
968 const VarRegion
* getVarRegion(const VarDecl
*D
, const LocationContext
*LC
);
970 /// getVarRegion - Retrieve or create the memory region associated with
971 /// a specified VarDecl and super region.
972 const VarRegion
* getVarRegion(const VarDecl
*D
, const MemRegion
*superR
);
974 /// getElementRegion - Retrieve the memory region associated with the
975 /// associated element type, index, and super region.
976 const ElementRegion
*getElementRegion(QualType elementType
, NonLoc Idx
,
977 const MemRegion
*superRegion
,
980 const ElementRegion
*getElementRegionWithSuper(const ElementRegion
*ER
,
981 const MemRegion
*superRegion
) {
982 return getElementRegion(ER
->getElementType(), ER
->getIndex(),
983 superRegion
, ER
->getContext());
986 /// getFieldRegion - Retrieve or create the memory region associated with
987 /// a specified FieldDecl. 'superRegion' corresponds to the containing
988 /// memory region (which typically represents the memory representing
989 /// a structure or class).
990 const FieldRegion
*getFieldRegion(const FieldDecl
* fd
,
991 const MemRegion
* superRegion
);
993 const FieldRegion
*getFieldRegionWithSuper(const FieldRegion
*FR
,
994 const MemRegion
*superRegion
) {
995 return getFieldRegion(FR
->getDecl(), superRegion
);
998 /// getObjCIvarRegion - Retrieve or create the memory region associated with
999 /// a specified Objective-c instance variable. 'superRegion' corresponds
1000 /// to the containing region (which typically represents the Objective-C
1002 const ObjCIvarRegion
*getObjCIvarRegion(const ObjCIvarDecl
* ivd
,
1003 const MemRegion
* superRegion
);
1005 const CXXTempObjectRegion
*getCXXTempObjectRegion(Expr
const *Ex
,
1006 LocationContext
const *LC
);
1008 const CXXBaseObjectRegion
*getCXXBaseObjectRegion(const CXXRecordDecl
*decl
,
1009 const MemRegion
*superRegion
);
1011 const FunctionTextRegion
*getFunctionTextRegion(const FunctionDecl
*FD
);
1012 const BlockTextRegion
*getBlockTextRegion(const BlockDecl
*BD
,
1014 AnalysisContext
*AC
);
1016 /// getBlockDataRegion - Get the memory region associated with an instance
1017 /// of a block. Unlike many other MemRegions, the LocationContext*
1018 /// argument is allowed to be NULL for cases where we have no known
1020 const BlockDataRegion
*getBlockDataRegion(const BlockTextRegion
*bc
,
1021 const LocationContext
*lc
= NULL
);
1023 bool isGlobalsRegion(const MemRegion
* R
) {
1025 return R
== globals
;
1029 template <typename RegionTy
, typename A1
>
1030 RegionTy
* getRegion(const A1 a1
);
1032 template <typename RegionTy
, typename A1
>
1033 RegionTy
* getSubRegion(const A1 a1
, const MemRegion
* superRegion
);
1035 template <typename RegionTy
, typename A1
, typename A2
>
1036 RegionTy
* getRegion(const A1 a1
, const A2 a2
);
1038 template <typename RegionTy
, typename A1
, typename A2
>
1039 RegionTy
* getSubRegion(const A1 a1
, const A2 a2
,
1040 const MemRegion
* superRegion
);
1042 template <typename RegionTy
, typename A1
, typename A2
, typename A3
>
1043 RegionTy
* getSubRegion(const A1 a1
, const A2 a2
, const A3 a3
,
1044 const MemRegion
* superRegion
);
1046 template <typename REG
>
1047 const REG
* LazyAllocate(REG
*& region
);
1049 template <typename REG
, typename ARG
>
1050 const REG
* LazyAllocate(REG
*& region
, ARG a
);
1053 //===----------------------------------------------------------------------===//
1054 // Out-of-line member definitions.
1055 //===----------------------------------------------------------------------===//
1057 inline ASTContext
& MemRegion::getContext() const {
1058 return getMemRegionManager()->getContext();
1061 } // end GR namespace
1063 } // end clang namespace
1065 //===----------------------------------------------------------------------===//
1066 // Pretty-printing regions.
1067 //===----------------------------------------------------------------------===//
1070 static inline raw_ostream
& operator<<(raw_ostream
& os
,
1071 const clang::GR::MemRegion
* R
) {
1072 R
->dumpToStream(os
);
1075 } // end llvm namespace