]> granicus.if.org Git - clang/commitdiff
split code for handling grouping parens in declarators from code that
authorChris Lattner <sabre@nondot.org>
Sun, 6 Apr 2008 05:45:57 +0000 (05:45 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 6 Apr 2008 05:45:57 +0000 (05:45 +0000)
handles function argument parens in declarators.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49265 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Parser.h
lib/Parse/ParseDecl.cpp

index 01879479a8e6d65d7e2a69011182c25b7716bbf6..e072b87362793f0b5bfca18c7fed9abdc7ba6bb0 100644 (file)
@@ -470,6 +470,7 @@ private:
   void ParseTypeQualifierListOpt(DeclSpec &DS);
   void ParseDirectDeclarator(Declarator &D);
   void ParseParenDeclarator(Declarator &D);
+  void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D);
   void ParseBracketDeclarator(Declarator &D);
   
   //===--------------------------------------------------------------------===//
index a46490c7e1e16e10f0a328d2ec5e07ed8a7d4986..3e6b93dfec3985249965e2e8c5d2c114b9fd96fc 100644 (file)
@@ -1045,9 +1045,6 @@ void Parser::ParseDeclarator(Declarator &D) {
   /// This implements the 'declarator' production in the C grammar, then checks
   /// for well-formedness and issues diagnostics.
   ParseDeclaratorInternal(D);
-  
-  // TODO: validate D.
-
 }
 
 /// ParseDeclaratorInternal
@@ -1155,7 +1152,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
   
   while (1) {
     if (Tok.is(tok::l_paren)) {
-      ParseParenDeclarator(D);
+      ParseFunctionDeclarator(ConsumeParen(), D);
     } else if (Tok.is(tok::l_square)) {
       ParseBracketDeclarator(D);
     } else {
@@ -1164,10 +1161,64 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
   }
 }
 
-/// ParseParenDeclarator - We parsed the declarator D up to a paren.  This may
-/// either be before the identifier (in which case these are just grouping
-/// parens for precedence) or it may be after the identifier, in which case
-/// these are function arguments.
+/// ParseParenDeclarator - We parsed the declarator D up to a paren.  This is
+/// only called before the identifier, so these are most likely just grouping
+/// parens for precedence.  If we find that these are actually function 
+/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
+///
+///       direct-declarator:
+///         '(' declarator ')'
+/// [GNU]   '(' attributes declarator ')'
+///
+void Parser::ParseParenDeclarator(Declarator &D) {
+  SourceLocation StartLoc = ConsumeParen();
+  assert(!D.isPastIdentifier() && "Should be called before passing identifier");
+  
+  // If we haven't past the identifier yet (or where the identifier would be
+  // stored, if this is an abstract declarator), then this is probably just
+  // grouping parens. However, if this could be an abstract-declarator, then
+  // this could also be the start of function arguments (consider 'void()').
+  bool isGrouping;
+  
+  if (!D.mayOmitIdentifier()) {
+    // If this can't be an abstract-declarator, this *must* be a grouping
+    // paren, because we haven't seen the identifier yet.
+    isGrouping = true;
+  } else if (Tok.is(tok::r_paren) ||           // 'int()' is a function.
+             isDeclarationSpecifier()) {       // 'int(int)' is a function.
+    // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
+    // considered to be a type, not a K&R identifier-list.
+    isGrouping = false;
+  } else {
+    // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
+    isGrouping = true;
+  }
+  
+  // If this is a grouping paren, handle:
+  // direct-declarator: '(' declarator ')'
+  // direct-declarator: '(' attributes declarator ')'
+  if (isGrouping) {
+    if (Tok.is(tok::kw___attribute))
+      D.AddAttributes(ParseAttributes());
+    
+    ParseDeclaratorInternal(D);
+    // Match the ')'.
+    MatchRHSPunctuation(tok::r_paren, StartLoc);
+    return;
+  }
+  
+  // Okay, if this wasn't a grouping paren, it must be the start of a function
+  // argument list.  Recognize that this declarator will never have an
+  // identifier (and remember where it would have been), then fall through to
+  // the handling of argument lists.
+  D.SetIdentifier(0, Tok.getLocation());
+
+  ParseFunctionDeclarator(StartLoc, D); 
+}
+
+/// ParseFunctionDeclarator - We are after the identifier and have parsed the
+/// declarator D up to a paren, which indicates that we are parsing function
+/// arguments.
 ///
 /// This method also handles this portion of the grammar:
 ///       parameter-type-list: [C99 6.7.5]
@@ -1188,51 +1239,9 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
 ///         identifier
 ///         identifier-list ',' identifier
 ///
-void Parser::ParseParenDeclarator(Declarator &D) {
-  SourceLocation StartLoc = ConsumeParen();
-  
-  // If we haven't past the identifier yet (or where the identifier would be
-  // stored, if this is an abstract declarator), then this is probably just
-  // grouping parens.
-  if (!D.isPastIdentifier()) {
-    // Okay, this is probably a grouping paren.  However, if this could be an
-    // abstract-declarator, then this could also be the start of function
-    // arguments (consider 'void()').
-    bool isGrouping;
-    
-    if (!D.mayOmitIdentifier()) {
-      // If this can't be an abstract-declarator, this *must* be a grouping
-      // paren, because we haven't seen the identifier yet.
-      isGrouping = true;
-    } else if (Tok.is(tok::r_paren) ||           // 'int()' is a function.
-               isDeclarationSpecifier()) {       // 'int(int)' is a function.
-      // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
-      // considered to be a type, not a K&R identifier-list.
-      isGrouping = false;
-    } else {
-      // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
-      isGrouping = true;
-    }
-    
-    // If this is a grouping paren, handle:
-    // direct-declarator: '(' declarator ')'
-    // direct-declarator: '(' attributes declarator ')'
-    if (isGrouping) {
-      if (Tok.is(tok::kw___attribute))
-        D.AddAttributes(ParseAttributes());
-      
-      ParseDeclaratorInternal(D);
-      // Match the ')'.
-      MatchRHSPunctuation(tok::r_paren, StartLoc);
-      return;
-    }
-    
-    // Okay, if this wasn't a grouping paren, it must be the start of a function
-    // argument list.  Recognize that this declarator will never have an
-    // identifier (and remember where it would have been), then fall through to
-    // the handling of argument lists.
-    D.SetIdentifier(0, Tok.getLocation());
-  }
+void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D) {
+  // lparen is already consumed!
+  assert(D.isPastIdentifier() && "Should not call before identifier!");
   
   // Okay, this is the parameter list of a function definition, or it is an
   // identifier list of a K&R-style function.
@@ -1400,7 +1409,7 @@ void Parser::ParseParenDeclarator(Declarator &D) {
   if (!ErrorEmitted)
     D.AddTypeInfo(DeclaratorChunk::getFunction(HasPrototype, IsVariadic,
                                                &ParamInfo[0], ParamInfo.size(),
-                                               StartLoc));
+                                               LParenLoc));
   
   // If we have the closing ')', eat it and we're done.
   if (Tok.is(tok::r_paren)) {
@@ -1415,6 +1424,7 @@ void Parser::ParseParenDeclarator(Declarator &D) {
 }
 
 
+
 /// [C90]   direct-declarator '[' constant-expression[opt] ']'
 /// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
 /// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'