Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 181573)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -10960,196 +10960,15 @@
   // capture.
 }
 
-/// \brief Capture the given variable in the captured region.
-static ExprResult captureInCapturedRegion(Sema &S, CapturedRegionScopeInfo *RSI,
-                                          VarDecl *Var, QualType FieldType,
-                                          QualType DeclRefType,
-                                          SourceLocation Loc,
-                                          bool RefersToEnclosingLocal) {
-  // The current implemention assumes that all variables are captured
-  // by references. Since there is no capture by copy, no expression evaluation
-  // will be needed.
-  //
-  RecordDecl *RD = RSI->TheRecordDecl;
 
-  FieldDecl *Field
-    = FieldDecl::Create(S.Context, RD, Loc, Loc, 0, FieldType,
-                        S.Context.getTrivialTypeSourceInfo(FieldType, Loc),
-                        0, false, ICIS_NoInit);
-  Field->setImplicit(true);
-  Field->setAccess(AS_private);
-  RD->addDecl(Field);
-
-  Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal,
-                                          DeclRefType, VK_LValue, Loc);
-  Var->setReferenced(true);
-  Var->setUsed(true);
-
-  return Ref;
-}
-
-/// \brief Capture the given variable in the given lambda expression.
-static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI,
-                                  VarDecl *Var, QualType FieldType, 
-                                  QualType DeclRefType,
-                                  SourceLocation Loc,
-                                  bool RefersToEnclosingLocal) {
-  CXXRecordDecl *Lambda = LSI->Lambda;
-
-  // Build the non-static data member.
-  FieldDecl *Field
-    = FieldDecl::Create(S.Context, Lambda, Loc, Loc, 0, FieldType,
-                        S.Context.getTrivialTypeSourceInfo(FieldType, Loc),
-                        0, false, ICIS_NoInit);
-  Field->setImplicit(true);
-  Field->setAccess(AS_private);
-  Lambda->addDecl(Field);
-
-  // C++11 [expr.prim.lambda]p21:
-  //   When the lambda-expression is evaluated, the entities that
-  //   are captured by copy are used to direct-initialize each
-  //   corresponding non-static data member of the resulting closure
-  //   object. (For array members, the array elements are
-  //   direct-initialized in increasing subscript order.) These
-  //   initializations are performed in the (unspecified) order in
-  //   which the non-static data members are declared.
-      
-  // Introduce a new evaluation context for the initialization, so
-  // that temporaries introduced as part of the capture are retained
-  // to be re-"exported" from the lambda expression itself.
-  EnterExpressionEvaluationContext scope(S, Sema::PotentiallyEvaluated);
-
-  // C++ [expr.prim.labda]p12:
-  //   An entity captured by a lambda-expression is odr-used (3.2) in
-  //   the scope containing the lambda-expression.
-  Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal, 
-                                          DeclRefType, VK_LValue, Loc);
-  Var->setReferenced(true);
-  Var->setUsed(true);
-
-  // When the field has array type, create index variables for each
-  // dimension of the array. We use these index variables to subscript
-  // the source array, and other clients (e.g., CodeGen) will perform
-  // the necessary iteration with these index variables.
-  SmallVector<VarDecl *, 4> IndexVariables;
-  QualType BaseType = FieldType;
-  QualType SizeType = S.Context.getSizeType();
-  LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
-  while (const ConstantArrayType *Array
-                        = S.Context.getAsConstantArrayType(BaseType)) {
-    // Create the iteration variable for this array index.
-    IdentifierInfo *IterationVarName = 0;
-    {
-      SmallString<8> Str;
-      llvm::raw_svector_ostream OS(Str);
-      OS << "__i" << IndexVariables.size();
-      IterationVarName = &S.Context.Idents.get(OS.str());
-    }
-    VarDecl *IterationVar
-      = VarDecl::Create(S.Context, S.CurContext, Loc, Loc,
-                        IterationVarName, SizeType,
-                        S.Context.getTrivialTypeSourceInfo(SizeType, Loc),
-                        SC_None);
-    IndexVariables.push_back(IterationVar);
-    LSI->ArrayIndexVars.push_back(IterationVar);
-    
-    // Create a reference to the iteration variable.
-    ExprResult IterationVarRef
-      = S.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc);
-    assert(!IterationVarRef.isInvalid() &&
-           "Reference to invented variable cannot fail!");
-    IterationVarRef = S.DefaultLvalueConversion(IterationVarRef.take());
-    assert(!IterationVarRef.isInvalid() &&
-           "Conversion of invented variable cannot fail!");
-    
-    // Subscript the array with this iteration variable.
-    ExprResult Subscript = S.CreateBuiltinArraySubscriptExpr(
-                             Ref, Loc, IterationVarRef.take(), Loc);
-    if (Subscript.isInvalid()) {
-      S.CleanupVarDeclMarking();
-      S.DiscardCleanupsInEvaluationContext();
-      return ExprError();
-    }
-
-    Ref = Subscript.take();
-    BaseType = Array->getElementType();
-  }
-
-  // Construct the entity that we will be initializing. For an array, this
-  // will be first element in the array, which may require several levels
-  // of array-subscript entities. 
-  SmallVector<InitializedEntity, 4> Entities;
-  Entities.reserve(1 + IndexVariables.size());
-  Entities.push_back(
-    InitializedEntity::InitializeLambdaCapture(Var, Field, Loc));
-  for (unsigned I = 0, N = IndexVariables.size(); I != N; ++I)
-    Entities.push_back(InitializedEntity::InitializeElement(S.Context,
-                                                            0,
-                                                            Entities.back()));
-
-  InitializationKind InitKind
-    = InitializationKind::CreateDirect(Loc, Loc, Loc);
-  InitializationSequence Init(S, Entities.back(), InitKind, Ref);
-  ExprResult Result(true);
-  if (!Init.Diagnose(S, Entities.back(), InitKind, Ref))
-    Result = Init.Perform(S, Entities.back(), InitKind, Ref);
-
-  // If this initialization requires any cleanups (e.g., due to a
-  // default argument to a copy constructor), note that for the
-  // lambda.
-  if (S.ExprNeedsCleanups)
-    LSI->ExprNeedsCleanups = true;
-
-  // Exit the expression evaluation context used for the capture.
-  S.CleanupVarDeclMarking();
-  S.DiscardCleanupsInEvaluationContext();
-  return Result;
-}
-
-bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, 
-                              TryCaptureKind Kind, SourceLocation EllipsisLoc,
-                              bool BuildAndDiagnose, 
+static bool isVariableAlreadyCaptured(CapturingScopeInfo *CSI, VarDecl *Var, 
+                                      bool &SubCapturesAreNested,
                               QualType &CaptureType,
                               QualType &DeclRefType) {
-  bool Nested = false;
-  
-  DeclContext *DC = CurContext;
-  if (Var->getDeclContext() == DC) return true;
-  if (!Var->hasLocalStorage()) return true;
-
-  bool HasBlocksAttr = Var->hasAttr<BlocksAttr>();
-
-  // Walk up the stack to determine whether we can capture the variable,
-  // performing the "simple" checks that don't depend on type. We stop when
-  // we've either hit the declared scope of the variable or find an existing
-  // capture of that variable.
-  CaptureType = Var->getType();
-  DeclRefType = CaptureType.getNonReferenceType();
-  bool Explicit = (Kind != TryCapture_Implicit);
-  unsigned FunctionScopesIndex = FunctionScopes.size() - 1;
-  do {
-    // Only block literals, captured statements, and lambda expressions can
-    // capture; other scopes don't work.
-    DeclContext *ParentDC;
-    if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC))
-      ParentDC = DC->getParent();
-    else if (isa<CXXMethodDecl>(DC) &&
-             cast<CXXMethodDecl>(DC)->getOverloadedOperator() == OO_Call &&
-             cast<CXXRecordDecl>(DC->getParent())->isLambda())
-      ParentDC = DC->getParent()->getParent();
-    else {
-      if (BuildAndDiagnose)
-        diagnoseUncapturableValueReference(*this, Loc, Var, DC);
-      return true;
-    }
-
-    CapturingScopeInfo *CSI =
-      cast<CapturingScopeInfo>(FunctionScopes[FunctionScopesIndex]);
-
     // Check whether we've already captured it.
     if (CSI->CaptureMap.count(Var)) {
       // If we found a capture, any subcaptures are nested.
-      Nested = true;
+    SubCapturesAreNested = true;
       
       // Retrieve the capture type for this variable.
       CaptureType = CSI->getCapture(Var).getCaptureType();
@@ -11161,9 +10980,36 @@
       if (Cap.isCopyCapture() &&
           !(isa<LambdaScopeInfo>(CSI) && cast<LambdaScopeInfo>(CSI)->Mutable))
         DeclRefType.addConst();
-      break;
+    return true;
     }
