/* Process source files and output type information.
   Copyright (C) 2006-2022 Free Software Foundation, Inc.

   This file is part of GCC.

   GCC is free software; you can redistribute it and/or modify it under
   the terms of the GNU General Public License as published by the Free
   Software Foundation; either version 3, or (at your option) any later
   version.

   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   for more details.

   You should have received a copy of the GNU General Public License
   along with GCC; see the file COPYING3.  If not see
   <http://www.gnu.org/licenses/>.  */

#ifdef HOST_GENERATOR_FILE
#include "config.h"
#define GENERATOR_FILE 1
#else
#include "bconfig.h"
#endif
#include "system.h"
#include "gengtype.h"

/* This is a simple recursive-descent parser which understands a subset of
   the C type grammar.

   Rule functions are suffixed _seq if they scan a sequence of items;
   _opt if they may consume zero tokens; _seqopt if both are true.  The
   "consume_" prefix indicates that a sequence of tokens is parsed for
   syntactic correctness and then thrown away.  */

/* Simple one-token lookahead mechanism.  */

struct token
{
  const char *value;
  int code;
  bool valid;
};
static struct token T;

/* Retrieve the code of the current token; if there is no current token,
   get the next one from the lexer.  */
static inline int
token (void)
{
  if (!T.valid)
    {
      T.code = yylex (&T.value);
      T.valid = true;
    }
  return T.code;
}

/* Retrieve the value of the current token (if any) and mark it consumed.
   The next call to token() will get another token from the lexer.  */
static inline const char *
advance (void)
{
  T.valid = false;
  return T.value;
}

/* Diagnostics.  */

/* This array is indexed by the token code minus CHAR_TOKEN_OFFSET.  */
static const char *const token_names[] = {
  "GTY",
  "typedef",
  "extern",
  "static",
  "union",
  "struct",
  "enum",
  "...",
  "ptr_alias",
  "nested_ptr",
  "a param<N>_is option",
  "a number",
  "a scalar type",
  "an identifier",
  "a string constant",
  "a character constant",
  "an array declarator",
  "a C++ keyword to ignore"
};

/* This array is indexed by token code minus FIRST_TOKEN_WITH_VALUE.  */
static const char *const token_value_format[] = {
  "%s",
  "'%s'",
  "'%s'",
  "'%s'",
  "'\"%s\"'",
  "\"'%s'\"",
  "'[%s]'",
  "'%s'",
};

/* Produce a printable representation for a token defined by CODE and
   VALUE.  This sometimes returns pointers into malloc memory and
   sometimes not, therefore it is unsafe to free the pointer it
   returns, so that memory is leaked.  This does not matter, as this
   function is only used for diagnostics, and in a successful run of
   the program there will be none.  */
static const char *
print_token (int code, const char *value)
{
  if (code < CHAR_TOKEN_OFFSET)
    return xasprintf ("'%c'", code);
  else if (code < FIRST_TOKEN_WITH_VALUE)
    return xasprintf ("'%s'", token_names[code - CHAR_TOKEN_OFFSET]);
  else if (!value)
    return token_names[code - CHAR_TOKEN_OFFSET];	/* don't quote these */
  else
    return xasprintf (token_value_format[code - FIRST_TOKEN_WITH_VALUE],
		      value);
}

/* Convenience wrapper around print_token which produces the printable
   representation of the current token.  */
static inline const char *
print_cur_token (void)
{
  return print_token (T.code, T.value);
}

/* Report a parse error on the current line, with diagnostic MSG.
   Behaves as standard printf with respect to additional arguments and
   format escapes.  */
static void ATTRIBUTE_PRINTF_1
parse_error (const char *msg, ...)
{
  va_list ap;

  fprintf (stderr, "%s:%d: parse error: ", 
	   get_input_file_name (lexer_line.file), lexer_line.line);

  va_start (ap, msg);
  vfprintf (stderr, msg, ap);
  va_end (ap);

  fputc ('\n', stderr);

  hit_error = true;
}

/* If the next token does not have code T, report a parse error; otherwise
   return the token's value.  */
static const char *
require (int t)
{
  int u = token ();
  const char *v = advance ();
  if (u != t)
    {
      parse_error ("expected %s, have %s",
		   print_token (t, 0), print_token (u, v));
      return 0;
    }
  return v;
}

