Skip to content

Commit

Permalink
Switch to an RAII object to revert tentative parsing automatically.
Browse files Browse the repository at this point in the history
llvm-svn: 274165
  • Loading branch information
zygoloid committed Jun 29, 2016
1 parent 8ea99cd commit 91b73f2
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 27 deletions.
10 changes: 10 additions & 0 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,16 @@ class Parser : public CodeCompletionHandler {
assert(!isActive && "Forgot to call Commit or Revert!");
}
};
/// A TentativeParsingAction that automatically reverts in its destructor.
/// Useful for disambiguation parses that will always be reverted.
class RevertingTentativeParsingAction
: private Parser::TentativeParsingAction {
public:
RevertingTentativeParsingAction(Parser &P)
: Parser::TentativeParsingAction(P) {}
~RevertingTentativeParsingAction() { Revert(); }
};

class UnannotatedTentativeParsingAction;

/// ObjCDeclContextSwitch - An object used to switch context from
Expand Down
40 changes: 13 additions & 27 deletions clang/lib/Parse/ParseTentative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,11 @@ bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
// 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)
Expand Down Expand Up @@ -354,7 +355,7 @@ bool Parser::isCXXConditionDeclaration() {
// 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();
Expand All @@ -378,8 +379,6 @@ bool Parser::isCXXConditionDeclaration() {
TPR = TPResult::False;
}

PA.Revert();

assert(TPR == TPResult::True || TPR == TPResult::False);
return TPR == TPResult::True;
}
Expand Down Expand Up @@ -423,7 +422,7 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
// 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();
Expand Down Expand Up @@ -456,8 +455,6 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
TPR = TPResult::False;
}

PA.Revert();

assert(TPR == TPResult::True || TPR == TPResult::False);
return TPR == TPResult::True;
}
Expand Down Expand Up @@ -508,7 +505,7 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
if (!Disambiguate && !getLangOpts().ObjC1)
return CAK_AttributeSpecifier;

TentativeParsingAction PA(*this);
RevertingTentativeParsingAction PA(*this);

// Opening brackets were checked for above.
ConsumeBracket();
Expand All @@ -520,8 +517,6 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
bool IsAttribute = SkipUntil(tok::r_square);
IsAttribute &= Tok.is(tok::r_square);

PA.Revert();

return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
}

Expand All @@ -542,8 +537,6 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
// 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;
Expand All @@ -564,7 +557,6 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
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;
}

Expand Down Expand Up @@ -611,8 +603,6 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate,
}
}

PA.Revert();

if (IsAttribute)
// Case 1: C++11 statement attribute.
return CAK_AttributeSpecifier;
Expand Down Expand Up @@ -1340,6 +1330,8 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
*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.
Expand Down Expand Up @@ -1391,15 +1383,13 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
// 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;

Expand Down Expand Up @@ -1452,14 +1442,12 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
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;

Expand Down Expand Up @@ -1599,7 +1587,7 @@ bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
// 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;
Expand All @@ -1623,8 +1611,6 @@ bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
}
}

PA.Revert();

if (IsAmbiguous && TPR == TPResult::Ambiguous)
*IsAmbiguous = true;

Expand Down

0 comments on commit 91b73f2

Please sign in to comment.