+  return false;
+}
 
+// Only block literals, captured statements, and lambda expressions can
+// capture; other scopes don't work.
+static DeclContext *getParentOfCapturingContextOrNull(DeclContext *DC, VarDecl *Var, 
+                                 SourceLocation Loc, 
+                                 const bool BuildAndDiagnose, Sema &S) {
+  if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC))
+    return DC->getParent();
+  else if (isa<CXXMethodDecl>(DC) &&
+                cast<CXXMethodDecl>(DC)->getOverloadedOperator() == OO_Call &&
+                cast<CXXRecordDecl>(DC->getParent())->isLambda())
+    return DC->getParent()->getParent();
+  else {
+    if (BuildAndDiagnose)
+       diagnoseUncapturableValueReference(S, Loc, Var, DC);
+  }
+  return 0;
+}
+
+// Certain capturing entities (lambdas, blocks etc.) are not allowed to capture 
+// certain types of variables (unnamed, variably modified types etc.)
+// so check for eligibility.
+static bool isVariableCapturable(CapturingScopeInfo *CSI, VarDecl *Var, 
+                                 SourceLocation Loc, 
+                                 const bool BuildAndDiagnose, Sema &S) {
+
     bool IsBlock = isa<BlockScopeInfo>(CSI);
     bool IsLambda = isa<LambdaScopeInfo>(CSI);
 
@@ -11173,23 +11019,23 @@
     // assuming that's the intent.
     if (IsLambda && !Var->getDeclName()) {
       if (BuildAndDiagnose) {
-        Diag(Loc, diag::err_lambda_capture_anonymous_var);
-        Diag(Var->getLocation(), diag::note_declared_at);
+      S.Diag(Loc, diag::err_lambda_capture_anonymous_var);
+      S.Diag(Var->getLocation(), diag::note_declared_at);
       }
-      return true;
+    return false;
     }
 
     // Prohibit variably-modified types; they're difficult to deal with.
     if (Var->getType()->isVariablyModifiedType()) {
       if (BuildAndDiagnose) {
         if (IsBlock)
-          Diag(Loc, diag::err_ref_vm_type);
+        S.Diag(Loc, diag::err_ref_vm_type);
         else
-          Diag(Loc, diag::err_lambda_capture_vm_type) << Var->getDeclName();
-        Diag(Var->getLocation(), diag::note_previous_decl) 
+        S.Diag(Loc, diag::err_lambda_capture_vm_type) << Var->getDeclName();
+      S.Diag(Var->getLocation(), diag::note_previous_decl) 
           << Var->getDeclName();
       }
-      return true;
+    return false;
     }
     // Prohibit structs with flexible array members too.
     // We cannot capture what is in the tail end of the struct.
@@ -11197,79 +11043,64 @@
       if (VTTy->getDecl()->hasFlexibleArrayMember()) {
         if (BuildAndDiagnose) {
           if (IsBlock)
-            Diag(Loc, diag::err_ref_flexarray_type);
+          S.Diag(Loc, diag::err_ref_flexarray_type);
           else
-            Diag(Loc, diag::err_lambda_capture_flexarray_type)
+          S.Diag(Loc, diag::err_lambda_capture_flexarray_type)
               << Var->getDeclName();
-          Diag(Var->getLocation(), diag::note_previous_decl)
+        S.Diag(Var->getLocation(), diag::note_previous_decl)
             << Var->getDeclName();
         }
-        return true;
+      return false;
       }
     }