/* As per require, but do not advance.  */
static const char *
require_without_advance (int t)
{
  int u = token ();
  const char *v = T.value;
  if (u != t)
    {
      parse_error ("expected %s, have %s",
		   print_token (t, 0), print_token (u, v));
      return 0;
    }
  return v;
}

/* If the next token does not have one of the codes T1 or T2, report a
   parse error; otherwise return the token's value.  */
static const char *
require2 (int t1, int t2)
{
  int u = token ();
  const char *v = advance ();
  if (u != t1 && u != t2)
    {
      parse_error ("expected %s or %s, have %s",
		   print_token (t1, 0), print_token (t2, 0),
		   print_token (u, v));
      return 0;
    }
  return v;
}

/* If the next token does not have one of the codes T1, T2, T3 or T4, report a
   parse error; otherwise return the token's value.  */
static const char *
require4 (int t1, int t2, int t3, int t4)
{
  int u = token ();
  const char *v = advance ();
  if (u != t1 && u != t2 && u != t3 && u != t4)
    {
      parse_error ("expected %s, %s, %s or %s, have %s",
		   print_token (t1, 0), print_token (t2, 0),
		   print_token (t3, 0), print_token (t4, 0),
		   print_token (u, v));
      return 0;
    }
  return v;
}

/* Near-terminals.  */

/* C-style string constant concatenation: STRING+
   Bare STRING should appear nowhere else in this file.  */
static const char *
string_seq (void)
{
  const char *s1, *s2;
  size_t l1, l2;
  char *buf;

  s1 = require (STRING);
  if (s1 == 0)
    return "";
  while (token () == STRING)
    {
      s2 = advance ();

      l1 = strlen (s1);
      l2 = strlen (s2);
      buf = XRESIZEVEC (char, CONST_CAST (char *, s1), l1 + l2 + 1);
      memcpy (buf + l1, s2, l2 + 1);
      XDELETE (CONST_CAST (char *, s2));
      s1 = buf;
    }
  return s1;
}


/* The caller has detected a template declaration that starts
   with TMPL_NAME.  Parse up to the closing '>'.  This recognizes
   simple template declarations of the form ID<ID1,ID2,...,IDn>,
   potentially with a single level of indirection e.g.
     ID<ID1 *, ID2, ID3 *, ..., IDn>.
   It does not try to parse anything more sophisticated than that.

   Returns the template declaration string "ID<ID1,ID2,...,IDn>".  */

static const char *
require_template_declaration (const char *tmpl_name)
{
  char *str;
  int num_indirections = 0;

  /* Recognize the opening '<'.  */
  require ('<');
  str = concat (tmpl_name, "<", (char *) 0);

  /* Read the comma-separated list of identifiers.  */
  int depth = 1;
  while (depth > 0)
    {
      if (token () == ENUM)
	{
	  advance ();
	  str = concat (str, "enum ", (char *) 0);
	  continue;
	}
      if (token () == NUM
	  || token () == ':'
	  || token () == '+')
	{
	  str = concat (str, advance (), (char *) 0);
	  continue;
	}
      if (token () == '<')
	{
	  advance ();
	  str = concat (str, "<", (char *) 0);
	  depth += 1;
	  continue;
	}
      if (token () == '>')
	{
	  advance ();
	  str = concat (str, ">", (char *) 0);
	  depth -= 1;
	  continue;
	}
      const char *id = require4 (SCALAR, ID, '*', ',');
      if (id == NULL)
	{
	  if (T.code == '*')
	    {
	      id = "*";
	      if (num_indirections++)
		parse_error ("only one level of indirection is supported"
			     " in template arguments");
	    }
	  else
	    id = ",";
	}
      else
	num_indirections = 0;
      str = concat (str, id, (char *) 0);
    }
  return str;
}


/* typedef_name: either an ID, or a template type
   specification of the form ID<t1,t2,...,tn>.  */

static const char *
typedef_name (void)
{
  const char *id = require (ID);
  if (token () == '<')
    return require_template_declaration (id);
  else
    return id;
}

