Author: rsmith Date: Wed Jun 29 16:06:51 2016 New Revision: 274165 URL: http://llvm.org/viewvc/llvm-project?rev=274165&view=rev Log: Switch to an RAII object to revert tentative parsing automatically.
Modified: cfe/trunk/include/clang/Parse/Parser.h cfe/trunk/lib/Parse/ParseTentative.cpp Modified: cfe/trunk/include/clang/Parse/Parser.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=274165&r1=274164&r2=274165&view=diff ============================================================================== --- cfe/trunk/include/clang/Parse/Parser.h (original) +++ cfe/trunk/include/clang/Parse/Parser.h Wed Jun 29 16:06:51 2016 @@ -715,6 +715,16 @@ private: 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 Modified: cfe/trunk/lib/Parse/ParseTentative.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=274165&r1=274164&r2=274165&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseTentative.cpp (original) +++ cfe/trunk/lib/Parse/ParseTentative.cpp Wed Jun 29 16:06:51 2016 @@ -125,10 +125,11 @@ bool Parser::isCXXSimpleDeclaration(bool // 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) @@ -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(); @@ -378,8 +379,6 @@ bool Parser::isCXXConditionDeclaration() TPR = TPResult::False; } - PA.Revert(); - assert(TPR == TPResult::True || TPR == TPResult::False); return TPR == TPResult::True; } @@ -423,7 +422,7 @@ bool Parser::isCXXTypeId(TentativeCXXTyp // 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(); @@ -456,8 +455,6 @@ bool Parser::isCXXTypeId(TentativeCXXTyp TPR = TPResult::False; } - PA.Revert(); - assert(TPR == TPResult::True || TPR == TPResult::False); return TPR == TPResult::True; } @@ -508,7 +505,7 @@ Parser::isCXX11AttributeSpecifier(bool D if (!Disambiguate && !getLangOpts().ObjC1) return CAK_AttributeSpecifier; - TentativeParsingAction PA(*this); + RevertingTentativeParsingAction PA(*this); // Opening brackets were checked for above. ConsumeBracket(); @@ -520,8 +517,6 @@ Parser::isCXX11AttributeSpecifier(bool D bool IsAttribute = SkipUntil(tok::r_square); IsAttribute &= Tok.is(tok::r_square); - PA.Revert(); - return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier; } @@ -542,8 +537,6 @@ Parser::isCXX11AttributeSpecifier(bool D // 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; @@ -564,7 +557,6 @@ Parser::isCXX11AttributeSpecifier(bool D 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; } @@ -611,8 +603,6 @@ Parser::isCXX11AttributeSpecifier(bool D } } - PA.Revert(); - if (IsAttribute) // Case 1: C++11 statement attribute. return CAK_AttributeSpecifier; @@ -1340,6 +1330,8 @@ Parser::isCXXDeclarationSpecifier(Parser *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. @@ -1391,15 +1383,13 @@ Parser::isCXXDeclarationSpecifier(Parser // 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; @@ -1452,14 +1442,12 @@ Parser::isCXXDeclarationSpecifier(Parser 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; @@ -1599,7 +1587,7 @@ bool Parser::isCXXFunctionDeclarator(boo // 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; @@ -1623,8 +1611,6 @@ bool Parser::isCXXFunctionDeclarator(boo } } - PA.Revert(); - if (IsAmbiguous && TPR == TPResult::Ambiguous) *IsAmbiguous = true; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits