671
679
return ParseLambdaExpressionAfterIntroducer(Intro);
674
/// ParseLambdaExpression - Parse a lambda introducer.
676
/// Returns a DiagnosticID if it hit something unexpected.
677
Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro) {
682
/// \brief Parse a lambda introducer.
683
/// \param Intro A LambdaIntroducer filled in with information about the
684
/// contents of the lambda-introducer.
685
/// \param SkippedInits If non-null, we are disambiguating between an Obj-C
686
/// message send and a lambda expression. In this mode, we will
687
/// sometimes skip the initializers for init-captures and not fully
688
/// populate \p Intro. This flag will be set to \c true if we do so.
689
/// \return A DiagnosticID if it hit something unexpected. The location for
690
/// for the diagnostic is that of the current token.
691
Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
692
bool *SkippedInits) {
678
693
typedef Optional<unsigned> DiagResult;
680
695
assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['.");
757
773
if (Tok.is(tok::identifier)) {
758
774
Id = Tok.getIdentifierInfo();
759
775
Loc = ConsumeToken();
761
if (Tok.is(tok::ellipsis))
762
EllipsisLoc = ConsumeToken();
763
776
} else if (Tok.is(tok::kw_this)) {
764
777
// FIXME: If we want to suggest a fixit here, will need to return more
765
778
// than just DiagnosticID. Perhaps full DiagnosticBuilder that can be
769
782
return DiagResult(diag::err_expected_capture);
785
if (Tok.is(tok::l_paren)) {
786
BalancedDelimiterTracker Parens(*this, tok::l_paren);
787
Parens.consumeOpen();
793
*SkippedInits = true;
794
} else if (ParseExpressionList(Exprs, Commas)) {
798
Parens.consumeClose();
799
Init = Actions.ActOnParenListExpr(Parens.getOpenLocation(),
800
Parens.getCloseLocation(),
803
} else if (Tok.is(tok::l_brace) || Tok.is(tok::equal)) {
804
if (Tok.is(tok::equal))
808
Init = ParseInitializer();
809
else if (Tok.is(tok::l_brace)) {
810
BalancedDelimiterTracker Braces(*this, tok::l_brace);
811
Braces.consumeOpen();
813
*SkippedInits = true;
815
// We're disambiguating this:
819
// We need to find the end of the following expression in order to
820
// determine whether this is an Obj-C message send's receiver, or a
821
// lambda init-capture.
823
// Parse the expression to find where it ends, and annotate it back
824
// onto the tokens. We would have parsed this expression the same way
825
// in either case: both the RHS of an init-capture and the RHS of an
826
// assignment expression are parsed as an initializer-clause, and in
827
// neither case can anything be added to the scope between the '[' and
830
// FIXME: This is horrible. Adding a mechanism to skip an expression
831
// would be much cleaner.
832
// FIXME: If there is a ',' before the next ']' or ':', we can skip to
833
// that instead. (And if we see a ':' with no matching '?', we can
834
// classify this as an Obj-C message send.)
835
SourceLocation StartLoc = Tok.getLocation();
836
InMessageExpressionRAIIObject MaybeInMessageExpression(*this, true);
837
Init = ParseInitializer();
839
if (Tok.getLocation() != StartLoc) {
840
// Back out the lexing of the token after the initializer.
841
PP.RevertCachedTokens(1);
843
// Replace the consumed tokens with an appropriate annotation.
844
Tok.setLocation(StartLoc);
845
Tok.setKind(tok::annot_primary_expr);
846
setExprAnnotation(Tok, Init);
847
Tok.setAnnotationEndLoc(PP.getLastCachedTokenLocation());
848
PP.AnnotateCachedTokens(Tok);
850
// Consume the annotated initializer.
854
} else if (Tok.is(tok::ellipsis))
855
EllipsisLoc = ConsumeToken();
773
Intro.addCapture(Kind, Loc, Id, EllipsisLoc);
858
Intro.addCapture(Kind, Loc, Id, EllipsisLoc, Init);
776
861
T.consumeClose();
785
870
bool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) {
786
871
TentativeParsingAction PA(*this);
788
Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro));
873
bool SkippedInits = false;
874
Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro, &SkippedInits));
882
// Parse it again, but this time parse the init-captures too.
884
Intro = LambdaIntroducer();
885
DiagID = ParseLambdaIntroducer(Intro);
886
assert(!DiagID && "parsing lambda-introducer failed on reparse");
806
901
PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
807
902
"lambda expression parsing");
904
// FIXME: Call into Actions to add any init-capture declarations to the
905
// scope while parsing the lambda-declarator and compound-statement.
809
907
// Parse lambda-declarator[opt].
810
908
DeclSpec DS(AttrFactory);
811
909
Declarator D(DS, Declarator::LambdaExprContext);
1456
1554
if (!InitExpr.isInvalid())
1457
1555
Actions.AddInitializerToDecl(DeclOut, InitExpr.take(), !CopyInitialization,
1458
DS.getTypeSpecType() == DeclSpec::TST_auto);
1556
DS.containsPlaceholderType());
1558
Actions.ActOnInitializerError(DeclOut);
1460
1560
// FIXME: Build a reference to this declaration? Convert it to bool?
1461
1561
// (This is currently handled by Sema).