/* Absorb a sequence of tokens delimited by balanced ()[]{}.  */
static void
consume_balanced (int opener, int closer)
{
  require (opener);
  for (;;)
    switch (token ())
      {
      default:
	advance ();
	break;
      case '(':
	consume_balanced ('(', ')');
	break;
      case '[':
	consume_balanced ('[', ']');
	break;
      case '{':
	consume_balanced ('{', '}');
	break;

      case '}':
      case ']':
      case ')':
	if (token () != closer)
	  parse_error ("unbalanced delimiters - expected '%c', have '%c'",
		       closer, token ());
      advance ();
      return;

      case EOF_TOKEN:
	parse_error ("unexpected end of file within %c%c-delimited construct",
		     opener, closer);
	return;
      }
}

/* Absorb a sequence of tokens, possibly including ()[]{}-delimited
   expressions, until we encounter an end-of-statement marker (a ';' or
   a '}') outside any such delimiters; absorb that too.  */

static void
consume_until_eos (void)
{
  for (;;)
    switch (token ())
      {
      case ';':
	advance ();
	return;

      case '{':
	consume_balanced ('{', '}');
	return;

      case '(':
	consume_balanced ('(', ')');
	break;

      case '[':
	consume_balanced ('[', ']');
	break;

      case '}':
      case ']':
      case ')':
	parse_error ("unmatched '%c' while scanning for ';'", token ());
	return;

      case EOF_TOKEN:
	parse_error ("unexpected end of file while scanning for ';'");
	return;

      default:
	advance ();
	break;
      }
}

/* Absorb a sequence of tokens, possibly including ()[]{}-delimited
   expressions, until we encounter a comma or semicolon outside any
   such delimiters; absorb that too.  Returns true if the loop ended
   with a comma.  */

static bool
consume_until_comma_or_eos ()
{
  for (;;)
    switch (token ())
      {
      case ',':
	advance ();
	return true;

      case ';':
	advance ();
	return false;

      case '{':
	consume_balanced ('{', '}');
	return false;

      case '(':
	consume_balanced ('(', ')');
	break;

      case '[':
	consume_balanced ('[', ']');
	break;

      case '}':
      case ']':
      case ')':
	parse_error ("unmatched '%s' while scanning for ',' or ';'",
		     print_cur_token ());
      return false;

      case EOF_TOKEN:
	parse_error ("unexpected end of file while scanning for ',' or ';'");
	return false;

      default:
	advance ();
	break;
      }
}


/* GTY(()) option handling.  */
static type_p type (options_p *optsp, bool nested);

/* Optional parenthesized string: ('(' string_seq ')')? */
static options_p
str_optvalue_opt (options_p prev)
{
  const char *name = advance ();
  const char *value = "";
  if (token () == '(')
    {
      advance ();
      value = string_seq ();
      require (')');
    }
  return create_string_option (prev, name, value);
}

/* absdecl: type '*'*
   -- a vague approximation to what the C standard calls an abstract
   declarator.  The only kinds that are actually used are those that
   are just a bare type and those that have trailing pointer-stars.
   Further kinds should be implemented if and when they become
   necessary.  Used only within GTY(()) option values, therefore
   further GTY(()) tags within the type are invalid.  Note that the
   return value has already been run through adjust_field_type.  */
static type_p
absdecl (void)
{
  type_p ty;
  options_p opts;

  ty = type (&opts, true);
  while (token () == '*')
    {
      ty = create_pointer (ty);
      advance ();
    }

  if (opts)
    parse_error ("nested GTY(()) options are invalid");

  return adjust_field_type (ty, 0);
}

/* Type-option: '(' absdecl ')' */
static options_p
type_optvalue (options_p prev, const char *name)
{
  type_p ty;
  require ('(');
  ty = absdecl ();
  require (')');
  return create_type_option (prev, name, ty);
}

/* Nested pointer data: '(' type '*'* ',' string_seq ',' string_seq ')' */
static options_p
nestedptr_optvalue (options_p prev)
{
  type_p ty;
  const char *from, *to;

  require ('(');
  ty = absdecl ();
  require (',');
  to = string_seq ();
  require (',');
  from = string_seq ();
  require (')');

  return create_nested_ptr_option (prev, ty, to, from);
}

