// Ok, we have a simple-type-specifier/typename-specifier followed by a '(',
// or an identifier which doesn't resolve as anything. We need tentative
// parsing...
-
- TentativeParsingAction PA(*this);
- TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
- PA.Revert();
+
+ {
+ RevertingTentativeParsingAction PA(*this);
+ TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
+ }
// In case of an error, let the declaration parsing code handle it.
if (TPR == TPResult::Error)
// Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
// We need tentative parsing...
- TentativeParsingAction PA(*this);
+ RevertingTentativeParsingAction PA(*this);
// type-specifier-seq
TryConsumeDeclarationSpecifier();
TPR = TPResult::False;
}
- PA.Revert();
-
assert(TPR == TPResult::True || TPR == TPResult::False);
return TPR == TPResult::True;
}
// Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
// We need tentative parsing...
- TentativeParsingAction PA(*this);
+ RevertingTentativeParsingAction PA(*this);
// type-specifier-seq
TryConsumeDeclarationSpecifier();
TPR = TPResult::False;
}
- PA.Revert();
-
assert(TPR == TPResult::True || TPR == TPResult::False);
return TPR == TPResult::True;
}
if (!Disambiguate && !getLangOpts().ObjC1)
return CAK_AttributeSpecifier;
- TentativeParsingAction PA(*this);
+ RevertingTentativeParsingAction PA(*this);
// Opening brackets were checked for above.
ConsumeBracket();
bool IsAttribute = SkipUntil(tok::r_square);
IsAttribute &= Tok.is(tok::r_square);
- PA.Revert();
-
return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
}
// A lambda cannot end with ']]', and an attribute must.
bool IsAttribute = Tok.is(tok::r_square);
- PA.Revert();
-
if (IsAttribute)
// Case 1: C++11 attribute.
return CAK_AttributeSpecifier;
while (Tok.isNot(tok::r_square)) {
if (Tok.is(tok::comma)) {
// Case 1: Stray commas can only occur in attributes.
- PA.Revert();
return CAK_AttributeSpecifier;
}
}
}
- PA.Revert();
-
if (IsAttribute)
// Case 1: C++11 statement attribute.
return CAK_AttributeSpecifier;
*HasMissingTypename = true;
return TPResult::Ambiguous;
}
+
+ // FIXME: Fails to either revert or commit the tentative parse!
} else {
// Try to resolve the name. If it doesn't exist, assume it was
// intended to name a type and keep disambiguating.
// In Objective-C, we might have a protocol-qualified type.
if (getLangOpts().ObjC1 && NextToken().is(tok::less)) {
// Tentatively parse the protocol qualifiers.
- TentativeParsingAction PA(*this);
+ RevertingTentativeParsingAction PA(*this);
ConsumeToken(); // The type token
TPResult TPR = TryParseProtocolQualifiers();
bool isFollowedByParen = Tok.is(tok::l_paren);
bool isFollowedByBrace = Tok.is(tok::l_brace);
- PA.Revert();
-
if (TPR == TPResult::Error)
return TPResult::Error;
if (NextToken().isNot(tok::l_paren))
return TPResult::True;
- TentativeParsingAction PA(*this);
+ RevertingTentativeParsingAction PA(*this);
TPResult TPR = TryParseTypeofSpecifier();
bool isFollowedByParen = Tok.is(tok::l_paren);
bool isFollowedByBrace = Tok.is(tok::l_brace);
- PA.Revert();
-
if (TPR == TPResult::Error)
return TPResult::Error;
// ambiguities mentioned in 6.8, the resolution is to consider any construct
// that could possibly be a declaration a declaration.
- TentativeParsingAction PA(*this);
+ RevertingTentativeParsingAction PA(*this);
ConsumeParen();
bool InvalidAsDeclaration = false;
}
}
- PA.Revert();
-
if (IsAmbiguous && TPR == TPResult::Ambiguous)
*IsAmbiguous = true;