]> granicus.if.org Git - clang/commitdiff
eliminate lookahead when parsing ::new / ::delete.
authorChris Lattner <sabre@nondot.org>
Sun, 4 Jan 2009 21:25:24 +0000 (21:25 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 4 Jan 2009 21:25:24 +0000 (21:25 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61638 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Parser.h
lib/Parse/ParseExpr.cpp
lib/Parse/ParseExprCXX.cpp

index e23f72b5ca7c9f52320f964981a1b1bac314e7cd..cccd97107321bc949d4e67cec3659751ab562770 100644 (file)
@@ -643,10 +643,11 @@ private:
 
   //===--------------------------------------------------------------------===//
   // C++ 5.3.4 and 5.3.5: C++ new and delete
-  OwningExprResult ParseCXXNewExpression();
   bool ParseExpressionListOrTypeId(ExprListTy &Exprs, Declarator &D);
   void ParseDirectNewDeclarator(Declarator &D);
-  OwningExprResult ParseCXXDeleteExpression();
+  OwningExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start);
+  OwningExprResult ParseCXXDeleteExpression(bool UseGlobal,
+                                            SourceLocation Start);
 
   //===--------------------------------------------------------------------===//
   // C++ if/switch/while/for condition expression.
index 0c25fab4f44a1943c4381a5d33f1699bd9a5a457..f719b8914f50a155e83d203c26b8ba541b628154 100644 (file)
@@ -626,19 +626,23 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
     Res = ParseCXXIdExpression();
     return ParsePostfixExpressionSuffix(move(Res));
 
-  case tok::coloncolon: // [C++] new-expression or [C++] delete-expression
-    // If the next token is neither 'new' nor 'delete', the :: would have been
-    // parsed as a scope specifier already.
-    if (NextToken().is(tok::kw_new))
-      return ParseCXXNewExpression();
-    else
-      return ParseCXXDeleteExpression();
+  case tok::coloncolon: { // [C++] new-expression or [C++] delete-expression
+    SourceLocation ScopeLoc = ConsumeToken();
+    if (Tok.is(tok::kw_new))
+      return ParseCXXNewExpression(true, ScopeLoc);
+    else {
+      // If the next token is neither 'new' nor 'delete', the :: would have been
+      // parsed as a scope specifier already.
+      assert(Tok.is(tok::kw_delete));
+      return ParseCXXDeleteExpression(true, ScopeLoc);
+    }
+  }
 
   case tok::kw_new: // [C++] new-expression
-    return ParseCXXNewExpression();
+    return ParseCXXNewExpression(false, Tok.getLocation());
 
   case tok::kw_delete: // [C++] delete-expression
-    return ParseCXXDeleteExpression();
+    return ParseCXXDeleteExpression(false, Tok.getLocation());
 
   case tok::at: {
     SourceLocation AtLoc = ConsumeToken();
index b0ce072a415aba704de10ab7fb27635fc87d6734..75e4e1fe7c50f01a420ab7809532e27b44cdd8dd 100644 (file)
@@ -639,6 +639,10 @@ Parser::TypeTy *Parser::ParseConversionFunctionId() {
 
 /// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
 /// memory in a typesafe manner and call constructors.
+/// 
+/// This method is called to parse the new expression after the optional :: has
+/// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
+/// is its location.  Otherwise, "Start" is the location of the 'new' token.
 ///
 ///        new-expression:
 ///                   '::'[opt] 'new' new-placement[opt] new-type-id
@@ -660,21 +664,10 @@ Parser::TypeTy *Parser::ParseConversionFunctionId() {
 ///                   '(' expression-list[opt] ')'
 /// [C++0x]           braced-init-list                                   [TODO]
 ///
-Parser::OwningExprResult Parser::ParseCXXNewExpression()
-{
-  assert((Tok.is(tok::coloncolon) || Tok.is(tok::kw_new)) &&
-         "Expected :: or 'new' keyword");
-
-  SourceLocation Start = Tok.getLocation();
-  bool UseGlobal = false;
-  if (Tok.is(tok::coloncolon)) {
-    UseGlobal = true;
-    ConsumeToken();
-  }
-
-  assert(Tok.is(tok::kw_new) && "Lookahead should have ensured 'new'");
-  // Consume 'new'
-  ConsumeToken();
+Parser::OwningExprResult
+Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
+  assert(Tok.is(tok::kw_new) && "expected 'new' token");
+  ConsumeToken();   // Consume 'new'
 
   // A '(' now can be a new-placement or the '(' wrapping the type-id in the
   // second form of new-expression. It can't be a new-type-id.
@@ -768,8 +761,7 @@ Parser::OwningExprResult Parser::ParseCXXNewExpression()
 ///                   '[' expression ']'
 ///                   direct-new-declarator '[' constant-expression ']'
 ///
-void Parser::ParseDirectNewDeclarator(Declarator &D)
-{
+void Parser::ParseDirectNewDeclarator(Declarator &D) {
   // Parse the array dimensions.
   bool first = true;
   while (Tok.is(tok::l_square)) {
@@ -802,8 +794,7 @@ void Parser::ParseDirectNewDeclarator(Declarator &D)
 ///                   '(' expression-list ')'
 ///
 bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
-                                         Declarator &D)
-{
+                                         Declarator &D) {
   // The '(' was already consumed.
   if (isTypeIdInParens()) {
     ParseSpecifierQualifierList(D.getMutableDeclSpec());
@@ -820,24 +811,18 @@ bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
 /// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
 /// to free memory allocated by new.
 ///
+/// This method is called to parse the 'delete' expression after the optional
+/// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
+/// and "Start" is its location.  Otherwise, "Start" is the location of the
+/// 'delete' token.
+///
 ///        delete-expression:
 ///                   '::'[opt] 'delete' cast-expression
 ///                   '::'[opt] 'delete' '[' ']' cast-expression
-Parser::OwningExprResult Parser::ParseCXXDeleteExpression()
-{
-  assert((Tok.is(tok::coloncolon) || Tok.is(tok::kw_delete)) &&
-         "Expected :: or 'delete' keyword");
-
-  SourceLocation Start = Tok.getLocation();
-  bool UseGlobal = false;
-  if (Tok.is(tok::coloncolon)) {
-    UseGlobal = true;
-    ConsumeToken();
-  }
-
-  assert(Tok.is(tok::kw_delete) && "Lookahead should have ensured 'delete'");
-  // Consume 'delete'
-  ConsumeToken();
+Parser::OwningExprResult
+Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
+  assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
+  ConsumeToken(); // Consume 'delete'
 
   // Array delete?
   bool ArrayDelete = false;