diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-01-04 02:40:39 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-01-04 02:40:39 +0000 |
commit | dc3b723d35067e5d13474247b94a10c869cc7e58 (patch) | |
tree | ff854188e2a842098addbad74dd52dde0987ac30 /lib/Parse/ParseExprCXX.cpp | |
parent | 4cd55b04e37d2c2c078be8d55c767213af8cc4ef (diff) |
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
Diffstat (limited to 'lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index bd97fcee7c..901a537f5e 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 @@ ExprResult Parser::ParseLambdaExpression() { 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 @@ ExprResult Parser::TryParseLambdaExpression() { 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 @@ bool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) { /// 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 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( 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 |