When completing a lambda expression, make sure to check and attach the
body of the lambda to the function call operator.

llvm-svn: 150087
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 9c5bdbe..22d2a20 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -831,8 +831,10 @@
                                               BlockScope, Block));
 }
 
-void Sema::PushLambdaScope(CXXRecordDecl *Lambda) {
-  FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda));
+void Sema::PushLambdaScope(CXXRecordDecl *Lambda, 
+                           CXXMethodDecl *CallOperator) {
+  FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda,
+                                               CallOperator));
 }
 
 void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index ffc7c61..ed8d8a5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7236,7 +7236,8 @@
       computeNRVO(Body, getCurFunction());
     }
     
-    assert(FD == getCurFunctionDecl() && "Function parsing confused");
+    assert((FD == getCurFunctionDecl() || getCurLambda()->CallOperator == FD) &&
+           "Function parsing confused");
   } else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) {
     assert(MD == getCurMethodDecl() && "Method parsing confused");
     MD->setBody(Body);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 1829565..bbf992c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -9722,8 +9722,6 @@
       // of the copy/move done to move a __block variable to the heap.
       type.addConst();
 
-      // FIXME: Add an initialized entity for lambda capture.
-      // FIXME: Won't work for arrays, although we do need this behavior.
       Expr *declRef = new (Context) DeclRefExpr(var, type, VK_LValue, loc);
       ExprResult result =
         PerformCopyInitialization(
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index cd2c210..98ab978 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -4896,6 +4896,7 @@
   QualType MethodTy;
   TypeSourceInfo *MethodTyInfo;
   bool ExplicitParams = true;
+  SourceLocation EndLoc;
   if (ParamInfo.getNumTypeObjects() == 0) {
     // C++11 [expr.prim.lambda]p4:
     //   If a lambda-expression does not include a lambda-declarator, it is as 
@@ -4906,6 +4907,7 @@
                                        /*Args=*/0, /*NumArgs=*/0, EPI);
     MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy);
     ExplicitParams = false;
+    EndLoc = Intro.Range.getEnd();
   } else {
     assert(ParamInfo.isFunctionDeclarator() &&
            "lambda-declarator is a function");
@@ -4928,6 +4930,7 @@
     assert(MethodTyInfo && "no type from lambda-declarator");
     MethodTy = MethodTyInfo->getType();
     assert(!MethodTy.isNull() && "no type from lambda declarator");
+    EndLoc = ParamInfo.getSourceRange().getEnd();
   }
   
   // C++11 [expr.prim.lambda]p5:
@@ -4937,19 +4940,22 @@
   //   trailing-return-type respectively.
   DeclarationName MethodName
     = Context.DeclarationNames.getCXXOperatorName(OO_Call);
+  DeclarationNameLoc MethodNameLoc;
+  MethodNameLoc.CXXOperatorName.BeginOpNameLoc
+    = Intro.Range.getBegin().getRawEncoding();
+  MethodNameLoc.CXXOperatorName.EndOpNameLoc
+    = Intro.Range.getEnd().getRawEncoding();
   CXXMethodDecl *Method
-    = CXXMethodDecl::Create(Context,
-                            Class,
-                            ParamInfo.getSourceRange().getEnd(),
-                            DeclarationNameInfo(MethodName,
-                                                /*NameLoc=*/SourceLocation()),
-                            MethodTy,
-                            MethodTyInfo,
+    = CXXMethodDecl::Create(Context, Class, EndLoc,
+                            DeclarationNameInfo(MethodName, 
+                                                Intro.Range.getBegin(),
+                                                MethodNameLoc),
+                            MethodTy, MethodTyInfo,
                             /*isStatic=*/false,
                             SC_None,
                             /*isInline=*/true,
                             /*isConstExpr=*/false,
-                            ParamInfo.getSourceRange().getEnd());
+                            EndLoc);
   Method->setAccess(AS_public);
   Class->addDecl(Method);
   Method->setLexicalDeclContext(DC); // FIXME: Minor hack.
@@ -4963,7 +4969,7 @@
   PushDeclContext(CurScope, Method);
     
   // Introduce the lambda scope.
-  PushLambdaScope(Class);
+  PushLambdaScope(Class, Method);
   LambdaScopeInfo *LSI = getCurLambda();
   if (Intro.Default == LCD_ByCopy)
     LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval;
@@ -5123,9 +5129,6 @@
   DiscardCleanupsInEvaluationContext();
   PopExpressionEvaluationContext();
 
-  // Leave the context of the lambda.
-  PopDeclContext();
-
   // FIXME: End-of-lambda checking
 
   // Collect information from the lambda scope.
@@ -5184,7 +5187,10 @@
       break;
     }
 
-    PopFunctionScopeInfo();
+    // C++ [expr.prim.lambda]p7:
+    //   The lambda-expression’s compound-statement yields the
+    //   function-body (8.4) of the function call operator [...].
+    ActOnFinishFunctionBody(LSI->CallOperator, Body, /*IsInstantation=*/false);
   }
 
   Expr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,