Merging r196454:
------------------------------------------------------------------------
r196454 | faisalv | 2013-12-04 17:40:41 -0800 (Wed, 04 Dec 2013) | 43 lines

Fix init-captures for generic lambdas.

For an init capture, process the initialization expression
right away.  For lambda init-captures such as the following:
const int x = 10;
 auto L = [i = x+1](int a) {
   return [j = x+2,
          &k = x](char b) { };
 };
keep in mind that each lambda init-capture has to have:
 - its initialization expression executed in the context
   of the enclosing/parent decl-context.
 - but the variable itself has to be 'injected' into the
   decl-context of its lambda's call-operator (which has
   not yet been created).
Each init-expression is a full-expression that has to get
Sema-analyzed (for capturing etc.) before its lambda's
call-operator's decl-context, scope & scopeinfo are pushed on their
respective stacks.  Thus if any variable is odr-used in the init-capture
it will correctly get captured in the enclosing lambda, if one exists.
The init-variables above are created later once the lambdascope and
call-operators decl-context is pushed onto its respective stack.

Since the lambda init-capture's initializer expression occurs in the
context of the enclosing function or lambda, therefore we can not wait
till a lambda scope has been pushed on before deciding whether the
variable needs to be captured.  We also need to process all
lvalue-to-rvalue conversions and discarded-value conversions,
so that we can avoid capturing certain constant variables.
For e.g.,
 void test() {
  const int x = 10;
  auto L = [&z = x](char a) { <-- don't capture by the current lambda
    return [y = x](int i) { <-- don't capture by enclosing lambda
         return y;
    }
  };
If x was not const, the second use would require 'L' to capture, and
that would be an error.
Make sure TranformLambdaExpr is also aware of this.

Patch approved by Richard (Thanks!!) 
http://llvm-reviews.chandlerc.com/D2092
------------------------------------------------------------------------


git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_34@196470 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 6db37ec..a7d5b65 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -609,12 +609,20 @@
   }
 }
 
-VarDecl *Sema::checkInitCapture(SourceLocation Loc, bool ByRef,
-                                IdentifierInfo *Id, Expr *Init) {
-  // C++1y [expr.prim.lambda]p11:
-  //   An init-capture behaves as if it declares and explicitly captures
-  //   a variable of the form
-  //     "auto init-capture;"
+QualType Sema::performLambdaInitCaptureInitialization(SourceLocation Loc,
+                                                      bool ByRef,
+                                                      IdentifierInfo *Id,
+                                                      Expr *&Init) {
+
+  // We do not need to distinguish between direct-list-initialization
+  // and copy-list-initialization here, because we will always deduce
+  // std::initializer_list<T>, and direct- and copy-list-initialization
+  // always behave the same for such a type.
+  // FIXME: We should model whether an '=' was present.
+  const bool IsDirectInit = isa<ParenListExpr>(Init) || isa<InitListExpr>(Init);
+
+  // Create an 'auto' or 'auto&' TypeSourceInfo that we can use to
+  // deduce against.
   QualType DeductType = Context.getAutoDeductType();
   TypeLocBuilder TLB;
   TLB.pushTypeSpec(DeductType).setNameLoc(Loc);
@@ -625,24 +633,100 @@
   }
   TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType);
 