+  const bool HasBlocksAttr = Var->hasAttr<BlocksAttr>();
     // Lambdas and captured statements are not allowed to capture __block
     // variables; they don't support the expected semantics.
     if (HasBlocksAttr && (IsLambda || isa<CapturedRegionScopeInfo>(CSI))) {
       if (BuildAndDiagnose) {
-        Diag(Loc, diag::err_capture_block_variable)
+      S.Diag(Loc, diag::err_capture_block_variable)
           << Var->getDeclName() << !IsLambda;
-        Diag(Var->getLocation(), diag::note_previous_decl) 
+      S.Diag(Var->getLocation(), diag::note_previous_decl)
           << Var->getDeclName();
       }
-      return true;
+    return false;
     }
 
-    if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None && !Explicit) {
-      // No capture-default
-      if (BuildAndDiagnose) {
-        Diag(Loc, diag::err_lambda_impcap) << Var->getDeclName();
-        Diag(Var->getLocation(), diag::note_previous_decl) 
-          << Var->getDeclName();
-        Diag(cast<LambdaScopeInfo>(CSI)->Lambda->getLocStart(),
-             diag::note_lambda_decl);
-      }
       return true;
     }
 
-    FunctionScopesIndex--;
-    DC = ParentDC;
-    Explicit = false;
-  } while (!Var->getDeclContext()->Equals(DC));
-
-  // Walk back down the scope stack, computing the type of the capture at
-  // each step, checking type-specific requirements, and adding captures if
-  // requested.
-  for (unsigned I = ++FunctionScopesIndex, N = FunctionScopes.size(); I != N; 
-       ++I) {
-    CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[I]);
-    
-    // Compute the type of the capture and of a reference to the capture within
-    // this scope.
-    if (isa<BlockScopeInfo>(CSI)) {
+// Returns true if the capture by block was successful.
+static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var, 
+                                 SourceLocation Loc, 
+                                 const bool BuildAndDiagnose, 
+                                 QualType &CaptureType,
+                                 QualType &DeclRefType, 
+                                 const bool Nested,
+                                 Sema &S) {
       Expr *CopyExpr = 0;
       bool ByRef = false;
       
       // Blocks are not allowed to capture arrays.
       if (CaptureType->isArrayType()) {
         if (BuildAndDiagnose) {
-          Diag(Loc, diag::err_ref_array_type);
-          Diag(Var->getLocation(), diag::note_previous_decl) 
+      S.Diag(Loc, diag::err_ref_array_type);
+      S.Diag(Var->getLocation(), diag::note_previous_decl) 
           << Var->getDeclName();
         }
-        return true;
+    return false;
       }
 
       // Forbid the block-capture of autoreleasing variables.
       if (CaptureType.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) {
         if (BuildAndDiagnose) {
-          Diag(Loc, diag::err_arc_autoreleasing_capture)
+      S.Diag(Loc, diag::err_arc_autoreleasing_capture)
             << /*block*/ 0;
-          Diag(Var->getLocation(), diag::note_previous_decl)
+      S.Diag(Var->getLocation(), diag::note_previous_decl)
             << Var->getDeclName();
         }
-        return true;
+    return false;
       }
-
+  const bool HasBlocksAttr = Var->hasAttr<BlocksAttr>();
       if (HasBlocksAttr || CaptureType->isReferenceType()) {
         // Block capture by reference does not change the capture or
         // declaration reference types.
@@ -11279,7 +11110,7 @@
         CaptureType = CaptureType.getNonReferenceType().withConst();
         DeclRefType = CaptureType;
                 
-        if (getLangOpts().CPlusPlus && BuildAndDiagnose) {
+    if (S.getLangOpts().CPlusPlus && BuildAndDiagnose) {
           if (const RecordType *Record = DeclRefType->getAs<RecordType>()) {
             // The capture logic needs the destructor, so make sure we mark it.
             // Usually this is unnecessary because most local variables have
@@ -11287,24 +11118,24 @@
             // an exception because it's technically only the call site that
             // actually requires the destructor.
             if (isa<ParmVarDecl>(Var))
-              FinalizeVarWithDestructor(Var, Record);
+          S.FinalizeVarWithDestructor(Var, Record);
 
             // Enter a new evaluation context to insulate the copy
             // full-expression.
-            EnterExpressionEvaluationContext scope(*this, PotentiallyEvaluated);
+        EnterExpressionEvaluationContext scope(S, S.PotentiallyEvaluated);
 
             // According to the blocks spec, the capture of a variable from
             // the stack requires a const copy constructor.  This is not true
             // of the copy/move done to move a __block variable to the heap.
-            Expr *DeclRef = new (Context) DeclRefExpr(Var, Nested,
+        Expr *DeclRef = new (S.Context) DeclRefExpr(Var, Nested,
                                                       DeclRefType.withConst(), 
                                                       VK_LValue, Loc);
             
             ExprResult Result
-              = PerformCopyInitialization(
+          = S.PerformCopyInitialization(
                   InitializedEntity::InitializeBlock(Var->getLocation(),
                                                      CaptureType, false),
-                  Loc, Owned(DeclRef));
+              Loc, S.Owned(DeclRef));
             
             // Build a full-expression copy expression if initialization
             // succeeded and used a non-trivial constructor.  Recover from
@@ -11312,7 +11143,7 @@
             if (!Result.isInvalid() &&
                 !cast<CXXConstructExpr>(Result.get())->getConstructor()
                    ->isTrivial()) {
-              Result = MaybeCreateExprWithCleanups(Result);
+          Result = S.MaybeCreateExprWithCleanups(Result);
               CopyExpr = Result.take();
             }
           }
@@ -11321,41 +11152,202 @@
 
       // Actually capture the variable.
       if (BuildAndDiagnose)
-        CSI->addCapture(Var, HasBlocksAttr, ByRef, Nested, Loc, 
+    BSI->addCapture(Var, HasBlocksAttr, ByRef, Nested, Loc, 
                         SourceLocation(), CaptureType, CopyExpr);
-      Nested = true;
-      continue;
+
+  return true;
+
     }
 
-    if (CapturedRegionScopeInfo *RSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) {
+
+
+
+/// \brief Capture the given variable in the captured region.
+static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI,
+                                    VarDecl *Var, 
+                                    SourceLocation Loc, 
+                                    const bool BuildAndDiagnose, 
+                                    QualType &CaptureType,
+                                    QualType &DeclRefType, 
+                                    const bool RefersToEnclosingLocal,
+                                    Sema &S) {
+  
       // By default, capture variables by reference.
       bool ByRef = true;
       // Using an LValue reference type is consistent with Lambdas (see below).
-      CaptureType = Context.getLValueReferenceType(DeclRefType);
+  CaptureType = S.Context.getLValueReferenceType(DeclRefType);
 
       Expr *CopyExpr = 0;
       if (BuildAndDiagnose) {
-        ExprResult Result = captureInCapturedRegion(*this, RSI, Var,
-                                                    CaptureType, DeclRefType,
-                                                    Loc, Nested);
-        if (!Result.isInvalid())
-          CopyExpr = Result.take();
+    // The current implementation assumes that all variables are captured
+    // by references. Since there is no capture by copy, no expression evaluation
+    // will be needed.
+    //
+    RecordDecl *RD = RSI->TheRecordDecl;
+
+    FieldDecl *Field
+      = FieldDecl::Create(S.Context, RD, Loc, Loc, 0, CaptureType,
+                          S.Context.getTrivialTypeSourceInfo(CaptureType, Loc),
+                          0, false, ICIS_NoInit);
+    Field->setImplicit(true);
+    Field->setAccess(AS_private);
+    RD->addDecl(Field);
+
+    CopyExpr = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal,
+                                            DeclRefType, VK_LValue, Loc);
+    Var->setReferenced(true);
+    Var->setUsed(true);
       }
 
       // Actually capture the variable.
       if (BuildAndDiagnose)
-        CSI->addCapture(Var, /*isBlock*/false, ByRef, Nested, Loc,
+    RSI->addCapture(Var, /*isBlock*/false, ByRef, RefersToEnclosingLocal, Loc,
                         SourceLocation(), CaptureType, CopyExpr);
-      Nested = true;
-      continue;
+  
+  
+  return true;
     }
 
-    LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(CSI);
     
+/// \brief Create a field within the lambda class for the variable
+///  being captured.  Handle Array captures.  
+static ExprResult addAsFieldToClosureType(Sema &S, 
+                                  LambdaScopeInfo *LSI,
+                                  VarDecl *Var, QualType FieldType, 
+                                  QualType DeclRefType,
+                                  SourceLocation Loc,
+                                  bool RefersToEnclosingLocal) {
+  CXXRecordDecl *Lambda = LSI->Lambda;
+
+  // Build the non-static data member.
+  FieldDecl *Field
+    = FieldDecl::Create(S.Context, Lambda, Loc, Loc, 0, FieldType,
+                        S.Context.getTrivialTypeSourceInfo(FieldType, Loc),
+                        0, false, ICIS_NoInit);
+  Field->setImplicit(true);
+  Field->setAccess(AS_private);
+  Lambda->addDecl(Field);
+
+  // C++11 [expr.prim.lambda]p21:
+  //   When the lambda-expression is evaluated, the entities that
+  //   are captured by copy are used to direct-initialize each
+  //   corresponding non-static data member of the resulting closure
+  //   object. (For array members, the array elements are
+  //   direct-initialized in increasing subscript order.) These
+  //   initializations are performed in the (unspecified) order in
+  //   which the non-static data members are declared.
+      
+  // Introduce a new evaluation context for the initialization, so
+  // that temporaries introduced as part of the capture are retained
+  // to be re-"exported" from the lambda expression itself.
+  EnterExpressionEvaluationContext scope(S, Sema::PotentiallyEvaluated);
+
+  // C++ [expr.prim.labda]p12:
+  //   An entity captured by a lambda-expression is odr-used (3.2) in
+  //   the scope containing the lambda-expression.
+  Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal, 
+                                          DeclRefType, VK_LValue, Loc);
+  Var->setReferenced(true);
+  Var->setUsed(true);
+
+  // When the field has array type, create index variables for each
+  // dimension of the array. We use these index variables to subscript
+  // the source array, and other clients (e.g., CodeGen) will perform
+  // the necessary iteration with these index variables.
+  SmallVector<VarDecl *, 4> IndexVariables;
+  QualType BaseType = FieldType;
+  QualType SizeType = S.Context.getSizeType();
+  LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
+  while (const ConstantArrayType *Array
+                        = S.Context.getAsConstantArrayType(BaseType)) {
+    // Create the iteration variable for this array index.
+    IdentifierInfo *IterationVarName = 0;
+    {
+      SmallString<8> Str;
+      llvm::raw_svector_ostream OS(Str);
+      OS << "__i" << IndexVariables.size();
+      IterationVarName = &S.Context.Idents.get(OS.str());
+    }
+    VarDecl *IterationVar
+      = VarDecl::Create(S.Context, S.CurContext, Loc, Loc,
+                        IterationVarName, SizeType,
+                        S.Context.getTrivialTypeSourceInfo(SizeType, Loc),
+                        SC_None);
+    IndexVariables.push_back(IterationVar);
+    LSI->ArrayIndexVars.push_back(IterationVar);
+    
+    // Create a reference to the iteration variable.
+    ExprResult IterationVarRef
+      = S.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc);
+    assert(!IterationVarRef.isInvalid() &&
+           "Reference to invented variable cannot fail!");
+    IterationVarRef = S.DefaultLvalueConversion(IterationVarRef.take());
+    assert(!IterationVarRef.isInvalid() &&
+           "Conversion of invented variable cannot fail!");
+    
+    // Subscript the array with this iteration variable.
+    ExprResult Subscript = S.CreateBuiltinArraySubscriptExpr(
+                             Ref, Loc, IterationVarRef.take(), Loc);
+    if (Subscript.isInvalid()) {
+      S.CleanupVarDeclMarking();
+      S.DiscardCleanupsInEvaluationContext();
+      return ExprError();
+    }
+
+    Ref = Subscript.take();
+    BaseType = Array->getElementType();
+  }
+
+  // Construct the entity that we will be initializing. For an array, this
+  // will be first element in the array, which may require several levels
+  // of array-subscript entities. 
+  SmallVector<InitializedEntity, 4> Entities;
+  Entities.reserve(1 + IndexVariables.size());
+  Entities.push_back(
+    InitializedEntity::InitializeLambdaCapture(Var, Field, Loc));
+  for (unsigned I = 0, N = IndexVariables.size(); I != N; ++I)
+    Entities.push_back(InitializedEntity::InitializeElement(S.Context,
+                                                            0,
+                                                            Entities.back()));
+
+  InitializationKind InitKind
+    = InitializationKind::CreateDirect(Loc, Loc, Loc);
+  InitializationSequence Init(S, Entities.back(), InitKind, Ref);
+  ExprResult Result(true);
+  if (!Init.Diagnose(S, Entities.back(), InitKind, Ref))
+    Result = Init.Perform(S, Entities.back(), InitKind, Ref);
+
+  // If this initialization requires any cleanups (e.g., due to a
+  // default argument to a copy constructor), note that for the
+  // lambda.
+  if (S.ExprNeedsCleanups)
+    LSI->ExprNeedsCleanups = true;
+
+  // Exit the expression evaluation context used for the capture.
+  S.CleanupVarDeclMarking();
+  S.DiscardCleanupsInEvaluationContext();
+  return Result;
+}
+
+
+
+/// \brief Capture the given variable in the lambda.
+static bool captureInLambda(LambdaScopeInfo *LSI,
+                            VarDecl *Var, 
+                            SourceLocation Loc, 
+                            const bool BuildAndDiagnose, 
+                            QualType &CaptureType,
+                            QualType &DeclRefType, 
+                            const bool RefersToEnclosingLocal,
+                            const Sema::TryCaptureKind Kind, 
+                            SourceLocation EllipsisLoc,
+                            const bool IsCurrentTopScope,
+                            Sema &S) {
+
     // Determine whether we are capturing by reference or by value.
     bool ByRef = false;
-    if (I == N - 1 && Kind != TryCapture_Implicit) {
-      ByRef = (Kind == TryCapture_ExplicitByRef);
+  if (IsCurrentTopScope && Kind != Sema::TryCapture_Implicit) {
+    ByRef = (Kind == Sema::TryCapture_ExplicitByRef);
     } else {
       ByRef = (LSI->ImpCaptureStyle == LambdaScopeInfo::ImpCap_LambdaByref);
     }
@@ -11374,7 +11366,7 @@
       // to do the former, while EDG does the latter. Core issue 1249 will 
       // clarify, but for now we follow GCC because it's a more permissive and
       // easily defensible position.
-      CaptureType = Context.getLValueReferenceType(DeclRefType);
+    CaptureType = S.Context.getLValueReferenceType(DeclRefType);
     } else {
       // C++11 [expr.prim.lambda]p14:
       //   For each entity captured by copy, an unnamed non-static
@@ -11394,20 +11386,20 @@
       // Forbid the lambda copy-capture of autoreleasing variables.
       if (CaptureType.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) {
         if (BuildAndDiagnose) {
-          Diag(Loc, diag::err_arc_autoreleasing_capture) << /*lambda*/ 1;
-          Diag(Var->getLocation(), diag::note_previous_decl)
+        S.Diag(Loc, diag::err_arc_autoreleasing_capture) << /*lambda*/ 1;
+        S.Diag(Var->getLocation(), diag::note_previous_decl)
             << Var->getDeclName();
         }
-        return true;
+      return false;
       }
     }
 
     // Capture this variable in the lambda.
     Expr *CopyExpr = 0;
     if (BuildAndDiagnose) {
-      ExprResult Result = captureInLambda(*this, LSI, Var, CaptureType,
-                                          DeclRefType, Loc,
-                                          Nested);
+    ExprResult Result = addAsFieldToClosureType(S, LSI, Var, 
+                                        CaptureType, DeclRefType, Loc,
+                                        RefersToEnclosingLocal);
       if (!Result.isInvalid())
         CopyExpr = Result.take();
     }
@@ -11428,10 +11420,105 @@
     
     // Add the capture.
     if (BuildAndDiagnose)
-      CSI->addCapture(Var, /*IsBlock=*/false, ByRef, Nested, Loc,
-                      EllipsisLoc, CaptureType, CopyExpr);
+    LSI->addCapture(Var, /*IsBlock=*/false, ByRef, RefersToEnclosingLocal, 
+                    Loc, EllipsisLoc, CaptureType, CopyExpr);
+      
+  return true;
+}
+
+
+
+
+bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, 
+                              TryCaptureKind Kind, SourceLocation EllipsisLoc,
+                              bool BuildAndDiagnose, 
+                              QualType &CaptureType,
+                              QualType &DeclRefType) {
+  bool Nested = false;
+  
+  DeclContext *DC = CurContext;
+  // If the variable is declared in the current context, there is 
+  // no need to capture it.
+  if (Var->getDeclContext() == DC) return true;
+  // If the variable is not a local, no need to capture.
+  if (!Var->hasLocalStorage()) return true;
+
+  bool HasBlocksAttr = Var->hasAttr<BlocksAttr>();
+
+  // Walk up the stack to determine whether we can capture the variable,
+  // performing the "simple" checks that don't depend on type. We stop when
+  // we've either hit the declared scope of the variable or find an existing
+  // capture of that variable.
+  CaptureType = Var->getType();
+  DeclRefType = CaptureType.getNonReferenceType();
+  bool Explicit = (Kind != TryCapture_Implicit);
+  unsigned FunctionScopesIndex = FunctionScopes.size() - 1;
+  do {
+    // Only block literals, captured statements, and lambda expressions can
+    // capture; other scopes don't work.
+    DeclContext *ParentDC = getParentOfCapturingContextOrNull(DC, Var, Loc, 
+                                                     BuildAndDiagnose, *this);
+    if (!ParentDC) return true;
+    
+    CapturingScopeInfo *CSI =
+      cast<CapturingScopeInfo>(FunctionScopes[FunctionScopesIndex]);
+
+    // Check whether we've already captured it.
+    if (isVariableAlreadyCaptured(CSI, Var, Nested, 
+                                  CaptureType, DeclRefType)) 
+      break;
+
+    // Certain capturing entities (lambdas, blocks etc.) are not allowed to capture 
+    // certain types of variables (unnamed, variably modified types etc.)
+    // so check for eligibility.
+    if (!isVariableCapturable(CSI, Var, Loc, BuildAndDiagnose, *this))
+       return true;    
+    
+    if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None && !Explicit) {
+      // No capture-default
+      if (BuildAndDiagnose) {
+        Diag(Loc, diag::err_lambda_impcap) << Var->getDeclName();
+        Diag(Var->getLocation(), diag::note_previous_decl) 
+          << Var->getDeclName();
+        Diag(cast<LambdaScopeInfo>(CSI)->Lambda->getLocStart(),
+             diag::note_lambda_decl);
+      }
+      return true;
+    }
+
+    FunctionScopesIndex--;
+    DC = ParentDC;
+    Explicit = false;
+  } while (!Var->getDeclContext()->Equals(DC));
+
+  // Walk back down the scope stack, computing the type of the capture at
+  // each step, checking type-specific requirements, and adding captures if
+  // requested.
+  for (unsigned I = ++FunctionScopesIndex, N = FunctionScopes.size(); I != N; 
+       ++I) {
+    CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[I]);
+    
+    if (BlockScopeInfo *BSI = dyn_cast<BlockScopeInfo>(CSI)) {
+      if (!captureInBlock(BSI, Var, Loc, BuildAndDiagnose, CaptureType, 
+                          DeclRefType, Nested, *this))
+        return true;
     Nested = true;
   }
+    else if (CapturedRegionScopeInfo *RSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) {
+      if (!captureInCapturedRegion(RSI, Var, Loc, BuildAndDiagnose, CaptureType, 
+                                   DeclRefType, Nested, *this))
+        return true;
+      Nested = true;
+    }
+    else {
+      LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(CSI);
+      if (!captureInLambda(LSI, Var, Loc, BuildAndDiagnose, CaptureType, 
+                                   DeclRefType, Nested, Kind, EllipsisLoc, 
+                                   /*IsCurrentScopeOnStack*/I == N - 1, *this))
+        return true;
+      Nested = true;
+    }
+  }
 
   return false;
 }