/* One GTY(()) option:
   ID str_optvalue_opt
   | PTR_ALIAS type_optvalue
   | NESTED_PTR nestedptr_optvalue
*/
static options_p
option (options_p prev)
{
  switch (token ())
    {
    case ID:
      return str_optvalue_opt (prev);

    case PTR_ALIAS:
      advance ();
      return type_optvalue (prev, "ptr_alias");

    case NESTED_PTR:
      advance ();
      return nestedptr_optvalue (prev);

    case USER_GTY:
      advance ();
      return create_string_option (prev, "user", "");

    default:
      parse_error ("expected an option keyword, have %s", print_cur_token ());
      advance ();
      return create_string_option (prev, "", "");
    }
}

/* One comma-separated list of options.  */
static options_p
option_seq (void)
{
  options_p o;

  o = option (0);
  while (token () == ',')
    {
      advance ();
      o = option (o);
    }
  return o;
}

/* GTY marker: 'GTY' '(' '(' option_seq? ')' ')' */
static options_p
gtymarker (void)
{
  options_p result = 0;
  require (GTY_TOKEN);
  require ('(');
  require ('(');
  if (token () != ')')
    result = option_seq ();
  require (')');
  require (')');
  return result;
}

/* Optional GTY marker.  */
static options_p
gtymarker_opt (void)
{
  if (token () != GTY_TOKEN)
    return 0;
  return gtymarker ();
}



/* Declarators. The logic here is largely lifted from c-parser.cc.
   Note that we do not have to process abstract declarators, which can
   appear only in parameter type lists or casts (but see absdecl,
   above).  Also, type qualifiers are thrown out in gengtype-lex.l so
   we don't have to do it.  */

/* array_and_function_declarators_opt:
   \epsilon
   array_and_function_declarators_opt ARRAY
   array_and_function_declarators_opt '(' ... ')'

   where '...' indicates stuff we ignore except insofar as grouping
   symbols ()[]{} must balance.

   Subroutine of direct_declarator - do not use elsewhere. */

static type_p
array_and_function_declarators_opt (type_p ty)
{
  if (token () == ARRAY)
    {
      const char *array = advance ();
      return create_array (array_and_function_declarators_opt (ty), array);
    }
  else if (token () == '(')
    {
      /* We don't need exact types for functions.  */
      consume_balanced ('(', ')');
      array_and_function_declarators_opt (ty);
      return create_scalar_type ("function type");
    }
  else
    return ty;
}

static type_p inner_declarator (type_p, const char **, options_p *, bool);

/* direct_declarator:
   '(' inner_declarator ')'
   '(' \epsilon ')'	<-- C++ ctors/dtors
   gtymarker_opt ID array_and_function_declarators_opt

   Subroutine of declarator, mutually recursive with inner_declarator;
   do not use elsewhere.

   IN_STRUCT is true if we are called while parsing structures or classes.  */

static type_p
direct_declarator (type_p ty, const char **namep, options_p *optsp,
		   bool in_struct)
{
  /* The first token in a direct-declarator must be an ID, a
     GTY marker, or an open parenthesis.  */
  switch (token ())
    {
    case GTY_TOKEN:
      *optsp = gtymarker ();
      /* fall through */

    case ID:
      *namep = require (ID);
      /* If the next token is '(', we are parsing a function declaration.
	 Functions are ignored by gengtype, so we return NULL.  */
      if (token () == '(')
	return NULL;
      break;

    case '(':
      /* If the declarator starts with a '(', we have three options.  We
	 are either parsing 'TYPE (*ID)' (i.e., a function pointer)
	 or 'TYPE(...)'.

	 The latter will be a constructor iff we are inside a
	 structure or class.  Otherwise, it could be a typedef, but
	 since we explicitly reject typedefs inside structures, we can
	 assume that we found a ctor and return NULL.  */
      advance ();
      if (in_struct && token () != '*')
	{
	  /* Found a constructor.  Find and consume the closing ')'.  */
	  while (token () != ')')
	    advance ();
	  advance ();
	  /* Tell the caller to ignore this.  */
	  return NULL;
	}
      ty = inner_declarator (ty, namep, optsp, in_struct);
      require (')');
      break;

    case IGNORABLE_CXX_KEYWORD:
      /* Any C++ keyword like 'operator' means that we are not looking
	 at a regular data declarator.  */
      return NULL;

    default:
      parse_error ("expected '(', ')', 'GTY', or an identifier, have %s",
		   print_cur_token ());
      /* Do _not_ advance if what we have is a close squiggle brace, as
	 we will get much better error recovery that way.  */
      if (token () != '}')
	advance ();
      return 0;
    }
  return array_and_function_declarators_opt (ty);
}

