summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseTentative.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-05-20 18:01:54 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-05-20 18:01:54 +0000
commite9585060398960d78cce6dd59b79e31e736b8f51 (patch)
tree8aec90e80180321de91daaf2765a0b616d9fcb4b /clang/lib/Parse/ParseTentative.cpp
parentd91f1dd4706d2bc591fc64d7f315c020f521678e (diff)
downloadbcm5719-llvm-e9585060398960d78cce6dd59b79e31e736b8f51.tar.gz
bcm5719-llvm-e9585060398960d78cce6dd59b79e31e736b8f51.zip
Rearrange and clean up how we disambiguate lambda-introducers from ObjC
message sends, designators, and attributes. Instead of having the tentative parsing phase sometimes return an indicator to say what diagnostic to produce if parsing fails and sometimes ask the caller to run it again, consistently ask the caller to try parsing again if tentative parsing would fail or is otherwise unable to completely parse the lambda-introducer without producing an irreversible semantic effect. Mostly NFC, but we should recover marginally better in some error cases (avoiding duplicate diagnostics). llvm-svn: 361182
Diffstat (limited to 'clang/lib/Parse/ParseTentative.cpp')
-rw-r--r--clang/lib/Parse/ParseTentative.cpp52
1 files changed, 38 insertions, 14 deletions
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index 4393326f6c7..e97a8e5b544 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -653,12 +653,15 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
if (!Disambiguate && !getLangOpts().ObjC)
return CAK_AttributeSpecifier;
+ // '[[using ns: ...]]' is an attribute.
+ if (GetLookAheadToken(2).is(tok::kw_using))
+ return CAK_AttributeSpecifier;
+
RevertingTentativeParsingAction PA(*this);
// Opening brackets were checked for above.
ConsumeBracket();
- // Outside Obj-C++11, treat anything with a matching ']]' as an attribute.
if (!getLangOpts().ObjC) {
ConsumeBracket();
@@ -677,24 +680,45 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
// 4) [[obj]{ return self; }() doStuff]; Lambda in message send.
// (1) is an attribute, (2) is ill-formed, and (3) and (4) are accepted.
- // If we have a lambda-introducer, then this is definitely not a message send.
+ // Check to see if this is a lambda-expression.
// FIXME: If this disambiguation is too slow, fold the tentative lambda parse
// into the tentative attribute parse below.
- LambdaIntroducer Intro;
- if (!TryParseLambdaIntroducer(Intro)) {
- // A lambda cannot end with ']]', and an attribute must.
- bool IsAttribute = Tok.is(tok::r_square);
-
- if (IsAttribute)
- // Case 1: C++11 attribute.
- return CAK_AttributeSpecifier;
+ {
+ RevertingTentativeParsingAction LambdaTPA(*this);
+ LambdaIntroducer Intro;
+ LambdaIntroducerTentativeParse Tentative;
+ if (ParseLambdaIntroducer(Intro, &Tentative)) {
+ // We hit a hard error after deciding this was not an attribute.
+ // FIXME: Don't parse and annotate expressions when disambiguating
+ // against an attribute.
+ return CAK_NotAttributeSpecifier;
+ }
- if (OuterMightBeMessageSend)
- // Case 4: Lambda in message send.
+ switch (Tentative) {
+ case LambdaIntroducerTentativeParse::MessageSend:
+ // Case 3: The inner construct is definitely a message send, so the
+ // outer construct is definitely not an attribute.
return CAK_NotAttributeSpecifier;
- // Case 2: Lambda in array size / index.
- return CAK_InvalidAttributeSpecifier;
+ case LambdaIntroducerTentativeParse::Success:
+ case LambdaIntroducerTentativeParse::Incomplete:
+ // This is a lambda-introducer or attribute-specifier.
+ if (Tok.is(tok::r_square))
+ // Case 1: C++11 attribute.
+ return CAK_AttributeSpecifier;
+
+ if (OuterMightBeMessageSend)
+ // Case 4: Lambda in message send.
+ return CAK_NotAttributeSpecifier;
+
+ // Case 2: Lambda in array size / index.
+ return CAK_InvalidAttributeSpecifier;
+
+ case LambdaIntroducerTentativeParse::Invalid:
+ // No idea what this is; we couldn't parse it as a lambda-introducer.
+ // Might still be an attribute-specifier or a message send.
+ break;
+ }
}
ConsumeBracket();
OpenPOWER on IntegriCloud