summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseInit.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-04-13 04:31:48 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-04-13 04:31:48 +0000
commit9e2f0a4f628b2cefb9a234c3c66f820bdbc966fc (patch)
tree243b31598db83cc659cf606531530741e4836db4 /clang/lib/Parse/ParseInit.cpp
parent0563ca1be808a14863d87f3c878c30555328b0bf (diff)
downloadbcm5719-llvm-9e2f0a4f628b2cefb9a234c3c66f820bdbc966fc.tar.gz
bcm5719-llvm-9e2f0a4f628b2cefb9a234c3c66f820bdbc966fc.zip
PR19339: Disambiguate lambdas with init-captures from designated initializers
properly. llvm-svn: 206128
Diffstat (limited to 'clang/lib/Parse/ParseInit.cpp')
-rw-r--r--clang/lib/Parse/ParseInit.cpp58
1 files changed, 21 insertions, 37 deletions
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
index 44053f193bd..bdd45131676 100644
--- a/clang/lib/Parse/ParseInit.cpp
+++ b/clang/lib/Parse/ParseInit.cpp
@@ -66,45 +66,29 @@ bool Parser::MayBeDesignationStart() {
}
// Parse up to (at most) the token after the closing ']' to determine
- // whether this is a C99 designator or a lambda.
+ // whether this is a C99 designator or a lambda.
TentativeParsingAction Tentative(*this);
- ConsumeBracket();
- while (true) {
- switch (Tok.getKind()) {
- case tok::equal:
- case tok::amp:
- case tok::identifier:
- case tok::kw_this:
- // These tokens can occur in a capture list or a constant-expression.
- // Keep looking.
- ConsumeToken();
- continue;
-
- case tok::comma:
- // Since a comma cannot occur in a constant-expression, this must
- // be a lambda.
- Tentative.Revert();
- return false;
-
- case tok::r_square: {
- // Once we hit the closing square bracket, we look at the next
- // token. If it's an '=', this is a designator. Otherwise, it's a
- // lambda expression. This decision favors lambdas over the older
- // GNU designator syntax, which allows one to omit the '=', but is
- // consistent with GCC.
- ConsumeBracket();
- tok::TokenKind Kind = Tok.getKind();
- Tentative.Revert();
- return Kind == tok::equal;
- }
-
- default:
- // Anything else cannot occur in a lambda capture list, so it
- // must be a designator.
- Tentative.Revert();
- return true;
- }
+
+ LambdaIntroducer Intro;
+ bool SkippedInits = false;
+ Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro, &SkippedInits));
+
+ if (DiagID) {
+ // If this can't be a lambda capture list, it's a designator.
+ Tentative.Revert();
+ return true;
}
+
+ // Once we hit the closing square bracket, we look at the next
+ // token. If it's an '=', this is a designator. Otherwise, it's a
+ // lambda expression. This decision favors lambdas over the older
+ // GNU designator syntax, which allows one to omit the '=', but is
+ // consistent with GCC.
+ tok::TokenKind Kind = Tok.getKind();
+ // FIXME: If we didn't skip any inits, parse the lambda from here
+ // rather than throwing away then reparsing the LambdaIntroducer.
+ Tentative.Revert();
+ return Kind == tok::equal;
}
static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc,
OpenPOWER on IntegriCloud