/* Process declarations and variables for C compiler.
   Copyright (C) 1988-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/>.  */

/* Process declarations and symbol lookup for C front end.
   Also constructs types; the standard scalar types at initialization,
   and structure, union, array and enum types when they are declared.  */

/* ??? not all decl nodes are given the most useful possible
   line numbers.  For example, the CONST_DECLs for enum values.  */

#include "config.h"
#define INCLUDE_STRING
#define INCLUDE_UNIQUE_PTR
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "function.h"
#include "c-tree.h"
#include "timevar.h"
#include "stringpool.h"
#include "cgraph.h"
#include "intl.h"
#include "print-tree.h"
#include "stor-layout.h"
#include "varasm.h"
#include "attribs.h"
#include "toplev.h"
#include "debug.h"
#include "c-family/c-objc.h"
#include "c-family/c-pragma.h"
#include "c-family/c-ubsan.h"
#include "c-lang.h"
#include "langhooks.h"
#include "tree-iterator.h"
#include "dumpfile.h"
#include "plugin.h"
#include "c-family/c-ada-spec.h"
#include "builtins.h"
#include "spellcheck-tree.h"
#include "gcc-rich-location.h"
#include "asan.h"
#include "c-family/name-hint.h"
#include "c-family/known-headers.h"
#include "c-family/c-spellcheck.h"
#include "context.h"  /* For 'g'.  */
#include "omp-general.h"
#include "omp-offload.h"  /* For offload_vars.  */

#include "tree-pretty-print.h"

/* In grokdeclarator, distinguish syntactic contexts of declarators.  */
enum decl_context
{ NORMAL,			/* Ordinary declaration */
  FUNCDEF,			/* Function definition */
  PARM,				/* Declaration of parm before function body */
  FIELD,			/* Declaration inside struct or union */
  TYPENAME};			/* Typename (inside cast or sizeof)  */

/* States indicating how grokdeclarator() should handle declspecs marked
   with __attribute__((deprecated)) or __attribute__((unavailable)).
   An object declared as __attribute__((unavailable)) should suppress
   any reports of being declared  with unavailable or deprecated items.
   An object declared as __attribute__((deprecated)) should suppress
   warnings of uses of other deprecated items.  */

enum deprecated_states {
  DEPRECATED_NORMAL,
  DEPRECATED_SUPPRESS,
  UNAVAILABLE_DEPRECATED_SUPPRESS
};


/* Nonzero if we have seen an invalid cross reference
   to a struct, union, or enum, but not yet printed the message.  */
tree pending_invalid_xref;

/* File and line to appear in the eventual error message.  */
location_t pending_invalid_xref_location;

/* The file and line that the prototype came from if this is an
   old-style definition; used for diagnostics in
   store_parm_decls_oldstyle.  */

static location_t current_function_prototype_locus;

/* Whether this prototype was built-in.  */

static bool current_function_prototype_built_in;

/* The argument type information of this prototype.  */

static tree current_function_prototype_arg_types;

/* The argument information structure for the function currently being
   defined.  */

static struct c_arg_info *current_function_arg_info;

/* The obstack on which parser and related data structures, which are
   not live beyond their top-level declaration or definition, are
   allocated.  */
struct obstack parser_obstack;

/* The current statement tree.  */

static GTY(()) struct stmt_tree_s c_stmt_tree;

/* Zero if we are not in an iteration or switch statement, otherwise
   a bitmask.  See bitmask definitions in c-tree.h.  */
unsigned char in_statement;

/* A list of decls to be made automatically visible in each file scope.  */
static GTY(()) tree visible_builtins;

/* Set to 0 at beginning of a function definition, set to 1 if
   a return statement that specifies a return value is seen.  */

int current_function_returns_value;

/* Set to 0 at beginning of a function definition, set to 1 if
   a return statement with no argument is seen.  */

int current_function_returns_null;

/* Set to 0 at beginning of a function definition, set to 1 if
   a call to a noreturn function is seen.  */

int current_function_returns_abnormally;

/* Set to nonzero by `grokdeclarator' for a function
   whose return type is defaulted, if warnings for this are desired.  */

static int warn_about_return_type;

/* Nonzero when the current toplevel function contains a declaration
   of a nested function which is never defined.  */

static bool undef_nested_function;

/* If non-zero, implicit "omp declare target" attribute is added into the
   attribute lists.  */
int current_omp_declare_target_attribute;

/* Each c_binding structure describes one binding of an identifier to
   a decl.  All the decls in a scope - irrespective of namespace - are
   chained together by the ->prev field, which (as the name implies)
   runs in reverse order.  All the decls in a given namespace bound to
   a given identifier are chained by the ->shadowed field, which runs
   from inner to outer scopes.

   The ->decl field usually points to a DECL node, but there are two
   exceptions.  In the namespace of type tags, the bound entity is a
   RECORD_TYPE, UNION_TYPE, or ENUMERAL_TYPE node.  If an undeclared
   identifier is encountered, it is bound to error_mark_node to
   suppress further errors about that identifier in the current
   function.

   The ->u.type field stores the type of the declaration in this scope;
   if NULL, the type is the type of the ->decl field.  This is only of
   relevance for objects with external or internal linkage which may
   be redeclared in inner scopes, forming composite types that only
   persist for the duration of those scopes.  In the external scope,
   this stores the composite of all the types declared for this
   object, visible or not.  The ->inner_comp field (used only at file
   scope) stores whether an incomplete array type at file scope was
   completed at an inner scope to an array size other than 1.

   The ->u.label field is used for labels.  It points to a structure
   which stores additional information used for warnings.

   The depth field is copied from the scope structure that holds this
   decl.  It is used to preserve the proper ordering of the ->shadowed
   field (see bind()) and also for a handful of special-case checks.
   Finally, the invisible bit is true for a decl which should be
   ignored for purposes of normal name lookup, and the nested bit is
   true for a decl that's been bound a second time in an inner scope;
   in all such cases, the binding in the outer scope will have its
   invisible bit true.  */

struct GTY((chain_next ("%h.prev"))) c_binding {
  union GTY(()) {		/* first so GTY desc can use decl */
    tree GTY((tag ("0"))) type; /* the type in this scope */
    struct c_label_vars * GTY((tag ("1"))) label; /* for warnings */
  } GTY((desc ("TREE_CODE (%0.decl) == LABEL_DECL"))) u;
  tree decl;			/* the decl bound */
  tree id;			/* the identifier it's bound to */
  struct c_binding *prev;	/* the previous decl in this scope */
  struct c_binding *shadowed;	/* the innermost decl shadowed by this one */
  unsigned int depth : 28;      /* depth of this scope */
  BOOL_BITFIELD invisible : 1;  /* normal lookup should ignore this binding */
  BOOL_BITFIELD nested : 1;     /* do not set DECL_CONTEXT when popping */
  BOOL_BITFIELD inner_comp : 1; /* incomplete array completed in inner scope */
  BOOL_BITFIELD in_struct : 1;	/* currently defined as struct field */
  location_t locus;		/* location for nested bindings */
};
#define B_IN_SCOPE(b1, b2) ((b1)->depth == (b2)->depth)
#define B_IN_CURRENT_SCOPE(b) ((b)->depth == current_scope->depth)
#define B_IN_FILE_SCOPE(b) ((b)->depth == 1 /*file_scope->depth*/)
#define B_IN_EXTERNAL_SCOPE(b) ((b)->depth == 0 /*external_scope->depth*/)

/* Each C symbol points to three linked lists of c_binding structures.
   These describe the values of the identifier in the three different
   namespaces defined by the language.  */

struct GTY(()) lang_identifier {
  struct c_common_identifier common_id;
  struct c_binding *symbol_binding; /* vars, funcs, constants, typedefs */
  struct c_binding *tag_binding;    /* struct/union/enum tags */
  struct c_binding *label_binding;  /* labels */
};

/* Validate c-lang.c's assumptions.  */
extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate
[(sizeof(struct lang_identifier) == C_SIZEOF_STRUCT_LANG_IDENTIFIER) ? 1 : -1];

/* The binding oracle; see c-tree.h.  */
void (*c_binding_oracle) (enum c_oracle_request, tree identifier);

/* This flag is set on an identifier if we have previously asked the
   binding oracle for this identifier's symbol binding.  */
#define I_SYMBOL_CHECKED(node) \
  (TREE_LANG_FLAG_4 (IDENTIFIER_NODE_CHECK (node)))

static inline struct c_binding* *
i_symbol_binding (tree node)
{
  struct lang_identifier *lid
    = (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);

  if (lid->symbol_binding == NULL
      && c_binding_oracle != NULL
      && !I_SYMBOL_CHECKED (node))
    {
      /* Set the "checked" flag first, to avoid infinite recursion
	 when the binding oracle calls back into gcc.  */
      I_SYMBOL_CHECKED (node) = 1;
      c_binding_oracle (C_ORACLE_SYMBOL, node);
    }

  return &lid->symbol_binding;
}

#define I_SYMBOL_BINDING(node) (*i_symbol_binding (node))

#define I_SYMBOL_DECL(node) \
 (I_SYMBOL_BINDING(node) ? I_SYMBOL_BINDING(node)->decl : 0)

/* This flag is set on an identifier if we have previously asked the
   binding oracle for this identifier's tag binding.  */
#define I_TAG_CHECKED(node) \
  (TREE_LANG_FLAG_5 (IDENTIFIER_NODE_CHECK (node)))

static inline struct c_binding **
i_tag_binding (tree node)
{
  struct lang_identifier *lid
    = (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);

  if (lid->tag_binding == NULL
      && c_binding_oracle != NULL
      && !I_TAG_CHECKED (node))
    {
      /* Set the "checked" flag first, to avoid infinite recursion
	 when the binding oracle calls back into gcc.  */
      I_TAG_CHECKED (node) = 1;
      c_binding_oracle (C_ORACLE_TAG, node);
    }

  return &lid->tag_binding;
}

#define I_TAG_BINDING(node) (*i_tag_binding (node))

#define I_TAG_DECL(node) \
 (I_TAG_BINDING(node) ? I_TAG_BINDING(node)->decl : 0)

/* This flag is set on an identifier if we have previously asked the
   binding oracle for this identifier's label binding.  */
#define I_LABEL_CHECKED(node) \
  (TREE_LANG_FLAG_6 (IDENTIFIER_NODE_CHECK (node)))

static inline struct c_binding **
i_label_binding (tree node)
{
  struct lang_identifier *lid
    = (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);

  if (lid->label_binding == NULL
      && c_binding_oracle != NULL
      && !I_LABEL_CHECKED (node))
    {
      /* Set the "checked" flag first, to avoid infinite recursion
	 when the binding oracle calls back into gcc.  */
      I_LABEL_CHECKED (node) = 1;
      c_binding_oracle (C_ORACLE_LABEL, node);
    }

  return &lid->label_binding;
}

#define I_LABEL_BINDING(node) (*i_label_binding (node))

#define I_LABEL_DECL(node) \
 (I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)

/* The resulting tree type.  */

union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
       chain_next ("(union lang_tree_node *) c_tree_chain_next (&%h.generic)"))) lang_tree_node
 {
  union tree_node GTY ((tag ("0"),
			desc ("tree_node_structure (&%h)")))
    generic;
  struct lang_identifier GTY ((tag ("1"))) identifier;
};

/* Track bindings and other things that matter for goto warnings.  For
   efficiency, we do not gather all the decls at the point of
   definition.  Instead, we point into the bindings structure.  As
   scopes are popped, we update these structures and gather the decls
   that matter at that time.  */

struct GTY(()) c_spot_bindings {
  /* The currently open scope which holds bindings defined when the
     label was defined or the goto statement was found.  */
  struct c_scope *scope;
  /* The bindings in the scope field which were defined at the point
     of the label or goto.  This lets us look at older or newer
     bindings in the scope, as appropriate.  */
  struct c_binding *bindings_in_scope;
  /* The number of statement expressions that have started since this
     label or goto statement was defined.  This is zero if we are at
     the same statement expression level.  It is positive if we are in
     a statement expression started since this spot.  It is negative
     if this spot was in a statement expression and we have left
     it.  */
  int stmt_exprs;
  /* Whether we started in a statement expression but are no longer in
     it.  This is set to true if stmt_exprs ever goes negative.  */
  bool left_stmt_expr;
};

/* This structure is used to keep track of bindings seen when a goto
   statement is defined.  This is only used if we see the goto
   statement before we see the label.  */

struct GTY(()) c_goto_bindings {
  /* The location of the goto statement.  */
  location_t loc;
  /* The bindings of the goto statement.  */
  struct c_spot_bindings goto_bindings;
};

typedef struct c_goto_bindings *c_goto_bindings_p;

/* The additional information we keep track of for a label binding.
   These fields are updated as scopes are popped.  */

struct GTY(()) c_label_vars {
  /* The shadowed c_label_vars, when one label shadows another (which
     can only happen using a __label__ declaration).  */
  struct c_label_vars *shadowed;
  /* The bindings when the label was defined.  */
  struct c_spot_bindings label_bindings;
  /* A list of decls that we care about: decls about which we should
     warn if a goto branches to this label from later in the function.
     Decls are added to this list as scopes are popped.  We only add
     the decls that matter.  */
  vec<tree, va_gc> *decls_in_scope;
  /* A list of goto statements to this label.  This is only used for
     goto statements seen before the label was defined, so that we can
     issue appropriate warnings for them.  */
  vec<c_goto_bindings_p, va_gc> *gotos;
};

/* Each c_scope structure describes the complete contents of one
   scope.  Four scopes are distinguished specially: the innermost or
   current scope, the innermost function scope, the file scope (always
   the second to outermost) and the outermost or external scope.

   Most declarations are recorded in the current scope.

   All normal label declarations are recorded in the innermost
   function scope, as are bindings of undeclared identifiers to
   error_mark_node.  (GCC permits nested functions as an extension,
   hence the 'innermost' qualifier.)  Explicitly declared labels
   (using the __label__ extension) appear in the current scope.

   Being in the file scope (current_scope == file_scope) causes
   special behavior in several places below.  Also, under some
   conditions the Objective-C front end records declarations in the
   file scope even though that isn't the current scope.

   All declarations with external linkage are recorded in the external
   scope, even if they aren't visible there; this models the fact that
   such declarations are visible to the entire program, and (with a
   bit of cleverness, see pushdecl) allows diagnosis of some violations
   of C99 6.2.2p7 and 6.2.7p2:

     If, within the same translation unit, the same identifier appears
     with both internal and external linkage, the behavior is
     undefined.

     All declarations that refer to the same object or function shall
     have compatible type; otherwise, the behavior is undefined.

   Initially only the built-in declarations, which describe compiler
   intrinsic functions plus a subset of the standard library, are in
   this scope.

   The order of the blocks list matters, and it is frequently appended
   to.  To avoid having to walk all the way to the end of the list on
   each insertion, or reverse the list later, we maintain a pointer to
   the last list entry.  (FIXME: It should be feasible to use a reversed
   list here.)

   The bindings list is strictly in reverse order of declarations;
   pop_scope relies on this.  */


struct GTY((chain_next ("%h.outer"))) c_scope {
  /* The scope containing this one.  */
  struct c_scope *outer;

  /* The next outermost function scope.  */
  struct c_scope *outer_function;

  /* All bindings in this scope.  */
  struct c_binding *bindings;

  /* For each scope (except the global one), a chain of BLOCK nodes
     for all the scopes that were entered and exited one level down.  */
  tree blocks;
  tree blocks_last;

  /* The depth of this scope.  Used to keep the ->shadowed chain of
     bindings sorted innermost to outermost.  */
  unsigned int depth : 28;

  /* True if we are currently filling this scope with parameter
     declarations.  */
  BOOL_BITFIELD parm_flag : 1;

  /* True if we saw [*] in this scope.  Used to give an error messages
     if these appears in a function definition.  */
  BOOL_BITFIELD had_vla_unspec : 1;

  /* True if we already complained about forward parameter decls
     in this scope.  This prevents double warnings on
     foo (int a; int b; ...)  */
  BOOL_BITFIELD warned_forward_parm_decls : 1;

  /* True if this is the outermost block scope of a function body.
     This scope contains the parameters, the local variables declared
     in the outermost block, and all the labels (except those in
     nested functions, or declared at block scope with __label__).  */
  BOOL_BITFIELD function_body : 1;

  /* True means make a BLOCK for this scope no matter what.  */
  BOOL_BITFIELD keep : 1;

  /* True means that an unsuffixed float constant is _Decimal64.  */
  BOOL_BITFIELD float_const_decimal64 : 1;

  /* True if this scope has any label bindings.  This is used to speed
     up searching for labels when popping scopes, particularly since
     labels are normally only found at function scope.  */
  BOOL_BITFIELD has_label_bindings : 1;

  /* True if we should issue a warning if a goto statement crosses any
     of the bindings.  We still need to check the list of bindings to
     find the specific ones we need to warn about.  This is true if
     decl_jump_unsafe would return true for any of the bindings.  This
     is used to avoid looping over all the bindings unnecessarily.  */
  BOOL_BITFIELD has_jump_unsafe_decl : 1;
};

/* The scope currently in effect.  */

static GTY(()) struct c_scope *current_scope;

/* The innermost function scope.  Ordinary (not explicitly declared)
   labels, bindings to error_mark_node, and the lazily-created
   bindings of __func__ and its friends get this scope.  */

static GTY(()) struct c_scope *current_function_scope;

/* The C file scope.  This is reset for each input translation unit.  */

static GTY(()) struct c_scope *file_scope;

/* The outermost scope.  This is used for all declarations with
   external linkage, and only these, hence the name.  */

static GTY(()) struct c_scope *external_scope;

/* A chain of c_scope structures awaiting reuse.  */

static GTY((deletable)) struct c_scope *scope_freelist;

/* A chain of c_binding structures awaiting reuse.  */

static GTY((deletable)) struct c_binding *binding_freelist;

/* Append VAR to LIST in scope SCOPE.  */
#define SCOPE_LIST_APPEND(scope, list, decl) do {	\
  struct c_scope *s_ = (scope);				\
  tree d_ = (decl);					\
  if (s_->list##_last)					\
    BLOCK_CHAIN (s_->list##_last) = d_;			\
  else							\
    s_->list = d_;					\
  s_->list##_last = d_;					\
} while (0)

/* Concatenate FROM in scope FSCOPE onto TO in scope TSCOPE.  */
#define SCOPE_LIST_CONCAT(tscope, to, fscope, from) do {	\
  struct c_scope *t_ = (tscope);				\
  struct c_scope *f_ = (fscope);				\
  if (t_->to##_last)						\
    BLOCK_CHAIN (t_->to##_last) = f_->from;			\
  else								\
    t_->to = f_->from;						\
  t_->to##_last = f_->from##_last;				\
} while (0)

/* A c_inline_static structure stores details of a static identifier
   referenced in a definition of a function that may be an inline
   definition if no subsequent declaration of that function uses
   "extern" or does not use "inline".  */

struct GTY((chain_next ("%h.next"))) c_inline_static {
  /* The location for a diagnostic.  */
  location_t location;

  /* The function that may be an inline definition.  */
  tree function;

  /* The object or function referenced.  */
  tree static_decl;

  /* What sort of reference this is.  */
  enum c_inline_static_type type;

  /* The next such structure or NULL.  */
  struct c_inline_static *next;
};

/* List of static identifiers used or referenced in functions that may
   be inline definitions.  */
static GTY(()) struct c_inline_static *c_inline_statics;

/* True means unconditionally make a BLOCK for the next scope pushed.  */

static bool keep_next_level_flag;

/* True means the next call to push_scope will be the outermost scope
   of a function body, so do not push a new scope, merely cease
   expecting parameter decls.  */

static bool next_is_function_body;

/* A vector of pointers to c_binding structures.  */

typedef struct c_binding *c_binding_ptr;

/* Information that we keep for a struct or union while it is being
   parsed.  */

class c_struct_parse_info
{
public:
  /* If warn_cxx_compat, a list of types defined within this
     struct.  */
  auto_vec<tree> struct_types;
  /* If warn_cxx_compat, a list of field names which have bindings,
     and which are defined in this struct, but which are not defined
     in any enclosing struct.  This is used to clear the in_struct
     field of the c_bindings structure.  */
  auto_vec<c_binding_ptr> fields;
  /* If warn_cxx_compat, a list of typedef names used when defining
     fields in this struct.  */
  auto_vec<tree> typedefs_seen;
};

/* Information for the struct or union currently being parsed, or
   NULL if not parsing a struct or union.  */
static class c_struct_parse_info *struct_parse_info;

/* Forward declarations.  */
static tree lookup_name_in_scope (tree, struct c_scope *);
static tree c_make_fname_decl (location_t, tree, int);
static tree grokdeclarator (const struct c_declarator *,
			    struct c_declspecs *,
			    enum decl_context, bool, tree *, tree *, tree *,
			    bool *, enum deprecated_states);
static tree grokparms (struct c_arg_info *, bool);
static void layout_array_type (tree);
static void warn_defaults_to (location_t, int, const char *, ...)
    ATTRIBUTE_GCC_DIAG(3,4);
static const char *header_for_builtin_fn (tree);

/* T is a statement.  Add it to the statement-tree.  This is the
   C/ObjC version--C++ has a slightly different version of this
   function.  */

tree
add_stmt (tree t)
{
  enum tree_code code = TREE_CODE (t);

  if (CAN_HAVE_LOCATION_P (t) && code != LABEL_EXPR)
    {
      if (!EXPR_HAS_LOCATION (t))
	SET_EXPR_LOCATION (t, input_location);
    }

  if (code == LABEL_EXPR || code == CASE_LABEL_EXPR)
    STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1;

  /* Add T to the statement-tree.  Non-side-effect statements need to be
     recorded during statement expressions.  */
  if (!building_stmt_list_p ())
    push_stmt_list ();
  append_to_statement_list_force (t, &cur_stmt_list);

  return t;
}

/* Build a pointer type using the default pointer mode.  */

static tree
c_build_pointer_type (tree to_type)
{
  addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
					      : TYPE_ADDR_SPACE (to_type);
  machine_mode pointer_mode;

  if (as != ADDR_SPACE_GENERIC || c_default_pointer_mode == VOIDmode)
    pointer_mode = targetm.addr_space.pointer_mode (as);
  else
    pointer_mode = c_default_pointer_mode;
  return build_pointer_type_for_mode (to_type, pointer_mode, false);
}


/* Return true if we will want to say something if a goto statement
   crosses DECL.  */

static bool
decl_jump_unsafe (tree decl)
{
  if (error_operand_p (decl))
    return false;

  /* Don't warn for compound literals.  If a goto statement crosses
     their initialization, it should cross also all the places where
     the complit is used or where the complit address might be saved
     into some variable, so code after the label to which goto jumps
     should not be able to refer to the compound literal.  */
  if (VAR_P (decl) && C_DECL_COMPOUND_LITERAL_P (decl))
    return false;

  /* Always warn about crossing variably modified types.  */
  if ((VAR_P (decl) || TREE_CODE (decl) == TYPE_DECL)
      && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
    return true;

  /* Otherwise, only warn if -Wgoto-misses-init and this is an
     initialized automatic decl.  */
  if (warn_jump_misses_init
      && VAR_P (decl)
      && !TREE_STATIC (decl)
      && DECL_INITIAL (decl) != NULL_TREE)
    return true;

  return false;
}


void
c_print_identifier (FILE *file, tree node, int indent)
{
  void (*save) (enum c_oracle_request, tree identifier);

  /* Temporarily hide any binding oracle.  Without this, calls to
     debug_tree from the debugger will end up calling into the oracle,
     making for a confusing debug session.  As the oracle isn't needed
     here for normal operation, it's simplest to suppress it.  */
  save = c_binding_oracle;
  c_binding_oracle = NULL;

  print_node (file, "symbol", I_SYMBOL_DECL (node), indent + 4);
  print_node (file, "tag", I_TAG_DECL (node), indent + 4);
  print_node (file, "label", I_LABEL_DECL (node), indent + 4);
  if (C_IS_RESERVED_WORD (node) && C_RID_CODE (node) != RID_CXX_COMPAT_WARN)
    {
      tree rid = ridpointers[C_RID_CODE (node)];
      indent_to (file, indent + 4);
      fprintf (file, "rid " HOST_PTR_PRINTF " \"%s\"",
	       (void *) rid, IDENTIFIER_POINTER (rid));
    }

  c_binding_oracle = save;
}

/* Establish a binding between NAME, an IDENTIFIER_NODE, and DECL,
   which may be any of several kinds of DECL or TYPE or error_mark_node,
   in the scope SCOPE.  */
static void
bind (tree name, tree decl, struct c_scope *scope, bool invisible,
      bool nested, location_t locus)
{
  struct c_binding *b, **here;

  if (binding_freelist)
    {
      b = binding_freelist;
      binding_freelist = b->prev;
    }
  else
    b = ggc_alloc<c_binding> ();

  b->shadowed = 0;
  b->decl = decl;
  b->id = name;
  b->depth = scope->depth;
  b->invisible = invisible;
  b->nested = nested;
  b->inner_comp = 0;
  b->in_struct = 0;
  b->locus = locus;

  b->u.type = NULL;

  b->prev = scope->bindings;
  scope->bindings = b;

  if (decl_jump_unsafe (decl))
    scope->has_jump_unsafe_decl = 1;

  if (!name)
    return;

  switch (TREE_CODE (decl))
    {
    case LABEL_DECL:     here = &I_LABEL_BINDING (name);   break;
    case ENUMERAL_TYPE:
    case UNION_TYPE:
    case RECORD_TYPE:    here = &I_TAG_BINDING (name);     break;
    case VAR_DECL:
    case FUNCTION_DECL:
    case TYPE_DECL:
    case CONST_DECL:
    case PARM_DECL:
    case ERROR_MARK:     here = &I_SYMBOL_BINDING (name);  break;

    default:
      gcc_unreachable ();
    }

  /* Locate the appropriate place in the chain of shadowed decls
     to insert this binding.  Normally, scope == current_scope and
     this does nothing.  */
  while (*here && (*here)->depth > scope->depth)
    here = &(*here)->shadowed;

  b->shadowed = *here;
  *here = b;
}

/* Clear the binding structure B, stick it on the binding_freelist,
   and return the former value of b->prev.  This is used by pop_scope
   and get_parm_info to iterate destructively over all the bindings
   from a given scope.  */
static struct c_binding *
free_binding_and_advance (struct c_binding *b)
{
  struct c_binding *prev = b->prev;

  memset (b, 0, sizeof (struct c_binding));
  b->prev = binding_freelist;
  binding_freelist = b;

  return prev;
}

/* Bind a label.  Like bind, but skip fields which aren't used for
   labels, and add the LABEL_VARS value.  */
static void
bind_label (tree name, tree label, struct c_scope *scope,
	    struct c_label_vars *label_vars)
{
  struct c_binding *b;

  bind (name, label, scope, /*invisible=*/false, /*nested=*/false,
	UNKNOWN_LOCATION);

  scope->has_label_bindings = true;

  b = scope->bindings;
  gcc_assert (b->decl == label);
  label_vars->shadowed = b->u.label;
  b->u.label = label_vars;
}

/* Hook called at end of compilation to assume 1 elt
   for a file-scope tentative array defn that wasn't complete before.  */

void
c_finish_incomplete_decl (tree decl)
{
  if (VAR_P (decl))
    {
      tree type = TREE_TYPE (decl);
      if (type != error_mark_node
	  && TREE_CODE (type) == ARRAY_TYPE
	  && !DECL_EXTERNAL (decl)
	  && TYPE_DOMAIN (type) == NULL_TREE)
	{
	  warning_at (DECL_SOURCE_LOCATION (decl),
		      0, "array %q+D assumed to have one element", decl);

	  complete_array_type (&TREE_TYPE (decl), NULL_TREE, true);

	  relayout_decl (decl);
	}
    }
}

/* Record that inline function FUNC contains a reference (location
   LOC) to static DECL (file-scope or function-local according to
   TYPE).  */

void
record_inline_static (location_t loc, tree func, tree decl,
		      enum c_inline_static_type type)
{
  c_inline_static *csi = ggc_alloc<c_inline_static> ();
  csi->location = loc;
  csi->function = func;
  csi->static_decl = decl;
  csi->type = type;
  csi->next = c_inline_statics;
  c_inline_statics = csi;
}

/* Check for references to static declarations in inline functions at
   the end of the translation unit and diagnose them if the functions
   are still inline definitions.  */

static void
check_inline_statics (void)
{
  struct c_inline_static *csi;
  for (csi = c_inline_statics; csi; csi = csi->next)
    {
      if (DECL_EXTERNAL (csi->function))
	switch (csi->type)
	  {
	  case csi_internal:
	    pedwarn (csi->location, 0,
		     "%qD is static but used in inline function %qD "
		     "which is not static", csi->static_decl, csi->function);
	    break;
	  case csi_modifiable:
	    pedwarn (csi->location, 0,
		     "%q+D is static but declared in inline function %qD "
		     "which is not static", csi->static_decl, csi->function);
	    break;
	  default:
	    gcc_unreachable ();
	  }
    }
  c_inline_statics = NULL;
}

/* Fill in a c_spot_bindings structure.  If DEFINING is true, set it
   for the current state, otherwise set it to uninitialized.  */

static void
set_spot_bindings (struct c_spot_bindings *p, bool defining)
{
  if (defining)
    {
      p->scope = current_scope;
      p->bindings_in_scope = current_scope->bindings;
    }
  else
    {
      p->scope = NULL;
      p->bindings_in_scope = NULL;
    }
  p->stmt_exprs = 0;
  p->left_stmt_expr = false;
}

/* Update spot bindings P as we pop out of SCOPE.  Return true if we
   should push decls for a label.  */

static bool
update_spot_bindings (struct c_scope *scope, struct c_spot_bindings *p)
{
  if (p->scope != scope)
    {
      /* This label or goto is defined in some other scope, or it is a
	 label which is not yet defined.  There is nothing to
	 update.  */
      return false;
    }

  /* Adjust the spot bindings to refer to the bindings already defined
     in the enclosing scope.  */
  p->scope = scope->outer;
  p->bindings_in_scope = p->scope->bindings;

  return true;
}

/* The Objective-C front-end often needs to determine the current scope.  */

void *
objc_get_current_scope (void)
{
  return current_scope;
}

/* The following function is used only by Objective-C.  It needs to live here
   because it accesses the innards of c_scope.  */

void
objc_mark_locals_volatile (void *enclosing_blk)
{
  struct c_scope *scope;
  struct c_binding *b;

  for (scope = current_scope;
       scope && scope != enclosing_blk;
       scope = scope->outer)
    {
      for (b = scope->bindings; b; b = b->prev)
	objc_volatilize_decl (b->decl);

      /* Do not climb up past the current function.  */
      if (scope->function_body)
	break;
    }
}

/* Return true if we are in the global binding level.  */

bool
global_bindings_p (void)
{
  return current_scope == file_scope;
}

/* Return true if we're declaring parameters in an old-style function
   declaration.  */

bool
old_style_parameter_scope (void)
{
  /* If processing parameters and there is no function statement list, we
   * have an old-style function declaration.  */
  return (current_scope->parm_flag && !DECL_SAVED_TREE (current_function_decl));
}

void
keep_next_level (void)
{
  keep_next_level_flag = true;
}

/* Set the flag for the FLOAT_CONST_DECIMAL64 pragma being ON.  */

void
set_float_const_decimal64 (void)
{
  current_scope->float_const_decimal64 = true;
}

/* Clear the flag for the FLOAT_CONST_DECIMAL64 pragma.  */

void
clear_float_const_decimal64 (void)
{
  current_scope->float_const_decimal64 = false;
}

/* Return nonzero if an unsuffixed float constant is _Decimal64.  */

bool
float_const_decimal64_p (void)
{
  return current_scope->float_const_decimal64;
}

/* Identify this scope as currently being filled with parameters.  */

void
declare_parm_level (void)
{
  current_scope->parm_flag = true;
}

void
push_scope (void)
{
  if (next_is_function_body)
    {
      /* This is the transition from the parameters to the top level
	 of the function body.  These are the same scope
	 (C99 6.2.1p4,6) so we do not push another scope structure.
	 next_is_function_body is set only by store_parm_decls, which
	 in turn is called when and only when we are about to
	 encounter the opening curly brace for the function body.

	 The outermost block of a function always gets a BLOCK node,
	 because the debugging output routines expect that each
	 function has at least one BLOCK.  */
      current_scope->parm_flag         = false;
      current_scope->function_body     = true;
      current_scope->keep              = true;
      current_scope->outer_function    = current_function_scope;
      current_function_scope           = current_scope;

      keep_next_level_flag = false;
      next_is_function_body = false;

      /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes.  */
      if (current_scope->outer)
	current_scope->float_const_decimal64
	  = current_scope->outer->float_const_decimal64;
      else
	current_scope->float_const_decimal64 = false;
    }
  else
    {
      struct c_scope *scope;
      if (scope_freelist)
	{
	  scope = scope_freelist;
	  scope_freelist = scope->outer;
	}
      else
	scope = ggc_cleared_alloc<c_scope> ();

      /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes.  */
      if (current_scope)
	scope->float_const_decimal64 = current_scope->float_const_decimal64;
      else
	scope->float_const_decimal64 = false;

      scope->keep          = keep_next_level_flag;
      scope->outer         = current_scope;
      scope->depth	   = current_scope ? (current_scope->depth + 1) : 0;

      /* Check for scope depth overflow.  Unlikely (2^28 == 268,435,456) but
	 possible.  */
      if (current_scope && scope->depth == 0)
	{
	  scope->depth--;
	  sorry ("GCC supports only %u nested scopes", scope->depth);
	}

      current_scope        = scope;
      keep_next_level_flag = false;
    }
}

/* This is called when we are leaving SCOPE.  For each label defined
   in SCOPE, add any appropriate decls to its decls_in_scope fields.
   These are the decls whose initialization will be skipped by a goto
   later in the function.  */

static void
update_label_decls (struct c_scope *scope)
{
  struct c_scope *s;

  s = scope;
  while (s != NULL)
    {
      if (s->has_label_bindings)
	{
	  struct c_binding *b;

	  for (b = s->bindings; b != NULL; b = b->prev)
	    {
	      struct c_label_vars *label_vars;
	      struct c_binding *b1;
	      bool hjud;
	      unsigned int ix;
	      struct c_goto_bindings *g;

	      if (TREE_CODE (b->decl) != LABEL_DECL)
		continue;
	      label_vars = b->u.label;

	      b1 = label_vars->label_bindings.bindings_in_scope;
	      if (label_vars->label_bindings.scope == NULL)
		hjud = false;
	      else
		hjud = label_vars->label_bindings.scope->has_jump_unsafe_decl;
	      if (update_spot_bindings (scope, &label_vars->label_bindings))
		{
		  /* This label is defined in this scope.  */
		  if (hjud)
		    {
		      for (; b1 != NULL; b1 = b1->prev)
			{
			  /* A goto from later in the function to this
			     label will never see the initialization
			     of B1, if any.  Save it to issue a
			     warning if needed.  */
			  if (decl_jump_unsafe (b1->decl))
			    vec_safe_push(label_vars->decls_in_scope, b1->decl);
			}
		    }
		}

	      /* Update the bindings of any goto statements associated
		 with this label.  */
	      FOR_EACH_VEC_SAFE_ELT (label_vars->gotos, ix, g)
		update_spot_bindings (scope, &g->goto_bindings);
	    }
	}

      /* Don't search beyond the current function.  */
      if (s == current_function_scope)
	break;

      s = s->outer;
    }
}

/* Set the TYPE_CONTEXT of all of TYPE's variants to CONTEXT.  */

static void
set_type_context (tree type, tree context)
{
  for (type = TYPE_MAIN_VARIANT (type); type;
       type = TYPE_NEXT_VARIANT (type))
    TYPE_CONTEXT (type) = context;
}

/* Exit a scope.  Restore the state of the identifier-decl mappings
   that were in effect when this scope was entered.  Return a BLOCK
   node containing all the DECLs in this scope that are of interest
   to debug info generation.  */

tree
pop_scope (void)
{
  struct c_scope *scope = current_scope;
  tree block, context, p;
  struct c_binding *b;

  bool functionbody = scope->function_body;
  bool keep = functionbody || scope->keep || scope->bindings;

  update_label_decls (scope);

  /* If appropriate, create a BLOCK to record the decls for the life
     of this function.  */
  block = NULL_TREE;
  if (keep)
    {
      block = make_node (BLOCK);
      BLOCK_SUBBLOCKS (block) = scope->blocks;
      TREE_USED (block) = 1;

      /* In each subblock, record that this is its superior.  */
      for (p = scope->blocks; p; p = BLOCK_CHAIN (p))
	BLOCK_SUPERCONTEXT (p) = block;

      BLOCK_VARS (block) = NULL_TREE;
    }

  /* The TYPE_CONTEXTs for all of the tagged types belonging to this
     scope must be set so that they point to the appropriate
     construct, i.e.  either to the current FUNCTION_DECL node, or
     else to the BLOCK node we just constructed.

     Note that for tagged types whose scope is just the formal
     parameter list for some function type specification, we can't
     properly set their TYPE_CONTEXTs here, because we don't have a
     pointer to the appropriate FUNCTION_TYPE node readily available
     to us.  For those cases, the TYPE_CONTEXTs of the relevant tagged
     type nodes get set in `grokdeclarator' as soon as we have created
     the FUNCTION_TYPE node which will represent the "scope" for these
     "parameter list local" tagged types.  */
  if (scope->function_body)
    context = current_function_decl;
  else if (scope == file_scope)
    {
      tree file_decl
	= build_translation_unit_decl (get_identifier (main_input_filename));
      context = file_decl;
      debug_hooks->register_main_translation_unit (file_decl);
    }
  else
    context = block;

  /* Clear all bindings in this scope.  */
  for (b = scope->bindings; b; b = free_binding_and_advance (b))
    {
      p = b->decl;
      switch (TREE_CODE (p))
	{
	case LABEL_DECL:
	  /* Warnings for unused labels, errors for undefined labels.  */
	  if (TREE_USED (p) && !DECL_INITIAL (p))
	    {
	      error ("label %q+D used but not defined", p);
	      DECL_INITIAL (p) = error_mark_node;
	    }
	  else
	    warn_for_unused_label (p);

	  /* Labels go in BLOCK_VARS.  */
	  DECL_CHAIN (p) = BLOCK_VARS (block);
	  BLOCK_VARS (block) = p;
	  gcc_assert (I_LABEL_BINDING (b->id) == b);
	  I_LABEL_BINDING (b->id) = b->shadowed;

	  /* Also pop back to the shadowed label_vars.  */
	  release_tree_vector (b->u.label->decls_in_scope);
	  b->u.label = b->u.label->shadowed;
	  break;

	case ENUMERAL_TYPE:
	case UNION_TYPE:
	case RECORD_TYPE:
	  set_type_context (p, context);

	  /* Types may not have tag-names, in which case the type
	     appears in the bindings list with b->id NULL.  */
	  if (b->id)
	    {
	      gcc_assert (I_TAG_BINDING (b->id) == b);
	      I_TAG_BINDING (b->id) = b->shadowed;
	    }
	  break;

	case FUNCTION_DECL:
	  /* Propagate TREE_ADDRESSABLE from nested functions to their
	     containing functions.  */
	  if (!TREE_ASM_WRITTEN (p)
	      && DECL_INITIAL (p) != NULL_TREE
	      && TREE_ADDRESSABLE (p)
	      && DECL_ABSTRACT_ORIGIN (p) != NULL_TREE
	      && DECL_ABSTRACT_ORIGIN (p) != p)
	    TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (p)) = 1;
	  if (!TREE_PUBLIC (p)
	      && !DECL_INITIAL (p)
	      && !b->nested
	      && scope != file_scope
	      && scope != external_scope)
	    {
	      error ("nested function %q+D declared but never defined", p);
	      undef_nested_function = true;
	    }
	  else if (DECL_DECLARED_INLINE_P (p)
		   && TREE_PUBLIC (p)
		   && !DECL_INITIAL (p))
	    {
	      /* C99 6.7.4p6: "a function with external linkage... declared
		 with an inline function specifier ... shall also be defined
		 in the same translation unit."  */
	      if (!flag_gnu89_inline
		  && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (p))
		  && scope == external_scope)
		pedwarn (input_location, 0,
			 "inline function %q+D declared but never defined", p);
	      DECL_EXTERNAL (p) = 1;
	    }

	  goto common_symbol;

	case VAR_DECL:
	  /* Warnings for unused variables.  */
	  if ((!TREE_USED (p) || !DECL_READ_P (p))
	      && !warning_suppressed_p (p, OPT_Wunused_but_set_variable)
	      && !DECL_IN_SYSTEM_HEADER (p)
	      && DECL_NAME (p)
	      && !DECL_ARTIFICIAL (p)
	      && scope != file_scope
	      && scope != external_scope)
	    {
	      if (!TREE_USED (p))
		warning (OPT_Wunused_variable, "unused variable %q+D", p);
	      else if (DECL_CONTEXT (p) == current_function_decl)
		warning_at (DECL_SOURCE_LOCATION (p),
			    OPT_Wunused_but_set_variable,
			    "variable %qD set but not used", p);
	    }

	  if (b->inner_comp)
	    {
	      error ("type of array %q+D completed incompatibly with"
		     " implicit initialization", p);
	    }

	  /* Fall through.  */
	case TYPE_DECL:
	case CONST_DECL:
	common_symbol:
	  /* All of these go in BLOCK_VARS, but only if this is the
	     binding in the home scope.  */
	  if (!b->nested)
	    {
	      DECL_CHAIN (p) = BLOCK_VARS (block);
	      BLOCK_VARS (block) = p;
	    }
	  else if (VAR_OR_FUNCTION_DECL_P (p) && scope != file_scope)
	    {
	      /* For block local externs add a special
		 DECL_EXTERNAL decl for debug info generation.  */
	      tree extp = copy_node (p);

	      DECL_EXTERNAL (extp) = 1;
	      TREE_STATIC (extp) = 0;
	      TREE_PUBLIC (extp) = 1;
	      DECL_INITIAL (extp) = NULL_TREE;
	      DECL_LANG_SPECIFIC (extp) = NULL;
	      DECL_CONTEXT (extp) = current_function_decl;
	      if (TREE_CODE (p) == FUNCTION_DECL)
		{
		  DECL_RESULT (extp) = NULL_TREE;
		  DECL_SAVED_TREE (extp) = NULL_TREE;
		  DECL_STRUCT_FUNCTION (extp) = NULL;
		}
	      if (b->locus != UNKNOWN_LOCATION)
		DECL_SOURCE_LOCATION (extp) = b->locus;
	      DECL_CHAIN (extp) = BLOCK_VARS (block);
	      BLOCK_VARS (block) = extp;
	    }
	  /* If this is the file scope set DECL_CONTEXT of each decl to
	     the TRANSLATION_UNIT_DECL.  This makes same_translation_unit_p
	     work.  */
	  if (scope == file_scope)
	    {
	      DECL_CONTEXT (p) = context;
	      if (TREE_CODE (p) == TYPE_DECL
		  && TREE_TYPE (p) != error_mark_node)
		set_type_context (TREE_TYPE (p), context);
	    }

	  gcc_fallthrough ();
	  /* Parameters go in DECL_ARGUMENTS, not BLOCK_VARS, and have
	     already been put there by store_parm_decls.  Unused-
	     parameter warnings are handled by function.c.
	     error_mark_node obviously does not go in BLOCK_VARS and
	     does not get unused-variable warnings.  */
	case PARM_DECL:
	case ERROR_MARK:
	  /* It is possible for a decl not to have a name.  We get
	     here with b->id NULL in this case.  */
	  if (b->id)
	    {
	      gcc_assert (I_SYMBOL_BINDING (b->id) == b);
	      I_SYMBOL_BINDING (b->id) = b->shadowed;
	      if (b->shadowed && b->shadowed->u.type)
		TREE_TYPE (b->shadowed->decl) = b->shadowed->u.type;
	    }
	  break;

	default:
	  gcc_unreachable ();
	}
    }


  /* Dispose of the block that we just made inside some higher level.  */
  if ((scope->function_body || scope == file_scope) && context)
    {
      DECL_INITIAL (context) = block;
      BLOCK_SUPERCONTEXT (block) = context;
    }
  else if (scope->outer)
    {
      if (block)
	SCOPE_LIST_APPEND (scope->outer, blocks, block);
      /* If we did not make a block for the scope just exited, any
	 blocks made for inner scopes must be carried forward so they
	 will later become subblocks of something else.  */
      else if (scope->blocks)
	SCOPE_LIST_CONCAT (scope->outer, blocks, scope, blocks);
    }

  /* Pop the current scope, and free the structure for reuse.  */
  current_scope = scope->outer;
  if (scope->function_body)
    current_function_scope = scope->outer_function;

  memset (scope, 0, sizeof (struct c_scope));
  scope->outer = scope_freelist;
  scope_freelist = scope;

  return block;
}

void
push_file_scope (void)
{
  tree decl;

  if (file_scope)
    return;

  push_scope ();
  file_scope = current_scope;

  start_fname_decls ();

  for (decl = visible_builtins; decl; decl = DECL_CHAIN (decl))
    bind (DECL_NAME (decl), decl, file_scope,
	  /*invisible=*/false, /*nested=*/true, DECL_SOURCE_LOCATION (decl));
}

void
pop_file_scope (void)
{
  /* In case there were missing closebraces, get us back to the global
     binding level.  */
  while (current_scope != file_scope)
    pop_scope ();

  /* __FUNCTION__ is defined at file scope ("").  This
     call may not be necessary as my tests indicate it
     still works without it.  */
  finish_fname_decls ();

  check_inline_statics ();

  /* This is the point to write out a PCH if we're doing that.
     In that case we do not want to do anything else.  */
  if (pch_file)
    {
      c_common_write_pch ();
      /* Ensure even the callers don't try to finalize the CU.  */
      flag_syntax_only = 1;
      return;
    }

  /* Pop off the file scope and close this translation unit.  */
  pop_scope ();
  file_scope = 0;

  maybe_apply_pending_pragma_weaks ();
}

/* Adjust the bindings for the start of a statement expression.  */

void
c_bindings_start_stmt_expr (struct c_spot_bindings* switch_bindings)
{
  struct c_scope *scope;

  for (scope = current_scope; scope != NULL; scope = scope->outer)
    {
      struct c_binding *b;

      if (!scope->has_label_bindings)
	continue;

      for (b = scope->bindings; b != NULL; b = b->prev)
	{
	  struct c_label_vars *label_vars;
	  unsigned int ix;
	  struct c_goto_bindings *g;

	  if (TREE_CODE (b->decl) != LABEL_DECL)
	    continue;
	  label_vars = b->u.label;
	  ++label_vars->label_bindings.stmt_exprs;
	  FOR_EACH_VEC_SAFE_ELT (label_vars->gotos, ix, g)
	    ++g->goto_bindings.stmt_exprs;
	}
    }

  if (switch_bindings != NULL)
    ++switch_bindings->stmt_exprs;
}

/* Adjust the bindings for the end of a statement expression.  */

void
c_bindings_end_stmt_expr (struct c_spot_bindings *switch_bindings)
{
  struct c_scope *scope;

  for (scope = current_scope; scope != NULL; scope = scope->outer)
    {
      struct c_binding *b;

      if (!scope->has_label_bindings)
	continue;

      for (b = scope->bindings; b != NULL; b = b->prev)
	{
	  struct c_label_vars *label_vars;
	  unsigned int ix;
	  struct c_goto_bindings *g;

	  if (TREE_CODE (b->decl) != LABEL_DECL)
	    continue;
	  label_vars = b->u.label;
	  --label_vars->label_bindings.stmt_exprs;
	  if (label_vars->label_bindings.stmt_exprs < 0)
	    {
	      label_vars->label_bindings.left_stmt_expr = true;
	      label_vars->label_bindings.stmt_exprs = 0;
	    }
	  FOR_EACH_VEC_SAFE_ELT (label_vars->gotos, ix, g)
	    {
	      --g->goto_bindings.stmt_exprs;
	      if (g->goto_bindings.stmt_exprs < 0)
		{
		  g->goto_bindings.left_stmt_expr = true;
		  g->goto_bindings.stmt_exprs = 0;
		}
	    }
	}
    }

  if (switch_bindings != NULL)
    {
      --switch_bindings->stmt_exprs;
      gcc_assert (switch_bindings->stmt_exprs >= 0);
    }
}

/* Push a definition or a declaration of struct, union or enum tag "name".
   "type" should be the type node.
   We assume that the tag "name" is not already defined, and has a location
   of LOC.

   Note that the definition may really be just a forward reference.
   In that case, the TYPE_SIZE will be zero.  */

static void
pushtag (location_t loc, tree name, tree type)
{
  /* Record the identifier as the type's name if it has none.  */
  if (name && !TYPE_NAME (type))
    TYPE_NAME (type) = name;
  bind (name, type, current_scope, /*invisible=*/false, /*nested=*/false, loc);

  /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the
     tagged type we just added to the current scope.  This fake
     NULL-named TYPE_DECL node helps dwarfout.c to know when it needs
     to output a representation of a tagged type, and it also gives
     us a convenient place to record the "scope start" address for the
     tagged type.  */

  TYPE_STUB_DECL (type) = pushdecl (build_decl (loc,
						TYPE_DECL, NULL_TREE, type));

  /* An approximation for now, so we can tell this is a function-scope tag.
     This will be updated in pop_scope.  */
  TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_STUB_DECL (type));

  if (warn_cxx_compat && name != NULL_TREE)
    {
      struct c_binding *b = I_SYMBOL_BINDING (name);

      if (b != NULL
	  && b->decl != NULL_TREE
	  && TREE_CODE (b->decl) == TYPE_DECL
	  && (B_IN_CURRENT_SCOPE (b)
	      || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b)))
	  && (TYPE_MAIN_VARIANT (TREE_TYPE (b->decl))
	      != TYPE_MAIN_VARIANT (type)))
	{
	  auto_diagnostic_group d;
	  if (warning_at (loc, OPT_Wc___compat,
			  ("using %qD as both a typedef and a tag is "
			   "invalid in C++"), b->decl)
	      && b->locus != UNKNOWN_LOCATION)
	    inform (b->locus, "originally defined here");
	}
    }
}

/* An exported interface to pushtag.  This is used by the gdb plugin's
   binding oracle to introduce a new tag binding.  */

void
c_pushtag (location_t loc, tree name, tree type)
{
  pushtag (loc, name, type);
}

/* An exported interface to bind a declaration.  LOC is the location
   to use.  DECL is the declaration to bind.  The decl's name is used
   to determine how it is bound.  If DECL is a VAR_DECL, then
   IS_GLOBAL determines whether the decl is put into the global (file
   and external) scope or the current function's scope; if DECL is not
   a VAR_DECL then it is always put into the file scope.  */

void
c_bind (location_t loc, tree decl, bool is_global)
{
  struct c_scope *scope;
  bool nested = false;

  if (!VAR_P (decl) || current_function_scope == NULL)
    {
      /* Types and functions are always considered to be global.  */
      scope = file_scope;
      DECL_EXTERNAL (decl) = 1;
      TREE_PUBLIC (decl) = 1;
    }
  else if (is_global)
    {
      /* Also bind it into the external scope.  */
      bind (DECL_NAME (decl), decl, external_scope, true, false, loc);
      nested = true;
      scope = file_scope;
      DECL_EXTERNAL (decl) = 1;
      TREE_PUBLIC (decl) = 1;
    }
  else
    {
      DECL_CONTEXT (decl) = current_function_decl;
      TREE_PUBLIC (decl) = 0;
      scope = current_function_scope;
    }

  bind (DECL_NAME (decl), decl, scope, false, nested, loc);
}


/* Stores the first FILE*, const struct tm* etc. argument type (whatever
   it is) seen in a declaration of a file I/O etc. built-in, corresponding
   to the builtin_structptr_types array.  Subsequent declarations of such
   built-ins are expected to refer to it rather than to fileptr_type_node,
   etc. which is just void* (or to any other type).
   Used only by match_builtin_function_types.  */

static const unsigned builtin_structptr_type_count
  = sizeof builtin_structptr_types / sizeof builtin_structptr_types[0];

static GTY(()) tree last_structptr_types[builtin_structptr_type_count];

/* Returns true if types T1 and T2 representing return types or types
   of function arguments are close enough to be considered interchangeable
   in redeclarations of built-in functions.  */

static bool
types_close_enough_to_match (tree t1, tree t2)
{
  return (TYPE_MODE (t1) == TYPE_MODE (t2)
	  && POINTER_TYPE_P (t1) == POINTER_TYPE_P (t2)
	  && FUNCTION_POINTER_TYPE_P (t1) == FUNCTION_POINTER_TYPE_P (t2));
}

/* Subroutine of compare_decls.  Allow harmless mismatches in return
   and argument types provided that the type modes match.  Set *STRICT
   and *ARGNO to the expected argument type and number in case of
   an argument type mismatch or null and zero otherwise.  Return
   a unified type given a suitable match, and 0 otherwise.  */

static tree
match_builtin_function_types (tree newtype, tree oldtype,
			      tree *strict, unsigned *argno)
{
  *argno = 0;
  *strict = NULL_TREE;

  /* Accept the return type of the new declaration if it has the same
     mode and if they're both pointers or if neither is.  */
  tree oldrettype = TREE_TYPE (oldtype);
  tree newrettype = TREE_TYPE (newtype);

  if (!types_close_enough_to_match (oldrettype, newrettype))
    return NULL_TREE;

  /* Check that the return types are compatible but don't fail if they
     are not (e.g., int vs long in ILP32) and just let the caller know.  */
  if (!comptypes (TYPE_MAIN_VARIANT (oldrettype),
		  TYPE_MAIN_VARIANT (newrettype)))
    *strict = oldrettype;

  tree oldargs = TYPE_ARG_TYPES (oldtype);
  tree newargs = TYPE_ARG_TYPES (newtype);
  tree tryargs = newargs;

  const unsigned nlst
    = sizeof last_structptr_types / sizeof last_structptr_types[0];
  const unsigned nbst
    = sizeof builtin_structptr_types / sizeof builtin_structptr_types[0];

  gcc_checking_assert (nlst == nbst);

  for (unsigned i = 1; oldargs || newargs; ++i)
    {
      if (!oldargs
	  || !newargs
	  || !TREE_VALUE (oldargs)
	  || !TREE_VALUE (newargs))
	return NULL_TREE;

      tree oldtype = TYPE_MAIN_VARIANT (TREE_VALUE (oldargs));
      tree newtype = TREE_VALUE (newargs);
      if (newtype == error_mark_node)
       return NULL_TREE;
      newtype = TYPE_MAIN_VARIANT (newtype);

      if (!types_close_enough_to_match (oldtype, newtype))
	return NULL_TREE;

      unsigned j = nbst;
      if (POINTER_TYPE_P (oldtype))
	/* Iterate over well-known struct types like FILE (whose types
	   aren't known to us) and compare the pointer to each to
	   the pointer argument.  */
	for (j = 0; j < nbst; ++j)
	  {
	    if (TREE_VALUE (oldargs) != builtin_structptr_types[j].node)
	      continue;
	    /* Store the first FILE* etc. argument type (whatever it is), and
	       expect any subsequent declarations of file I/O etc. built-ins
	       to refer to it rather than to fileptr_type_node etc. which is
	       just void* (or const void*).  */
	    if (last_structptr_types[j])
	      {
		if (!comptypes (last_structptr_types[j], newtype))
		  {
		    *argno = i;
		    *strict = last_structptr_types[j];
		  }
	      }
	    else
	      last_structptr_types[j] = newtype;
	    break;
	  }

      if (j == nbst && !comptypes (oldtype, newtype))
	{
	  if (POINTER_TYPE_P (oldtype))
	    {
	      /* For incompatible pointers, only reject differences in
		 the unqualified variants of the referenced types but
		 consider differences in qualifiers as benign (report
		 those to caller via *STRICT below).  */
	      tree oldref = TYPE_MAIN_VARIANT (TREE_TYPE (oldtype));
	      tree newref = TYPE_MAIN_VARIANT (TREE_TYPE (newtype));
	      if (!comptypes (oldref, newref))
		return NULL_TREE;
	    }

	  if (!*strict)
	    {
	      *argno = i;
	      *strict = oldtype;
	    }
	}

      oldargs = TREE_CHAIN (oldargs);
      newargs = TREE_CHAIN (newargs);
    }

  tree trytype = build_function_type (newrettype, tryargs);

  /* Allow declaration to change transaction_safe attribute.  */
  tree oldattrs = TYPE_ATTRIBUTES (oldtype);
  tree oldtsafe = lookup_attribute ("transaction_safe", oldattrs);
  tree newattrs = TYPE_ATTRIBUTES (newtype);
  tree newtsafe = lookup_attribute ("transaction_safe", newattrs);
  if (oldtsafe && !newtsafe)
    oldattrs = remove_attribute ("transaction_safe", oldattrs);
  else if (newtsafe && !oldtsafe)
    oldattrs = tree_cons (get_identifier ("transaction_safe"),
			  NULL_TREE, oldattrs);

  return build_type_attribute_variant (trytype, oldattrs);
}

/* Subroutine of diagnose_mismatched_decls.  Check for function type
   mismatch involving an empty arglist vs a nonempty one and give clearer
   diagnostics.  */
static void
diagnose_arglist_conflict (tree newdecl, tree olddecl,
			   tree newtype, tree oldtype)
{
  tree t;

  if (TREE_CODE (olddecl) != FUNCTION_DECL
      || !comptypes (TREE_TYPE (oldtype), TREE_TYPE (newtype))
      || !((!prototype_p (oldtype) && DECL_INITIAL (olddecl) == NULL_TREE)
	   || (!prototype_p (newtype) && DECL_INITIAL (newdecl) == NULL_TREE)))
    return;

  t = TYPE_ARG_TYPES (oldtype);
  if (t == NULL_TREE)
    t = TYPE_ARG_TYPES (newtype);
  for (; t; t = TREE_CHAIN (t))
    {
      tree type = TREE_VALUE (t);

      if (TREE_CHAIN (t) == NULL_TREE
	  && TYPE_MAIN_VARIANT (type) != void_type_node)
	{
	  inform (input_location, "a parameter list with an ellipsis "
		  "cannot match an empty parameter name list declaration");
	  break;
	}

      if (c_type_promotes_to (type) != type)
	{
	  inform (input_location, "an argument type that has a default "
		  "promotion cannot match an empty parameter name list "
		  "declaration");
	  break;
	}
    }
}

/* Another subroutine of diagnose_mismatched_decls.  OLDDECL is an
   old-style function definition, NEWDECL is a prototype declaration.
   Diagnose inconsistencies in the argument list.  Returns TRUE if
   the prototype is compatible, FALSE if not.  */
static bool
validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
{
  tree newargs, oldargs;
  int i;

#define END_OF_ARGLIST(t) ((t) == void_type_node)

  oldargs = TYPE_ACTUAL_ARG_TYPES (oldtype);
  newargs = TYPE_ARG_TYPES (newtype);
  i = 1;

  for (;;)
    {
      tree oldargtype = TREE_VALUE (oldargs);
      tree newargtype = TREE_VALUE (newargs);

      if (oldargtype == error_mark_node || newargtype == error_mark_node)
	return false;

      oldargtype = (TYPE_ATOMIC (oldargtype)
		    ? c_build_qualified_type (TYPE_MAIN_VARIANT (oldargtype),
					      TYPE_QUAL_ATOMIC)
		    : TYPE_MAIN_VARIANT (oldargtype));
      newargtype = (TYPE_ATOMIC (newargtype)
		    ? c_build_qualified_type (TYPE_MAIN_VARIANT (newargtype),
					      TYPE_QUAL_ATOMIC)
		    : TYPE_MAIN_VARIANT (newargtype));

      if (END_OF_ARGLIST (oldargtype) && END_OF_ARGLIST (newargtype))
	break;

      /* Reaching the end of just one list means the two decls don't
	 agree on the number of arguments.  */
      if (END_OF_ARGLIST (oldargtype))
	{
	  error ("prototype for %q+D declares more arguments "
		 "than previous old-style definition", newdecl);
	  return false;
	}
      else if (END_OF_ARGLIST (newargtype))
	{
	  error ("prototype for %q+D declares fewer arguments "
		 "than previous old-style definition", newdecl);
	  return false;
	}

      /* Type for passing arg must be consistent with that declared
	 for the arg.  */
      else if (!comptypes (oldargtype, newargtype))
	{
	  error ("prototype for %q+D declares argument %d"
		 " with incompatible type",
		 newdecl, i);
	  return false;
	}

      oldargs = TREE_CHAIN (oldargs);
      newargs = TREE_CHAIN (newargs);
      i++;
    }

  /* If we get here, no errors were found, but do issue a warning
     for this poor-style construct.  */
  warning (0, "prototype for %q+D follows non-prototype definition",
	   newdecl);
  return true;
#undef END_OF_ARGLIST
}

/* Subroutine of diagnose_mismatched_decls.  Report the location of DECL,
   first in a pair of mismatched declarations, using the diagnostic
   function DIAG.  */
static void
locate_old_decl (tree decl)
{
  if (TREE_CODE (decl) == FUNCTION_DECL
      && fndecl_built_in_p (decl)
      && !C_DECL_DECLARED_BUILTIN (decl))
    ;
  else if (DECL_INITIAL (decl))
    inform (input_location,
	    "previous definition of %q+D with type %qT",
	    decl, TREE_TYPE (decl));
  else if (C_DECL_IMPLICIT (decl))
    inform (input_location,
	    "previous implicit declaration of %q+D with type %qT",
	    decl, TREE_TYPE (decl));
  else
    inform (input_location,
	    "previous declaration of %q+D with type %qT",
	    decl, TREE_TYPE (decl));
}

/* Subroutine of duplicate_decls.  Compare NEWDECL to OLDDECL.
   Returns true if the caller should proceed to merge the two, false
   if OLDDECL should simply be discarded.  As a side effect, issues
   all necessary diagnostics for invalid or poor-style combinations.
   If it returns true, writes the types of NEWDECL and OLDDECL to
   *NEWTYPEP and *OLDTYPEP - these may have been adjusted from
   TREE_TYPE (NEWDECL, OLDDECL) respectively.  */

static bool
diagnose_mismatched_decls (tree newdecl, tree olddecl,
			   tree *newtypep, tree *oldtypep)
{
  tree newtype, oldtype;
  bool retval = true;

#define DECL_EXTERN_INLINE(DECL) (DECL_DECLARED_INLINE_P (DECL)  \
				  && DECL_EXTERNAL (DECL))

  /* If we have error_mark_node for either decl or type, just discard
     the previous decl - we're in an error cascade already.  */
  if (olddecl == error_mark_node || newdecl == error_mark_node)
    return false;
  *oldtypep = oldtype = TREE_TYPE (olddecl);
  *newtypep = newtype = TREE_TYPE (newdecl);
  if (oldtype == error_mark_node || newtype == error_mark_node)
    return false;

  /* Two different categories of symbol altogether.  This is an error
     unless OLDDECL is a builtin.  OLDDECL will be discarded in any case.  */
  if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
    {
      if (!(TREE_CODE (olddecl) == FUNCTION_DECL
	    && fndecl_built_in_p (olddecl)
	    && !C_DECL_DECLARED_BUILTIN (olddecl)))
	{
	  auto_diagnostic_group d;
	  error ("%q+D redeclared as different kind of symbol", newdecl);
	  locate_old_decl (olddecl);
	}
      else if (TREE_PUBLIC (newdecl))
	warning (OPT_Wbuiltin_declaration_mismatch,
		 "built-in function %q+D declared as non-function",
		 newdecl);
      else
	warning (OPT_Wshadow, "declaration of %q+D shadows "
		 "a built-in function", newdecl);
      return false;
    }

  /* Enumerators have no linkage, so may only be declared once in a
     given scope.  */
  if (TREE_CODE (olddecl) == CONST_DECL)
    {
      auto_diagnostic_group d;
      error ("redeclaration of enumerator %q+D", newdecl);
      locate_old_decl (olddecl);
      return false;
    }

  bool pedwarned = false;
  bool warned = false;
  auto_diagnostic_group d;

  if (!comptypes (oldtype, newtype))
    {
      if (TREE_CODE (olddecl) == FUNCTION_DECL
	  && fndecl_built_in_p (olddecl, BUILT_IN_NORMAL)
	  && !C_DECL_DECLARED_BUILTIN (olddecl))
	{
	  /* Accept "harmless" mismatches in function types such
	     as missing qualifiers or int vs long when they're the same
	     size.  However, diagnose return and argument types that are
	     incompatible according to language rules.  */
	  tree mismatch_expect;
	  unsigned mismatch_argno;

	  tree trytype = match_builtin_function_types (newtype, oldtype,
						       &mismatch_expect,
						       &mismatch_argno);

	  if (trytype && comptypes (newtype, trytype))
	    *oldtypep = oldtype = trytype;
	  else
	    {
	      /* If types don't match for a built-in, throw away the
		 built-in.  No point in calling locate_old_decl here, it
		 won't print anything.  */
	      const char *header = header_for_builtin_fn (olddecl);
	      location_t loc = DECL_SOURCE_LOCATION (newdecl);
	      if (warning_at (loc, OPT_Wbuiltin_declaration_mismatch,
			      "conflicting types for built-in function %q+D; "
			      "expected %qT",
			      newdecl, oldtype)
		  && header)
		{
		  /* Suggest the right header to include as the preferred
		     solution rather than the spelling of the declaration.  */
		  rich_location richloc (line_table, loc);
		  maybe_add_include_fixit (&richloc, header, true);
		  inform (&richloc,
			  "%qD is declared in header %qs", olddecl, header);
		}
	      return false;
	    }

	  if (mismatch_expect && extra_warnings)
	    {
	      location_t newloc = DECL_SOURCE_LOCATION (newdecl);
	      bool warned = false;
	      if (mismatch_argno)
		warned = warning_at (newloc, OPT_Wbuiltin_declaration_mismatch,
				     "mismatch in argument %u type of built-in "
				     "function %qD; expected %qT",
				     mismatch_argno, newdecl, mismatch_expect);
	      else
		warned = warning_at (newloc, OPT_Wbuiltin_declaration_mismatch,
				     "mismatch in return type of built-in "
				     "function %qD; expected %qT",
				     newdecl, mismatch_expect);
	      const char *header = header_for_builtin_fn (olddecl);
	      if (warned && header)
		{
		  rich_location richloc (line_table, newloc);
		  maybe_add_include_fixit (&richloc, header, true);
		  inform (&richloc,
			  "%qD is declared in header %qs", olddecl, header);
		}
	    }
	}
      else if (TREE_CODE (olddecl) == FUNCTION_DECL
	       && DECL_IS_UNDECLARED_BUILTIN (olddecl))
	{
	  /* A conflicting function declaration for a predeclared
	     function that isn't actually built in.  Objective C uses
	     these.  The new declaration silently overrides everything
	     but the volatility (i.e. noreturn) indication.  See also
	     below.  FIXME: Make Objective C use normal builtins.  */
	  TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
	  return false;
	}
      /* Permit void foo (...) to match int foo (...) if the latter is
	 the definition and implicit int was used.  See
	 c-torture/compile/920625-2.c.  */
      else if (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl)
	       && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == void_type_node
	       && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node
	       && C_FUNCTION_IMPLICIT_INT (newdecl) && !DECL_INITIAL (olddecl))
	{
	  pedwarned = pedwarn (input_location, 0,
			       "conflicting types for %q+D", newdecl);
	  /* Make sure we keep void as the return type.  */
	  TREE_TYPE (newdecl) = *newtypep = newtype = oldtype;
	  C_FUNCTION_IMPLICIT_INT (newdecl) = 0;
	}
      /* Permit void foo (...) to match an earlier call to foo (...) with
	 no declared type (thus, implicitly int).  */
      else if (TREE_CODE (newdecl) == FUNCTION_DECL
	       && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == void_type_node
	       && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == integer_type_node
	       && C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl))
	{
	  pedwarned = pedwarn (input_location, 0,
			       "conflicting types for %q+D; have %qT",
			       newdecl, newtype);
	  /* Make sure we keep void as the return type.  */
	  TREE_TYPE (olddecl) = *oldtypep = oldtype = newtype;
	}
      else
	{
	  int new_quals = TYPE_QUALS (newtype);
	  int old_quals = TYPE_QUALS (oldtype);

	  if (new_quals != old_quals)
	    {
	      addr_space_t new_addr = DECODE_QUAL_ADDR_SPACE (new_quals);
	      addr_space_t old_addr = DECODE_QUAL_ADDR_SPACE (old_quals);
	      if (new_addr != old_addr)
		{
		  if (ADDR_SPACE_GENERIC_P (new_addr))
		    error ("conflicting named address spaces (generic vs %s) "
			   "for %q+D",
			   c_addr_space_name (old_addr), newdecl);
		  else if (ADDR_SPACE_GENERIC_P (old_addr))
		    error ("conflicting named address spaces (%s vs generic) "
			   "for %q+D",
			   c_addr_space_name (new_addr), newdecl);
		  else
		    error ("conflicting named address spaces (%s vs %s) "
			   "for %q+D",
			   c_addr_space_name (new_addr),
			   c_addr_space_name (old_addr),
			   newdecl);
		}

	      if (CLEAR_QUAL_ADDR_SPACE (new_quals)
		  != CLEAR_QUAL_ADDR_SPACE (old_quals))
		error ("conflicting type qualifiers for %q+D", newdecl);
	    }
	  else
	    error ("conflicting types for %q+D; have %qT", newdecl, newtype);
	  diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype);
	  locate_old_decl (olddecl);
	  return false;
	}
    }

  /* Redeclaration of a type is a constraint violation (6.7.2.3p1),
     but silently ignore the redeclaration if either is in a system
     header.  (Conflicting redeclarations were handled above.)  This
     is allowed for C11 if the types are the same, not just
     compatible.  */
  if (TREE_CODE (newdecl) == TYPE_DECL)
    {
      bool types_different = false;
      int comptypes_result;

      comptypes_result
	= comptypes_check_different_types (oldtype, newtype, &types_different);

      if (comptypes_result != 1 || types_different)
	{
	  error ("redefinition of typedef %q+D with different type", newdecl);
	  locate_old_decl (olddecl);
	  return false;
	}

      if (DECL_IN_SYSTEM_HEADER (newdecl)
	  || DECL_IN_SYSTEM_HEADER (olddecl)
	  || warning_suppressed_p (newdecl, OPT_Wpedantic)
	  || warning_suppressed_p (olddecl, OPT_Wpedantic))
	return true;  /* Allow OLDDECL to continue in use.  */

      if (variably_modified_type_p (newtype, NULL))
	{
	  error ("redefinition of typedef %q+D with variably modified type",
		 newdecl);
	  locate_old_decl (olddecl);
	}
      else if (pedwarn_c99 (input_location, OPT_Wpedantic,
			    "redefinition of typedef %q+D", newdecl))
	locate_old_decl (olddecl);

      return true;
    }

  /* Function declarations can either be 'static' or 'extern' (no
     qualifier is equivalent to 'extern' - C99 6.2.2p5) and therefore
     can never conflict with each other on account of linkage
     (6.2.2p4).  Multiple definitions are not allowed (6.9p3,5) but
     gnu89 mode permits two definitions if one is 'extern inline' and
     one is not.  The non- extern-inline definition supersedes the
     extern-inline definition.  */

  else if (TREE_CODE (newdecl) == FUNCTION_DECL)
    {
      /* If you declare a built-in function name as static, or
	 define the built-in with an old-style definition (so we
	 can't validate the argument list) the built-in definition is
	 overridden, but optionally warn this was a bad choice of name.  */
      if (fndecl_built_in_p (olddecl)
	  && !C_DECL_DECLARED_BUILTIN (olddecl))
	{
	  if (!TREE_PUBLIC (newdecl)
	      || (DECL_INITIAL (newdecl)
		  && !prototype_p (TREE_TYPE (newdecl))))
	    {
	      warning_at (DECL_SOURCE_LOCATION (newdecl),
			  OPT_Wshadow, "declaration of %qD shadows "
			  "a built-in function", newdecl);
	      /* Discard the old built-in function.  */
	      return false;
	    }

	  if (!prototype_p (TREE_TYPE (newdecl)))
	    {
	      /* Set for built-ins that take no arguments.  */
	      bool func_void_args = false;
	      if (tree at = TYPE_ARG_TYPES (oldtype))
		func_void_args = VOID_TYPE_P (TREE_VALUE (at));

	      if (extra_warnings && !func_void_args)
		warning_at (DECL_SOURCE_LOCATION (newdecl),
			    OPT_Wbuiltin_declaration_mismatch,
			    "declaration of built-in function %qD without "
			    "a prototype; expected %qT",
			    newdecl, TREE_TYPE (olddecl));
	    }
	}

      if (DECL_INITIAL (newdecl))
	{
	  if (DECL_INITIAL (olddecl))
	    {
	      /* If both decls are in the same TU and the new declaration
		 isn't overriding an extern inline reject the new decl.
		 In c99, no overriding is allowed in the same translation
		 unit.  */
	      if ((!DECL_EXTERN_INLINE (olddecl)
		   || DECL_EXTERN_INLINE (newdecl)
		   || (!flag_gnu89_inline
		       && (!DECL_DECLARED_INLINE_P (olddecl)
			   || !lookup_attribute ("gnu_inline",
						 DECL_ATTRIBUTES (olddecl)))
		       && (!DECL_DECLARED_INLINE_P (newdecl)
			   || !lookup_attribute ("gnu_inline",
						 DECL_ATTRIBUTES (newdecl))))
		  )
		  && same_translation_unit_p (newdecl, olddecl))
		{
		  auto_diagnostic_group d;
		  error ("redefinition of %q+D", newdecl);
		  locate_old_decl (olddecl);
		  return false;
		}
	    }
	}
      /* If we have a prototype after an old-style function definition,
	 the argument types must be checked specially.  */
      else if (DECL_INITIAL (olddecl)
	       && !prototype_p (oldtype) && prototype_p (newtype)
	       && TYPE_ACTUAL_ARG_TYPES (oldtype))
	{
	  auto_diagnostic_group d;
	  if (!validate_proto_after_old_defn (newdecl, newtype, oldtype))
	    {
	      locate_old_decl (olddecl);
	      return false;
	    }
	}
      /* A non-static declaration (even an "extern") followed by a
	 static declaration is undefined behavior per C99 6.2.2p3-5,7.
	 The same is true for a static forward declaration at block
	 scope followed by a non-static declaration/definition at file
	 scope.  Static followed by non-static at the same scope is
	 not undefined behavior, and is the most convenient way to get
	 some effects (see e.g.  what unwind-dw2-fde-glibc.c does to
	 the definition of _Unwind_Find_FDE in unwind-dw2-fde.c), but
	 we do diagnose it if -Wtraditional.  */
      if (TREE_PUBLIC (olddecl) && !TREE_PUBLIC (newdecl))
	{
	  /* Two exceptions to the rule.  If olddecl is an extern
	     inline, or a predeclared function that isn't actually
	     built in, newdecl silently overrides olddecl.  The latter
	     occur only in Objective C; see also above.  (FIXME: Make
	     Objective C use normal builtins.)  */
	  if (!DECL_IS_UNDECLARED_BUILTIN (olddecl)
	      && !DECL_EXTERN_INLINE (olddecl))
	    {
	      auto_diagnostic_group d;
	      error ("static declaration of %q+D follows "
		     "non-static declaration", newdecl);
	      locate_old_decl (olddecl);
	    }
	  return false;
	}
      else if (TREE_PUBLIC (newdecl) && !TREE_PUBLIC (olddecl))
	{
	  if (DECL_CONTEXT (olddecl))
	    {
	      auto_diagnostic_group d;
	      error ("non-static declaration of %q+D follows "
		     "static declaration", newdecl);
	      locate_old_decl (olddecl);
	      return false;
	    }
	  else if (warn_traditional)
	    {
	      warned |= warning (OPT_Wtraditional,
				 "non-static declaration of %q+D "
				 "follows static declaration", newdecl);
	    }
	}

      /* Make sure gnu_inline attribute is either not present, or
	 present on all inline decls.  */
      if (DECL_DECLARED_INLINE_P (olddecl)
	  && DECL_DECLARED_INLINE_P (newdecl))
	{
	  bool newa = lookup_attribute ("gnu_inline",
					DECL_ATTRIBUTES (newdecl)) != NULL;
	  bool olda = lookup_attribute ("gnu_inline",
					DECL_ATTRIBUTES (olddecl)) != NULL;
	  if (newa != olda)
	    {
	      auto_diagnostic_group d;
	      error_at (input_location, "%<gnu_inline%> attribute present on %q+D",
			newa ? newdecl : olddecl);
	      error_at (DECL_SOURCE_LOCATION (newa ? olddecl : newdecl),
			"but not here");
	    }
	}
    }
  else if (VAR_P (newdecl))
    {
      /* Only variables can be thread-local, and all declarations must
	 agree on this property.  */
      if (C_DECL_THREADPRIVATE_P (olddecl) && !DECL_THREAD_LOCAL_P (newdecl))
	{
	  /* Nothing to check.  Since OLDDECL is marked threadprivate
	     and NEWDECL does not have a thread-local attribute, we
	     will merge the threadprivate attribute into NEWDECL.  */
	  ;
	}
      else if (DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl))
	{
	  auto_diagnostic_group d;
	  if (DECL_THREAD_LOCAL_P (newdecl))
	    error ("thread-local declaration of %q+D follows "
		   "non-thread-local declaration", newdecl);
	  else
	    error ("non-thread-local declaration of %q+D follows "
		   "thread-local declaration", newdecl);

	  locate_old_decl (olddecl);
	  return false;
	}

      /* Multiple initialized definitions are not allowed (6.9p3,5).  */
      if (DECL_INITIAL (newdecl) && DECL_INITIAL (olddecl))
	{
	  auto_diagnostic_group d;
	  error ("redefinition of %q+D", newdecl);
	  locate_old_decl (olddecl);
	  return false;
	}

      /* Objects declared at file scope: if the first declaration had
	 external linkage (even if it was an external reference) the
	 second must have external linkage as well, or the behavior is
	 undefined.  If the first declaration had internal linkage, then
	 the second must too, or else be an external reference (in which
	 case the composite declaration still has internal linkage).
	 As for function declarations, we warn about the static-then-
	 extern case only for -Wtraditional.  See generally 6.2.2p3-5,7.  */
      if (DECL_FILE_SCOPE_P (newdecl)
	  && TREE_PUBLIC (newdecl) != TREE_PUBLIC (olddecl))
	{
	  if (DECL_EXTERNAL (newdecl))
	    {
	      if (!DECL_FILE_SCOPE_P (olddecl))
		{
		  auto_diagnostic_group d;
		  error ("extern declaration of %q+D follows "
			 "declaration with no linkage", newdecl);
		  locate_old_decl (olddecl);
		  return false;
		}
	      else if (warn_traditional)
		{
		  warned |= warning (OPT_Wtraditional,
				     "non-static declaration of %q+D "
				     "follows static declaration", newdecl);
		}
	    }
	  else
	    {
	      auto_diagnostic_group d;
	      if (TREE_PUBLIC (newdecl))
		error ("non-static declaration of %q+D follows "
		       "static declaration", newdecl);
	      else
		error ("static declaration of %q+D follows "
		       "non-static declaration", newdecl);

	      locate_old_decl (olddecl);
	      return false;
	    }
	}
      /* Two objects with the same name declared at the same block
	 scope must both be external references (6.7p3).  */
      else if (!DECL_FILE_SCOPE_P (newdecl))
	{
	  if (DECL_EXTERNAL (newdecl))
	    {
	      /* Extern with initializer at block scope, which will
		 already have received an error.  */
	    }
	  else if (DECL_EXTERNAL (olddecl))
	    {
	      auto_diagnostic_group d;
	      error ("declaration of %q+D with no linkage follows "
		     "extern declaration", newdecl);
	      locate_old_decl (olddecl);
	    }
	  else
	    {
	      auto_diagnostic_group d;
	      error ("redeclaration of %q+D with no linkage", newdecl);
	      locate_old_decl (olddecl);
	    }

	  return false;
	}

      /* C++ does not permit a decl to appear multiple times at file
	 scope.  */
      if (warn_cxx_compat
	  && DECL_FILE_SCOPE_P (newdecl)
	  && !DECL_EXTERNAL (newdecl)
	  && !DECL_EXTERNAL (olddecl))
	warned |= warning_at (DECL_SOURCE_LOCATION (newdecl),
			      OPT_Wc___compat,
			      ("duplicate declaration of %qD is "
			       "invalid in C++"),
			      newdecl);
    }

  /* warnings */
  /* All decls must agree on a visibility.  */
  if (CODE_CONTAINS_STRUCT (TREE_CODE (newdecl), TS_DECL_WITH_VIS)
      && DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY_SPECIFIED (olddecl)
      && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
    {
      warned |= warning (0, "redeclaration of %q+D with different visibility "
			 "(old visibility preserved)", newdecl);
    }

  if (TREE_CODE (newdecl) == FUNCTION_DECL)
    warned |= diagnose_mismatched_attributes (olddecl, newdecl);
  else /* PARM_DECL, VAR_DECL */
    {
      /* Redeclaration of a parameter is a constraint violation (this is
	 not explicitly stated, but follows from C99 6.7p3 [no more than
	 one declaration of the same identifier with no linkage in the
	 same scope, except type tags] and 6.2.2p6 [parameters have no
	 linkage]).  We must check for a forward parameter declaration,
	 indicated by TREE_ASM_WRITTEN on the old declaration - this is
	 an extension, the mandatory diagnostic for which is handled by
	 mark_forward_parm_decls.  */

      if (TREE_CODE (newdecl) == PARM_DECL
	  && (!TREE_ASM_WRITTEN (olddecl) || TREE_ASM_WRITTEN (newdecl)))
	{
	  auto_diagnostic_group d;
	  error ("redefinition of parameter %q+D", newdecl);
	  locate_old_decl (olddecl);
	  return false;
	}
    }

  /* Optional warning for completely redundant decls.  */
  if (!warned && !pedwarned
      && warn_redundant_decls
      /* Don't warn about a function declaration followed by a
	 definition.  */
      && !(TREE_CODE (newdecl) == FUNCTION_DECL
	   && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl))
      /* Don't warn about redundant redeclarations of builtins.  */
      && !(TREE_CODE (newdecl) == FUNCTION_DECL
	   && !fndecl_built_in_p (newdecl)
	   && fndecl_built_in_p (olddecl)
	   && !C_DECL_DECLARED_BUILTIN (olddecl))
      /* Don't warn about an extern followed by a definition.  */
      && !(DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl))
      /* Don't warn about forward parameter decls.  */
      && !(TREE_CODE (newdecl) == PARM_DECL
	   && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))
      /* Don't warn about a variable definition following a declaration.  */
      && !(VAR_P (newdecl)
	   && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl)))
    {
      warned = warning (OPT_Wredundant_decls, "redundant redeclaration of %q+D",
			newdecl);
    }

  /* Report location of previous decl/defn.  */
  if (warned || pedwarned)
    locate_old_decl (olddecl);

#undef DECL_EXTERN_INLINE

  return retval;
}

/* Subroutine of duplicate_decls.  NEWDECL has been found to be
   consistent with OLDDECL, but carries new information.  Merge the
   new information into OLDDECL.  This function issues no
   diagnostics.  */

static void
merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
{
  bool new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
			    && DECL_INITIAL (newdecl) != NULL_TREE);
  bool new_is_prototype = (TREE_CODE (newdecl) == FUNCTION_DECL
			   && prototype_p (TREE_TYPE (newdecl)));
  bool old_is_prototype = (TREE_CODE (olddecl) == FUNCTION_DECL
			   && prototype_p (TREE_TYPE (olddecl)));

  /* For real parm decl following a forward decl, rechain the old decl
     in its new location and clear TREE_ASM_WRITTEN (it's not a
     forward decl anymore).  */
  if (TREE_CODE (newdecl) == PARM_DECL
      && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))
    {
      struct c_binding *b, **here;

      for (here = &current_scope->bindings; *here; here = &(*here)->prev)
	if ((*here)->decl == olddecl)
	  goto found;
      gcc_unreachable ();

    found:
      b = *here;
      *here = b->prev;
      b->prev = current_scope->bindings;
      current_scope->bindings = b;

      TREE_ASM_WRITTEN (olddecl) = 0;
    }

  DECL_ATTRIBUTES (newdecl)
    = targetm.merge_decl_attributes (olddecl, newdecl);

  /* For typedefs use the old type, as the new type's DECL_NAME points
     at newdecl, which will be ggc_freed.  */
  if (TREE_CODE (newdecl) == TYPE_DECL)
    {
      /* But NEWTYPE might have an attribute, honor that.  */
      tree tem = newtype;
      newtype = oldtype;

      if (TYPE_USER_ALIGN (tem))
	{
	  if (TYPE_ALIGN (tem) > TYPE_ALIGN (newtype))
	    SET_TYPE_ALIGN (newtype, TYPE_ALIGN (tem));
	  TYPE_USER_ALIGN (newtype) = true;
	}

      /* And remove the new type from the variants list.  */
      if (TYPE_NAME (TREE_TYPE (newdecl)) == newdecl)
	{
	  tree remove = TREE_TYPE (newdecl);
	  if (TYPE_MAIN_VARIANT (remove) == remove)
	    {
	      gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE);
	      /* If remove is the main variant, no need to remove that
		 from the list.  One of the DECL_ORIGINAL_TYPE
		 variants, e.g. created for aligned attribute, might still
		 refer to the newdecl TYPE_DECL though, so remove that one
		 in that case.  */
	      if (DECL_ORIGINAL_TYPE (newdecl)
		  && DECL_ORIGINAL_TYPE (newdecl) != remove)
		for (tree t = TYPE_MAIN_VARIANT (DECL_ORIGINAL_TYPE (newdecl));
		     t; t = TYPE_MAIN_VARIANT (t))
		  if (TYPE_NAME (TYPE_NEXT_VARIANT (t)) == newdecl)
		    {
		      TYPE_NEXT_VARIANT (t)
			= TYPE_NEXT_VARIANT (TYPE_NEXT_VARIANT (t));
		      break;
		    }
	    }	    
	  else
	    for (tree t = TYPE_MAIN_VARIANT (remove); ;
		 t = TYPE_NEXT_VARIANT (t))
	      if (TYPE_NEXT_VARIANT (t) == remove)
		{
		  TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove);
		  break;
		}
	}
    }

  /* Merge the data types specified in the two decls.  */
  TREE_TYPE (newdecl)
    = TREE_TYPE (olddecl)
    = composite_type (newtype, oldtype);

  /* Lay the type out, unless already done.  */
  if (!comptypes (oldtype, TREE_TYPE (newdecl)))
    {
      if (TREE_TYPE (newdecl) != error_mark_node)
	layout_type (TREE_TYPE (newdecl));
      if (TREE_CODE (newdecl) != FUNCTION_DECL
	  && TREE_CODE (newdecl) != TYPE_DECL
	  && TREE_CODE (newdecl) != CONST_DECL)
	layout_decl (newdecl, 0);
    }
  else
    {
      /* Since the type is OLDDECL's, make OLDDECL's size go with.  */
      DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
      DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
      SET_DECL_MODE (newdecl, DECL_MODE (olddecl));
      if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
	{
	  SET_DECL_ALIGN (newdecl, DECL_ALIGN (olddecl));
	  DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
	}
      else if (DECL_ALIGN (olddecl) == DECL_ALIGN (newdecl)
	       && DECL_USER_ALIGN (olddecl) != DECL_USER_ALIGN (newdecl))
	DECL_USER_ALIGN (newdecl) = 1;
      if (DECL_WARN_IF_NOT_ALIGN (olddecl)
	  > DECL_WARN_IF_NOT_ALIGN (newdecl))
	SET_DECL_WARN_IF_NOT_ALIGN (newdecl,
				    DECL_WARN_IF_NOT_ALIGN (olddecl));
    }

  /* Keep the old rtl since we can safely use it.  */
  if (HAS_RTL_P (olddecl))
    COPY_DECL_RTL (olddecl, newdecl);

  /* Merge the type qualifiers.  */
  if (TREE_READONLY (newdecl))
    TREE_READONLY (olddecl) = 1;

  if (TREE_THIS_VOLATILE (newdecl))
    TREE_THIS_VOLATILE (olddecl) = 1;

  /* Merge deprecatedness.  */
  if (TREE_DEPRECATED (newdecl))
    TREE_DEPRECATED (olddecl) = 1;

  /* Merge unavailability.  */
  if (TREE_UNAVAILABLE (newdecl))
    TREE_UNAVAILABLE (olddecl) = 1;

  /* If a decl is in a system header and the other isn't, keep the one on the
     system header. Otherwise, keep source location of definition rather than
     declaration and of prototype rather than non-prototype unless that
     prototype is built-in.  */
  if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS)
      && DECL_IN_SYSTEM_HEADER (olddecl)
      && !DECL_IN_SYSTEM_HEADER (newdecl) )
    DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
  else if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS)
	   && DECL_IN_SYSTEM_HEADER (newdecl)
	   && !DECL_IN_SYSTEM_HEADER (olddecl))
    DECL_SOURCE_LOCATION (olddecl) = DECL_SOURCE_LOCATION (newdecl);
  else if ((DECL_INITIAL (newdecl) == NULL_TREE
	    && DECL_INITIAL (olddecl) != NULL_TREE)
	   || (old_is_prototype && !new_is_prototype
	       && !C_DECL_BUILTIN_PROTOTYPE (olddecl)))
    DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);

  /* Merge the initialization information.  */
   if (DECL_INITIAL (newdecl) == NULL_TREE)
    DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);

  /* Merge the threadprivate attribute.  */
  if (VAR_P (olddecl) && C_DECL_THREADPRIVATE_P (olddecl))
    C_DECL_THREADPRIVATE_P (newdecl) = 1;

  if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS))
    {
      /* Copy the assembler name.
	 Currently, it can only be defined in the prototype.  */
      COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);

      /* Use visibility of whichever declaration had it specified */
      if (DECL_VISIBILITY_SPECIFIED (olddecl))
	{
	  DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
	  DECL_VISIBILITY_SPECIFIED (newdecl) = 1;
	}

      if (TREE_CODE (newdecl) == FUNCTION_DECL)
	{
	  DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
	  DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
	  DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
	  DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
	    |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
	  TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
	  DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
	  if (DECL_IS_OPERATOR_NEW_P (olddecl))
	    DECL_SET_IS_OPERATOR_NEW (newdecl, true);
	  if (DECL_IS_OPERATOR_DELETE_P (olddecl))
	    DECL_SET_IS_OPERATOR_DELETE (newdecl, true);
	  TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
	  DECL_PURE_P (newdecl) |= DECL_PURE_P (olddecl);
	  DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl);
	}

      /* Merge the storage class information.  */
      merge_weak (newdecl, olddecl);

      /* For functions, static overrides non-static.  */
      if (TREE_CODE (newdecl) == FUNCTION_DECL)
	{
	  TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
	  /* This is since we don't automatically
	     copy the attributes of NEWDECL into OLDDECL.  */
	  TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
	  /* If this clears `static', clear it in the identifier too.  */
	  if (!TREE_PUBLIC (olddecl))
	    TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
	}
    }

  /* In c99, 'extern' declaration before (or after) 'inline' means this
     function is not DECL_EXTERNAL, unless 'gnu_inline' attribute
     is present.  */
  if (TREE_CODE (newdecl) == FUNCTION_DECL
      && !flag_gnu89_inline
      && (DECL_DECLARED_INLINE_P (newdecl)
	  || DECL_DECLARED_INLINE_P (olddecl))
      && (!DECL_DECLARED_INLINE_P (newdecl)
	  || !DECL_DECLARED_INLINE_P (olddecl)
	  || !DECL_EXTERNAL (olddecl))
      && DECL_EXTERNAL (newdecl)
      && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (newdecl))
      && !current_function_decl)
    DECL_EXTERNAL (newdecl) = 0;

  /* An inline definition following a static declaration is not
     DECL_EXTERNAL.  */
  if (new_is_definition
      && (DECL_DECLARED_INLINE_P (newdecl)
	  || DECL_DECLARED_INLINE_P (olddecl))
      && !TREE_PUBLIC (olddecl))
    DECL_EXTERNAL (newdecl) = 0;

  if (DECL_EXTERNAL (newdecl))
    {
      TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
      DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);

      /* An extern decl does not override previous storage class.  */
      TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
      if (!DECL_EXTERNAL (newdecl))
	{
	  DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
	  DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
	}
    }
  else
    {
      TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
      TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
    }

  if (TREE_CODE (newdecl) == FUNCTION_DECL)
    {
      /* If we're redefining a function previously defined as extern
	 inline, make sure we emit debug info for the inline before we
	 throw it away, in case it was inlined into a function that
	 hasn't been written out yet.  */
      if (new_is_definition && DECL_INITIAL (olddecl))
	/* The new defn must not be inline.  */
	DECL_UNINLINABLE (newdecl) = 1;
      else
	{
	  /* If either decl says `inline', this fn is inline, unless
	     its definition was passed already.  */
	  if (DECL_DECLARED_INLINE_P (newdecl)
	      || DECL_DECLARED_INLINE_P (olddecl))
	    DECL_DECLARED_INLINE_P (newdecl) = 1;

	  DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
	    = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));

	  DECL_DISREGARD_INLINE_LIMITS (newdecl)
	    = DECL_DISREGARD_INLINE_LIMITS (olddecl)
	    = (DECL_DISREGARD_INLINE_LIMITS (newdecl)
	       || DECL_DISREGARD_INLINE_LIMITS (olddecl));
	}

      if (fndecl_built_in_p (olddecl))
	{
	  /* If redeclaring a builtin function, it stays built in.
	     But it gets tagged as having been declared.  */
	  copy_decl_built_in_function (newdecl, olddecl);
	  C_DECL_DECLARED_BUILTIN (newdecl) = 1;
	  if (new_is_prototype)
	    {
	      C_DECL_BUILTIN_PROTOTYPE (newdecl) = 0;
	      if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
		{
		  enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
		  switch (fncode)
		    {
		      /* If a compatible prototype of these builtin functions
			 is seen, assume the runtime implements it with the
			 expected semantics.  */
		    case BUILT_IN_STPCPY:
		      if (builtin_decl_explicit_p (fncode))
			set_builtin_decl_implicit_p (fncode, true);
		      break;
		    default:
		      if (builtin_decl_explicit_p (fncode))
			set_builtin_decl_declared_p (fncode, true);
		      break;
		    }

		  copy_attributes_to_builtin (newdecl);
		}
	    }
	  else
	    C_DECL_BUILTIN_PROTOTYPE (newdecl)
	      = C_DECL_BUILTIN_PROTOTYPE (olddecl);
	}

      /* Preserve function specific target and optimization options */
      if (DECL_FUNCTION_SPECIFIC_TARGET (olddecl)
	  && !DECL_FUNCTION_SPECIFIC_TARGET (newdecl))
	DECL_FUNCTION_SPECIFIC_TARGET (newdecl)
	  = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);

      if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl)
	  && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl))
	DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl)
	  = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl);

      /* Also preserve various other info from the definition.  */
      if (!new_is_definition)
	{
	  tree t;
	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
	  DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
	  DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
	  DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
	  DECL_ARGUMENTS (newdecl) = copy_list (DECL_ARGUMENTS (olddecl));
	  for (t = DECL_ARGUMENTS (newdecl); t ; t = DECL_CHAIN (t))
	    DECL_CONTEXT (t) = newdecl;

	  /* See if we've got a function to instantiate from.  */
	  if (DECL_SAVED_TREE (olddecl))
	    DECL_ABSTRACT_ORIGIN (newdecl)
	      = DECL_ABSTRACT_ORIGIN (olddecl);
	}
    }

  /* Merge the USED information.  */
  if (TREE_USED (olddecl))
    TREE_USED (newdecl) = 1;
  else if (TREE_USED (newdecl))
    TREE_USED (olddecl) = 1;
  if (VAR_P (olddecl) || TREE_CODE (olddecl) == PARM_DECL)
    DECL_READ_P (newdecl) |= DECL_READ_P (olddecl);
  if (DECL_PRESERVE_P (olddecl))
    DECL_PRESERVE_P (newdecl) = 1;
  else if (DECL_PRESERVE_P (newdecl))
    DECL_PRESERVE_P (olddecl) = 1;

  /* Merge DECL_COMMON */
  if (VAR_P (olddecl) && VAR_P (newdecl)
      && !lookup_attribute ("common", DECL_ATTRIBUTES (newdecl))
      && !lookup_attribute ("nocommon", DECL_ATTRIBUTES (newdecl)))
    DECL_COMMON (newdecl) = DECL_COMMON (newdecl) && DECL_COMMON (olddecl);

  /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
     But preserve OLDDECL's DECL_UID, DECL_CONTEXT and
     DECL_ARGUMENTS (if appropriate).  */
  {
    unsigned olddecl_uid = DECL_UID (olddecl);
    tree olddecl_context = DECL_CONTEXT (olddecl);
    tree olddecl_arguments = NULL;
    if (TREE_CODE (olddecl) == FUNCTION_DECL)
      olddecl_arguments = DECL_ARGUMENTS (olddecl);

    memcpy ((char *) olddecl + sizeof (struct tree_common),
	    (char *) newdecl + sizeof (struct tree_common),
	    sizeof (struct tree_decl_common) - sizeof (struct tree_common));
    DECL_USER_ALIGN (olddecl) = DECL_USER_ALIGN (newdecl);
    switch (TREE_CODE (olddecl))
      {
      case FUNCTION_DECL:
      case VAR_DECL:
	{
	  struct symtab_node *snode = olddecl->decl_with_vis.symtab_node;

	  memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
		  (char *) newdecl + sizeof (struct tree_decl_common),
		  tree_code_size (TREE_CODE (olddecl)) - sizeof (struct tree_decl_common));
	  olddecl->decl_with_vis.symtab_node = snode;

	  if ((DECL_EXTERNAL (olddecl)
	       || TREE_PUBLIC (olddecl)
	       || TREE_STATIC (olddecl))
	      && DECL_SECTION_NAME (newdecl) != NULL)
	    set_decl_section_name (olddecl, newdecl);

	  /* This isn't quite correct for something like
		int __thread x attribute ((tls_model ("local-exec")));
		extern int __thread x;
	     as we'll lose the "local-exec" model.  */
	  if (VAR_P (olddecl) && DECL_THREAD_LOCAL_P (newdecl))
	    set_decl_tls_model (olddecl, DECL_TLS_MODEL (newdecl));
	  break;
	}

      case FIELD_DECL:
      case PARM_DECL:
      case LABEL_DECL:
      case RESULT_DECL:
      case CONST_DECL:
      case TYPE_DECL:
	memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
		(char *) newdecl + sizeof (struct tree_decl_common),
		tree_code_size (TREE_CODE (olddecl)) - sizeof (struct tree_decl_common));
	break;

      default:

	memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
		(char *) newdecl + sizeof (struct tree_decl_common),
		sizeof (struct tree_decl_non_common) - sizeof (struct tree_decl_common));
      }
    DECL_UID (olddecl) = olddecl_uid;
    DECL_CONTEXT (olddecl) = olddecl_context;
    if (TREE_CODE (olddecl) == FUNCTION_DECL)
      DECL_ARGUMENTS (olddecl) = olddecl_arguments;
  }

  /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
     so that encode_section_info has a chance to look at the new decl
     flags and attributes.  */
  if (DECL_RTL_SET_P (olddecl)
      && (TREE_CODE (olddecl) == FUNCTION_DECL
	  || (VAR_P (olddecl) && TREE_STATIC (olddecl))))
    make_decl_rtl (olddecl);
}

/* Handle when a new declaration NEWDECL has the same name as an old
   one OLDDECL in the same binding contour.  Prints an error message
   if appropriate.

   If safely possible, alter OLDDECL to look like NEWDECL, and return
   true.  Otherwise, return false.  */

static bool
duplicate_decls (tree newdecl, tree olddecl)
{
  tree newtype = NULL, oldtype = NULL;

  if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, &oldtype))
    {
      /* Avoid `unused variable' and other warnings for OLDDECL.  */
      suppress_warning (olddecl, OPT_Wunused);
      /* If the types are completely different, poison them both with
 	 error_mark_node.  */
      if (TREE_CODE (TREE_TYPE (newdecl)) != TREE_CODE (TREE_TYPE (olddecl))
	  && olddecl != error_mark_node
	  && seen_error ())
	{
	  if (TREE_CODE (olddecl) != FUNCTION_DECL)
	    TREE_TYPE (olddecl) = error_mark_node;
	  if (TREE_CODE (newdecl) != FUNCTION_DECL)
	    TREE_TYPE (newdecl) = error_mark_node;
	}
      return false;
    }

  merge_decls (newdecl, olddecl, newtype, oldtype);

  /* The NEWDECL will no longer be needed.

     Before releasing the node, be sure to remove function from symbol
     table that might have been inserted there to record comdat group.
     Be sure to however do not free DECL_STRUCT_FUNCTION because this
     structure is shared in between NEWDECL and OLDECL.  */
  if (TREE_CODE (newdecl) == FUNCTION_DECL)
    DECL_STRUCT_FUNCTION (newdecl) = NULL;
  if (VAR_OR_FUNCTION_DECL_P (newdecl))
    {
      struct symtab_node *snode = symtab_node::get (newdecl);
      if (snode)
	snode->remove ();
    }
  ggc_free (newdecl);
  return true;
}


/* Check whether decl-node NEW_DECL shadows an existing declaration.  */
static void
warn_if_shadowing (tree new_decl)
{
  struct c_binding *b;

  /* Shadow warnings wanted?  */
  if (!(warn_shadow
        || warn_shadow_local
        || warn_shadow_compatible_local)
      /* No shadow warnings for internally generated vars.  */
      || DECL_IS_UNDECLARED_BUILTIN (new_decl))
    return;

  /* Is anything being shadowed?  Invisible decls do not count.  */
  for (b = I_SYMBOL_BINDING (DECL_NAME (new_decl)); b; b = b->shadowed)
    if (b->decl && b->decl != new_decl && !b->invisible
	&& (b->decl == error_mark_node
	    || diagnostic_report_warnings_p (global_dc,
					     DECL_SOURCE_LOCATION (b->decl))))
      {
	tree old_decl = b->decl;

	if (old_decl == error_mark_node)
	  {
	    warning (OPT_Wshadow, "declaration of %q+D shadows previous "
		     "non-variable", new_decl);
	    break;
	  }

	bool warned = false;
	auto_diagnostic_group d;
	if (TREE_CODE (old_decl) == PARM_DECL)
	  {
	    enum opt_code warning_code;

	    /* If '-Wshadow=compatible-local' is specified without other
	       -Wshadow= flags, we will warn only when the types of the
	       shadowing variable (i.e. new_decl) and the shadowed variable
	       (old_decl) are compatible.  */
	    if (warn_shadow)
	      warning_code = OPT_Wshadow;
	    else if (comptypes (TREE_TYPE (old_decl), TREE_TYPE (new_decl)))
	      warning_code = OPT_Wshadow_compatible_local;
	    else
	      warning_code = OPT_Wshadow_local;
	    warned = warning_at (DECL_SOURCE_LOCATION (new_decl), warning_code,
				 "declaration of %qD shadows a parameter",
				 new_decl);
	  }
	else if (DECL_FILE_SCOPE_P (old_decl))
	  {
	    /* Do not warn if a variable shadows a function, unless
	       the variable is a function or a pointer-to-function.  */
	    if (TREE_CODE (old_decl) == FUNCTION_DECL
		&& TREE_CODE (new_decl) != FUNCTION_DECL
		&& !FUNCTION_POINTER_TYPE_P (TREE_TYPE (new_decl)))
		continue;

	    warned = warning_at (DECL_SOURCE_LOCATION (new_decl), OPT_Wshadow,
				 "declaration of %qD shadows a global "
				 "declaration",
				 new_decl);
	  }
	else if (TREE_CODE (old_decl) == FUNCTION_DECL
		 && fndecl_built_in_p (old_decl))
	  {
	    warning (OPT_Wshadow, "declaration of %q+D shadows "
		     "a built-in function", new_decl);
	    break;
	  }
	else
	  {
	    enum opt_code warning_code;

	    /* If '-Wshadow=compatible-local' is specified without other
	       -Wshadow= flags, we will warn only when the types of the
	       shadowing variable (i.e. new_decl) and the shadowed variable
	       (old_decl) are compatible.  */
	    if (warn_shadow)
	      warning_code = OPT_Wshadow;
	    else if (comptypes (TREE_TYPE (old_decl), TREE_TYPE (new_decl)))
	      warning_code = OPT_Wshadow_compatible_local;
	    else
	      warning_code = OPT_Wshadow_local;
	    warned = warning_at (DECL_SOURCE_LOCATION (new_decl), warning_code,
				 "declaration of %qD shadows a previous local",
				 new_decl);
	  }

	if (warned)
	  inform (DECL_SOURCE_LOCATION (old_decl),
		  "shadowed declaration is here");

	break;
      }
}

/* Record a decl-node X as belonging to the current lexical scope.
   Check for errors (such as an incompatible declaration for the same
   name already seen in the same scope).

   Returns either X or an old decl for the same name.
   If an old decl is returned, it may have been smashed
   to agree with what X says.  */

tree
pushdecl (tree x)
{
  tree name = DECL_NAME (x);
  struct c_scope *scope = current_scope;
  struct c_binding *b;
  bool nested = false;
  location_t locus = DECL_SOURCE_LOCATION (x);

  /* Must set DECL_CONTEXT for everything not at file scope or
     DECL_FILE_SCOPE_P won't work.  Local externs don't count
     unless they have initializers (which generate code).  */
  if (current_function_decl
      && (!VAR_OR_FUNCTION_DECL_P (x)
	  || DECL_INITIAL (x) || !TREE_PUBLIC (x)))
    DECL_CONTEXT (x) = current_function_decl;

  /* Anonymous decls are just inserted in the scope.  */
  if (!name)
    {
      bind (name, x, scope, /*invisible=*/false, /*nested=*/false,
	    locus);
      return x;
    }

  /* First, see if there is another declaration with the same name in
     the current scope.  If there is, duplicate_decls may do all the
     work for us.  If duplicate_decls returns false, that indicates
     two incompatible decls in the same scope; we are to silently
     replace the old one (duplicate_decls has issued all appropriate
     diagnostics).  In particular, we should not consider possible
     duplicates in the external scope, or shadowing.  */
  b = I_SYMBOL_BINDING (name);
  if (b && B_IN_SCOPE (b, scope))
    {
      struct c_binding *b_ext, *b_use;
      tree type = TREE_TYPE (x);
      tree visdecl = b->decl;
      tree vistype = TREE_TYPE (visdecl);
      if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
	  && COMPLETE_TYPE_P (TREE_TYPE (x)))
	b->inner_comp = false;
      b_use = b;
      b_ext = b;
      /* If this is an external linkage declaration, we should check
	 for compatibility with the type in the external scope before
	 setting the type at this scope based on the visible
	 information only.  */
      if (TREE_PUBLIC (x) && TREE_PUBLIC (visdecl))
	{
	  while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext))
	    b_ext = b_ext->shadowed;
	  if (b_ext)
	    {
	      b_use = b_ext;
	      if (b_use->u.type)
		TREE_TYPE (b_use->decl) = b_use->u.type;
	    }
	}
      if (duplicate_decls (x, b_use->decl))
	{
	  if (b_use != b)
	    {
	      /* Save the updated type in the external scope and
		 restore the proper type for this scope.  */
	      tree thistype;
	      if (comptypes (vistype, type))
		thistype = composite_type (vistype, type);
	      else
		thistype = TREE_TYPE (b_use->decl);
	      b_use->u.type = TREE_TYPE (b_use->decl);
	      if (TREE_CODE (b_use->decl) == FUNCTION_DECL
		  && fndecl_built_in_p (b_use->decl))
		thistype
		  = build_type_attribute_variant (thistype,
						  TYPE_ATTRIBUTES
						  (b_use->u.type));
	      TREE_TYPE (b_use->decl) = thistype;
	    }
	  return b_use->decl;
	}
      else
	goto skip_external_and_shadow_checks;
    }

  /* All declarations with external linkage, and all external
     references, go in the external scope, no matter what scope is
     current.  However, the binding in that scope is ignored for
     purposes of normal name lookup.  A separate binding structure is
     created in the requested scope; this governs the normal
     visibility of the symbol.

     The binding in the externals scope is used exclusively for
     detecting duplicate declarations of the same object, no matter
     what scope they are in; this is what we do here.  (C99 6.2.7p2:
     All declarations that refer to the same object or function shall
     have compatible type; otherwise, the behavior is undefined.)
     However, in Objective-C, we also want to detect declarations
     conflicting with those of the basic types.  */
  if ((DECL_EXTERNAL (x) || scope == file_scope)
      && (VAR_OR_FUNCTION_DECL_P (x) || c_dialect_objc ()))
    {
      tree type = TREE_TYPE (x);
      tree vistype = NULL_TREE;
      tree visdecl = NULL_TREE;
      bool type_saved = false;
      if (b && !B_IN_EXTERNAL_SCOPE (b)
	  && VAR_OR_FUNCTION_DECL_P (b->decl)
	  && DECL_FILE_SCOPE_P (b->decl))
	{
	  visdecl = b->decl;
	  vistype = TREE_TYPE (visdecl);
	}
      if (scope != file_scope
	  && !DECL_IN_SYSTEM_HEADER (x))
	warning_at (locus, OPT_Wnested_externs,
		    "nested extern declaration of %qD", x);

      while (b && !B_IN_EXTERNAL_SCOPE (b))
	{
	  /* If this decl might be modified, save its type.  This is
	     done here rather than when the decl is first bound
	     because the type may change after first binding, through
	     being completed or through attributes being added.  If we
	     encounter multiple such decls, only the first should have
	     its type saved; the others will already have had their
	     proper types saved and the types will not have changed as
	     their scopes will not have been re-entered.  */
	  if (DECL_P (b->decl) && DECL_FILE_SCOPE_P (b->decl) && !type_saved)
	    {
	      b->u.type = TREE_TYPE (b->decl);
	      type_saved = true;
	    }
	  if (B_IN_FILE_SCOPE (b)
	      && VAR_P (b->decl)
	      && TREE_STATIC (b->decl)
	      && TREE_CODE (TREE_TYPE (b->decl)) == ARRAY_TYPE
	      && !TYPE_DOMAIN (TREE_TYPE (b->decl))
	      && TREE_CODE (type) == ARRAY_TYPE
	      && TYPE_DOMAIN (type)
	      && TYPE_MAX_VALUE (TYPE_DOMAIN (type))
	      && !integer_zerop (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
	    {
	      /* Array type completed in inner scope, which should be
		 diagnosed if the completion does not have size 1 and
		 it does not get completed in the file scope.  */
	      b->inner_comp = true;
	    }
	  b = b->shadowed;
	}

      /* If a matching external declaration has been found, set its
	 type to the composite of all the types of that declaration.
	 After the consistency checks, it will be reset to the
	 composite of the visible types only.  */
      if (b && (TREE_PUBLIC (x) || same_translation_unit_p (x, b->decl))
	  && b->u.type)
	TREE_TYPE (b->decl) = b->u.type;

      /* The point of the same_translation_unit_p check here is,
	 we want to detect a duplicate decl for a construct like
	 foo() { extern bar(); } ... static bar();  but not if
	 they are in different translation units.  In any case,
	 the static does not go in the externals scope.  */
      if (b
	  && (TREE_PUBLIC (x) || same_translation_unit_p (x, b->decl))
	  && duplicate_decls (x, b->decl))
	{
	  tree thistype;
	  if (vistype)
	    {
	      if (comptypes (vistype, type))
		thistype = composite_type (vistype, type);
	      else
		thistype = TREE_TYPE (b->decl);
	    }
	  else
	    thistype = type;
	  b->u.type = TREE_TYPE (b->decl);
	  /* Propagate the type attributes to the decl.  */
	  thistype
	    = build_type_attribute_variant (thistype,
					    TYPE_ATTRIBUTES (b->u.type));
	  TREE_TYPE (b->decl) = thistype;
	  bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true,
		locus);
	  return b->decl;
	}
      else if (TREE_PUBLIC (x))
	{
	  if (visdecl && !b && duplicate_decls (x, visdecl))
	    {
	      /* An external declaration at block scope referring to a
		 visible entity with internal linkage.  The composite
		 type will already be correct for this scope, so we
		 just need to fall through to make the declaration in
		 this scope.  */
	      nested = true;
	      x = visdecl;
	    }
	  else
	    {
	      bind (name, x, external_scope, /*invisible=*/true,
		    /*nested=*/false, locus);
	      nested = true;
	    }
	}
    }

  if (TREE_CODE (x) != PARM_DECL)
    warn_if_shadowing (x);

 skip_external_and_shadow_checks:
  if (TREE_CODE (x) == TYPE_DECL)
    {
      /* So this is a typedef, set its underlying type.  */
      set_underlying_type (x);

      /* If X is a typedef defined in the current function, record it
	 for the purpose of implementing the -Wunused-local-typedefs
	 warning.  */
      record_locally_defined_typedef (x);
    }

  bind (name, x, scope, /*invisible=*/false, nested, locus);

  /* If x's type is incomplete because it's based on a
     structure or union which has not yet been fully declared,
     attach it to that structure or union type, so we can go
     back and complete the variable declaration later, if the
     structure or union gets fully declared.

     If the input is erroneous, we can have error_mark in the type
     slot (e.g. "f(void a, ...)") - that doesn't count as an
     incomplete type.  */
  if (TREE_TYPE (x) != error_mark_node
      && !COMPLETE_TYPE_P (TREE_TYPE (x)))
    {
      tree element = TREE_TYPE (x);

      while (TREE_CODE (element) == ARRAY_TYPE)
	element = TREE_TYPE (element);
      element = TYPE_MAIN_VARIANT (element);

      if ((RECORD_OR_UNION_TYPE_P (element)
	   || TREE_CODE (element) == ENUMERAL_TYPE)
	  && (TREE_CODE (x) != TYPE_DECL
	      || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
	  && !COMPLETE_TYPE_P (element))
	C_TYPE_INCOMPLETE_VARS (element)
	  = tree_cons (NULL_TREE, x, C_TYPE_INCOMPLETE_VARS (element));
    }
  return x;
}


/* Issue a warning about implicit function declaration.  ID is the function
   identifier, OLDDECL is a declaration of the function in a different scope,
   or NULL_TREE.  */

static void
implicit_decl_warning (location_t loc, tree id, tree olddecl)
{
  if (!warn_implicit_function_declaration)
    return;

  bool warned;
  auto_diagnostic_group d;
  name_hint hint;
  if (!olddecl)
    hint = lookup_name_fuzzy (id, FUZZY_LOOKUP_FUNCTION_NAME, loc);

  if (flag_isoc99)
    {
      if (const char *suggestion = hint.suggestion ())
	{
	  gcc_rich_location richloc (loc);
	  richloc.add_fixit_replace (suggestion);
	  warned = pedwarn (&richloc, OPT_Wimplicit_function_declaration,
			    "implicit declaration of function %qE;"
			    " did you mean %qs?",
			    id, suggestion);
	}
      else
	warned = pedwarn (loc, OPT_Wimplicit_function_declaration,
			  "implicit declaration of function %qE", id);
    }
  else if (const char *suggestion = hint.suggestion ())
    {
      gcc_rich_location richloc (loc);
      richloc.add_fixit_replace (suggestion);
      warned = warning_at
	(&richloc, OPT_Wimplicit_function_declaration,
	 G_("implicit declaration of function %qE; did you mean %qs?"),
	 id, suggestion);
    }
  else
    warned = warning_at (loc, OPT_Wimplicit_function_declaration,
			 G_("implicit declaration of function %qE"), id);

  if (warned)
    {
      /* Whether the olddecl is an undeclared builtin function.
	 locate_old_decl will not generate a diagnostic for those,
	 so in that case we want to look elsewhere.  */
      bool undeclared_builtin = (olddecl
				 && TREE_CODE (olddecl) == FUNCTION_DECL
				 && fndecl_built_in_p (olddecl)
				 && !C_DECL_DECLARED_BUILTIN (olddecl));
      if (undeclared_builtin)
	{
	  const char *header = header_for_builtin_fn (olddecl);
	  if (header)
	    {
	      rich_location richloc (line_table, loc);
	      maybe_add_include_fixit (&richloc, header, true);
	      inform (&richloc,
		      "include %qs or provide a declaration of %qE",
		      header, id);
	    }
	}
      else if (olddecl)
	locate_old_decl (olddecl);
    }

  if (!warned)
    hint.suppress ();
}

/* Return the name of the header file that declares built-in function
   FNDECL, or null if either we don't know or don't expect to see an
   explicit declaration.  */

static const char *
header_for_builtin_fn (tree fndecl)
{
  if (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
    return NULL;

  switch (DECL_FUNCTION_CODE (fndecl))
    {
    CASE_FLT_FN (BUILT_IN_ACOS):
    CASE_FLT_FN (BUILT_IN_ACOSH):
    CASE_FLT_FN (BUILT_IN_ASIN):
    CASE_FLT_FN (BUILT_IN_ASINH):
    CASE_FLT_FN (BUILT_IN_ATAN):
    CASE_FLT_FN (BUILT_IN_ATANH):
    CASE_FLT_FN (BUILT_IN_ATAN2):
    CASE_FLT_FN (BUILT_IN_CBRT):
    CASE_FLT_FN (BUILT_IN_CEIL):
    CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL):
    CASE_FLT_FN (BUILT_IN_COPYSIGN):
    CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
    CASE_FLT_FN (BUILT_IN_COS):
    CASE_FLT_FN (BUILT_IN_COSH):
    CASE_FLT_FN (BUILT_IN_ERF):
    CASE_FLT_FN (BUILT_IN_ERFC):
    CASE_FLT_FN (BUILT_IN_EXP):
    CASE_FLT_FN (BUILT_IN_EXP2):
    CASE_FLT_FN (BUILT_IN_EXPM1):
    CASE_FLT_FN (BUILT_IN_FABS):
    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
    CASE_FLT_FN (BUILT_IN_FDIM):
    CASE_FLT_FN (BUILT_IN_FLOOR):
    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR):
    CASE_FLT_FN (BUILT_IN_FMA):
    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
    CASE_FLT_FN (BUILT_IN_FMAX):
    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMAX):
    CASE_FLT_FN (BUILT_IN_FMIN):
    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMIN):
    CASE_FLT_FN (BUILT_IN_FMOD):
    CASE_FLT_FN (BUILT_IN_FREXP):
    CASE_FLT_FN (BUILT_IN_HYPOT):
    CASE_FLT_FN (BUILT_IN_ILOGB):
    CASE_FLT_FN (BUILT_IN_LDEXP):
    CASE_FLT_FN (BUILT_IN_LGAMMA):
    CASE_FLT_FN (BUILT_IN_LLRINT):
    CASE_FLT_FN (BUILT_IN_LLROUND):
    CASE_FLT_FN (BUILT_IN_LOG):
    CASE_FLT_FN (BUILT_IN_LOG10):
    CASE_FLT_FN (BUILT_IN_LOG1P):
    CASE_FLT_FN (BUILT_IN_LOG2):
    CASE_FLT_FN (BUILT_IN_LOGB):
    CASE_FLT_FN (BUILT_IN_LRINT):
    CASE_FLT_FN (BUILT_IN_LROUND):
    CASE_FLT_FN (BUILT_IN_MODF):
    CASE_FLT_FN (BUILT_IN_NAN):
    CASE_FLT_FN (BUILT_IN_NEARBYINT):
    CASE_FLT_FN_FLOATN_NX (BUILT_IN_NEARBYINT):
    CASE_FLT_FN (BUILT_IN_NEXTAFTER):
    CASE_FLT_FN (BUILT_IN_NEXTTOWARD):
    CASE_FLT_FN (BUILT_IN_POW):
    CASE_FLT_FN (BUILT_IN_REMAINDER):
    CASE_FLT_FN (BUILT_IN_REMQUO):
    CASE_FLT_FN (BUILT_IN_RINT):
    CASE_FLT_FN_FLOATN_NX (BUILT_IN_RINT):
    CASE_FLT_FN (BUILT_IN_ROUND):
    CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND):
    CASE_FLT_FN (BUILT_IN_SCALBLN):
    CASE_FLT_FN (BUILT_IN_SCALBN):
    CASE_FLT_FN (BUILT_IN_SIN):
    CASE_FLT_FN (BUILT_IN_SINH):
    CASE_FLT_FN (BUILT_IN_SINCOS):
    CASE_FLT_FN (BUILT_IN_SQRT):
    CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
    CASE_FLT_FN (BUILT_IN_TAN):
    CASE_FLT_FN (BUILT_IN_TANH):
    CASE_FLT_FN (BUILT_IN_TGAMMA):
    CASE_FLT_FN (BUILT_IN_TRUNC):
    CASE_FLT_FN_FLOATN_NX (BUILT_IN_TRUNC):
    case BUILT_IN_ISINF:
    case BUILT_IN_ISNAN:
      return "<math.h>";
    CASE_FLT_FN (BUILT_IN_CABS):
    CASE_FLT_FN (BUILT_IN_CACOS):
    CASE_FLT_FN (BUILT_IN_CACOSH):
    CASE_FLT_FN (BUILT_IN_CARG):
    CASE_FLT_FN (BUILT_IN_CASIN):
    CASE_FLT_FN (BUILT_IN_CASINH):
    CASE_FLT_FN (BUILT_IN_CATAN):
    CASE_FLT_FN (BUILT_IN_CATANH):
    CASE_FLT_FN (BUILT_IN_CCOS):
    CASE_FLT_FN (BUILT_IN_CCOSH):
    CASE_FLT_FN (BUILT_IN_CEXP):
    CASE_FLT_FN (BUILT_IN_CIMAG):
    CASE_FLT_FN (BUILT_IN_CLOG):
    CASE_FLT_FN (BUILT_IN_CONJ):
    CASE_FLT_FN (BUILT_IN_CPOW):
    CASE_FLT_FN (BUILT_IN_CPROJ):
    CASE_FLT_FN (BUILT_IN_CREAL):
    CASE_FLT_FN (BUILT_IN_CSIN):
    CASE_FLT_FN (BUILT_IN_CSINH):
    CASE_FLT_FN (BUILT_IN_CSQRT):
    CASE_FLT_FN (BUILT_IN_CTAN):
    CASE_FLT_FN (BUILT_IN_CTANH):
      return "<complex.h>";
    case BUILT_IN_MEMCHR:
    case BUILT_IN_MEMCMP:
    case BUILT_IN_MEMCPY:
    case BUILT_IN_MEMMOVE:
    case BUILT_IN_MEMSET:
    case BUILT_IN_STRCAT:
    case BUILT_IN_STRCHR:
    case BUILT_IN_STRCMP:
    case BUILT_IN_STRCPY:
    case BUILT_IN_STRCSPN:
    case BUILT_IN_STRLEN:
    case BUILT_IN_STRNCAT:
    case BUILT_IN_STRNCMP:
    case BUILT_IN_STRNCPY:
    case BUILT_IN_STRPBRK:
    case BUILT_IN_STRRCHR:
    case BUILT_IN_STRSPN:
    case BUILT_IN_STRSTR:
      return "<string.h>";
    case BUILT_IN_FPRINTF:
    case BUILT_IN_PUTC:
    case BUILT_IN_FPUTC:
    case BUILT_IN_FPUTS:
    case BUILT_IN_FSCANF:
    case BUILT_IN_FWRITE:
    case BUILT_IN_PRINTF:
    case BUILT_IN_PUTCHAR:
    case BUILT_IN_PUTS:
    case BUILT_IN_SCANF:
    case BUILT_IN_SNPRINTF:
    case BUILT_IN_SPRINTF:
    case BUILT_IN_SSCANF:
    case BUILT_IN_VFPRINTF:
    case BUILT_IN_VFSCANF:
    case BUILT_IN_VPRINTF:
    case BUILT_IN_VSCANF:
    case BUILT_IN_VSNPRINTF:
    case BUILT_IN_VSPRINTF:
    case BUILT_IN_VSSCANF:
      return "<stdio.h>";
    case BUILT_IN_ISALNUM:
    case BUILT_IN_ISALPHA:
    case BUILT_IN_ISBLANK:
    case BUILT_IN_ISCNTRL:
    case BUILT_IN_ISDIGIT:
    case BUILT_IN_ISGRAPH:
    case BUILT_IN_ISLOWER:
    case BUILT_IN_ISPRINT:
    case BUILT_IN_ISPUNCT:
    case BUILT_IN_ISSPACE:
    case BUILT_IN_ISUPPER:
    case BUILT_IN_ISXDIGIT:
    case BUILT_IN_TOLOWER:
    case BUILT_IN_TOUPPER:
      return "<ctype.h>";
    case BUILT_IN_ISWALNUM:
    case BUILT_IN_ISWALPHA:
    case BUILT_IN_ISWBLANK:
    case BUILT_IN_ISWCNTRL:
    case BUILT_IN_ISWDIGIT:
    case BUILT_IN_ISWGRAPH:
    case BUILT_IN_ISWLOWER:
    case BUILT_IN_ISWPRINT:
    case BUILT_IN_ISWPUNCT:
    case BUILT_IN_ISWSPACE:
    case BUILT_IN_ISWUPPER:
    case BUILT_IN_ISWXDIGIT:
    case BUILT_IN_TOWLOWER:
    case BUILT_IN_TOWUPPER:
      return "<wctype.h>";
    case BUILT_IN_ABORT:
    case BUILT_IN_ABS:
    case BUILT_IN_CALLOC:
    case BUILT_IN_EXIT:
    case BUILT_IN_FREE:
    case BUILT_IN_LABS:
    case BUILT_IN_LLABS:
    case BUILT_IN_MALLOC:
    case BUILT_IN_REALLOC:
    case BUILT_IN__EXIT2:
    case BUILT_IN_ALIGNED_ALLOC:
      return "<stdlib.h>";
    case BUILT_IN_IMAXABS:
      return "<inttypes.h>";
    case BUILT_IN_STRFTIME:
      return "<time.h>";
    default:
      return NULL;
    }
}

/* Generate an implicit declaration for identifier FUNCTIONID at LOC as a
   function of type int ().  */

tree
implicitly_declare (location_t loc, tree functionid)
{
  struct c_binding *b;
  tree decl = NULL_TREE;
  tree asmspec_tree;

  for (b = I_SYMBOL_BINDING (functionid); b; b = b->shadowed)
    {
      if (B_IN_SCOPE (b, external_scope))
	{
	  decl = b->decl;
	  break;
	}
    }

  if (decl)
    {
      if (TREE_CODE (decl) != FUNCTION_DECL)
	return decl;

      /* FIXME: Objective-C has weird not-really-builtin functions
	 which are supposed to be visible automatically.  They wind up
	 in the external scope because they're pushed before the file
	 scope gets created.  Catch this here and rebind them into the
	 file scope.  */
      if (!fndecl_built_in_p (decl) && DECL_IS_UNDECLARED_BUILTIN (decl))
	{
	  bind (functionid, decl, file_scope,
		/*invisible=*/false, /*nested=*/true,
		DECL_SOURCE_LOCATION (decl));
	  return decl;
	}
      else
	{
	  tree newtype = default_function_type;
	  if (b->u.type)
	    TREE_TYPE (decl) = b->u.type;
	  /* Implicit declaration of a function already declared
	     (somehow) in a different scope, or as a built-in.
	     If this is the first time this has happened, warn;
	     then recycle the old declaration but with the new type.  */
	  if (!C_DECL_IMPLICIT (decl))
	    {
	      implicit_decl_warning (loc, functionid, decl);
	      C_DECL_IMPLICIT (decl) = 1;
	    }
	  if (fndecl_built_in_p (decl))
	    {
	      newtype = build_type_attribute_variant (newtype,
						      TYPE_ATTRIBUTES
						      (TREE_TYPE (decl)));
	      if (!comptypes (newtype, TREE_TYPE (decl)))
		{
		  bool warned = warning_at (loc,
					    OPT_Wbuiltin_declaration_mismatch,
					    "incompatible implicit "
					    "declaration of built-in "
					    "function %qD", decl);
		  /* See if we can hint which header to include.  */
		  const char *header = header_for_builtin_fn (decl);
		  if (header != NULL && warned)
		    {
		      rich_location richloc (line_table, loc);
		      maybe_add_include_fixit (&richloc, header, true);
		      inform (&richloc,
			      "include %qs or provide a declaration of %qD",
			      header, decl);
		    }
		  newtype = TREE_TYPE (decl);
		}
	    }
	  else
	    {
	      if (!comptypes (newtype, TREE_TYPE (decl)))
		{
		  auto_diagnostic_group d;
		  error_at (loc, "incompatible implicit declaration of "
			    "function %qD", decl);
		  locate_old_decl (decl);
		}
	    }
	  b->u.type = TREE_TYPE (decl);
	  TREE_TYPE (decl) = newtype;
	  bind (functionid, decl, current_scope,
		/*invisible=*/false, /*nested=*/true,
		DECL_SOURCE_LOCATION (decl));
	  return decl;
	}
    }

  /* Not seen before.  */
  decl = build_decl (loc, FUNCTION_DECL, functionid, default_function_type);
  DECL_EXTERNAL (decl) = 1;
  TREE_PUBLIC (decl) = 1;
  C_DECL_IMPLICIT (decl) = 1;
  implicit_decl_warning (loc, functionid, 0);
  asmspec_tree = maybe_apply_renaming_pragma (decl, /*asmname=*/NULL);
  if (asmspec_tree)
    set_user_assembler_name (decl, TREE_STRING_POINTER (asmspec_tree));

  /* C89 says implicit declarations are in the innermost block.
     So we record the decl in the standard fashion.  */
  decl = pushdecl (decl);

  /* No need to call objc_check_decl here - it's a function type.  */
  rest_of_decl_compilation (decl, 0, 0);

  /* Write a record describing this implicit function declaration
     to the prototypes file (if requested).  */
  gen_aux_info_record (decl, 0, 1, 0);

  /* Possibly apply some default attributes to this implicit declaration.  */
  decl_attributes (&decl, NULL_TREE, 0);

  return decl;
}

/* Issue an error message for a reference to an undeclared variable
   ID, including a reference to a builtin outside of function-call
   context.  Establish a binding of the identifier to error_mark_node
   in an appropriate scope, which will suppress further errors for the
   same identifier.  The error message should be given location LOC.  */
void
undeclared_variable (location_t loc, tree id)
{
  static bool already = false;
  struct c_scope *scope;

  auto_diagnostic_group d;
  if (current_function_decl == NULL_TREE)
    {
      name_hint guessed_id = lookup_name_fuzzy (id, FUZZY_LOOKUP_NAME, loc);
      if (const char *suggestion = guessed_id.suggestion ())
	{
	  gcc_rich_location richloc (loc);
	  richloc.add_fixit_replace (suggestion);
	  error_at (&richloc,
		    "%qE undeclared here (not in a function);"
		    " did you mean %qs?",
		    id, suggestion);
	}
      else
	error_at (loc, "%qE undeclared here (not in a function)", id);
      scope = current_scope;
    }
  else
    {
      if (!objc_diagnose_private_ivar (id))
	{
	  name_hint guessed_id = lookup_name_fuzzy (id, FUZZY_LOOKUP_NAME, loc);
	  if (const char *suggestion = guessed_id.suggestion ())
	    {
	      gcc_rich_location richloc (loc);
	      richloc.add_fixit_replace (suggestion);
	      error_at (&richloc,
			"%qE undeclared (first use in this function);"
			" did you mean %qs?",
			id, suggestion);
	    }
	  else
	    error_at (loc, "%qE undeclared (first use in this function)", id);
	}
      if (!already)
	{
          inform (loc, "each undeclared identifier is reported only"
                  " once for each function it appears in");
	  already = true;
	}

      /* If we are parsing old-style parameter decls, current_function_decl
	 will be nonnull but current_function_scope will be null.  */
      scope = current_function_scope ? current_function_scope : current_scope;
    }
  bind (id, error_mark_node, scope, /*invisible=*/false, /*nested=*/false,
	UNKNOWN_LOCATION);
}

/* Subroutine of lookup_label, declare_label, define_label: construct a
   LABEL_DECL with all the proper frills.  Also create a struct
   c_label_vars initialized for the current scope.  */

static tree
make_label (location_t location, tree name, bool defining,
	    struct c_label_vars **p_label_vars)
{
  tree label = build_decl (location, LABEL_DECL, name, void_type_node);
  DECL_CONTEXT (label) = current_function_decl;
  SET_DECL_MODE (label, VOIDmode);

  c_label_vars *label_vars = ggc_alloc<c_label_vars> ();
  label_vars->shadowed = NULL;
  set_spot_bindings (&label_vars->label_bindings, defining);
  label_vars->decls_in_scope = make_tree_vector ();
  label_vars->gotos = NULL;
  *p_label_vars = label_vars;

  return label;
}

/* Get the LABEL_DECL corresponding to identifier NAME as a label.
   Create one if none exists so far for the current function.
   This is called when a label is used in a goto expression or
   has its address taken.  */

tree
lookup_label (tree name)
{
  tree label;
  struct c_label_vars *label_vars;

  if (current_function_scope == 0)
    {
      error ("label %qE referenced outside of any function", name);
      return NULL_TREE;
    }

  /* Use a label already defined or ref'd with this name, but not if
     it is inherited from a containing function and wasn't declared
     using __label__.  */
  label = I_LABEL_DECL (name);
  if (label && (DECL_CONTEXT (label) == current_function_decl
		|| C_DECLARED_LABEL_FLAG (label)))
    {
      /* If the label has only been declared, update its apparent
	 location to point here, for better diagnostics if it
	 turns out not to have been defined.  */
      if (DECL_INITIAL (label) == NULL_TREE)
	DECL_SOURCE_LOCATION (label) = input_location;
      return label;
    }

  /* No label binding for that identifier; make one.  */
  label = make_label (input_location, name, false, &label_vars);

  /* Ordinary labels go in the current function scope.  */
  bind_label (name, label, current_function_scope, label_vars);

  return label;
}

/* Issue a warning about DECL for a goto statement at GOTO_LOC going
   to LABEL.  */

static void
warn_about_goto (location_t goto_loc, tree label, tree decl)
{
  if (variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
    error_at (goto_loc,
	      "jump into scope of identifier with variably modified type");
  else
    warning_at (goto_loc, OPT_Wjump_misses_init,
		"jump skips variable initialization");
  inform (DECL_SOURCE_LOCATION (label), "label %qD defined here", label);
  inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
}

/* Look up a label because of a goto statement.  This is like
   lookup_label, but also issues any appropriate warnings.  */

tree
lookup_label_for_goto (location_t loc, tree name)
{
  tree label;
  struct c_label_vars *label_vars;
  unsigned int ix;
  tree decl;

  label = lookup_label (name);
  if (label == NULL_TREE)
    return NULL_TREE;

  /* If we are jumping to a different function, we can't issue any
     useful warnings.  */
  if (DECL_CONTEXT (label) != current_function_decl)
    {
      gcc_assert (C_DECLARED_LABEL_FLAG (label));
      return label;
    }

  label_vars = I_LABEL_BINDING (name)->u.label;

  /* If the label has not yet been defined, then push this goto on a
     list for possible later warnings.  */
  if (label_vars->label_bindings.scope == NULL)
    {
      c_goto_bindings *g = ggc_alloc<c_goto_bindings> ();

      g->loc = loc;
      set_spot_bindings (&g->goto_bindings, true);
      vec_safe_push (label_vars->gotos, g);
      return label;
    }

  /* If there are any decls in label_vars->decls_in_scope, then this
     goto has missed the declaration of the decl.  This happens for a
     case like
       int i = 1;
      lab:
       ...
       goto lab;
     Issue a warning or error.  */
  FOR_EACH_VEC_SAFE_ELT (label_vars->decls_in_scope, ix, decl)
    warn_about_goto (loc, label, decl);

  if (label_vars->label_bindings.left_stmt_expr)
    {
      error_at (loc, "jump into statement expression");
      inform (DECL_SOURCE_LOCATION (label), "label %qD defined here", label);
    }

  return label;
}

/* Make a label named NAME in the current function, shadowing silently
   any that may be inherited from containing functions or containing
   scopes.  This is called for __label__ declarations.  */

tree
declare_label (tree name)
{
  struct c_binding *b = I_LABEL_BINDING (name);
  tree label;
  struct c_label_vars *label_vars;

  /* Check to make sure that the label hasn't already been declared
     at this scope */
  if (b && B_IN_CURRENT_SCOPE (b))
    {
      auto_diagnostic_group d;
      error ("duplicate label declaration %qE", name);
      locate_old_decl (b->decl);

      /* Just use the previous declaration.  */
      return b->decl;
    }

  label = make_label (input_location, name, false, &label_vars);
  C_DECLARED_LABEL_FLAG (label) = 1;

  /* Declared labels go in the current scope.  */
  bind_label (name, label, current_scope, label_vars);

  return label;
}

/* When we define a label, issue any appropriate warnings if there are
   any gotos earlier in the function which jump to this label.  */

static void
check_earlier_gotos (tree label, struct c_label_vars* label_vars)
{
  unsigned int ix;
  struct c_goto_bindings *g;

  FOR_EACH_VEC_SAFE_ELT (label_vars->gotos, ix, g)
    {
      struct c_binding *b;
      struct c_scope *scope;

      /* We have a goto to this label.  The goto is going forward.  In
	 g->scope, the goto is going to skip any binding which was
	 defined after g->bindings_in_scope.  */
      if (g->goto_bindings.scope->has_jump_unsafe_decl)
	{
	  for (b = g->goto_bindings.scope->bindings;
	       b != g->goto_bindings.bindings_in_scope;
	       b = b->prev)
	    {
	      if (decl_jump_unsafe (b->decl))
		warn_about_goto (g->loc, label, b->decl);
	    }
	}

      /* We also need to warn about decls defined in any scopes
	 between the scope of the label and the scope of the goto.  */
      for (scope = label_vars->label_bindings.scope;
	   scope != g->goto_bindings.scope;
	   scope = scope->outer)
	{
	  gcc_assert (scope != NULL);
	  if (scope->has_jump_unsafe_decl)
	    {
	      if (scope == label_vars->label_bindings.scope)
		b = label_vars->label_bindings.bindings_in_scope;
	      else
		b = scope->bindings;
	      for (; b != NULL; b = b->prev)
		{
		  if (decl_jump_unsafe (b->decl))
		    warn_about_goto (g->loc, label, b->decl);
		}
	    }
	}

      if (g->goto_bindings.stmt_exprs > 0)
	{
	  error_at (g->loc, "jump into statement expression");
	  inform (DECL_SOURCE_LOCATION (label), "label %qD defined here",
		  label);
	}
    }

  /* Now that the label is defined, we will issue warnings about
     subsequent gotos to this label when we see them.  */
  vec_safe_truncate (label_vars->gotos, 0);
  label_vars->gotos = NULL;
}

/* Define a label, specifying the location in the source file.
   Return the LABEL_DECL node for the label, if the definition is valid.
   Otherwise return NULL_TREE.  */

tree
define_label (location_t location, tree name)
{
  /* Find any preexisting label with this name.  It is an error
     if that label has already been defined in this function, or
     if there is a containing function with a declared label with
     the same name.  */
  tree label = I_LABEL_DECL (name);

  if (label
      && ((DECL_CONTEXT (label) == current_function_decl
	   && DECL_INITIAL (label) != NULL_TREE)
	  || (DECL_CONTEXT (label) != current_function_decl
	      && C_DECLARED_LABEL_FLAG (label))))
    {
      auto_diagnostic_group d;
      error_at (location, "duplicate label %qD", label);
      locate_old_decl (label);
      return NULL_TREE;
    }
  else if (label && DECL_CONTEXT (label) == current_function_decl)
    {
      struct c_label_vars *label_vars = I_LABEL_BINDING (name)->u.label;

      /* The label has been used or declared already in this function,
	 but not defined.  Update its location to point to this
	 definition.  */
      DECL_SOURCE_LOCATION (label) = location;
      set_spot_bindings (&label_vars->label_bindings, true);

      /* Issue warnings as required about any goto statements from
	 earlier in the function.  */
      check_earlier_gotos (label, label_vars);
    }
  else
    {
      struct c_label_vars *label_vars;

      /* No label binding for that identifier; make one.  */
      label = make_label (location, name, true, &label_vars);

      /* Ordinary labels go in the current function scope.  */
      bind_label (name, label, current_function_scope, label_vars);
    }

  if (!in_system_header_at (input_location) && lookup_name (name))
    warning_at (location, OPT_Wtraditional,
		"traditional C lacks a separate namespace "
		"for labels, identifier %qE conflicts", name);

  /* Mark label as having been defined.  */
  DECL_INITIAL (label) = error_mark_node;
  return label;
}

/* Get the bindings for a new switch statement.  This is used to issue
   warnings as appropriate for jumps from the switch to case or
   default labels.  */

struct c_spot_bindings *
c_get_switch_bindings (void)
{
  struct c_spot_bindings *switch_bindings;

  switch_bindings = XNEW (struct c_spot_bindings);
  set_spot_bindings (switch_bindings, true);
  return switch_bindings;
}

void
c_release_switch_bindings (struct c_spot_bindings *bindings)
{
  gcc_assert (bindings->stmt_exprs == 0 && !bindings->left_stmt_expr);
  XDELETE (bindings);
}

/* This is called at the point of a case or default label to issue
   warnings about decls as needed.  It returns true if it found an
   error, not just a warning.  */

bool
c_check_switch_jump_warnings (struct c_spot_bindings *switch_bindings,
			      location_t switch_loc, location_t case_loc)
{
  bool saw_error;
  struct c_scope *scope;

  saw_error = false;
  for (scope = current_scope;
       scope != switch_bindings->scope;
       scope = scope->outer)
    {
      struct c_binding *b;

      gcc_assert (scope != NULL);

      if (!scope->has_jump_unsafe_decl)
	continue;

      for (b = scope->bindings; b != NULL; b = b->prev)
	{
	  if (decl_jump_unsafe (b->decl))
	    {
	      if (variably_modified_type_p (TREE_TYPE (b->decl), NULL_TREE))
		{
		  saw_error = true;
		  error_at (case_loc,
			    ("switch jumps into scope of identifier with "
			     "variably modified type"));
		}
	      else
		warning_at (case_loc, OPT_Wjump_misses_init,
			    "switch jumps over variable initialization");
	      inform (switch_loc, "switch starts here");
	      inform (DECL_SOURCE_LOCATION (b->decl), "%qD declared here",
		      b->decl);
	    }
	}
    }

  if (switch_bindings->stmt_exprs > 0)
    {
      saw_error = true;
      error_at (case_loc, "switch jumps into statement expression");
      inform (switch_loc, "switch starts here");
    }

  return saw_error;
}

/* Given NAME, an IDENTIFIER_NODE,
   return the structure (or union or enum) definition for that name.
   If THISLEVEL_ONLY is nonzero, searches only the current_scope.
   CODE says which kind of type the caller wants;
   it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE.
   If PLOC is not NULL and this returns non-null, it sets *PLOC to the
   location where the tag was defined.
   If the wrong kind of type is found, an error is reported.  */

static tree
lookup_tag (enum tree_code code, tree name, bool thislevel_only,
	    location_t *ploc)
{
  struct c_binding *b = I_TAG_BINDING (name);
  bool thislevel = false;

  if (!b || !b->decl)
    return NULL_TREE;

  /* We only care about whether it's in this level if
     thislevel_only was set or it might be a type clash.  */
  if (thislevel_only || TREE_CODE (b->decl) != code)
    {
      /* For our purposes, a tag in the external scope is the same as
	 a tag in the file scope.  (Primarily relevant to Objective-C
	 and its builtin structure tags, which get pushed before the
	 file scope is created.)  */
      if (B_IN_CURRENT_SCOPE (b)
	  || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b)))
	thislevel = true;
    }

  if (thislevel_only && !thislevel)
    return NULL_TREE;

  if (TREE_CODE (b->decl) != code)
    {
      /* Definition isn't the kind we were looking for.  */
      pending_invalid_xref = name;
      pending_invalid_xref_location = input_location;

      /* If in the same binding level as a declaration as a tag
	 of a different type, this must not be allowed to
	 shadow that tag, so give the error immediately.
	 (For example, "struct foo; union foo;" is invalid.)  */
      if (thislevel)
	pending_xref_error ();
    }

  if (ploc != NULL)
    *ploc = b->locus;

  return b->decl;
}

/* Return true if a definition exists for NAME with code CODE.  */

bool
tag_exists_p (enum tree_code code, tree name)
{
  struct c_binding *b = I_TAG_BINDING (name);

  if (b == NULL || b->decl == NULL_TREE)
    return false;
  return TREE_CODE (b->decl) == code;
}

/* Print an error message now
   for a recent invalid struct, union or enum cross reference.
   We don't print them immediately because they are not invalid
   when used in the `struct foo;' construct for shadowing.  */

void
pending_xref_error (void)
{
  if (pending_invalid_xref != NULL_TREE)
    error_at (pending_invalid_xref_location, "%qE defined as wrong kind of tag",
	      pending_invalid_xref);
  pending_invalid_xref = NULL_TREE;
}


/* Look up NAME in the current scope and its superiors
   in the namespace of variables, functions and typedefs.
   Return a ..._DECL node of some kind representing its definition,
   or return NULL_TREE if it is undefined.  */

tree
lookup_name (tree name)
{
  struct c_binding *b = I_SYMBOL_BINDING (name);
  if (b && !b->invisible)
    {
      maybe_record_typedef_use (b->decl);
      return b->decl;
    }
  return NULL_TREE;
}

/* Similar to `lookup_name' but look only at the indicated scope.  */

static tree
lookup_name_in_scope (tree name, struct c_scope *scope)
{
  struct c_binding *b;

  for (b = I_SYMBOL_BINDING (name); b; b = b->shadowed)
    if (B_IN_SCOPE (b, scope))
      return b->decl;
  return NULL_TREE;
}

/* Look for the closest match for NAME within the currently valid
   scopes.

   This finds the identifier with the lowest Levenshtein distance to
   NAME.  If there are multiple candidates with equal minimal distance,
   the first one found is returned.  Scopes are searched from innermost
   outwards, and within a scope in reverse order of declaration, thus
   benefiting candidates "near" to the current scope.

   The function also looks for similar macro names to NAME, since a
   misspelled macro name will not be expanded, and hence looks like an
   identifier to the C frontend.

   It also looks for start_typename keywords, to detect "singed" vs "signed"
   typos.

   Use LOC for any deferred diagnostics.  */

name_hint
lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind, location_t loc)
{
  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);

  /* First, try some well-known names in the C standard library, in case
     the user forgot a #include.  */
  const char *header_hint
    = get_c_stdlib_header_for_name (IDENTIFIER_POINTER (name));

  if (header_hint)
    return name_hint (NULL,
		      new suggest_missing_header (loc,
						  IDENTIFIER_POINTER (name),
						  header_hint));

  /* Only suggest names reserved for the implementation if NAME begins
     with an underscore.  */
  bool consider_implementation_names = (IDENTIFIER_POINTER (name)[0] == '_');

  best_match<tree, tree> bm (name);

  /* Look within currently valid scopes.  */
  for (c_scope *scope = current_scope; scope; scope = scope->outer)
    for (c_binding *binding = scope->bindings; binding; binding = binding->prev)
      {
	if (!binding->id || binding->invisible)
	  continue;
	if (binding->decl == error_mark_node)
	  continue;
	/* Don't use bindings from implicitly declared functions,
	   as they were likely misspellings themselves.  */
	if (TREE_CODE (binding->decl) == FUNCTION_DECL)
	  if (C_DECL_IMPLICIT (binding->decl))
	    continue;
	/* Don't suggest names that are reserved for use by the
	   implementation, unless NAME began with an underscore.  */
	if (!consider_implementation_names)
	  {
	    const char *suggestion_str = IDENTIFIER_POINTER (binding->id);
	    if (name_reserved_for_implementation_p (suggestion_str))
	      continue;
	  }
	switch (kind)
	  {
	  case FUZZY_LOOKUP_TYPENAME:
	    if (TREE_CODE (binding->decl) != TYPE_DECL)
	      continue;
	    break;

	  case FUZZY_LOOKUP_FUNCTION_NAME:
	    if (TREE_CODE (binding->decl) != FUNCTION_DECL)
	      {
		/* Allow function pointers.  */
		if ((VAR_P (binding->decl)
		     || TREE_CODE (binding->decl) == PARM_DECL)
		    && TREE_CODE (TREE_TYPE (binding->decl)) == POINTER_TYPE
		    && (TREE_CODE (TREE_TYPE (TREE_TYPE (binding->decl)))
			== FUNCTION_TYPE))
		  break;
		continue;
	      }
	    break;

	  default:
	    break;
	  }
	bm.consider (binding->id);
      }

  /* Consider macros: if the user misspelled a macro name e.g. "SOME_MACRO"
     as:
       x = SOME_OTHER_MACRO (y);
     then "SOME_OTHER_MACRO" will survive to the frontend and show up
     as a misspelled identifier.

     Use the best distance so far so that a candidate is only set if
     a macro is better than anything so far.  This allows early rejection
     (without calculating the edit distance) of macro names that must have
     distance >= bm.get_best_distance (), and means that we only get a
     non-NULL result for best_macro_match if it's better than any of
     the identifiers already checked, which avoids needless creation
     of identifiers for macro hashnodes.  */
  best_macro_match bmm (name, bm.get_best_distance (), parse_in);
  cpp_hashnode *best_macro = bmm.get_best_meaningful_candidate ();
  /* If a macro is the closest so far to NAME, use it, creating an
     identifier tree node for it.  */
  if (best_macro)
    {
      const char *id = (const char *)best_macro->ident.str;
      tree macro_as_identifier
	= get_identifier_with_length (id, best_macro->ident.len);
      bm.set_best_so_far (macro_as_identifier,
			  bmm.get_best_distance (),
			  bmm.get_best_candidate_length ());
    }

  /* Try the "start_typename" keywords to detect
     "singed" vs "signed" typos.  */
  if (kind == FUZZY_LOOKUP_TYPENAME)
    {
      for (unsigned i = 0; i < num_c_common_reswords; i++)
	{
	  const c_common_resword *resword = &c_common_reswords[i];
	  if (!c_keyword_starts_typename (resword->rid))
	    continue;
	  tree resword_identifier = ridpointers [resword->rid];
	  if (!resword_identifier)
	    continue;
	  gcc_assert (TREE_CODE (resword_identifier) == IDENTIFIER_NODE);
	  bm.consider (resword_identifier);
	}
    }

  tree best = bm.get_best_meaningful_candidate ();
  if (best)
    return name_hint (IDENTIFIER_POINTER (best), NULL);
  else
    return name_hint (NULL, NULL);
}


/* Handle the standard [[nodiscard]] attribute.  */

static tree
handle_nodiscard_attribute (tree *node, tree name, tree /*args*/,
			    int /*flags*/, bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL)
    {
      if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
	warning_at (DECL_SOURCE_LOCATION (*node),
		    OPT_Wattributes, "%qE attribute applied to %qD with void "
		    "return type", name, *node);
    }
  else if (RECORD_OR_UNION_TYPE_P (*node)
	   || TREE_CODE (*node) == ENUMERAL_TYPE)
    /* OK */;
  else
    {
      pedwarn (input_location,
	       OPT_Wattributes, "%qE attribute can only be applied to "
	       "functions or to structure, union or enumeration types", name);
      *no_add_attrs = true;
    }
  return NULL_TREE;
}
/* Table of supported standard (C2x) attributes.  */
const struct attribute_spec std_attribute_table[] =
{
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
       affects_type_identity, handler, exclude } */
  { "deprecated", 0, 1, false, false, false, false,
    handle_deprecated_attribute, NULL },
  { "fallthrough", 0, 0, false, false, false, false,
    handle_fallthrough_attribute, NULL },
  { "maybe_unused", 0, 0, false, false, false, false,
    handle_unused_attribute, NULL },
  { "nodiscard", 0, 1, false, false, false, false,
    handle_nodiscard_attribute, NULL },
  { NULL, 0, 0, false, false, false, false, NULL, NULL }
};

/* Create the predefined scalar types of C,
   and some nodes representing standard constants (0, 1, (void *) 0).
   Initialize the global scope.
   Make definitions for built-in primitive functions.  */

void
c_init_decl_processing (void)
{
  location_t save_loc = input_location;

  /* Initialize reserved words for parser.  */
  c_parse_init ();

  register_scoped_attributes (std_attribute_table, NULL);

  current_function_decl = NULL_TREE;

  gcc_obstack_init (&parser_obstack);

  /* Make the externals scope.  */
  push_scope ();
  external_scope = current_scope;

  /* Declarations from c_common_nodes_and_builtins must not be associated
     with this input file, lest we get differences between using and not
     using preprocessed headers.  */
  input_location = BUILTINS_LOCATION;

  c_common_nodes_and_builtins ();

  /* In C, comparisons and TRUTH_* expressions have type int.  */
  truthvalue_type_node = integer_type_node;
  truthvalue_true_node = integer_one_node;
  truthvalue_false_node = integer_zero_node;

  /* Even in C99, which has a real boolean type.  */
  pushdecl (build_decl (UNKNOWN_LOCATION, TYPE_DECL, get_identifier ("_Bool"),
			boolean_type_node));

  input_location = save_loc;

  make_fname_decl = c_make_fname_decl;
  start_fname_decls ();
}

/* Create the VAR_DECL at LOC for __FUNCTION__ etc. ID is the name to
   give the decl, NAME is the initialization string and TYPE_DEP
   indicates whether NAME depended on the type of the function.  As we
   don't yet implement delayed emission of static data, we mark the
   decl as emitted so it is not placed in the output.  Anything using
   it must therefore pull out the STRING_CST initializer directly.
   FIXME.  */

static tree
c_make_fname_decl (location_t loc, tree id, int type_dep)
{
  const char *name = fname_as_string (type_dep);
  tree decl, type, init;
  size_t length = strlen (name);

  type = build_array_type (char_type_node,
			   build_index_type (size_int (length)));
  type = c_build_qualified_type (type, TYPE_QUAL_CONST);

  decl = build_decl (loc, VAR_DECL, id, type);

  TREE_STATIC (decl) = 1;
  TREE_READONLY (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;

  init = build_string (length + 1, name);
  free (CONST_CAST (char *, name));
  TREE_TYPE (init) = type;
  DECL_INITIAL (decl) = init;

  TREE_USED (decl) = 1;

  if (current_function_decl
      /* For invalid programs like this:

         void foo()
         const char* p = __FUNCTION__;

	 the __FUNCTION__ is believed to appear in K&R style function
	 parameter declarator.  In that case we still don't have
	 function_scope.  */
      && current_function_scope)
    {
      DECL_CONTEXT (decl) = current_function_decl;
      bind (id, decl, current_function_scope,
	    /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION);
    }

  finish_decl (decl, loc, init, NULL_TREE, NULL_TREE);

  return decl;
}

tree
c_builtin_function (tree decl)
{
  tree type = TREE_TYPE (decl);
  tree   id = DECL_NAME (decl);

  const char *name = IDENTIFIER_POINTER (id);
  C_DECL_BUILTIN_PROTOTYPE (decl) = prototype_p (type);

  /* Should never be called on a symbol with a preexisting meaning.  */
  gcc_assert (!I_SYMBOL_BINDING (id));

  bind (id, decl, external_scope, /*invisible=*/true, /*nested=*/false,
	UNKNOWN_LOCATION);

  /* Builtins in the implementation namespace are made visible without
     needing to be explicitly declared.  See push_file_scope.  */
  if (name[0] == '_' && (name[1] == '_' || ISUPPER (name[1])))
    {
      DECL_CHAIN (decl) = visible_builtins;
      visible_builtins = decl;
    }

  return decl;
}

tree
c_builtin_function_ext_scope (tree decl)
{
  tree type = TREE_TYPE (decl);
  tree   id = DECL_NAME (decl);

  const char *name = IDENTIFIER_POINTER (id);
  C_DECL_BUILTIN_PROTOTYPE (decl) = prototype_p (type);

  if (external_scope)
    bind (id, decl, external_scope, /*invisible=*/false, /*nested=*/false,
	  UNKNOWN_LOCATION);

  /* Builtins in the implementation namespace are made visible without
     needing to be explicitly declared.  See push_file_scope.  */
  if (name[0] == '_' && (name[1] == '_' || ISUPPER (name[1])))
    {
      DECL_CHAIN (decl) = visible_builtins;
      visible_builtins = decl;
    }

  return decl;
}

/* Implement LANG_HOOKS_SIMULATE_BUILTIN_FUNCTION_DECL.  */

tree
c_simulate_builtin_function_decl (tree decl)
{
  tree type = TREE_TYPE (decl);
  C_DECL_BUILTIN_PROTOTYPE (decl) = prototype_p (type);
  return pushdecl (decl);
}

/* Warn about attributes in a context where they are unused
   (attribute-declarations, except for the "fallthrough" case, and
   attributes on statements).  */

void
c_warn_unused_attributes (tree attrs)
{
  for (tree t = attrs; t != NULL_TREE; t = TREE_CHAIN (t))
    if (get_attribute_namespace (t) == NULL_TREE)
      /* The specifications of standard attributes mean this is a
	 constraint violation.  */
      pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
	       get_attribute_name (t));
    else
      warning (OPT_Wattributes, "%qE attribute ignored",
	       get_attribute_name (t));
}

/* Warn for standard attributes being applied to a type that is not
   being defined, where that is a constraint violation, and return a
   list of attributes with them removed.  */

tree
c_warn_type_attributes (tree attrs)
{
  tree *attr_ptr = &attrs;
  while (*attr_ptr)
    if (get_attribute_namespace (*attr_ptr) == NULL_TREE)
      {
	pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
		 get_attribute_name (*attr_ptr));
	*attr_ptr = TREE_CHAIN (*attr_ptr);
      }
    else
      attr_ptr = &TREE_CHAIN (*attr_ptr);
  return attrs;
}

/* Called when a declaration is seen that contains no names to declare.
   If its type is a reference to a structure, union or enum inherited
   from a containing scope, shadow that tag name for the current scope
   with a forward reference.
   If its type defines a new named structure or union
   or defines an enum, it is valid but we need not do anything here.
   Otherwise, it is an error.  */

void
shadow_tag (const struct c_declspecs *declspecs)
{
  shadow_tag_warned (declspecs, 0);
}

/* WARNED is 1 if we have done a pedwarn, 2 if we have done a warning,
   but no pedwarn.  */
void
shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
{
  bool found_tag = false;

  if (declspecs->type && !declspecs->default_int_p && !declspecs->typedef_p)
    {
      tree value = declspecs->type;
      enum tree_code code = TREE_CODE (value);

      if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
	/* Used to test also that TYPE_SIZE (value) != 0.
	   That caused warning for `struct foo;' at top level in the file.  */
	{
	  tree name = TYPE_NAME (value);
	  tree t;

	  found_tag = true;

	  if (declspecs->restrict_p)
	    {
	      error ("invalid use of %<restrict%>");
	      warned = 1;
	    }

	  if (name == NULL_TREE)
	    {
	      if (warned != 1 && code != ENUMERAL_TYPE)
		/* Empty unnamed enum OK */
		{
		  pedwarn (input_location, 0,
			   "unnamed struct/union that defines no instances");
		  warned = 1;
		}
	    }
	  else if (declspecs->typespec_kind != ctsk_tagdef
                   && declspecs->typespec_kind != ctsk_tagfirstref
		   && declspecs->typespec_kind != ctsk_tagfirstref_attrs
		   && declspecs->storage_class != csc_none)
	    {
	      if (warned != 1)
		pedwarn (input_location, 0,
			 "empty declaration with storage class specifier "
			 "does not redeclare tag");
	      warned = 1;
	      pending_xref_error ();
	    }
	  else if (declspecs->typespec_kind != ctsk_tagdef
                   && declspecs->typespec_kind != ctsk_tagfirstref
                   && declspecs->typespec_kind != ctsk_tagfirstref_attrs
		   && (declspecs->const_p
		       || declspecs->volatile_p
		       || declspecs->atomic_p
		       || declspecs->restrict_p
		       || declspecs->address_space))
	    {
	      if (warned != 1)
		pedwarn (input_location, 0,
			 "empty declaration with type qualifier "
			  "does not redeclare tag");
	      warned = 1;
	      pending_xref_error ();
	    }
	  else if (declspecs->typespec_kind != ctsk_tagdef
                   && declspecs->typespec_kind != ctsk_tagfirstref
                   && declspecs->typespec_kind != ctsk_tagfirstref_attrs
		   && declspecs->alignas_p)
	    {
	      if (warned != 1)
		pedwarn (input_location, 0,
			 "empty declaration with %<_Alignas%> "
			  "does not redeclare tag");
	      warned = 1;
	      pending_xref_error ();
	    }
	  else
	    {
	      pending_invalid_xref = NULL_TREE;
	      t = lookup_tag (code, name, true, NULL);

	      if (t == NULL_TREE)
		{
		  t = make_node (code);
		  pushtag (input_location, name, t);
		}
	    }
	}
      else
	{
	  if (warned != 1 && !in_system_header_at (input_location))
	    {
	      pedwarn (input_location, 0,
		       "useless type name in empty declaration");
	      warned = 1;
	    }
	}
    }
  else if (warned != 1 && !in_system_header_at (input_location)
	   && declspecs->typedef_p)
    {
      pedwarn (input_location, 0, "useless type name in empty declaration");
      warned = 1;
    }

  pending_invalid_xref = NULL_TREE;

  if (declspecs->inline_p)
    {
      error ("%<inline%> in empty declaration");
      warned = 1;
    }

  if (declspecs->noreturn_p)
    {
      error ("%<_Noreturn%> in empty declaration");
      warned = 1;
    }

  if (current_scope == file_scope && declspecs->storage_class == csc_auto)
    {
      error ("%<auto%> in file-scope empty declaration");
      warned = 1;
    }

  if (current_scope == file_scope && declspecs->storage_class == csc_register)
    {
      error ("%<register%> in file-scope empty declaration");
      warned = 1;
    }

  if (!warned && !in_system_header_at (input_location)
      && declspecs->storage_class != csc_none)
    {
      warning (0, "useless storage class specifier in empty declaration");
      warned = 2;
    }

  if (!warned && !in_system_header_at (input_location) && declspecs->thread_p)
    {
      warning (0, "useless %qs in empty declaration",
	       declspecs->thread_gnu_p ? "__thread" : "_Thread_local");
      warned = 2;
    }

  if (!warned
      && !in_system_header_at (input_location)
      && (declspecs->const_p
	  || declspecs->volatile_p
	  || declspecs->atomic_p
	  || declspecs->restrict_p
	  || declspecs->address_space))
    {
      warning (0, "useless type qualifier in empty declaration");
      warned = 2;
    }

  if (!warned && !in_system_header_at (input_location)
      && declspecs->alignas_p)
    {
      warning (0, "useless %<_Alignas%> in empty declaration");
      warned = 2;
    }

  if (found_tag
      && warned == 2
      && (declspecs->typespec_kind == ctsk_tagref_attrs
	  || declspecs->typespec_kind == ctsk_tagfirstref_attrs))
    {
      /* Standard attributes after the "struct" or "union" keyword are
	 only permitted when the contents of the type are defined, or
	 in the form "struct-or-union attribute-specifier-sequence
	 identifier;".  If the ';' was not present, attributes were
	 diagnosed in the parser.  Here, ensure that any other useless
	 elements of the declaration result in a pedwarn, not just a
	 warning.  Forward declarations of enum types are not part of
	 standard C, but handle them the same.  */
      pedwarn (input_location, 0,
	       "invalid use of attributes in empty declaration");
      warned = 1;
    }

  if (warned != 1)
    {
      if (declspecs->declspecs_seen_p
	  && !declspecs->non_std_attrs_seen_p)
	/* An attribute declaration (but not a fallthrough attribute
	   declaration, which was handled separately); warn if there
	   are any attributes being ignored (but not if the attributes
	   were empty).  */
	c_warn_unused_attributes (declspecs->attrs);
      else if (!found_tag)
	pedwarn (input_location, 0, "empty declaration");
    }
}


/* Return the qualifiers from SPECS as a bitwise OR of TYPE_QUAL_*
   bits.  SPECS represents declaration specifiers that the grammar
   only permits to contain type qualifiers and attributes.  */

int
quals_from_declspecs (const struct c_declspecs *specs)
{
  int quals = ((specs->const_p ? TYPE_QUAL_CONST : 0)
	       | (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0)
	       | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0)
	       | (specs->atomic_p ? TYPE_QUAL_ATOMIC : 0)
	       | (ENCODE_QUAL_ADDR_SPACE (specs->address_space)));
  gcc_assert (!specs->type
	      && !specs->decl_attr
	      && specs->typespec_word == cts_none
	      && specs->storage_class == csc_none
	      && !specs->typedef_p
	      && !specs->explicit_signed_p
	      && !specs->deprecated_p
	      && !specs->unavailable_p
	      && !specs->long_p
	      && !specs->long_long_p
	      && !specs->short_p
	      && !specs->signed_p
	      && !specs->unsigned_p
	      && !specs->complex_p
	      && !specs->inline_p
	      && !specs->noreturn_p
	      && !specs->thread_p);
  return quals;
}

/* Construct an array declarator.  LOC is the location of the
   beginning of the array (usually the opening brace).  EXPR is the
   expression inside [], or NULL_TREE.  QUALS are the type qualifiers
   inside the [] (to be applied to the pointer to which a parameter
   array is converted).  STATIC_P is true if "static" is inside the
   [], false otherwise.  VLA_UNSPEC_P is true if the array is [*], a
   VLA of unspecified length which is nevertheless a complete type,
   false otherwise.  The field for the contained declarator is left to
   be filled in by set_array_declarator_inner.  */

struct c_declarator *
build_array_declarator (location_t loc,
			tree expr, struct c_declspecs *quals, bool static_p,
			bool vla_unspec_p)
{
  struct c_declarator *declarator = XOBNEW (&parser_obstack,
					    struct c_declarator);
  declarator->id_loc = loc;
  declarator->kind = cdk_array;
  declarator->declarator = 0;
  declarator->u.array.dimen = expr;
  if (quals)
    {
      declarator->u.array.attrs = quals->attrs;
      declarator->u.array.quals = quals_from_declspecs (quals);
    }
  else
    {
      declarator->u.array.attrs = NULL_TREE;
      declarator->u.array.quals = 0;
    }
  declarator->u.array.static_p = static_p;
  declarator->u.array.vla_unspec_p = vla_unspec_p;
  if (static_p || quals != NULL)
    pedwarn_c90 (loc, OPT_Wpedantic,
		 "ISO C90 does not support %<static%> or type "
		 "qualifiers in parameter array declarators");
  if (vla_unspec_p)
    pedwarn_c90 (loc, OPT_Wpedantic,
		 "ISO C90 does not support %<[*]%> array declarators");
  if (vla_unspec_p)
    {
      if (!current_scope->parm_flag)
	{
	  /* C99 6.7.5.2p4 */
	  error_at (loc, "%<[*]%> not allowed in other than "
		    "function prototype scope");
	  declarator->u.array.vla_unspec_p = false;
	  return NULL;
	}
      current_scope->had_vla_unspec = true;
    }
  return declarator;
}

/* Set the contained declarator of an array declarator.  DECL is the
   declarator, as constructed by build_array_declarator; INNER is what
   appears on the left of the [].  */

struct c_declarator *
set_array_declarator_inner (struct c_declarator *decl,
			    struct c_declarator *inner)
{
  decl->declarator = inner;
  return decl;
}

/* INIT is a constructor that forms DECL's initializer.  If the final
   element initializes a flexible array field, add the size of that
   initializer to DECL's size.  */

static void
add_flexible_array_elts_to_size (tree decl, tree init)
{
  tree elt, type;

  if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
    return;

  elt = CONSTRUCTOR_ELTS (init)->last ().value;
  type = TREE_TYPE (elt);
  if (TREE_CODE (type) == ARRAY_TYPE
      && TYPE_SIZE (type) == NULL_TREE
      && TYPE_DOMAIN (type) != NULL_TREE
      && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE)
    {
      complete_array_type (&type, elt, false);
      DECL_SIZE (decl)
	= size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (type));
      DECL_SIZE_UNIT (decl)
	= size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl), TYPE_SIZE_UNIT (type));
    }
}

/* Decode a "typename", such as "int **", returning a ..._TYPE node.
   Set *EXPR, if EXPR not NULL, to any expression to be evaluated
   before the type name, and set *EXPR_CONST_OPERANDS, if
   EXPR_CONST_OPERANDS not NULL, to indicate whether the type name may
   appear in a constant expression.  */

tree
groktypename (struct c_type_name *type_name, tree *expr,
	      bool *expr_const_operands)
{
  tree type;
  tree attrs = type_name->specs->attrs;

  type_name->specs->attrs = NULL_TREE;

  type = grokdeclarator (type_name->declarator, type_name->specs, TYPENAME,
			 false, NULL, &attrs, expr, expr_const_operands,
			 DEPRECATED_NORMAL);

  /* Apply attributes.  */
  attrs = c_warn_type_attributes (attrs);
  decl_attributes (&type, attrs, 0);

  return type;
}

/* Looks up the most recent pushed declaration corresponding to DECL.  */

static tree
lookup_last_decl (tree decl)
{
  tree last_decl = lookup_name (DECL_NAME (decl));
  if (!last_decl)
    last_decl = lookup_name_in_scope (DECL_NAME (decl), external_scope);
  return last_decl;
}

/* Wrapper for decl_attributes that adds some implicit attributes
   to VAR_DECLs or FUNCTION_DECLs.  */

static tree
c_decl_attributes (tree *node, tree attributes, int flags)
{
  /* Add implicit "omp declare target" attribute if requested.  */
  if (current_omp_declare_target_attribute
      && ((VAR_P (*node) && is_global_var (*node))
	  || TREE_CODE (*node) == FUNCTION_DECL))
    {
      if (VAR_P (*node)
	  && !lang_hooks.types.omp_mappable_type (TREE_TYPE (*node)))
	attributes = tree_cons (get_identifier ("omp declare target implicit"),
				NULL_TREE, attributes);
      else
	{
	  attributes = tree_cons (get_identifier ("omp declare target"),
				  NULL_TREE, attributes);
	  attributes = tree_cons (get_identifier ("omp declare target block"),
				  NULL_TREE, attributes);
	}
    }

  /* Look up the current declaration with all the attributes merged
     so far so that attributes on the current declaration that's
     about to be pushed that conflict with the former can be detected,
     diagnosed, and rejected as appropriate.  */
  tree last_decl = lookup_last_decl (*node);
  return decl_attributes (node, attributes, flags, last_decl);
}


/* Decode a declarator in an ordinary declaration or data definition.
   This is called as soon as the type information and variable name
   have been parsed, before parsing the initializer if any.
   Here we create the ..._DECL node, fill in its type,
   and put it on the list of decls for the current context.
   When nonnull, set *LASTLOC to the location of the prior declaration
   of the same entity if one exists.
   The ..._DECL node is returned as the value.

   Exception: for arrays where the length is not specified,
   the type is left null, to be filled in by `finish_decl'.

   Function definitions do not come here; they go to start_function
   instead.  However, external and forward declarations of functions
   do go through here.  Structure field declarations are done by
   grokfield and not through here.  */

tree
start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
	    bool initialized, tree attributes, location_t *lastloc /* = NULL */)
{
  tree decl;
  tree tem;
  tree expr = NULL_TREE;
  enum deprecated_states deprecated_state = DEPRECATED_NORMAL;

  /* An object declared as __attribute__((unavailable)) suppresses
     warnings and errors from __attribute__((deprecated/unavailable))
     components.
     An object declared as __attribute__((deprecated)) suppresses
     warnings of uses of other deprecated items.  */
  if (lookup_attribute ("unavailable", attributes))
    deprecated_state = UNAVAILABLE_DEPRECATED_SUPPRESS;
  else if (lookup_attribute ("deprecated", attributes))
    deprecated_state = DEPRECATED_SUPPRESS;

  decl = grokdeclarator (declarator, declspecs,
			 NORMAL, initialized, NULL, &attributes, &expr, NULL,
			 deprecated_state);
  if (!decl || decl == error_mark_node)
    return NULL_TREE;

  if (tree lastdecl = lastloc ? lookup_last_decl (decl) : NULL_TREE)
    if (lastdecl != error_mark_node)
      *lastloc = DECL_SOURCE_LOCATION (lastdecl);

  if (expr)
    add_stmt (fold_convert (void_type_node, expr));

  if (TREE_CODE (decl) != FUNCTION_DECL && MAIN_NAME_P (DECL_NAME (decl))
      && TREE_PUBLIC (decl))
    warning (OPT_Wmain, "%q+D is usually a function", decl);

  if (initialized)
    /* Is it valid for this decl to have an initializer at all?
       If not, set INITIALIZED to zero, which will indirectly
       tell 'finish_decl' to ignore the initializer once it is parsed.  */
    switch (TREE_CODE (decl))
      {
      case TYPE_DECL:
	error ("typedef %qD is initialized (use %<__typeof__%> instead)", decl);
	initialized = false;
	break;

      case FUNCTION_DECL:
	error ("function %qD is initialized like a variable", decl);
	initialized = false;
	break;

      case PARM_DECL:
	/* DECL_INITIAL in a PARM_DECL is really DECL_ARG_TYPE.  */
	error ("parameter %qD is initialized", decl);
	initialized = false;
	break;

      default:
	/* Don't allow initializations for incomplete types except for
	   arrays which might be completed by the initialization.  */

	/* This can happen if the array size is an undefined macro.
	   We already gave a warning, so we don't need another one.  */
	if (TREE_TYPE (decl) == error_mark_node)
	  initialized = false;
	else if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
	  {
	    /* A complete type is ok if size is fixed.  */

	    if (!poly_int_tree_p (TYPE_SIZE (TREE_TYPE (decl)))
		|| C_DECL_VARIABLE_SIZE (decl))
	      {
		error ("variable-sized object may not be initialized");
		initialized = false;
	      }
	  }
	else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
	  {
	    error ("variable %qD has initializer but incomplete type", decl);
	    initialized = false;
	  }
	else if (C_DECL_VARIABLE_SIZE (decl))
	  {
	    /* Although C99 is unclear about whether incomplete arrays
	       of VLAs themselves count as VLAs, it does not make
	       sense to permit them to be initialized given that
	       ordinary VLAs may not be initialized.  */
	    error ("variable-sized object may not be initialized");
	    initialized = false;
	  }
      }

  if (initialized)
    {
      if (current_scope == file_scope)
	TREE_STATIC (decl) = 1;

      /* Tell 'pushdecl' this is an initialized decl
	 even though we don't yet have the initializer expression.
	 Also tell 'finish_decl' it may store the real initializer.  */
      DECL_INITIAL (decl) = error_mark_node;
    }

  /* If this is a function declaration, write a record describing it to the
     prototypes file (if requested).  */

  if (TREE_CODE (decl) == FUNCTION_DECL)
    gen_aux_info_record (decl, 0, 0, prototype_p (TREE_TYPE (decl)));

  /* ANSI specifies that a tentative definition which is not merged with
     a non-tentative definition behaves exactly like a definition with an
     initializer equal to zero.  (Section 3.7.2)

     -fno-common gives strict ANSI behavior, though this tends to break
     a large body of code that grew up without this rule.

     Thread-local variables are never common, since there's no entrenched
     body of code to break, and it allows more efficient variable references
     in the presence of dynamic linking.  */

  if (VAR_P (decl)
      && !initialized
      && TREE_PUBLIC (decl)
      && !DECL_THREAD_LOCAL_P (decl)
      && !flag_no_common)
    DECL_COMMON (decl) = 1;

  /* Set attributes here so if duplicate decl, will have proper attributes.  */
  c_decl_attributes (&decl, attributes, 0);

  /* Handle gnu_inline attribute.  */
  if (declspecs->inline_p
      && !flag_gnu89_inline
      && TREE_CODE (decl) == FUNCTION_DECL
      && (lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl))
	  || current_function_decl))
    {
      if (declspecs->storage_class == csc_auto && current_scope != file_scope)
	;
      else if (declspecs->storage_class != csc_static)
	DECL_EXTERNAL (decl) = !DECL_EXTERNAL (decl);
    }

  if (TREE_CODE (decl) == FUNCTION_DECL
      && targetm.calls.promote_prototypes (TREE_TYPE (decl)))
    {
      struct c_declarator *ce = declarator;

      if (ce->kind == cdk_pointer)
	ce = declarator->declarator;
      if (ce->kind == cdk_function)
	{
	  tree args = ce->u.arg_info->parms;
	  for (; args; args = DECL_CHAIN (args))
	    {
	      tree type = TREE_TYPE (args);
	      if (type && INTEGRAL_TYPE_P (type)
		  && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
		DECL_ARG_TYPE (args) = c_type_promotes_to (type);
	    }
	}
    }

  if (TREE_CODE (decl) == FUNCTION_DECL
      && DECL_DECLARED_INLINE_P (decl)
      && DECL_UNINLINABLE (decl)
      && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
    warning (OPT_Wattributes, "inline function %q+D given attribute %qs",
	     decl, "noinline");

  /* C99 6.7.4p3: An inline definition of a function with external
     linkage shall not contain a definition of a modifiable object
     with static storage duration...  */
  if (VAR_P (decl)
      && current_scope != file_scope
      && TREE_STATIC (decl)
      && !TREE_READONLY (decl)
      && DECL_DECLARED_INLINE_P (current_function_decl)
      && DECL_EXTERNAL (current_function_decl))
    record_inline_static (input_location, current_function_decl,
			  decl, csi_modifiable);

  if (c_dialect_objc ()
      && VAR_OR_FUNCTION_DECL_P (decl))
      objc_check_global_decl (decl);

  /* Add this decl to the current scope.
     TEM may equal DECL or it may be a previous decl of the same name.  */
  tem = pushdecl (decl);

  if (initialized && DECL_EXTERNAL (tem))
    {
      DECL_EXTERNAL (tem) = 0;
      TREE_STATIC (tem) = 1;
    }

  return tem;
}

/* Subroutine of finish_decl. TYPE is the type of an uninitialized object
   DECL or the non-array element type if DECL is an uninitialized array.
   If that type has a const member, diagnose this. */

static void
diagnose_uninitialized_cst_member (tree decl, tree type)
{
  tree field;
  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
    {
      tree field_type;
      if (TREE_CODE (field) != FIELD_DECL)
	continue;
      field_type = strip_array_types (TREE_TYPE (field));

      if (TYPE_QUALS (field_type) & TYPE_QUAL_CONST)
      	{
	  warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
	  	      "uninitialized const member in %qT is invalid in C++",
		      strip_array_types (TREE_TYPE (decl)));
	  inform (DECL_SOURCE_LOCATION (field), "%qD should be initialized", field);
	}

      if (RECORD_OR_UNION_TYPE_P (field_type))
	diagnose_uninitialized_cst_member (decl, field_type);
    }
}

/* Finish processing of a declaration;
   install its initial value.
   If ORIGTYPE is not NULL_TREE, it is the original type of INIT.
   If the length of an array type is not known before,
   it must be determined now, from the initial value, or it is an error.

   INIT_LOC is the location of the initial value.  */

void
finish_decl (tree decl, location_t init_loc, tree init,
	     tree origtype, tree asmspec_tree)
{
  tree type;
  bool was_incomplete = (DECL_SIZE (decl) == NULL_TREE);
  const char *asmspec = 0;

  /* If a name was specified, get the string.  */
  if (VAR_OR_FUNCTION_DECL_P (decl)
      && DECL_FILE_SCOPE_P (decl))
    asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
  if (asmspec_tree)
    asmspec = TREE_STRING_POINTER (asmspec_tree);

  if (VAR_P (decl)
      && TREE_STATIC (decl)
      && global_bindings_p ())
    /* So decl is a global variable. Record the types it uses
       so that we can decide later to emit debug info for them.  */
    record_types_used_by_current_var_decl (decl);

  /* If `start_decl' didn't like having an initialization, ignore it now.  */
  if (init != NULL_TREE && DECL_INITIAL (decl) == NULL_TREE)
    init = NULL_TREE;

  /* Don't crash if parm is initialized.  */
  if (TREE_CODE (decl) == PARM_DECL)
    init = NULL_TREE;

  if (init)
    store_init_value (init_loc, decl, init, origtype);

  if (c_dialect_objc () && (VAR_OR_FUNCTION_DECL_P (decl)
			    || TREE_CODE (decl) == FIELD_DECL))
    objc_check_decl (decl);

  type = TREE_TYPE (decl);

  /* Deduce size of array from initialization, if not already known.
     This is only needed for an initialization in the current scope;
     it must not be done for a file-scope initialization of a
     declaration with external linkage, redeclared in an inner scope
     with the outer declaration shadowed in an intermediate scope.  */
  if (TREE_CODE (type) == ARRAY_TYPE
      && TYPE_DOMAIN (type) == NULL_TREE
      && TREE_CODE (decl) != TYPE_DECL
      && !(TREE_PUBLIC (decl) && current_scope != file_scope))
    {
      bool do_default
	= (TREE_STATIC (decl)
	   /* Even if pedantic, an external linkage array
	      may have incomplete type at first.  */
	   ? pedantic && !TREE_PUBLIC (decl)
	   : !DECL_EXTERNAL (decl));
      int failure
	= complete_array_type (&TREE_TYPE (decl), DECL_INITIAL (decl),
			       do_default);

      /* Get the completed type made by complete_array_type.  */
      type = TREE_TYPE (decl);

      switch (failure)
	{
	case 1:
	  error ("initializer fails to determine size of %q+D", decl);
	  break;

	case 2:
	  if (do_default)
	    error ("array size missing in %q+D", decl);
	  break;

	case 3:
	  error ("zero or negative size array %q+D", decl);
	  break;

	case 0:
	  /* For global variables, update the copy of the type that
	     exists in the binding.  */
	  if (TREE_PUBLIC (decl))
	    {
	      struct c_binding *b_ext = I_SYMBOL_BINDING (DECL_NAME (decl));
	      while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext))
		b_ext = b_ext->shadowed;
	      if (b_ext && TREE_CODE (decl) == TREE_CODE (b_ext->decl))
		{
		  if (b_ext->u.type && comptypes (b_ext->u.type, type))
		    b_ext->u.type = composite_type (b_ext->u.type, type);
		  else
		    b_ext->u.type = type;
		}
	    }
	  break;

	default:
	  gcc_unreachable ();
	}

      if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node)
	TREE_TYPE (DECL_INITIAL (decl)) = type;

      relayout_decl (decl);
    }

  /* Look for braced array initializers for character arrays and
     recursively convert them into STRING_CSTs.  */
  if (tree init = DECL_INITIAL (decl))
    DECL_INITIAL (decl) = braced_lists_to_strings (type, init);

  if (VAR_P (decl))
    {
      if (init && TREE_CODE (init) == CONSTRUCTOR)
	add_flexible_array_elts_to_size (decl, init);

      complete_flexible_array_elts (DECL_INITIAL (decl));

      if (is_global_var (decl))
	{
	  type_context_kind context = (DECL_THREAD_LOCAL_P (decl)
				       ? TCTX_THREAD_STORAGE
				       : TCTX_STATIC_STORAGE);
	  if (!verify_type_context (input_location, context, TREE_TYPE (decl)))
	    TREE_TYPE (decl) = error_mark_node;
	}

      if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node
	  && COMPLETE_TYPE_P (TREE_TYPE (decl)))
	layout_decl (decl, 0);

      if (DECL_SIZE (decl) == NULL_TREE
	  /* Don't give an error if we already gave one earlier.  */
	  && TREE_TYPE (decl) != error_mark_node
	  && (TREE_STATIC (decl)
	      /* A static variable with an incomplete type
		 is an error if it is initialized.
		 Also if it is not file scope.
		 Otherwise, let it through, but if it is not `extern'
		 then it may cause an error message later.  */
	      ? (DECL_INITIAL (decl) != NULL_TREE
		 || !DECL_FILE_SCOPE_P (decl))
	      /* An automatic variable with an incomplete type
		 is an error.  */
	      : !DECL_EXTERNAL (decl)))
	 {
	   error ("storage size of %q+D isn%'t known", decl);
	   TREE_TYPE (decl) = error_mark_node;
	 }

      if ((RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
	  || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
	  && DECL_SIZE (decl) == NULL_TREE
	  && TREE_STATIC (decl))
	incomplete_record_decls.safe_push (decl);

      if (is_global_var (decl)
	  && DECL_SIZE (decl) != NULL_TREE
	  && TREE_TYPE (decl) != error_mark_node)
	{
	  if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
	    constant_expression_warning (DECL_SIZE (decl));
	  else
	    {
	      error ("storage size of %q+D isn%'t constant", decl);
	      TREE_TYPE (decl) = error_mark_node;
	    }
	}

      if (TREE_USED (type))
	{
	  TREE_USED (decl) = 1;
	  DECL_READ_P (decl) = 1;
	}
    }

  /* If this is a function and an assembler name is specified, reset DECL_RTL
     so we can give it its new name.  Also, update builtin_decl if it
     was a normal built-in.  */
  if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
    {
      if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
	set_builtin_user_assembler_name (decl, asmspec);
      set_user_assembler_name (decl, asmspec);
    }

  /* If #pragma weak was used, mark the decl weak now.  */
  maybe_apply_pragma_weak (decl);

  /* Output the assembler code and/or RTL code for variables and functions,
     unless the type is an undefined structure or union.
     If not, it will get done when the type is completed.  */

  if (VAR_OR_FUNCTION_DECL_P (decl))
    {
      /* Determine the ELF visibility.  */
      if (TREE_PUBLIC (decl))
	c_determine_visibility (decl);

      /* This is a no-op in c-lang.c or something real in objc-act.c.  */
      if (c_dialect_objc ())
	objc_check_decl (decl);

      if (asmspec)
	{
	  /* If this is not a static variable, issue a warning.
	     It doesn't make any sense to give an ASMSPEC for an
	     ordinary, non-register local variable.  Historically,
	     GCC has accepted -- but ignored -- the ASMSPEC in
	     this case.  */
	  if (!DECL_FILE_SCOPE_P (decl)
	      && VAR_P (decl)
	      && !C_DECL_REGISTER (decl)
	      && !TREE_STATIC (decl))
	    warning (0, "ignoring %<asm%> specifier for non-static local "
		     "variable %q+D", decl);
	  else
	    set_user_assembler_name (decl, asmspec);
	}

      if (DECL_FILE_SCOPE_P (decl))
	{
	  if (DECL_INITIAL (decl) == NULL_TREE
	      || DECL_INITIAL (decl) == error_mark_node)
	    /* Don't output anything
	       when a tentative file-scope definition is seen.
	       But at end of compilation, do output code for them.  */
	    DECL_DEFER_OUTPUT (decl) = 1;
	  if (asmspec && VAR_P (decl) && C_DECL_REGISTER (decl))
	    DECL_HARD_REGISTER (decl) = 1;
	  rest_of_decl_compilation (decl, true, 0);

	  if (TREE_CODE (decl) == FUNCTION_DECL)
	    {
	      tree parms = DECL_ARGUMENTS (decl);
	      const bool builtin = fndecl_built_in_p (decl);
	      if (tree access = build_attr_access_from_parms (parms, !builtin))
		decl_attributes (&decl, access, 0);
	    }
	}
      else
	{
	  /* In conjunction with an ASMSPEC, the `register'
	     keyword indicates that we should place the variable
	     in a particular register.  */
	  if (asmspec && C_DECL_REGISTER (decl))
	    {
	      DECL_HARD_REGISTER (decl) = 1;
	      /* This cannot be done for a structure with volatile
		 fields, on which DECL_REGISTER will have been
		 reset.  */
	      if (!DECL_REGISTER (decl))
		error ("cannot put object with volatile field into register");
	    }

	  if (TREE_CODE (decl) != FUNCTION_DECL)
	    {
	      /* If we're building a variable sized type, and we might be
		 reachable other than via the top of the current binding
		 level, then create a new BIND_EXPR so that we deallocate
		 the object at the right time.  */
	      /* Note that DECL_SIZE can be null due to errors.  */
	      if (DECL_SIZE (decl)
		  && !TREE_CONSTANT (DECL_SIZE (decl))
		  && STATEMENT_LIST_HAS_LABEL (cur_stmt_list))
		{
		  tree bind;
		  bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
		  TREE_SIDE_EFFECTS (bind) = 1;
		  add_stmt (bind);
		  BIND_EXPR_BODY (bind) = push_stmt_list ();
		}
	      add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl),
				    DECL_EXPR, decl));
	    }
	}


      if (!DECL_FILE_SCOPE_P (decl))
	{
	  /* Recompute the RTL of a local array now
	     if it used to be an incomplete type.  */
	  if (was_incomplete && !is_global_var (decl))
	    {
	      /* If we used it already as memory, it must stay in memory.  */
	      TREE_ADDRESSABLE (decl) = TREE_USED (decl);
	      /* If it's still incomplete now, no init will save it.  */
	      if (DECL_SIZE (decl) == NULL_TREE)
		DECL_INITIAL (decl) = NULL_TREE;
	    }
	}
    }

  if (TREE_CODE (decl) == TYPE_DECL)
    {
      if (!DECL_FILE_SCOPE_P (decl)
	  && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
	add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));

      rest_of_decl_compilation (decl, DECL_FILE_SCOPE_P (decl), 0);
    }

  /* Install a cleanup (aka destructor) if one was given.  */
  if (VAR_P (decl) && !TREE_STATIC (decl))
    {
      tree attr = lookup_attribute ("cleanup", DECL_ATTRIBUTES (decl));
      if (attr)
	{
	  tree cleanup_id = TREE_VALUE (TREE_VALUE (attr));
	  tree cleanup_decl = lookup_name (cleanup_id);
	  tree cleanup;
	  vec<tree, va_gc> *v;

	  /* Build "cleanup(&decl)" for the destructor.  */
	  cleanup = build_unary_op (input_location, ADDR_EXPR, decl, false);
	  vec_alloc (v, 1);
	  v->quick_push (cleanup);
	  cleanup = c_build_function_call_vec (DECL_SOURCE_LOCATION (decl),
					       vNULL, cleanup_decl, v, NULL);
	  vec_free (v);

	  /* Don't warn about decl unused; the cleanup uses it.  */
	  TREE_USED (decl) = 1;
	  TREE_USED (cleanup_decl) = 1;
	  DECL_READ_P (decl) = 1;

	  push_cleanup (decl, cleanup, false);
	}
    }

  if (warn_cxx_compat
      && VAR_P (decl)
      && !DECL_EXTERNAL (decl)
      && DECL_INITIAL (decl) == NULL_TREE)
    {
      type = strip_array_types (type);
      if (TREE_READONLY (decl))
	warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
		    "uninitialized %<const %D%> is invalid in C++", decl);
      else if (RECORD_OR_UNION_TYPE_P (type)
	       && C_TYPE_FIELDS_READONLY (type))
	diagnose_uninitialized_cst_member (decl, type);
    }

  if (flag_openmp
      && VAR_P (decl)
      && lookup_attribute ("omp declare target implicit",
			   DECL_ATTRIBUTES (decl)))
    {
      DECL_ATTRIBUTES (decl)
	= remove_attribute ("omp declare target implicit",
			    DECL_ATTRIBUTES (decl));
      if (!lang_hooks.types.omp_mappable_type (TREE_TYPE (decl)))
	error ("%q+D in declare target directive does not have mappable type",
	       decl);
      else if (!lookup_attribute ("omp declare target",
				  DECL_ATTRIBUTES (decl))
	       && !lookup_attribute ("omp declare target link",
				     DECL_ATTRIBUTES (decl)))
	{
	  DECL_ATTRIBUTES (decl)
	    = tree_cons (get_identifier ("omp declare target"),
			 NULL_TREE, DECL_ATTRIBUTES (decl));
	    symtab_node *node = symtab_node::get (decl);
	    if (node != NULL)
	      {
		node->offloadable = 1;
		if (ENABLE_OFFLOADING)
		  {
		    g->have_offload = true;
		    if (is_a <varpool_node *> (node))
		      vec_safe_push (offload_vars, decl);
		  }
	      }
	}
    }

  /* This is the last point we can lower alignment so give the target the
     chance to do so.  */
  if (VAR_P (decl)
      && !is_global_var (decl)
      && !DECL_HARD_REGISTER (decl))
    targetm.lower_local_decl_alignment (decl);

  invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
}

/* Given a parsed parameter declaration, decode it into a PARM_DECL.
   EXPR is NULL or a pointer to an expression that needs to be
   evaluated for the side effects of array size expressions in the
   parameters.  */

tree
grokparm (const struct c_parm *parm, tree *expr)
{
  tree attrs = parm->attrs;
  tree decl = grokdeclarator (parm->declarator, parm->specs, PARM, false,
			      NULL, &attrs, expr, NULL, DEPRECATED_NORMAL);

  decl_attributes (&decl, attrs, 0);

  return decl;
}

/* Return attribute "arg spec" corresponding to an array/VLA parameter
   described by PARM, concatenated onto attributes ATTRS.
   The spec consists of one dollar symbol for each specified variable
   bound, one asterisk for each unspecified variable bound, followed
   by at most one specification of the most significant bound of
   an ordinary array parameter.  For ordinary arrays the specification
   is either the constant bound itself, or the space character for
   an array with an unspecified bound (the [] form).  Finally, a chain
   of specified variable bounds is appended to the spec, starting with
   the most significant bound.  For example, the PARM T a[2][m][3][n]
   will produce __attribute__((arg spec ("[$$2]", m, n)).
   For T a typedef for an array with variable bounds, the bounds are
   included in the specification in the expected order.
   No "arg spec"  is created for parameters of pointer types, making
   a distinction between T(*)[N] (or, equivalently, T[][N]) and
   the T[M][N] form, all of which have the same type and are represented
   the same, but only the last of which gets an "arg spec" describing
   the most significant bound M.  */

static tree
get_parm_array_spec (const struct c_parm *parm, tree attrs)
{
  /* The attribute specification string, minor bound first.  */
  std::string spec;

  /* A list of VLA variable bounds, major first, or null if unspecified
     or not a VLA.  */
  tree vbchain = NULL_TREE;
  /* True for a pointer parameter.  */
  bool pointer = false;
  /* True for an ordinary array with an unpecified bound.  */
  bool nobound = false;

  /* Create a string representation for the bounds of the array/VLA.  */
  for (c_declarator *pd = parm->declarator, *next; pd; pd = next)
    {
      next = pd->declarator;
      while (next && next->kind == cdk_attrs)
	next = next->declarator;

      /* Remember if a pointer has been seen to avoid storing the constant
	 bound.  */
      if (pd->kind == cdk_pointer)
	pointer = true;

      if ((pd->kind == cdk_pointer || pd->kind == cdk_function)
	  && (!next || next->kind == cdk_id))
	{
	  /* Do nothing for the common case of a pointer.  The fact that
	     the parameter is one can be deduced from the absence of
	     an arg spec for it.  */
	  return attrs;
	}

      if (pd->kind == cdk_id)
	{
	  if (pointer
	      || !parm->specs->type
	      || TREE_CODE (parm->specs->type) != ARRAY_TYPE
	      || !TYPE_DOMAIN (parm->specs->type)
	      || !TYPE_MAX_VALUE (TYPE_DOMAIN (parm->specs->type)))
	    continue;

	  tree max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm->specs->type));
	  if (!vbchain
	      && TREE_CODE (max) == INTEGER_CST)
	    {
	      /* Extract the upper bound from a parameter of an array type
		 unless the parameter is an ordinary array of unspecified
		 bound in which case a next iteration of the loop will
		 exit.  */
	      if (spec.empty () || spec.end ()[-1] != ' ')
		{
		  if (!tree_fits_shwi_p (max))
		    continue;

		  /* The upper bound is the value of the largest valid
		     index.  */
		  HOST_WIDE_INT n = tree_to_shwi (max) + 1;
		  char buf[40];
		  sprintf (buf, "%lu", (unsigned long)n);
		  spec += buf;
		}
	      continue;
	    }

	  /* For a VLA typedef, create a list of its variable bounds and
	     append it in the expected order to VBCHAIN.  */
	  tree tpbnds = NULL_TREE;
	  for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE;
	       type = TREE_TYPE (type))
	    {
	      tree nelts = array_type_nelts (type);
	      if (error_operand_p (nelts))
		return attrs;
	      if (TREE_CODE (nelts) != INTEGER_CST)
		{
		  /* Each variable VLA bound is represented by the dollar
		     sign.  */
		  spec += "$";
		  tpbnds = tree_cons (NULL_TREE, nelts, tpbnds);
		}
	    }
	  tpbnds = nreverse (tpbnds);
	  vbchain = chainon (vbchain, tpbnds);
	  continue;
	}

      if (pd->kind != cdk_array)
	continue;

      if (pd->u.array.vla_unspec_p)
	{
	  /* Each unspecified bound is represented by a star.  There
	     can be any number of these in a declaration (but none in
	     a definition).  */
	  spec += '*';
	  continue;
	}

      tree nelts = pd->u.array.dimen;
      if (!nelts)
	{
	  /* Ordinary array of unspecified size.  There can be at most
	     one for the most significant bound.  Exit on the next
	     iteration which determines whether or not PARM is declared
	     as a pointer or an array.  */
	  nobound = true;
	  continue;
	}

      if (pd->u.array.static_p)
	spec += 's';

      if (TREE_CODE (nelts) == INTEGER_CST)
	{
	  /* Skip all constant bounds except the most significant one.
	     The interior ones are included in the array type.  */
	  if (next && (next->kind == cdk_array || next->kind == cdk_pointer))
	    continue;

	  if (!tree_fits_uhwi_p (nelts))
	    /* Bail completely on invalid bounds.  */
	    return attrs;

	  char buf[40];
	  unsigned HOST_WIDE_INT n = tree_to_uhwi (nelts);
	  sprintf (buf, "%llu", (unsigned long long)n);
	  spec += buf;
	  break;
	}
      else if (!INTEGRAL_TYPE_P (TREE_TYPE (nelts)))
	/* Avoid invalid NELTS.  */
	return attrs;

      /* Each variable VLA bound is represented by a dollar sign.  */
      spec += "$";
      STRIP_NOPS (nelts);
      vbchain = tree_cons (NULL_TREE, nelts, vbchain);
    }

  if (spec.empty () && !nobound)
    return attrs;

  spec.insert (0, "[");
  if (nobound)
    /* Ordinary array of unspecified bound is represented by a space.
       It must be last in the spec.  */
    spec += ' ';
  spec += ']';

  tree acsstr = build_string (spec.length () + 1, spec.c_str ());
  tree args = tree_cons (NULL_TREE, acsstr, vbchain);
  tree name = get_identifier ("arg spec");
  return tree_cons (name, args, attrs);
}

/* Given a parsed parameter declaration, decode it into a PARM_DECL
   and push that on the current scope.  EXPR is a pointer to an
   expression that needs to be evaluated for the side effects of array
   size expressions in the parameters.  */

void
push_parm_decl (const struct c_parm *parm, tree *expr)
{
  tree attrs = parm->attrs;
  tree decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, NULL,
			      &attrs, expr, NULL, DEPRECATED_NORMAL);
  if (decl && DECL_P (decl))
    DECL_SOURCE_LOCATION (decl) = parm->loc;

  attrs = get_parm_array_spec (parm, attrs);
  decl_attributes (&decl, attrs, 0);

  decl = pushdecl (decl);

  finish_decl (decl, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
}

/* Mark all the parameter declarations to date as forward decls.
   Also diagnose use of this extension.  */

void
mark_forward_parm_decls (void)
{
  struct c_binding *b;

  if (pedantic && !current_scope->warned_forward_parm_decls)
    {
      pedwarn (input_location, OPT_Wpedantic,
	       "ISO C forbids forward parameter declarations");
      current_scope->warned_forward_parm_decls = true;
    }

  for (b = current_scope->bindings; b; b = b->prev)
    if (TREE_CODE (b->decl) == PARM_DECL)
      TREE_ASM_WRITTEN (b->decl) = 1;
}

/* Build a COMPOUND_LITERAL_EXPR.  TYPE is the type given in the compound
   literal, which may be an incomplete array type completed by the
   initializer; INIT is a CONSTRUCTOR at LOC that initializes the compound
   literal.  NON_CONST is true if the initializers contain something
   that cannot occur in a constant expression.  If ALIGNAS_ALIGN is nonzero,
   it is the (valid) alignment for this compound literal, as specified
   with _Alignas.  */

tree
build_compound_literal (location_t loc, tree type, tree init, bool non_const,
			unsigned int alignas_align)
{
  /* We do not use start_decl here because we have a type, not a declarator;
     and do not use finish_decl because the decl should be stored inside
     the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_EXPR.  */
  tree decl;
  tree complit;
  tree stmt;

  if (type == error_mark_node
      || init == error_mark_node)
    return error_mark_node;

  decl = build_decl (loc, VAR_DECL, NULL_TREE, type);
  DECL_EXTERNAL (decl) = 0;
  TREE_PUBLIC (decl) = 0;
  TREE_STATIC (decl) = (current_scope == file_scope);
  DECL_CONTEXT (decl) = current_function_decl;
  TREE_USED (decl) = 1;
  DECL_READ_P (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  C_DECL_COMPOUND_LITERAL_P (decl) = 1;
  TREE_TYPE (decl) = type;
  c_apply_type_quals_to_decl (TYPE_QUALS (strip_array_types (type)), decl);
  if (alignas_align)
    {
      SET_DECL_ALIGN (decl, alignas_align * BITS_PER_UNIT);
      DECL_USER_ALIGN (decl) = 1;
    }
  store_init_value (loc, decl, init, NULL_TREE);

  if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
    {
      int failure = complete_array_type (&TREE_TYPE (decl),
					 DECL_INITIAL (decl), true);
      /* If complete_array_type returns 3, it means that the
         initial value of the compound literal is empty.  Allow it.  */
      gcc_assert (failure == 0 || failure == 3);

      type = TREE_TYPE (decl);
      TREE_TYPE (DECL_INITIAL (decl)) = type;
    }

  if (type == error_mark_node || !COMPLETE_TYPE_P (type))
    {
      c_incomplete_type_error (loc, NULL_TREE, type);
      return error_mark_node;
    }

  if (TREE_STATIC (decl)
      && !verify_type_context (loc, TCTX_STATIC_STORAGE, type))
    return error_mark_node;

  stmt = build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl);
  complit = build1 (COMPOUND_LITERAL_EXPR, type, stmt);
  TREE_SIDE_EFFECTS (complit) = 1;

  layout_decl (decl, 0);

  if (TREE_STATIC (decl))
    {
      /* This decl needs a name for the assembler output.  */
      set_compound_literal_name (decl);
      DECL_DEFER_OUTPUT (decl) = 1;
      DECL_COMDAT (decl) = 1;
      pushdecl (decl);
      rest_of_decl_compilation (decl, 1, 0);
    }
  else if (current_function_decl && !current_scope->parm_flag)
    pushdecl (decl);

  if (non_const)
    {
      complit = build2 (C_MAYBE_CONST_EXPR, type, NULL, complit);
      C_MAYBE_CONST_EXPR_NON_CONST (complit) = 1;
    }

  return complit;
}

/* Check the type of a compound literal.  Here we just check that it
   is valid for C++.  */

void
check_compound_literal_type (location_t loc, struct c_type_name *type_name)
{
  if (warn_cxx_compat
      && (type_name->specs->typespec_kind == ctsk_tagdef
          || type_name->specs->typespec_kind == ctsk_tagfirstref
	  || type_name->specs->typespec_kind == ctsk_tagfirstref_attrs))
    warning_at (loc, OPT_Wc___compat,
		"defining a type in a compound literal is invalid in C++");
}

/* Performs sanity checks on the TYPE and WIDTH of the bit-field NAME,
   replacing with appropriate values if they are invalid.  */

static void
check_bitfield_type_and_width (location_t loc, tree *type, tree *width,
			       tree orig_name)
{
  tree type_mv;
  unsigned int max_width;
  unsigned HOST_WIDE_INT w;
  const char *name = (orig_name
		      ? identifier_to_locale (IDENTIFIER_POINTER (orig_name))
		      : _("<anonymous>"));

  /* Detect and ignore out of range field width and process valid
     field widths.  */
  if (!INTEGRAL_TYPE_P (TREE_TYPE (*width)))
    {
      error_at (loc, "bit-field %qs width not an integer constant", name);
      *width = integer_one_node;
    }
  else
    {
      if (TREE_CODE (*width) != INTEGER_CST)
	{
	  *width = c_fully_fold (*width, false, NULL);
	  if (TREE_CODE (*width) == INTEGER_CST)
	    pedwarn (loc, OPT_Wpedantic,
		     "bit-field %qs width not an integer constant expression",
		     name);
	}
      if (TREE_CODE (*width) != INTEGER_CST)
	{
	  error_at (loc, "bit-field %qs width not an integer constant", name);
	  *width = integer_one_node;
	}
      constant_expression_warning (*width);
      if (tree_int_cst_sgn (*width) < 0)
	{
	  error_at (loc, "negative width in bit-field %qs", name);
	  *width = integer_one_node;
	}
      else if (integer_zerop (*width) && orig_name)
	{
	  error_at (loc, "zero width for bit-field %qs", name);
	  *width = integer_one_node;
	}
    }

  /* Detect invalid bit-field type.  */
  if (TREE_CODE (*type) != INTEGER_TYPE
      && TREE_CODE (*type) != BOOLEAN_TYPE
      && TREE_CODE (*type) != ENUMERAL_TYPE)
    {
      error_at (loc, "bit-field %qs has invalid type", name);
      *type = unsigned_type_node;
    }

  if (TYPE_WARN_IF_NOT_ALIGN (*type))
    {
      error_at (loc, "cannot declare bit-field %qs with %<warn_if_not_aligned%> type",
		name);
      *type = unsigned_type_node;
    }

  type_mv = TYPE_MAIN_VARIANT (*type);
  if (!in_system_header_at (input_location)
      && type_mv != integer_type_node
      && type_mv != unsigned_type_node
      && type_mv != boolean_type_node)
    pedwarn_c90 (loc, OPT_Wpedantic,
		 "type of bit-field %qs is a GCC extension", name);

  max_width = TYPE_PRECISION (*type);

  if (compare_tree_int (*width, max_width) > 0)
    {
      error_at (loc, "width of %qs exceeds its type", name);
      w = max_width;
      *width = build_int_cst (integer_type_node, w);
    }
  else
    w = tree_to_uhwi (*width);

  if (TREE_CODE (*type) == ENUMERAL_TYPE)
    {
      struct lang_type *lt = TYPE_LANG_SPECIFIC (*type);
      if (!lt
	  || w < tree_int_cst_min_precision (lt->enum_min, TYPE_SIGN (*type))
	  || w < tree_int_cst_min_precision (lt->enum_max, TYPE_SIGN (*type)))
	warning_at (loc, 0, "%qs is narrower than values of its type", name);
    }
}



/* Print warning about variable length array if necessary.  */

static void
warn_variable_length_array (tree name, tree size)
{
  if (TREE_CONSTANT (size))
    {
      if (name)
	pedwarn_c90 (input_location, OPT_Wvla,
		     "ISO C90 forbids array %qE whose size "
		     "cannot be evaluated", name);
      else
	pedwarn_c90 (input_location, OPT_Wvla, "ISO C90 forbids array "
		     "whose size cannot be evaluated");
    }
  else
    {
      if (name)
	pedwarn_c90 (input_location, OPT_Wvla,
		     "ISO C90 forbids variable length array %qE", name);
      else
	pedwarn_c90 (input_location, OPT_Wvla, "ISO C90 forbids variable "
		     "length array");
    }
}

/* Print warning about defaulting to int if necessary.  */

static void
warn_defaults_to (location_t location, int opt, const char *gmsgid, ...)
{
  diagnostic_info diagnostic;
  va_list ap;
  rich_location richloc (line_table, location);

  va_start (ap, gmsgid);
  diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
                       flag_isoc99 ? DK_PEDWARN : DK_WARNING);
  diagnostic.option_index = opt;
  diagnostic_report_diagnostic (global_dc, &diagnostic);
  va_end (ap);
}

/* Returns the smallest location != UNKNOWN_LOCATION in LOCATIONS,
   considering only those c_declspec_words found in LIST, which
   must be terminated by cdw_number_of_elements.  */

static location_t
smallest_type_quals_location (const location_t *locations,
			      const c_declspec_word *list)
{
  location_t loc = UNKNOWN_LOCATION;
  while (*list != cdw_number_of_elements)
    {
      location_t newloc = locations[*list];
      if (loc == UNKNOWN_LOCATION
	  || (newloc != UNKNOWN_LOCATION && newloc < loc))
	loc = newloc;
      list++;
    }

  return loc;
}

/* Given declspecs and a declarator,
   determine the name and type of the object declared
   and construct a ..._DECL node for it.
   (In one case we can return a ..._TYPE node instead.
    For invalid input we sometimes return NULL_TREE.)

   DECLSPECS is a c_declspecs structure for the declaration specifiers.

   DECL_CONTEXT says which syntactic context this declaration is in:
     NORMAL for most contexts.  Make a VAR_DECL or FUNCTION_DECL or TYPE_DECL.
     FUNCDEF for a function definition.  Like NORMAL but a few different
      error messages in each case.  Return value may be zero meaning
      this definition is too screwy to try to parse.
     PARM for a parameter declaration (either within a function prototype
      or before a function body).  Make a PARM_DECL, or return void_type_node.
     TYPENAME if for a typename (in a cast or sizeof).
      Don't make a DECL node; just return the ..._TYPE node.
     FIELD for a struct or union field; make a FIELD_DECL.
   INITIALIZED is true if the decl has an initializer.
   WIDTH is non-NULL for bit-fields, and is a pointer to an INTEGER_CST node
   representing the width of the bit-field.
   DECL_ATTRS points to the list of attributes that should be added to this
     decl.  Any nested attributes that belong on the decl itself will be
     added to this list.
   If EXPR is not NULL, any expressions that need to be evaluated as
     part of evaluating variably modified types will be stored in *EXPR.
   If EXPR_CONST_OPERANDS is not NULL, *EXPR_CONST_OPERANDS will be
     set to indicate whether operands in *EXPR can be used in constant
     expressions.
   DEPRECATED_STATE is a deprecated_states value indicating whether
   deprecation/unavailability warnings should be suppressed.

   In the TYPENAME case, DECLARATOR is really an absolute declarator.
   It may also be so in the PARM case, for a prototype where the
   argument type is specified but not the name.

   This function is where the complicated C meanings of `static'
   and `extern' are interpreted.  */

static tree
grokdeclarator (const struct c_declarator *declarator,
		struct c_declspecs *declspecs,
		enum decl_context decl_context, bool initialized, tree *width,
		tree *decl_attrs, tree *expr, bool *expr_const_operands,
		enum deprecated_states deprecated_state)
{
  tree type = declspecs->type;
  bool threadp = declspecs->thread_p;
  enum c_storage_class storage_class = declspecs->storage_class;
  int constp;
  int restrictp;
  int volatilep;
  int atomicp;
  int type_quals = TYPE_UNQUALIFIED;
  tree name = NULL_TREE;
  bool funcdef_flag = false;
  bool funcdef_syntax = false;
  bool size_varies = false;
  tree decl_attr = declspecs->decl_attr;
  int array_ptr_quals = TYPE_UNQUALIFIED;
  tree array_ptr_attrs = NULL_TREE;
  bool array_parm_static = false;
  bool array_parm_vla_unspec_p = false;
  tree returned_attrs = NULL_TREE;
  tree decl_id_attrs = NULL_TREE;
  bool bitfield = width != NULL;
  tree element_type;
  tree orig_qual_type = NULL;
  size_t orig_qual_indirect = 0;
  struct c_arg_info *arg_info = 0;
  addr_space_t as1, as2, address_space;
  location_t loc = UNKNOWN_LOCATION;
  tree expr_dummy;
  bool expr_const_operands_dummy;
  enum c_declarator_kind first_non_attr_kind;
  unsigned int alignas_align = 0;

  if (TREE_CODE (type) == ERROR_MARK)
    return error_mark_node;
  if (expr == NULL)
    {
      expr = &expr_dummy;
      expr_dummy = NULL_TREE;
    }
  if (expr_const_operands == NULL)
    expr_const_operands = &expr_const_operands_dummy;

  if (declspecs->expr)
    {
      if (*expr)
	*expr = build2 (COMPOUND_EXPR, TREE_TYPE (declspecs->expr), *expr,
			declspecs->expr);
      else
	*expr = declspecs->expr;
    }
  *expr_const_operands = declspecs->expr_const_operands;

  if (decl_context == FUNCDEF)
    funcdef_flag = true, decl_context = NORMAL;

  /* Look inside a declarator for the name being declared
     and get it as an IDENTIFIER_NODE, for an error message.  */
  {
    const struct c_declarator *decl = declarator;

    first_non_attr_kind = cdk_attrs;
    while (decl)
      switch (decl->kind)
	{
	case cdk_array:
	  loc = decl->id_loc;
	  /* FALL THRU.  */

	case cdk_function:
	case cdk_pointer:
	  funcdef_syntax = (decl->kind == cdk_function);
	  if (first_non_attr_kind == cdk_attrs)
	    first_non_attr_kind = decl->kind;
	  decl = decl->declarator;
	  break;

	case cdk_attrs:
	  decl = decl->declarator;
	  break;

	case cdk_id:
	  loc = decl->id_loc;
	  if (decl->u.id.id)
	    name = decl->u.id.id;
	  decl_id_attrs = decl->u.id.attrs;
	  if (first_non_attr_kind == cdk_attrs)
	    first_non_attr_kind = decl->kind;
	  decl = 0;
	  break;

	default:
	  gcc_unreachable ();
	}
    if (name == NULL_TREE)
      {
	gcc_assert (decl_context == PARM
		    || decl_context == TYPENAME
		    || (decl_context == FIELD
			&& declarator->kind == cdk_id));
	gcc_assert (!initialized);
      }
  }

  /* A function definition's declarator must have the form of
     a function declarator.  */

  if (funcdef_flag && !funcdef_syntax)
    return NULL_TREE;

  /* If this looks like a function definition, make it one,
     even if it occurs where parms are expected.
     Then store_parm_decls will reject it and not use it as a parm.  */
  if (decl_context == NORMAL && !funcdef_flag && current_scope->parm_flag)
    decl_context = PARM;

  if (deprecated_state != UNAVAILABLE_DEPRECATED_SUPPRESS)
    {
      if (declspecs->unavailable_p)
	error_unavailable_use (declspecs->type, declspecs->decl_attr);
      else if (declspecs->deprecated_p
		&& deprecated_state != DEPRECATED_SUPPRESS)
	warn_deprecated_use (declspecs->type, declspecs->decl_attr);
    }

  if ((decl_context == NORMAL || decl_context == FIELD)
      && current_scope == file_scope
      && variably_modified_type_p (type, NULL_TREE))
    {
      if (name)
	error_at (loc, "variably modified %qE at file scope", name);
      else
	error_at (loc, "variably modified field at file scope");
      type = integer_type_node;
    }

  size_varies = C_TYPE_VARIABLE_SIZE (type) != 0;

  /* Diagnose defaulting to "int".  */

  if (declspecs->default_int_p && !in_system_header_at (input_location))
    {
      /* Issue a warning if this is an ISO C 99 program or if
	 -Wreturn-type and this is a function, or if -Wimplicit;
	 prefer the former warning since it is more explicit.  */
      if ((warn_implicit_int || warn_return_type > 0 || flag_isoc99)
	  && funcdef_flag)
	warn_about_return_type = 1;
      else
	{
	  if (name)
	    warn_defaults_to (loc, OPT_Wimplicit_int,
			      "type defaults to %<int%> in declaration "
			      "of %qE", name);
	  else
	    warn_defaults_to (loc, OPT_Wimplicit_int,
			      "type defaults to %<int%> in type name");
	}
    }

  /* Adjust the type if a bit-field is being declared,
     -funsigned-bitfields applied and the type is not explicitly
     "signed".  */
  if (bitfield && !flag_signed_bitfields && !declspecs->explicit_signed_p
      && TREE_CODE (type) == INTEGER_TYPE)
    type = unsigned_type_for (type);

  /* Figure out the type qualifiers for the declaration.  There are
     two ways a declaration can become qualified.  One is something
     like `const int i' where the `const' is explicit.  Another is
     something like `typedef const int CI; CI i' where the type of the
     declaration contains the `const'.  A third possibility is that
     there is a type qualifier on the element type of a typedefed
     array type, in which case we should extract that qualifier so
     that c_apply_type_quals_to_decl receives the full list of
     qualifiers to work with (C90 is not entirely clear about whether
     duplicate qualifiers should be diagnosed in this case, but it
     seems most appropriate to do so).  */
  element_type = strip_array_types (type);
  constp = declspecs->const_p + TYPE_READONLY (element_type);
  restrictp = declspecs->restrict_p + TYPE_RESTRICT (element_type);
  volatilep = declspecs->volatile_p + TYPE_VOLATILE (element_type);
  atomicp = declspecs->atomic_p + TYPE_ATOMIC (element_type);
  as1 = declspecs->address_space;
  as2 = TYPE_ADDR_SPACE (element_type);
  address_space = ADDR_SPACE_GENERIC_P (as1)? as2 : as1;

  if (constp > 1)
    pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<const%>");
  if (restrictp > 1)
    pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<restrict%>");
  if (volatilep > 1)
    pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<volatile%>");
  if (atomicp > 1)
    pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<_Atomic%>");

  if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) && as1 != as2)
    error_at (loc, "conflicting named address spaces (%s vs %s)",
	      c_addr_space_name (as1), c_addr_space_name (as2));

  if ((TREE_CODE (type) == ARRAY_TYPE
       || first_non_attr_kind == cdk_array)
      && TYPE_QUALS (element_type))
    {
      orig_qual_type = type;
      type = TYPE_MAIN_VARIANT (type);
    }
  type_quals = ((constp ? TYPE_QUAL_CONST : 0)
		| (restrictp ? TYPE_QUAL_RESTRICT : 0)
		| (volatilep ? TYPE_QUAL_VOLATILE : 0)
		| (atomicp ? TYPE_QUAL_ATOMIC : 0)
		| ENCODE_QUAL_ADDR_SPACE (address_space));
  if (type_quals != TYPE_QUALS (element_type))
    orig_qual_type = NULL_TREE;

  /* Applying the _Atomic qualifier to an array type (through the use
     of typedefs or typeof) must be detected here.  If the qualifier
     is introduced later, any appearance of applying it to an array is
     actually applying it to an element of that array.  */
  if (declspecs->atomic_p && TREE_CODE (type) == ARRAY_TYPE)
    error_at (loc, "%<_Atomic%>-qualified array type");

  /* Warn about storage classes that are invalid for certain
     kinds of declarations (parameters, typenames, etc.).  */

  if (funcdef_flag
      && (threadp
	  || storage_class == csc_auto
	  || storage_class == csc_register
	  || storage_class == csc_typedef))
    {
      if (storage_class == csc_auto)
	pedwarn (loc,
		 (current_scope == file_scope) ? 0 : OPT_Wpedantic,
		 "function definition declared %<auto%>");
      if (storage_class == csc_register)
	error_at (loc, "function definition declared %<register%>");
      if (storage_class == csc_typedef)
	error_at (loc, "function definition declared %<typedef%>");
      if (threadp)
	error_at (loc, "function definition declared %qs",
		  declspecs->thread_gnu_p ? "__thread" : "_Thread_local");
      threadp = false;
      if (storage_class == csc_auto
	  || storage_class == csc_register
	  || storage_class == csc_typedef)
	storage_class = csc_none;
    }
  else if (decl_context != NORMAL && (storage_class != csc_none || threadp))
    {
      if (decl_context == PARM && storage_class == csc_register)
	;
      else
	{
	  switch (decl_context)
	    {
	    case FIELD:
	      if (name)
		error_at (loc, "storage class specified for structure "
		    	  "field %qE", name);
	      else
		error_at (loc, "storage class specified for structure field");
	      break;
	    case PARM:
	      if (name)
		error_at (loc, "storage class specified for parameter %qE",
		    	  name);
	      else
		error_at (loc, "storage class specified for unnamed parameter");
	      break;
	    default:
	      error_at (loc, "storage class specified for typename");
	      break;
	    }
	  storage_class = csc_none;
	  threadp = false;
	}
    }
  else if (storage_class == csc_extern
	   && initialized
	   && !funcdef_flag)
    {
      /* 'extern' with initialization is invalid if not at file scope.  */
       if (current_scope == file_scope)
         {
           /* It is fine to have 'extern const' when compiling at C
              and C++ intersection.  */
           if (!(warn_cxx_compat && constp))
             warning_at (loc, 0, "%qE initialized and declared %<extern%>",
		 	 name);
         }
      else
	error_at (loc, "%qE has both %<extern%> and initializer", name);
    }
  else if (current_scope == file_scope)
    {
      if (storage_class == csc_auto)
	error_at (loc, "file-scope declaration of %qE specifies %<auto%>",
	    	  name);
      if (pedantic && storage_class == csc_register)
	pedwarn (input_location, OPT_Wpedantic,
		 "file-scope declaration of %qE specifies %<register%>", name);
    }
  else
    {
      if (storage_class == csc_extern && funcdef_flag)
	error_at (loc, "nested function %qE declared %<extern%>", name);
      else if (threadp && storage_class == csc_none)
	{
	  error_at (loc, "function-scope %qE implicitly auto and declared "
		    "%qs", name,
		    declspecs->thread_gnu_p ? "__thread" : "_Thread_local");
	  threadp = false;
	}
    }

  /* Now figure out the structure of the declarator proper.
     Descend through it, creating more complex types, until we reach
     the declared identifier (or NULL_TREE, in an absolute declarator).
     At each stage we maintain an unqualified version of the type
     together with any qualifiers that should be applied to it with
     c_build_qualified_type; this way, array types including
     multidimensional array types are first built up in unqualified
     form and then the qualified form is created with
     TYPE_MAIN_VARIANT pointing to the unqualified form.  */

  while (declarator && declarator->kind != cdk_id)
    {
      if (type == error_mark_node)
	{
	  declarator = declarator->declarator;
	  continue;
	}

      /* Each level of DECLARATOR is either a cdk_array (for ...[..]),
	 a cdk_pointer (for *...),
	 a cdk_function (for ...(...)),
	 a cdk_attrs (for nested attributes),
	 or a cdk_id (for the name being declared
	 or the place in an absolute declarator
	 where the name was omitted).
	 For the last case, we have just exited the loop.

	 At this point, TYPE is the type of elements of an array,
	 or for a function to return, or for a pointer to point to.
	 After this sequence of ifs, TYPE is the type of the
	 array or function or pointer, and DECLARATOR has had its
	 outermost layer removed.  */

      if (array_ptr_quals != TYPE_UNQUALIFIED
	  || array_ptr_attrs != NULL_TREE
	  || array_parm_static)
	{
	  /* Only the innermost declarator (making a parameter be of
	     array type which is converted to pointer type)
	     may have static or type qualifiers.  */
	  error_at (loc, "static or type qualifiers in non-parameter array declarator");
	  array_ptr_quals = TYPE_UNQUALIFIED;
	  array_ptr_attrs = NULL_TREE;
	  array_parm_static = false;
	}

      switch (declarator->kind)
	{
	case cdk_attrs:
	  {
	    /* A declarator with embedded attributes.  */
	    tree attrs = declarator->u.attrs;
	    const struct c_declarator *inner_decl;
	    int attr_flags = 0;
	    declarator = declarator->declarator;
	    /* Standard attribute syntax precisely defines what entity
	       an attribute in each position appertains to, so only
	       apply laxity about positioning to GNU attribute syntax.
	       Standard attributes applied to a function or array
	       declarator apply exactly to that type; standard
	       attributes applied to the identifier apply to the
	       declaration rather than to the type, and are specified
	       using a cdk_id declarator rather than using
	       cdk_attrs.  */
	    inner_decl = declarator;
	    while (inner_decl->kind == cdk_attrs)
	      inner_decl = inner_decl->declarator;
	    if (!cxx11_attribute_p (attrs))
	      {
		if (inner_decl->kind == cdk_id)
		  attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
		else if (inner_decl->kind == cdk_function)
		  attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
		else if (inner_decl->kind == cdk_array)
		  attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
	      }
	    attrs = c_warn_type_attributes (attrs);
	    returned_attrs = decl_attributes (&type,
					      chainon (returned_attrs, attrs),
					      attr_flags);
	    break;
	  }
	case cdk_array:
	  {
	    tree itype = NULL_TREE;
	    tree size = declarator->u.array.dimen;
	    /* The index is a signed object `sizetype' bits wide.  */
	    tree index_type = c_common_signed_type (sizetype);

	    array_ptr_quals = declarator->u.array.quals;
	    array_ptr_attrs = declarator->u.array.attrs;
	    array_parm_static = declarator->u.array.static_p;
	    array_parm_vla_unspec_p = declarator->u.array.vla_unspec_p;

	    declarator = declarator->declarator;

	    /* Check for some types that there cannot be arrays of.  */

	    if (VOID_TYPE_P (type))
	      {
		if (name)
		  error_at (loc, "declaration of %qE as array of voids", name);
		else
		  error_at (loc, "declaration of type name as array of voids");
		type = error_mark_node;
	      }

	    if (TREE_CODE (type) == FUNCTION_TYPE)
	      {
		if (name)
		  error_at (loc, "declaration of %qE as array of functions",
		      	    name);
		else
		  error_at (loc, "declaration of type name as array of "
		            "functions");
		type = error_mark_node;
	      }

	    if (pedantic && !in_system_header_at (input_location)
		&& flexible_array_type_p (type))
	      pedwarn (loc, OPT_Wpedantic,
		       "invalid use of structure with flexible array member");

	    if (size == error_mark_node)
	      type = error_mark_node;

	    if (type == error_mark_node)
	      continue;

	    if (!verify_type_context (loc, TCTX_ARRAY_ELEMENT, type))
	      {
		type = error_mark_node;
		continue;
	      }

	    /* If size was specified, set ITYPE to a range-type for
	       that size.  Otherwise, ITYPE remains null.  finish_decl
	       may figure it out from an initial value.  */

	    if (size)
	      {
		bool size_maybe_const = true;
		bool size_int_const = (TREE_CODE (size) == INTEGER_CST
				       && !TREE_OVERFLOW (size));
		bool this_size_varies = false;

		/* Strip NON_LVALUE_EXPRs since we aren't using as an
		   lvalue.  */
		STRIP_TYPE_NOPS (size);

		if (!INTEGRAL_TYPE_P (TREE_TYPE (size)))
		  {
		    if (name)
		      error_at (loc, "size of array %qE has non-integer type",
				name);
		    else
		      error_at (loc,
				"size of unnamed array has non-integer type");
		    size = integer_one_node;
		    size_int_const = true;
		  }
		/* This can happen with enum forward declaration.  */
		else if (!COMPLETE_TYPE_P (TREE_TYPE (size)))
		  {
		    if (name)
		      error_at (loc, "size of array %qE has incomplete type",
				name);
		    else
		      error_at (loc, "size of unnamed array has incomplete "
				"type");
		    size = integer_one_node;
		    size_int_const = true;
		  }

		size = c_fully_fold (size, false, &size_maybe_const);

		if (pedantic && size_maybe_const && integer_zerop (size))
		  {
		    if (name)
		      pedwarn (loc, OPT_Wpedantic,
			       "ISO C forbids zero-size array %qE", name);
		    else
		      pedwarn (loc, OPT_Wpedantic,
			       "ISO C forbids zero-size array");
		  }

		if (TREE_CODE (size) == INTEGER_CST && size_maybe_const)
		  {
		    constant_expression_warning (size);
		    if (tree_int_cst_sgn (size) < 0)
		      {
			if (name)
			  error_at (loc, "size of array %qE is negative", name);
			else
			  error_at (loc, "size of unnamed array is negative");
			size = integer_one_node;
			size_int_const = true;
		      }
		    /* Handle a size folded to an integer constant but
		       not an integer constant expression.  */
		    if (!size_int_const)
		      {
			/* If this is a file scope declaration of an
			   ordinary identifier, this is invalid code;
			   diagnosing it here and not subsequently
			   treating the type as variable-length avoids
			   more confusing diagnostics later.  */
			if ((decl_context == NORMAL || decl_context == FIELD)
			    && current_scope == file_scope)
			  pedwarn (input_location, 0,
				   "variably modified %qE at file scope",
				   name);
			else
			  this_size_varies = size_varies = true;
			warn_variable_length_array (name, size);
		      }
		  }
		else if ((decl_context == NORMAL || decl_context == FIELD)
			 && current_scope == file_scope)
		  {
		    error_at (loc, "variably modified %qE at file scope", name);
		    size = integer_one_node;
		  }
		else
		  {
		    /* Make sure the array size remains visibly
		       nonconstant even if it is (eg) a const variable
		       with known value.  */
		    this_size_varies = size_varies = true;
		    warn_variable_length_array (name, size);
		    if (sanitize_flags_p (SANITIZE_VLA)
			&& current_function_decl != NULL_TREE
			&& decl_context == NORMAL)
		      {
			/* Evaluate the array size only once.  */
			size = save_expr (size);
			size = c_fully_fold (size, false, NULL);
		        size = fold_build2 (COMPOUND_EXPR, TREE_TYPE (size),
					    ubsan_instrument_vla (loc, size),
					    size);
		      }
		  }

		if (integer_zerop (size) && !this_size_varies)
		  {
		    /* A zero-length array cannot be represented with
		       an unsigned index type, which is what we'll
		       get with build_index_type.  Create an
		       open-ended range instead.  */
		    itype = build_range_type (sizetype, size, NULL_TREE);
		  }
		else
		  {
		    /* Arrange for the SAVE_EXPR on the inside of the
		       MINUS_EXPR, which allows the -1 to get folded
		       with the +1 that happens when building TYPE_SIZE.  */
		    if (size_varies)
		      size = save_expr (size);
		    if (this_size_varies && TREE_CODE (size) == INTEGER_CST)
		      size = build2 (COMPOUND_EXPR, TREE_TYPE (size),
				     integer_zero_node, size);

		    /* Compute the maximum valid index, that is, size
		       - 1.  Do the calculation in index_type, so that
		       if it is a variable the computations will be
		       done in the proper mode.  */
		    itype = fold_build2_loc (loc, MINUS_EXPR, index_type,
					     convert (index_type, size),
					     convert (index_type,
						      size_one_node));

		    /* The above overflows when size does not fit
		       in index_type.
		       ???  While a size of INT_MAX+1 technically shouldn't
		       cause an overflow (because we subtract 1), handling
		       this case seems like an unnecessary complication.  */
		    if (TREE_CODE (size) == INTEGER_CST
			&& !int_fits_type_p (size, index_type))
		      {
			if (name)
			  error_at (loc, "size of array %qE is too large",
			            name);
			else
			  error_at (loc, "size of unnamed array is too large");
			type = error_mark_node;
			continue;
		      }

		    itype = build_index_type (itype);
		  }
		if (this_size_varies)
		  {
		    if (TREE_SIDE_EFFECTS (size))
		      {
			if (*expr)
			  *expr = build2 (COMPOUND_EXPR, TREE_TYPE (size),
					  *expr, size);
			else
			  *expr = size;
		      }
		    *expr_const_operands &= size_maybe_const;
		  }
	      }
	    else if (decl_context == FIELD)
	      {
		bool flexible_array_member = false;
		if (array_parm_vla_unspec_p)
		  /* Field names can in fact have function prototype
		     scope so [*] is disallowed here through making
		     the field variably modified, not through being
		     something other than a declaration with function
		     prototype scope.  */
		  size_varies = true;
		else
		  {
		    const struct c_declarator *t = declarator;
		    while (t->kind == cdk_attrs)
		      t = t->declarator;
		    flexible_array_member = (t->kind == cdk_id);
		  }
		if (flexible_array_member
		    && !in_system_header_at (input_location))
		  pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not "
			       "support flexible array members");

		/* ISO C99 Flexible array members are effectively
		   identical to GCC's zero-length array extension.  */
		if (flexible_array_member || array_parm_vla_unspec_p)
		  itype = build_range_type (sizetype, size_zero_node,
					    NULL_TREE);
	      }
	    else if (decl_context == PARM)
	      {
		if (array_parm_vla_unspec_p)
		  {
		    itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
		    size_varies = true;
		  }
	      }
	    else if (decl_context == TYPENAME)
	      {
		if (array_parm_vla_unspec_p)
		  {
		    /* C99 6.7.5.2p4 */
		    warning (0, "%<[*]%> not in a declaration");
		    /* We use this to avoid messing up with incomplete
		       array types of the same type, that would
		       otherwise be modified below.  */
		    itype = build_range_type (sizetype, size_zero_node,
					      NULL_TREE);
		    size_varies = true;
		  }
	      }

	    /* Complain about arrays of incomplete types.  */
	    if (!COMPLETE_TYPE_P (type))
	      {
		error_at (loc, "array type has incomplete element type %qT",
			  type);
		/* See if we can be more helpful.  */
		if (TREE_CODE (type) == ARRAY_TYPE)
		  {
		    if (name)
		      inform (loc, "declaration of %qE as multidimensional "
			      "array must have bounds for all dimensions "
			      "except the first", name);
		    else
		      inform (loc, "declaration of multidimensional array "
			      "must have bounds for all dimensions except "
			      "the first");
		  }
		type = error_mark_node;
	      }
	    else
	    /* When itype is NULL, a shared incomplete array type is
	       returned for all array of a given type.  Elsewhere we
	       make sure we don't complete that type before copying
	       it, but here we want to make sure we don't ever
	       modify the shared type, so we gcc_assert (itype)
	       below.  */
	      {
		addr_space_t as = DECODE_QUAL_ADDR_SPACE (type_quals);
		if (!ADDR_SPACE_GENERIC_P (as) && as != TYPE_ADDR_SPACE (type))
		  type = build_qualified_type (type,
					       ENCODE_QUAL_ADDR_SPACE (as));

		type = build_array_type (type, itype);
	      }

	    if (type != error_mark_node)
	      {
		if (size_varies)
		  {
		    /* It is ok to modify type here even if itype is
		       NULL: if size_varies, we're in a
		       multi-dimensional array and the inner type has
		       variable size, so the enclosing shared array type
		       must too.  */
		    if (size && TREE_CODE (size) == INTEGER_CST)
		      type
			= build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
		    C_TYPE_VARIABLE_SIZE (type) = 1;
		  }

		/* The GCC extension for zero-length arrays differs from
		   ISO flexible array members in that sizeof yields
		   zero.  */
		if (size && integer_zerop (size))
		  {
		    gcc_assert (itype);
		    type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
		    TYPE_SIZE (type) = bitsize_zero_node;
		    TYPE_SIZE_UNIT (type) = size_zero_node;
		    SET_TYPE_STRUCTURAL_EQUALITY (type);
		  }
		if (array_parm_vla_unspec_p)
		  {
		    gcc_assert (itype);
		    /* The type is complete.  C99 6.7.5.2p4  */
		    type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
		    TYPE_SIZE (type) = bitsize_zero_node;
		    TYPE_SIZE_UNIT (type) = size_zero_node;
		    SET_TYPE_STRUCTURAL_EQUALITY (type);
		  }

		if (!valid_array_size_p (loc, type, name))
		  type = error_mark_node;
	      }

	    if (decl_context != PARM
		&& (array_ptr_quals != TYPE_UNQUALIFIED
		    || array_ptr_attrs != NULL_TREE
		    || array_parm_static))
	      {
		error_at (loc, "static or type qualifiers in non-parameter "
			  "array declarator");
		array_ptr_quals = TYPE_UNQUALIFIED;
		array_ptr_attrs = NULL_TREE;
		array_parm_static = false;
	      }
	    orig_qual_indirect++;
	    break;
	  }
	case cdk_function:
	  {
	    /* Say it's a definition only for the declarator closest
	       to the identifier, apart possibly from some
	       attributes.  */
	    bool really_funcdef = false;
	    tree arg_types;
	    orig_qual_type = NULL_TREE;
	    if (funcdef_flag)
	      {
		const struct c_declarator *t = declarator->declarator;
		while (t->kind == cdk_attrs)
		  t = t->declarator;
		really_funcdef = (t->kind == cdk_id);
	      }

	    /* Declaring a function type.  Make sure we have a valid
	       type for the function to return.  */
	    if (type == error_mark_node)
	      continue;

	    size_varies = false;

	    /* Warn about some types functions can't return.  */
	    if (TREE_CODE (type) == FUNCTION_TYPE)
	      {
		if (name)
		  error_at (loc, "%qE declared as function returning a "
		      		 "function", name);
		else
		  error_at (loc, "type name declared as function "
			    "returning a function");
		type = integer_type_node;
	      }
	    if (TREE_CODE (type) == ARRAY_TYPE)
	      {
		if (name)
		  error_at (loc, "%qE declared as function returning an array",
		      	    name);
		else
		  error_at (loc, "type name declared as function returning "
		      	    "an array");
		type = integer_type_node;
	      }

	    /* Construct the function type and go to the next
	       inner layer of declarator.  */
	    arg_info = declarator->u.arg_info;
	    arg_types = grokparms (arg_info, really_funcdef);

	    /* Type qualifiers before the return type of the function
	       qualify the return type, not the function type.  */
	    if (type_quals)
	      {
		const enum c_declspec_word ignored_quals_list[] =
		  {
		    cdw_const, cdw_volatile, cdw_restrict, cdw_address_space,
		    cdw_atomic, cdw_number_of_elements
		  };
		location_t specs_loc
		  = smallest_type_quals_location (declspecs->locations,
						  ignored_quals_list);
		if (specs_loc == UNKNOWN_LOCATION)
		  specs_loc = declspecs->locations[cdw_typedef];
		if (specs_loc == UNKNOWN_LOCATION)
		  specs_loc = loc;

		/* Type qualifiers on a function return type are
		   normally permitted by the standard but have no
		   effect, so give a warning at -Wreturn-type.
		   Qualifiers on a void return type are banned on
		   function definitions in ISO C; GCC used to used
		   them for noreturn functions.  The resolution of C11
		   DR#423 means qualifiers (other than _Atomic) are
		   actually removed from the return type when
		   determining the function type.  */
		int quals_used = type_quals;
		if (flag_isoc11)
		  quals_used &= TYPE_QUAL_ATOMIC;
		if (quals_used && VOID_TYPE_P (type) && really_funcdef)
		  pedwarn (specs_loc, 0,
			   "function definition has qualified void "
			   "return type");
		else
		  warning_at (specs_loc, OPT_Wignored_qualifiers,
			      "type qualifiers ignored on function "
			      "return type");

		/* Ensure an error for restrict on invalid types; the
		   DR#423 resolution is not entirely clear about
		   this.  */
		if (flag_isoc11
		    && (type_quals & TYPE_QUAL_RESTRICT)
		    && (!POINTER_TYPE_P (type)
			|| !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
		  error_at (loc, "invalid use of %<restrict%>");
		type = c_build_qualified_type (type, quals_used);
	      }
	    type_quals = TYPE_UNQUALIFIED;

	    type = build_function_type (type, arg_types);
	    declarator = declarator->declarator;

	    /* Set the TYPE_CONTEXTs for each tagged type which is local to
	       the formal parameter list of this FUNCTION_TYPE to point to
	       the FUNCTION_TYPE node itself.  */
	    {
	      c_arg_tag *tag;
	      unsigned ix;

	      FOR_EACH_VEC_SAFE_ELT_REVERSE (arg_info->tags, ix, tag)
		TYPE_CONTEXT (tag->type) = type;
	    }
	    break;
	  }
	case cdk_pointer:
	  {
	    /* Merge any constancy or volatility into the target type
	       for the pointer.  */
	    if ((type_quals & TYPE_QUAL_ATOMIC)
		&& TREE_CODE (type) == FUNCTION_TYPE)
	      {
		error_at (loc,
			  "%<_Atomic%>-qualified function type");
		type_quals &= ~TYPE_QUAL_ATOMIC;
	      }
	    else if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
		     && type_quals)
	      pedwarn (loc, OPT_Wpedantic,
		       "ISO C forbids qualified function types");
	    if (type_quals)
	      type = c_build_qualified_type (type, type_quals, orig_qual_type,
					     orig_qual_indirect);
	    orig_qual_type = NULL_TREE;
	    size_varies = false;

	    /* When the pointed-to type involves components of variable size,
	       care must be taken to ensure that the size evaluation code is
	       emitted early enough to dominate all the possible later uses
	       and late enough for the variables on which it depends to have
	       been assigned.

	       This is expected to happen automatically when the pointed-to
	       type has a name/declaration of it's own, but special attention
	       is required if the type is anonymous.

	       We attach an artificial TYPE_DECL to such pointed-to type
	       and arrange for it to be included in a DECL_EXPR.  This
	       forces the sizes evaluation at a safe point and ensures it
	       is not deferred until e.g. within a deeper conditional context.

	       PARM contexts have no enclosing statement list that
	       can hold the DECL_EXPR, so we need to use a BIND_EXPR
	       instead, and add it to the list of expressions that
	       need to be evaluated.

	       TYPENAME contexts do have an enclosing statement list,
	       but it would be incorrect to use it, as the size should
	       only be evaluated if the containing expression is
	       evaluated.  We might also be in the middle of an
	       expression with side effects on the pointed-to type size
	       "arguments" prior to the pointer declaration point and
	       the fake TYPE_DECL in the enclosing context would force
	       the size evaluation prior to the side effects.  We therefore
	       use BIND_EXPRs in TYPENAME contexts too.  */
	    if (!TYPE_NAME (type)
		&& variably_modified_type_p (type, NULL_TREE))
	      {
		tree bind = NULL_TREE;
		if (decl_context == TYPENAME || decl_context == PARM)
		  {
		    bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
				   NULL_TREE, NULL_TREE);
		    TREE_SIDE_EFFECTS (bind) = 1;
		    BIND_EXPR_BODY (bind) = push_stmt_list ();
		    push_scope ();
		  }
		tree decl = build_decl (loc, TYPE_DECL, NULL_TREE, type);
		DECL_ARTIFICIAL (decl) = 1;
		pushdecl (decl);
		finish_decl (decl, loc, NULL_TREE, NULL_TREE, NULL_TREE);
		TYPE_NAME (type) = decl;
		if (bind)
		  {
		    pop_scope ();
		    BIND_EXPR_BODY (bind)
		      = pop_stmt_list (BIND_EXPR_BODY (bind));
		    if (*expr)
		      *expr = build2 (COMPOUND_EXPR, void_type_node, *expr,
				      bind);
		    else
		      *expr = bind;
		  }
	      }

	    type = c_build_pointer_type (type);

	    /* Process type qualifiers (such as const or volatile)
	       that were given inside the `*'.  */
	    type_quals = declarator->u.pointer_quals;

	    declarator = declarator->declarator;
	    break;
	  }
	default:
	  gcc_unreachable ();
	}
    }
  *decl_attrs = chainon (returned_attrs, *decl_attrs);
  *decl_attrs = chainon (decl_id_attrs, *decl_attrs);

  /* Now TYPE has the actual type, apart from any qualifiers in
     TYPE_QUALS.  */

  /* Warn about address space used for things other than static memory or
     pointers.  */
  address_space = DECODE_QUAL_ADDR_SPACE (type_quals);
  if (!ADDR_SPACE_GENERIC_P (address_space))
    {
      if (decl_context == NORMAL)
	{
	  switch (storage_class)
	    {
	    case csc_auto:
	      error ("%qs combined with %<auto%> qualifier for %qE",
		     c_addr_space_name (address_space), name);
	      break;
	    case csc_register:
	      error ("%qs combined with %<register%> qualifier for %qE",
		     c_addr_space_name (address_space), name);
	      break;
	    case csc_none:
	      if (current_function_scope)
		{
		  error ("%qs specified for auto variable %qE",
			 c_addr_space_name (address_space), name);
		  break;
		}
	      break;
	    case csc_static:
	    case csc_extern:
	    case csc_typedef:
	      break;
	    default:
	      gcc_unreachable ();
	    }
	}
      else if (decl_context == PARM && TREE_CODE (type) != ARRAY_TYPE)
	{
	  if (name)
	    error ("%qs specified for parameter %qE",
		   c_addr_space_name (address_space), name);
	  else
	    error ("%qs specified for unnamed parameter",
		   c_addr_space_name (address_space));
	}
      else if (decl_context == FIELD)
	{
	  if (name)
	    error ("%qs specified for structure field %qE",
		   c_addr_space_name (address_space), name);
	  else
	    error ("%qs specified for structure field",
		   c_addr_space_name (address_space));
	}
    }

  /* Check the type and width of a bit-field.  */
  if (bitfield)
    {
      check_bitfield_type_and_width (loc, &type, width, name);
      /* C11 makes it implementation-defined (6.7.2.1#5) whether
	 atomic types are permitted for bit-fields; we have no code to
	 make bit-field accesses atomic, so disallow them.  */
      if (type_quals & TYPE_QUAL_ATOMIC)
	{
	  if (name)
	    error_at (loc, "bit-field %qE has atomic type", name);
	  else
	    error_at (loc, "bit-field has atomic type");
	  type_quals &= ~TYPE_QUAL_ATOMIC;
	}
    }

  /* Reject invalid uses of _Alignas.  */
  if (declspecs->alignas_p)
    {
      if (storage_class == csc_typedef)
	error_at (loc, "alignment specified for typedef %qE", name);
      else if (storage_class == csc_register)
	error_at (loc, "alignment specified for %<register%> object %qE",
		  name);
      else if (decl_context == PARM)
	{
	  if (name)
	    error_at (loc, "alignment specified for parameter %qE", name);
	  else
	    error_at (loc, "alignment specified for unnamed parameter");
	}
      else if (bitfield)
	{
	  if (name)
	    error_at (loc, "alignment specified for bit-field %qE", name);
	  else
	    error_at (loc, "alignment specified for unnamed bit-field");
	}
      else if (TREE_CODE (type) == FUNCTION_TYPE)
	error_at (loc, "alignment specified for function %qE", name);
      else if (declspecs->align_log != -1 && TYPE_P (type))
	{
	  alignas_align = 1U << declspecs->align_log;
	  if (alignas_align < min_align_of_type (type))
	    {
	      if (name)
		error_at (loc, "%<_Alignas%> specifiers cannot reduce "
			  "alignment of %qE", name);
	      else
		error_at (loc, "%<_Alignas%> specifiers cannot reduce "
			  "alignment of unnamed field");
	      alignas_align = 0;
	    }
	}
    }

  /* If this is declaring a typedef name, return a TYPE_DECL.  */

  if (storage_class == csc_typedef)
    {
      tree decl;
      if ((type_quals & TYPE_QUAL_ATOMIC)
	  && TREE_CODE (type) == FUNCTION_TYPE)
	{
	  error_at (loc,
		    "%<_Atomic%>-qualified function type");
	  type_quals &= ~TYPE_QUAL_ATOMIC;
	}
      else if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
	       && type_quals)
	pedwarn (loc, OPT_Wpedantic,
		 "ISO C forbids qualified function types");
      if (type_quals)
	type = c_build_qualified_type (type, type_quals, orig_qual_type,
				       orig_qual_indirect);
      decl = build_decl (declarator->id_loc,
			 TYPE_DECL, declarator->u.id.id, type);
      if (declspecs->explicit_signed_p)
	C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
      if (declspecs->inline_p)
	pedwarn (loc, 0,"typedef %q+D declared %<inline%>", decl);
      if (declspecs->noreturn_p)
	pedwarn (loc, 0,"typedef %q+D declared %<_Noreturn%>", decl);

      if (warn_cxx_compat && declarator->u.id.id != NULL_TREE)
	{
	  struct c_binding *b = I_TAG_BINDING (declarator->u.id.id);

	  if (b != NULL
	      && b->decl != NULL_TREE
	      && (B_IN_CURRENT_SCOPE (b)
		  || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b)))
	      && TYPE_MAIN_VARIANT (b->decl) != TYPE_MAIN_VARIANT (type))
	    {
	      auto_diagnostic_group d;
	      if (warning_at (declarator->id_loc, OPT_Wc___compat,
			      ("using %qD as both a typedef and a tag is "
			       "invalid in C++"), decl)
		  && b->locus != UNKNOWN_LOCATION)
		inform (b->locus, "originally defined here");
	    }
	}

      return decl;
    }

  /* If this is a type name (such as, in a cast or sizeof),
     compute the type and return it now.  */

  if (decl_context == TYPENAME)
    {
      /* Note that the grammar rejects storage classes in typenames
	 and fields.  */
      gcc_assert (storage_class == csc_none && !threadp
		  && !declspecs->inline_p && !declspecs->noreturn_p);
      if ((type_quals & TYPE_QUAL_ATOMIC)
	  && TREE_CODE (type) == FUNCTION_TYPE)
	{
	  error_at (loc,
		    "%<_Atomic%>-qualified function type");
	  type_quals &= ~TYPE_QUAL_ATOMIC;
	}
      else if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
	       && type_quals)
	pedwarn (loc, OPT_Wpedantic,
		 "ISO C forbids const or volatile function types");
      if (type_quals)
	type = c_build_qualified_type (type, type_quals, orig_qual_type,
				       orig_qual_indirect);
      return type;
    }

  if (pedantic && decl_context == FIELD
      && variably_modified_type_p (type, NULL_TREE))
    {
      /* C99 6.7.2.1p8 */
      pedwarn (loc, OPT_Wpedantic, "a member of a structure or union cannot "
	       "have a variably modified type");
    }

  /* Aside from typedefs and type names (handle above),
     `void' at top level (not within pointer)
     is allowed only in public variables.
     We don't complain about parms either, but that is because
     a better error message can be made later.  */

  if (VOID_TYPE_P (type) && decl_context != PARM
      && !((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
	    && (storage_class == csc_extern
		|| (current_scope == file_scope
		    && !(storage_class == csc_static
			 || storage_class == csc_register)))))
    {
      error_at (loc, "variable or field %qE declared void", name);
      type = integer_type_node;
    }

  /* Now create the decl, which may be a VAR_DECL, a PARM_DECL
     or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE.  */

  {
    tree decl;

    if (decl_context == PARM)
      {
	tree promoted_type;
	bool array_parameter_p = false;

	/* A parameter declared as an array of T is really a pointer to T.
	   One declared as a function is really a pointer to a function.  */

	if (TREE_CODE (type) == ARRAY_TYPE)
	  {
	    /* Transfer const-ness of array into that of type pointed to.  */
	    type = TREE_TYPE (type);
	    if (orig_qual_type != NULL_TREE)
	      {
		if (orig_qual_indirect == 0)
		  orig_qual_type = TREE_TYPE (orig_qual_type);
		else
		  orig_qual_indirect--;
	      }
	    if (type_quals)
	      type = c_build_qualified_type (type, type_quals, orig_qual_type,
					     orig_qual_indirect);
	    type = c_build_pointer_type (type);
	    type_quals = array_ptr_quals;
	    if (type_quals)
	      type = c_build_qualified_type (type, type_quals);

	    /* We don't yet implement attributes in this context.  */
	    if (array_ptr_attrs != NULL_TREE)
	      warning_at (loc, OPT_Wattributes,
			  "attributes in parameter array declarator ignored");

	    size_varies = false;
	    array_parameter_p = true;
	  }
	else if (TREE_CODE (type) == FUNCTION_TYPE)
	  {
	    if (type_quals & TYPE_QUAL_ATOMIC)
	      {
		error_at (loc,
			  "%<_Atomic%>-qualified function type");
		type_quals &= ~TYPE_QUAL_ATOMIC;
	      }
	    else if (type_quals)
	      pedwarn (loc, OPT_Wpedantic,
		       "ISO C forbids qualified function types");
	    if (type_quals)
	      type = c_build_qualified_type (type, type_quals);
	    type = c_build_pointer_type (type);
	    type_quals = TYPE_UNQUALIFIED;
	  }
	else if (type_quals)
	  type = c_build_qualified_type (type, type_quals);

	decl = build_decl (declarator->id_loc,
			   PARM_DECL, declarator->u.id.id, type);
	if (size_varies)
	  C_DECL_VARIABLE_SIZE (decl) = 1;
	C_ARRAY_PARAMETER (decl) = array_parameter_p;

	/* Compute the type actually passed in the parmlist,
	   for the case where there is no prototype.
	   (For example, shorts and chars are passed as ints.)
	   When there is a prototype, this is overridden later.  */

	if (type == error_mark_node)
	  promoted_type = type;
	else
	  promoted_type = c_type_promotes_to (type);

	DECL_ARG_TYPE (decl) = promoted_type;
	if (declspecs->inline_p)
	  pedwarn (loc, 0, "parameter %q+D declared %<inline%>", decl);
	if (declspecs->noreturn_p)
	  pedwarn (loc, 0, "parameter %q+D declared %<_Noreturn%>", decl);
      }
    else if (decl_context == FIELD)
      {
	/* Note that the grammar rejects storage classes in typenames
	   and fields.  */
	gcc_assert (storage_class == csc_none && !threadp
		    && !declspecs->inline_p && !declspecs->noreturn_p);

	/* Structure field.  It may not be a function.  */

	if (TREE_CODE (type) == FUNCTION_TYPE)
	  {
	    error_at (loc, "field %qE declared as a function", name);
	    type = build_pointer_type (type);
	  }
	else if (TREE_CODE (type) != ERROR_MARK
		 && !COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (type))
	  {
	    if (name)
	      error_at (loc, "field %qE has incomplete type", name);
	    else
	      error_at (loc, "unnamed field has incomplete type");
	    type = error_mark_node;
	  }
	else if (TREE_CODE (type) == ARRAY_TYPE
		 && TYPE_DOMAIN (type) == NULL_TREE)
	  {
	    /* We have a flexible array member through a typedef.
	       Set suitable range.  Whether this is a correct position
	       for a flexible array member will be determined elsewhere.  */
	    if (!in_system_header_at (input_location))
	      pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not "
			   "support flexible array members");
	    type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
	    TYPE_DOMAIN (type) = build_range_type (sizetype, size_zero_node,
						   NULL_TREE);
	    if (orig_qual_indirect == 0)
	      orig_qual_type = NULL_TREE;
	  }
	if (type != error_mark_node
	    && !verify_type_context (loc, TCTX_FIELD, type))
	  type = error_mark_node;

	type = c_build_qualified_type (type, type_quals, orig_qual_type,
				       orig_qual_indirect);
	decl = build_decl (declarator->id_loc,
			   FIELD_DECL, declarator->u.id.id, type);
	DECL_NONADDRESSABLE_P (decl) = bitfield;
	if (bitfield && !declarator->u.id.id)
	  DECL_PADDING_P (decl) = 1;

	if (size_varies)
	  C_DECL_VARIABLE_SIZE (decl) = 1;
      }
    else if (TREE_CODE (type) == FUNCTION_TYPE)
      {
	if (storage_class == csc_register || threadp)
	  {
	    error_at (loc, "invalid storage class for function %qE", name);
	  }
	else if (current_scope != file_scope)
	  {
	    /* Function declaration not at file scope.  Storage
	       classes other than `extern' are not allowed, C99
	       6.7.1p5, and `extern' makes no difference.  However,
	       GCC allows 'auto', perhaps with 'inline', to support
	       nested functions.  */
	    if (storage_class == csc_auto)
		pedwarn (loc, OPT_Wpedantic,
			 "invalid storage class for function %qE", name);
	    else if (storage_class == csc_static)
	      {
		error_at (loc, "invalid storage class for function %qE", name);
		if (funcdef_flag)
		  storage_class = declspecs->storage_class = csc_none;
		else
		  return NULL_TREE;
	      }
	  }

	decl = build_decl (declarator->id_loc,
			   FUNCTION_DECL, declarator->u.id.id, type);
	decl = build_decl_attribute_variant (decl, decl_attr);

	if (type_quals & TYPE_QUAL_ATOMIC)
	  {
	    error_at (loc,
		      "%<_Atomic%>-qualified function type");
	    type_quals &= ~TYPE_QUAL_ATOMIC;
	  }
	else if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl))
	  pedwarn (loc, OPT_Wpedantic,
		   "ISO C forbids qualified function types");

	/* Every function declaration is an external reference
	   (DECL_EXTERNAL) except for those which are not at file
	   scope and are explicitly declared "auto".  This is
	   forbidden by standard C (C99 6.7.1p5) and is interpreted by
	   GCC to signify a forward declaration of a nested function.  */
	if (storage_class == csc_auto && current_scope != file_scope)
	  DECL_EXTERNAL (decl) = 0;
	/* In C99, a function which is declared 'inline' with 'extern'
	   is not an external reference (which is confusing).  It
	   means that the later definition of the function must be output
	   in this file, C99 6.7.4p6.  In GNU C89, a function declared
	   'extern inline' is an external reference.  */
	else if (declspecs->inline_p && storage_class != csc_static)
	  DECL_EXTERNAL (decl) = ((storage_class == csc_extern)
				  == flag_gnu89_inline);
	else
	  DECL_EXTERNAL (decl) = !initialized;

	/* Record absence of global scope for `static' or `auto'.  */
	TREE_PUBLIC (decl)
	  = !(storage_class == csc_static || storage_class == csc_auto);

	/* For a function definition, record the argument information
	   block where store_parm_decls will look for it.  */
	if (funcdef_flag)
	  current_function_arg_info = arg_info;

	if (declspecs->default_int_p)
	  C_FUNCTION_IMPLICIT_INT (decl) = 1;

	/* Record presence of `inline' and `_Noreturn', if it is
	   reasonable.  */
	if (flag_hosted && MAIN_NAME_P (declarator->u.id.id))
	  {
	    if (declspecs->inline_p)
	      pedwarn (loc, 0, "cannot inline function %<main%>");
	    if (declspecs->noreturn_p)
	      pedwarn (loc, 0, "%<main%> declared %<_Noreturn%>");
	  }
	else
	  {
	    if (declspecs->inline_p)
	      /* Record that the function is declared `inline'.  */
	      DECL_DECLARED_INLINE_P (decl) = 1;
	    if (declspecs->noreturn_p)
	      {
		if (flag_isoc99)
		  pedwarn_c99 (loc, OPT_Wpedantic,
			       "ISO C99 does not support %<_Noreturn%>");
		else
		  pedwarn_c99 (loc, OPT_Wpedantic,
			       "ISO C90 does not support %<_Noreturn%>");
		TREE_THIS_VOLATILE (decl) = 1;
	      }
	  }
      }
    else
      {
	/* It's a variable.  */
	/* An uninitialized decl with `extern' is a reference.  */
	int extern_ref = !initialized && storage_class == csc_extern;

	type = c_build_qualified_type (type, type_quals, orig_qual_type,
				       orig_qual_indirect);

	/* C99 6.2.2p7: It is invalid (compile-time undefined
	   behavior) to create an 'extern' declaration for a
	   variable if there is a global declaration that is
	   'static' and the global declaration is not visible.
	   (If the static declaration _is_ currently visible,
	   the 'extern' declaration is taken to refer to that decl.) */
	if (extern_ref && current_scope != file_scope)
	  {
	    tree global_decl  = identifier_global_value (declarator->u.id.id);
	    tree visible_decl = lookup_name (declarator->u.id.id);

	    if (global_decl
		&& global_decl != visible_decl
		&& VAR_P (global_decl)
		&& !TREE_PUBLIC (global_decl))
	      error_at (loc, "variable previously declared %<static%> "
			"redeclared %<extern%>");
	  }

	decl = build_decl (declarator->id_loc,
			   VAR_DECL, declarator->u.id.id, type);
	if (size_varies)
	  C_DECL_VARIABLE_SIZE (decl) = 1;

	if (declspecs->inline_p)
	  pedwarn (loc, 0, "variable %q+D declared %<inline%>", decl);
	if (declspecs->noreturn_p)
	  pedwarn (loc, 0, "variable %q+D declared %<_Noreturn%>", decl);

	/* At file scope, an initialized extern declaration may follow
	   a static declaration.  In that case, DECL_EXTERNAL will be
	   reset later in start_decl.  */
	DECL_EXTERNAL (decl) = (storage_class == csc_extern);

	/* At file scope, the presence of a `static' or `register' storage
	   class specifier, or the absence of all storage class specifiers
	   makes this declaration a definition (perhaps tentative).  Also,
	   the absence of `static' makes it public.  */
	if (current_scope == file_scope)
	  {
	    TREE_PUBLIC (decl) = storage_class != csc_static;
	    TREE_STATIC (decl) = !extern_ref;
	  }
	/* Not at file scope, only `static' makes a static definition.  */
	else
	  {
	    TREE_STATIC (decl) = (storage_class == csc_static);
	    TREE_PUBLIC (decl) = extern_ref;
	  }

	if (threadp)
	  set_decl_tls_model (decl, decl_default_tls_model (decl));
      }

    if ((storage_class == csc_extern
	 || (storage_class == csc_none
	     && TREE_CODE (type) == FUNCTION_TYPE
	     && !funcdef_flag))
	&& variably_modified_type_p (type, NULL_TREE))
      {
	/* C99 6.7.5.2p2 */
	if (TREE_CODE (type) == FUNCTION_TYPE)
	  error_at (loc, "non-nested function with variably modified type");
	else
	  error_at (loc, "object with variably modified type must have "
	      	    "no linkage");
      }

    /* For nested functions disqualify ones taking VLAs by value
       from inlining since the middle-end cannot deal with this.
       ???  We should arrange for those to be passed by reference
       with emitting the copy on the caller side in the frontend.  */
    if (storage_class == csc_none
	&& TREE_CODE (type) == FUNCTION_TYPE)
      for (tree al = TYPE_ARG_TYPES (type); al; al = TREE_CHAIN (al))
	{
	  tree arg = TREE_VALUE (al);
	  if (arg != error_mark_node
	      && C_TYPE_VARIABLE_SIZE (arg))
	    {
	      DECL_UNINLINABLE (decl) = 1;
	      break;
	    }
	}

    /* Record `register' declaration for warnings on &
       and in case doing stupid register allocation.  */

    if (storage_class == csc_register)
      {
	C_DECL_REGISTER (decl) = 1;
	DECL_REGISTER (decl) = 1;
      }

    /* Record constancy and volatility.  */
    c_apply_type_quals_to_decl (type_quals, decl);

    /* Apply _Alignas specifiers.  */
    if (alignas_align)
      {
	SET_DECL_ALIGN (decl, alignas_align * BITS_PER_UNIT);
	DECL_USER_ALIGN (decl) = 1;
      }

    /* If a type has volatile components, it should be stored in memory.
       Otherwise, the fact that those components are volatile
       will be ignored, and would even crash the compiler.
       Of course, this only makes sense on  VAR,PARM, and RESULT decl's.   */
    if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl))
	&& (VAR_P (decl) ||  TREE_CODE (decl) == PARM_DECL
	  || TREE_CODE (decl) == RESULT_DECL))
      {
	/* It is not an error for a structure with volatile fields to
	   be declared register, but reset DECL_REGISTER since it
	   cannot actually go in a register.  */
	int was_reg = C_DECL_REGISTER (decl);
	C_DECL_REGISTER (decl) = 0;
	DECL_REGISTER (decl) = 0;
	c_mark_addressable (decl);
	C_DECL_REGISTER (decl) = was_reg;
      }

  /* This is the earliest point at which we might know the assembler
     name of a variable.  Thus, if it's known before this, die horribly.  */
    gcc_assert (!HAS_DECL_ASSEMBLER_NAME_P (decl)
		|| !DECL_ASSEMBLER_NAME_SET_P (decl));

    if (warn_cxx_compat
	&& VAR_P (decl)
	&& TREE_PUBLIC (decl)
	&& TREE_STATIC (decl)
	&& (RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
	    || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
	&& TYPE_NAME (TREE_TYPE (decl)) == NULL_TREE)
      warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
		  ("non-local variable %qD with anonymous type is "
		   "questionable in C++"),
		  decl);

    return decl;
  }
}

/* Decode the parameter-list info for a function type or function definition.
   The argument is the value returned by `get_parm_info' (or made in c-parse.c
   if there is an identifier list instead of a parameter decl list).
   These two functions are separate because when a function returns
   or receives functions then each is called multiple times but the order
   of calls is different.  The last call to `grokparms' is always the one
   that contains the formal parameter names of a function definition.

   Return a list of arg types to use in the FUNCTION_TYPE for this function.

   FUNCDEF_FLAG is true for a function definition, false for
   a mere declaration.  A nonempty identifier-list gets an error message
   when FUNCDEF_FLAG is false.  */

static tree
grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
{
  tree arg_types = arg_info->types;

  if (funcdef_flag && arg_info->had_vla_unspec)
    {
      /* A function definition isn't function prototype scope C99 6.2.1p4.  */
      /* C99 6.7.5.2p4 */
      error ("%<[*]%> not allowed in other than function prototype scope");
    }

  if (arg_types == NULL_TREE && !funcdef_flag
      && !in_system_header_at (input_location))
    warning (OPT_Wstrict_prototypes,
	     "function declaration isn%'t a prototype");

  if (arg_types == error_mark_node)
    /* Don't set TYPE_ARG_TYPES in this case.  */
    return NULL_TREE;

  else if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == IDENTIFIER_NODE)
    {
      if (!funcdef_flag)
	{
	  pedwarn (input_location, 0, "parameter names (without types) in "
		   "function declaration");
	  arg_info->parms = NULL_TREE;
	}
      else
	arg_info->parms = arg_info->types;

      arg_info->types = NULL_TREE;
      return NULL_TREE;
    }
  else
    {
      tree parm, type, typelt;
      unsigned int parmno;

      /* In C2X, convert () in a function definition to (void).  */
      if (flag_isoc2x
	  && funcdef_flag
	  && !arg_types
	  && !arg_info->parms)
	arg_types = arg_info->types = void_list_node;

      /* If there is a parameter of incomplete type in a definition,
	 this is an error.  In a declaration this is valid, and a
	 struct or union type may be completed later, before any calls
	 or definition of the function.  In the case where the tag was
	 first declared within the parameter list, a warning has
	 already been given.  If a parameter has void type, then
	 however the function cannot be defined or called, so
	 warn.  */

      for (parm = arg_info->parms, typelt = arg_types, parmno = 1;
	   parm;
	   parm = DECL_CHAIN (parm), typelt = TREE_CHAIN (typelt), parmno++)
	{
	  type = TREE_VALUE (typelt);
	  if (type == error_mark_node)
	    continue;

	  if (!COMPLETE_TYPE_P (type))
	    {
	      if (funcdef_flag)
		{
		  if (DECL_NAME (parm))
		    error_at (input_location,
			      "parameter %u (%q+D) has incomplete type",
			      parmno, parm);
		  else
		    error_at (DECL_SOURCE_LOCATION (parm),
			      "parameter %u has incomplete type",
			      parmno);

		  TREE_VALUE (typelt) = error_mark_node;
		  TREE_TYPE (parm) = error_mark_node;
		  arg_types = NULL_TREE;
		}
	      else if (VOID_TYPE_P (type))
		{
		  if (DECL_NAME (parm))
		    warning_at (input_location, 0,
				"parameter %u (%q+D) has void type",
				parmno, parm);
		  else
		    warning_at (DECL_SOURCE_LOCATION (parm), 0,
				"parameter %u has void type",
				parmno);
		}
	    }

	  if (DECL_NAME (parm) && TREE_USED (parm))
	    warn_if_shadowing (parm);
	}
      return arg_types;
    }
}

/* Allocate and initialize a c_arg_info structure from the parser's
   obstack.  */

struct c_arg_info *
build_arg_info (void)
{
  struct c_arg_info *ret = XOBNEW (&parser_obstack, struct c_arg_info);
  ret->parms = NULL_TREE;
  ret->tags = NULL;
  ret->types = NULL_TREE;
  ret->others = NULL_TREE;
  ret->pending_sizes = NULL;
  ret->had_vla_unspec = 0;
  return ret;
}

/* Take apart the current scope and return a c_arg_info structure with
   info on a parameter list just parsed.

   This structure is later fed to 'grokparms' and 'store_parm_decls'.

   ELLIPSIS being true means the argument list ended in '...' so don't
   append a sentinel (void_list_node) to the end of the type-list.

   EXPR is NULL or an expression that needs to be evaluated for the
   side effects of array size expressions in the parameters.  */

struct c_arg_info *
get_parm_info (bool ellipsis, tree expr)
{
  struct c_binding *b = current_scope->bindings;
  struct c_arg_info *arg_info = build_arg_info ();

  tree parms = NULL_TREE;
  vec<c_arg_tag, va_gc> *tags = NULL;
  tree types = NULL_TREE;
  tree others = NULL_TREE;

  bool gave_void_only_once_err = false;

  arg_info->had_vla_unspec = current_scope->had_vla_unspec;

  /* The bindings in this scope must not get put into a block.
     We will take care of deleting the binding nodes.  */
  current_scope->bindings = 0;

  /* This function is only called if there was *something* on the
     parameter list.  */
  gcc_assert (b);

  /* A parameter list consisting solely of 'void' indicates that the
     function takes no arguments.  But if the 'void' is qualified
     (by 'const' or 'volatile'), or has a storage class specifier
     ('register'), then the behavior is undefined; issue an error.
     Typedefs for 'void' are OK (see DR#157).  */
  if (b->prev == 0			    /* one binding */
      && TREE_CODE (b->decl) == PARM_DECL   /* which is a parameter */
      && !DECL_NAME (b->decl)               /* anonymous */
      && VOID_TYPE_P (TREE_TYPE (b->decl))) /* of void type */
    {
      if (TYPE_QUALS (TREE_TYPE (b->decl)) != TYPE_UNQUALIFIED
	  || C_DECL_REGISTER (b->decl))
	error_at (b->locus, "%<void%> as only parameter may not be qualified");

      /* There cannot be an ellipsis.  */
      if (ellipsis)
	error_at (b->locus, "%<void%> must be the only parameter");

      arg_info->types = void_list_node;
      return arg_info;
    }

  if (!ellipsis)
    types = void_list_node;

  /* Break up the bindings list into parms, tags, types, and others;
     apply sanity checks; purge the name-to-decl bindings.  */
  while (b)
    {
      tree decl = b->decl;
      tree type = TREE_TYPE (decl);
      c_arg_tag tag;
      const char *keyword;

      switch (TREE_CODE (decl))
	{
	case PARM_DECL:
	  if (b->id)
	    {
	      gcc_assert (I_SYMBOL_BINDING (b->id) == b);
	      I_SYMBOL_BINDING (b->id) = b->shadowed;
	    }

	  /* Check for forward decls that never got their actual decl.  */
	  if (TREE_ASM_WRITTEN (decl))
	    error_at (b->locus,
		      "parameter %q+D has just a forward declaration", decl);
	  /* Check for (..., void, ...) and issue an error.  */
	  else if (VOID_TYPE_P (type) && !DECL_NAME (decl))
	    {
	      if (!gave_void_only_once_err)
		{
		  error_at (b->locus, "%<void%> must be the only parameter");
		  gave_void_only_once_err = true;
		}
	    }
	  else
	    {
	      /* Valid parameter, add it to the list.  */
	      DECL_CHAIN (decl) = parms;
	      parms = decl;

	      /* Since there is a prototype, args are passed in their
		 declared types.  The back end may override this later.  */
	      DECL_ARG_TYPE (decl) = type;
	      types = tree_cons (0, type, types);
	    }
	  break;

	case ENUMERAL_TYPE: keyword = "enum"; goto tag;
	case UNION_TYPE:    keyword = "union"; goto tag;
	case RECORD_TYPE:   keyword = "struct"; goto tag;
	tag:
	  /* Types may not have tag-names, in which case the type
	     appears in the bindings list with b->id NULL.  */
	  if (b->id)
	    {
	      gcc_assert (I_TAG_BINDING (b->id) == b);
	      I_TAG_BINDING (b->id) = b->shadowed;
	    }

	  /* Warn about any struct, union or enum tags defined in a
	     parameter list.  The scope of such types is limited to
	     the parameter list, which is rarely if ever desirable
	     (it's impossible to call such a function with type-
	     correct arguments).  An anonymous union parm type is
	     meaningful as a GNU extension, so don't warn for that.  */
	  if (TREE_CODE (decl) != UNION_TYPE || b->id != NULL_TREE)
	    {
	      if (b->id)
		/* The %s will be one of 'struct', 'union', or 'enum'.  */
		warning_at (b->locus, 0,
			    "%<%s %E%> declared inside parameter list"
			    " will not be visible outside of this definition or"
			    " declaration", keyword, b->id);
	      else
		/* The %s will be one of 'struct', 'union', or 'enum'.  */
		warning_at (b->locus, 0,
			    "anonymous %s declared inside parameter list"
			    " will not be visible outside of this definition or"
			    " declaration", keyword);
	    }

	  tag.id = b->id;
	  tag.type = decl;
	  vec_safe_push (tags, tag);
	  break;

	case FUNCTION_DECL:
	  /* FUNCTION_DECLs appear when there is an implicit function
	     declaration in the parameter list.  */
	  gcc_assert (b->nested || seen_error ());
	  goto set_shadowed;

	case CONST_DECL:
	case TYPE_DECL:
	  /* CONST_DECLs appear here when we have an embedded enum,
	     and TYPE_DECLs appear here when we have an embedded struct
	     or union.  No warnings for this - we already warned about the
	     type itself.  */

	  /* When we reinsert this decl in the function body, we need
	     to reconstruct whether it was marked as nested.  */
	  gcc_assert (!b->nested);
	  DECL_CHAIN (decl) = others;
	  others = decl;
	  /* fall through */

	case ERROR_MARK:
	set_shadowed:
	  /* error_mark_node appears here when we have an undeclared
	     variable.  Just throw it away.  */
	  if (b->id)
	    {
	      gcc_assert (I_SYMBOL_BINDING (b->id) == b);
	      I_SYMBOL_BINDING (b->id) = b->shadowed;
	    }
	  break;

	  /* Other things that might be encountered.  */
	case LABEL_DECL:
	case VAR_DECL:
	default:
	  gcc_unreachable ();
	}

      b = free_binding_and_advance (b);
    }

  arg_info->parms = parms;
  arg_info->tags = tags;
  arg_info->types = types;
  arg_info->others = others;
  arg_info->pending_sizes = expr;
  return arg_info;
}

/* Get the struct, enum or union (CODE says which) with tag NAME.
   Define the tag as a forward-reference with location LOC if it is
   not defined.  HAVE_STD_ATTRS says whether any standard attributes
   were present after the struct, union or enum keyword; ATTRS are the
   standard attributes present there.  Return a c_typespec structure
   for the type specifier.  */

struct c_typespec
parser_xref_tag (location_t loc, enum tree_code code, tree name,
		 bool have_std_attrs, tree attrs)
{
  struct c_typespec ret;
  tree ref;
  location_t refloc;

  ret.expr = NULL_TREE;
  ret.expr_const_operands = true;

  /* If a cross reference is requested, look up the type
     already defined for this tag and return it.  */

  ref = lookup_tag (code, name, false, &refloc);
  /* If this is the right type of tag, return what we found.
     (This reference will be shadowed by shadow_tag later if appropriate.)
     If this is the wrong type of tag, do not return it.  If it was the
     wrong type in the same scope, we will have had an error
     message already; if in a different scope and declaring
     a name, pending_xref_error will give an error message; but if in a
     different scope and not declaring a name, this tag should
     shadow the previous declaration of a different type of tag, and
     this would not work properly if we return the reference found.
     (For example, with "struct foo" in an outer scope, "union foo;"
     must shadow that tag with a new one of union type.)  */
  ret.kind = (ref
	      ? (have_std_attrs ? ctsk_tagref_attrs : ctsk_tagref)
	      : (have_std_attrs ? ctsk_tagfirstref_attrs : ctsk_tagfirstref));
  if (ref && TREE_CODE (ref) == code)
    {
      decl_attributes (&ref, attrs, (int) ATTR_FLAG_TYPE_IN_PLACE);
      if (C_TYPE_DEFINED_IN_STRUCT (ref)
	  && loc != UNKNOWN_LOCATION
	  && warn_cxx_compat)
	{
	  switch (code)
	    {
	    case ENUMERAL_TYPE:
	      warning_at (loc, OPT_Wc___compat,
			  ("enum type defined in struct or union "
			   "is not visible in C++"));
	      inform (refloc, "enum type defined here");
	      break;
	    case RECORD_TYPE:
	      warning_at (loc, OPT_Wc___compat,
			  ("struct defined in struct or union "
			   "is not visible in C++"));
	      inform (refloc, "struct defined here");
	      break;
	    case UNION_TYPE:
	      warning_at (loc, OPT_Wc___compat,
			  ("union defined in struct or union "
			   "is not visible in C++"));
	      inform (refloc, "union defined here");
	      break;
	    default:
	      gcc_unreachable();
	    }
	}

      ret.spec = ref;
      return ret;
    }

  /* If no such tag is yet defined, create a forward-reference node
     and record it as the "definition".
     When a real declaration of this type is found,
     the forward-reference will be altered into a real type.  */

  ref = make_node (code);
  if (code == ENUMERAL_TYPE)
    {
      /* Give the type a default layout like unsigned int
	 to avoid crashing if it does not get defined.  */
      SET_TYPE_MODE (ref, TYPE_MODE (unsigned_type_node));
      SET_TYPE_ALIGN (ref, TYPE_ALIGN (unsigned_type_node));
      TYPE_USER_ALIGN (ref) = 0;
      TYPE_UNSIGNED (ref) = 1;
      TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node);
      TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node);
      TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node);
    }

  pushtag (loc, name, ref);
  decl_attributes (&ref, attrs, (int) ATTR_FLAG_TYPE_IN_PLACE);

  ret.spec = ref;
  return ret;
}

/* Get the struct, enum or union (CODE says which) with tag NAME.
   Define the tag as a forward-reference if it is not defined.
   Return a tree for the type.  */

tree
xref_tag (enum tree_code code, tree name)
{
  return parser_xref_tag (input_location, code, name, false, NULL_TREE).spec;
}

/* Make sure that the tag NAME is defined *in the current scope*
   at least as a forward reference.
   LOC is the location of the struct's definition.
   CODE says which kind of tag NAME ought to be.

   This stores the current value of the file static STRUCT_PARSE_INFO
   in *ENCLOSING_STRUCT_PARSE_INFO, and points STRUCT_PARSE_INFO at a
   new c_struct_parse_info structure.  The old value of
   STRUCT_PARSE_INFO is restored in finish_struct.  */

tree
start_struct (location_t loc, enum tree_code code, tree name,
	      class c_struct_parse_info **enclosing_struct_parse_info)
{
  /* If there is already a tag defined at this scope
     (as a forward reference), just return it.  */

  tree ref = NULL_TREE;
  location_t refloc = UNKNOWN_LOCATION;

  if (name != NULL_TREE)
    ref = lookup_tag (code, name, true, &refloc);
  if (ref && TREE_CODE (ref) == code)
    {
      if (TYPE_STUB_DECL (ref))
	refloc = DECL_SOURCE_LOCATION (TYPE_STUB_DECL (ref));

      if (TYPE_SIZE (ref))
	{
	  if (code == UNION_TYPE)
	    error_at (loc, "redefinition of %<union %E%>", name);
	  else
	    error_at (loc, "redefinition of %<struct %E%>", name);
	  if (refloc != UNKNOWN_LOCATION)
	    inform (refloc, "originally defined here");
	  /* Don't create structures using a name already in use.  */
	  ref = NULL_TREE;
	}
      else if (C_TYPE_BEING_DEFINED (ref))
	{
	  if (code == UNION_TYPE)
	    error_at (loc, "nested redefinition of %<union %E%>", name);
	  else
	    error_at (loc, "nested redefinition of %<struct %E%>", name);
	  /* Don't bother to report "originally defined here" for a
	     nested redefinition; the original definition should be
	     obvious.  */
	  /* Don't create structures that contain themselves.  */
	  ref = NULL_TREE;
	}
    }

  /* Otherwise create a forward-reference just so the tag is in scope.  */

  if (ref == NULL_TREE || TREE_CODE (ref) != code)
    {
      ref = make_node (code);
      pushtag (loc, name, ref);
    }

  C_TYPE_BEING_DEFINED (ref) = 1;
  for (tree v = TYPE_MAIN_VARIANT (ref); v; v = TYPE_NEXT_VARIANT (v))
    TYPE_PACKED (v) = flag_pack_struct;

  *enclosing_struct_parse_info = struct_parse_info;
  struct_parse_info = new c_struct_parse_info ();

  /* FIXME: This will issue a warning for a use of a type defined
     within a statement expr used within sizeof, et. al.  This is not
     terribly serious as C++ doesn't permit statement exprs within
     sizeof anyhow.  */
  if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof))
    warning_at (loc, OPT_Wc___compat,
		"defining type in %qs expression is invalid in C++",
		(in_sizeof
		 ? "sizeof"
		 : (in_typeof ? "typeof" : "alignof")));

  return ref;
}

/* Process the specs, declarator and width (NULL if omitted)
   of a structure component, returning a FIELD_DECL node.
   WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node.
   DECL_ATTRS is as for grokdeclarator.

   LOC is the location of the structure component.

   This is done during the parsing of the struct declaration.
   The FIELD_DECL nodes are chained together and the lot of them
   are ultimately passed to `build_struct' to make the RECORD_TYPE node.  */

tree
grokfield (location_t loc,
	   struct c_declarator *declarator, struct c_declspecs *declspecs,
	   tree width, tree *decl_attrs)
{
  tree value;

  if (declarator->kind == cdk_id && declarator->u.id.id == NULL_TREE
      && width == NULL_TREE)
    {
      /* This is an unnamed decl.

	 If we have something of the form "union { list } ;" then this
	 is the anonymous union extension.  Similarly for struct.

	 If this is something of the form "struct foo;", then
	   If MS or Plan 9 extensions are enabled, this is handled as
	     an anonymous struct.
	   Otherwise this is a forward declaration of a structure tag.

	 If this is something of the form "foo;" and foo is a TYPE_DECL, then
	   If foo names a structure or union without a tag, then this
	     is an anonymous struct (this is permitted by C11).
	   If MS or Plan 9 extensions are enabled and foo names a
	     structure, then again this is an anonymous struct.
	   Otherwise this is an error.

	 Oh what a horrid tangled web we weave.  I wonder if MS consciously
	 took this from Plan 9 or if it was an accident of implementation
	 that took root before someone noticed the bug...  */

      tree type = declspecs->type;
      bool ok = false;

      if (RECORD_OR_UNION_TYPE_P (type)
	  && (flag_ms_extensions
	      || flag_plan9_extensions
	      || !declspecs->typedef_p))
	{
	  if (flag_ms_extensions || flag_plan9_extensions)
	    ok = true;
	  else if (TYPE_NAME (type) == NULL)
	    ok = true;
	  else
	    ok = false;
	}
      if (!ok)
	{
	  pedwarn (loc, 0, "declaration does not declare anything");
	  return NULL_TREE;
	}
      if (flag_isoc99)
	pedwarn_c99 (loc, OPT_Wpedantic,
		     "ISO C99 doesn%'t support unnamed structs/unions");
      else
	pedwarn_c99 (loc, OPT_Wpedantic,
		     "ISO C90 doesn%'t support unnamed structs/unions");
    }

  value = grokdeclarator (declarator, declspecs, FIELD, false,
			  width ? &width : NULL, decl_attrs, NULL, NULL,
			  DEPRECATED_NORMAL);

  finish_decl (value, loc, NULL_TREE, NULL_TREE, NULL_TREE);
  DECL_INITIAL (value) = width;
  if (width)
    SET_DECL_C_BIT_FIELD (value);

  if (warn_cxx_compat && DECL_NAME (value) != NULL_TREE)
    {
      /* If we currently have a binding for this field, set the
	 in_struct field in the binding, so that we warn about lookups
	 which find it.  */
      struct c_binding *b = I_SYMBOL_BINDING (DECL_NAME (value));
      if (b != NULL)
	{
	  /* If the in_struct field is not yet set, push it on a list
	     to be cleared when this struct is finished.  */
	  if (!b->in_struct)
	    {
	      struct_parse_info->fields.safe_push (b);
	      b->in_struct = 1;
	    }
	}
    }

  return value;
}

/* Subroutine of detect_field_duplicates: return whether X and Y,
   which are both fields in the same struct, have duplicate field
   names.  */

static bool
is_duplicate_field (tree x, tree y)
{
  if (DECL_NAME (x) != NULL_TREE && DECL_NAME (x) == DECL_NAME (y))
    return true;

  /* When using -fplan9-extensions, an anonymous field whose name is a
     typedef can duplicate a field name.  */
  if (flag_plan9_extensions
      && (DECL_NAME (x) == NULL_TREE || DECL_NAME (y) == NULL_TREE))
    {
      tree xt, xn, yt, yn;

      xt = TREE_TYPE (x);
      if (DECL_NAME (x) != NULL_TREE)
	xn = DECL_NAME (x);
      else if (RECORD_OR_UNION_TYPE_P (xt)
	       && TYPE_NAME (xt) != NULL_TREE
	       && TREE_CODE (TYPE_NAME (xt)) == TYPE_DECL)
	xn = DECL_NAME (TYPE_NAME (xt));
      else
	xn = NULL_TREE;

      yt = TREE_TYPE (y);
      if (DECL_NAME (y) != NULL_TREE)
	yn = DECL_NAME (y);
      else if (RECORD_OR_UNION_TYPE_P (yt)
	       && TYPE_NAME (yt) != NULL_TREE
	       && TREE_CODE (TYPE_NAME (yt)) == TYPE_DECL)
	yn = DECL_NAME (TYPE_NAME (yt));
      else
	yn = NULL_TREE;

      if (xn != NULL_TREE && xn == yn)
	return true;
    }

  return false;
}

/* Subroutine of detect_field_duplicates: add the fields of FIELDLIST
   to HTAB, giving errors for any duplicates.  */

static void
detect_field_duplicates_hash (tree fieldlist,
			      hash_table<nofree_ptr_hash <tree_node> > *htab)
{
  tree x, y;
  tree_node **slot;

  for (x = fieldlist; x ; x = DECL_CHAIN (x))
    if ((y = DECL_NAME (x)) != NULL_TREE)
      {
	slot = htab->find_slot (y, INSERT);
	if (*slot)
	  {
	    error ("duplicate member %q+D", x);
	    DECL_NAME (x) = NULL_TREE;
	  }
	*slot = y;
      }
    else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (x)))
      {
	detect_field_duplicates_hash (TYPE_FIELDS (TREE_TYPE (x)), htab);

	/* When using -fplan9-extensions, an anonymous field whose
	   name is a typedef can duplicate a field name.  */
	if (flag_plan9_extensions
	    && TYPE_NAME (TREE_TYPE (x)) != NULL_TREE
	    && TREE_CODE (TYPE_NAME (TREE_TYPE (x))) == TYPE_DECL)
	  {
	    tree xn = DECL_NAME (TYPE_NAME (TREE_TYPE (x)));
	    slot = htab->find_slot (xn, INSERT);
	    if (*slot)
	      error ("duplicate member %q+D", TYPE_NAME (TREE_TYPE (x)));
	    *slot = xn;
	  }
      }
}

/* Generate an error for any duplicate field names in FIELDLIST.  Munge
   the list such that this does not present a problem later.  */

static void
detect_field_duplicates (tree fieldlist)
{
  tree x, y;
  int timeout = 10;

  /* If the struct is the list of instance variables of an Objective-C
     class, then we need to check all the instance variables of
     superclasses when checking for duplicates (since you can't have
     an instance variable in a subclass with the same name as an
     instance variable in a superclass).  We pass on this job to the
     Objective-C compiler.  objc_detect_field_duplicates() will return
     false if we are not checking the list of instance variables and
     the C frontend should proceed with the standard field duplicate
     checks.  If we are checking the list of instance variables, the
     ObjC frontend will do the check, emit the errors if needed, and
     then return true.  */
  if (c_dialect_objc ())
    if (objc_detect_field_duplicates (false))
      return;

  /* First, see if there are more than "a few" fields.
     This is trivially true if there are zero or one fields.  */
  if (!fieldlist || !DECL_CHAIN (fieldlist))
    return;
  x = fieldlist;
  do {
    timeout--;
    if (DECL_NAME (x) == NULL_TREE
	&& RECORD_OR_UNION_TYPE_P (TREE_TYPE (x)))
      timeout = 0;
    x = DECL_CHAIN (x);
  } while (timeout > 0 && x);

  /* If there were "few" fields and no anonymous structures or unions,
     avoid the overhead of allocating a hash table.  Instead just do
     the nested traversal thing.  */
  if (timeout > 0)
    {
      for (x = DECL_CHAIN (fieldlist); x; x = DECL_CHAIN (x))
	/* When using -fplan9-extensions, we can have duplicates
	   between typedef names and fields.  */
	if (DECL_NAME (x)
	    || (flag_plan9_extensions
		&& DECL_NAME (x) == NULL_TREE
		&& RECORD_OR_UNION_TYPE_P (TREE_TYPE (x))
		&& TYPE_NAME (TREE_TYPE (x)) != NULL_TREE
		&& TREE_CODE (TYPE_NAME (TREE_TYPE (x))) == TYPE_DECL))
	  {
	    for (y = fieldlist; y != x; y = TREE_CHAIN (y))
	      if (is_duplicate_field (y, x))
		{
		  error ("duplicate member %q+D", x);
		  DECL_NAME (x) = NULL_TREE;
		}
	  }
    }
  else
    {
      hash_table<nofree_ptr_hash <tree_node> > htab (37);
      detect_field_duplicates_hash (fieldlist, &htab);
    }
}

/* Finish up struct info used by -Wc++-compat.  */

static void
warn_cxx_compat_finish_struct (tree fieldlist, enum tree_code code,
			       location_t record_loc)
{
  unsigned int ix;
  tree x;
  struct c_binding *b;

  if (fieldlist == NULL_TREE)
    {
      if (code == RECORD_TYPE)
	warning_at (record_loc, OPT_Wc___compat,
		    "empty struct has size 0 in C, size 1 in C++");
      else
	warning_at (record_loc, OPT_Wc___compat,
		    "empty union has size 0 in C, size 1 in C++");
    }

  /* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in
     the current struct.  We do this now at the end of the struct
     because the flag is used to issue visibility warnings, and we
     only want to issue those warnings if the type is referenced
     outside of the struct declaration.  */
  FOR_EACH_VEC_ELT (struct_parse_info->struct_types, ix, x)
    C_TYPE_DEFINED_IN_STRUCT (x) = 1;

  /* The TYPEDEFS_SEEN field of STRUCT_PARSE_INFO is a list of
     typedefs used when declaring fields in this struct.  If the name
     of any of the fields is also a typedef name then the struct would
     not parse in C++, because the C++ lookup rules say that the
     typedef name would be looked up in the context of the struct, and
     would thus be the field rather than the typedef.  */
  if (!struct_parse_info->typedefs_seen.is_empty ()
      && fieldlist != NULL_TREE)
    {
      /* Use a hash_set<tree> using the name of the typedef.  We can use
	 a hash_set<tree> because identifiers are interned.  */
      hash_set<tree> tset;

      FOR_EACH_VEC_ELT (struct_parse_info->typedefs_seen, ix, x)
	tset.add (DECL_NAME (x));

      for (x = fieldlist; x != NULL_TREE; x = DECL_CHAIN (x))
	{
	  if (DECL_NAME (x) != NULL_TREE
	      && tset.contains (DECL_NAME (x)))
	    {
	      warning_at (DECL_SOURCE_LOCATION (x), OPT_Wc___compat,
			  ("using %qD as both field and typedef name is "
			   "invalid in C++"),
			  x);
	      /* FIXME: It would be nice to report the location where
		 the typedef name is used.  */
	    }
	}
    }

  /* For each field which has a binding and which was not defined in
     an enclosing struct, clear the in_struct field.  */
  FOR_EACH_VEC_ELT (struct_parse_info->fields, ix, b)
    b->in_struct = 0;
}

/* Function to help qsort sort FIELD_DECLs by name order.  */

static int
field_decl_cmp (const void *x_p, const void *y_p)
{
  const tree *const x = (const tree *) x_p;
  const tree *const y = (const tree *) y_p;

  if (DECL_NAME (*x) == DECL_NAME (*y))
    /* A nontype is "greater" than a type.  */
    return (TREE_CODE (*y) == TYPE_DECL) - (TREE_CODE (*x) == TYPE_DECL);
  if (DECL_NAME (*x) == NULL_TREE)
    return -1;
  if (DECL_NAME (*y) == NULL_TREE)
    return 1;
  if (DECL_NAME (*x) < DECL_NAME (*y))
    return -1;
  return 1;
}

/* If this structure or union completes the type of any previous
   variable declaration, lay it out and output its rtl.  */
static void
finish_incomplete_vars (tree incomplete_vars, bool toplevel)
{
  for (tree x = incomplete_vars; x; x = TREE_CHAIN (x))
    {
      tree decl = TREE_VALUE (x);
      if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
	layout_array_type (TREE_TYPE (decl));
      if (TREE_CODE (decl) != TYPE_DECL)
	{
	  relayout_decl (decl);
	  if (c_dialect_objc ())
	    objc_check_decl (decl);
	  rest_of_decl_compilation (decl, toplevel, 0);
	}
    }
}

/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
   LOC is the location of the RECORD_TYPE or UNION_TYPE's definition.
   FIELDLIST is a chain of FIELD_DECL nodes for the fields.
   ATTRIBUTES are attributes to be applied to the structure.

   ENCLOSING_STRUCT_PARSE_INFO is the value of STRUCT_PARSE_INFO when
   the struct was started.  */

tree
finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
	       class c_struct_parse_info *enclosing_struct_parse_info)
{
  tree x;
  bool toplevel = file_scope == current_scope;

  /* If this type was previously laid out as a forward reference,
     make sure we lay it out again.  */

  TYPE_SIZE (t) = NULL_TREE;

  decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);

  if (pedantic)
    {
      for (x = fieldlist; x; x = DECL_CHAIN (x))
	{
	  if (DECL_NAME (x) != NULL_TREE)
	    break;
	  if (flag_isoc11 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (x)))
	    break;
	}

      if (x == NULL_TREE)
	{
	  if (TREE_CODE (t) == UNION_TYPE)
	    {
	      if (fieldlist)
		pedwarn (loc, OPT_Wpedantic, "union has no named members");
	      else
		pedwarn (loc, OPT_Wpedantic, "union has no members");
	    }
	  else
	    {
	      if (fieldlist)
		pedwarn (loc, OPT_Wpedantic, "struct has no named members");
	      else
		pedwarn (loc, OPT_Wpedantic, "struct has no members");
	    }
	}
    }

  /* Install struct as DECL_CONTEXT of each field decl.
     Also process specified field sizes, found in the DECL_INITIAL,
     storing 0 there after the type has been changed to precision equal
     to its width, rather than the precision of the specified standard
     type.  (Correct layout requires the original type to have been preserved
     until now.)  */

  bool saw_named_field = false;
  for (x = fieldlist; x; x = DECL_CHAIN (x))
    {
      if (TREE_TYPE (x) == error_mark_node)
	continue;

      DECL_CONTEXT (x) = t;

      /* If any field is const, the structure type is pseudo-const.  */
      if (TREE_READONLY (x))
	C_TYPE_FIELDS_READONLY (t) = 1;
      else
	{
	  /* A field that is pseudo-const makes the structure likewise.  */
	  tree t1 = strip_array_types (TREE_TYPE (x));
	  if (RECORD_OR_UNION_TYPE_P (t1) && C_TYPE_FIELDS_READONLY (t1))
	    C_TYPE_FIELDS_READONLY (t) = 1;
	}

      /* Any field that is volatile means variables of this type must be
	 treated in some ways as volatile.  */
      if (TREE_THIS_VOLATILE (x))
	C_TYPE_FIELDS_VOLATILE (t) = 1;

      /* Any field of nominal variable size implies structure is too.  */
      if (C_DECL_VARIABLE_SIZE (x))
	C_TYPE_VARIABLE_SIZE (t) = 1;

      if (DECL_C_BIT_FIELD (x))
	{
	  unsigned HOST_WIDE_INT width = tree_to_uhwi (DECL_INITIAL (x));
	  DECL_SIZE (x) = bitsize_int (width);
	  DECL_BIT_FIELD (x) = 1;
	}

      if (TYPE_PACKED (t)
	  && (DECL_BIT_FIELD (x)
	      || TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT))
	DECL_PACKED (x) = 1;

      /* Detect flexible array member in an invalid context.  */
      if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
	  && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
	  && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE
	  && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
	{
	  if (TREE_CODE (t) == UNION_TYPE)
	    {
	      error_at (DECL_SOURCE_LOCATION (x),
			"flexible array member in union");
	      TREE_TYPE (x) = error_mark_node;
	    }
	  else if (DECL_CHAIN (x) != NULL_TREE)
	    {
	      error_at (DECL_SOURCE_LOCATION (x),
			"flexible array member not at end of struct");
	      TREE_TYPE (x) = error_mark_node;
	    }
	  else if (!saw_named_field)
	    {
	      error_at (DECL_SOURCE_LOCATION (x),
			"flexible array member in a struct with no named "
			"members");
	      TREE_TYPE (x) = error_mark_node;
	    }
	}

      if (pedantic && TREE_CODE (t) == RECORD_TYPE
	  && flexible_array_type_p (TREE_TYPE (x)))
	pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
		 "invalid use of structure with flexible array member");

      if (DECL_NAME (x)
	  || RECORD_OR_UNION_TYPE_P (TREE_TYPE (x)))
	saw_named_field = true;
    }

  detect_field_duplicates (fieldlist);

  /* Now we have the nearly final fieldlist.  Record it,
     then lay out the structure or union (including the fields).  */

  TYPE_FIELDS (t) = fieldlist;

  maybe_apply_pragma_scalar_storage_order (t);

  layout_type (t);

  if (TYPE_SIZE_UNIT (t)
      && TREE_CODE (TYPE_SIZE_UNIT (t)) == INTEGER_CST
      && !TREE_OVERFLOW (TYPE_SIZE_UNIT (t))
      && !valid_constant_size_p (TYPE_SIZE_UNIT (t)))
    error ("type %qT is too large", t);

  /* Give bit-fields their proper types and rewrite the type of array fields
     with scalar component if the enclosing type has reverse storage order.  */
  for (tree field = fieldlist; field; field = DECL_CHAIN (field))
    {
      if (TREE_CODE (field) == FIELD_DECL
	  && DECL_INITIAL (field)
	  && TREE_TYPE (field) != error_mark_node)
	{
	  unsigned HOST_WIDE_INT width
	    = tree_to_uhwi (DECL_INITIAL (field));
	  tree type = TREE_TYPE (field);
	  if (width != TYPE_PRECISION (type))
	    {
	      TREE_TYPE (field)
		= c_build_bitfield_integer_type (width, TYPE_UNSIGNED (type));
	      SET_DECL_MODE (field, TYPE_MODE (TREE_TYPE (field)));
	    }
	  DECL_INITIAL (field) = NULL_TREE;
	}
      else if (TYPE_REVERSE_STORAGE_ORDER (t)
	       && TREE_CODE (field) == FIELD_DECL
	       && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
	{
	  tree ftype = TREE_TYPE (field);
	  tree ctype = strip_array_types (ftype);
	  if (!RECORD_OR_UNION_TYPE_P (ctype) && TYPE_MODE (ctype) != QImode)
	    {
	      tree fmain_type = TYPE_MAIN_VARIANT (ftype);
	      tree *typep = &fmain_type;
	      do {
		*typep = build_distinct_type_copy (*typep);
		TYPE_REVERSE_STORAGE_ORDER (*typep) = 1;
		typep = &TREE_TYPE (*typep);
	      } while (TREE_CODE (*typep) == ARRAY_TYPE);
	      TREE_TYPE (field)
		= c_build_qualified_type (fmain_type, TYPE_QUALS (ftype));
	    }
	}

      /* Warn on problematic type punning for storage order purposes.  */
      if (TREE_CODE (t) == UNION_TYPE
	  && TREE_CODE (field) == FIELD_DECL
	  && AGGREGATE_TYPE_P (TREE_TYPE (field)))
	{
	  tree ftype = TREE_TYPE (field);
	  if (TREE_CODE (ftype) == ARRAY_TYPE)
	    ftype = strip_array_types (ftype);
	  if (RECORD_OR_UNION_TYPE_P (ftype)
	      && TYPE_REVERSE_STORAGE_ORDER (ftype)
		 != TYPE_REVERSE_STORAGE_ORDER (t))
	    warning_at (DECL_SOURCE_LOCATION (field),
			OPT_Wscalar_storage_order,
			"type punning toggles scalar storage order");
	}
    }

  /* Now we have the truly final field list.
     Store it in this type and in the variants.  */

  TYPE_FIELDS (t) = fieldlist;

  /* If there are lots of fields, sort so we can look through them fast.
     We arbitrarily consider 16 or more elts to be "a lot".  */

  {
    int len = 0;

    for (x = fieldlist; x; x = DECL_CHAIN (x))
      {
	if (len > 15 || DECL_NAME (x) == NULL)
	  break;
	len += 1;
      }

    if (len > 15)
      {
	tree *field_array;
	struct lang_type *space;
	struct sorted_fields_type *space2;

	len += list_length (x);

	/* Use the same allocation policy here that make_node uses, to
	  ensure that this lives as long as the rest of the struct decl.
	  All decls in an inline function need to be saved.  */

	space = ggc_cleared_alloc<struct lang_type> ();
	space2 = (sorted_fields_type *) ggc_internal_alloc
	  (sizeof (struct sorted_fields_type) + len * sizeof (tree));

	len = 0;
	space->s = space2;
	field_array = &space2->elts[0];
	for (x = fieldlist; x; x = DECL_CHAIN (x))
	  {
	    field_array[len++] = x;

	    /* If there is anonymous struct or union, break out of the loop.  */
	    if (DECL_NAME (x) == NULL)
	      break;
	  }
	/* Found no anonymous struct/union.  Add the TYPE_LANG_SPECIFIC.  */
	if (x == NULL)
	  {
	    TYPE_LANG_SPECIFIC (t) = space;
	    TYPE_LANG_SPECIFIC (t)->s->len = len;
	    field_array = TYPE_LANG_SPECIFIC (t)->s->elts;
	    qsort (field_array, len, sizeof (tree), field_decl_cmp);
	  }
      }
  }

  /* If this was supposed to be a transparent union, but we can't
     make it one, warn and turn off the flag.  */
  if (TREE_CODE (t) == UNION_TYPE
      && TYPE_TRANSPARENT_AGGR (t)
      && (!TYPE_FIELDS (t) || TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t))))
    {
      TYPE_TRANSPARENT_AGGR (t) = 0;
      warning_at (loc, 0, "union cannot be made transparent");
    }

  tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
  for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
    {
      TYPE_FIELDS (x) = TYPE_FIELDS (t);
      TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
      TYPE_TRANSPARENT_AGGR (x) = TYPE_TRANSPARENT_AGGR (t);
      C_TYPE_FIELDS_READONLY (x) = C_TYPE_FIELDS_READONLY (t);
      C_TYPE_FIELDS_VOLATILE (x) = C_TYPE_FIELDS_VOLATILE (t);
      C_TYPE_VARIABLE_SIZE (x) = C_TYPE_VARIABLE_SIZE (t);
      C_TYPE_INCOMPLETE_VARS (x) = NULL_TREE;
    }

  /* Update type location to the one of the definition, instead of e.g.
     a forward declaration.  */
  if (TYPE_STUB_DECL (t))
    DECL_SOURCE_LOCATION (TYPE_STUB_DECL (t)) = loc;

  /* Finish debugging output for this type.  */
  rest_of_type_compilation (t, toplevel);

  finish_incomplete_vars (incomplete_vars, toplevel);

  /* If we're inside a function proper, i.e. not file-scope and not still
     parsing parameters, then arrange for the size of a variable sized type
     to be bound now.  */
  if (building_stmt_list_p () && variably_modified_type_p (t, NULL_TREE))
    add_stmt (build_stmt (loc,
			  DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t)));

  if (warn_cxx_compat)
    warn_cxx_compat_finish_struct (fieldlist, TREE_CODE (t), loc);

  delete struct_parse_info;

  struct_parse_info = enclosing_struct_parse_info;

  /* If this struct is defined inside a struct, add it to
     struct_types.  */
  if (warn_cxx_compat
      && struct_parse_info != NULL
      && !in_sizeof && !in_typeof && !in_alignof)
    struct_parse_info->struct_types.safe_push (t);

  return t;
}

static struct {
  gt_pointer_operator new_value;
  void *cookie;
} resort_data;

/* This routine compares two fields like field_decl_cmp but using the
pointer operator in resort_data.  */

static int
resort_field_decl_cmp (const void *x_p, const void *y_p)
{
  const tree *const x = (const tree *) x_p;
  const tree *const y = (const tree *) y_p;

  if (DECL_NAME (*x) == DECL_NAME (*y))
    /* A nontype is "greater" than a type.  */
    return (TREE_CODE (*y) == TYPE_DECL) - (TREE_CODE (*x) == TYPE_DECL);
  if (DECL_NAME (*x) == NULL_TREE)
    return -1;
  if (DECL_NAME (*y) == NULL_TREE)
    return 1;
  {
    tree d1 = DECL_NAME (*x);
    tree d2 = DECL_NAME (*y);
    resort_data.new_value (&d1, resort_data.cookie);
    resort_data.new_value (&d2, resort_data.cookie);
    if (d1 < d2)
      return -1;
  }
  return 1;
}

/* Resort DECL_SORTED_FIELDS because pointers have been reordered.  */

void
resort_sorted_fields (void *obj,
		      void * ARG_UNUSED (orig_obj),
		      gt_pointer_operator new_value,
		      void *cookie)
{
  struct sorted_fields_type *sf = (struct sorted_fields_type *) obj;
  resort_data.new_value = new_value;
  resort_data.cookie = cookie;
  qsort (&sf->elts[0], sf->len, sizeof (tree),
	 resort_field_decl_cmp);
}

/* Lay out the type T, and its element type, and so on.  */

static void
layout_array_type (tree t)
{
  if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
    layout_array_type (TREE_TYPE (t));
  layout_type (t);
}

/* Begin compiling the definition of an enumeration type.
   NAME is its name (or null if anonymous).
   LOC is the enum's location.
   Returns the type object, as yet incomplete.
   Also records info about it so that build_enumerator
   may be used to declare the individual values as they are read.  */

tree
start_enum (location_t loc, struct c_enum_contents *the_enum, tree name)
{
  tree enumtype = NULL_TREE;
  location_t enumloc = UNKNOWN_LOCATION;

  /* If this is the real definition for a previous forward reference,
     fill in the contents in the same object that used to be the
     forward reference.  */

  if (name != NULL_TREE)
    enumtype = lookup_tag (ENUMERAL_TYPE, name, true, &enumloc);

  if (enumtype == NULL_TREE || TREE_CODE (enumtype) != ENUMERAL_TYPE)
    {
      enumtype = make_node (ENUMERAL_TYPE);
      pushtag (loc, name, enumtype);
    }
  /* Update type location to the one of the definition, instead of e.g.
     a forward declaration.  */
  else if (TYPE_STUB_DECL (enumtype))
    {
      enumloc = DECL_SOURCE_LOCATION (TYPE_STUB_DECL (enumtype));
      DECL_SOURCE_LOCATION (TYPE_STUB_DECL (enumtype)) = loc;
    }

  if (C_TYPE_BEING_DEFINED (enumtype))
    error_at (loc, "nested redefinition of %<enum %E%>", name);

  C_TYPE_BEING_DEFINED (enumtype) = 1;

  if (TYPE_VALUES (enumtype) != NULL_TREE)
    {
      /* This enum is a named one that has been declared already.  */
      error_at (loc, "redeclaration of %<enum %E%>", name);
      if (enumloc != UNKNOWN_LOCATION)
	inform (enumloc, "originally defined here");

      /* Completely replace its old definition.
	 The old enumerators remain defined, however.  */
      TYPE_VALUES (enumtype) = NULL_TREE;
    }

  the_enum->enum_next_value = integer_zero_node;
  the_enum->enum_overflow = 0;

  if (flag_short_enums)
    for (tree v = TYPE_MAIN_VARIANT (enumtype); v; v = TYPE_NEXT_VARIANT (v))
      TYPE_PACKED (v) = 1;

  /* FIXME: This will issue a warning for a use of a type defined
     within sizeof in a statement expr.  This is not terribly serious
     as C++ doesn't permit statement exprs within sizeof anyhow.  */
  if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof))
    warning_at (loc, OPT_Wc___compat,
		"defining type in %qs expression is invalid in C++",
		(in_sizeof
		 ? "sizeof"
		 : (in_typeof ? "typeof" : "alignof")));

  return enumtype;
}

/* After processing and defining all the values of an enumeration type,
   install their decls in the enumeration type and finish it off.
   ENUMTYPE is the type object, VALUES a list of decl-value pairs,
   and ATTRIBUTES are the specified attributes.
   Returns ENUMTYPE.  */

tree
finish_enum (tree enumtype, tree values, tree attributes)
{
  tree pair, tem;
  tree minnode = NULL_TREE, maxnode = NULL_TREE;
  int precision;
  signop sign;
  bool toplevel = (file_scope == current_scope);
  struct lang_type *lt;

  decl_attributes (&enumtype, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);

  /* Calculate the maximum value of any enumerator in this type.  */

  if (values == error_mark_node)
    minnode = maxnode = integer_zero_node;
  else
    {
      minnode = maxnode = TREE_VALUE (values);
      for (pair = TREE_CHAIN (values); pair; pair = TREE_CHAIN (pair))
	{
	  tree value = TREE_VALUE (pair);
	  if (tree_int_cst_lt (maxnode, value))
	    maxnode = value;
	  if (tree_int_cst_lt (value, minnode))
	    minnode = value;
	}
    }

  /* Construct the final type of this enumeration.  It is the same
     as one of the integral types - the narrowest one that fits, except
     that normally we only go as narrow as int - and signed iff any of
     the values are negative.  */
  sign = (tree_int_cst_sgn (minnode) >= 0) ? UNSIGNED : SIGNED;
  precision = MAX (tree_int_cst_min_precision (minnode, sign),
		   tree_int_cst_min_precision (maxnode, sign));

  /* If the precision of the type was specified with an attribute and it
     was too small, give an error.  Otherwise, use it.  */
  if (TYPE_PRECISION (enumtype) && lookup_attribute ("mode", attributes))
    {
      if (precision > TYPE_PRECISION (enumtype))
	{
	  TYPE_PRECISION (enumtype) = 0;
	  error ("specified mode too small for enumerated values");
	}
      else
	precision = TYPE_PRECISION (enumtype);
    }
  else
    TYPE_PRECISION (enumtype) = 0;

  if (TYPE_PACKED (enumtype)
      || precision > TYPE_PRECISION (integer_type_node)
      || TYPE_PRECISION (enumtype))
    {
      tem = c_common_type_for_size (precision, sign == UNSIGNED ? 1 : 0);
      if (tem == NULL)
	{
	  warning (0, "enumeration values exceed range of largest integer");
	  tem = long_long_integer_type_node;
	}
    }
  else
    tem = sign == UNSIGNED ? unsigned_type_node : integer_type_node;

  TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (tem);
  TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem);
  TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (tem);
  SET_TYPE_ALIGN (enumtype, TYPE_ALIGN (tem));
  TYPE_SIZE (enumtype) = NULL_TREE;
  TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem);

  layout_type (enumtype);

  if (values != error_mark_node)
    {
      /* Change the type of the enumerators to be the enum type.  We
	 need to do this irrespective of the size of the enum, for
	 proper type checking.  Replace the DECL_INITIALs of the
	 enumerators, and the value slots of the list, with copies
	 that have the enum type; they cannot be modified in place
	 because they may be shared (e.g.  integer_zero_node) Finally,
	 change the purpose slots to point to the names of the decls.  */
      for (pair = values; pair; pair = TREE_CHAIN (pair))
	{
	  tree enu = TREE_PURPOSE (pair);
	  tree ini = DECL_INITIAL (enu);

	  TREE_TYPE (enu) = enumtype;

	  /* The ISO C Standard mandates enumerators to have type int,
	     even though the underlying type of an enum type is
	     unspecified.  However, GCC allows enumerators of any
	     integer type as an extensions.  build_enumerator()
	     converts any enumerators that fit in an int to type int,
	     to avoid promotions to unsigned types when comparing
	     integers with enumerators that fit in the int range.
	     When -pedantic is given, build_enumerator() would have
	     already warned about those that don't fit. Here we
	     convert the rest to the enumerator type. */
	  if (TREE_TYPE (ini) != integer_type_node)
	    ini = convert (enumtype, ini);

	  DECL_INITIAL (enu) = ini;
	  TREE_PURPOSE (pair) = DECL_NAME (enu);
	  TREE_VALUE (pair) = ini;
	}

      TYPE_VALUES (enumtype) = values;
    }

  /* Record the min/max values so that we can warn about bit-field
     enumerations that are too small for the values.  */
  lt = ggc_cleared_alloc<struct lang_type> ();
  lt->enum_min = minnode;
  lt->enum_max = maxnode;
  TYPE_LANG_SPECIFIC (enumtype) = lt;

  /* Fix up all variant types of this enum type.  */
  tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (enumtype));
  for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem))
    {
      C_TYPE_INCOMPLETE_VARS (tem) = NULL_TREE;
      if (tem == enumtype)
	continue;
      TYPE_VALUES (tem) = TYPE_VALUES (enumtype);
      TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype);
      TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype);
      TYPE_SIZE (tem) = TYPE_SIZE (enumtype);
      TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype);
      SET_TYPE_MODE (tem, TYPE_MODE (enumtype));
      TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
      SET_TYPE_ALIGN (tem, TYPE_ALIGN (enumtype));
      TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype);
      TYPE_UNSIGNED (tem) = TYPE_UNSIGNED (enumtype);
      TYPE_LANG_SPECIFIC (tem) = TYPE_LANG_SPECIFIC (enumtype);
    }

  /* Finish debugging output for this type.  */
  rest_of_type_compilation (enumtype, toplevel);

  finish_incomplete_vars (incomplete_vars, toplevel);

  /* If this enum is defined inside a struct, add it to
     struct_types.  */
  if (warn_cxx_compat
      && struct_parse_info != NULL
      && !in_sizeof && !in_typeof && !in_alignof)
    struct_parse_info->struct_types.safe_push (enumtype);

  C_TYPE_BEING_DEFINED (enumtype) = 0;

  return enumtype;
}

/* Build and install a CONST_DECL for one value of the
   current enumeration type (one that was begun with start_enum).
   DECL_LOC is the location of the enumerator.
   LOC is the location of the '=' operator if any, DECL_LOC otherwise.
   Return a tree-list containing the CONST_DECL and its value.
   Assignment of sequential values by default is handled here.  */

tree
build_enumerator (location_t decl_loc, location_t loc,
		  struct c_enum_contents *the_enum, tree name, tree value)
{
  tree decl, type;

  /* Validate and default VALUE.  */

  if (value != NULL_TREE)
    {
      /* Don't issue more errors for error_mark_node (i.e. an
	 undeclared identifier) - just ignore the value expression.  */
      if (value == error_mark_node)
	value = NULL_TREE;
      else if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
	{
	  error_at (loc, "enumerator value for %qE is not an integer constant",
		    name);
	  value = NULL_TREE;
	}
      else
	{
	  if (TREE_CODE (value) != INTEGER_CST)
	    {
	      value = c_fully_fold (value, false, NULL);
	      if (TREE_CODE (value) == INTEGER_CST)
		pedwarn (loc, OPT_Wpedantic,
			 "enumerator value for %qE is not an integer "
			 "constant expression", name);
	    }
	  if (TREE_CODE (value) != INTEGER_CST)
	    {
	      error ("enumerator value for %qE is not an integer constant",
		     name);
	      value = NULL_TREE;
	    }
	  else
	    {
	      value = default_conversion (value);
	      constant_expression_warning (value);
	    }
	}
    }

  /* Default based on previous value.  */
  /* It should no longer be possible to have NON_LVALUE_EXPR
     in the default.  */
  if (value == NULL_TREE)
    {
      value = the_enum->enum_next_value;
      if (the_enum->enum_overflow)
	error_at (loc, "overflow in enumeration values");
    }
  /* Even though the underlying type of an enum is unspecified, the
     type of enumeration constants is explicitly defined as int
     (6.4.4.3/2 in the C99 Standard).  GCC allows any integer type as
     an extension.  */
  else if (!int_fits_type_p (value, integer_type_node))
    pedwarn (loc, OPT_Wpedantic,
	     "ISO C restricts enumerator values to range of %<int%>");

  /* The ISO C Standard mandates enumerators to have type int, even
     though the underlying type of an enum type is unspecified.
     However, GCC allows enumerators of any integer type as an
     extensions.  Here we convert any enumerators that fit in an int
     to type int, to avoid promotions to unsigned types when comparing
     integers with enumerators that fit in the int range.  When
     -pedantic is given, we would have already warned about those that
     don't fit. We have to do this here rather than in finish_enum
     because this value may be used to define more enumerators.  */
  if (int_fits_type_p (value, integer_type_node))
    value = convert (integer_type_node, value);

  /* Set basis for default for next value.  */
  the_enum->enum_next_value
    = build_binary_op (EXPR_LOC_OR_LOC (value, input_location),
		       PLUS_EXPR, value, integer_one_node, false);
  the_enum->enum_overflow = tree_int_cst_lt (the_enum->enum_next_value, value);

  /* Now create a declaration for the enum value name.  */

  type = TREE_TYPE (value);
  type = c_common_type_for_size (MAX (TYPE_PRECISION (type),
				      TYPE_PRECISION (integer_type_node)),
				 (TYPE_PRECISION (type)
				  >= TYPE_PRECISION (integer_type_node)
				  && TYPE_UNSIGNED (type)));

  decl = build_decl (decl_loc, CONST_DECL, name, type);
  DECL_INITIAL (decl) = convert (type, value);
  pushdecl (decl);

  return tree_cons (decl, value, NULL_TREE);
}

/* Implement LANG_HOOKS_SIMULATE_ENUM_DECL.  */

tree
c_simulate_enum_decl (location_t loc, const char *name,
		      vec<string_int_pair> *values_ptr)
{
  location_t saved_loc = input_location;
  input_location = loc;

  struct c_enum_contents the_enum;
  tree enumtype = start_enum (loc, &the_enum, get_identifier (name));

  tree value_chain = NULL_TREE;
  string_int_pair *value;
  vec<string_int_pair> values = *values_ptr;
  unsigned int i;
  FOR_EACH_VEC_ELT (values, i, value)
    {
      tree decl = build_enumerator (loc, loc, &the_enum,
				    get_identifier (value->first),
				    build_int_cst (integer_type_node,
						   value->second));
      TREE_CHAIN (decl) = value_chain;
      value_chain = decl;
    }

  finish_enum (enumtype, nreverse (value_chain), NULL_TREE);

  input_location = saved_loc;
  return enumtype;
}

/* Create the FUNCTION_DECL for a function definition.
   DECLSPECS, DECLARATOR and ATTRIBUTES are the parts of
   the declaration; they describe the function's name and the type it returns,
   but twisted together in a fashion that parallels the syntax of C.

   This function creates a binding context for the function body
   as well as setting up the FUNCTION_DECL in current_function_decl.

   Returns true on success.  If the DECLARATOR is not suitable for a function
   (it defines a datum instead), we return false to report a parse error.  */

bool
start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
		tree attributes)
{
  tree decl1, old_decl;
  tree restype, resdecl;
  location_t loc;

  current_function_returns_value = 0;  /* Assume, until we see it does.  */
  current_function_returns_null = 0;
  current_function_returns_abnormally = 0;
  warn_about_return_type = 0;
  c_switch_stack = NULL;

  /* Indicate no valid break/continue context.  */
  in_statement = 0;

  decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, true, NULL,
			  &attributes, NULL, NULL, DEPRECATED_NORMAL);
  invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1);

  /* If the declarator is not suitable for a function definition,
     cause a syntax error.  */
  if (decl1 == NULL_TREE
      || TREE_CODE (decl1) != FUNCTION_DECL)
    return false;

  loc = DECL_SOURCE_LOCATION (decl1);

  /* A nested function is not global.  */
  if (current_function_decl != NULL_TREE)
    TREE_PUBLIC (decl1) = 0;

  c_decl_attributes (&decl1, attributes, 0);

  if (DECL_DECLARED_INLINE_P (decl1)
      && DECL_UNINLINABLE (decl1)
      && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
    warning_at (loc, OPT_Wattributes,
		"inline function %qD given attribute %qs",
		decl1, "noinline");

  /* Handle gnu_inline attribute.  */
  if (declspecs->inline_p
      && !flag_gnu89_inline
      && TREE_CODE (decl1) == FUNCTION_DECL
      && (lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl1))
	  || current_function_decl))
    {
      if (declspecs->storage_class != csc_static)
	DECL_EXTERNAL (decl1) = !DECL_EXTERNAL (decl1);
    }

  announce_function (decl1);

  if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl1))))
    {
      error_at (loc, "return type is an incomplete type");
      /* Make it return void instead.  */
      TREE_TYPE (decl1)
	= build_function_type (void_type_node,
			       TYPE_ARG_TYPES (TREE_TYPE (decl1)));
    }

  if (warn_about_return_type)
    warn_defaults_to (loc, flag_isoc99 ? OPT_Wimplicit_int
			   : (warn_return_type > 0 ? OPT_Wreturn_type
			      : OPT_Wimplicit_int),
		      "return type defaults to %<int%>");

  /* Make the init_value nonzero so pushdecl knows this is not tentative.
     error_mark_node is replaced below (in pop_scope) with the BLOCK.  */
  DECL_INITIAL (decl1) = error_mark_node;

  /* If this definition isn't a prototype and we had a prototype declaration
     before, copy the arg type info from that prototype.  */
  old_decl = lookup_name_in_scope (DECL_NAME (decl1), current_scope);
  if (old_decl && TREE_CODE (old_decl) != FUNCTION_DECL)
    old_decl = NULL_TREE;

  current_function_prototype_locus = UNKNOWN_LOCATION;
  current_function_prototype_built_in = false;
  current_function_prototype_arg_types = NULL_TREE;
  tree newtype = TREE_TYPE (decl1);
  tree oldtype = old_decl ? TREE_TYPE (old_decl) : newtype;
  if (!prototype_p (newtype))
    {
      tree oldrt = TREE_TYPE (oldtype);
      tree newrt = TREE_TYPE (newtype);
      if (old_decl != NULL_TREE
	  && TREE_CODE (oldtype) == FUNCTION_TYPE
	  && comptypes (oldrt, newrt))
	{
	  if (stdarg_p (oldtype))
	    {
	      auto_diagnostic_group d;
	      warning_at (loc, 0, "%q+D defined as variadic function "
			  "without prototype", decl1);
	      locate_old_decl (old_decl);
	    }
	  TREE_TYPE (decl1) = composite_type (oldtype, newtype);
	  current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl);
	  current_function_prototype_built_in
	    = C_DECL_BUILTIN_PROTOTYPE (old_decl);
	  current_function_prototype_arg_types
	    = TYPE_ARG_TYPES (newtype);
	}
      if (TREE_PUBLIC (decl1))
	{
	  /* If there is an external prototype declaration of this
	     function, record its location but do not copy information
	     to this decl.  This may be an invisible declaration
	     (built-in or in a scope which has finished) or simply
	     have more refined argument types than any declaration
	     found above.  */
	  struct c_binding *b;
	  for (b = I_SYMBOL_BINDING (DECL_NAME (decl1)); b; b = b->shadowed)
	    if (B_IN_SCOPE (b, external_scope))
	      break;
	  if (b)
	    {
	      tree ext_decl, ext_type;
	      ext_decl = b->decl;
	      ext_type = b->u.type ? b->u.type : TREE_TYPE (ext_decl);
	      if (TREE_CODE (ext_type) == FUNCTION_TYPE
		  && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
				TREE_TYPE (ext_type)))
		{
		  current_function_prototype_locus
		    = DECL_SOURCE_LOCATION (ext_decl);
		  current_function_prototype_built_in
		    = C_DECL_BUILTIN_PROTOTYPE (ext_decl);
		  current_function_prototype_arg_types
		    = TYPE_ARG_TYPES (ext_type);
		}
	    }
	}
    }

  /* Optionally warn of old-fashioned def with no previous prototype.  */
  if (warn_strict_prototypes
      && old_decl != error_mark_node
      && !prototype_p (TREE_TYPE (decl1))
      && C_DECL_ISNT_PROTOTYPE (old_decl))
    warning_at (loc, OPT_Wstrict_prototypes,
		"function declaration isn%'t a prototype");
  /* Optionally warn of any global def with no previous prototype.  */
  else if (warn_missing_prototypes
	   && old_decl != error_mark_node
	   && TREE_PUBLIC (decl1)
	   && !MAIN_NAME_P (DECL_NAME (decl1))
	   && C_DECL_ISNT_PROTOTYPE (old_decl)
	   && !DECL_DECLARED_INLINE_P (decl1))
    warning_at (loc, OPT_Wmissing_prototypes,
		"no previous prototype for %qD", decl1);
  /* Optionally warn of any def with no previous prototype
     if the function has already been used.  */
  else if (warn_missing_prototypes
	   && old_decl != NULL_TREE
	   && old_decl != error_mark_node
	   && TREE_USED (old_decl)
	   && !prototype_p (TREE_TYPE (old_decl)))
    warning_at (loc, OPT_Wmissing_prototypes,
		"%qD was used with no prototype before its definition", decl1);
  /* Optionally warn of any global def with no previous declaration.  */
  else if (warn_missing_declarations
	   && TREE_PUBLIC (decl1)
	   && old_decl == NULL_TREE
	   && !MAIN_NAME_P (DECL_NAME (decl1))
	   && !DECL_DECLARED_INLINE_P (decl1))
    warning_at (loc, OPT_Wmissing_declarations,
		"no previous declaration for %qD",
		decl1);
  /* Optionally warn of any def with no previous declaration
     if the function has already been used.  */
  else if (warn_missing_declarations
	   && old_decl != NULL_TREE
	   && old_decl != error_mark_node
	   && TREE_USED (old_decl)
	   && C_DECL_IMPLICIT (old_decl))
    warning_at (loc, OPT_Wmissing_declarations,
		"%qD was used with no declaration before its definition", decl1);

  /* This function exists in static storage.
     (This does not mean `static' in the C sense!)  */
  TREE_STATIC (decl1) = 1;

  /* This is the earliest point at which we might know the assembler
     name of the function.  Thus, if it's set before this, die horribly.  */
  gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl1));

  /* If #pragma weak was used, mark the decl weak now.  */
  if (current_scope == file_scope)
    maybe_apply_pragma_weak (decl1);

  /* Warn for unlikely, improbable, or stupid declarations of `main'.  */
  if (warn_main && MAIN_NAME_P (DECL_NAME (decl1)))
    {
      if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
	  != integer_type_node)
	pedwarn (loc, OPT_Wmain, "return type of %qD is not %<int%>", decl1);
      else if (TYPE_ATOMIC (TREE_TYPE (TREE_TYPE (decl1))))
	pedwarn (loc, OPT_Wmain, "%<_Atomic%>-qualified return type of %qD",
		 decl1);

      check_main_parameter_types (decl1);

      if (!TREE_PUBLIC (decl1))
	pedwarn (loc, OPT_Wmain,
		 "%qD is normally a non-static function", decl1);
    }

  tree parms = current_function_arg_info->parms;
  if (old_decl)
    {
      location_t origloc = DECL_SOURCE_LOCATION (old_decl);
      warn_parm_array_mismatch (origloc, old_decl, parms);
    }

  /* Record the decl so that the function name is defined.
     If we already have a decl for this name, and it is a FUNCTION_DECL,
     use the old decl.  */

  current_function_decl = pushdecl (decl1);

  if (tree access = build_attr_access_from_parms (parms, false))
    decl_attributes (&current_function_decl, access, ATTR_FLAG_INTERNAL,
		     old_decl);

  push_scope ();
  declare_parm_level ();

  restype = TREE_TYPE (TREE_TYPE (current_function_decl));
  resdecl = build_decl (loc, RESULT_DECL, NULL_TREE, restype);
  DECL_ARTIFICIAL (resdecl) = 1;
  DECL_IGNORED_P (resdecl) = 1;
  DECL_RESULT (current_function_decl) = resdecl;

  start_fname_decls ();

  return true;
}

/* Subroutine of store_parm_decls which handles new-style function
   definitions (prototype format). The parms already have decls, so we
   need only record them as in effect and complain if any redundant
   old-style parm decls were written.  */
static void
store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info)
{
  tree decl;
  c_arg_tag *tag;
  unsigned ix;

  if (current_scope->bindings)
    {
      error_at (DECL_SOURCE_LOCATION (fndecl),
		"old-style parameter declarations in prototyped "
		"function definition");

      /* Get rid of the old-style declarations.  */
      pop_scope ();
      push_scope ();
    }
  /* Don't issue this warning for nested functions, and don't issue this
     warning if we got here because ARG_INFO_TYPES was error_mark_node
     (this happens when a function definition has just an ellipsis in
     its parameter list).  */
  else if (!in_system_header_at (input_location)
	   && !current_function_scope
	   && arg_info->types != error_mark_node)
    warning_at (DECL_SOURCE_LOCATION (fndecl), OPT_Wtraditional,
		"traditional C rejects ISO C style function definitions");

  /* Now make all the parameter declarations visible in the function body.
     We can bypass most of the grunt work of pushdecl.  */
  for (decl = arg_info->parms; decl; decl = DECL_CHAIN (decl))
    {
      DECL_CONTEXT (decl) = current_function_decl;
      if (DECL_NAME (decl))
	{
	  bind (DECL_NAME (decl), decl, current_scope,
		/*invisible=*/false, /*nested=*/false,
		UNKNOWN_LOCATION);
	  if (!TREE_USED (decl))
	    warn_if_shadowing (decl);
	}
      else
	pedwarn_c11 (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic,
		     "ISO C does not support omitting parameter names in "
		     "function definitions before C2X");
    }

  /* Record the parameter list in the function declaration.  */
  DECL_ARGUMENTS (fndecl) = arg_info->parms;

  /* Now make all the ancillary declarations visible, likewise.  */
  for (decl = arg_info->others; decl; decl = DECL_CHAIN (decl))
    {
      DECL_CONTEXT (decl) = current_function_decl;
      if (DECL_NAME (decl))
	bind (DECL_NAME (decl), decl, current_scope,
	      /*invisible=*/false,
	      /*nested=*/(TREE_CODE (decl) == FUNCTION_DECL),
	      UNKNOWN_LOCATION);
    }

  /* And all the tag declarations.  */
  FOR_EACH_VEC_SAFE_ELT_REVERSE (arg_info->tags, ix, tag)
    if (tag->id)
      bind (tag->id, tag->type, current_scope,
	    /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION);
}

/* Subroutine of store_parm_decls which handles old-style function
   definitions (separate parameter list and declarations).  */

static void
store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
{
  struct c_binding *b;
  tree parm, decl, last;
  tree parmids = arg_info->parms;
  hash_set<tree> seen_args;

  if (!in_system_header_at (input_location))
    {
      if (flag_isoc2x)
	pedwarn (DECL_SOURCE_LOCATION (fndecl),
		 OPT_Wold_style_definition, "old-style function definition");
      else
	warning_at (DECL_SOURCE_LOCATION (fndecl),
		    OPT_Wold_style_definition,
		    "old-style function definition");
    }

  if (current_scope->had_vla_unspec)
    error ("%<[*]%> not allowed in other than function prototype scope");

  /* Match each formal parameter name with its declaration.  Save each
     decl in the appropriate TREE_PURPOSE slot of the parmids chain.  */
  for (parm = parmids; parm; parm = TREE_CHAIN (parm))
    {
      if (TREE_VALUE (parm) == NULL_TREE)
	{
	  error_at (DECL_SOURCE_LOCATION (fndecl),
		    "parameter name missing from parameter list");
	  TREE_PURPOSE (parm) = NULL_TREE;
	  continue;
	}

      b = I_SYMBOL_BINDING (TREE_VALUE (parm));
      if (b && B_IN_CURRENT_SCOPE (b))
	{
	  decl = b->decl;
	  /* Skip erroneous parameters.  */
	  if (decl == error_mark_node)
	    continue;
	  /* If we got something other than a PARM_DECL it is an error.  */
	  if (TREE_CODE (decl) != PARM_DECL)
	    {
	      error_at (DECL_SOURCE_LOCATION (decl),
			"%qD declared as a non-parameter", decl);
	      continue;
	    }
	  /* If the declaration is already marked, we have a duplicate
	     name.  Complain and ignore the duplicate.  */
	  else if (seen_args.contains (decl))
	    {
	      error_at (DECL_SOURCE_LOCATION (decl),
			"multiple parameters named %qD", decl);
	      TREE_PURPOSE (parm) = NULL_TREE;
	      continue;
	    }
	  /* If the declaration says "void", complain and turn it into
	     an int.  */
	  else if (VOID_TYPE_P (TREE_TYPE (decl)))
	    {
	      error_at (DECL_SOURCE_LOCATION (decl),
			"parameter %qD declared with void type", decl);
	      TREE_TYPE (decl) = integer_type_node;
	      DECL_ARG_TYPE (decl) = integer_type_node;
	      layout_decl (decl, 0);
	    }
	  warn_if_shadowing (decl);
	}
      /* If no declaration found, default to int.  */
      else
	{
	  /* FIXME diagnostics: This should be the location of the argument,
	     not the FNDECL.  E.g., for an old-style declaration

	       int f10(v) { blah; }

	     We should use the location of the V, not the F10.
	     Unfortunately, the V is an IDENTIFIER_NODE which has no
	     location.  In the future we need locations for c_arg_info
	     entries.

	     See gcc.dg/Wshadow-3.c for an example of this problem. */
	  decl = build_decl (DECL_SOURCE_LOCATION (fndecl),
			     PARM_DECL, TREE_VALUE (parm), integer_type_node);
	  DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
	  pushdecl (decl);
	  warn_if_shadowing (decl);

	  if (flag_isoc99)
	    pedwarn (DECL_SOURCE_LOCATION (decl),
		     OPT_Wimplicit_int, "type of %qD defaults to %<int%>",
		     decl);
	  else
	    warning_at (DECL_SOURCE_LOCATION (decl),
			OPT_Wmissing_parameter_type,
			"type of %qD defaults to %<int%>", decl);
	}

      TREE_PURPOSE (parm) = decl;
      seen_args.add (decl);
    }

  /* Now examine the parms chain for incomplete declarations
     and declarations with no corresponding names.  */

  for (b = current_scope->bindings; b; b = b->prev)
    {
      parm = b->decl;
      if (TREE_CODE (parm) != PARM_DECL)
	continue;

      if (TREE_TYPE (parm) != error_mark_node
	  && !COMPLETE_TYPE_P (TREE_TYPE (parm)))
	{
	  error_at (DECL_SOURCE_LOCATION (parm),
		    "parameter %qD has incomplete type", parm);
	  TREE_TYPE (parm) = error_mark_node;
	}

      if (!seen_args.contains (parm))
	{
	  error_at (DECL_SOURCE_LOCATION (parm),
		    "declaration for parameter %qD but no such parameter",
		    parm);

	  /* Pretend the parameter was not missing.
	     This gets us to a standard state and minimizes
	     further error messages.  */
	  parmids = chainon (parmids, tree_cons (parm, 0, 0));
	}
    }

  /* Chain the declarations together in the order of the list of
     names.  Store that chain in the function decl, replacing the
     list of names.  Update the current scope to match.  */
  DECL_ARGUMENTS (fndecl) = NULL_TREE;

  for (parm = parmids; parm; parm = TREE_CHAIN (parm))
    if (TREE_PURPOSE (parm))
      break;
  if (parm && TREE_PURPOSE (parm))
    {
      last = TREE_PURPOSE (parm);
      DECL_ARGUMENTS (fndecl) = last;

      for (parm = TREE_CHAIN (parm); parm; parm = TREE_CHAIN (parm))
	if (TREE_PURPOSE (parm))
	  {
	    DECL_CHAIN (last) = TREE_PURPOSE (parm);
	    last = TREE_PURPOSE (parm);
	  }
      DECL_CHAIN (last) = NULL_TREE;
    }

  /* If there was a previous prototype,
     set the DECL_ARG_TYPE of each argument according to
     the type previously specified, and report any mismatches.  */

  if (current_function_prototype_arg_types)
    {
      tree type;
      for (parm = DECL_ARGUMENTS (fndecl),
	     type = current_function_prototype_arg_types;
	   parm || (type != NULL_TREE
		    && TREE_VALUE (type) != error_mark_node
		    && TYPE_MAIN_VARIANT (TREE_VALUE (type)) != void_type_node);
	   parm = DECL_CHAIN (parm), type = TREE_CHAIN (type))
	{
	  if (parm == NULL_TREE
	      || type == NULL_TREE
	      || (TREE_VALUE (type) != error_mark_node
		  && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node))
	    {
	      if (current_function_prototype_built_in)
		warning_at (DECL_SOURCE_LOCATION (fndecl),
			    0, "number of arguments doesn%'t match "
			    "built-in prototype");
	      else
		{
		  /* FIXME diagnostics: This should be the location of
		     FNDECL, but there is bug when a prototype is
		     declared inside function context, but defined
		     outside of it (e.g., gcc.dg/pr15698-2.c).  In
		     which case FNDECL gets the location of the
		     prototype, not the definition.  */
		  error_at (input_location,
			    "number of arguments doesn%'t match prototype");

		  error_at (current_function_prototype_locus,
			    "prototype declaration");
		}
	      break;
	    }
	  /* Type for passing arg must be consistent with that
	     declared for the arg.  ISO C says we take the unqualified
	     type for parameters declared with qualified type.  */
	  if (TREE_TYPE (parm) != error_mark_node
	      && TREE_VALUE (type) != error_mark_node
	      && ((TYPE_ATOMIC (DECL_ARG_TYPE (parm))
		   != TYPE_ATOMIC (TREE_VALUE (type)))
		  || !comptypes (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)),
				 TYPE_MAIN_VARIANT (TREE_VALUE (type)))))
	    {
	      if ((TYPE_ATOMIC (DECL_ARG_TYPE (parm))
		   == TYPE_ATOMIC (TREE_VALUE (type)))
		  && (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
		      == TYPE_MAIN_VARIANT (TREE_VALUE (type))))
		{
		  /* Adjust argument to match prototype.  E.g. a previous
		     `int foo(float);' prototype causes
		     `int foo(x) float x; {...}' to be treated like
		     `int foo(float x) {...}'.  This is particularly
		     useful for argument types like uid_t.  */
		  DECL_ARG_TYPE (parm) = TREE_TYPE (parm);

		  if (targetm.calls.promote_prototypes (TREE_TYPE (current_function_decl))
		      && INTEGRAL_TYPE_P (TREE_TYPE (parm))
		      && (TYPE_PRECISION (TREE_TYPE (parm))
			  < TYPE_PRECISION (integer_type_node)))
		    DECL_ARG_TYPE (parm)
		      = c_type_promotes_to (TREE_TYPE (parm));

		  /* ??? Is it possible to get here with a
		     built-in prototype or will it always have
		     been diagnosed as conflicting with an
		     old-style definition and discarded?  */
		  if (current_function_prototype_built_in)
		    warning_at (DECL_SOURCE_LOCATION (parm),
				OPT_Wpedantic, "promoted argument %qD "
				"doesn%'t match built-in prototype", parm);
		  else
		    {
		      pedwarn (DECL_SOURCE_LOCATION (parm),
			       OPT_Wpedantic, "promoted argument %qD "
			       "doesn%'t match prototype", parm);
		      pedwarn (current_function_prototype_locus, OPT_Wpedantic,
			       "prototype declaration");
		    }
		}
	      else
		{
		  if (current_function_prototype_built_in)
		    warning_at (DECL_SOURCE_LOCATION (parm),
				0, "argument %qD doesn%'t match "
				"built-in prototype", parm);
		  else
		    {
		      error_at (DECL_SOURCE_LOCATION (parm),
				"argument %qD doesn%'t match prototype", parm);
		      error_at (current_function_prototype_locus,
				"prototype declaration");
		    }
		}
	    }
	}
      TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = NULL_TREE;
    }

  /* Otherwise, create a prototype that would match.  */

  else
    {
      tree actual = NULL_TREE, last = NULL_TREE, type;

      for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
	{
	  type = tree_cons (NULL_TREE, DECL_ARG_TYPE (parm), NULL_TREE);
	  if (last)
	    TREE_CHAIN (last) = type;
	  else
	    actual = type;
	  last = type;
	}
      type = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
      if (last)
	TREE_CHAIN (last) = type;
      else
	actual = type;

      /* We are going to assign a new value for the TYPE_ACTUAL_ARG_TYPES
	 of the type of this function, but we need to avoid having this
	 affect the types of other similarly-typed functions, so we must
	 first force the generation of an identical (but separate) type
	 node for the relevant function type.  The new node we create
	 will be a variant of the main variant of the original function
	 type.  */

      TREE_TYPE (fndecl) = build_variant_type_copy (TREE_TYPE (fndecl));

      TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = actual;
    }
}

/* Store parameter declarations passed in ARG_INFO into the current
   function declaration.  */

void
store_parm_decls_from (struct c_arg_info *arg_info)
{
  current_function_arg_info = arg_info;
  store_parm_decls ();
}

/* Called by walk_tree to look for and update context-less labels
   or labels with context in the parent function.  */

static tree
set_labels_context_r (tree *tp, int *walk_subtrees, void *data)
{
  tree ctx = static_cast<tree>(data);
  if (TREE_CODE (*tp) == LABEL_EXPR
      && (DECL_CONTEXT (LABEL_EXPR_LABEL (*tp)) == NULL_TREE
	  || DECL_CONTEXT (LABEL_EXPR_LABEL (*tp)) == DECL_CONTEXT (ctx)))
    {
      DECL_CONTEXT (LABEL_EXPR_LABEL (*tp)) = ctx;
      *walk_subtrees = 0;
    }

  return NULL_TREE;
}

/* Store the parameter declarations into the current function declaration.
   This is called after parsing the parameter declarations, before
   digesting the body of the function.

   For an old-style definition, construct a prototype out of the old-style
   parameter declarations and inject it into the function's type.  */

void
store_parm_decls (void)
{
  tree fndecl = current_function_decl;
  bool proto;

  /* The argument information block for FNDECL.  */
  struct c_arg_info *arg_info = current_function_arg_info;
  current_function_arg_info = 0;

  /* True if this definition is written with a prototype.  In C2X, an
     empty argument list was converted to (void) in grokparms; in
     older C standard versions, it does not give the function a type
     with a prototype for future calls.  */
  proto = arg_info->types != 0;

  if (proto)
    store_parm_decls_newstyle (fndecl, arg_info);
  else
    store_parm_decls_oldstyle (fndecl, arg_info);

  /* The next call to push_scope will be a function body.  */

  next_is_function_body = true;

  /* Write a record describing this function definition to the prototypes
     file (if requested).  */

  gen_aux_info_record (fndecl, 1, 0, proto);

  /* Initialize the RTL code for the function.  */
  allocate_struct_function (fndecl, false);

  if (warn_unused_local_typedefs)
    cfun->language = ggc_cleared_alloc<language_function> ();

  /* Begin the statement tree for this function.  */
  DECL_SAVED_TREE (fndecl) = push_stmt_list ();

  /* ??? Insert the contents of the pending sizes list into the function
     to be evaluated.  The only reason left to have this is
	void foo(int n, int array[n++])
     because we throw away the array type in favor of a pointer type, and
     thus won't naturally see the SAVE_EXPR containing the increment.  All
     other pending sizes would be handled by gimplify_parameters.  */
  if (arg_info->pending_sizes)
    {
      /* In very special circumstances, e.g. for code like
	   _Atomic int i = 5;
	   void f (int a[i += 2]) {}
	 we need to execute the atomic assignment on function entry.
	 But in this case, it is not just a straight store, it has the
	 op= form, which means that build_atomic_assign has generated
	 gotos, labels, etc.  Because at that time the function decl
	 for F has not been created yet, those labels do not have any
	 function context.  But we have the fndecl now, so update the
	 labels accordingly.  gimplify_expr would crash otherwise.
	 Or with nested functions the labels could be created with parent
	 function's context, while when the statement is emitted at the
	 start of the nested function, it needs the nested function's
	 context.  */
      walk_tree_without_duplicates (&arg_info->pending_sizes,
				    set_labels_context_r, fndecl);
      add_stmt (arg_info->pending_sizes);
    }
}

/* Store PARM_DECLs in PARMS into scope temporarily.  Used for
   c_finish_omp_declare_simd for function prototypes.  No diagnostics
   should be done.  */

void
temp_store_parm_decls (tree fndecl, tree parms)
{
  push_scope ();
  for (tree p = parms; p; p = DECL_CHAIN (p))
    {
      DECL_CONTEXT (p) = fndecl;
      if (DECL_NAME (p))
	bind (DECL_NAME (p), p, current_scope,
	      /*invisible=*/false, /*nested=*/false,
	      UNKNOWN_LOCATION);
    }
}

/* Undo what temp_store_parm_decls did.  */

void
temp_pop_parm_decls (void)
{
  /* Clear all bindings in this temporary scope, so that
     pop_scope doesn't create a BLOCK.  */
  struct c_binding *b = current_scope->bindings;
  current_scope->bindings = NULL;
  for (; b; b = free_binding_and_advance (b))
    {
      gcc_assert (TREE_CODE (b->decl) == PARM_DECL
		  || b->decl == error_mark_node);
      gcc_assert (I_SYMBOL_BINDING (b->id) == b);
      I_SYMBOL_BINDING (b->id) = b->shadowed;
      if (b->shadowed && b->shadowed->u.type)
	TREE_TYPE (b->shadowed->decl) = b->shadowed->u.type;
    }
  pop_scope ();
}


/* Finish up a function declaration and compile that function
   all the way to assembler language output.  Then free the storage
   for the function definition.

   This is called after parsing the body of the function definition.  */

void
finish_function (location_t end_loc)
{
  tree fndecl = current_function_decl;
  
  if (c_dialect_objc ())
    objc_finish_function ();

  if (TREE_CODE (fndecl) == FUNCTION_DECL
      && targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
    {
      tree args = DECL_ARGUMENTS (fndecl);
      for (; args; args = DECL_CHAIN (args))
	{
	  tree type = TREE_TYPE (args);
	  if (INTEGRAL_TYPE_P (type)
	      && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
	    DECL_ARG_TYPE (args) = c_type_promotes_to (type);
	}
    }

  if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node)
    BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;

  /* Must mark the RESULT_DECL as being in this function.  */

  if (DECL_RESULT (fndecl) && DECL_RESULT (fndecl) != error_mark_node)
    DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;

  if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted
      && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
      == integer_type_node && flag_isoc99)
    {
      /* Hack.  We don't want the middle-end to warn that this return
	 is unreachable, so we mark its location as special.  Using
	 UNKNOWN_LOCATION has the problem that it gets clobbered in
	 annotate_one_with_locus.  A cleaner solution might be to
	 ensure ! should_carry_locus_p (stmt), but that needs a flag.
      */
      c_finish_return (BUILTINS_LOCATION, integer_zero_node, NULL_TREE);
    }

  /* Tie off the statement tree for this function.  */
  DECL_SAVED_TREE (fndecl) = pop_stmt_list (DECL_SAVED_TREE (fndecl));

  finish_fname_decls ();

  /* Complain if there's no return statement only if option specified on
     command line.  */
  if (warn_return_type > 0
      && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
      && !current_function_returns_value && !current_function_returns_null
      /* Don't complain if we are no-return.  */
      && !current_function_returns_abnormally
      /* Don't complain if we are declared noreturn.  */
      && !TREE_THIS_VOLATILE (fndecl)
      /* Don't warn for main().  */
      && !MAIN_NAME_P (DECL_NAME (fndecl))
      /* Or if they didn't actually specify a return type.  */
      && !C_FUNCTION_IMPLICIT_INT (fndecl)
      /* Normally, with -Wreturn-type, flow will complain, but we might
         optimize out static functions.  */
      && !TREE_PUBLIC (fndecl)
      && targetm.warn_func_return (fndecl)
      && warning (OPT_Wreturn_type,
		  "no return statement in function returning non-void"))
    suppress_warning (fndecl, OPT_Wreturn_type);

  /* Complain about parameters that are only set, but never otherwise used.  */
  if (warn_unused_but_set_parameter)
    {
      tree decl;

      for (decl = DECL_ARGUMENTS (fndecl);
	   decl;
	   decl = DECL_CHAIN (decl))
	if (TREE_USED (decl)
	    && TREE_CODE (decl) == PARM_DECL
	    && !DECL_READ_P (decl)
	    && DECL_NAME (decl)
	    && !DECL_ARTIFICIAL (decl)
	    && !warning_suppressed_p (decl, OPT_Wunused_but_set_parameter))
	  warning_at (DECL_SOURCE_LOCATION (decl),
		      OPT_Wunused_but_set_parameter,
		      "parameter %qD set but not used", decl);
    }

  /* Complain about locally defined typedefs that are not used in this
     function.  */
  maybe_warn_unused_local_typedefs ();

  /* Possibly warn about unused parameters.  */
  if (warn_unused_parameter)
    do_warn_unused_parameter (fndecl);

  /* Store the end of the function, so that we get good line number
     info for the epilogue.  */
  cfun->function_end_locus = end_loc;

  /* Finalize the ELF visibility for the function.  */
  c_determine_visibility (fndecl);

  /* For GNU C extern inline functions disregard inline limits.  */
  if (DECL_EXTERNAL (fndecl)
      && DECL_DECLARED_INLINE_P (fndecl)
      && (flag_gnu89_inline
	  || lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (fndecl))))
    DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1;

  /* Genericize before inlining.  Delay genericizing nested functions
     until their parent function is genericized.  Since finalizing
     requires GENERIC, delay that as well.  */

  if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node
      && !undef_nested_function)
    {
      if (!decl_function_context (fndecl))
	{
	  invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
	  c_genericize (fndecl);

	  /* ??? Objc emits functions after finalizing the compilation unit.
	     This should be cleaned up later and this conditional removed.  */
	  if (symtab->global_info_ready)
	    {
	      cgraph_node::add_new_function (fndecl, false);
	      return;
	    }
	  cgraph_node::finalize_function (fndecl, false);
	}
      else
	{
	  /* Register this function with cgraph just far enough to get it
	    added to our parent's nested function list.  Handy, since the
	    C front end doesn't have such a list.  */
	  (void) cgraph_node::get_create (fndecl);
	}
    }

  if (!decl_function_context (fndecl))
    undef_nested_function = false;

  if (cfun->language != NULL)
    {
      ggc_free (cfun->language);
      cfun->language = NULL;
    }

  /* We're leaving the context of this function, so zap cfun.
     It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
     tree_rest_of_compilation.  */
  set_cfun (NULL);
  invoke_plugin_callbacks (PLUGIN_FINISH_PARSE_FUNCTION, current_function_decl);
  current_function_decl = NULL;
}

/* Check the declarations given in a for-loop for satisfying the C99
   constraints.  If exactly one such decl is found, return it.  LOC is
   the location of the opening parenthesis of the for loop.  The last
   parameter allows you to control the "for loop initial declarations
   are only allowed in C99 mode".  Normally, you should pass
   flag_isoc99 as that parameter.  But in some cases (Objective-C
   foreach loop, for example) we want to run the checks in this
   function even if not in C99 mode, so we allow the caller to turn
   off the error about not being in C99 mode.
*/

tree
check_for_loop_decls (location_t loc, bool turn_off_iso_c99_error)
{
  struct c_binding *b;
  tree one_decl = NULL_TREE;
  int n_decls = 0;

  if (!turn_off_iso_c99_error)
    {
      static bool hint = true;
      /* If we get here, declarations have been used in a for loop without
	 the C99 for loop scope.  This doesn't make much sense, so don't
	 allow it.  */
      error_at (loc, "%<for%> loop initial declarations "
		"are only allowed in C99 or C11 mode");
      if (hint)
	{
	  inform (loc,
		  "use option %<-std=c99%>, %<-std=gnu99%>, %<-std=c11%> or "
		  "%<-std=gnu11%> to compile your code");
	  hint = false;
	}
      return NULL_TREE;
    }
  else
    pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support %<for%> loop "
		 "initial declarations");

  /* C99 subclause 6.8.5 paragraph 3:

       [#3]  The  declaration  part  of  a for statement shall only
       declare identifiers for objects having storage class auto or
       register.

     It isn't clear whether, in this sentence, "identifiers" binds to
     "shall only declare" or to "objects" - that is, whether all identifiers
     declared must be identifiers for objects, or whether the restriction
     only applies to those that are.  (A question on this in comp.std.c
     in November 2000 received no answer.)  We implement the strictest
     interpretation, to avoid creating an extension which later causes
     problems.  */

  for (b = current_scope->bindings; b; b = b->prev)
    {
      tree id = b->id;
      tree decl = b->decl;

      if (!id)
	continue;

      switch (TREE_CODE (decl))
	{
	case VAR_DECL:
	  {
	    location_t decl_loc = DECL_SOURCE_LOCATION (decl);
	    if (TREE_STATIC (decl))
	      error_at (decl_loc,
			"declaration of static variable %qD in %<for%> loop "
			"initial declaration", decl);
	    else if (DECL_EXTERNAL (decl))
	      error_at (decl_loc,
			"declaration of %<extern%> variable %qD in %<for%> loop "
			"initial declaration", decl);
	  }
	  break;

	case RECORD_TYPE:
	  error_at (loc,
		    "%<struct %E%> declared in %<for%> loop initial "
		    "declaration", id);
	  break;
	case UNION_TYPE:
	  error_at (loc,
		    "%<union %E%> declared in %<for%> loop initial declaration",
		    id);
	  break;
	case ENUMERAL_TYPE:
	  error_at (loc, "%<enum %E%> declared in %<for%> loop "
		    "initial declaration", id);
	  break;
	default:
	  error_at (loc, "declaration of non-variable "
		    "%qD in %<for%> loop initial declaration", decl);
	}

      n_decls++;
      one_decl = decl;
    }

  return n_decls == 1 ? one_decl : NULL_TREE;
}

/* Save and reinitialize the variables
   used during compilation of a C function.  */

void
c_push_function_context (void)
{
  struct language_function *p = cfun->language;
  /* cfun->language might have been already allocated by the use of
     -Wunused-local-typedefs.  In that case, just re-use it.  */
  if (p == NULL)
    cfun->language = p = ggc_cleared_alloc<language_function> ();

  p->base.x_stmt_tree = c_stmt_tree;
  c_stmt_tree.x_cur_stmt_list = vec_safe_copy (c_stmt_tree.x_cur_stmt_list);
  p->x_in_statement = in_statement;
  p->x_switch_stack = c_switch_stack;
  p->arg_info = current_function_arg_info;
  p->returns_value = current_function_returns_value;
  p->returns_null = current_function_returns_null;
  p->returns_abnormally = current_function_returns_abnormally;
  p->warn_about_return_type = warn_about_return_type;

  push_function_context ();
}

/* Restore the variables used during compilation of a C function.  */

void
c_pop_function_context (void)
{
  struct language_function *p;

  pop_function_context ();
  p = cfun->language;

  /* When -Wunused-local-typedefs is in effect, cfun->languages is
     used to store data throughout the life time of the current cfun,
     So don't deallocate it.  */
  if (!warn_unused_local_typedefs)
    cfun->language = NULL;

  if (DECL_STRUCT_FUNCTION (current_function_decl) == 0
      && DECL_SAVED_TREE (current_function_decl) == NULL_TREE)
    {
      /* Stop pointing to the local nodes about to be freed.  */
      /* But DECL_INITIAL must remain nonzero so we know this
	 was an actual function definition.  */
      DECL_INITIAL (current_function_decl) = error_mark_node;
      DECL_ARGUMENTS (current_function_decl) = NULL_TREE;
    }

  c_stmt_tree = p->base.x_stmt_tree;
  p->base.x_stmt_tree.x_cur_stmt_list = NULL;
  in_statement = p->x_in_statement;
  c_switch_stack = p->x_switch_stack;
  current_function_arg_info = p->arg_info;
  current_function_returns_value = p->returns_value;
  current_function_returns_null = p->returns_null;
  current_function_returns_abnormally = p->returns_abnormally;
  warn_about_return_type = p->warn_about_return_type;
}

/* The functions below are required for functionality of doing
   function at once processing in the C front end. Currently these
   functions are not called from anywhere in the C front end, but as
   these changes continue, that will change.  */

/* Returns the stmt_tree (if any) to which statements are currently
   being added.  If there is no active statement-tree, NULL is
   returned.  */

stmt_tree
current_stmt_tree (void)
{
  return &c_stmt_tree;
}

/* Return the global value of T as a symbol.  */

tree
identifier_global_value	(tree t)
{
  struct c_binding *b;

  for (b = I_SYMBOL_BINDING (t); b; b = b->shadowed)
    if (B_IN_FILE_SCOPE (b) || B_IN_EXTERNAL_SCOPE (b))
      return b->decl;

  return NULL_TREE;
}

/* Return the global value of tag T as a symbol.  */

tree
identifier_global_tag (tree t)
{
  struct c_binding *b;

  for (b = I_TAG_BINDING (t); b; b = b->shadowed)
    if (B_IN_FILE_SCOPE (b) || B_IN_EXTERNAL_SCOPE (b))
      return b->decl;

  return NULL_TREE;
}

/* Returns true if NAME refers to a built-in function or function-like
   operator.  */

bool
names_builtin_p (const char *name)
{
  tree id = get_identifier (name);
  if (tree decl = identifier_global_value (id))
    return TREE_CODE (decl) == FUNCTION_DECL && DECL_IS_UNDECLARED_BUILTIN (decl);

  /* Also detect common reserved C words that aren't strictly built-in
     functions.  */
  switch (C_RID_CODE (id))
    {
    case RID_BUILTIN_CONVERTVECTOR:
    case RID_BUILTIN_HAS_ATTRIBUTE:
    case RID_BUILTIN_SHUFFLE:
    case RID_BUILTIN_SHUFFLEVECTOR:
    case RID_CHOOSE_EXPR:
    case RID_OFFSETOF:
    case RID_TYPES_COMPATIBLE_P:
      return true;
    default:
      break;
    }

  return false;
}

/* In C, the only C-linkage public declaration is at file scope.  */

tree
c_linkage_bindings (tree name)
{
  return identifier_global_value (name);
}

/* Record a builtin type for C.  If NAME is non-NULL, it is the name used;
   otherwise the name is found in ridpointers from RID_INDEX.  */

void
record_builtin_type (enum rid rid_index, const char *name, tree type)
{
  tree id, decl;
  if (name == 0)
    id = ridpointers[(int) rid_index];
  else
    id = get_identifier (name);
  decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL, id, type);
  pushdecl (decl);
  if (debug_hooks->type_decl)
    debug_hooks->type_decl (decl, false);
}

/* Build the void_list_node (void_type_node having been created).  */
tree
build_void_list_node (void)
{
  tree t = build_tree_list (NULL_TREE, void_type_node);
  return t;
}

/* Return a c_parm structure with the given SPECS, ATTRS and DECLARATOR.  */

struct c_parm *
build_c_parm (struct c_declspecs *specs, tree attrs,
	      struct c_declarator *declarator,
	      location_t loc)
{
  struct c_parm *ret = XOBNEW (&parser_obstack, struct c_parm);
  ret->specs = specs;
  ret->attrs = attrs;
  ret->declarator = declarator;
  ret->loc = loc;
  return ret;
}

/* Return a declarator with nested attributes.  TARGET is the inner
   declarator to which these attributes apply.  ATTRS are the
   attributes.  */

struct c_declarator *
build_attrs_declarator (tree attrs, struct c_declarator *target)
{
  struct c_declarator *ret = XOBNEW (&parser_obstack, struct c_declarator);
  ret->kind = cdk_attrs;
  ret->declarator = target;
  ret->u.attrs = attrs;
  return ret;
}

/* Return a declarator for a function with arguments specified by ARGS
   and return type specified by TARGET.  */

struct c_declarator *
build_function_declarator (struct c_arg_info *args,
			   struct c_declarator *target)
{
  struct c_declarator *ret = XOBNEW (&parser_obstack, struct c_declarator);
  ret->kind = cdk_function;
  ret->declarator = target;
  ret->u.arg_info = args;
  return ret;
}

/* Return a declarator for the identifier IDENT (which may be
   NULL_TREE for an abstract declarator).  */

struct c_declarator *
build_id_declarator (tree ident)
{
  struct c_declarator *ret = XOBNEW (&parser_obstack, struct c_declarator);
  ret->kind = cdk_id;
  ret->declarator = 0;
  ret->u.id.id = ident;
  ret->u.id.attrs = NULL_TREE;
  /* Default value - may get reset to a more precise location. */
  ret->id_loc = input_location;
  return ret;
}

/* Return something to represent absolute declarators containing a *.
   TARGET is the absolute declarator that the * contains.
   TYPE_QUALS_ATTRS is a structure for type qualifiers and attributes
   to apply to the pointer type.  */

struct c_declarator *
make_pointer_declarator (struct c_declspecs *type_quals_attrs,
			 struct c_declarator *target)
{
  tree attrs;
  int quals = 0;
  struct c_declarator *itarget = target;
  struct c_declarator *ret = XOBNEW (&parser_obstack, struct c_declarator);
  if (type_quals_attrs)
    {
      attrs = type_quals_attrs->attrs;
      quals = quals_from_declspecs (type_quals_attrs);
      if (attrs != NULL_TREE)
	itarget = build_attrs_declarator (attrs, target);
    }
  ret->kind = cdk_pointer;
  ret->declarator = itarget;
  ret->u.pointer_quals = quals;
  return ret;
}

/* Return a pointer to a structure for an empty list of declaration
   specifiers.  */

struct c_declspecs *
build_null_declspecs (void)
{
  struct c_declspecs *ret = XOBNEW (&parser_obstack, struct c_declspecs);
  memset (ret, 0, sizeof *ret);
  ret->align_log = -1;
  ret->typespec_word = cts_none;
  ret->storage_class = csc_none;
  ret->expr_const_operands = true;
  ret->typespec_kind = ctsk_none;
  ret->address_space = ADDR_SPACE_GENERIC;
  return ret;
}

/* Add the address space ADDRSPACE to the declaration specifiers
   SPECS, returning SPECS.  */

struct c_declspecs *
declspecs_add_addrspace (location_t location,
			 struct c_declspecs *specs, addr_space_t as)
{
  specs->non_sc_seen_p = true;
  specs->declspecs_seen_p = true;
  specs->non_std_attrs_seen_p = true;

  if (!ADDR_SPACE_GENERIC_P (specs->address_space)
      && specs->address_space != as)
    error ("incompatible address space qualifiers %qs and %qs",
	   c_addr_space_name (as),
	   c_addr_space_name (specs->address_space));
  else
    {
      specs->address_space = as;
      specs->locations[cdw_address_space] = location;
    }
  return specs;
}

/* Add the type qualifier QUAL to the declaration specifiers SPECS,
   returning SPECS.  */

struct c_declspecs *
declspecs_add_qual (location_t loc,
		    struct c_declspecs *specs, tree qual)
{
  enum rid i;
  bool dupe = false;
  specs->non_sc_seen_p = true;
  specs->declspecs_seen_p = true;
  specs->non_std_attrs_seen_p = true;
  gcc_assert (TREE_CODE (qual) == IDENTIFIER_NODE
	      && C_IS_RESERVED_WORD (qual));
  i = C_RID_CODE (qual);
  location_t prev_loc = UNKNOWN_LOCATION;
  switch (i)
    {
    case RID_CONST:
      dupe = specs->const_p;
      specs->const_p = true;
      prev_loc = specs->locations[cdw_const];
      specs->locations[cdw_const] = loc;
      break;
    case RID_VOLATILE:
      dupe = specs->volatile_p;
      specs->volatile_p = true;
      prev_loc = specs->locations[cdw_volatile];
      specs->locations[cdw_volatile] = loc;
      break;
    case RID_RESTRICT:
      dupe = specs->restrict_p;
      specs->restrict_p = true;
      prev_loc = specs->locations[cdw_restrict];
      specs->locations[cdw_restrict] = loc;
      break;
    case RID_ATOMIC:
      dupe = specs->atomic_p;
      specs->atomic_p = true;
      prev_loc = specs->locations[cdw_atomic];
      specs->locations[cdw_atomic] = loc;
      break;
    default:
      gcc_unreachable ();
    }
  if (dupe)
    {
      bool warned = pedwarn_c90 (loc, OPT_Wpedantic,
				 "duplicate %qE declaration specifier", qual);
      if (!warned
	  && warn_duplicate_decl_specifier
	  && prev_loc >= RESERVED_LOCATION_COUNT
	  && !from_macro_expansion_at (prev_loc)
	  && !from_macro_expansion_at (loc))
	warning_at (loc, OPT_Wduplicate_decl_specifier,
		    "duplicate %qE declaration specifier", qual);
    }
  return specs;
}

/* Add the type specifier TYPE to the declaration specifiers SPECS,
   returning SPECS.  */

struct c_declspecs *
declspecs_add_type (location_t loc, struct c_declspecs *specs,
		    struct c_typespec spec)
{
  tree type = spec.spec;
  specs->non_sc_seen_p = true;
  specs->declspecs_seen_p = true;
  specs->non_std_attrs_seen_p = true;
  specs->typespec_kind = spec.kind;
  if (TREE_DEPRECATED (type))
    specs->deprecated_p = true;
  if (TREE_UNAVAILABLE (type))
    specs->unavailable_p = true;

  /* Handle type specifier keywords.  */
  if (TREE_CODE (type) == IDENTIFIER_NODE
      && C_IS_RESERVED_WORD (type)
      && C_RID_CODE (type) != RID_CXX_COMPAT_WARN)
    {
      enum rid i = C_RID_CODE (type);
      if (specs->type)
	{
	  error_at (loc, "two or more data types in declaration specifiers");
	  return specs;
	}
      if ((int) i <= (int) RID_LAST_MODIFIER)
	{
	  /* "long", "short", "signed", "unsigned", "_Complex" or "_Sat".  */
	  bool dupe = false;
	  switch (i)
	    {
	    case RID_LONG:
	      if (specs->long_long_p)
		{
		  error_at (loc, "%<long long long%> is too long for GCC");
		  break;
		}
	      if (specs->long_p)
		{
		  if (specs->typespec_word == cts_double)
		    {
		      error_at (loc,
				("both %<long long%> and %<double%> in "
				 "declaration specifiers"));
		      break;
		    }
		  pedwarn_c90 (loc, OPT_Wlong_long,
			       "ISO C90 does not support %<long long%>");
		  specs->long_long_p = 1;
		  specs->locations[cdw_long_long] = loc;
		  break;
		}
	      if (specs->short_p)
		error_at (loc,
			  ("both %<long%> and %<short%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_auto_type)
		error_at (loc,
			  ("both %<long%> and %<__auto_type%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_void)
		error_at (loc,
			  ("both %<long%> and %<void%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_int_n)
		  error_at (loc,
			    ("both %<long%> and %<__int%d%> in "
			     "declaration specifiers"),
			    int_n_data[specs->int_n_idx].bitsize);
	      else if (specs->typespec_word == cts_bool)
		error_at (loc,
			  ("both %<long%> and %<_Bool%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_char)
		error_at (loc,
			  ("both %<long%> and %<char%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_float)
		error_at (loc,
			  ("both %<long%> and %<float%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_floatn_nx)
		error_at (loc,
			  ("both %<long%> and %<_Float%d%s%> in "
			   "declaration specifiers"),
			  floatn_nx_types[specs->floatn_nx_idx].n,
			  (floatn_nx_types[specs->floatn_nx_idx].extended
			   ? "x"
			   : ""));
	      else if (specs->typespec_word == cts_dfloat32)
		error_at (loc,
			  ("both %<long%> and %<_Decimal32%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_dfloat64)
		error_at (loc,
			  ("both %<long%> and %<_Decimal64%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_dfloat128)
		error_at (loc,
			  ("both %<long%> and %<_Decimal128%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->long_p = true;
		  specs->locations[cdw_long] = loc;
		}
	      break;
	    case RID_SHORT:
	      dupe = specs->short_p;
	      if (specs->long_p)
		error_at (loc,
			  ("both %<long%> and %<short%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_auto_type)
		error_at (loc,
			  ("both %<short%> and %<__auto_type%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_void)
		error_at (loc,
			  ("both %<short%> and %<void%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_int_n)
		error_at (loc,
			  ("both %<short%> and %<__int%d%> in "
			   "declaration specifiers"),
			  int_n_data[specs->int_n_idx].bitsize);
	      else if (specs->typespec_word == cts_bool)
		error_at (loc,
			  ("both %<short%> and %<_Bool%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_char)
		error_at (loc,
			  ("both %<short%> and %<char%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_float)
		error_at (loc,
			  ("both %<short%> and %<float%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_double)
		error_at (loc,
			  ("both %<short%> and %<double%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_floatn_nx)
		error_at (loc,
			  ("both %<short%> and %<_Float%d%s%> in "
			   "declaration specifiers"),
			  floatn_nx_types[specs->floatn_nx_idx].n,
			  (floatn_nx_types[specs->floatn_nx_idx].extended
			   ? "x"
			   : ""));
	      else if (specs->typespec_word == cts_dfloat32)
                error_at (loc,
			  ("both %<short%> and %<_Decimal32%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_dfloat64)
		error_at (loc,
			  ("both %<short%> and %<_Decimal64%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_dfloat128)
		error_at (loc,
			  ("both %<short%> and %<_Decimal128%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->short_p = true;
		  specs->locations[cdw_short] = loc;
		}
	      break;
	    case RID_SIGNED:
	      dupe = specs->signed_p;
	      if (specs->unsigned_p)
		error_at (loc,
			  ("both %<signed%> and %<unsigned%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_auto_type)
		error_at (loc,
			  ("both %<signed%> and %<__auto_type%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_void)
		error_at (loc,
			  ("both %<signed%> and %<void%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_bool)
		error_at (loc,
			  ("both %<signed%> and %<_Bool%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_float)
		error_at (loc,
			  ("both %<signed%> and %<float%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_double)
		error_at (loc,
			  ("both %<signed%> and %<double%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_floatn_nx)
		error_at (loc,
			  ("both %<signed%> and %<_Float%d%s%> in "
			   "declaration specifiers"),
			  floatn_nx_types[specs->floatn_nx_idx].n,
			  (floatn_nx_types[specs->floatn_nx_idx].extended
			   ? "x"
			   : ""));
	      else if (specs->typespec_word == cts_dfloat32)
		error_at (loc,
			  ("both %<signed%> and %<_Decimal32%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_dfloat64)
		error_at (loc,
			  ("both %<signed%> and %<_Decimal64%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_dfloat128)
		error_at (loc,
			  ("both %<signed%> and %<_Decimal128%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->signed_p = true;
		  specs->locations[cdw_signed] = loc;
		}
	      break;
	    case RID_UNSIGNED:
	      dupe = specs->unsigned_p;
	      if (specs->signed_p)
		error_at (loc,
			  ("both %<signed%> and %<unsigned%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_auto_type)
		error_at (loc,
			  ("both %<unsigned%> and %<__auto_type%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_void)
		error_at (loc,
			  ("both %<unsigned%> and %<void%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_bool)
		error_at (loc,
			  ("both %<unsigned%> and %<_Bool%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_float)
		error_at (loc,
			  ("both %<unsigned%> and %<float%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_double)
		error_at (loc,
			  ("both %<unsigned%> and %<double%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_floatn_nx)
		error_at (loc,
			  ("both %<unsigned%> and %<_Float%d%s%> in "
			   "declaration specifiers"),
			  floatn_nx_types[specs->floatn_nx_idx].n,
			  (floatn_nx_types[specs->floatn_nx_idx].extended
			   ? "x"
			   : ""));
              else if (specs->typespec_word == cts_dfloat32)
		error_at (loc,
			  ("both %<unsigned%> and %<_Decimal32%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_dfloat64)
		error_at (loc,
			  ("both %<unsigned%> and %<_Decimal64%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_dfloat128)
		error_at (loc,
			  ("both %<unsigned%> and %<_Decimal128%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->unsigned_p = true;
		  specs->locations[cdw_unsigned] = loc;
		}
	      break;
	    case RID_COMPLEX:
	      dupe = specs->complex_p;
	      if (!in_system_header_at (loc))
		pedwarn_c90 (loc, OPT_Wpedantic,
			     "ISO C90 does not support complex types");
	      if (specs->typespec_word == cts_auto_type)
		error_at (loc,
			  ("both %<complex%> and %<__auto_type%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_void)
		error_at (loc,
			  ("both %<complex%> and %<void%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_bool)
		error_at (loc,
			  ("both %<complex%> and %<_Bool%> in "
			   "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat32)
		error_at (loc,
			  ("both %<complex%> and %<_Decimal32%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_dfloat64)
		error_at (loc,
			  ("both %<complex%> and %<_Decimal64%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_dfloat128)
		error_at (loc,
			  ("both %<complex%> and %<_Decimal128%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_fract)
		error_at (loc,
			  ("both %<complex%> and %<_Fract%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_accum)
		error_at (loc,
			  ("both %<complex%> and %<_Accum%> in "
			   "declaration specifiers"));
	      else if (specs->saturating_p)
		error_at (loc,
			  ("both %<complex%> and %<_Sat%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->complex_p = true;
		  specs->locations[cdw_complex] = loc;
		}
	      break;
	    case RID_SAT:
	      dupe = specs->saturating_p;
	      pedwarn (loc, OPT_Wpedantic,
		       "ISO C does not support saturating types");
	      if (specs->typespec_word == cts_int_n)
	        {
		  error_at (loc,
			    ("both %<_Sat%> and %<__int%d%> in "
			     "declaration specifiers"),
			    int_n_data[specs->int_n_idx].bitsize);
	        }
	      else if (specs->typespec_word == cts_auto_type)
		error_at (loc,
			  ("both %<_Sat%> and %<__auto_type%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_void)
		error_at (loc,
			  ("both %<_Sat%> and %<void%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_bool)
		error_at (loc,
			  ("both %<_Sat%> and %<_Bool%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_char)
		error_at (loc,
			  ("both %<_Sat%> and %<char%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_int)
		error_at (loc,
			  ("both %<_Sat%> and %<int%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_float)
		error_at (loc,
			  ("both %<_Sat%> and %<float%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_double)
		error_at (loc,
			  ("both %<_Sat%> and %<double%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_floatn_nx)
		error_at (loc,
			  ("both %<_Sat%> and %<_Float%d%s%> in "
			   "declaration specifiers"),
			  floatn_nx_types[specs->floatn_nx_idx].n,
			  (floatn_nx_types[specs->floatn_nx_idx].extended
			   ? "x"
			   : ""));
              else if (specs->typespec_word == cts_dfloat32)
		error_at (loc,
			  ("both %<_Sat%> and %<_Decimal32%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_dfloat64)
		error_at (loc,
			  ("both %<_Sat%> and %<_Decimal64%> in "
			   "declaration specifiers"));
	      else if (specs->typespec_word == cts_dfloat128)
		error_at (loc,
			  ("both %<_Sat%> and %<_Decimal128%> in "
			   "declaration specifiers"));
	      else if (specs->complex_p)
		error_at (loc,
			  ("both %<_Sat%> and %<complex%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->saturating_p = true;
		  specs->locations[cdw_saturating] = loc;
		}
	      break;
	    default:
	      gcc_unreachable ();
	    }

	  if (dupe)
	    error_at (loc, "duplicate %qE", type);

	  return specs;
	}
      else
	{
	  /* "void", "_Bool", "char", "int", "float", "double",
	     "_FloatN", "_FloatNx", "_Decimal32", "__intN",
	     "_Decimal64", "_Decimal128", "_Fract", "_Accum" or
	     "__auto_type".  */
	  if (specs->typespec_word != cts_none)
	    {
	      error_at (loc,
			"two or more data types in declaration specifiers");
	      return specs;
	    }
	  switch (i)
	    {
	    case RID_AUTO_TYPE:
	      if (specs->long_p)
		error_at (loc,
			  ("both %<long%> and %<__auto_type%> in "
			   "declaration specifiers"));
	      else if (specs->short_p)
		error_at (loc,
			  ("both %<short%> and %<__auto_type%> in "
			   "declaration specifiers"));
	      else if (specs->signed_p)
		error_at (loc,
			  ("both %<signed%> and %<__auto_type%> in "
			   "declaration specifiers"));
	      else if (specs->unsigned_p)
		error_at (loc,
			  ("both %<unsigned%> and %<__auto_type%> in "
			   "declaration specifiers"));
	      else if (specs->complex_p)
		error_at (loc,
			  ("both %<complex%> and %<__auto_type%> in "
			   "declaration specifiers"));
	      else if (specs->saturating_p)
		error_at (loc,
			  ("both %<_Sat%> and %<__auto_type%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->typespec_word = cts_auto_type;
		  specs->locations[cdw_typespec] = loc;
		}
	      return specs;
	    case RID_INT_N_0:
	    case RID_INT_N_1:
	    case RID_INT_N_2:
	    case RID_INT_N_3:
	      specs->int_n_idx = i - RID_INT_N_0;
	      if (!in_system_header_at (input_location)
		  /* If the INT_N type ends in "__", and so is of the format
		     "__intN__", don't pedwarn.  */
		  && (strncmp (IDENTIFIER_POINTER (type)
			       + (IDENTIFIER_LENGTH (type) - 2), "__", 2) != 0))
		pedwarn (loc, OPT_Wpedantic,
			 "ISO C does not support %<__int%d%> types",
			 int_n_data[specs->int_n_idx].bitsize);

	      if (specs->long_p)
		error_at (loc,
			  ("both %<__int%d%> and %<long%> in "
			   "declaration specifiers"),
			  int_n_data[specs->int_n_idx].bitsize);
	      else if (specs->saturating_p)
		error_at (loc,
			  ("both %<_Sat%> and %<__int%d%> in "
			   "declaration specifiers"),
			  int_n_data[specs->int_n_idx].bitsize);
	      else if (specs->short_p)
		error_at (loc,
			  ("both %<__int%d%> and %<short%> in "
			   "declaration specifiers"),
			  int_n_data[specs->int_n_idx].bitsize);
	      else if (! int_n_enabled_p[specs->int_n_idx])
		{
		  specs->typespec_word = cts_int_n;
		  error_at (loc,
			    "%<__int%d%> is not supported on this target",
			    int_n_data[specs->int_n_idx].bitsize);
		}
	      else
		{
		  specs->typespec_word = cts_int_n;
		  specs->locations[cdw_typespec] = loc;
		}
	      return specs;
	    case RID_VOID:
	      if (specs->long_p)
		error_at (loc,
			  ("both %<long%> and %<void%> in "
			   "declaration specifiers"));
	      else if (specs->short_p)
		error_at (loc,
			  ("both %<short%> and %<void%> in "
			   "declaration specifiers"));
	      else if (specs->signed_p)
		error_at (loc,
			  ("both %<signed%> and %<void%> in "
			   "declaration specifiers"));
	      else if (specs->unsigned_p)
		error_at (loc,
			  ("both %<unsigned%> and %<void%> in "
			   "declaration specifiers"));
	      else if (specs->complex_p)
		error_at (loc,
			  ("both %<complex%> and %<void%> in "
			   "declaration specifiers"));
	      else if (specs->saturating_p)
		error_at (loc,
			  ("both %<_Sat%> and %<void%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->typespec_word = cts_void;
		  specs->locations[cdw_typespec] = loc;
		}
	      return specs;
	    case RID_BOOL:
	      if (!in_system_header_at (loc))
		pedwarn_c90 (loc, OPT_Wpedantic,
			     "ISO C90 does not support boolean types");
	      if (specs->long_p)
		error_at (loc,
			  ("both %<long%> and %<_Bool%> in "
			   "declaration specifiers"));
	      else if (specs->short_p)
		error_at (loc,
			  ("both %<short%> and %<_Bool%> in "
			   "declaration specifiers"));
	      else if (specs->signed_p)
		error_at (loc,
			  ("both %<signed%> and %<_Bool%> in "
			   "declaration specifiers"));
	      else if (specs->unsigned_p)
		error_at (loc,
			  ("both %<unsigned%> and %<_Bool%> in "
			   "declaration specifiers"));
	      else if (specs->complex_p)
		error_at (loc,
			  ("both %<complex%> and %<_Bool%> in "
			   "declaration specifiers"));
	      else if (specs->saturating_p)
		error_at (loc,
			  ("both %<_Sat%> and %<_Bool%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->typespec_word = cts_bool;
		  specs->locations[cdw_typespec] = loc;
		}
	      return specs;
	    case RID_CHAR:
	      if (specs->long_p)
		error_at (loc,
			  ("both %<long%> and %<char%> in "
			   "declaration specifiers"));
	      else if (specs->short_p)
		error_at (loc,
			  ("both %<short%> and %<char%> in "
			   "declaration specifiers"));
	      else if (specs->saturating_p)
		error_at (loc,
			  ("both %<_Sat%> and %<char%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->typespec_word = cts_char;
		  specs->locations[cdw_typespec] = loc;
		}
	      return specs;
	    case RID_INT:
	      if (specs->saturating_p)
		error_at (loc,
			  ("both %<_Sat%> and %<int%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->typespec_word = cts_int;
		  specs->locations[cdw_typespec] = loc;
		}
	      return specs;
	    case RID_FLOAT:
	      if (specs->long_p)
		error_at (loc,
			  ("both %<long%> and %<float%> in "
			   "declaration specifiers"));
	      else if (specs->short_p)
		error_at (loc,
			  ("both %<short%> and %<float%> in "
			   "declaration specifiers"));
	      else if (specs->signed_p)
		error_at (loc,
			  ("both %<signed%> and %<float%> in "
			   "declaration specifiers"));
	      else if (specs->unsigned_p)
		error_at (loc,
			  ("both %<unsigned%> and %<float%> in "
			   "declaration specifiers"));
	      else if (specs->saturating_p)
		error_at (loc,
			  ("both %<_Sat%> and %<float%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->typespec_word = cts_float;
		  specs->locations[cdw_typespec] = loc;
		}
	      return specs;
	    case RID_DOUBLE:
	      if (specs->long_long_p)
		error_at (loc,
			  ("both %<long long%> and %<double%> in "
			   "declaration specifiers"));
	      else if (specs->short_p)
		error_at (loc,
			  ("both %<short%> and %<double%> in "
			   "declaration specifiers"));
	      else if (specs->signed_p)
		error_at (loc,
			  ("both %<signed%> and %<double%> in "
			   "declaration specifiers"));
	      else if (specs->unsigned_p)
		error_at (loc,
			  ("both %<unsigned%> and %<double%> in "
			   "declaration specifiers"));
	      else if (specs->saturating_p)
		error_at (loc,
			  ("both %<_Sat%> and %<double%> in "
			   "declaration specifiers"));
	      else
		{
		  specs->typespec_word = cts_double;
		  specs->locations[cdw_typespec] = loc;
		}
	      return specs;
	    CASE_RID_FLOATN_NX:
	      specs->floatn_nx_idx = i - RID_FLOATN_NX_FIRST;
	      if (!in_system_header_at (input_location))
		pedwarn (loc, OPT_Wpedantic,
			 "ISO C does not support the %<_Float%d%s%> type",
			 floatn_nx_types[specs->floatn_nx_idx].n,
			 (floatn_nx_types[specs->floatn_nx_idx].extended
			  ? "x"
			  : ""));

	      if (specs->long_p)
		error_at (loc,
			  ("both %<long%> and %<_Float%d%s%> in "
			   "declaration specifiers"),
			  floatn_nx_types[specs->floatn_nx_idx].n,
			  (floatn_nx_types[specs->floatn_nx_idx].extended
			   ? "x"
			   : ""));
	      else if (specs->short_p)
		error_at (loc,
			  ("both %<short%> and %<_Float%d%s%> in "
			   "declaration specifiers"),
			  floatn_nx_types[specs->floatn_nx_idx].n,
			  (floatn_nx_types[specs->floatn_nx_idx].extended
			   ? "x"
			   : ""));
	      else if (specs->signed_p)
		error_at (loc,
			  ("both %<signed%> and %<_Float%d%s%> in "
			   "declaration specifiers"),
			  floatn_nx_types[specs->floatn_nx_idx].n,
			  (floatn_nx_types[specs->floatn_nx_idx].extended
			   ? "x"
			   : ""));
	      else if (specs->unsigned_p)
		error_at (loc,
			  ("both %<unsigned%> and %<_Float%d%s%> in "
			   "declaration specifiers"),
			  floatn_nx_types[specs->floatn_nx_idx].n,
			  (floatn_nx_types[specs->floatn_nx_idx].extended
			   ? "x"
			   : ""));
	      else if (specs->saturating_p)
		error_at (loc,
			  ("both %<_Sat%> and %<_Float%d%s%> in "
			   "declaration specifiers"),
			  floatn_nx_types[specs->floatn_nx_idx].n,
			  (floatn_nx_types[specs->floatn_nx_idx].extended
			   ? "x"
			   : ""));
	      else if (FLOATN_NX_TYPE_NODE (specs->floatn_nx_idx) == NULL_TREE)
		{
		  specs->typespec_word = cts_floatn_nx;
		  error_at (loc,
			    "%<_Float%d%s%> is not supported on this target",
			    floatn_nx_types[specs->floatn_nx_idx].n,
			    (floatn_nx_types[specs->floatn_nx_idx].extended
			     ? "x"
			     : ""));
		}
	      else
		{
		  specs->typespec_word = cts_floatn_nx;
		  specs->locations[cdw_typespec] = loc;
		}
	      return specs;
	    case RID_DFLOAT32:
	    case RID_DFLOAT64:
	    case RID_DFLOAT128:
	      {
		const char *str;
		if (i == RID_DFLOAT32)
		  str = "_Decimal32";
		else if (i == RID_DFLOAT64)
		  str = "_Decimal64";
		else
		  str = "_Decimal128";
		if (specs->long_long_p)
		  error_at (loc,
			    ("both %<long long%> and %qs in "
			     "declaration specifiers"),
			    str);
		if (specs->long_p)
		  error_at (loc,
			    ("both %<long%> and %qs in "
			     "declaration specifiers"),
			    str);
		else if (specs->short_p)
		  error_at (loc,
			    ("both %<short%> and %qs in "
			     "declaration specifiers"),
			    str);
		else if (specs->signed_p)
		  error_at (loc,
			    ("both %<signed%> and %qs in "
			     "declaration specifiers"),
			    str);
		else if (specs->unsigned_p)
		  error_at (loc,
			    ("both %<unsigned%> and %qs in "
			     "declaration specifiers"),
			    str);
                else if (specs->complex_p)
                  error_at (loc,
			    ("both %<complex%> and %qs in "
			     "declaration specifiers"),
			    str);
                else if (specs->saturating_p)
                  error_at (loc,
			    ("both %<_Sat%> and %qs in "
			     "declaration specifiers"),
			    str);
		else if (i == RID_DFLOAT32)
		  specs->typespec_word = cts_dfloat32;
		else if (i == RID_DFLOAT64)
		  specs->typespec_word = cts_dfloat64;
		else
		  specs->typespec_word = cts_dfloat128;
		specs->locations[cdw_typespec] = loc;
	      }
	      if (!targetm.decimal_float_supported_p ())
		error_at (loc,
			  ("decimal floating-point not supported "
			   "for this target"));
	      pedwarn_c11 (loc, OPT_Wpedantic,
			   "ISO C does not support decimal floating-point "
			   "before C2X");
	      return specs;
	    case RID_FRACT:
	    case RID_ACCUM:
	      {
		const char *str;
		if (i == RID_FRACT)
		  str = "_Fract";
		else
		  str = "_Accum";
                if (specs->complex_p)
                  error_at (loc,
			    ("both %<complex%> and %qs in "
			     "declaration specifiers"),
			    str);
		else if (i == RID_FRACT)
		    specs->typespec_word = cts_fract;
		else
		    specs->typespec_word = cts_accum;
		specs->locations[cdw_typespec] = loc;
	      }
	      if (!targetm.fixed_point_supported_p ())
		error_at (loc,
			  "fixed-point types not supported for this target");
	      pedwarn (loc, OPT_Wpedantic,
		       "ISO C does not support fixed-point types");
	      return specs;
	    default:
	      /* ObjC reserved word "id", handled below.  */
	      break;
	    }
	}
    }

  /* Now we have a typedef (a TYPE_DECL node), an identifier (some
     form of ObjC type, cases such as "int" and "long" being handled
     above), a TYPE (struct, union, enum and typeof specifiers) or an
     ERROR_MARK.  In none of these cases may there have previously
     been any type specifiers.  */
  if (specs->type || specs->typespec_word != cts_none
      || specs->long_p || specs->short_p || specs->signed_p
      || specs->unsigned_p || specs->complex_p)
    error_at (loc, "two or more data types in declaration specifiers");
  else if (TREE_CODE (type) == TYPE_DECL)
    {
      if (TREE_TYPE (type) == error_mark_node)
	; /* Allow the type to default to int to avoid cascading errors.  */
      else
	{
	  specs->type = TREE_TYPE (type);
	  specs->decl_attr = DECL_ATTRIBUTES (type);
	  specs->typedef_p = true;
	  specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type);
	  specs->locations[cdw_typedef] = loc;

	  /* If this typedef name is defined in a struct, then a C++
	     lookup would return a different value.  */
	  if (warn_cxx_compat
	      && I_SYMBOL_BINDING (DECL_NAME (type))->in_struct)
	    warning_at (loc, OPT_Wc___compat,
			"C++ lookup of %qD would return a field, not a type",
			type);

	  /* If we are parsing a struct, record that a struct field
	     used a typedef.  */
	  if (warn_cxx_compat && struct_parse_info != NULL)
	    struct_parse_info->typedefs_seen.safe_push (type);
	}
    }
  else if (TREE_CODE (type) == IDENTIFIER_NODE)
    {
      tree t = lookup_name (type);
      if (!t || TREE_CODE (t) != TYPE_DECL)
	error_at (loc, "%qE fails to be a typedef or built in type", type);
      else if (TREE_TYPE (t) == error_mark_node)
	;
      else
	{
	  specs->type = TREE_TYPE (t);
	  specs->locations[cdw_typespec] = loc;
	}
    }
  else
    {
      if (TREE_CODE (type) != ERROR_MARK && spec.kind == ctsk_typeof)
	{
	  specs->typedef_p = true;
	  specs->locations[cdw_typedef] = loc;
	  if (spec.expr)
	    {
	      if (specs->expr)
		specs->expr = build2 (COMPOUND_EXPR, TREE_TYPE (spec.expr),
				      specs->expr, spec.expr);
	      else
		specs->expr = spec.expr;
	      specs->expr_const_operands &= spec.expr_const_operands;
	    }
	}
      specs->type = type;
    }

  return specs;
}

/* Add the storage class specifier or function specifier SCSPEC to the
   declaration specifiers SPECS, returning SPECS.  */

struct c_declspecs *
declspecs_add_scspec (location_t loc,
		      struct c_declspecs *specs,
		      tree scspec)
{
  enum rid i;
  enum c_storage_class n = csc_none;
  bool dupe = false;
  specs->declspecs_seen_p = true;
  specs->non_std_attrs_seen_p = true;
  gcc_assert (TREE_CODE (scspec) == IDENTIFIER_NODE
	      && C_IS_RESERVED_WORD (scspec));
  i = C_RID_CODE (scspec);
  if (specs->non_sc_seen_p)
    warning (OPT_Wold_style_declaration,
             "%qE is not at beginning of declaration", scspec);
  switch (i)
    {
    case RID_INLINE:
      /* C99 permits duplicate inline.  Although of doubtful utility,
	 it seems simplest to permit it in gnu89 mode as well, as
	 there is also little utility in maintaining this as a
	 difference between gnu89 and C99 inline.  */
      dupe = false;
      specs->inline_p = true;
      specs->locations[cdw_inline] = loc;
      break;
    case RID_NORETURN:
      /* Duplicate _Noreturn is permitted.  */
      dupe = false;
      specs->noreturn_p = true;
      specs->locations[cdw_noreturn] = loc;
      break;
    case RID_THREAD:
      dupe = specs->thread_p;
      if (specs->storage_class == csc_auto)
	error ("%qE used with %<auto%>", scspec);
      else if (specs->storage_class == csc_register)
	error ("%qE used with %<register%>", scspec);
      else if (specs->storage_class == csc_typedef)
	error ("%qE used with %<typedef%>", scspec);
      else
	{
	  specs->thread_p = true;
	  specs->thread_gnu_p = (strcmp (IDENTIFIER_POINTER (scspec),
					 "__thread") == 0);
	  /* A diagnostic is not required for the use of this
	     identifier in the implementation namespace; only diagnose
	     it for the C11 spelling because of existing code using
	     the other spelling.  */
	  if (!specs->thread_gnu_p)
	    {
	      if (flag_isoc99)
		pedwarn_c99 (loc, OPT_Wpedantic,
			     "ISO C99 does not support %qE", scspec);
	      else
		pedwarn_c99 (loc, OPT_Wpedantic,
			     "ISO C90 does not support %qE", scspec);
	    }
	  specs->locations[cdw_thread] = loc;
	}
      break;
    case RID_AUTO:
      n = csc_auto;
      break;
    case RID_EXTERN:
      n = csc_extern;
      /* Diagnose "__thread extern".  */
      if (specs->thread_p && specs->thread_gnu_p)
	error ("%<__thread%> before %<extern%>");
      break;
    case RID_REGISTER:
      n = csc_register;
      break;
    case RID_STATIC:
      n = csc_static;
      /* Diagnose "__thread static".  */
      if (specs->thread_p && specs->thread_gnu_p)
	error ("%<__thread%> before %<static%>");
      break;
    case RID_TYPEDEF:
      n = csc_typedef;
      break;
    default:
      gcc_unreachable ();
    }
  if (n != csc_none && n == specs->storage_class)
    dupe = true;
  if (dupe)
    {
      if (i == RID_THREAD)
	error ("duplicate %<_Thread_local%> or %<__thread%>");
      else
	error ("duplicate %qE", scspec);
    }
  if (n != csc_none)
    {
      if (specs->storage_class != csc_none && n != specs->storage_class)
	{
	  error ("multiple storage classes in declaration specifiers");
	}
      else
	{
	  specs->storage_class = n;
	  specs->locations[cdw_storage_class] = loc;
	  if (n != csc_extern && n != csc_static && specs->thread_p)
	    {
	      error ("%qs used with %qE",
		     specs->thread_gnu_p ? "__thread" : "_Thread_local",
		     scspec);
	      specs->thread_p = false;
	    }
	}
    }
  return specs;
}

/* Add the attributes ATTRS to the declaration specifiers SPECS,
   returning SPECS.  */

struct c_declspecs *
declspecs_add_attrs (location_t loc, struct c_declspecs *specs, tree attrs)
{
  specs->attrs = chainon (attrs, specs->attrs);
  specs->locations[cdw_attributes] = loc;
  specs->declspecs_seen_p = true;
  /* In the case of standard attributes at the start of the
     declaration, the caller will reset this.  */
  specs->non_std_attrs_seen_p = true;
  return specs;
}

/* Add an _Alignas specifier (expression ALIGN, or type whose
   alignment is ALIGN) to the declaration specifiers SPECS, returning
   SPECS.  */
struct c_declspecs *
declspecs_add_alignas (location_t loc,
		       struct c_declspecs *specs, tree align)
{
  specs->alignas_p = true;
  specs->locations[cdw_alignas] = loc;
  if (align == error_mark_node)
    return specs;

  /* Only accept the alignment if it's valid and greater than
     the current one.  Zero is invalid but by C11 required to
     be silently ignored.  */
  int align_log = check_user_alignment (align, false, /* warn_zero = */false);
  if (align_log > specs->align_log)
    specs->align_log = align_log;
  return specs;
}

/* Combine "long", "short", "signed", "unsigned" and "_Complex" type
   specifiers with any other type specifier to determine the resulting
   type.  This is where ISO C checks on complex types are made, since
   "_Complex long" is a prefix of the valid ISO C type "_Complex long
   double".  Also apply postfix standard attributes to modify the type.  */

struct c_declspecs *
finish_declspecs (struct c_declspecs *specs)
{
  /* If a type was specified as a whole, we have no modifiers and are
     done.  */
  if (specs->type != NULL_TREE)
    {
      gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p
		  && !specs->signed_p && !specs->unsigned_p
		  && !specs->complex_p);

      /* Set a dummy type.  */
      if (TREE_CODE (specs->type) == ERROR_MARK)
        specs->type = integer_type_node;
      goto handle_postfix_attrs;
    }

  /* If none of "void", "_Bool", "char", "int", "float" or "double"
     has been specified, treat it as "int" unless "_Complex" is
     present and there are no other specifiers.  If we just have
     "_Complex", it is equivalent to "_Complex double", but e.g.
     "_Complex short" is equivalent to "_Complex short int".  */
  if (specs->typespec_word == cts_none)
    {
      if (specs->saturating_p)
	{
	  error_at (specs->locations[cdw_saturating],
		    "%<_Sat%> is used without %<_Fract%> or %<_Accum%>");
	  if (!targetm.fixed_point_supported_p ())
	    error_at (specs->locations[cdw_saturating],
		      "fixed-point types not supported for this target");
	  specs->typespec_word = cts_fract;
	}
      else if (specs->long_p || specs->short_p
	       || specs->signed_p || specs->unsigned_p)
	{
	  specs->typespec_word = cts_int;
	}
      else if (specs->complex_p)
	{
	  specs->typespec_word = cts_double;
	  pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
		   "ISO C does not support plain %<complex%> meaning "
		   "%<double complex%>");
	}
      else
	{
	  specs->typespec_word = cts_int;
	  specs->default_int_p = true;
	  /* We don't diagnose this here because grokdeclarator will
	     give more specific diagnostics according to whether it is
	     a function definition.  */
	}
    }

  /* If "signed" was specified, record this to distinguish "int" and
     "signed int" in the case of a bit-field with
     -funsigned-bitfields.  */
  specs->explicit_signed_p = specs->signed_p;

  /* Now compute the actual type.  */
  switch (specs->typespec_word)
    {
    case cts_auto_type:
      gcc_assert (!specs->long_p && !specs->short_p
		  && !specs->signed_p && !specs->unsigned_p
		  && !specs->complex_p);
      /* Type to be filled in later.  */
      if (specs->postfix_attrs)
	error ("%<__auto_type%> followed by %<[[]]%> attributes");
      break;
    case cts_void:
      gcc_assert (!specs->long_p && !specs->short_p
		  && !specs->signed_p && !specs->unsigned_p
		  && !specs->complex_p);
      specs->type = void_type_node;
      break;
    case cts_bool:
      gcc_assert (!specs->long_p && !specs->short_p
		  && !specs->signed_p && !specs->unsigned_p
		  && !specs->complex_p);
      specs->type = boolean_type_node;
      break;
    case cts_char:
      gcc_assert (!specs->long_p && !specs->short_p);
      gcc_assert (!(specs->signed_p && specs->unsigned_p));
      if (specs->signed_p)
	specs->type = signed_char_type_node;
      else if (specs->unsigned_p)
	specs->type = unsigned_char_type_node;
      else
	specs->type = char_type_node;
      if (specs->complex_p)
	{
	  pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
		   "ISO C does not support complex integer types");
	  specs->type = build_complex_type (specs->type);
	}
      break;
    case cts_int_n:
      gcc_assert (!specs->long_p && !specs->short_p && !specs->long_long_p);
      gcc_assert (!(specs->signed_p && specs->unsigned_p));
      if (! int_n_enabled_p[specs->int_n_idx])
	specs->type = integer_type_node;
      else
	specs->type = (specs->unsigned_p
		       ? int_n_trees[specs->int_n_idx].unsigned_type
		       : int_n_trees[specs->int_n_idx].signed_type);
      if (specs->complex_p)
	{
	  pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
		   "ISO C does not support complex integer types");
	  specs->type = build_complex_type (specs->type);
	}
      break;
    case cts_int:
      gcc_assert (!(specs->long_p && specs->short_p));
      gcc_assert (!(specs->signed_p && specs->unsigned_p));
      if (specs->long_long_p)
	specs->type = (specs->unsigned_p
		       ? long_long_unsigned_type_node
		       : long_long_integer_type_node);
      else if (specs->long_p)
	specs->type = (specs->unsigned_p
		       ? long_unsigned_type_node
		       : long_integer_type_node);
      else if (specs->short_p)
	specs->type = (specs->unsigned_p
		       ? short_unsigned_type_node
		       : short_integer_type_node);
      else
	specs->type = (specs->unsigned_p
		       ? unsigned_type_node
		       : integer_type_node);
      if (specs->complex_p)
	{
	  pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
		   "ISO C does not support complex integer types");
	  specs->type = build_complex_type (specs->type);
	}
      break;
    case cts_float:
      gcc_assert (!specs->long_p && !specs->short_p
		  && !specs->signed_p && !specs->unsigned_p);
      specs->type = (specs->complex_p
		     ? complex_float_type_node
		     : float_type_node);
      break;
    case cts_double:
      gcc_assert (!specs->long_long_p && !specs->short_p
		  && !specs->signed_p && !specs->unsigned_p);
      if (specs->long_p)
	{
	  specs->type = (specs->complex_p
			 ? complex_long_double_type_node
			 : long_double_type_node);
	}
      else
	{
	  specs->type = (specs->complex_p
			 ? complex_double_type_node
			 : double_type_node);
	}
      break;
    case cts_floatn_nx:
      gcc_assert (!specs->long_p && !specs->short_p
		  && !specs->signed_p && !specs->unsigned_p);
      if (FLOATN_NX_TYPE_NODE (specs->floatn_nx_idx) == NULL_TREE)
	specs->type = integer_type_node;
      else if (specs->complex_p)
	specs->type = COMPLEX_FLOATN_NX_TYPE_NODE (specs->floatn_nx_idx);
      else
	specs->type = FLOATN_NX_TYPE_NODE (specs->floatn_nx_idx);
      break;
    case cts_dfloat32:
    case cts_dfloat64:
    case cts_dfloat128:
      gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p
		  && !specs->signed_p && !specs->unsigned_p && !specs->complex_p);
      if (!targetm.decimal_float_supported_p ())
	specs->type = integer_type_node;
      else if (specs->typespec_word == cts_dfloat32)
	specs->type = dfloat32_type_node;
      else if (specs->typespec_word == cts_dfloat64)
	specs->type = dfloat64_type_node;
      else
	specs->type = dfloat128_type_node;
      break;
    case cts_fract:
      gcc_assert (!specs->complex_p);
      if (!targetm.fixed_point_supported_p ())
	specs->type = integer_type_node;
      else if (specs->saturating_p)
	{
	  if (specs->long_long_p)
	    specs->type = specs->unsigned_p
			  ? sat_unsigned_long_long_fract_type_node
			  : sat_long_long_fract_type_node;
	  else if (specs->long_p)
	    specs->type = specs->unsigned_p
			  ? sat_unsigned_long_fract_type_node
			  : sat_long_fract_type_node;
	  else if (specs->short_p)
	    specs->type = specs->unsigned_p
			  ? sat_unsigned_short_fract_type_node
			  : sat_short_fract_type_node;
	  else
	    specs->type = specs->unsigned_p
			  ? sat_unsigned_fract_type_node
			  : sat_fract_type_node;
	}
      else
	{
	  if (specs->long_long_p)
	    specs->type = specs->unsigned_p
			  ? unsigned_long_long_fract_type_node
			  : long_long_fract_type_node;
	  else if (specs->long_p)
	    specs->type = specs->unsigned_p
			  ? unsigned_long_fract_type_node
			  : long_fract_type_node;
	  else if (specs->short_p)
	    specs->type = specs->unsigned_p
			  ? unsigned_short_fract_type_node
			  : short_fract_type_node;
	  else
	    specs->type = specs->unsigned_p
			  ? unsigned_fract_type_node
			  : fract_type_node;
	}
      break;
    case cts_accum:
      gcc_assert (!specs->complex_p);
      if (!targetm.fixed_point_supported_p ())
	specs->type = integer_type_node;
      else if (specs->saturating_p)
	{
	  if (specs->long_long_p)
	    specs->type = specs->unsigned_p
			  ? sat_unsigned_long_long_accum_type_node
			  : sat_long_long_accum_type_node;
	  else if (specs->long_p)
	    specs->type = specs->unsigned_p
			  ? sat_unsigned_long_accum_type_node
			  : sat_long_accum_type_node;
	  else if (specs->short_p)
	    specs->type = specs->unsigned_p
			  ? sat_unsigned_short_accum_type_node
			  : sat_short_accum_type_node;
	  else
	    specs->type = specs->unsigned_p
			  ? sat_unsigned_accum_type_node
			  : sat_accum_type_node;
	}
      else
	{
	  if (specs->long_long_p)
	    specs->type = specs->unsigned_p
			  ? unsigned_long_long_accum_type_node
			  : long_long_accum_type_node;
	  else if (specs->long_p)
	    specs->type = specs->unsigned_p
			  ? unsigned_long_accum_type_node
			  : long_accum_type_node;
	  else if (specs->short_p)
	    specs->type = specs->unsigned_p
			  ? unsigned_short_accum_type_node
			  : short_accum_type_node;
	  else
	    specs->type = specs->unsigned_p
			  ? unsigned_accum_type_node
			  : accum_type_node;
	}
      break;
    default:
      gcc_unreachable ();
    }
 handle_postfix_attrs:
  if (specs->type != NULL)
    {
      specs->postfix_attrs = c_warn_type_attributes (specs->postfix_attrs);
      decl_attributes (&specs->type, specs->postfix_attrs, 0);
      specs->postfix_attrs = NULL_TREE;
    }

  return specs;
}

/* Perform final processing on one file scope's declarations (or the
   external scope's declarations), GLOBALS.  */

static void
c_write_global_declarations_1 (tree globals)
{
  tree decl;
  bool reconsider;

  /* Process the decls in the order they were written.  */
  for (decl = globals; decl; decl = DECL_CHAIN (decl))
    {
      /* Check for used but undefined static functions using the C
	 standard's definition of "used", and set TREE_NO_WARNING so
	 that check_global_declaration doesn't repeat the check.  */
      if (TREE_CODE (decl) == FUNCTION_DECL
	  && DECL_INITIAL (decl) == NULL_TREE
	  && DECL_EXTERNAL (decl)
	  && !TREE_PUBLIC (decl))
	{
	  if (C_DECL_USED (decl))
	    {
	      /* TODO: Add OPT_Wundefined-inline.  */
	      if (pedwarn (input_location, 0, "%q+F used but never defined",
			   decl))
		suppress_warning (decl /* OPT_Wundefined-inline.  */);
	    }
	  /* For -Wunused-function warn about unused static prototypes.  */
	  else if (warn_unused_function
		   && ! DECL_ARTIFICIAL (decl)
		   && ! warning_suppressed_p (decl, OPT_Wunused_function))
	    {
	      if (warning (OPT_Wunused_function,
			   "%q+F declared %<static%> but never defined",
			   decl))
		suppress_warning (decl, OPT_Wunused_function);
	    }
	}

      wrapup_global_declaration_1 (decl);
    }

  do
    {
      reconsider = false;
      for (decl = globals; decl; decl = DECL_CHAIN (decl))
	reconsider |= wrapup_global_declaration_2 (decl);
    }
  while (reconsider);
}

/* Preserve the external declarations scope across a garbage collect.  */
static GTY(()) tree ext_block;

/* Collect all references relevant to SOURCE_FILE.  */

static void
collect_all_refs (const char *source_file)
{
  tree t;
  unsigned i;

  FOR_EACH_VEC_ELT (*all_translation_units, i, t)
    collect_ada_nodes (BLOCK_VARS (DECL_INITIAL (t)), source_file);

  collect_ada_nodes (BLOCK_VARS (ext_block), source_file);
}

/* Collect source file references at global level.  */

static void
collect_source_refs (void)
{
  tree t;
  tree decls;
  tree decl;
  unsigned i;

  FOR_EACH_VEC_ELT (*all_translation_units, i, t)
    { 
      decls = DECL_INITIAL (t);
      for (decl = BLOCK_VARS (decls); decl; decl = TREE_CHAIN (decl))
	if (!DECL_IS_UNDECLARED_BUILTIN (decl))
	  collect_source_ref (DECL_SOURCE_FILE (decl));
    }

  for (decl = BLOCK_VARS (ext_block); decl; decl = TREE_CHAIN (decl))
    if (!DECL_IS_UNDECLARED_BUILTIN (decl))
      collect_source_ref (DECL_SOURCE_FILE (decl));
}

/* Free attribute access data that are not needed by the middle end. */

static void
free_attr_access_data ()
{
  struct cgraph_node *n;

  /* Iterate over all functions declared in the translation unit.  */
  FOR_EACH_FUNCTION (n)
    {
      for (tree parm = DECL_ARGUMENTS (n->decl); parm; parm = TREE_CHAIN (parm))
	if (tree attrs = DECL_ATTRIBUTES (parm))
	  attr_access::free_lang_data (attrs);

      tree fntype = TREE_TYPE (n->decl);
      if (!fntype || fntype == error_mark_node)
	continue;
      tree attrs = TYPE_ATTRIBUTES (fntype);
      if (!attrs)
	continue;

      attr_access::free_lang_data (attrs);
    }
}

/* Perform any final parser cleanups and generate initial debugging
   information.  */

void
c_parse_final_cleanups (void)
{
  tree t;
  unsigned i;

  /* We don't want to do this if generating a PCH.  */
  if (pch_file)
    return;

  timevar_stop (TV_PHASE_PARSING);
  timevar_start (TV_PHASE_DEFERRED);

  /* Do the Objective-C stuff.  This is where all the Objective-C
     module stuff gets generated (symtab, class/protocol/selector
     lists etc).  */
  if (c_dialect_objc ())
    objc_write_global_declarations ();

  /* Close the external scope.  */
  ext_block = pop_scope ();
  external_scope = 0;
  gcc_assert (!current_scope);

  /* Handle -fdump-ada-spec[-slim]. */
  if (flag_dump_ada_spec || flag_dump_ada_spec_slim)
    {
      /* Build a table of files to generate specs for */
      collect_source_ref (main_input_filename);
      if (!flag_dump_ada_spec_slim)
	collect_source_refs ();

      dump_ada_specs (collect_all_refs, NULL);
    }

  /* Process all file scopes in this compilation, and the external_scope,
     through wrapup_global_declarations.  */
  FOR_EACH_VEC_ELT (*all_translation_units, i, t)
    c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t)));
  c_write_global_declarations_1 (BLOCK_VARS (ext_block));

  if (!in_lto_p)
    free_attr_access_data ();

  timevar_stop (TV_PHASE_DEFERRED);
  timevar_start (TV_PHASE_PARSING);

  ext_block = NULL;
}

/* Register reserved keyword WORD as qualifier for address space AS.  */

void
c_register_addr_space (const char *word, addr_space_t as)
{
  int rid = RID_FIRST_ADDR_SPACE + as;
  tree id;

  /* Address space qualifiers are only supported
     in C with GNU extensions enabled.  */
  if (c_dialect_objc () || flag_no_asm)
    return;

  id = get_identifier (word);
  C_SET_RID_CODE (id, rid);
  C_IS_RESERVED_WORD (id) = 1;
  ridpointers [rid] = id;
}

/* Return identifier to look up for omp declare reduction.  */

tree
c_omp_reduction_id (enum tree_code reduction_code, tree reduction_id)
{
  const char *p = NULL;
  switch (reduction_code)
    {
    case PLUS_EXPR: p = "+"; break;
    case MULT_EXPR: p = "*"; break;
    case MINUS_EXPR: p = "-"; break;
    case BIT_AND_EXPR: p = "&"; break;
    case BIT_XOR_EXPR: p = "^"; break;
    case BIT_IOR_EXPR: p = "|"; break;
    case TRUTH_ANDIF_EXPR: p = "&&"; break;
    case TRUTH_ORIF_EXPR: p = "||"; break;
    case MIN_EXPR: p = "min"; break;
    case MAX_EXPR: p = "max"; break;
    default:
      break;
    }

  if (p == NULL)
    {
      if (TREE_CODE (reduction_id) != IDENTIFIER_NODE)
	return error_mark_node;
      p = IDENTIFIER_POINTER (reduction_id);
    }

  const char prefix[] = "omp declare reduction ";
  size_t lenp = sizeof (prefix);
  size_t len = strlen (p);
  char *name = XALLOCAVEC (char, lenp + len);
  memcpy (name, prefix, lenp - 1);
  memcpy (name + lenp - 1, p, len + 1);
  return get_identifier (name);
}

/* Lookup REDUCTION_ID in the current scope, or create an artificial
   VAR_DECL, bind it into the current scope and return it.  */

tree
c_omp_reduction_decl (tree reduction_id)
{
  struct c_binding *b = I_SYMBOL_BINDING (reduction_id);
  if (b != NULL && B_IN_CURRENT_SCOPE (b))
    return b->decl;

  tree decl = build_decl (BUILTINS_LOCATION, VAR_DECL,
			  reduction_id, integer_type_node);
  DECL_ARTIFICIAL (decl) = 1;
  DECL_EXTERNAL (decl) = 1;
  TREE_STATIC (decl) = 1;
  TREE_PUBLIC (decl) = 0;
  bind (reduction_id, decl, current_scope, true, false, BUILTINS_LOCATION);
  return decl;
}

/* Lookup REDUCTION_ID in the first scope where it has entry for TYPE.  */

tree
c_omp_reduction_lookup (tree reduction_id, tree type)
{
  struct c_binding *b = I_SYMBOL_BINDING (reduction_id);
  while (b)
    {
      tree t;
      for (t = DECL_INITIAL (b->decl); t; t = TREE_CHAIN (t))
	if (comptypes (TREE_PURPOSE (t), type))
	  return TREE_VALUE (t);
      b = b->shadowed;
    }
  return error_mark_node;
}

/* Helper function called via walk_tree, to diagnose invalid
   #pragma omp declare reduction combiners or initializers.  */

tree
c_check_omp_declare_reduction_r (tree *tp, int *, void *data)
{
  tree *vars = (tree *) data;
  if (SSA_VAR_P (*tp)
      && !DECL_ARTIFICIAL (*tp)
      && *tp != vars[0]
      && *tp != vars[1])
    {
      location_t loc = DECL_SOURCE_LOCATION (vars[0]);
      if (strcmp (IDENTIFIER_POINTER (DECL_NAME (vars[0])), "omp_out") == 0)
	error_at (loc, "%<#pragma omp declare reduction%> combiner refers to "
		       "variable %qD which is not %<omp_out%> nor %<omp_in%>",
		  *tp);
      else
	error_at (loc, "%<#pragma omp declare reduction%> initializer refers "
		       "to variable %qD which is not %<omp_priv%> nor "
		       "%<omp_orig%>",
		  *tp);
      return *tp;
    }
  return NULL_TREE;
}


bool
c_check_in_current_scope (tree decl)
{
  struct c_binding *b = I_SYMBOL_BINDING (DECL_NAME (decl));
  return b != NULL && B_IN_CURRENT_SCOPE (b);
}

#include "gt-c-c-decl.h"
