Enhance understanding of VarRegions referenced by a block whose declarations are outside the current stack frame.  Fixes <rdar://problem/7462324>.

llvm-svn: 91107
diff --git a/clang/lib/Analysis/MemRegion.cpp b/clang/lib/Analysis/MemRegion.cpp
index 3bf3e5b..da45c4d 100644
--- a/clang/lib/Analysis/MemRegion.cpp
+++ b/clang/lib/Analysis/MemRegion.cpp
@@ -381,13 +381,22 @@
 }
 
 const StackLocalsSpaceRegion*
-MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {  
-  return LazyAllocate(stackLocals, STC);
+MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
+  assert(STC);
+  if (STC == cachedStackLocalsFrame)
+    return cachedStackLocalsRegion;
+  cachedStackLocalsFrame = STC;
+  return LazyAllocate(cachedStackLocalsRegion, STC);
 }
 
 const StackArgumentsSpaceRegion *
 MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
-  return LazyAllocate(stackArguments, STC);
+  assert(STC);
+  if (STC == cachedStackArgumentsFrame)
+    return cachedStackArgumentsRegion;
+  
+  cachedStackArgumentsFrame = STC;
+  return LazyAllocate(cachedStackArgumentsRegion, STC);
 }
 
 const GlobalsSpaceRegion *MemRegionManager::getGlobalsRegion() {
@@ -418,15 +427,19 @@
                                                 const LocationContext *LC) {
   const MemRegion *sReg = 0;
 
-  if (D->hasLocalStorage()) {
+  if (D->hasLocalStorage()) {    
     // FIXME: Once we implement scope handling, we will need to properly lookup
     // 'D' to the proper LocationContext.
-    const StackFrameContext *STC = LC->getCurrentStackFrame();
+    const DeclContext *DC = D->getDeclContext();
+    const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
 
-    assert(STC);
-    sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
-           ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
-           : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
+    if (!STC)
+      sReg = getUnknownRegion();
+    else {
+      sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
+            ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
+            : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
+    }
   }
   else {
     sReg = getGlobalsRegion();