Stub out the Sema interface for lambda expressions, and change the parser to use it.  Unconditionally error on lambda expressions because they don't work in any meaningful way yet.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147515 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index bd97fce..901a537 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -14,6 +14,7 @@
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/Parser.h"
 #include "RAIIObjectsForParser.h"
+#include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ParsedTemplate.h"
@@ -563,6 +564,9 @@
   if (DiagID) {
     Diag(Tok, DiagID.getValue());
     SkipUntil(tok::r_square);
+    SkipUntil(tok::l_brace);
+    SkipUntil(tok::r_brace);
+    return ExprError();
   }
 
   return ParseLambdaExpressionAfterIntroducer(Intro);
@@ -591,14 +595,21 @@
     return ParseLambdaExpression();
   }
 
-  // If lookahead indicates this is an Objective-C message...
+  // If lookahead indicates an ObjC message send...
+  // [identifier identifier
   if (Next.is(tok::identifier) && After.is(tok::identifier)) {
-    return ExprError();
+    return ExprEmpty();
   }
 
+  // Here, we're stuck: lambda introducers and Objective-C message sends are
+  // unambiguous, but it requires arbitrary lookhead.  [a,b,c,d,e,f,g] is a
+  // lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send.  Instead of
+  // writing two routines to parse a lambda introducer, just try to parse
+  // a lambda introducer first, and fall back if that fails.
+  // (TryParseLambdaIntroducer never produces any diagnostic output.)
   LambdaIntroducer Intro;
   if (TryParseLambdaIntroducer(Intro))
-    return ExprError();
+    return ExprEmpty();
   return ParseLambdaExpressionAfterIntroducer(Intro);
 }
 
@@ -694,11 +705,17 @@
 /// expression.
 ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
                      LambdaIntroducer &Intro) {
-  Diag(Intro.Range.getBegin(), diag::warn_cxx98_compat_lambda);
+  SourceLocation LambdaBeginLoc = Intro.Range.getBegin();
+  Diag(LambdaBeginLoc, diag::warn_cxx98_compat_lambda);
+
+  PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
+                                "lambda expression parsing");
+
+  Actions.ActOnLambdaStart(LambdaBeginLoc, getCurScope());
 
   // Parse lambda-declarator[opt].
   DeclSpec DS(AttrFactory);
-  Declarator D(DS, Declarator::PrototypeContext);
+  Declarator D(DS, Declarator::BlockLiteralContext);
 
   if (Tok.is(tok::l_paren)) {
     ParseScope PrototypeScope(this,
@@ -775,24 +792,32 @@
                                            DeclLoc, DeclEndLoc, D,
                                            TrailingReturnType),
                   Attr, DeclEndLoc);
+
+     // Inform sema that we are starting a block.
+     Actions.ActOnLambdaArguments(D, getCurScope());
   }
 
   // Parse compound-statement.
-  if (Tok.is(tok::l_brace)) {
-    // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
-    // it.
-    ParseScope BodyScope(this, Scope::BlockScope | Scope::FnScope |
-                               Scope::BreakScope | Scope::ContinueScope |
-                               Scope::DeclScope);
-
-    ParseCompoundStatementBody();
-
-    BodyScope.Exit();
-  } else {
+  if (!Tok.is(tok::l_brace)) {
     Diag(Tok, diag::err_expected_lambda_body);
+    Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
+    return ExprError();
   }
 
-  return ExprEmpty();
+  // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
+  // it.
+  ParseScope BodyScope(this, Scope::BlockScope | Scope::FnScope |
+                             Scope::BreakScope | Scope::ContinueScope |
+                             Scope::DeclScope);
+  StmtResult Stmt(ParseCompoundStatementBody());
+  BodyScope.Exit();
+
+   if (!Stmt.isInvalid())
+     return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.take(),
+                                    getCurScope());
+ 
+   Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
+   return ExprError();
 }
 
 /// ParseCXXCasts - This handles the various ways to cast expressions to another