FreeBSD/contrib/gcc/c-parser.c
/* Parse a direct declarator or direct abstract declarator; arguments
   as c_parser_declarator.  */
Parse a direct declarator or direct abstract declarator; arguments
as c_parser_declarator.
Parse a direct declarator or direct abstract declarator ; arguments as c_parser_declarator .
static struct c_declarator *
c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
			    bool *seen_id)
{
  if ((kind != C_DTR_ABSTRACT && kind != C_DTR_BLOCK)
      && c_parser_next_token_is (parser, CPP_NAME)
      && ((type_seen_p
	   && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
	       || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
	  || c_parser_peek_token (parser)->id_kind == C_ID_ID))
    {
      struct c_declarator *inner
	= build_id_declarator (c_parser_peek_token (parser)->value);
      *seen_id = true;
      inner->id_loc = c_parser_peek_token (parser)->location;
      c_parser_consume_token (parser);
      return c_parser_direct_declarator_inner (parser, *seen_id, inner);
    }
  if (kind != C_DTR_NORMAL
      && c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
    {
      struct c_declarator *inner = build_id_declarator (NULL_TREE);
      return c_parser_direct_declarator_inner (parser, *seen_id, inner);
    }
  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
    {
      tree attrs;
      struct c_declarator *inner;
      c_parser_consume_token (parser);
      attrs = c_parser_attributes (parser);
      if (kind != C_DTR_NORMAL
	  && (c_parser_next_token_starts_declspecs (parser)
	      || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
	{
	  struct c_arg_info *args
	    = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
					 attrs);
	  if (args == NULL)
	    return NULL;
	  else
	    {
	      inner
		= build_function_declarator (args,
					     build_id_declarator (NULL_TREE));
	      return c_parser_direct_declarator_inner (parser, *seen_id,
						       inner);
	    }
	}
      inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
      if (inner != NULL && attrs != NULL)
	inner = build_attrs_declarator (attrs, inner);
      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
	{
	  c_parser_consume_token (parser);
	  if (inner == NULL)
	    return NULL;
	  else
	    return c_parser_direct_declarator_inner (parser, *seen_id, inner);
	}
      else
	{
	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
				     "expected %<)%>");
	  return NULL;
	}
    }
  else
    {
      if (kind == C_DTR_NORMAL)
	{
	  c_parser_error (parser, "expected identifier or %<(%>");
	  return NULL;
	}
      else
	return build_id_declarator (NULL_TREE);
    }
}
static struct c_declarator * c_parser_direct_declarator ( c_parser * parser , bool type_seen_p , c_dtr_syn kind , bool * seen_id ) { if ( ( kind != C_DTR_ABSTRACT && kind != C_DTR_BLOCK ) && c_parser_next_token_is ( parser , CPP_NAME ) && ( ( type_seen_p && ( c_parser_peek_token ( parser ) -> id_kind == C_ID_TYPENAME || c_parser_peek_token ( parser ) -> id_kind == C_ID_CLASSNAME ) ) || c_parser_peek_token ( parser ) -> id_kind == C_ID_ID ) ) { struct c_declarator * inner = build_id_declarator ( c_parser_peek_token ( parser ) -> value ) ; * seen_id = true ; inner -> id_loc = c_parser_peek_token ( parser ) -> location ; c_parser_consume_token ( parser ) ; return c_parser_direct_declarator_inner ( parser , * seen_id , inner ) ; } if ( kind != C_DTR_NORMAL && c_parser_next_token_is ( parser , CPP_OPEN_SQUARE ) ) { struct c_declarator * inner = build_id_declarator ( NULL_TREE ) ; return c_parser_direct_declarator_inner ( parser , * seen_id , inner ) ; } if ( c_parser_next_token_is ( parser , CPP_OPEN_PAREN ) ) { tree attrs ; struct c_declarator * inner ; c_parser_consume_token ( parser ) ; attrs = c_parser_attributes ( parser ) ; if ( kind != C_DTR_NORMAL && ( c_parser_next_token_starts_declspecs ( parser ) || c_parser_next_token_is ( parser , CPP_CLOSE_PAREN ) ) ) { struct c_arg_info * args = c_parser_parms_declarator ( parser , kind == C_DTR_NORMAL , attrs ) ; if ( args == NULL ) return NULL ; else { inner = build_function_declarator ( args , build_id_declarator ( NULL_TREE ) ) ; return c_parser_direct_declarator_inner ( parser , * seen_id , inner ) ; } } inner = c_parser_declarator ( parser , type_seen_p , kind , seen_id ) ; if ( inner != NULL && attrs != NULL ) inner = build_attrs_declarator ( attrs , inner ) ; if ( c_parser_next_token_is ( parser , CPP_CLOSE_PAREN ) ) { c_parser_consume_token ( parser ) ; if ( inner == NULL ) return NULL ; else return c_parser_direct_declarator_inner ( parser , * seen_id , inner ) ; } else { c_parser_skip_until_found ( parser , CPP_CLOSE_PAREN , " " ) ; return NULL ; } } else { if ( kind == C_DTR_NORMAL ) { c_parser_error ( parser , " " ) ; return NULL ; } else return build_id_declarator ( NULL_TREE ) ; } }
Parse a direct declarator or direct abstract declarator; arguments
as c_parser_declarator.
Parse a direct declarator or direct abstract declarator ; arguments as c_parser_declarator .
/* The direct declarator must start with an identifier (possibly
     omitted) or a parenthesized declarator (possibly abstract).  In
     an ordinary declarator, initial parentheses must start a
     parenthesized declarator.  In an abstract declarator or parameter
     declarator, they could start a parenthesized declarator or a
     parameter list.  To tell which, the open parenthesis and any
     following attributes must be read.  If a declaration specifier
     follows, then it is a parameter list; if the specifier is a
     typedef name, there might be an ambiguity about redeclaring it,
     which is resolved in the direction of treating it as a typedef
     name.  If a close parenthesis follows, it is also an empty
     parameter list, as the syntax does not permit empty abstract
     declarators.  Otherwise, it is a parenthesized declarator (in
     which case the analysis may be repeated inside it, recursively).

     ??? There is an ambiguity in a parameter declaration "int
     (__attribute__((foo)) x)", where x is not a typedef name: it
     could be an abstract declarator for a function, or declare x with
     parentheses.  The proper resolution of this ambiguity needs
     documenting.  At present we follow an accident of the old
     parser's implementation, whereby the first parameter must have
     some declaration specifiers other than just attributes.  Thus as
     a parameter declaration it is treated as a parenthesized
     parameter named x, and as an abstract declarator it is
     rejected.

     ??? Also following the old parser, attributes inside an empty
     parameter list are ignored, making it a list not yielding a
     prototype, rather than giving an error or making it have one
     parameter with implicit type int.

     ??? Also following the old parser, typedef names may be
     redeclared in declarators, but not Objective-C class names.  */ /* APPLE LOCAL blocks 6339747 */ /* APPLE LOCAL begin radar 4281748 */ /* APPLE LOCAL end radar 4281748 */ /* Either we are at the end of an abstract declarator, or we have
     parentheses.  */ /* A parenthesized declarator.  */