Introduce basic ASTs for lambda expressions. This covers:
  - Capturing variables by-reference and by-copy within a lambda
  - The representation of lambda captures
  - The creation of the non-static data members in the lambda class
  that store the captured variables
  - The initialization of the non-static data members from the
  captured variables
  - Pretty-printing lambda expressions

There are a number of FIXMEs, both explicit and implied, including:
  - Creating a field for a capture of 'this'
  - Improved diagnostics for initialization failures when capturing
  variables by copy
  - Dealing with temporaries created during said initialization
  - Template instantiation
  - AST (de-)serialization
  - Binding and returning the lambda expression; turning it into a
  proper temporary
  - Lots and lots of semantic constraints
  - Parameter pack captures


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149977 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 30b0529..cd2c210 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -4895,6 +4895,7 @@
   // at this point, but we need something to attach child declarations to.
   QualType MethodTy;
   TypeSourceInfo *MethodTyInfo;
+  bool ExplicitParams = true;
   if (ParamInfo.getNumTypeObjects() == 0) {
     // C++11 [expr.prim.lambda]p4:
     //   If a lambda-expression does not include a lambda-declarator, it is as 
@@ -4904,6 +4905,7 @@
     MethodTy = Context.getFunctionType(Context.DependentTy,
                                        /*Args=*/0, /*NumArgs=*/0, EPI);
     MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy);
+    ExplicitParams = false;
   } else {
     assert(ParamInfo.isFunctionDeclarator() &&
            "lambda-declarator is a function");
@@ -4967,9 +4969,10 @@
     LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval;
   else if (Intro.Default == LCD_ByRef)
     LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByref;
-
+  LSI->IntroducerRange = Intro.Range;
+  LSI->ExplicitParams = ExplicitParams;
   LSI->Mutable = (Method->getTypeQualifiers() & Qualifiers::Const) == 0;
-
+ 
   // Handle explicit captures.
   for (llvm::SmallVector<LambdaCapture, 4>::const_iterator
          C = Intro.Captures.begin(), 
@@ -5116,8 +5119,78 @@
 
 ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc,
                                  Stmt *Body, Scope *CurScope) {
-  // FIXME: Implement
+  // Leave the expression-evaluation context.
+  DiscardCleanupsInEvaluationContext();
+  PopExpressionEvaluationContext();
+
+  // Leave the context of the lambda.
+  PopDeclContext();
+
+  // FIXME: End-of-lambda checking
+
+  // Collect information from the lambda scope.
+  llvm::SmallVector<LambdaExpr::Capture, 4> Captures;
+  llvm::SmallVector<Expr *, 4> CaptureInits;
+  LambdaCaptureDefault CaptureDefault;
+  CXXRecordDecl *Class;
+  SourceRange IntroducerRange;
+  bool ExplicitParams;
+  {
+    LambdaScopeInfo *LSI = getCurLambda();
+    Class = LSI->Lambda;
+    IntroducerRange = LSI->IntroducerRange;
+    ExplicitParams = LSI->ExplicitParams;
+
+    // Translate captures.
+    for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) {
+      LambdaScopeInfo::Capture From = LSI->Captures[I];
+      assert(!From.isBlockCapture() && "Cannot capture __block variables");
+      bool IsImplicit = I >= LSI->NumExplicitCaptures;
+
+      // Handle 'this' capture.
+      if (From.isThisCapture()) {
+        Captures.push_back(LambdaExpr::Capture(From.getLocation(),
+                                               IsImplicit,
+                                               LCK_This));
+        CaptureInits.push_back(new (Context) CXXThisExpr(From.getLocation(),
+                                                         getCurrentThisType(),
+                                                         /*isImplicit=*/true));
+        continue;
+      }
+
+      VarDecl *Var = From.getVariable();
+      // FIXME: Handle pack expansions.
+      LambdaCaptureKind Kind = From.isCopyCapture()? LCK_ByCopy : LCK_ByRef;
+      Captures.push_back(LambdaExpr::Capture(From.getLocation(), IsImplicit, 
+                                             Kind, Var));
+      CaptureInits.push_back(From.getCopyExpr());
+    }
+
+    switch (LSI->ImpCaptureStyle) {
+    case CapturingScopeInfo::ImpCap_None:
+      CaptureDefault = LCD_None;
+      break;
+
+    case CapturingScopeInfo::ImpCap_LambdaByval:
+      CaptureDefault = LCD_ByCopy;
+      break;
+
+    case CapturingScopeInfo::ImpCap_LambdaByref:
+      CaptureDefault = LCD_ByRef;
+      break;
+
+    case CapturingScopeInfo::ImpCap_Block:
+      llvm_unreachable("block capture in lambda");
+      break;
+    }
+
+    PopFunctionScopeInfo();
+  }
+
+  Expr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange, 
+                                    CaptureDefault, Captures, ExplicitParams, 
+                                    CaptureInits, Body->getLocEnd());
+  (void)Lambda;
   Diag(StartLoc, diag::err_lambda_unsupported);
-  ActOnLambdaError(StartLoc, CurScope);
   return ExprError();
 }