r274165 - Switch to an RAII object to revert tentative parsing automatically.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 29 14:06:51 PDT 2016


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;
 




More information about the cfe-commits mailing list