diff options
Diffstat (limited to 'include/clang/Analysis/PathSensitive/MemRegion.h')
| -rw-r--r-- | include/clang/Analysis/PathSensitive/MemRegion.h | 496 |
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 |