/* The difference between inner_declarator and declarator is in the
   handling of stars.  Consider this declaration:

   char * (*pfc) (void)

   It declares a pointer to a function that takes no arguments and
   returns a char*.  To construct the correct type for this
   declaration, the star outside the parentheses must be processed
   _before_ the function type, the star inside the parentheses must
   be processed _after_ the function type.  To accomplish this,
   declarator() creates pointers before recursing (it is actually
   coded as a while loop), whereas inner_declarator() recurses before
   creating pointers.  */

/* inner_declarator:
   '*' inner_declarator
   direct_declarator

   Mutually recursive subroutine of direct_declarator; do not use
   elsewhere.

   IN_STRUCT is true if we are called while parsing structures or classes.  */

static type_p
inner_declarator (type_p ty, const char **namep, options_p *optsp,
		  bool in_struct)
{
  if (token () == '*')
    {
      type_p inner;
      advance ();
      inner = inner_declarator (ty, namep, optsp, in_struct);
      if (inner == 0)
	return 0;
      else
	return create_pointer (ty);
    }
  else
    return direct_declarator (ty, namep, optsp, in_struct);
}

/* declarator: '*'+ direct_declarator

   This is the sole public interface to this part of the grammar.
   Arguments are the type known so far, a pointer to where the name
   may be stored, and a pointer to where GTY options may be stored.

   IN_STRUCT is true when we are called to parse declarators inside
   a structure or class.

   Returns the final type.  */

static type_p
declarator (type_p ty, const char **namep, options_p *optsp,
	    bool in_struct = false)
{
  *namep = 0;
  *optsp = 0;
  while (token () == '*')
    {
      advance ();
      ty = create_pointer (ty);
    }
  return direct_declarator (ty, namep, optsp, in_struct);
}

/* Types and declarations.  */

/* Structure field(s) declaration:
   (
   type bitfield ';'
   | type declarator bitfield? ( ',' declarator bitfield? )+ ';'
   )*

   Knows that such declarations must end with a close brace (or,
   erroneously, at EOF).
*/
static pair_p
struct_field_seq (void)
{
  pair_p f = 0;
  type_p ty, dty;
  options_p opts, dopts;
  const char *name;
  bool another;

  while (token () != '}' && token () != EOF_TOKEN)
    {
      ty = type (&opts, true);

      /* Ignore access-control keywords ("public:" etc).  */
      while (!ty && token () == IGNORABLE_CXX_KEYWORD)
	{
	  const char *keyword = advance ();
	  if (strcmp (keyword, "public:") != 0
	      && strcmp (keyword, "private:") != 0
	      && strcmp (keyword, "protected:") != 0)
	    break;
	  ty = type (&opts, true);
	}

      if (!ty || token () == ':')
	{
	  consume_until_eos ();
	  continue;
	}

      do
	{
	  dty = declarator (ty, &name, &dopts, true);

	  /* There could be any number of weird things after the declarator,
	     notably bitfield declarations and __attribute__s.  If this
	     function returns true, the last thing was a comma, so we have
	     more than one declarator paired with the current type.  */
	  another = consume_until_comma_or_eos ();

	  if (!dty)
	    continue;

	  if (opts && dopts)
	    parse_error ("two GTY(()) options for field %s", name);
	  if (opts && !dopts)
	    dopts = opts;

	  f = create_field_at (f, dty, name, dopts, &lexer_line);
	}
      while (another);
    }
  return nreverse_pairs (f);
}

/* Return true if OPTS contain the option named STR.  */

bool
opts_have (options_p opts, const char *str)
{
  for (options_p opt = opts; opt; opt = opt->next)
    if (strcmp (opt->name, str) == 0)
      return true;
  return false;
}


