/* Process source files and output type information.
   Copyright (C) 2006-2021 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.c.
   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 ();
}
