[cfe-commits] r49268 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp

Chris Lattner sabre at nondot.org
Sat Apr 5 23:34:08 PDT 2008


Author: lattner
Date: Sun Apr  6 01:34:08 2008
New Revision: 49268

URL: http://llvm.org/viewvc/llvm-project?rev=49268&view=rev
Log:
split parsing of identifier lists in function declarators out into
their own method.

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDecl.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=49268&r1=49267&r2=49268&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sun Apr  6 01:34:08 2008
@@ -471,6 +471,8 @@
   void ParseDirectDeclarator(Declarator &D);
   void ParseParenDeclarator(Declarator &D);
   void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D);
+  void ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
+                                             Declarator &D);
   void ParseBracketDeclarator(Declarator &D);
   
   //===--------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=49268&r1=49267&r2=49268&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Sun Apr  6 01:34:08 2008
@@ -1235,10 +1235,6 @@
 ///         declaration-specifiers abstract-declarator[opt] 
 /// [GNU]   declaration-specifiers abstract-declarator[opt] attributes
 ///
-///       identifier-list: [C99 6.7.5]
-///         identifier
-///         identifier-list ',' identifier
-///
 void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D) {
   // lparen is already consumed!
   assert(D.isPastIdentifier() && "Should not call before identifier!");
@@ -1263,50 +1259,7 @@
              !Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) {
     // Identifier list.  Note that '(' identifier-list ')' is only allowed for
     // normal declarators, not for abstract-declarators.
-    assert(D.isPastIdentifier() && "Identifier (if present) must be passed!");
-    
-    // If there was no identifier specified, either we are in an
-    // abstract-declarator, or we are in a parameter declarator which was found
-    // to be abstract.  In abstract-declarators, identifier lists are not valid,
-    // diagnose this.
-    if (!D.getIdentifier())
-      Diag(Tok, diag::ext_ident_list_in_param);
-
-    // Remember this identifier in ParamInfo.
-    ParamInfo.push_back(DeclaratorChunk::ParamInfo(Tok.getIdentifierInfo(),
-                                                   Tok.getLocation(), 0));
-
-    ConsumeToken();
-    while (Tok.is(tok::comma)) {
-      // Eat the comma.
-      ConsumeToken();
-      
-      if (Tok.isNot(tok::identifier)) {
-        Diag(Tok, diag::err_expected_ident);
-        ErrorEmitted = true;
-        break;
-      }
-      
-      IdentifierInfo *ParmII = Tok.getIdentifierInfo();
-      
-      // Verify that the argument identifier has not already been mentioned.
-      if (!ParamsSoFar.insert(ParmII)) {
-        Diag(Tok.getLocation(), diag::err_param_redefinition,ParmII->getName());
-        ParmII = 0;
-      }
-          
-      // Remember this identifier in ParamInfo.
-      if (ParmII)
-        ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
-                                                       Tok.getLocation(), 0));
-      
-      // Eat the identifier.
-      ConsumeToken();
-    }
-    
-    // K&R 'prototype'.
-    IsVariadic = false;
-    HasPrototype = false;
+    return ParseFunctionDeclaratorIdentifierList(LParenLoc, D);
   } else {
     // Finally, a normal, non-empty parameter type list.
     
@@ -1424,6 +1377,79 @@
 }
 
 
+/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
+/// we found a K&R-style identifier list instead of a type argument list.  The
+/// current token is known to be the first identifier in the list.
+///
+///       identifier-list: [C99 6.7.5]
+///         identifier
+///         identifier-list ',' identifier
+///
+void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
+                                                   Declarator &D) {
+  // Build up an array of information about the parsed arguments.
+  llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
+  llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
+  
+  // If there was no identifier specified for the declarator, either we are in
+  // an abstract-declarator, or we are in a parameter declarator which was found
+  // to be abstract.  In abstract-declarators, identifier lists are not valid:
+  // diagnose this.
+  if (!D.getIdentifier())
+    Diag(Tok, diag::ext_ident_list_in_param);
+
+  // Tok is known to be the first identifier in the list.  Remember this
+  // identifier in ParamInfo.
+  ParamInfo.push_back(DeclaratorChunk::ParamInfo(Tok.getIdentifierInfo(),
+                                                 Tok.getLocation(), 0));
+  
+  ConsumeToken();
+  bool ErrorEmitted = false;
+  
+  while (Tok.is(tok::comma)) {
+    // Eat the comma.
+    ConsumeToken();
+    
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_expected_ident);
+      ErrorEmitted = true;
+      break;
+    }
+    
+    IdentifierInfo *ParmII = Tok.getIdentifierInfo();
+    
+    // Verify that the argument identifier has not already been mentioned.
+    if (!ParamsSoFar.insert(ParmII)) {
+      Diag(Tok.getLocation(), diag::err_param_redefinition,ParmII->getName());
+      ParmII = 0;
+    }
+    
+    // Remember this identifier in ParamInfo.
+    if (ParmII)
+      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
+                                                     Tok.getLocation(), 0));
+    
+    // Eat the identifier.
+    ConsumeToken();
+  }
+  
+  // Remember that we parsed a function type, and remember the attributes.
+  if (!ErrorEmitted)
+    D.AddTypeInfo(DeclaratorChunk::getFunction(false, false,
+                                               &ParamInfo[0], ParamInfo.size(),
+                                               LParenLoc));
+  
+  // If we have the closing ')', eat it and we're done.
+  if (Tok.is(tok::r_paren)) {
+    ConsumeParen();
+  } else {
+    // If an error happened earlier parsing something else in the proto, don't
+    // issue another error.
+    if (!ErrorEmitted)
+      Diag(Tok, diag::err_expected_rparen);
+    SkipUntil(tok::r_paren);
+  }
+}
 
 /// [C90]   direct-declarator '[' constant-expression[opt] ']'
 /// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'





More information about the cfe-commits mailing list