/* This is called type(), but what it parses (sort of) is what C calls
   declaration-specifiers and specifier-qualifier-list:

   SCALAR
   | ID     // typedef
   | (STRUCT|UNION) ID? gtymarker? ( '{' gtymarker? struct_field_seq '}' )?
   | ENUM ID ( '{' ... '}' )?

   Returns a partial type; under some conditions (notably
   "struct foo GTY((...)) thing;") it may write an options
   structure to *OPTSP.

   NESTED is true when parsing a declaration already known to have a
   GTY marker. In these cases, typedef and enum declarations are not
   allowed because gengtype only understands types at the global
   scope.  */

static type_p
type (options_p *optsp, bool nested)
{
  const char *s;
  *optsp = 0;
  switch (token ())
    {
    case SCALAR:
      s = advance ();
      return create_scalar_type (s);

    case ID:
      s = typedef_name ();
      return resolve_typedef (s, &lexer_line);

    case IGNORABLE_CXX_KEYWORD:
      /* By returning NULL here, we indicate to the caller that they
	 should ignore everything following this keyword up to the
	 next ';' or '}'.  */
      return NULL;

    case STRUCT:
    case UNION:
      {
	type_p base_class = NULL;
	options_p opts = 0;
	/* GTY annotations follow attribute syntax
	   GTY_BEFORE_ID is for union/struct declarations
	   GTY_AFTER_ID is for variable declarations.  */
	enum
	{
	  NO_GTY,
	  GTY_BEFORE_ID,
	  GTY_AFTER_ID
	} is_gty = NO_GTY;
	enum typekind kind = (token () == UNION) ? TYPE_UNION : TYPE_STRUCT;
	advance ();

	/* Top-level structures that are not explicitly tagged GTY(())
	   are treated as mere forward declarations.  This is because
	   there are a lot of structures that we don't need to know
	   about, and some of those have C++ and macro constructs that
	   we cannot handle.  */
	if (nested || token () == GTY_TOKEN)
	  {
	    is_gty = GTY_BEFORE_ID;
	    opts = gtymarker_opt ();
	  }

	if (token () == ID)
	  s = advance ();
	else
	  s = xasprintf ("anonymous:%s:%d",
			 get_input_file_name (lexer_line.file),
			 lexer_line.line);

	/* Unfortunately above GTY_TOKEN check does not capture the
	   typedef struct_type GTY case.  */
	if (token () == GTY_TOKEN)
	  {
	    is_gty = GTY_AFTER_ID;
	    opts = gtymarker_opt ();
	  }

	bool is_user_gty = opts_have (opts, "user");

	if (token () == ':')
	  {
	    if (is_gty && !is_user_gty)
	      {
		/* For GTY-marked types that are not "user", parse some C++
		   inheritance specifications.
		   We require single-inheritance from a non-template type.  */
		advance ();
		const char *basename = require (ID);
		/* This may be either an access specifier, or the base name.  */
		if (strcmp (basename, "public") == 0
		    || strcmp (basename, "protected") == 0
		    || strcmp (basename, "private") == 0)
		  basename = require (ID);
		base_class = find_structure (basename, TYPE_STRUCT);
		if (!base_class)
		  parse_error ("unrecognized base class: %s", basename);
		require_without_advance ('{');
	      }
	    else
	      {
		/* For types lacking GTY-markings, skip over C++ inheritance
		   specification (and thus avoid having to parse e.g. template
		   types).  */
		while (token () != '{')
		  advance ();
	      }
	  }

	if (is_gty)
	  {
	    if (token () == '{')
	      {
		pair_p fields;

		if (is_gty == GTY_AFTER_ID)
		  parse_error ("GTY must be specified before identifier");

		if (!is_user_gty)
		  {
		    advance ();
		    fields = struct_field_seq ();
		    require ('}');
		  }
		else
		  {
		    /* Do not look inside user defined structures.  */
		    fields = NULL;
		    kind = TYPE_USER_STRUCT;
		    consume_balanced ('{', '}');
		    return create_user_defined_type (s, &lexer_line);
		  }

		return new_structure (s, kind, &lexer_line, fields, opts,
				      base_class);
	      }
	  }
	else if (token () == '{')
	  consume_balanced ('{', '}');
	if (opts)
	  *optsp = opts;
	return find_structure (s, kind);
      }

    case TYPEDEF:
      /* In C++, a typedef inside a struct/class/union defines a new
	 type for that inner scope.  We cannot support this in
	 gengtype because we have no concept of scoping.

	 We handle typedefs in the global scope separately (see
	 parse_file), so if we find a 'typedef', we must be inside
	 a struct.  */
      gcc_assert (nested);
      parse_error ("typedefs not supported in structures marked with "
		   "automatic GTY markers.  Use GTY((user)) to mark "
		   "this structure.");
      advance ();
      return NULL;

    case ENUM:
      advance ();
      if (token () == ID)
	s = advance ();
      else
	s = xasprintf ("anonymous:%s:%d",
		       get_input_file_name (lexer_line.file),
		       lexer_line.line);

      if (token () == '{')
	consume_balanced ('{', '}');

      /* If after parsing the enum we are at the end of the statement,
	 and we are currently inside a structure, then this was an
	 enum declaration inside this scope.

	 We cannot support this for the same reason we cannot support
	 'typedef' inside structures (see the TYPEDEF handler above).
	 If this happens, emit an error and return NULL.  */
      if (nested && token () == ';')
	{
	  parse_error ("enum definitions not supported in structures marked "
		       "with automatic GTY markers.  Use GTY((user)) to mark "
	               "this structure.");
	  advance ();
	  return NULL;
	}

      return create_scalar_type (s);

    default:
      parse_error ("expected a type specifier, have %s", print_cur_token ());
      advance ();
      return create_scalar_type ("erroneous type");
    }
}

