Refine MemRegions for blocks.  Add a new region called
'BlockDataRegion' to distinguish between the code associated with a
block (which is represented by 'BlockTextRegion') and an instance of a
block, which includes both code and data.  'BlockDataRegion' has an
associated LocationContext, which can be used to eventually model the
lifetime of a block object once LocationContexts can represent scopes
(and iterations around a loop, etc.).

llvm-svn: 89900
diff --git a/clang/lib/Analysis/MemRegion.cpp b/clang/lib/Analysis/MemRegion.cpp
index 8b4c7a6..430ec23 100644
--- a/clang/lib/Analysis/MemRegion.cpp
+++ b/clang/lib/Analysis/MemRegion.cpp
@@ -148,6 +148,19 @@
   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.
 //===----------------------------------------------------------------------===//
@@ -176,9 +189,14 @@
 }
 
 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 <<  " }";
@@ -274,6 +292,18 @@
   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);