aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseExprCXX.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-01-04 02:40:39 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-01-04 02:40:39 +0000
commitdc3b723d35067e5d13474247b94a10c869cc7e58 (patch)
treeff854188e2a842098addbad74dd52dde0987ac30 /lib/Parse/ParseExprCXX.cpp
parent4cd55b04e37d2c2c078be8d55c767213af8cc4ef (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.cpp59
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