+  // Are we a non-list direct initialization?
+  ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
+
+  Expr *DeduceInit = Init;
+  // Initializer could be a C++ direct-initializer. Deduction only works if it
+  // contains exactly one expression.
+  if (CXXDirectInit) {
+    if (CXXDirectInit->getNumExprs() == 0) {
+      Diag(CXXDirectInit->getLocStart(), diag::err_init_capture_no_expression)
+          << DeclarationName(Id) << TSI->getType() << Loc;
+      return QualType();
+    } else if (CXXDirectInit->getNumExprs() > 1) {
+      Diag(CXXDirectInit->getExpr(1)->getLocStart(),
+           diag::err_init_capture_multiple_expressions)
+          << DeclarationName(Id) << TSI->getType() << Loc;
+      return QualType();
+    } else {
+      DeduceInit = CXXDirectInit->getExpr(0);
+    }
+  }
+
+  // Now deduce against the initialization expression and store the deduced
+  // type below.
+  QualType DeducedType;
+  if (DeduceAutoType(TSI, DeduceInit, DeducedType) == DAR_Failed) {
+    if (isa<InitListExpr>(Init))
+      Diag(Loc, diag::err_init_capture_deduction_failure_from_init_list)
+          << DeclarationName(Id)
+          << (DeduceInit->getType().isNull() ? TSI->getType()
+                                             : DeduceInit->getType())
+          << DeduceInit->getSourceRange();
+    else
+      Diag(Loc, diag::err_init_capture_deduction_failure)
+          << DeclarationName(Id) << TSI->getType()
+          << (DeduceInit->getType().isNull() ? TSI->getType()
+                                             : DeduceInit->getType())
+          << DeduceInit->getSourceRange();
+  }
+  if (DeducedType.isNull())
+    return QualType();
+
+  // Perform initialization analysis and ensure any implicit conversions
+  // (such as lvalue-to-rvalue) are enforced.
+  InitializedEntity Entity =
+      InitializedEntity::InitializeLambdaCapture(Id, DeducedType, Loc);
+  InitializationKind Kind =
+      IsDirectInit
+          ? (CXXDirectInit ? InitializationKind::CreateDirect(
+                                 Loc, Init->getLocStart(), Init->getLocEnd())
+                           : InitializationKind::CreateDirectList(Loc))
+          : InitializationKind::CreateCopy(Loc, Init->getLocStart());
+
+  MultiExprArg Args = Init;
+  if (CXXDirectInit)
+    Args =
+        MultiExprArg(CXXDirectInit->getExprs(), CXXDirectInit->getNumExprs());
+  QualType DclT;
+  InitializationSequence InitSeq(*this, Entity, Kind, Args);
+  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT);
+
+  if (Result.isInvalid())
+    return QualType();
+  Init = Result.takeAs<Expr>();
+
+  // The init-capture initialization is a full-expression that must be
+  // processed as one before we enter the declcontext of the lambda's
+  // call-operator.
+  Result = ActOnFinishFullExpr(Init, Loc, /*DiscardedValue*/ false,
+                               /*IsConstexpr*/ false,
+                               /*IsLambdaInitCaptureInitalizer*/ true);
+  if (Result.isInvalid())
+    return QualType();
+
+  Init = Result.takeAs<Expr>();
+  return DeducedType;
+}
+
+VarDecl *Sema::createLambdaInitCaptureVarDecl(SourceLocation Loc, 
+    QualType InitCaptureType, IdentifierInfo *Id, Expr *Init) {
+
+  TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo(InitCaptureType,
+      Loc);
   // Create a dummy variable representing the init-capture. This is not actually
   // used as a variable, and only exists as a way to name and refer to the
   // init-capture.
   // FIXME: Pass in separate source locations for '&' and identifier.
   VarDecl *NewVD = VarDecl::Create(Context, CurContext, Loc,
-                                   Loc, Id, TSI->getType(), TSI, SC_Auto);
+                                   Loc, Id, InitCaptureType, TSI, SC_Auto);
   NewVD->setInitCapture(true);
   NewVD->setReferenced(true);
   NewVD->markUsed(Context);
-
-  // We do not need to distinguish between direct-list-initialization
-  // and copy-list-initialization here, because we will always deduce
-  // std::initializer_list<T>, and direct- and copy-list-initialization
-  // always behave the same for such a type.
-  // FIXME: We should model whether an '=' was present.
-  bool DirectInit = isa<ParenListExpr>(Init) || isa<InitListExpr>(Init);
-  AddInitializerToDecl(NewVD, Init, DirectInit, /*ContainsAuto*/true);
+  NewVD->setInit(Init);
   return NewVD;
+
 }
 
 FieldDecl *Sema::buildInitCaptureField(LambdaScopeInfo *LSI, VarDecl *Var) {
@@ -816,7 +900,7 @@
     if (C->Init.isInvalid())
       continue;
 
-    VarDecl *Var;
+    VarDecl *Var = 0;
     if (C->Init.isUsable()) {
       Diag(C->Loc, getLangOpts().CPlusPlus1y
                        ? diag::warn_cxx11_compat_init_capture
@@ -824,9 +908,15 @@
 
       if (C->Init.get()->containsUnexpandedParameterPack())
         ContainsUnexpandedParameterPack = true;
-
-      Var = checkInitCapture(C->Loc, C->Kind == LCK_ByRef,
-                             C->Id, C->Init.take());
+      // If the initializer expression is usable, but the InitCaptureType
+      // is not, then an error has occurred - so ignore the capture for now.
+      // for e.g., [n{0}] { }; <-- if no <initializer_list> is included.
+      // FIXME: we should create the init capture variable and mark it invalid 
+      // in this case.
+      if (C->InitCaptureType.get().isNull()) 
+        continue;
+      Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(), 
+            C->Id, C->Init.take());
       // C++1y [expr.prim.lambda]p11:
       //   An init-capture behaves as if it declares and explicitly
       //   captures a variable [...] whose declarative region is the