summaryrefslogtreecommitdiff
path: root/include/clang/Analysis/PathSensitive/MemRegion.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Analysis/PathSensitive/MemRegion.h')
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h496
1 files changed, 239 insertions, 257 deletions
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
index 5926229e517c..0e487691a891 100644
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/include/clang/Analysis/PathSensitive/MemRegion.h
@@ -31,10 +31,15 @@
namespace llvm { class raw_ostream; }
namespace clang {
-
+
class MemRegionManager;
-class MemSpaceRegion;
-
+class MemSpaceRegion;
+class LocationContext;
+
+//===----------------------------------------------------------------------===//
+// Base region classes.
+//===----------------------------------------------------------------------===//
+
/// MemRegion - The root abstract class for all memory regions.
class MemRegion : public llvm::FoldingSetNode {
public:
@@ -46,55 +51,57 @@ public:
CodeTextRegionKind,
CompoundLiteralRegionKind,
StringRegionKind, ElementRegionKind,
- TypedViewRegionKind,
// Decl Regions.
BEG_DECL_REGIONS,
VarRegionKind, FieldRegionKind,
ObjCIvarRegionKind, ObjCObjectRegionKind,
END_DECL_REGIONS,
- END_TYPED_REGIONS };
+ END_TYPED_REGIONS };
private:
const Kind kind;
-
+
protected:
MemRegion(Kind k) : kind(k) {}
virtual ~MemRegion();
- ASTContext &getContext() const;
public:
+ ASTContext &getContext() const;
+
virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
virtual MemRegionManager* getMemRegionManager() const = 0;
std::string getString() const;
-
+
const MemSpaceRegion *getMemorySpace() const;
-
+
+ const MemRegion *getBaseRegion() const;
+
bool hasStackStorage() const;
-
+
bool hasParametersStorage() const;
-
+
bool hasGlobalsStorage() const;
-
+
bool hasGlobalsOrParametersStorage() const;
-
+
bool hasHeapStorage() const;
-
+
bool hasHeapOrStackStorage() const;
- virtual void print(llvm::raw_ostream& os) const;
+ virtual void dumpToStream(llvm::raw_ostream& os) const;
+
+ void dump() const;
+
+ Kind getKind() const { return kind; }
- void printStdErr() const;
-
- Kind getKind() const { return kind; }
-
template<typename RegionTy> const RegionTy* getAs() const;
-
+
virtual bool isBoundable() const { return false; }
static bool classof(const MemRegion*) { return true; }
};
-
+
/// MemSpaceRegion - A memory region that represents and "memory space";
/// for example, the set of global variables, the stack frame, etc.
class MemSpaceRegion : public MemRegion {
@@ -105,7 +112,7 @@ protected:
MemSpaceRegion(MemRegionManager *mgr) : MemRegion(MemSpaceRegionKind),
Mgr(mgr) {}
-
+
MemRegionManager* getMemRegionManager() const {
return Mgr;
}
@@ -124,13 +131,13 @@ public:
/// are subclasses of SubRegion.
class SubRegion : public MemRegion {
protected:
- const MemRegion* superRegion;
+ const MemRegion* superRegion;
SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
public:
const MemRegion* getSuperRegion() const {
return superRegion;
}
-
+
MemRegionManager* getMemRegionManager() const;
bool isSubRegionOf(const MemRegion* R) const;
@@ -140,6 +147,32 @@ public:
}
};
+//===----------------------------------------------------------------------===//
+// Auxillary data classes for use with MemRegions.
+//===----------------------------------------------------------------------===//
+
+class ElementRegion;
+
+class RegionRawOffset : public std::pair<const MemRegion*, int64_t> {
+private:
+ friend class ElementRegion;
+
+ RegionRawOffset(const MemRegion* reg, int64_t offset = 0)
+ : std::pair<const MemRegion*, int64_t>(reg, offset) {}
+
+public:
+ // FIXME: Eventually support symbolic offsets.
+ int64_t getByteOffset() const { return second; }
+ const MemRegion *getRegion() const { return first; }
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+ void dump() const;
+};
+
+//===----------------------------------------------------------------------===//
+// MemRegion subclasses.
+//===----------------------------------------------------------------------===//
+
/// AllocaRegion - A region that represents an untyped blob of bytes created
/// by a call to 'alloca'.
class AllocaRegion : public SubRegion {
@@ -151,43 +184,45 @@ protected:
AllocaRegion(const Expr* ex, unsigned cnt, const MemRegion *superRegion)
: SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
-
+
public:
-
+
const Expr* getExpr() const { return Ex; }
-
+
+ bool isBoundable() const { return true; }
+
void Profile(llvm::FoldingSetNodeID& ID) const;
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex,
unsigned Cnt, const MemRegion *superRegion);
-
- void print(llvm::raw_ostream& os) const;
-
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
static bool classof(const MemRegion* R) {
return R->getKind() == AllocaRegionKind;
}
-};
-
+};
+
/// TypedRegion - An abstract class representing regions that are typed.
class TypedRegion : public SubRegion {
protected:
TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
-
+
public:
virtual QualType getValueType(ASTContext &C) const = 0;
-
+
virtual QualType getLocationType(ASTContext& C) const {
// FIXME: We can possibly optimize this later to cache this value.
return C.getPointerType(getValueType(C));
}
-
+
QualType getDesugaredValueType(ASTContext& C) const {
QualType T = getValueType(C);
- return T.getTypePtr() ? T->getDesugaredType() : T;
+ return T.getTypePtr() ? T.getDesugaredType() : T;
}
-
+
QualType getDesugaredLocationType(ASTContext& C) const {
- return getLocationType(C)->getDesugaredType();
+ return getLocationType(C).getDesugaredType();
}
bool isBoundable() const {
@@ -205,32 +240,12 @@ public:
/// is a function declared in the program. Symbolic function is a function
/// pointer that we don't know which function it points to.
class CodeTextRegion : public TypedRegion {
-public:
- enum CodeKind { Declared, Symbolic };
-
-private:
- // The function pointer kind that this CodeTextRegion represents.
- CodeKind codekind;
-
- // Data may be a SymbolRef or FunctionDecl*.
- const void* Data;
-
- // Cached function pointer type.
- QualType LocationType;
+ const FunctionDecl *FD;
public:
- CodeTextRegion(const FunctionDecl* fd, QualType t, const MemRegion* sreg)
- : TypedRegion(sreg, CodeTextRegionKind),
- codekind(Declared),
- Data(fd),
- LocationType(t) {}
-
- CodeTextRegion(SymbolRef sym, QualType t, const MemRegion* sreg)
- : TypedRegion(sreg, CodeTextRegionKind),
- codekind(Symbolic),
- Data(sym),
- LocationType(t) {}
+ CodeTextRegion(const FunctionDecl* fd, const MemRegion* sreg)
+ : TypedRegion(sreg, CodeTextRegionKind), FD(fd) {}
QualType getValueType(ASTContext &C) const {
// Do not get the object type of a CodeTextRegion.
@@ -239,30 +254,21 @@ public:
}
QualType getLocationType(ASTContext &C) const {
- return LocationType;
+ return C.getPointerType(FD->getType());
}
- bool isDeclared() const { return codekind == Declared; }
- bool isSymbolic() const { return codekind == Symbolic; }
-
- const FunctionDecl* getDecl() const {
- assert(codekind == Declared);
- return static_cast<const FunctionDecl*>(Data);
+ const FunctionDecl *getDecl() const {
+ return FD;
}
-
- SymbolRef getSymbol() const {
- assert(codekind == Symbolic);
- return const_cast<SymbolRef>(static_cast<const SymbolRef>(Data));
- }
-
+
bool isBoundable() const { return false; }
-
- virtual void print(llvm::raw_ostream& os) const;
+
+ virtual void dumpToStream(llvm::raw_ostream& os) const;
void Profile(llvm::FoldingSetNodeID& ID) const;
- static void ProfileRegion(llvm::FoldingSetNodeID& ID,
- const void* data, QualType t, const MemRegion*);
+ static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD,
+ const MemRegion*);
static bool classof(const MemRegion* R) {
return R->getKind() == CodeTextRegionKind;
@@ -279,25 +285,27 @@ protected:
const SymbolRef sym;
public:
- SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
+ SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
: SubRegion(sreg, SymbolicRegionKind), sym(s) {}
-
+
SymbolRef getSymbol() const {
return sym;
}
+ bool isBoundable() const { return true; }
+
void Profile(llvm::FoldingSetNodeID& ID) const;
static void ProfileRegion(llvm::FoldingSetNodeID& ID,
SymbolRef sym,
const MemRegion* superRegion);
-
- void print(llvm::raw_ostream& os) const;
-
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
static bool classof(const MemRegion* R) {
return R->getKind() == SymbolicRegionKind;
}
-};
+};
/// StringRegion - Region associated with a StringLiteral.
class StringRegion : public TypedRegion {
@@ -315,7 +323,7 @@ protected:
public:
const StringLiteral* getStringLiteral() const { return Str; }
-
+
QualType getValueType(ASTContext& C) const {
return Str->getType();
}
@@ -326,53 +334,13 @@ public:
ProfileRegion(ID, Str, superRegion);
}
- void print(llvm::raw_ostream& os) const;
+ void dumpToStream(llvm::raw_ostream& os) const;
static bool classof(const MemRegion* R) {
return R->getKind() == StringRegionKind;
}
};
-class TypedViewRegion : public TypedRegion {
- friend class MemRegionManager;
- QualType LValueType;
-
- TypedViewRegion(QualType lvalueType, const MemRegion* sreg)
- : TypedRegion(sreg, TypedViewRegionKind), LValueType(lvalueType) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
- const MemRegion* superRegion);
-
-public:
-
- void print(llvm::raw_ostream& os) const;
-
- QualType getLocationType(ASTContext&) const {
- return LValueType;
- }
-
- QualType getValueType(ASTContext&) const {
- const PointerType* PTy = LValueType->getAsPointerType();
- assert(PTy);
- return PTy->getPointeeType();
- }
-
- bool isBoundable() const {
- return isa<PointerType>(LValueType);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- ProfileRegion(ID, LValueType, superRegion);
- }
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == TypedViewRegionKind;
- }
-
- const MemRegion *removeViews() const;
-};
-
-
/// CompoundLiteralRegion - A memory region representing a compound literal.
/// Compound literals are essentially temporaries that are stack allocated
/// or in the global constant pool.
@@ -383,7 +351,7 @@ private:
CompoundLiteralRegion(const CompoundLiteralExpr* cl, const MemRegion* sReg)
: TypedRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
-
+
static void ProfileRegion(llvm::FoldingSetNodeID& ID,
const CompoundLiteralExpr* CL,
const MemRegion* superRegion);
@@ -395,11 +363,11 @@ public:
bool isBoundable() const { return !CL->isFileScope(); }
void Profile(llvm::FoldingSetNodeID& ID) const;
-
- void print(llvm::raw_ostream& os) const;
+
+ void dumpToStream(llvm::raw_ostream& os) const;
const CompoundLiteralExpr* getLiteralExpr() const { return CL; }
-
+
static bool classof(const MemRegion* R) {
return R->getKind() == CompoundLiteralRegionKind;
}
@@ -414,41 +382,51 @@ protected:
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
const MemRegion* superRegion, Kind k);
-
+
public:
const Decl* getDecl() const { return D; }
void Profile(llvm::FoldingSetNodeID& ID) const;
-
+
static bool classof(const MemRegion* R) {
unsigned k = R->getKind();
return k > BEG_DECL_REGIONS && k < END_DECL_REGIONS;
}
};
-
+
class VarRegion : public DeclRegion {
friend class MemRegionManager;
-
- VarRegion(const VarDecl* vd, const MemRegion* sReg)
- : DeclRegion(vd, sReg, VarRegionKind) {}
+
+ // Data.
+ const LocationContext *LC;
+
+ // Constructors and private methods.
+ VarRegion(const VarDecl* vd, const LocationContext *lC, const MemRegion* sReg)
+ : DeclRegion(vd, sReg, VarRegionKind), LC(lC) {}
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD,
- const MemRegion* superRegion) {
+ const LocationContext *LC,
+ const MemRegion *superRegion) {
DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
+ ID.AddPointer(LC);
}
-
-public:
- const VarDecl* getDecl() const { return cast<VarDecl>(D); }
-
- QualType getValueType(ASTContext& C) const {
+
+ void Profile(llvm::FoldingSetNodeID& ID) const;
+
+public:
+ const VarDecl *getDecl() const { return cast<VarDecl>(D); }
+
+ const LocationContext *getLocationContext() const { return LC; }
+
+ QualType getValueType(ASTContext& C) const {
// FIXME: We can cache this if needed.
return C.getCanonicalType(getDecl()->getType());
- }
-
- void print(llvm::raw_ostream& os) const;
-
+ }
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
static bool classof(const MemRegion* R) {
return R->getKind() == VarRegionKind;
- }
+ }
};
class FieldRegion : public DeclRegion {
@@ -458,57 +436,57 @@ class FieldRegion : public DeclRegion {
: DeclRegion(fd, sReg, FieldRegionKind) {}
public:
-
- void print(llvm::raw_ostream& os) const;
-
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
const FieldDecl* getDecl() const { return cast<FieldDecl>(D); }
-
- QualType getValueType(ASTContext& C) const {
+
+ QualType getValueType(ASTContext& C) const {
// FIXME: We can cache this if needed.
return C.getCanonicalType(getDecl()->getType());
- }
+ }
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl* FD,
const MemRegion* superRegion) {
DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
}
-
+
static bool classof(const MemRegion* R) {
return R->getKind() == FieldRegionKind;
}
};
-
+
class ObjCObjectRegion : public DeclRegion {
-
+
friend class MemRegionManager;
-
+
ObjCObjectRegion(const ObjCInterfaceDecl* ivd, const MemRegion* sReg)
: DeclRegion(ivd, sReg, ObjCObjectRegionKind) {}
-
+
static void ProfileRegion(llvm::FoldingSetNodeID& ID,
const ObjCInterfaceDecl* ivd,
const MemRegion* superRegion) {
DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCObjectRegionKind);
}
-
+
public:
const ObjCInterfaceDecl* getInterface() const {
return cast<ObjCInterfaceDecl>(D);
}
-
+
QualType getValueType(ASTContext& C) const {
return C.getObjCInterfaceType(getInterface());
}
-
+
static bool classof(const MemRegion* R) {
return R->getKind() == ObjCObjectRegionKind;
}
-};
-
+};
+
class ObjCIvarRegion : public DeclRegion {
-
+
friend class MemRegionManager;
-
+
ObjCIvarRegion(const ObjCIvarDecl* ivd, const MemRegion* sReg)
: DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
@@ -516,11 +494,13 @@ class ObjCIvarRegion : public DeclRegion {
const MemRegion* superRegion) {
DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
}
-
+
public:
const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); }
QualType getValueType(ASTContext&) const { return getDecl()->getType(); }
-
+
+ void dumpToStream(llvm::raw_ostream& os) const;
+
static bool classof(const MemRegion* R) {
return R->getKind() == ObjCIvarRegionKind;
}
@@ -539,7 +519,7 @@ class ElementRegion : public TypedRegion {
cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
"The index must be signed");
}
-
+
static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
SVal Idx, const MemRegion* superRegion);
@@ -550,12 +530,14 @@ public:
QualType getValueType(ASTContext&) const {
return ElementType;
}
-
+
QualType getElementType() const {
return ElementType;
}
-
- void print(llvm::raw_ostream& os) const;
+
+ RegionRawOffset getAsRawOffset() const;
+
+ void dumpToStream(llvm::raw_ostream& os) const;
void Profile(llvm::FoldingSetNodeID& ID) const;
@@ -563,25 +545,13 @@ public:
return R->getKind() == ElementRegionKind;
}
};
-
+
template<typename RegionTy>
const RegionTy* MemRegion::getAs() const {
- const MemRegion *R = this;
-
- do {
- if (const RegionTy* RT = dyn_cast<RegionTy>(R))
- return RT;
-
- if (const TypedViewRegion *TR = dyn_cast<TypedViewRegion>(R)) {
- R = TR->getSuperRegion();
- continue;
- }
-
- break;
- }
- while (R);
-
- return 0;
+ if (const RegionTy* RT = dyn_cast<RegionTy>(this))
+ return RT;
+
+ return NULL;
}
//===----------------------------------------------------------------------===//
@@ -592,7 +562,7 @@ class MemRegionManager {
ASTContext &C;
llvm::BumpPtrAllocator& A;
llvm::FoldingSet<MemRegion> Regions;
-
+
MemSpaceRegion *globals;
MemSpaceRegion *stack;
MemSpaceRegion *stackArguments;
@@ -604,11 +574,11 @@ public:
MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
: C(c), A(a), globals(0), stack(0), stackArguments(0), heap(0),
unknown(0), code(0) {}
-
+
~MemRegionManager() {}
-
+
ASTContext &getContext() { return C; }
-
+
/// getStackRegion - Retrieve the memory region associated with the
/// current stack frame.
MemSpaceRegion *getStackRegion();
@@ -616,11 +586,11 @@ public:
/// getStackArgumentsRegion - Retrieve the memory region associated with
/// function/method arguments of the current stack frame.
MemSpaceRegion *getStackArgumentsRegion();
-
+
/// getGlobalsRegion - Retrieve the memory region associated with
/// all global variables.
MemSpaceRegion *getGlobalsRegion();
-
+
/// getHeapRegion - Retrieve the memory region associated with the
/// generic "heap".
MemSpaceRegion *getHeapRegion();
@@ -633,69 +603,77 @@ public:
/// getAllocaRegion - Retrieve a region associated with a call to alloca().
AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt);
-
+
/// getCompoundLiteralRegion - Retrieve the region associated with a
/// given CompoundLiteral.
CompoundLiteralRegion*
- getCompoundLiteralRegion(const CompoundLiteralExpr* CL);
-
+ getCompoundLiteralRegion(const CompoundLiteralExpr* CL);
+
/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
SymbolicRegion* getSymbolicRegion(SymbolRef sym);
StringRegion* getStringRegion(const StringLiteral* Str);
/// getVarRegion - Retrieve or create the memory region associated with
- /// a specified VarDecl.
- VarRegion* getVarRegion(const VarDecl* vd);
-
+ /// a specified VarDecl and LocationContext.
+ VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
+
/// getElementRegion - Retrieve the memory region associated with the
/// associated element type, index, and super region.
- ElementRegion* getElementRegion(QualType elementType, SVal Idx,
- const MemRegion* superRegion,ASTContext &Ctx);
+ ElementRegion *getElementRegion(QualType elementType, SVal Idx,
+ const MemRegion *superRegion,
+ ASTContext &Ctx);
+
+ ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
+ const MemRegion *superRegion) {
+ return getElementRegion(ER->getElementType(), ER->getIndex(),
+ superRegion, ER->getContext());
+ }
/// getFieldRegion - Retrieve or create the memory region associated with
/// a specified FieldDecl. 'superRegion' corresponds to the containing
/// memory region (which typically represents the memory representing
/// a structure or class).
- FieldRegion* getFieldRegion(const FieldDecl* fd,
+ FieldRegion *getFieldRegion(const FieldDecl* fd,
const MemRegion* superRegion);
-
+
+ FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
+ const MemRegion *superRegion) {
+ return getFieldRegion(FR->getDecl(), superRegion);
+ }
+
/// getObjCObjectRegion - Retrieve or create the memory region associated with
/// the instance of a specified Objective-C class.
ObjCObjectRegion* getObjCObjectRegion(const ObjCInterfaceDecl* ID,
const MemRegion* superRegion);
-
+
/// getObjCIvarRegion - Retrieve or create the memory region associated with
/// a specified Objective-c instance variable. 'superRegion' corresponds
/// to the containing region (which typically represents the Objective-C
/// object).
- ObjCIvarRegion* getObjCIvarRegion(const ObjCIvarDecl* ivd,
+ ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd,
const MemRegion* superRegion);
- TypedViewRegion* getTypedViewRegion(QualType LValueType,
- const MemRegion* superRegion);
+ CodeTextRegion *getCodeTextRegion(const FunctionDecl *FD);
- CodeTextRegion* getCodeTextRegion(SymbolRef sym, QualType t);
- CodeTextRegion* getCodeTextRegion(const FunctionDecl* fd, QualType t);
-
template <typename RegionTy, typename A1>
RegionTy* getRegion(const A1 a1);
-
+
template <typename RegionTy, typename A1>
- RegionTy* getRegion(const A1 a1, const MemRegion* superRegion);
-
+ RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
+
template <typename RegionTy, typename A1, typename A2>
RegionTy* getRegion(const A1 a1, const A2 a2);
- bool isGlobalsRegion(const MemRegion* R) {
+ bool isGlobalsRegion(const MemRegion* R) {
assert(R);
- return R == globals;
+ return R == globals;
}
-
+
private:
MemSpaceRegion* LazyAllocate(MemSpaceRegion*& region);
};
-
+
//===----------------------------------------------------------------------===//
// Out-of-line member definitions.
//===----------------------------------------------------------------------===//
@@ -703,69 +681,69 @@ private:
inline ASTContext& MemRegion::getContext() const {
return getMemRegionManager()->getContext();
}
-
+
template<typename RegionTy> struct MemRegionManagerTrait;
-
+
template <typename RegionTy, typename A1>
RegionTy* MemRegionManager::getRegion(const A1 a1) {
const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
-
- llvm::FoldingSetNodeID ID;
- RegionTy::ProfileRegion(ID, a1, superRegion);
+
+ llvm::FoldingSetNodeID ID;
+ RegionTy::ProfileRegion(ID, a1, superRegion);
void* InsertPos;
RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
InsertPos));
-
+
if (!R) {
R = (RegionTy*) A.Allocate<RegionTy>();
new (R) RegionTy(a1, superRegion);
Regions.InsertNode(R, InsertPos);
}
-
+
return R;
}
template <typename RegionTy, typename A1>
-RegionTy* MemRegionManager::getRegion(const A1 a1, const MemRegion *superRegion)
-{
- llvm::FoldingSetNodeID ID;
- RegionTy::ProfileRegion(ID, a1, superRegion);
+RegionTy* MemRegionManager::getSubRegion(const A1 a1,
+ const MemRegion *superRegion) {
+ llvm::FoldingSetNodeID ID;
+ RegionTy::ProfileRegion(ID, a1, superRegion);
void* InsertPos;
RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
InsertPos));
-
+
if (!R) {
R = (RegionTy*) A.Allocate<RegionTy>();
new (R) RegionTy(a1, superRegion);
Regions.InsertNode(R, InsertPos);
}
-
+
return R;
}
-
+
template <typename RegionTy, typename A1, typename A2>
RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
-
+
const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
-
- llvm::FoldingSetNodeID ID;
- RegionTy::ProfileRegion(ID, a1, a2, superRegion);
+
+ llvm::FoldingSetNodeID ID;
+ RegionTy::ProfileRegion(ID, a1, a2, superRegion);
void* InsertPos;
RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
InsertPos));
-
+
if (!R) {
R = (RegionTy*) A.Allocate<RegionTy>();
new (R) RegionTy(a1, a2, superRegion);
Regions.InsertNode(R, InsertPos);
}
-
+
return R;
}
-
+
//===----------------------------------------------------------------------===//
// Traits for constructing regions.
//===----------------------------------------------------------------------===//
@@ -776,18 +754,18 @@ template <> struct MemRegionManagerTrait<AllocaRegion> {
const Expr *, unsigned) {
return MRMgr.getStackRegion();
}
-};
-
+};
+
template <> struct MemRegionManagerTrait<CompoundLiteralRegion> {
typedef MemRegion SuperRegionTy;
static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
const CompoundLiteralExpr *CL) {
-
- return CL->isFileScope() ? MRMgr.getGlobalsRegion()
+
+ return CL->isFileScope() ? MRMgr.getGlobalsRegion()
: MRMgr.getStackRegion();
}
};
-
+
template <> struct MemRegionManagerTrait<StringRegion> {
typedef MemSpaceRegion SuperRegionTy;
static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
@@ -795,20 +773,24 @@ template <> struct MemRegionManagerTrait<StringRegion> {
return MRMgr.getGlobalsRegion();
}
};
-
+
template <> struct MemRegionManagerTrait<VarRegion> {
typedef MemRegion SuperRegionTy;
- static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
- const VarDecl *d) {
- if (d->hasLocalStorage()) {
- return isa<ParmVarDecl>(d) || isa<ImplicitParamDecl>(d)
+ static const SuperRegionTy* getSuperRegion(MemRegionManager &MRMgr,
+ const VarDecl *D,
+ const LocationContext *LC) {
+
+ // FIXME: Make stack regions have a location context?
+
+ if (D->hasLocalStorage()) {
+ return isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
? MRMgr.getStackArgumentsRegion() : MRMgr.getStackRegion();
}
-
+
return MRMgr.getGlobalsRegion();
}
};
-
+
template <> struct MemRegionManagerTrait<SymbolicRegion> {
typedef MemRegion SuperRegionTy;
static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
@@ -820,7 +802,7 @@ template <> struct MemRegionManagerTrait<SymbolicRegion> {
template<> struct MemRegionManagerTrait<CodeTextRegion> {
typedef MemSpaceRegion SuperRegionTy;
static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
- const FunctionDecl*, QualType) {
+ const FunctionDecl*) {
return MRMgr.getCodeRegion();
}
static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
@@ -828,7 +810,7 @@ template<> struct MemRegionManagerTrait<CodeTextRegion> {
return MRMgr.getCodeRegion();
}
};
-
+
} // end clang namespace
//===----------------------------------------------------------------------===//
@@ -836,10 +818,10 @@ template<> struct MemRegionManagerTrait<CodeTextRegion> {
//===----------------------------------------------------------------------===//
namespace llvm {
-static inline raw_ostream& operator<<(raw_ostream& O,
- const clang::MemRegion* R) {
- R->print(O);
- return O;
+static inline raw_ostream& operator<<(raw_ostream& os,
+ const clang::MemRegion* R) {
+ R->dumpToStream(os);
+ return os;
}
} // end llvm namespace