/* Top level constructs.  */

/* Dispatch declarations beginning with 'typedef'.  */

static void
typedef_decl (void)
{
  type_p ty, dty;
  const char *name;
  options_p opts;
  bool another;

  gcc_assert (token () == TYPEDEF);
  advance ();

  ty = type (&opts, false);
  if (!ty)
    return;
  if (opts)
    parse_error ("GTY((...)) cannot be applied to a typedef");
  do
    {
      dty = declarator (ty, &name, &opts);
      if (opts)
	parse_error ("GTY((...)) cannot be applied to a typedef");

      /* Yet another place where we could have junk (notably attributes)
	 after the declarator.  */
      another = consume_until_comma_or_eos ();
      if (dty)
	do_typedef (name, dty, &lexer_line);
    }
  while (another);
}

/* Structure definition: type() does all the work.  */

static void
struct_or_union (void)
{
  options_p dummy;
  type (&dummy, false);
  /* There may be junk after the type: notably, we cannot currently
     distinguish 'struct foo *function(prototype);' from 'struct foo;'
     ...  we could call declarator(), but it's a waste of time at
     present.  Instead, just eat whatever token is currently lookahead
     and go back to lexical skipping mode. */
  advance ();
}

/* GC root declaration:
   (extern|static) gtymarker? type ID array_declarators_opt (';'|'=')
   If the gtymarker is not present, we ignore the rest of the declaration.  */
static void
extern_or_static (void)
{
  options_p opts, opts2, dopts;
  type_p ty, dty;
  const char *name;
  require2 (EXTERN, STATIC);

  if (token () != GTY_TOKEN)
    {
      advance ();
      return;
    }

  opts = gtymarker ();
  ty = type (&opts2, true);	/* if we get here, it's got a GTY(()) */
  dty = declarator (ty, &name, &dopts);

  if ((opts && dopts) || (opts && opts2) || (opts2 && dopts))
    parse_error ("GTY((...)) specified more than once for %s", name);
  else if (opts2)
    opts = opts2;
  else if (dopts)
    opts = dopts;

  if (dty)
    {
      note_variable (name, adjust_field_type (dty, opts), opts, &lexer_line);
      require2 (';', '=');
    }
}

/* Parse the file FNAME for GC-relevant declarations and definitions.
   This is the only entry point to this file.  */
void
parse_file (const char *fname)
{
  yybegin (fname);
  for (;;)
    {
      switch (token ())
	{
	case EXTERN:
	case STATIC:
	  extern_or_static ();
	  break;

	case STRUCT:
	case UNION:
	  struct_or_union ();
	  break;

	case TYPEDEF:
	  typedef_decl ();
	  break;

	case EOF_TOKEN:
	  goto eof;

	default:
	  parse_error ("unexpected top level token, %s", print_cur_token ());
	  goto eof;
	}
      lexer_toplevel_done = 1;
    }

 eof:
  advance ();
  yyend ();
}
