BEG_TYPED_REGIONS,
FunctionTextRegionKind,
BlockTextRegionKind,
+ BlockDataRegionKind,
CompoundLiteralRegionKind,
StringRegionKind, ElementRegionKind,
// Decl Regions.
/// BlockTextRegion - A region that represents code texts of blocks (closures).
+/// Blocks are represented with two kinds of regions. BlockTextRegions
+/// represent the "code", while BlockDataRegions represent instances of blocks,
+/// which correspond to "code+data". The distinction is important, because
+/// like a closure a block captures the values of externally referenced
+/// variables.
class BlockTextRegion : public CodeTextRegion {
const BlockDecl *BD;
CanQualType locTy;
return R->getKind() == BlockTextRegionKind;
}
};
+
+/// BlockDataRegion - A region that represents a block instance.
+/// Blocks are represented with two kinds of regions. BlockTextRegions
+/// represent the "code", while BlockDataRegions represent instances of blocks,
+/// which correspond to "code+data". The distinction is important, because
+/// like a closure a block captures the values of externally referenced
+/// variables.
+/// BlockDataRegion - A region that represents code texts of blocks (closures).
+class BlockDataRegion : public SubRegion {
+ const BlockTextRegion *BC;
+ const LocationContext *LC;
+public:
+ BlockDataRegion(const BlockTextRegion *bc,
+ const LocationContext *lc,
+ const MemRegion *sreg)
+ : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc) {}
+
+ const BlockTextRegion *getCodeRegion() const { return BC; }
+
+ virtual void dumpToStream(llvm::raw_ostream& os) const;
+
+ void Profile(llvm::FoldingSetNodeID& ID) const;
+
+ static void ProfileRegion(llvm::FoldingSetNodeID& ID,
+ const BlockTextRegion *BC,
+ const LocationContext *LC, const MemRegion *);
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == BlockDataRegionKind;
+ }
+};
/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
/// clases, SymbolicRegion represents a region that serves as an alias for
FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, CanQualType locTy);
-
+ BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
+ const LocationContext *lc);
template <typename RegionTy, typename A1>
RegionTy* getRegion(const A1 a1);
template <typename RegionTy, typename A1, typename A2>
RegionTy* getRegion(const A1 a1, const A2 a2);
+ template <typename RegionTy, typename A1, typename A2>
+ RegionTy* getSubRegion(const A1 a1, const A2 a2,
+ const MemRegion* superRegion);
+
bool isGlobalsRegion(const MemRegion* R) {
assert(R);
return R == globals;
return R;
}
+
+template <typename RegionTy, typename A1, typename A2>
+RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
+ const MemRegion *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.
BlockTextRegion::ProfileRegion(ID, BD, locTy, superRegion);
}
+void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+ const BlockTextRegion *BC,
+ const LocationContext *LC,
+ const MemRegion *) {
+ ID.AddInteger(MemRegion::BlockDataRegionKind);
+ ID.AddPointer(BC);
+ ID.AddPointer(LC);
+}
+
+void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+ BlockDataRegion::ProfileRegion(ID, BC, LC, NULL);
+}
+
//===----------------------------------------------------------------------===//
// Region pretty-printing.
//===----------------------------------------------------------------------===//
}
void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
- os << "block{" << (void*) this << '}';
+ os << "block_code{" << (void*) this << '}';
}
+void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
+ os << "block_data{" << BC << '}';
+}
+
+
void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
// FIXME: More elaborate pretty-printing.
os << "{ " << (void*) CL << " }";
return getRegion<VarRegion>(D, LC);
}
+BlockDataRegion *MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
+ const LocationContext *LC)
+{
+ // FIXME: Once we implement scope handling, we will need to properly lookup
+ // 'D' to the proper LocationContext. For now, just strip down to the
+ // StackFrame.
+ while (!isa<StackFrameContext>(LC))
+ LC = LC->getParent();
+
+ return getSubRegion<BlockDataRegion>(BC, LC, getStackRegion());
+}
+
CompoundLiteralRegion*
MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
return getRegion<CompoundLiteralRegion>(CL);