/* Process declarations and variables for C++ compiler.
   Copyright (C) 1988-2021 Free Software Foundation, Inc.
   Hacked by Michael Tiemann (tiemann@cygnus.com)

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"
#include "system.h"
#include "coretypes.h"
#include "memmodel.h"
#include "target.h"
#include "cp-tree.h"
#include "c-family/c-common.h"
#include "timevar.h"
#include "stringpool.h"
#include "cgraph.h"
#include "varasm.h"
#include "attribs.h"
#include "stor-layout.h"
#include "calls.h"
#include "decl.h"
#include "toplev.h"
#include "c-family/c-objc.h"
#include "c-family/c-pragma.h"
#include "dumpfile.h"
#include "intl.h"
#include "c-family/c-ada-spec.h"
#include "asan.h"
#include "optabs-query.h"

/* Id for dumping the raw trees.  */
int raw_dump_id;
 
extern cpp_reader *parse_in;

/* This structure contains information about the initializations
   and/or destructions required for a particular priority level.  */
typedef struct priority_info_s {
  /* Nonzero if there have been any initializations at this priority
     throughout the translation unit.  */
  int initializations_p;
  /* Nonzero if there have been any destructions at this priority
     throughout the translation unit.  */
  int destructions_p;
} *priority_info;

static tree start_objects (int, int);
static void finish_objects (int, int, tree);
static tree start_static_storage_duration_function (unsigned);
static void finish_static_storage_duration_function (tree);
static priority_info get_priority_info (int);
static void do_static_initialization_or_destruction (tree, bool);
static void one_static_initialization_or_destruction (tree, tree, bool);
static void generate_ctor_or_dtor_function (bool, int, location_t *);
static int generate_ctor_and_dtor_functions_for_priority (splay_tree_node,
							  void *);
static tree prune_vars_needing_no_initialization (tree *);
static void write_out_vars (tree);
static void import_export_class (tree);
static tree get_guard_bits (tree);
static void determine_visibility_from_class (tree, tree);
static bool determine_hidden_inline (tree);

/* A list of static class variables.  This is needed, because a
   static class variable can be declared inside the class without
   an initializer, and then initialized, statically, outside the class.  */
static GTY(()) vec<tree, va_gc> *pending_statics;

/* A list of functions which were declared inline, but which we
   may need to emit outline anyway.  */
static GTY(()) vec<tree, va_gc> *deferred_fns;

/* A list of decls that use types with no linkage, which we need to make
   sure are defined.  */
static GTY(()) vec<tree, va_gc> *no_linkage_decls;

/* A vector of alternating decls and identifiers, where the latter
   is to be an alias for the former if the former is defined.  */
static GTY(()) vec<tree, va_gc> *mangling_aliases;

/* hash traits for declarations.  Hashes single decls via
   DECL_ASSEMBLER_NAME_RAW.  */

struct mangled_decl_hash : ggc_remove <tree>
{
  typedef tree value_type; /* A DECL.  */
  typedef tree compare_type; /* An identifier.  */

  static hashval_t hash (const value_type decl)
  {
    return IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME_RAW (decl));
  }
  static bool equal (const value_type existing, compare_type candidate)
  {
    tree name = DECL_ASSEMBLER_NAME_RAW (existing);
    return candidate == name;
  }

  static const bool empty_zero_p = true;
  static inline void mark_empty (value_type &p) {p = NULL_TREE;}
  static inline bool is_empty (value_type p) {return !p;}

  static bool is_deleted (value_type e)
  {
    return e == reinterpret_cast <value_type> (1);
  }
  static void mark_deleted (value_type &e)
  {
    e = reinterpret_cast <value_type> (1);
  }
};

/* A hash table of decls keyed by mangled name.  Used to figure out if
   we need compatibility aliases.  */
static GTY(()) hash_table<mangled_decl_hash> *mangled_decls;

/* Nonzero if we're done parsing and into end-of-file activities.  */

int at_eof;

/* True if note_mangling_alias should enqueue mangling aliases for
   later generation, rather than emitting them right away.  */

bool defer_mangling_aliases = true;


/* Return a member function type (a METHOD_TYPE), given FNTYPE (a
   FUNCTION_TYPE), CTYPE (class type), and QUALS (the cv-qualifiers
   that apply to the function).  */

tree
build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals,
		  cp_ref_qualifier rqual)
{
  if (fntype == error_mark_node || ctype == error_mark_node)
    return error_mark_node;

  gcc_assert (FUNC_OR_METHOD_TYPE_P (fntype));

  cp_cv_quals type_quals = quals & ~TYPE_QUAL_RESTRICT;
  ctype = cp_build_qualified_type (ctype, type_quals);

  tree newtype
    = build_method_type_directly (ctype, TREE_TYPE (fntype),
				  (TREE_CODE (fntype) == METHOD_TYPE
				   ? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
				   : TYPE_ARG_TYPES (fntype)));
  if (tree attrs = TYPE_ATTRIBUTES (fntype))
    newtype = cp_build_type_attribute_variant (newtype, attrs);
  newtype = build_cp_fntype_variant (newtype, rqual,
				     TYPE_RAISES_EXCEPTIONS (fntype),
				     TYPE_HAS_LATE_RETURN_TYPE (fntype));

  return newtype;
}

/* Return a variant of FNTYPE, a FUNCTION_TYPE or METHOD_TYPE, with its
   return type changed to NEW_RET.  */

tree
change_return_type (tree new_ret, tree fntype)
{
  if (new_ret == error_mark_node)
    return fntype;

  if (same_type_p (new_ret, TREE_TYPE (fntype)))
    return fntype;

  tree newtype;
  tree args = TYPE_ARG_TYPES (fntype);

  if (TREE_CODE (fntype) == FUNCTION_TYPE)
    {
      newtype = build_function_type (new_ret, args);
      newtype = apply_memfn_quals (newtype,
				   type_memfn_quals (fntype));
    }
  else
    newtype = build_method_type_directly
      (class_of_this_parm (fntype), new_ret, TREE_CHAIN (args));

  if (tree attrs = TYPE_ATTRIBUTES (fntype))
    newtype = cp_build_type_attribute_variant (newtype, attrs);
  newtype = cxx_copy_lang_qualifiers (newtype, fntype);

  return newtype;
}

/* Build a PARM_DECL of FN with NAME and TYPE, and set DECL_ARG_TYPE
   appropriately.  */

tree
cp_build_parm_decl (tree fn, tree name, tree type)
{
  tree parm = build_decl (input_location,
			  PARM_DECL, name, type);
  DECL_CONTEXT (parm) = fn;

  /* DECL_ARG_TYPE is only used by the back end and the back end never
     sees templates.  */
  if (!processing_template_decl)
    DECL_ARG_TYPE (parm) = type_passed_as (type);

  return parm;
}

/* Returns a PARM_DECL of FN for a parameter of the indicated TYPE, with the
   indicated NAME.  */

tree
build_artificial_parm (tree fn, tree name, tree type)
{
  tree parm = cp_build_parm_decl (fn, name, type);
  DECL_ARTIFICIAL (parm) = 1;
  /* All our artificial parms are implicitly `const'; they cannot be
     assigned to.  */
  TREE_READONLY (parm) = 1;
  return parm;
}

/* Constructors for types with virtual baseclasses need an "in-charge" flag
   saying whether this constructor is responsible for initialization of
   virtual baseclasses or not.  All destructors also need this "in-charge"
   flag, which additionally determines whether or not the destructor should
   free the memory for the object.

   This function adds the "in-charge" flag to member function FN if
   appropriate.  It is called from grokclassfn and tsubst.
   FN must be either a constructor or destructor.

   The in-charge flag follows the 'this' parameter, and is followed by the
   VTT parm (if any), then the user-written parms.  */

void
maybe_retrofit_in_chrg (tree fn)
{
  tree basetype, arg_types, parms, parm, fntype;

  /* If we've already add the in-charge parameter don't do it again.  */
  if (DECL_HAS_IN_CHARGE_PARM_P (fn))
    return;

  /* When processing templates we can't know, in general, whether or
     not we're going to have virtual baseclasses.  */
  if (processing_template_decl)
    return;

  /* We don't need an in-charge parameter for constructors that don't
     have virtual bases.  */
  if (DECL_CONSTRUCTOR_P (fn)
      && !CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
    return;

  arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
  basetype = TREE_TYPE (TREE_VALUE (arg_types));
  arg_types = TREE_CHAIN (arg_types);

  parms = DECL_CHAIN (DECL_ARGUMENTS (fn));

  /* If this is a subobject constructor or destructor, our caller will
     pass us a pointer to our VTT.  */
  if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
    {
      parm = build_artificial_parm (fn, vtt_parm_identifier, vtt_parm_type);

      /* First add it to DECL_ARGUMENTS between 'this' and the real args...  */
      DECL_CHAIN (parm) = parms;
      parms = parm;

      /* ...and then to TYPE_ARG_TYPES.  */
      arg_types = hash_tree_chain (vtt_parm_type, arg_types);

      DECL_HAS_VTT_PARM_P (fn) = 1;
    }

  /* Then add the in-charge parm (before the VTT parm).  */
  parm = build_artificial_parm (fn, in_charge_identifier, integer_type_node);
  DECL_CHAIN (parm) = parms;
  parms = parm;
  arg_types = hash_tree_chain (integer_type_node, arg_types);

  /* Insert our new parameter(s) into the list.  */
  DECL_CHAIN (DECL_ARGUMENTS (fn)) = parms;

  /* And rebuild the function type.  */
  fntype = build_method_type_directly (basetype, TREE_TYPE (TREE_TYPE (fn)),
				       arg_types);
  if (TYPE_ATTRIBUTES (TREE_TYPE (fn)))
    fntype = (cp_build_type_attribute_variant
	      (fntype, TYPE_ATTRIBUTES (TREE_TYPE (fn))));
  fntype = cxx_copy_lang_qualifiers (fntype, TREE_TYPE (fn));
  TREE_TYPE (fn) = fntype;

  /* Now we've got the in-charge parameter.  */
  DECL_HAS_IN_CHARGE_PARM_P (fn) = 1;
}

/* Classes overload their constituent function names automatically.
   When a function name is declared in a record structure,
   its name is changed to it overloaded name.  Since names for
   constructors and destructors can conflict, we place a leading
   '$' for destructors.

   CNAME is the name of the class we are grokking for.

   FUNCTION is a FUNCTION_DECL.  It was created by `grokdeclarator'.

   FLAGS contains bits saying what's special about today's
   arguments.  DTOR_FLAG == DESTRUCTOR.

   If FUNCTION is a destructor, then we must add the `auto-delete' field
   as a second parameter.  There is some hair associated with the fact
   that we must "declare" this variable in the manner consistent with the
   way the rest of the arguments were declared.

   QUALS are the qualifiers for the this pointer.  */

void
grokclassfn (tree ctype, tree function, enum overload_flags flags)
{
  tree fn_name = DECL_NAME (function);

  /* Even within an `extern "C"' block, members get C++ linkage.  See
     [dcl.link] for details.  */
  SET_DECL_LANGUAGE (function, lang_cplusplus);

  if (fn_name == NULL_TREE)
    {
      error ("name missing for member function");
      fn_name = get_identifier ("<anonymous>");
      DECL_NAME (function) = fn_name;
    }

  DECL_CONTEXT (function) = ctype;

  if (flags == DTOR_FLAG)
    DECL_CXX_DESTRUCTOR_P (function) = 1;

  if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function))
    maybe_retrofit_in_chrg (function);
}

/* Create an ARRAY_REF, checking for the user doing things backwards
   along the way.  DECLTYPE_P is for N3276, as in the parser.  */

tree
grok_array_decl (location_t loc, tree array_expr, tree index_exp,
		 bool decltype_p)
{
  tree type;
  tree expr;
  tree orig_array_expr = array_expr;
  tree orig_index_exp = index_exp;
  tree overload = NULL_TREE;

  if (error_operand_p (array_expr) || error_operand_p (index_exp))
    return error_mark_node;

  if (processing_template_decl)
    {
      if (type_dependent_expression_p (array_expr)
	  || type_dependent_expression_p (index_exp))
	return build_min_nt_loc (loc, ARRAY_REF, array_expr, index_exp,
				 NULL_TREE, NULL_TREE);
      array_expr = build_non_dependent_expr (array_expr);
      index_exp = build_non_dependent_expr (index_exp);
    }

  type = TREE_TYPE (array_expr);
  gcc_assert (type);
  type = non_reference (type);

  /* If they have an `operator[]', use that.  */
  if (MAYBE_CLASS_TYPE_P (type) || MAYBE_CLASS_TYPE_P (TREE_TYPE (index_exp)))
    {
      tsubst_flags_t complain = tf_warning_or_error;
      if (decltype_p)
	complain |= tf_decltype;
      expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, array_expr,
			   index_exp, NULL_TREE, &overload, complain);
    }
  else
    {
      tree p1, p2, i1, i2;
      bool swapped = false;

      /* Otherwise, create an ARRAY_REF for a pointer or array type.
	 It is a little-known fact that, if `a' is an array and `i' is
	 an int, you can write `i[a]', which means the same thing as
	 `a[i]'.  */
      if (TREE_CODE (type) == ARRAY_TYPE || VECTOR_TYPE_P (type))
	p1 = array_expr;
      else
	p1 = build_expr_type_conversion (WANT_POINTER, array_expr, false);

      if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE)
	p2 = index_exp;
      else
	p2 = build_expr_type_conversion (WANT_POINTER, index_exp, false);

      i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr,
				       false);
      i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp,
				       false);

      if ((p1 && i2) && (i1 && p2))
	error ("ambiguous conversion for array subscript");

      if (p1 && i2)
	array_expr = p1, index_exp = i2;
      else if (i1 && p2)
	swapped = true, array_expr = p2, index_exp = i1;
      else
	{
	  error_at (loc, "invalid types %<%T[%T]%> for array subscript",
		    type, TREE_TYPE (index_exp));
	  return error_mark_node;
	}

      if (array_expr == error_mark_node || index_exp == error_mark_node)
	error ("ambiguous conversion for array subscript");

      if (TYPE_PTR_P (TREE_TYPE (array_expr)))
	array_expr = mark_rvalue_use (array_expr);
      else
	array_expr = mark_lvalue_use_nonread (array_expr);
      index_exp = mark_rvalue_use (index_exp);
      if (swapped
	  && flag_strong_eval_order == 2
	  && (TREE_SIDE_EFFECTS (array_expr) || TREE_SIDE_EFFECTS (index_exp)))
	expr = build_array_ref (input_location, index_exp, array_expr);
      else
	expr = build_array_ref (input_location, array_expr, index_exp);
    }
  if (processing_template_decl && expr != error_mark_node)
    {
      if (overload != NULL_TREE)
	return (build_min_non_dep_op_overload
		(ARRAY_REF, expr, overload, orig_array_expr, orig_index_exp));

      return build_min_non_dep (ARRAY_REF, expr, orig_array_expr, orig_index_exp,
				NULL_TREE, NULL_TREE);
    }
  return expr;
}

/* Given the cast expression EXP, checking out its validity.   Either return
   an error_mark_node if there was an unavoidable error, return a cast to
   void for trying to delete a pointer w/ the value 0, or return the
   call to delete.  If DOING_VEC is true, we handle things differently
   for doing an array delete.
   Implements ARM $5.3.4.  This is called from the parser.  */

tree
delete_sanity (location_t loc, tree exp, tree size, bool doing_vec,
	       int use_global_delete, tsubst_flags_t complain)
{
  tree t, type;

  if (exp == error_mark_node)
    return exp;

  if (processing_template_decl)
    {
      t = build_min (DELETE_EXPR, void_type_node, exp, size);
      DELETE_EXPR_USE_GLOBAL (t) = use_global_delete;
      DELETE_EXPR_USE_VEC (t) = doing_vec;
      TREE_SIDE_EFFECTS (t) = 1;
      SET_EXPR_LOCATION (t, loc);
      return t;
    }

  location_t exp_loc = cp_expr_loc_or_loc (exp, loc);

  /* An array can't have been allocated by new, so complain.  */
  if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
      && (complain & tf_warning))
    warning_at (exp_loc, 0, "deleting array %q#E", exp);

  t = build_expr_type_conversion (WANT_POINTER, exp, true);

  if (t == NULL_TREE || t == error_mark_node)
    {
      if (complain & tf_error)
	error_at (exp_loc,
		  "type %q#T argument given to %<delete%>, expected pointer",
		  TREE_TYPE (exp));
      return error_mark_node;
    }

  type = TREE_TYPE (t);

  /* As of Valley Forge, you can delete a pointer to const.  */

  /* You can't delete functions.  */
  if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
    {
      if (complain & tf_error)
	error_at (exp_loc,
		  "cannot delete a function.  Only pointer-to-objects are "
		  "valid arguments to %<delete%>");
      return error_mark_node;
    }

  /* Deleting ptr to void is undefined behavior [expr.delete/3].  */
  if (VOID_TYPE_P (TREE_TYPE (type)))
    {
      if (complain & tf_warning)
	warning_at (exp_loc, OPT_Wdelete_incomplete,
		    "deleting %qT is undefined", type);
      doing_vec = 0;
    }

  /* Deleting a pointer with the value zero is valid and has no effect.  */
  if (integer_zerop (t))
    return build1_loc (loc, NOP_EXPR, void_type_node, t);

  if (doing_vec)
    return build_vec_delete (loc, t, /*maxindex=*/NULL_TREE,
			     sfk_deleting_destructor,
			     use_global_delete, complain);
  else
    return build_delete (loc, type, t, sfk_deleting_destructor,
			 LOOKUP_NORMAL, use_global_delete,
			 complain);
}

/* Report an error if the indicated template declaration is not the
   sort of thing that should be a member template.  */

void
check_member_template (tree tmpl)
{
  tree decl;

  gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
  decl = DECL_TEMPLATE_RESULT (tmpl);

  if (TREE_CODE (decl) == FUNCTION_DECL
      || DECL_ALIAS_TEMPLATE_P (tmpl)
      || (TREE_CODE (decl) == TYPE_DECL
	  && MAYBE_CLASS_TYPE_P (TREE_TYPE (decl))))
    {
      /* The parser rejects template declarations in local classes
	 (with the exception of generic lambdas).  */
      gcc_assert (!current_function_decl || LAMBDA_FUNCTION_P (decl));
      /* The parser rejects any use of virtual in a function template.  */
      gcc_assert (!(TREE_CODE (decl) == FUNCTION_DECL
		    && DECL_VIRTUAL_P (decl)));

      /* The debug-information generating code doesn't know what to do
	 with member templates.  */
      DECL_IGNORED_P (tmpl) = 1;
    }
  else if (variable_template_p (tmpl))
    /* OK */;
  else
    error ("template declaration of %q#D", decl);
}

/* Sanity check: report error if this function FUNCTION is not
   really a member of the class (CTYPE) it is supposed to belong to.
   TEMPLATE_PARMS is used to specify the template parameters of a member
   template passed as FUNCTION_DECL. If the member template is passed as a
   TEMPLATE_DECL, it can be NULL since the parameters can be extracted
   from the declaration. If the function is not a function template, it
   must be NULL.
   It returns the original declaration for the function, NULL_TREE if
   no declaration was found, error_mark_node if an error was emitted.  */

tree
check_classfn (tree ctype, tree function, tree template_parms)
{
  if (DECL_USE_TEMPLATE (function)
      && !(TREE_CODE (function) == TEMPLATE_DECL
	   && DECL_TEMPLATE_SPECIALIZATION (function))
      && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (function)))
    /* Since this is a specialization of a member template,
       we're not going to find the declaration in the class.
       For example, in:

	 struct S { template <typename T> void f(T); };
	 template <> void S::f(int);

       we're not going to find `S::f(int)', but there's no
       reason we should, either.  We let our callers know we didn't
       find the method, but we don't complain.  */
    return NULL_TREE;

  /* Basic sanity check: for a template function, the template parameters
     either were not passed, or they are the same of DECL_TEMPLATE_PARMS.  */
  if (TREE_CODE (function) == TEMPLATE_DECL)
    {
      if (template_parms
	  && !comp_template_parms (template_parms,
				   DECL_TEMPLATE_PARMS (function)))
	{
	  error ("template parameter lists provided don%'t match the "
		 "template parameters of %qD", function);
	  return error_mark_node;
	}
      template_parms = DECL_TEMPLATE_PARMS (function);
    }

  /* OK, is this a definition of a member template?  */
  bool is_template = (template_parms != NULL_TREE);

  /* [temp.mem]

     A destructor shall not be a member template.  */
  if (DECL_DESTRUCTOR_P (function) && is_template)
    {
      error ("destructor %qD declared as member template", function);
      return error_mark_node;
    }

  /* We must enter the scope here, because conversion operators are
     named by target type, and type equivalence relies on typenames
     resolving within the scope of CTYPE.  */
  tree pushed_scope = push_scope (ctype);
  tree matched = NULL_TREE;
  tree fns = get_class_binding (ctype, DECL_NAME (function));
  
  for (ovl_iterator iter (fns); !matched && iter; ++iter)
    {
      tree fndecl = *iter;

      /* A member template definition only matches a member template
	 declaration.  */
      if (is_template != (TREE_CODE (fndecl) == TEMPLATE_DECL))
	continue;

      if (!DECL_DECLARES_FUNCTION_P (fndecl))
	continue;

      tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
      tree p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl));

      /* We cannot simply call decls_match because this doesn't work
	 for static member functions that are pretending to be
	 methods, and because the name may have been changed by
	 asm("new_name").  */

      /* Get rid of the this parameter on functions that become
	 static.  */
      if (DECL_STATIC_FUNCTION_P (fndecl)
	  && TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
	p1 = TREE_CHAIN (p1);

      /* ref-qualifier or absence of same must match.  */
      if (type_memfn_rqual (TREE_TYPE (function))
	  != type_memfn_rqual (TREE_TYPE (fndecl)))
	continue;

      // Include constraints in the match.
      tree c1 = get_constraints (function);
      tree c2 = get_constraints (fndecl);

      /* While finding a match, same types and params are not enough
	 if the function is versioned.  Also check version ("target")
	 attributes.  */
      if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
		       TREE_TYPE (TREE_TYPE (fndecl)))
	  && compparms (p1, p2)
	  && !targetm.target_option.function_versions (function, fndecl)
	  && (!is_template
	      || comp_template_parms (template_parms,
				      DECL_TEMPLATE_PARMS (fndecl)))
	  && equivalent_constraints (c1, c2)
	  && (DECL_TEMPLATE_SPECIALIZATION (function)
	      == DECL_TEMPLATE_SPECIALIZATION (fndecl))
	  && (!DECL_TEMPLATE_SPECIALIZATION (function)
	      || (DECL_TI_TEMPLATE (function) == DECL_TI_TEMPLATE (fndecl))))
	matched = fndecl;
    }

  if (!matched)
    {
      if (!COMPLETE_TYPE_P (ctype))
	cxx_incomplete_type_error (DECL_SOURCE_LOCATION (function),
				   function, ctype);
      else
	{
	  if (DECL_CONV_FN_P (function))
	    fns = get_class_binding (ctype, conv_op_identifier);

	  error_at (DECL_SOURCE_LOCATION (function),
		    "no declaration matches %q#D", function);
	  if (fns)
	    print_candidates (fns);
	  else if (DECL_CONV_FN_P (function))
	    inform (DECL_SOURCE_LOCATION (function),
		    "no conversion operators declared");
	  else
	    inform (DECL_SOURCE_LOCATION (function),
		    "no functions named %qD", function);
	  inform (DECL_SOURCE_LOCATION (TYPE_NAME (ctype)),
		  "%#qT defined here", ctype);
	}
      matched = error_mark_node;
    }

  if (pushed_scope)
    pop_scope (pushed_scope);

  return matched;
}

/* DECL is a function with vague linkage.  Remember it so that at the
   end of the translation unit we can decide whether or not to emit
   it.  */

void
note_vague_linkage_fn (tree decl)
{
  if (processing_template_decl)
    return;

  DECL_DEFER_OUTPUT (decl) = 1;
  vec_safe_push (deferred_fns, decl);
}

/* As above, but for variable template instantiations.  */

void
note_variable_template_instantiation (tree decl)
{
  vec_safe_push (pending_statics, decl);
}

/* We have just processed the DECL, which is a static data member.
   The other parameters are as for cp_finish_decl.  */

void
finish_static_data_member_decl (tree decl,
				tree init, bool init_const_expr_p,
				tree asmspec_tree,
				int flags)
{
  if (DECL_TEMPLATE_INSTANTIATED (decl))
    /* We already needed to instantiate this, so the processing in this
       function is unnecessary/wrong.  */
    return;

  DECL_CONTEXT (decl) = current_class_type;

  /* We cannot call pushdecl here, because that would fill in the
     TREE_CHAIN of our decl.  Instead, we modify cp_finish_decl to do
     the right thing, namely, to put this decl out straight away.  */

  if (! processing_template_decl)
    vec_safe_push (pending_statics, decl);

  if (LOCAL_CLASS_P (current_class_type)
      /* We already complained about the template definition.  */
      && !DECL_TEMPLATE_INSTANTIATION (decl))
    permerror (DECL_SOURCE_LOCATION (decl),
	       "local class %q#T shall not have static data member %q#D",
	       current_class_type, decl);
  else
    for (tree t = current_class_type; TYPE_P (t);
	 t = CP_TYPE_CONTEXT (t))
      if (TYPE_UNNAMED_P (t))
	{
	  auto_diagnostic_group d;
	  if (permerror (DECL_SOURCE_LOCATION (decl),
			 "static data member %qD in unnamed class", decl))
	    inform (DECL_SOURCE_LOCATION (TYPE_NAME (t)),
		    "unnamed class defined here");
	  break;
	}

  if (DECL_INLINE_VAR_P (decl) && !DECL_TEMPLATE_INSTANTIATION (decl))
    /* An inline variable is immediately defined, so don't set DECL_IN_AGGR_P.
       Except that if decl is a template instantiation, it isn't defined until
       instantiate_decl.  */;
  else
    DECL_IN_AGGR_P (decl) = 1;

  if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
      && TYPE_DOMAIN (TREE_TYPE (decl)) == NULL_TREE)
    SET_VAR_HAD_UNKNOWN_BOUND (decl);

  if (init)
    {
      /* Similarly to start_decl_1, we want to complete the type in order
	 to do the right thing in cp_apply_type_quals_to_decl, possibly
	 clear TYPE_QUAL_CONST (c++/65579).  */
      tree type = TREE_TYPE (decl) = complete_type (TREE_TYPE (decl));
      cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
    }

  cp_finish_decl (decl, init, init_const_expr_p, asmspec_tree, flags);
}

/* DECLARATOR and DECLSPECS correspond to a class member.  The other
   parameters are as for cp_finish_decl.  Return the DECL for the
   class member declared.  */

tree
grokfield (const cp_declarator *declarator,
	   cp_decl_specifier_seq *declspecs,
	   tree init, bool init_const_expr_p,
	   tree asmspec_tree,
	   tree attrlist)
{
  tree value;
  const char *asmspec = 0;
  int flags;

  if (init
      && TREE_CODE (init) == TREE_LIST
      && TREE_VALUE (init) == error_mark_node
      && TREE_CHAIN (init) == NULL_TREE)
    init = NULL_TREE;

  int initialized;
  if (init == ridpointers[(int)RID_DELETE])
    initialized = SD_DELETED;
  else if (init == ridpointers[(int)RID_DEFAULT])
    initialized = SD_DEFAULTED;
  else if (init)
    initialized = SD_INITIALIZED;
  else
    initialized = SD_UNINITIALIZED;

  value = grokdeclarator (declarator, declspecs, FIELD, initialized, &attrlist);
  if (! value || value == error_mark_node)
    /* friend or constructor went bad.  */
    return error_mark_node;
  if (TREE_TYPE (value) == error_mark_node)
    return value;

  if (TREE_CODE (value) == TYPE_DECL && init)
    {
      error_at (cp_expr_loc_or_loc (init, DECL_SOURCE_LOCATION (value)),
		"typedef %qD is initialized (use %qs instead)",
		value, "decltype");
      init = NULL_TREE;
    }

  /* Pass friendly classes back.  */
  if (value == void_type_node)
    return value;

  if (DECL_NAME (value)
      && TREE_CODE (DECL_NAME (value)) == TEMPLATE_ID_EXPR)
    {
      error_at (declarator->id_loc,
		"explicit template argument list not allowed");
      return error_mark_node;
    }

  /* Stash away type declarations.  */
  if (TREE_CODE (value) == TYPE_DECL)
    {
      DECL_NONLOCAL (value) = 1;
      DECL_CONTEXT (value) = current_class_type;

      if (attrlist)
	{
	  int attrflags = 0;

	  /* If this is a typedef that names the class for linkage purposes
	     (7.1.3p8), apply any attributes directly to the type.  */
	  if (OVERLOAD_TYPE_P (TREE_TYPE (value))
	      && value == TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (value))))
	    attrflags = ATTR_FLAG_TYPE_IN_PLACE;

	  cplus_decl_attributes (&value, attrlist, attrflags);
	}

      if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)
          && TREE_TYPE (value) != error_mark_node
          && TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (value))) != value)
	set_underlying_type (value);

      /* It's important that push_template_decl below follows
	 set_underlying_type above so that the created template
	 carries the properly set type of VALUE.  */
      if (processing_template_decl)
	value = push_template_decl (value);

      record_locally_defined_typedef (value);
      return value;
    }

  int friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend);

  if (!friendp && DECL_IN_AGGR_P (value))
    {
      error ("%qD is already defined in %qT", value, DECL_CONTEXT (value));
      return void_type_node;
    }

  if (asmspec_tree && asmspec_tree != error_mark_node)
    asmspec = TREE_STRING_POINTER (asmspec_tree);

  if (init)
    {
      if (TREE_CODE (value) == FUNCTION_DECL)
	{
	  if (init == ridpointers[(int)RID_DELETE])
	    {
	      DECL_DELETED_FN (value) = 1;
	      DECL_DECLARED_INLINE_P (value) = 1;
	    }
	  else if (init == ridpointers[(int)RID_DEFAULT])
	    {
	      if (defaultable_fn_check (value))
		{
		  DECL_DEFAULTED_FN (value) = 1;
		  DECL_INITIALIZED_IN_CLASS_P (value) = 1;
		  DECL_DECLARED_INLINE_P (value) = 1;
		  /* grokfndecl set this to error_mark_node, but we want to
		     leave it unset until synthesize_method.  */
		  DECL_INITIAL (value) = NULL_TREE;
		}
	    }
	  else if (TREE_CODE (init) == DEFERRED_PARSE)
	    error ("invalid initializer for member function %qD", value);
	  else if (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE)
	    {
	      if (integer_zerop (init))
		DECL_PURE_VIRTUAL_P (value) = 1;
	      else if (error_operand_p (init))
		; /* An error has already been reported.  */
	      else
		error ("invalid initializer for member function %qD",
		       value);
	    }
	  else
	    {
	      gcc_assert (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE);
	      location_t iloc
		= cp_expr_loc_or_loc (init, DECL_SOURCE_LOCATION (value));
	      if (friendp)
		error_at (iloc, "initializer specified for friend "
			  "function %qD", value);
	      else
		error_at (iloc, "initializer specified for static "
			  "member function %qD", value);
	    }
	}
      else if (TREE_CODE (value) == FIELD_DECL)
	/* C++11 NSDMI, keep going.  */;
      else if (!VAR_P (value))
	gcc_unreachable ();
    }

  /* Pass friend decls back.  */
  if ((TREE_CODE (value) == FUNCTION_DECL
       || TREE_CODE (value) == TEMPLATE_DECL)
      && DECL_CONTEXT (value) != current_class_type)
    {
      if (attrlist)
	cplus_decl_attributes (&value, attrlist, 0);
      return value;
    }

  /* Need to set this before push_template_decl.  */
  if (VAR_P (value))
    DECL_CONTEXT (value) = current_class_type;

  if (processing_template_decl && VAR_OR_FUNCTION_DECL_P (value))
    {
      value = push_template_decl (value);
      if (error_operand_p (value))
	return error_mark_node;
    }

  if (attrlist)
    cplus_decl_attributes (&value, attrlist, 0);

  if (init && DIRECT_LIST_INIT_P (init))
    flags = LOOKUP_NORMAL;
  else
    flags = LOOKUP_IMPLICIT;

  switch (TREE_CODE (value))
    {
    case VAR_DECL:
      finish_static_data_member_decl (value, init, init_const_expr_p,
				      asmspec_tree, flags);
      return value;

    case FIELD_DECL:
      if (asmspec)
	error ("%<asm%> specifiers are not permitted on non-static data members");
      if (DECL_INITIAL (value) == error_mark_node)
	init = error_mark_node;
      cp_finish_decl (value, init, /*init_const_expr_p=*/false,
		      NULL_TREE, flags);
      DECL_IN_AGGR_P (value) = 1;
      return value;

    case  FUNCTION_DECL:
      if (asmspec)
	set_user_assembler_name (value, asmspec);

      cp_finish_decl (value,
		      /*init=*/NULL_TREE,
		      /*init_const_expr_p=*/false,
		      asmspec_tree, flags);

      /* Pass friends back this way.  */
      if (DECL_UNIQUE_FRIEND_P (value))
	return void_type_node;

      DECL_IN_AGGR_P (value) = 1;
      return value;

    default:
      gcc_unreachable ();
    }
  return NULL_TREE;
}

/* Like `grokfield', but for bitfields.
   WIDTH is the width of the bitfield, a constant expression.
   The other parameters are as for grokfield.  */

tree
grokbitfield (const cp_declarator *declarator,
	      cp_decl_specifier_seq *declspecs, tree width, tree init,
	      tree attrlist)
{
  tree value = grokdeclarator (declarator, declspecs, BITFIELD,
			       init != NULL_TREE, &attrlist);

  if (value == error_mark_node)
    return NULL_TREE; /* friends went bad.  */

  tree type = TREE_TYPE (value);
  if (type == error_mark_node)
    return value;

  /* Pass friendly classes back.  */
  if (VOID_TYPE_P (value))
    return void_type_node;

  if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type)
      && (INDIRECT_TYPE_P (type) || !dependent_type_p (type)))
    {
      error_at (DECL_SOURCE_LOCATION (value),
		"bit-field %qD with non-integral type %qT",
		value, type);
      return error_mark_node;
    }

  if (TREE_CODE (value) == TYPE_DECL)
    {
      error_at (DECL_SOURCE_LOCATION (value),
		"cannot declare %qD to be a bit-field type", value);
      return NULL_TREE;
    }

  /* Usually, finish_struct_1 catches bitfields with invalid types.
     But, in the case of bitfields with function type, we confuse
     ourselves into thinking they are member functions, so we must
     check here.  */
  if (TREE_CODE (value) == FUNCTION_DECL)
    {
      error_at (DECL_SOURCE_LOCATION (value),
		"cannot declare bit-field %qD with function type", value);
      return NULL_TREE;
    }

  if (TYPE_WARN_IF_NOT_ALIGN (type))
    {
      error_at (DECL_SOURCE_LOCATION (value), "cannot declare bit-field "
		"%qD with %<warn_if_not_aligned%> type", value);
      return NULL_TREE;
    }

  if (DECL_IN_AGGR_P (value))
    {
      error ("%qD is already defined in the class %qT", value,
	     DECL_CONTEXT (value));
      return void_type_node;
    }

  if (TREE_STATIC (value))
    {
      error_at (DECL_SOURCE_LOCATION (value),
		"static member %qD cannot be a bit-field", value);
      return NULL_TREE;
    }

  int flags = LOOKUP_IMPLICIT;
  if (init && DIRECT_LIST_INIT_P (init))
    flags = LOOKUP_NORMAL;
  cp_finish_decl (value, init, false, NULL_TREE, flags);

  if (width != error_mark_node)
    {
      /* The width must be an integer type.  */
      if (!type_dependent_expression_p (width)
	  && !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (width)))
	error ("width of bit-field %qD has non-integral type %qT", value,
	       TREE_TYPE (width));
      else if (!check_for_bare_parameter_packs (width))
	{
	  /* Temporarily stash the width in DECL_BIT_FIELD_REPRESENTATIVE.
	     check_bitfield_decl picks it from there later and sets DECL_SIZE
	     accordingly.  */
	  DECL_BIT_FIELD_REPRESENTATIVE (value) = width;
	  SET_DECL_C_BIT_FIELD (value);
	}
    }

  DECL_IN_AGGR_P (value) = 1;

  if (attrlist)
    cplus_decl_attributes (&value, attrlist, /*flags=*/0);

  return value;
}


/* Returns true iff ATTR is an attribute which needs to be applied at
   instantiation time rather than template definition time.  */

static bool
is_late_template_attribute (tree attr, tree decl)
{
  tree name = get_attribute_name (attr);
  tree args = TREE_VALUE (attr);
  const struct attribute_spec *spec = lookup_attribute_spec (name);
  tree arg;

  if (!spec)
    /* Unknown attribute.  */
    return false;

  /* Attribute weak handling wants to write out assembly right away.  */
  if (is_attribute_p ("weak", name))
    return true;

  /* Attributes used and unused are applied directly to typedefs for the
     benefit of maybe_warn_unused_local_typedefs.  */
  if (TREE_CODE (decl) == TYPE_DECL
      && (is_attribute_p ("unused", name)
	  || is_attribute_p ("used", name)))
    return false;

  /* Attribute tls_model wants to modify the symtab.  */
  if (is_attribute_p ("tls_model", name))
    return true;

  /* #pragma omp declare simd attribute needs to be always deferred.  */
  if (flag_openmp
      && is_attribute_p ("omp declare simd", name))
    return true;

  if (args == error_mark_node)
    return false;

  /* An attribute pack is clearly dependent.  */
  if (args && PACK_EXPANSION_P (args))
    return true;

  /* If any of the arguments are dependent expressions, we can't evaluate
     the attribute until instantiation time.  */
  for (arg = args; arg; arg = TREE_CHAIN (arg))
    {
      tree t = TREE_VALUE (arg);

      /* If the first attribute argument is an identifier, only consider
	 second and following arguments.  Attributes like mode, format,
	 cleanup and several target specific attributes aren't late
	 just because they have an IDENTIFIER_NODE as first argument.  */
      if (arg == args && attribute_takes_identifier_p (name)
	  && identifier_p (t))
	continue;

      if (value_dependent_expression_p (t))
	return true;
    }

  if (TREE_CODE (decl) == TYPE_DECL
      || TYPE_P (decl)
      || spec->type_required)
    {
      tree type = TYPE_P (decl) ? decl : TREE_TYPE (decl);

      /* We can't apply any attributes to a completely unknown type until
	 instantiation time.  */
      enum tree_code code = TREE_CODE (type);
      if (code == TEMPLATE_TYPE_PARM
	  || code == BOUND_TEMPLATE_TEMPLATE_PARM
	  || code == TYPENAME_TYPE)
	return true;
      /* Also defer most attributes on dependent types.  This is not
	 necessary in all cases, but is the better default.  */
      else if (dependent_type_p (type)
	       /* But some attributes specifically apply to templates.  */
	       && !is_attribute_p ("abi_tag", name)
	       && !is_attribute_p ("deprecated", name)
	       && !is_attribute_p ("visibility", name))
	return true;
      else
	return false;
    }
  else
    return false;
}

/* ATTR_P is a list of attributes.  Remove any attributes which need to be
   applied at instantiation time and return them.  If IS_DEPENDENT is true,
   the declaration itself is dependent, so all attributes should be applied
   at instantiation time.  */

tree
splice_template_attributes (tree *attr_p, tree decl)
{
  tree *p = attr_p;
  tree late_attrs = NULL_TREE;
  tree *q = &late_attrs;

  if (!p)
    return NULL_TREE;

  for (; *p; )
    {
      if (is_late_template_attribute (*p, decl))
	{
	  ATTR_IS_DEPENDENT (*p) = 1;
	  *q = *p;
	  *p = TREE_CHAIN (*p);
	  q = &TREE_CHAIN (*q);
	  *q = NULL_TREE;
	}
      else
	p = &TREE_CHAIN (*p);
    }

  return late_attrs;
}

/* Remove any late attributes from the list in ATTR_P and attach them to
   DECL_P.  */

static void
save_template_attributes (tree *attr_p, tree *decl_p, int flags)
{
  tree *q;

  if (attr_p && *attr_p == error_mark_node)
    return;

  tree late_attrs = splice_template_attributes (attr_p, *decl_p);
  if (!late_attrs)
    return;

  if (DECL_P (*decl_p))
    q = &DECL_ATTRIBUTES (*decl_p);
  else
    q = &TYPE_ATTRIBUTES (*decl_p);

  tree old_attrs = *q;

  /* Place the late attributes at the beginning of the attribute
     list.  */
  late_attrs = chainon (late_attrs, *q);
  if (*q != late_attrs
      && !DECL_P (*decl_p)
      && !(flags & ATTR_FLAG_TYPE_IN_PLACE))
    {
      if (!dependent_type_p (*decl_p))
	*decl_p = cp_build_type_attribute_variant (*decl_p, late_attrs);
      else
	{
	  *decl_p = build_variant_type_copy (*decl_p);
	  TYPE_ATTRIBUTES (*decl_p) = late_attrs;
	}
    }
  else
    *q = late_attrs;

  if (!DECL_P (*decl_p) && *decl_p == TYPE_MAIN_VARIANT (*decl_p))
    {
      /* We've added new attributes directly to the main variant, so
	 now we need to update all of the other variants to include
	 these new attributes.  */
      tree variant;
      for (variant = TYPE_NEXT_VARIANT (*decl_p); variant;
	   variant = TYPE_NEXT_VARIANT (variant))
	{
	  gcc_assert (TYPE_ATTRIBUTES (variant) == old_attrs);
	  TYPE_ATTRIBUTES (variant) = TYPE_ATTRIBUTES (*decl_p);
	}
    }
}

/* True if ATTRS contains any dependent attributes that affect type
   identity.  */

bool
any_dependent_type_attributes_p (tree attrs)
{
  for (tree a = attrs; a; a = TREE_CHAIN (a))
    if (ATTR_IS_DEPENDENT (a))
      {
	const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (a));
	if (as && as->affects_type_identity)
	  return true;
      }
  return false;
}

/* Return true iff ATTRS are acceptable attributes to be applied in-place
   to a typedef which gives a previously unnamed class or enum a name for
   linkage purposes.  */

bool
attributes_naming_typedef_ok (tree attrs)
{
  for (; attrs; attrs = TREE_CHAIN (attrs))
    {
      tree name = get_attribute_name (attrs);
      if (is_attribute_p ("vector_size", name))
	return false;
    }
  return true;
}

/* Like reconstruct_complex_type, but handle also template trees.  */

tree
cp_reconstruct_complex_type (tree type, tree bottom)
{
  tree inner, outer;

  if (TYPE_PTR_P (type))
    {
      inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
      outer = build_pointer_type_for_mode (inner, TYPE_MODE (type),
					   TYPE_REF_CAN_ALIAS_ALL (type));
    }
  else if (TYPE_REF_P (type))
    {
      inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
      outer = build_reference_type_for_mode (inner, TYPE_MODE (type),
					     TYPE_REF_CAN_ALIAS_ALL (type));
    }
  else if (TREE_CODE (type) == ARRAY_TYPE)
    {
      inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
      outer = build_cplus_array_type (inner, TYPE_DOMAIN (type));
      /* Don't call cp_build_qualified_type on ARRAY_TYPEs, the
	 element type qualification will be handled by the recursive
	 cp_reconstruct_complex_type call and cp_build_qualified_type
	 for ARRAY_TYPEs changes the element type.  */
      return outer;
    }
  else if (TREE_CODE (type) == FUNCTION_TYPE)
    {
      inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
      outer = build_function_type (inner, TYPE_ARG_TYPES (type));
      outer = apply_memfn_quals (outer, type_memfn_quals (type));
    }
  else if (TREE_CODE (type) == METHOD_TYPE)
    {
      inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
      /* The build_method_type_directly() routine prepends 'this' to argument list,
	 so we must compensate by getting rid of it.  */
      outer
	= build_method_type_directly
	    (class_of_this_parm (type), inner,
	     TREE_CHAIN (TYPE_ARG_TYPES (type)));
    }
  else if (TREE_CODE (type) == OFFSET_TYPE)
    {
      inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom);
      outer = build_offset_type (TYPE_OFFSET_BASETYPE (type), inner);
    }
  else
    return bottom;

  if (TYPE_ATTRIBUTES (type))
    outer = cp_build_type_attribute_variant (outer, TYPE_ATTRIBUTES (type));
  outer = cp_build_qualified_type (outer, cp_type_quals (type));
  outer = cxx_copy_lang_qualifiers (outer, type);

  return outer;
}

/* Replaces any constexpr expression that may be into the attributes
   arguments with their reduced value.  */

void
cp_check_const_attributes (tree attributes)
{
  if (attributes == error_mark_node)
    return;

  tree attr;
  for (attr = attributes; attr; attr = TREE_CHAIN (attr))
    {
      tree arg;
      for (arg = TREE_VALUE (attr); arg && TREE_CODE (arg) == TREE_LIST;
	   arg = TREE_CHAIN (arg))
	{
	  tree expr = TREE_VALUE (arg);
	  if (EXPR_P (expr))
	    TREE_VALUE (arg) = fold_non_dependent_expr (expr);
	}
    }
}

/* Return true if TYPE is an OpenMP mappable type.
   If NOTES is non-zero, emit a note message for each problem.  */
static bool
cp_omp_mappable_type_1 (tree type, bool notes)
{
  bool result = true;

  /* Mappable type has to be complete.  */
  if (type == error_mark_node || !COMPLETE_TYPE_P (type))
    {
      if (notes && type != error_mark_node)
	{
	  tree decl = TYPE_MAIN_DECL (type);
	  inform ((decl ? DECL_SOURCE_LOCATION (decl) : input_location),
		  "incomplete type %qT is not mappable", type);
	}
      result = false;
    }
  /* Arrays have mappable type if the elements have mappable type.  */
  while (TREE_CODE (type) == ARRAY_TYPE)
    type = TREE_TYPE (type);
  /* A mappable type cannot contain virtual members.  */
  if (CLASS_TYPE_P (type) && CLASSTYPE_VTABLES (type))
    {
      if (notes)
	inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
		"type %qT with virtual members is not mappable", type);
      result = false;
    }
  /* All data members must be non-static.  */
  if (CLASS_TYPE_P (type))
    {
      tree field;
      for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
	if (VAR_P (field))
	  {
	    if (notes)
	      inform (DECL_SOURCE_LOCATION (field),
		      "static field %qD is not mappable", field);
	    result = false;
	  }
	/* All fields must have mappable types.  */
	else if (TREE_CODE (field) == FIELD_DECL
		 && !cp_omp_mappable_type_1 (TREE_TYPE (field), notes))
	  result = false;
    }
  return result;
}

/* Return true if TYPE is an OpenMP mappable type.  */
bool
cp_omp_mappable_type (tree type)
{
  return cp_omp_mappable_type_1 (type, false);
}

/* Return true if TYPE is an OpenMP mappable type.
   Emit an error messages if not.  */
bool
cp_omp_emit_unmappable_type_notes (tree type)
{
  return cp_omp_mappable_type_1 (type, true);
}

/* Return the last pushed declaration for the symbol DECL or NULL
   when no such declaration exists.  */

static tree
find_last_decl (tree decl)
{
  tree last_decl = NULL_TREE;

  if (tree name = DECL_P (decl) ? DECL_NAME (decl) : NULL_TREE)
    {
      /* Look up the declaration in its scope.  */
      tree pushed_scope = NULL_TREE;
      if (tree ctype = DECL_CONTEXT (decl))
	pushed_scope = push_scope (ctype);

      last_decl = lookup_name (name);

      if (pushed_scope)
	pop_scope (pushed_scope);

      /* The declaration may be a member conversion operator
	 or a bunch of overfloads (handle the latter below).  */
      if (last_decl && BASELINK_P (last_decl))
	last_decl = BASELINK_FUNCTIONS (last_decl);
    }

  if (!last_decl)
    return NULL_TREE;

  if (DECL_P (last_decl) || TREE_CODE (last_decl) == OVERLOAD)
    {
      /* A set of overloads of the same function.  */
      for (lkp_iterator iter (last_decl); iter; ++iter)
	{
	  if (TREE_CODE (*iter) == OVERLOAD)
	    continue;

	  if (decls_match (decl, *iter, /*record_decls=*/false))
	    return *iter;
	}
      return NULL_TREE;
    }

  return NULL_TREE;
}

/* Like decl_attributes, but handle C++ complexity.  */

void
cplus_decl_attributes (tree *decl, tree attributes, int flags)
{
  if (*decl == NULL_TREE || *decl == void_type_node
      || *decl == error_mark_node)
    return;

  /* Add implicit "omp declare target" attribute if requested.  */
  if (vec_safe_length (scope_chain->omp_declare_target_attribute)
      && ((VAR_P (*decl)
	   && (TREE_STATIC (*decl) || DECL_EXTERNAL (*decl)))
	  || TREE_CODE (*decl) == FUNCTION_DECL))
    {
      if (VAR_P (*decl)
	  && DECL_CLASS_SCOPE_P (*decl))
	error ("%q+D static data member inside of declare target directive",
	       *decl);
      else if (VAR_P (*decl)
	       && (processing_template_decl
		   || !cp_omp_mappable_type (TREE_TYPE (*decl))))
	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);
	}
    }

  if (processing_template_decl)
    {
      if (check_for_bare_parameter_packs (attributes))
	return;

      save_template_attributes (&attributes, decl, flags);
    }

  cp_check_const_attributes (attributes);

  if ((flag_openmp || flag_openmp_simd) && attributes != error_mark_node)
    {
      bool diagnosed = false;
      for (tree *pa = &attributes; *pa; )
	{
	  if (get_attribute_namespace (*pa) == omp_identifier)
	    {
	      tree name = get_attribute_name (*pa);
	      if (is_attribute_p ("directive", name)
		  || is_attribute_p ("sequence", name))
		{
		  if (!diagnosed)
		    {
		      error ("%<omp::%E%> not allowed to be specified in this "
			     "context", name);
		      diagnosed = true;
		    }
		  *pa = TREE_CHAIN (*pa);
		  continue;
		}
	    }
	  pa = &TREE_CHAIN (*pa);
	}
    }

  if (TREE_CODE (*decl) == TEMPLATE_DECL)
    decl = &DECL_TEMPLATE_RESULT (*decl);

  if (TREE_TYPE (*decl) && TYPE_PTRMEMFUNC_P (TREE_TYPE (*decl)))
    {
      attributes
	= decl_attributes (decl, attributes, flags | ATTR_FLAG_FUNCTION_NEXT);
      decl_attributes (&TYPE_PTRMEMFUNC_FN_TYPE_RAW (TREE_TYPE (*decl)),
		       attributes, flags);
    }
  else
    {
      tree last_decl = find_last_decl (*decl);
      decl_attributes (decl, attributes, flags, last_decl);
    }

  /* Propagate deprecation out to the template.  */
  if (TREE_DEPRECATED (*decl))
    if (tree ti = get_template_info (*decl))
      {
	tree tmpl = TI_TEMPLATE (ti);
	tree pattern = (TYPE_P (*decl) ? TREE_TYPE (tmpl)
			: DECL_TEMPLATE_RESULT (tmpl));
	if (*decl == pattern)
	  TREE_DEPRECATED (tmpl) = true;
      }

  /* Likewise, propagate unavailability out to the template.  */
  if (TREE_UNAVAILABLE (*decl))
    if (tree ti = get_template_info (*decl))
      {
	tree tmpl = TI_TEMPLATE (ti);
	tree pattern = (TYPE_P (*decl) ? TREE_TYPE (tmpl)
			: DECL_TEMPLATE_RESULT (tmpl));
	if (*decl == pattern)
	  TREE_UNAVAILABLE (tmpl) = true;
      }
}

/* Walks through the namespace- or function-scope anonymous union
   OBJECT, with the indicated TYPE, building appropriate VAR_DECLs.
   Returns one of the fields for use in the mangled name.  */

static tree
build_anon_union_vars (tree type, tree object)
{
  tree main_decl = NULL_TREE;
  tree field;

  /* Rather than write the code to handle the non-union case,
     just give an error.  */
  if (TREE_CODE (type) != UNION_TYPE)
    {
      error_at (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
		"anonymous struct not inside named type");
      return error_mark_node;
    }

  for (field = TYPE_FIELDS (type);
       field != NULL_TREE;
       field = DECL_CHAIN (field))
    {
      tree decl;
      tree ref;

      if (DECL_ARTIFICIAL (field))
	continue;
      if (TREE_CODE (field) != FIELD_DECL)
	{
	  permerror (DECL_SOURCE_LOCATION (field),
		     "%q#D invalid; an anonymous union can only "
		     "have non-static data members", field);
	  continue;
	}

      if (TREE_PRIVATE (field))
	permerror (DECL_SOURCE_LOCATION (field),
		   "private member %q#D in anonymous union", field);
      else if (TREE_PROTECTED (field))
	permerror (DECL_SOURCE_LOCATION (field),
		   "protected member %q#D in anonymous union", field);

      if (processing_template_decl)
	ref = build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF, object,
				DECL_NAME (field), NULL_TREE);
      else
	ref = build_class_member_access_expr (object, field, NULL_TREE,
					      false, tf_warning_or_error);

      if (DECL_NAME (field))
	{
	  tree base;

	  decl = build_decl (input_location,
			     VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
	  DECL_ANON_UNION_VAR_P (decl) = 1;
	  DECL_ARTIFICIAL (decl) = 1;

	  base = get_base_address (object);
	  TREE_PUBLIC (decl) = TREE_PUBLIC (base);
	  TREE_STATIC (decl) = TREE_STATIC (base);
	  DECL_EXTERNAL (decl) = DECL_EXTERNAL (base);

	  SET_DECL_VALUE_EXPR (decl, ref);
	  DECL_HAS_VALUE_EXPR_P (decl) = 1;

	  decl = pushdecl (decl);
	}
      else if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
	decl = build_anon_union_vars (TREE_TYPE (field), ref);
      else
	decl = 0;

      if (main_decl == NULL_TREE)
	main_decl = decl;
    }

  return main_decl;
}

/* Finish off the processing of a UNION_TYPE structure.  If the union is an
   anonymous union, then all members must be laid out together.  PUBLIC_P
   is nonzero if this union is not declared static.  */

void
finish_anon_union (tree anon_union_decl)
{
  tree type;
  tree main_decl;
  bool public_p;

  if (anon_union_decl == error_mark_node)
    return;

  type = TREE_TYPE (anon_union_decl);
  public_p = TREE_PUBLIC (anon_union_decl);

  /* The VAR_DECL's context is the same as the TYPE's context.  */
  DECL_CONTEXT (anon_union_decl) = DECL_CONTEXT (TYPE_NAME (type));

  if (TYPE_FIELDS (type) == NULL_TREE)
    return;

  if (public_p)
    {
      error ("namespace-scope anonymous aggregates must be static");
      return;
    }

  main_decl = build_anon_union_vars (type, anon_union_decl);
  if (main_decl == error_mark_node)
    return;
  if (main_decl == NULL_TREE)
    {
      pedwarn (input_location, 0, "anonymous union with no members");
      return;
    }

  if (!processing_template_decl)
    {
      /* Use main_decl to set the mangled name.  */
      DECL_NAME (anon_union_decl) = DECL_NAME (main_decl);
      maybe_commonize_var (anon_union_decl);
      if (TREE_STATIC (anon_union_decl) || DECL_EXTERNAL (anon_union_decl))
	{
	  if (DECL_DISCRIMINATOR_P (anon_union_decl))
	    determine_local_discriminator (anon_union_decl);
	  mangle_decl (anon_union_decl);
	}
      DECL_NAME (anon_union_decl) = NULL_TREE;
    }

  pushdecl (anon_union_decl);
  cp_finish_decl (anon_union_decl, NULL_TREE, false, NULL_TREE, 0);
}

/* Auxiliary functions to make type signatures for
   `operator new' and `operator delete' correspond to
   what compiler will be expecting.  */

tree
coerce_new_type (tree type, location_t loc)
{
  int e = 0;
  tree args = TYPE_ARG_TYPES (type);

  gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);

  if (!same_type_p (TREE_TYPE (type), ptr_type_node))
    {
      e = 1;
      error_at (loc, "%<operator new%> must return type %qT",
		ptr_type_node);
    }

  if (args && args != void_list_node)
    {
      if (TREE_PURPOSE (args))
	{
	  /* [basic.stc.dynamic.allocation]
	     
	     The first parameter shall not have an associated default
	     argument.  */
	  error_at (loc, "the first parameter of %<operator new%> cannot "
		    "have a default argument");
	  /* Throw away the default argument.  */
	  TREE_PURPOSE (args) = NULL_TREE;
	}

      if (!same_type_p (TREE_VALUE (args), size_type_node))
	{
	  e = 2;
	  args = TREE_CHAIN (args);
	}
    }
  else
    e = 2;

  if (e == 2)
    permerror (loc, "%<operator new%> takes type %<size_t%> (%qT) "
	       "as first parameter", size_type_node);

  switch (e)
  {
    case 2:
      args = tree_cons (NULL_TREE, size_type_node, args);
      /* Fall through.  */
    case 1:
      type = (cxx_copy_lang_qualifiers
	      (build_function_type (ptr_type_node, args),
	       type));
      /* Fall through.  */
    default:;
  }
  return type;
}

void
coerce_delete_type (tree decl, location_t loc)
{
  int e = 0;
  tree type = TREE_TYPE (decl);
  tree args = TYPE_ARG_TYPES (type);

  gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);

  if (!same_type_p (TREE_TYPE (type), void_type_node))
    {
      e = 1;
      error_at (loc, "%<operator delete%> must return type %qT",
		void_type_node);
    }

  tree ptrtype = ptr_type_node;
  if (destroying_delete_p (decl))
    {
      if (DECL_CLASS_SCOPE_P (decl))
	/* If the function is a destroying operator delete declared in class
	   type C, the type of its first parameter shall be C*.  */
	ptrtype = build_pointer_type (DECL_CONTEXT (decl));
      else
	/* A destroying operator delete shall be a class member function named
	   operator delete.  */
	error_at (loc,
		  "destroying %<operator delete%> must be a member function");
      const ovl_op_info_t *op = IDENTIFIER_OVL_OP_INFO (DECL_NAME (decl));
      if (op->flags & OVL_OP_FLAG_VEC)
	error_at (loc, "%<operator delete[]%> cannot be a destroying delete");
      if (!usual_deallocation_fn_p (decl))
	error_at (loc, "destroying %<operator delete%> must be a usual "
		  "deallocation function");
    }

  if (!args || args == void_list_node
      || !same_type_p (TREE_VALUE (args), ptrtype))
    {
      e = 2;
      if (args && args != void_list_node)
	args = TREE_CHAIN (args);
      error_at (loc, "%<operator delete%> takes type %qT as first parameter",
		ptrtype);
    }
  switch (e)
  {
    case 2:
      args = tree_cons (NULL_TREE, ptrtype, args);
      /* Fall through.  */
    case 1:
      type = (cxx_copy_lang_qualifiers
	      (build_function_type (void_type_node, args),
	       type));
      /* Fall through.  */
    default:;
  }

  TREE_TYPE (decl) = type;
}

/* DECL is a VAR_DECL for a vtable: walk through the entries in the vtable
   and mark them as needed.  */

static void
mark_vtable_entries (tree decl, vec<tree> &consteval_vtables)
{
  tree fnaddr;
  unsigned HOST_WIDE_INT idx;

  /* It's OK for the vtable to refer to deprecated virtual functions.  */
  warning_sentinel w(warn_deprecated_decl);

  bool consteval_seen = false;

  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (decl)),
			      idx, fnaddr)
    {
      tree fn;

      STRIP_NOPS (fnaddr);

      if (TREE_CODE (fnaddr) != ADDR_EXPR
	  && TREE_CODE (fnaddr) != FDESC_EXPR)
	/* This entry is an offset: a virtual base class offset, a
	   virtual call offset, an RTTI offset, etc.  */
	continue;

      fn = TREE_OPERAND (fnaddr, 0);
      if (TREE_CODE (fn) == FUNCTION_DECL && DECL_IMMEDIATE_FUNCTION_P (fn))
	{
	  if (!consteval_seen)
	    {
	      consteval_seen = true;
	      consteval_vtables.safe_push (decl);
	    }
	  continue;
	}
      TREE_ADDRESSABLE (fn) = 1;
      /* When we don't have vcall offsets, we output thunks whenever
	 we output the vtables that contain them.  With vcall offsets,
	 we know all the thunks we'll need when we emit a virtual
	 function, so we emit the thunks there instead.  */
      if (DECL_THUNK_P (fn))
	use_thunk (fn, /*emit_p=*/0);
      /* Set the location, as marking the function could cause
         instantiation.  We do not need to preserve the incoming
         location, as we're called from c_parse_final_cleanups, which
         takes care of that.  */
      input_location = DECL_SOURCE_LOCATION (fn);
      mark_used (fn);
    }
}

/* Replace any consteval functions in vtables with null pointers.  */

static void
clear_consteval_vfns (vec<tree> &consteval_vtables)
{
  for (tree vtable : consteval_vtables)
    for (constructor_elt &elt : CONSTRUCTOR_ELTS (DECL_INITIAL (vtable)))
      {
	tree fn = cp_get_fndecl_from_callee (elt.value, /*fold*/false);
	if (fn && DECL_IMMEDIATE_FUNCTION_P (fn))
	  elt.value = build_zero_cst (vtable_entry_type);
      }
}

/* Adjust the TLS model on variable DECL if need be, typically after
   the linkage of DECL has been modified.  */

static void
adjust_var_decl_tls_model (tree decl)
{
  if (CP_DECL_THREAD_LOCAL_P (decl)
      && !lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl)))
    set_decl_tls_model (decl, decl_default_tls_model (decl));
}

/* Set DECL up to have the closest approximation of "initialized common"
   linkage available.  */

void
comdat_linkage (tree decl)
{
  if (flag_weak)
    make_decl_one_only (decl, cxx_comdat_group (decl));
  else if (TREE_CODE (decl) == FUNCTION_DECL
	   || (VAR_P (decl) && DECL_ARTIFICIAL (decl)))
    /* We can just emit function and compiler-generated variables
       statically; having multiple copies is (for the most part) only
       a waste of space.

       There are two correctness issues, however: the address of a
       template instantiation with external linkage should be the
       same, independent of what translation unit asks for the
       address, and this will not hold when we emit multiple copies of
       the function.  However, there's little else we can do.

       Also, by default, the typeinfo implementation assumes that
       there will be only one copy of the string used as the name for
       each type.  Therefore, if weak symbols are unavailable, the
       run-time library should perform a more conservative check; it
       should perform a string comparison, rather than an address
       comparison.  */
    TREE_PUBLIC (decl) = 0;
  else
    {
      /* Static data member template instantiations, however, cannot
	 have multiple copies.  */
      if (DECL_INITIAL (decl) == 0
	  || DECL_INITIAL (decl) == error_mark_node)
	DECL_COMMON (decl) = 1;
      else if (EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
	{
	  DECL_COMMON (decl) = 1;
	  DECL_INITIAL (decl) = error_mark_node;
	}
      else if (!DECL_EXPLICIT_INSTANTIATION (decl))
	{
	  /* We can't do anything useful; leave vars for explicit
	     instantiation.  */
	  DECL_EXTERNAL (decl) = 1;
	  DECL_NOT_REALLY_EXTERN (decl) = 0;
	}
    }

  if (TREE_PUBLIC (decl))
    DECL_COMDAT (decl) = 1;

  if (VAR_P (decl))
    adjust_var_decl_tls_model (decl);
}

/* For win32 we also want to put explicit instantiations in
   linkonce sections, so that they will be merged with implicit
   instantiations; otherwise we get duplicate symbol errors.
   For Darwin we do not want explicit instantiations to be
   linkonce.  */

void
maybe_make_one_only (tree decl)
{
  /* We used to say that this was not necessary on targets that support weak
     symbols, because the implicit instantiations will defer to the explicit
     one.  However, that's not actually the case in SVR4; a strong definition
     after a weak one is an error.  Also, not making explicit
     instantiations one_only means that we can end up with two copies of
     some template instantiations.  */
  if (! flag_weak)
    return;

  /* We can't set DECL_COMDAT on functions, or cp_finish_file will think
     we can get away with not emitting them if they aren't used.  We need
     to for variables so that cp_finish_decl will update their linkage,
     because their DECL_INITIAL may not have been set properly yet.  */

  if (!TARGET_WEAK_NOT_IN_ARCHIVE_TOC
      || (! DECL_EXPLICIT_INSTANTIATION (decl)
	  && ! DECL_TEMPLATE_SPECIALIZATION (decl)))
    {
      make_decl_one_only (decl, cxx_comdat_group (decl));

      if (VAR_P (decl))
	{
	  varpool_node *node = varpool_node::get_create (decl);
	  DECL_COMDAT (decl) = 1;
	  /* Mark it needed so we don't forget to emit it.  */
          node->forced_by_abi = true;
	  TREE_USED (decl) = 1;

	  adjust_var_decl_tls_model (decl);
	}
    }
}

/* Returns true iff DECL, a FUNCTION_DECL or VAR_DECL, has vague linkage.
   This predicate will give the right answer during parsing of the
   function, which other tests may not.  */

bool
vague_linkage_p (tree decl)
{
  if (!TREE_PUBLIC (decl))
    {
      /* maybe_thunk_body clears TREE_PUBLIC and DECL_ABSTRACT_P on the
	 maybe-in-charge 'tor variants; in that case we need to check one of
	 the "clones" for the real linkage.  But only in that case; before
	 maybe_clone_body we haven't yet copied the linkage to the clones.  */
      if (DECL_MAYBE_IN_CHARGE_CDTOR_P (decl)
	  && !DECL_ABSTRACT_P (decl)
	  && DECL_CHAIN (decl)
	  && DECL_CLONED_FUNCTION_P (DECL_CHAIN (decl)))
	return vague_linkage_p (DECL_CHAIN (decl));

      gcc_checking_assert (!DECL_COMDAT (decl));
      return false;
    }
  /* Unfortunately, import_export_decl has not always been called
     before the function is processed, so we cannot simply check
     DECL_COMDAT.  */
  if (DECL_COMDAT (decl)
      || (TREE_CODE (decl) == FUNCTION_DECL
	  && DECL_DECLARED_INLINE_P (decl))
      || (DECL_LANG_SPECIFIC (decl)
	  && DECL_TEMPLATE_INSTANTIATION (decl))
      || (VAR_P (decl) && DECL_INLINE_VAR_P (decl)))
    return true;
  else if (DECL_FUNCTION_SCOPE_P (decl))
    /* A local static in an inline effectively has vague linkage.  */
    return (TREE_STATIC (decl)
	    && vague_linkage_p (DECL_CONTEXT (decl)));
  else
    return false;
}

/* Determine whether or not we want to specifically import or export CTYPE,
   using various heuristics.  */

static void
import_export_class (tree ctype)
{
  /* -1 for imported, 1 for exported.  */
  int import_export = 0;

  /* It only makes sense to call this function at EOF.  The reason is
     that this function looks at whether or not the first non-inline
     non-abstract virtual member function has been defined in this
     translation unit.  But, we can't possibly know that until we've
     seen the entire translation unit.  */
  gcc_assert (at_eof);

  if (CLASSTYPE_INTERFACE_KNOWN (ctype))
    return;

  /* If MULTIPLE_SYMBOL_SPACES is set and we saw a #pragma interface,
     we will have CLASSTYPE_INTERFACE_ONLY set but not
     CLASSTYPE_INTERFACE_KNOWN.  In that case, we don't want to use this
     heuristic because someone will supply a #pragma implementation
     elsewhere, and deducing it here would produce a conflict.  */
  if (CLASSTYPE_INTERFACE_ONLY (ctype))
    return;

  if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype)))
    import_export = -1;
  else if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype)))
    import_export = 1;
  else if (CLASSTYPE_IMPLICIT_INSTANTIATION (ctype)
	   && !flag_implicit_templates)
    /* For a template class, without -fimplicit-templates, check the
       repository.  If the virtual table is assigned to this
       translation unit, then export the class; otherwise, import
       it.  */
      import_export = -1;
  else if (TYPE_POLYMORPHIC_P (ctype))
    {
      /* The ABI specifies that the virtual table and associated
	 information are emitted with the key method, if any.  */
      tree method = CLASSTYPE_KEY_METHOD (ctype);
      /* If weak symbol support is not available, then we must be
	 careful not to emit the vtable when the key function is
	 inline.  An inline function can be defined in multiple
	 translation units.  If we were to emit the vtable in each
	 translation unit containing a definition, we would get
	 multiple definition errors at link-time.  */
      if (method && (flag_weak || ! DECL_DECLARED_INLINE_P (method)))
	import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1);
    }

  /* When MULTIPLE_SYMBOL_SPACES is set, we cannot count on seeing
     a definition anywhere else.  */
  if (MULTIPLE_SYMBOL_SPACES && import_export == -1)
    import_export = 0;

  /* Allow back ends the chance to overrule the decision.  */
  if (targetm.cxx.import_export_class)
    import_export = targetm.cxx.import_export_class (ctype, import_export);

  if (import_export)
    {
      SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
      CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0);
    }
}

/* Return true if VAR has already been provided to the back end; in that
   case VAR should not be modified further by the front end.  */
static bool
var_finalized_p (tree var)
{
  return varpool_node::get_create (var)->definition;
}

/* DECL is a VAR_DECL or FUNCTION_DECL which, for whatever reason,
   must be emitted in this translation unit.  Mark it as such.  */

void
mark_needed (tree decl)
{
  TREE_USED (decl) = 1;
  if (TREE_CODE (decl) == FUNCTION_DECL)
    {
      /* Extern inline functions don't become needed when referenced.
	 If we know a method will be emitted in other TU and no new
	 functions can be marked reachable, just use the external
	 definition.  */
      struct cgraph_node *node = cgraph_node::get_create (decl);
      node->forced_by_abi = true;

      /* #pragma interface can call mark_needed for
          maybe-in-charge 'tors; mark the clones as well.  */
      tree clone;
      FOR_EACH_CLONE (clone, decl)
	mark_needed (clone);
    }
  else if (VAR_P (decl))
    {
      varpool_node *node = varpool_node::get_create (decl);
      /* C++ frontend use mark_decl_references to force COMDAT variables
         to be output that might appear dead otherwise.  */
      node->forced_by_abi = true;
    }
}

/* DECL is either a FUNCTION_DECL or a VAR_DECL.  This function
   returns true if a definition of this entity should be provided in
   this object file.  Callers use this function to determine whether
   or not to let the back end know that a definition of DECL is
   available in this translation unit.  */

bool
decl_needed_p (tree decl)
{
  gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
  /* This function should only be called at the end of the translation
     unit.  We cannot be sure of whether or not something will be
     COMDAT until that point.  */
  gcc_assert (at_eof);

  /* All entities with external linkage that are not COMDAT/EXTERN should be
     emitted; they may be referred to from other object files.  */
  if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_REALLY_EXTERN (decl))
    return true;

  /* Functions marked "dllexport" must be emitted so that they are
     visible to other DLLs.  */
  if (flag_keep_inline_dllexport
      && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
    return true;

  /* When not optimizing, do not bother to produce definitions for extern
     symbols.  */
  if (DECL_REALLY_EXTERN (decl)
      && ((TREE_CODE (decl) != FUNCTION_DECL
	   && !optimize)
	  || (TREE_CODE (decl) == FUNCTION_DECL
	      && !opt_for_fn (decl, optimize)))
      && !lookup_attribute ("always_inline", decl))
    return false;

  /* If this entity was used, let the back end see it; it will decide
     whether or not to emit it into the object file.  */
  if (TREE_USED (decl))
    return true;

  /* Virtual functions might be needed for devirtualization.  */
  if (flag_devirtualize
      && TREE_CODE (decl) == FUNCTION_DECL
      && DECL_VIRTUAL_P (decl))
    return true;

  /* Otherwise, DECL does not need to be emitted -- yet.  A subsequent
     reference to DECL might cause it to be emitted later.  */
  return false;
}

/* If necessary, write out the vtables for the dynamic class CTYPE.
   Returns true if any vtables were emitted.  */

static bool
maybe_emit_vtables (tree ctype, vec<tree> &consteval_vtables)
{
  tree vtbl;
  tree primary_vtbl;
  int needed = 0;
  varpool_node *current = NULL, *last = NULL;

  /* If the vtables for this class have already been emitted there is
     nothing more to do.  */
  primary_vtbl = CLASSTYPE_VTABLES (ctype);
  if (var_finalized_p (primary_vtbl))
    return false;
  /* Ignore dummy vtables made by get_vtable_decl.  */
  if (TREE_TYPE (primary_vtbl) == void_type_node)
    return false;

  /* On some targets, we cannot determine the key method until the end
     of the translation unit -- which is when this function is
     called.  */
  if (!targetm.cxx.key_method_may_be_inline ())
    determine_key_method (ctype);

  /* See if any of the vtables are needed.  */
  for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = DECL_CHAIN (vtbl))
    {
      import_export_decl (vtbl);
      if (DECL_NOT_REALLY_EXTERN (vtbl) && decl_needed_p (vtbl))
	needed = 1;
    }
  if (!needed)
    {
      /* If the references to this class' vtables are optimized away,
	 still emit the appropriate debugging information.  See
	 dfs_debug_mark.  */
      if (DECL_COMDAT (primary_vtbl)
	  && CLASSTYPE_DEBUG_REQUESTED (ctype))
	note_debug_info_needed (ctype);
      return false;
    }

  /* The ABI requires that we emit all of the vtables if we emit any
     of them.  */
  for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = DECL_CHAIN (vtbl))
    {
      /* Mark entities references from the virtual table as used.  */
      mark_vtable_entries (vtbl, consteval_vtables);

      if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
	{
	  vec<tree, va_gc> *cleanups = NULL;
	  tree expr = store_init_value (vtbl, DECL_INITIAL (vtbl), &cleanups,
					LOOKUP_NORMAL);

	  /* It had better be all done at compile-time.  */
	  gcc_assert (!expr && !cleanups);
	}

      /* Write it out.  */
      DECL_EXTERNAL (vtbl) = 0;
      rest_of_decl_compilation (vtbl, 1, 1);

      /* Because we're only doing syntax-checking, we'll never end up
	 actually marking the variable as written.  */
      if (flag_syntax_only)
	TREE_ASM_WRITTEN (vtbl) = 1;
      else if (DECL_ONE_ONLY (vtbl))
	{
	  current = varpool_node::get_create (vtbl);
	  if (last)
	    current->add_to_same_comdat_group (last);
	  last = current;
	}
    }

  /* For abstract classes, the destructor has been removed from the
     vtable (in class.c's build_vtbl_initializer).  For a compiler-
     generated destructor, it hence might not have been generated in
     this translation unit - and with '#pragma interface' it might
     never get generated.  */
  if (CLASSTYPE_PURE_VIRTUALS (ctype)
      && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype)
      && !CLASSTYPE_LAZY_DESTRUCTOR (ctype)
      && DECL_DEFAULTED_IN_CLASS_P (CLASSTYPE_DESTRUCTOR (ctype)))
    note_vague_linkage_fn (CLASSTYPE_DESTRUCTOR (ctype));

  /* Since we're writing out the vtable here, also write the debug
     info.  */
  note_debug_info_needed (ctype);

  return true;
}

/* A special return value from type_visibility meaning internal
   linkage.  */

enum { VISIBILITY_ANON = VISIBILITY_INTERNAL+1 };

static int expr_visibility (tree);
static int type_visibility (tree);

/* walk_tree helper function for type_visibility.  */

static tree
min_vis_r (tree *tp, int *walk_subtrees, void *data)
{
  int *vis_p = (int *)data;
  int this_vis = VISIBILITY_DEFAULT;
  if (! TYPE_P (*tp))
    *walk_subtrees = 0;
  else if (OVERLOAD_TYPE_P (*tp)
	   && !TREE_PUBLIC (TYPE_MAIN_DECL (*tp)))
    {
      this_vis = VISIBILITY_ANON;
      *walk_subtrees = 0;
    }
  else if (CLASS_TYPE_P (*tp))
    {
      this_vis = CLASSTYPE_VISIBILITY (*tp);
      *walk_subtrees = 0;
    }
  else if (TREE_CODE (*tp) == ARRAY_TYPE
	   && uses_template_parms (TYPE_DOMAIN (*tp)))
    this_vis = expr_visibility (TYPE_MAX_VALUE (TYPE_DOMAIN (*tp)));

  if (this_vis > *vis_p)
    *vis_p = this_vis;

  /* Tell cp_walk_subtrees to look through typedefs.  */
  if (*walk_subtrees == 1)
    *walk_subtrees = 2;

  return NULL;
}

/* walk_tree helper function for expr_visibility.  */

static tree
min_vis_expr_r (tree *tp, int */*walk_subtrees*/, void *data)
{
  int *vis_p = (int *)data;
  int tpvis = VISIBILITY_DEFAULT;

  switch (TREE_CODE (*tp))
    {
    case CAST_EXPR:
    case IMPLICIT_CONV_EXPR:
    case STATIC_CAST_EXPR:
    case REINTERPRET_CAST_EXPR:
    case CONST_CAST_EXPR:
    case DYNAMIC_CAST_EXPR:
    case NEW_EXPR:
    case CONSTRUCTOR:
    case LAMBDA_EXPR:
      tpvis = type_visibility (TREE_TYPE (*tp));
      break;

    case VAR_DECL:
    case FUNCTION_DECL:
      if (! TREE_PUBLIC (*tp))
	tpvis = VISIBILITY_ANON;
      else
	tpvis = DECL_VISIBILITY (*tp);
      break;

    default:
      break;
    }

  if (tpvis > *vis_p)
    *vis_p = tpvis;

  return NULL_TREE;
}

/* Returns the visibility of TYPE, which is the minimum visibility of its
   component types.  */

static int
type_visibility (tree type)
{
  int vis = VISIBILITY_DEFAULT;
  cp_walk_tree_without_duplicates (&type, min_vis_r, &vis);
  return vis;
}

/* Returns the visibility of an expression EXPR that appears in the signature
   of a function template, which is the minimum visibility of names that appear
   in its mangling.  */

static int
expr_visibility (tree expr)
{
  int vis = VISIBILITY_DEFAULT;
  cp_walk_tree_without_duplicates (&expr, min_vis_expr_r, &vis);
  return vis;
}

/* Limit the visibility of DECL to VISIBILITY, if not explicitly
   specified (or if VISIBILITY is static).  If TMPL is true, this
   constraint is for a template argument, and takes precedence
   over explicitly-specified visibility on the template.  */

static void
constrain_visibility (tree decl, int visibility, bool tmpl)
{
  if (visibility == VISIBILITY_ANON)
    {
      /* extern "C" declarations aren't affected by the anonymous
	 namespace.  */
      if (!DECL_EXTERN_C_P (decl))
	{
	  TREE_PUBLIC (decl) = 0;
	  DECL_WEAK (decl) = 0;
	  DECL_COMMON (decl) = 0;
	  DECL_COMDAT (decl) = false;
	  if (VAR_OR_FUNCTION_DECL_P (decl))
	    {
	      struct symtab_node *snode = symtab_node::get (decl);

	      if (snode)
	        snode->set_comdat_group (NULL);
	    }
	  DECL_INTERFACE_KNOWN (decl) = 1;
	  if (DECL_LANG_SPECIFIC (decl))
	    DECL_NOT_REALLY_EXTERN (decl) = 1;
	}
    }
  else if (visibility > DECL_VISIBILITY (decl)
	   && (tmpl || !DECL_VISIBILITY_SPECIFIED (decl)))
    {
      DECL_VISIBILITY (decl) = (enum symbol_visibility) visibility;
      /* This visibility was not specified.  */
      DECL_VISIBILITY_SPECIFIED (decl) = false;
    }
}

/* Constrain the visibility of DECL based on the visibility of its template
   arguments.  */

static void
constrain_visibility_for_template (tree decl, tree targs)
{
  /* If this is a template instantiation, check the innermost
     template args for visibility constraints.  The outer template
     args are covered by the class check.  */
  tree args = INNERMOST_TEMPLATE_ARGS (targs);
  int i;
  for (i = TREE_VEC_LENGTH (args); i > 0; --i)
    {
      int vis = 0;

      tree arg = TREE_VEC_ELT (args, i-1);
      if (TYPE_P (arg))
	vis = type_visibility (arg);
      else
	vis = expr_visibility (arg);
      if (vis)
	constrain_visibility (decl, vis, true);
    }
}

/* Like c_determine_visibility, but with additional C++-specific
   behavior.

   Function-scope entities can rely on the function's visibility because
   it is set in start_preparsed_function.

   Class-scope entities cannot rely on the class's visibility until the end
   of the enclosing class definition.

   Note that because namespaces have multiple independent definitions,
   namespace visibility is handled elsewhere using the #pragma visibility
   machinery rather than by decorating the namespace declaration.

   The goal is for constraints from the type to give a diagnostic, and
   other constraints to be applied silently.  */

void
determine_visibility (tree decl)
{
  /* Remember that all decls get VISIBILITY_DEFAULT when built.  */

  /* Only relevant for names with external linkage.  */
  if (!TREE_PUBLIC (decl))
    return;

  /* Cloned constructors and destructors get the same visibility as
     the underlying function.  That should be set up in
     maybe_clone_body.  */
  gcc_assert (!DECL_CLONED_FUNCTION_P (decl));

  bool orig_visibility_specified = DECL_VISIBILITY_SPECIFIED (decl);
  enum symbol_visibility orig_visibility = DECL_VISIBILITY (decl);

  /* The decl may be a template instantiation, which could influence
     visibilty.  */
  tree template_decl = NULL_TREE;
  if (TREE_CODE (decl) == TYPE_DECL)
    {
      if (CLASS_TYPE_P (TREE_TYPE (decl)))
	{
	  if (CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)))
	    template_decl = decl;
	}
      else if (TYPE_TEMPLATE_INFO (TREE_TYPE (decl)))
	template_decl = decl;
    }
  else if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
    template_decl = decl;

  if (TREE_CODE (decl) == TYPE_DECL
      && LAMBDA_TYPE_P (TREE_TYPE (decl))
      && CLASSTYPE_LAMBDA_EXPR (TREE_TYPE (decl)) != error_mark_node)
    if (tree extra = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl)))
      {
	/* The lambda's visibility is limited by that of its extra
	   scope.  */
	int vis = 0;
	if (TYPE_P (extra))
	  vis = type_visibility (extra);
	else
	  vis = expr_visibility (extra);
	constrain_visibility (decl, vis, false);
      }

  /* If DECL is a member of a class, visibility specifiers on the
     class can influence the visibility of the DECL.  */
  tree class_type = NULL_TREE;
  if (DECL_CLASS_SCOPE_P (decl))
    class_type = DECL_CONTEXT (decl);
  else
    {
      /* Not a class member.  */

      /* Virtual tables have DECL_CONTEXT set to their associated class,
	 so they are automatically handled above.  */
      gcc_assert (!VAR_P (decl)
		  || !DECL_VTABLE_OR_VTT_P (decl));

      if (DECL_FUNCTION_SCOPE_P (decl) && ! DECL_VISIBILITY_SPECIFIED (decl))
	{
	  /* Local statics and classes get the visibility of their
	     containing function by default, except that
	     -fvisibility-inlines-hidden doesn't affect them.  */
	  tree fn = DECL_CONTEXT (decl);
	  if (DECL_VISIBILITY_SPECIFIED (fn))
	    {
	      DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
	      DECL_VISIBILITY_SPECIFIED (decl) = 
		DECL_VISIBILITY_SPECIFIED (fn);
	    }
	  else
	    {
	      if (DECL_CLASS_SCOPE_P (fn))
		determine_visibility_from_class (decl, DECL_CONTEXT (fn));
	      else if (determine_hidden_inline (fn))
		{
		  DECL_VISIBILITY (decl) = default_visibility;
		  DECL_VISIBILITY_SPECIFIED (decl) =
		    visibility_options.inpragma;
		}
	      else
		{
	          DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
	          DECL_VISIBILITY_SPECIFIED (decl) =
		    DECL_VISIBILITY_SPECIFIED (fn);
		}
	    }

	  /* Local classes in templates have CLASSTYPE_USE_TEMPLATE set,
	     but have no TEMPLATE_INFO, so don't try to check it.  */
	  template_decl = NULL_TREE;
	}
      else if (VAR_P (decl) && DECL_TINFO_P (decl)
	       && flag_visibility_ms_compat)
	{
	  /* Under -fvisibility-ms-compat, types are visible by default,
	     even though their contents aren't.  */
	  tree underlying_type = TREE_TYPE (DECL_NAME (decl));
	  int underlying_vis = type_visibility (underlying_type);
	  if (underlying_vis == VISIBILITY_ANON
	      || (CLASS_TYPE_P (underlying_type)
		  && CLASSTYPE_VISIBILITY_SPECIFIED (underlying_type)))
	    constrain_visibility (decl, underlying_vis, false);
	  else
	    DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
	}
      else if (VAR_P (decl) && DECL_TINFO_P (decl))
	{
	  /* tinfo visibility is based on the type it's for.  */
	  constrain_visibility
	    (decl, type_visibility (TREE_TYPE (DECL_NAME (decl))), false);

	  /* Give the target a chance to override the visibility associated
	     with DECL.  */
	  if (TREE_PUBLIC (decl)
	      && !DECL_REALLY_EXTERN (decl)
	      && CLASS_TYPE_P (TREE_TYPE (DECL_NAME (decl)))
	      && !CLASSTYPE_VISIBILITY_SPECIFIED (TREE_TYPE (DECL_NAME (decl))))
	    targetm.cxx.determine_class_data_visibility (decl);
	}
      else if (template_decl)
	/* Template instantiations and specializations get visibility based
	   on their template unless they override it with an attribute.  */;
      else if (! DECL_VISIBILITY_SPECIFIED (decl))
	{
          if (determine_hidden_inline (decl))
	    DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
	  else
            {
	      /* Set default visibility to whatever the user supplied with
	         #pragma GCC visibility or a namespace visibility attribute.  */
	      DECL_VISIBILITY (decl) = default_visibility;
	      DECL_VISIBILITY_SPECIFIED (decl) = visibility_options.inpragma;
            }
	}
    }

  if (template_decl)
    {
      /* If the specialization doesn't specify visibility, use the
	 visibility from the template.  */
      tree tinfo = get_template_info (template_decl);
      tree args = TI_ARGS (tinfo);
      tree attribs = (TREE_CODE (decl) == TYPE_DECL
		      ? TYPE_ATTRIBUTES (TREE_TYPE (decl))
		      : DECL_ATTRIBUTES (decl));
      tree attr = lookup_attribute ("visibility", attribs);
      
      if (args != error_mark_node)
	{
	  tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo));

	  if (!DECL_VISIBILITY_SPECIFIED (decl))
	    {
	      if (!attr
		  && determine_hidden_inline (decl))
		DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
	      else
		{
	          DECL_VISIBILITY (decl) = DECL_VISIBILITY (pattern);
	          DECL_VISIBILITY_SPECIFIED (decl)
		    = DECL_VISIBILITY_SPECIFIED (pattern);
		}
	    }

	  if (args
	      /* Template argument visibility outweighs #pragma or namespace
		 visibility, but not an explicit attribute.  */
	      && !attr)
	    {
	      int depth = TMPL_ARGS_DEPTH (args);
	      if (DECL_VISIBILITY_SPECIFIED (decl))
		{
		  /* A class template member with explicit visibility
		     overrides the class visibility, so we need to apply
		     all the levels of template args directly.  */
		  int i;
		  for (i = 1; i <= depth; ++i)
		    {
		      tree lev = TMPL_ARGS_LEVEL (args, i);
		      constrain_visibility_for_template (decl, lev);
		    }
		}
	      else if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)))
		/* Limit visibility based on its template arguments.  */
		constrain_visibility_for_template (decl, args);
	    }
	}
    }

  if (class_type)
    determine_visibility_from_class (decl, class_type);

  if (decl_anon_ns_mem_p (decl))
    /* Names in an anonymous namespace get internal linkage.  */
    constrain_visibility (decl, VISIBILITY_ANON, false);
  else if (TREE_CODE (decl) != TYPE_DECL)
    {
      /* Propagate anonymity from type to decl.  */
      int tvis = type_visibility (TREE_TYPE (decl));
      if (tvis == VISIBILITY_ANON
	  || ! DECL_VISIBILITY_SPECIFIED (decl))
	constrain_visibility (decl, tvis, false);
    }
  else if (no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/true))
    /* DR 757: A type without linkage shall not be used as the type of a
       variable or function with linkage, unless
       o the variable or function has extern "C" linkage (7.5 [dcl.link]), or
       o the variable or function is not used (3.2 [basic.def.odr]) or is
       defined in the same translation unit.

       Since non-extern "C" decls need to be defined in the same
       translation unit, we can make the type internal.  */
    constrain_visibility (decl, VISIBILITY_ANON, false);

  /* If visibility changed and DECL already has DECL_RTL, ensure
     symbol flags are updated.  */
  if ((DECL_VISIBILITY (decl) != orig_visibility
       || DECL_VISIBILITY_SPECIFIED (decl) != orig_visibility_specified)
      && ((VAR_P (decl) && TREE_STATIC (decl))
	  || TREE_CODE (decl) == FUNCTION_DECL)
      && DECL_RTL_SET_P (decl))
    make_decl_rtl (decl);
}

/* By default, static data members and function members receive
   the visibility of their containing class.  */

static void
determine_visibility_from_class (tree decl, tree class_type)
{
  if (DECL_VISIBILITY_SPECIFIED (decl))
    return;

  if (determine_hidden_inline (decl))
    DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
  else
    {
      /* Default to the class visibility.  */
      DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
      DECL_VISIBILITY_SPECIFIED (decl)
	= CLASSTYPE_VISIBILITY_SPECIFIED (class_type);
    }

  /* Give the target a chance to override the visibility associated
     with DECL.  */
  if (VAR_P (decl)
      && TREE_PUBLIC (decl)
      && (DECL_TINFO_P (decl) || DECL_VTABLE_OR_VTT_P (decl))
      && !DECL_REALLY_EXTERN (decl)
      && !CLASSTYPE_VISIBILITY_SPECIFIED (class_type))
    targetm.cxx.determine_class_data_visibility (decl);
}

/* Returns true iff DECL is an inline that should get hidden visibility
   because of -fvisibility-inlines-hidden.  */

static bool
determine_hidden_inline (tree decl)
{
  return (visibility_options.inlines_hidden
	  /* Don't do this for inline templates; specializations might not be
	     inline, and we don't want them to inherit the hidden
	     visibility.  We'll set it here for all inline instantiations.  */
	  && !processing_template_decl
	  && TREE_CODE (decl) == FUNCTION_DECL
	  && DECL_DECLARED_INLINE_P (decl)
	  && (! DECL_LANG_SPECIFIC (decl)
	      || ! DECL_EXPLICIT_INSTANTIATION (decl)));
}

/* Constrain the visibility of a class TYPE based on the visibility of its
   field types.  Warn if any fields require lesser visibility.  */

void
constrain_class_visibility (tree type)
{
  tree binfo;
  tree t;
  int i;

  int vis = type_visibility (type);

  if (vis == VISIBILITY_ANON
      || DECL_IN_SYSTEM_HEADER (TYPE_MAIN_DECL (type)))
    return;

  /* Don't warn about visibility if the class has explicit visibility.  */
  if (CLASSTYPE_VISIBILITY_SPECIFIED (type))
    vis = VISIBILITY_INTERNAL;

  for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
    if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node
	&& !DECL_ARTIFICIAL (t))
      {
	tree ftype = strip_pointer_or_array_types (TREE_TYPE (t));
	int subvis = type_visibility (ftype);

	if (subvis == VISIBILITY_ANON)
	  {
	    if (!in_main_input_context())
	      {
		tree nlt = no_linkage_check (ftype, /*relaxed_p=*/false);
		if (nlt)
		  {
		    if (same_type_p (TREE_TYPE (t), nlt))
		      warning (OPT_Wsubobject_linkage, "\
%qT has a field %qD whose type has no linkage",
			       type, t);
		    else
		      warning (OPT_Wsubobject_linkage, "\
%qT has a field %qD whose type depends on the type %qT which has no linkage",
			       type, t, nlt);
		  }
		else
		  warning (OPT_Wsubobject_linkage, "\
%qT has a field %qD whose type uses the anonymous namespace",
			   type, t);
	      }
	  }
	else if (MAYBE_CLASS_TYPE_P (ftype)
		 && vis < VISIBILITY_HIDDEN
		 && subvis >= VISIBILITY_HIDDEN)
	  warning (OPT_Wattributes, "\
%qT declared with greater visibility than the type of its field %qD",
		   type, t);
      }

  binfo = TYPE_BINFO (type);
  for (i = 0; BINFO_BASE_ITERATE (binfo, i, t); ++i)
    {
      int subvis = type_visibility (TREE_TYPE (t));

      if (subvis == VISIBILITY_ANON)
        {
	  if (!in_main_input_context())
	    {
	      tree nlt = no_linkage_check (TREE_TYPE (t), /*relaxed_p=*/false);
	      if (nlt)
		{
		  if (same_type_p (TREE_TYPE (t), nlt))
		    warning (OPT_Wsubobject_linkage, "\
%qT has a base %qT whose type has no linkage",
			     type, TREE_TYPE (t));
		  else
		    warning (OPT_Wsubobject_linkage, "\
%qT has a base %qT whose type depends on the type %qT which has no linkage",
			     type, TREE_TYPE (t), nlt);
		}
	      else
		warning (OPT_Wsubobject_linkage, "\
%qT has a base %qT whose type uses the anonymous namespace",
			 type, TREE_TYPE (t));
	    }
	}
      else if (vis < VISIBILITY_HIDDEN
	       && subvis >= VISIBILITY_HIDDEN)
	warning (OPT_Wattributes, "\
%qT declared with greater visibility than its base %qT",
		 type, TREE_TYPE (t));
    }
}

/* Functions for adjusting the visibility of a tagged type and its nested
   types and declarations when it gets a name for linkage purposes from a
   typedef.  */
// FIXME: It is now a DR for such a class type to contain anything
// other than C.  So at minium most of this can probably be deleted.

/* First reset the visibility of all the types.  */

static void
reset_type_linkage_1 (tree type)
{
  set_linkage_according_to_type (type, TYPE_MAIN_DECL (type));
  if (CLASS_TYPE_P (type))
    for (tree member = TYPE_FIELDS (type); member; member = DECL_CHAIN (member))
      if (DECL_IMPLICIT_TYPEDEF_P (member))
	reset_type_linkage_1 (TREE_TYPE (member));
}

/* Then reset the visibility of any static data members or member
   functions that use those types.  */

static void
reset_decl_linkage (tree decl)
{
  if (TREE_PUBLIC (decl))
    return;
  if (DECL_CLONED_FUNCTION_P (decl))
    return;
  TREE_PUBLIC (decl) = true;
  DECL_INTERFACE_KNOWN (decl) = false;
  determine_visibility (decl);
  tentative_decl_linkage (decl);
}

void
reset_type_linkage (tree type)
{
  reset_type_linkage_1 (type);
  if (CLASS_TYPE_P (type))
    {
      if (tree vt = CLASSTYPE_VTABLES (type))
	{
	  tree name = mangle_vtbl_for_type (type);
	  DECL_NAME (vt) = name;
	  SET_DECL_ASSEMBLER_NAME (vt, name);
	  reset_decl_linkage (vt);
	}
      if (!ANON_AGGR_TYPE_P (type))
	if (tree ti = CLASSTYPE_TYPEINFO_VAR (type))
	  {
	    tree name = mangle_typeinfo_for_type (type);
	    DECL_NAME (ti) = name;
	    SET_DECL_ASSEMBLER_NAME (ti, name);
	    TREE_TYPE (name) = type;
	    reset_decl_linkage (ti);
	  }
      for (tree m = TYPE_FIELDS (type); m; m = DECL_CHAIN (m))
	{
	  tree mem = STRIP_TEMPLATE (m);
	  if (TREE_CODE (mem) == VAR_DECL || TREE_CODE (mem) == FUNCTION_DECL)
	    reset_decl_linkage (mem);
	  else if (DECL_IMPLICIT_TYPEDEF_P (mem))
	    reset_type_linkage (TREE_TYPE (mem));
	}
    }
}

/* Set up our initial idea of what the linkage of DECL should be.  */

void
tentative_decl_linkage (tree decl)
{
  if (DECL_INTERFACE_KNOWN (decl))
    /* We've already made a decision as to how this function will
       be handled.  */;
  else if (vague_linkage_p (decl))
    {
      if (TREE_CODE (decl) == FUNCTION_DECL
	  && decl_defined_p (decl))
	{
	  DECL_EXTERNAL (decl) = 1;
	  DECL_NOT_REALLY_EXTERN (decl) = 1;
	  note_vague_linkage_fn (decl);
	  /* A non-template inline function with external linkage will
	     always be COMDAT.  As we must eventually determine the
	     linkage of all functions, and as that causes writes to
	     the data mapped in from the PCH file, it's advantageous
	     to mark the functions at this point.  */
	  if (DECL_DECLARED_INLINE_P (decl)
	      && (!DECL_IMPLICIT_INSTANTIATION (decl)
		  || DECL_DEFAULTED_FN (decl)))
	    {
	      /* This function must have external linkage, as
		 otherwise DECL_INTERFACE_KNOWN would have been
		 set.  */
	      gcc_assert (TREE_PUBLIC (decl));
	      comdat_linkage (decl);
	      DECL_INTERFACE_KNOWN (decl) = 1;
	    }
	}
      else if (VAR_P (decl))
	maybe_commonize_var (decl);
    }
}

/* DECL is a FUNCTION_DECL or VAR_DECL.  If the object file linkage
   for DECL has not already been determined, do so now by setting
   DECL_EXTERNAL, DECL_COMDAT and other related flags.  Until this
   function is called entities with vague linkage whose definitions
   are available must have TREE_PUBLIC set.

   If this function decides to place DECL in COMDAT, it will set
   appropriate flags -- but will not clear DECL_EXTERNAL.  It is up to
   the caller to decide whether or not to clear DECL_EXTERNAL.  Some
   callers defer that decision until it is clear that DECL is actually
   required.  */

void
import_export_decl (tree decl)
{
  bool comdat_p;
  bool import_p;
  tree class_type = NULL_TREE;

  if (DECL_INTERFACE_KNOWN (decl))
    return;

  /* We cannot determine what linkage to give to an entity with vague
     linkage until the end of the file.  For example, a virtual table
     for a class will be defined if and only if the key method is
     defined in this translation unit.  */
  gcc_assert (at_eof);
  /* Object file linkage for explicit instantiations is handled in
     mark_decl_instantiated.  For static variables in functions with
     vague linkage, maybe_commonize_var is used.

     Therefore, the only declarations that should be provided to this
     function are those with external linkage that are:

     * implicit instantiations of function templates

     * inline function

     * implicit instantiations of static data members of class
       templates

     * virtual tables

     * typeinfo objects

     Furthermore, all entities that reach this point must have a
     definition available in this translation unit.

     The following assertions check these conditions.  */
  gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
  /* Any code that creates entities with TREE_PUBLIC cleared should
     also set DECL_INTERFACE_KNOWN.  */
  gcc_assert (TREE_PUBLIC (decl));
  if (TREE_CODE (decl) == FUNCTION_DECL)
    gcc_assert (DECL_IMPLICIT_INSTANTIATION (decl)
		|| DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)
		|| DECL_DECLARED_INLINE_P (decl));
  else
    gcc_assert (DECL_IMPLICIT_INSTANTIATION (decl)
		|| DECL_VTABLE_OR_VTT_P (decl)
		|| DECL_TINFO_P (decl));
  /* Check that a definition of DECL is available in this translation
     unit.  */
  gcc_assert (!DECL_REALLY_EXTERN (decl));

  /* Assume that DECL will not have COMDAT linkage.  */
  comdat_p = false;
  /* Assume that DECL will not be imported into this translation
     unit.  */
  import_p = false;

  if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl))
    {
      class_type = DECL_CONTEXT (decl);
      import_export_class (class_type);
      if (CLASSTYPE_INTERFACE_KNOWN (class_type)
	  && CLASSTYPE_INTERFACE_ONLY (class_type))
	import_p = true;
      else if ((!flag_weak || TARGET_WEAK_NOT_IN_ARCHIVE_TOC)
	       && !CLASSTYPE_USE_TEMPLATE (class_type)
	       && CLASSTYPE_KEY_METHOD (class_type)
	       && !DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (class_type)))
	/* The ABI requires that all virtual tables be emitted with
	   COMDAT linkage.  However, on systems where COMDAT symbols
	   don't show up in the table of contents for a static
	   archive, or on systems without weak symbols (where we
	   approximate COMDAT linkage by using internal linkage), the
	   linker will report errors about undefined symbols because
	   it will not see the virtual table definition.  Therefore,
	   in the case that we know that the virtual table will be
	   emitted in only one translation unit, we make the virtual
	   table an ordinary definition with external linkage.  */
	DECL_EXTERNAL (decl) = 0;
      else if (CLASSTYPE_INTERFACE_KNOWN (class_type))
	{
	  /* CLASS_TYPE is being exported from this translation unit,
	     so DECL should be defined here.  */
	  if (!flag_weak && CLASSTYPE_EXPLICIT_INSTANTIATION (class_type))
	    /* If a class is declared in a header with the "extern
	       template" extension, then it will not be instantiated,
	       even in translation units that would normally require
	       it.  Often such classes are explicitly instantiated in
	       one translation unit.  Therefore, the explicit
	       instantiation must be made visible to other translation
	       units.  */
	    DECL_EXTERNAL (decl) = 0;
	  else
	    {
	      /* The generic C++ ABI says that class data is always
		 COMDAT, even if there is a key function.  Some
		 variants (e.g., the ARM EABI) says that class data
		 only has COMDAT linkage if the class data might be
		 emitted in more than one translation unit.  When the
		 key method can be inline and is inline, we still have
		 to arrange for comdat even though
		 class_data_always_comdat is false.  */
	      if (!CLASSTYPE_KEY_METHOD (class_type)
		  || DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (class_type))
		  || targetm.cxx.class_data_always_comdat ())
		{
		  /* The ABI requires COMDAT linkage.  Normally, we
		     only emit COMDAT things when they are needed;
		     make sure that we realize that this entity is
		     indeed needed.  */
		  comdat_p = true;
		  mark_needed (decl);
		}
	    }
	}
      else if (!flag_implicit_templates
	       && CLASSTYPE_IMPLICIT_INSTANTIATION (class_type))
	import_p = true;
      else
	comdat_p = true;
    }
  else if (VAR_P (decl) && DECL_TINFO_P (decl))
    {
      tree type = TREE_TYPE (DECL_NAME (decl));
      if (CLASS_TYPE_P (type))
	{
	  class_type = type;
	  import_export_class (type);
	  if (CLASSTYPE_INTERFACE_KNOWN (type)
	      && TYPE_POLYMORPHIC_P (type)
	      && CLASSTYPE_INTERFACE_ONLY (type)
	      /* If -fno-rtti was specified, then we cannot be sure
		 that RTTI information will be emitted with the
		 virtual table of the class, so we must emit it
		 wherever it is used.  */
	      && flag_rtti)
	    import_p = true;
	  else
	    {
	      if (CLASSTYPE_INTERFACE_KNOWN (type)
		  && !CLASSTYPE_INTERFACE_ONLY (type))
		{
		  comdat_p = (targetm.cxx.class_data_always_comdat ()
			      || (CLASSTYPE_KEY_METHOD (type)
				  && DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (type))));
		  mark_needed (decl);
		  if (!flag_weak)
		    {
		      comdat_p = false;
		      DECL_EXTERNAL (decl) = 0;
		    }
		}
	      else
		comdat_p = true;
	    }
	}
      else
	comdat_p = true;
    }
  else if (DECL_TEMPLOID_INSTANTIATION (decl))
    {
      /* DECL is an implicit instantiation of a function or static
	 data member.  */
      if (flag_implicit_templates
	  || (flag_implicit_inline_templates
	      && TREE_CODE (decl) == FUNCTION_DECL
	      && DECL_DECLARED_INLINE_P (decl)))
	comdat_p = true;
      else
	/* If we are not implicitly generating templates, then mark
	   this entity as undefined in this translation unit.  */
	import_p = true;
    }
  else if (DECL_FUNCTION_MEMBER_P (decl))
    {
      if (!DECL_DECLARED_INLINE_P (decl))
	{
	  tree ctype = DECL_CONTEXT (decl);
	  import_export_class (ctype);
	  if (CLASSTYPE_INTERFACE_KNOWN (ctype))
	    {
	      DECL_NOT_REALLY_EXTERN (decl)
		= ! (CLASSTYPE_INTERFACE_ONLY (ctype)
		     || (DECL_DECLARED_INLINE_P (decl)
			 && ! flag_implement_inlines
			 && !DECL_VINDEX (decl)));

	      if (!DECL_NOT_REALLY_EXTERN (decl))
		DECL_EXTERNAL (decl) = 1;

	      /* Always make artificials weak.  */
	      if (DECL_ARTIFICIAL (decl) && flag_weak)
		comdat_p = true;
	      else
		maybe_make_one_only (decl);
	    }
	}
      else
	comdat_p = true;
    }
  else
    comdat_p = true;

  if (import_p)
    {
      /* If we are importing DECL into this translation unit, mark is
	 an undefined here.  */
      DECL_EXTERNAL (decl) = 1;
      DECL_NOT_REALLY_EXTERN (decl) = 0;
    }
  else if (comdat_p)
    {
      /* If we decided to put DECL in COMDAT, mark it accordingly at
	 this point.  */
      comdat_linkage (decl);
    }

  DECL_INTERFACE_KNOWN (decl) = 1;
}

/* Return an expression that performs the destruction of DECL, which
   must be a VAR_DECL whose type has a non-trivial destructor, or is
   an array whose (innermost) elements have a non-trivial destructor.  */

tree
build_cleanup (tree decl)
{
  tree clean = cxx_maybe_build_cleanup (decl, tf_warning_or_error);
  gcc_assert (clean != NULL_TREE);
  return clean;
}

/* GUARD is a helper variable for DECL; make them have the same linkage and
   visibility.  */

void
copy_linkage (tree guard, tree decl)
{
  TREE_PUBLIC (guard) = TREE_PUBLIC (decl);
  TREE_STATIC (guard) = TREE_STATIC (decl);
  DECL_COMMON (guard) = DECL_COMMON (decl);
  DECL_COMDAT (guard) = DECL_COMDAT (decl);
  if (TREE_STATIC (guard))
    {
      CP_DECL_THREAD_LOCAL_P (guard) = CP_DECL_THREAD_LOCAL_P (decl);
      set_decl_tls_model (guard, DECL_TLS_MODEL (decl));
      if (DECL_ONE_ONLY (decl))
	make_decl_one_only (guard, cxx_comdat_group (guard));
      if (TREE_PUBLIC (decl))
	DECL_WEAK (guard) = DECL_WEAK (decl);
      /* Also check vague_linkage_p, as DECL_WEAK and DECL_ONE_ONLY might not
	 be set until import_export_decl at EOF.  */
      if (vague_linkage_p (decl))
	comdat_linkage (guard);
      DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl);
      DECL_VISIBILITY_SPECIFIED (guard) = DECL_VISIBILITY_SPECIFIED (decl);
    }
}

/* Returns the initialization guard variable for the variable DECL,
   which has static storage duration.  */

tree
get_guard (tree decl)
{
  tree sname = mangle_guard_variable (decl);
  tree guard = get_global_binding (sname);
  if (! guard)
    {
      tree guard_type;

      /* We use a type that is big enough to contain a mutex as well
	 as an integer counter.  */
      guard_type = targetm.cxx.guard_type ();
      guard = build_decl (DECL_SOURCE_LOCATION (decl),
			  VAR_DECL, sname, guard_type);

      /* The guard should have the same linkage as what it guards.  */
      copy_linkage (guard, decl);

      DECL_ARTIFICIAL (guard) = 1;
      DECL_IGNORED_P (guard) = 1;
      TREE_USED (guard) = 1;
      pushdecl_top_level_and_finish (guard, NULL_TREE);
    }
  return guard;
}

/* Returns true if accessing the GUARD atomic is expensive,
   i.e. involves a call to __sync_synchronize or similar.
   In this case let __cxa_guard_acquire handle the atomics.  */

static bool
is_atomic_expensive_p (machine_mode mode)
{
  if (!flag_inline_atomics)
    return true;

  if (!can_compare_and_swap_p (mode, false) || !can_atomic_load_p (mode))
    return true;

  return false;
}

/* Return an atomic load of src with the appropriate memory model.  */

static tree
build_atomic_load_type (tree src, HOST_WIDE_INT model, tree type)
{
  tree ptr_type = build_pointer_type (type);
  tree mem_model = build_int_cst (integer_type_node, model);
  tree t, addr, val;
  unsigned int size;
  int fncode;

  size = tree_to_uhwi (TYPE_SIZE_UNIT (type));

  fncode = BUILT_IN_ATOMIC_LOAD_N + exact_log2 (size) + 1;
  t = builtin_decl_implicit ((enum built_in_function) fncode);

  addr = build1 (ADDR_EXPR, ptr_type, src);
  val = build_call_expr (t, 2, addr, mem_model);
  return val;
}

/* Return those bits of the GUARD variable that should be set when the
   guarded entity is actually initialized.  */

static tree
get_guard_bits (tree guard)
{
  if (!targetm.cxx.guard_mask_bit ())
    {
      /* We only set the first byte of the guard, in order to leave room
	 for a mutex in the high-order bits.  */
      guard = build1 (ADDR_EXPR,
		      build_pointer_type (TREE_TYPE (guard)),
		      guard);
      guard = build1 (NOP_EXPR,
		      build_pointer_type (char_type_node),
		      guard);
      guard = build1 (INDIRECT_REF, char_type_node, guard);
    }

  return guard;
}

/* Return an expression which determines whether or not the GUARD
   variable has already been initialized.  */

tree
get_guard_cond (tree guard, bool thread_safe)
{
  tree guard_value;

  if (!thread_safe)
    guard = get_guard_bits (guard);
  else
    {
      tree type = targetm.cxx.guard_mask_bit ()
		  ? TREE_TYPE (guard) : char_type_node;

      if (is_atomic_expensive_p (TYPE_MODE (type)))
	guard = integer_zero_node;
      else
	guard = build_atomic_load_type (guard, MEMMODEL_ACQUIRE, type);
    }

  /* Mask off all but the low bit.  */
  if (targetm.cxx.guard_mask_bit ())
    {
      guard_value = integer_one_node;
      if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
	guard_value = fold_convert (TREE_TYPE (guard), guard_value);
      guard = cp_build_binary_op (input_location,
				  BIT_AND_EXPR, guard, guard_value,
				  tf_warning_or_error);
    }

  guard_value = integer_zero_node;
  if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
    guard_value = fold_convert (TREE_TYPE (guard), guard_value);
  return cp_build_binary_op (input_location,
			     EQ_EXPR, guard, guard_value,
			     tf_warning_or_error);
}

/* Return an expression which sets the GUARD variable, indicating that
   the variable being guarded has been initialized.  */

tree
set_guard (tree guard)
{
  tree guard_init;

  /* Set the GUARD to one.  */
  guard = get_guard_bits (guard);
  guard_init = integer_one_node;
  if (!same_type_p (TREE_TYPE (guard_init), TREE_TYPE (guard)))
    guard_init = fold_convert (TREE_TYPE (guard), guard_init);
  return cp_build_modify_expr (input_location, guard, NOP_EXPR, guard_init,
			       tf_warning_or_error);
}

/* Returns true iff we can tell that VAR does not have a dynamic
   initializer.  */

static bool
var_defined_without_dynamic_init (tree var)
{
  /* constinit vars are guaranteed to not have dynamic initializer,
     but still registering the destructor counts as dynamic initialization.  */
  if (DECL_DECLARED_CONSTINIT_P (var)
      && COMPLETE_TYPE_P (TREE_TYPE (var))
      && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var)))
    return true;
  /* If it's defined in another TU, we can't tell.  */
  if (DECL_EXTERNAL (var))
    return false;
  /* If it has a non-trivial destructor, registering the destructor
     counts as dynamic initialization.  */
  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var)))
    return false;
  /* If it's in this TU, its initializer has been processed, unless
     it's a case of self-initialization, then DECL_INITIALIZED_P is
     false while the initializer is handled by finish_id_expression.  */
  if (!DECL_INITIALIZED_P (var))
    return false;
  /* If it has no initializer or a constant one, it's not dynamic.  */
  return (!DECL_NONTRIVIALLY_INITIALIZED_P (var)
	  || DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var));
}

/* Returns true iff VAR is a variable that needs uses to be
   wrapped for possible dynamic initialization.  */

static bool
var_needs_tls_wrapper (tree var)
{
  return (!error_operand_p (var)
	  && CP_DECL_THREAD_LOCAL_P (var)
	  && !DECL_GNU_TLS_P (var)
	  && !DECL_FUNCTION_SCOPE_P (var)
	  && !var_defined_without_dynamic_init (var));
}

/* Get the FUNCTION_DECL for the shared TLS init function for this
   translation unit.  */

static tree
get_local_tls_init_fn (location_t loc)
{
  tree sname = get_identifier ("__tls_init");
  tree fn = get_global_binding (sname);
  if (!fn)
    {
      fn = build_lang_decl_loc (loc, FUNCTION_DECL, sname,
				build_function_type (void_type_node,
						     void_list_node));
      SET_DECL_LANGUAGE (fn, lang_c);
      TREE_PUBLIC (fn) = false;
      DECL_ARTIFICIAL (fn) = true;
      mark_used (fn);
      set_global_binding (fn);
    }
  return fn;
}

/* Get a FUNCTION_DECL for the init function for the thread_local
   variable VAR.  The init function will be an alias to the function
   that initializes all the non-local TLS variables in the translation
   unit.  The init function is only used by the wrapper function.  */

static tree
get_tls_init_fn (tree var)
{
  /* Only C++11 TLS vars need this init fn.  */
  if (!var_needs_tls_wrapper (var))
    return NULL_TREE;

  /* If -fno-extern-tls-init, assume that we don't need to call
     a tls init function for a variable defined in another TU.  */
  if (!flag_extern_tls_init && DECL_EXTERNAL (var))
    return NULL_TREE;

  /* If the variable is internal, or if we can't generate aliases,
     call the local init function directly.  */
  if (!TREE_PUBLIC (var) || !TARGET_SUPPORTS_ALIASES)
    return get_local_tls_init_fn (DECL_SOURCE_LOCATION (var));

  tree sname = mangle_tls_init_fn (var);
  tree fn = get_global_binding (sname);
  if (!fn)
    {
      fn = build_lang_decl (FUNCTION_DECL, sname,
			    build_function_type (void_type_node,
						 void_list_node));
      SET_DECL_LANGUAGE (fn, lang_c);
      TREE_PUBLIC (fn) = TREE_PUBLIC (var);
      DECL_ARTIFICIAL (fn) = true;
      DECL_COMDAT (fn) = DECL_COMDAT (var);
      DECL_EXTERNAL (fn) = DECL_EXTERNAL (var);
      if (DECL_ONE_ONLY (var))
	make_decl_one_only (fn, cxx_comdat_group (fn));
      if (TREE_PUBLIC (var))
	{
	  tree obtype = strip_array_types (non_reference (TREE_TYPE (var)));
	  /* If the variable is defined somewhere else and might have static
	     initialization, make the init function a weak reference.  */
	  if ((!TYPE_NEEDS_CONSTRUCTING (obtype)
	       || TYPE_HAS_CONSTEXPR_CTOR (obtype)
	       || TYPE_HAS_TRIVIAL_DFLT (obtype))
	      && TYPE_HAS_TRIVIAL_DESTRUCTOR (obtype)
	      && DECL_EXTERNAL (var))
	    declare_weak (fn);
	  else
	    DECL_WEAK (fn) = DECL_WEAK (var);
	}
      DECL_VISIBILITY (fn) = DECL_VISIBILITY (var);
      DECL_VISIBILITY_SPECIFIED (fn) = DECL_VISIBILITY_SPECIFIED (var);
      DECL_DLLIMPORT_P (fn) = DECL_DLLIMPORT_P (var);
      DECL_IGNORED_P (fn) = 1;
      mark_used (fn);

      DECL_BEFRIENDING_CLASSES (fn) = var;

      set_global_binding (fn);
    }
  return fn;
}

/* Get a FUNCTION_DECL for the init wrapper function for the thread_local
   variable VAR.  The wrapper function calls the init function (if any) for
   VAR and then returns a reference to VAR.  The wrapper function is used
   in place of VAR everywhere VAR is mentioned.  */

static tree
get_tls_wrapper_fn (tree var)
{
  /* Only C++11 TLS vars need this wrapper fn.  */
  if (!var_needs_tls_wrapper (var))
    return NULL_TREE;

  tree sname = mangle_tls_wrapper_fn (var);
  tree fn = get_global_binding (sname);
  if (!fn)
    {
      /* A named rvalue reference is an lvalue, so the wrapper should
	 always return an lvalue reference.  */
      tree type = non_reference (TREE_TYPE (var));
      type = build_reference_type (type);
      tree fntype = build_function_type (type, void_list_node);

      fn = build_lang_decl_loc (DECL_SOURCE_LOCATION (var),
				FUNCTION_DECL, sname, fntype);
      SET_DECL_LANGUAGE (fn, lang_c);
      TREE_PUBLIC (fn) = TREE_PUBLIC (var);
      DECL_ARTIFICIAL (fn) = true;
      DECL_IGNORED_P (fn) = 1;
      /* The wrapper is inline and emitted everywhere var is used.  */
      DECL_DECLARED_INLINE_P (fn) = true;
      if (TREE_PUBLIC (var))
	{
	  comdat_linkage (fn);
#ifdef HAVE_GAS_HIDDEN
	  /* Make the wrapper bind locally; there's no reason to share
	     the wrapper between multiple shared objects.  */
	  DECL_VISIBILITY (fn) = VISIBILITY_INTERNAL;
	  DECL_VISIBILITY_SPECIFIED (fn) = true;
#endif
	}
      if (!TREE_PUBLIC (fn))
	DECL_INTERFACE_KNOWN (fn) = true;
      mark_used (fn);
      note_vague_linkage_fn (fn);

#if 0
      /* We want CSE to commonize calls to the wrapper, but marking it as
	 pure is unsafe since it has side-effects.  I guess we need a new
	 ECF flag even weaker than ECF_PURE.  FIXME!  */
      DECL_PURE_P (fn) = true;
#endif

      DECL_BEFRIENDING_CLASSES (fn) = var;

      set_global_binding (fn);
    }
  return fn;
}

/* If EXPR is a thread_local variable that should be wrapped by init
   wrapper function, return a call to that function, otherwise return
   NULL.  */

tree
maybe_get_tls_wrapper_call (tree expr)
{
  if (VAR_P (expr)
      && !processing_template_decl
      && !cp_unevaluated_operand
      && CP_DECL_THREAD_LOCAL_P (expr))
    if (tree wrap = get_tls_wrapper_fn (expr))
      return build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
  return NULL;
}

/* At EOF, generate the definition for the TLS wrapper function FN:

   T& var_wrapper() {
     if (init_fn) init_fn();
     return var;
   }  */

static void
generate_tls_wrapper (tree fn)
{
  tree var = DECL_BEFRIENDING_CLASSES (fn);

  start_preparsed_function (fn, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
  tree body = begin_function_body ();
  /* Only call the init fn if there might be one.  */
  if (tree init_fn = get_tls_init_fn (var))
    {
      tree if_stmt = NULL_TREE;
      /* If init_fn is a weakref, make sure it exists before calling.  */
      if (lookup_attribute ("weak", DECL_ATTRIBUTES (init_fn)))
	{
	  if_stmt = begin_if_stmt ();
	  tree addr = cp_build_addr_expr (init_fn, tf_warning_or_error);
	  tree cond = cp_build_binary_op (DECL_SOURCE_LOCATION (var),
					  NE_EXPR, addr, nullptr_node,
					  tf_warning_or_error);
	  finish_if_stmt_cond (cond, if_stmt);
	}
      finish_expr_stmt (build_cxx_call
			(init_fn, 0, NULL, tf_warning_or_error));
      if (if_stmt)
	{
	  finish_then_clause (if_stmt);
	  finish_if_stmt (if_stmt);
	}
    }
  else
    /* If there's no initialization, the wrapper is a constant function.  */
    TREE_READONLY (fn) = true;
  finish_return_stmt (convert_from_reference (var));
  finish_function_body (body);
  expand_or_defer_fn (finish_function (/*inline_p=*/false));
}

/* Start the process of running a particular set of global constructors
   or destructors.  Subroutine of do_[cd]tors.  Also called from
   vtv_start_verification_constructor_init_function.  */

static tree
start_objects (int method_type, int initp)
{
  /* Make ctor or dtor function.  METHOD_TYPE may be 'I' or 'D'.  */
  int module_init = 0;

  if (initp == DEFAULT_INIT_PRIORITY && method_type == 'I')
    module_init = module_initializer_kind ();

  tree name = NULL_TREE;
  if (module_init > 0)
    name = mangle_module_global_init (0);
  else
    {
      char type[14];

      unsigned len = sprintf (type, "sub_%c", method_type);
      if (initp != DEFAULT_INIT_PRIORITY)
	{
	  char joiner = '_';
#ifdef JOINER
	  joiner = JOINER;
#endif
	  type[len++] = joiner;
	  sprintf (type + len, "%.5u", initp);
	}
      name = get_file_function_name (type);
    }

  tree fntype =	build_function_type (void_type_node, void_list_node);
  tree fndecl = build_lang_decl (FUNCTION_DECL, name, fntype);
  DECL_CONTEXT (fndecl) = FROB_CONTEXT (global_namespace);
  if (module_init > 0)
    {
      SET_DECL_ASSEMBLER_NAME (fndecl, name);
      TREE_PUBLIC (fndecl) = true;
      determine_visibility (fndecl);
    }
  else
    TREE_PUBLIC (fndecl) = 0;
  start_preparsed_function (fndecl, /*attrs=*/NULL_TREE, SF_PRE_PARSED);

  /* Mark as artificial because it's not explicitly in the user's
     source code.  */
  DECL_ARTIFICIAL (current_function_decl) = 1;

  /* Mark this declaration as used to avoid spurious warnings.  */
  TREE_USED (current_function_decl) = 1;

  /* Mark this function as a global constructor or destructor.  */
  if (method_type == 'I')
    DECL_GLOBAL_CTOR_P (current_function_decl) = 1;
  else
    DECL_GLOBAL_DTOR_P (current_function_decl) = 1;

  tree body = begin_compound_stmt (BCS_FN_BODY);

  if (module_init > 0)
    {
      // 'static bool __in_chrg = false;
      // if (__inchrg) return;
      // __inchrg = true
      tree var = build_lang_decl (VAR_DECL, in_charge_identifier,
				  boolean_type_node);
      DECL_CONTEXT (var) = fndecl;
      DECL_ARTIFICIAL (var) = true;
      TREE_STATIC (var) = true;
      pushdecl (var);
      cp_finish_decl (var, NULL_TREE, false, NULL_TREE, 0);

      tree if_stmt = begin_if_stmt ();
      finish_if_stmt_cond (var, if_stmt);
      finish_return_stmt (NULL_TREE);
      finish_then_clause (if_stmt);
      finish_if_stmt (if_stmt);

      tree assign = build2 (MODIFY_EXPR, boolean_type_node,
			    var, boolean_true_node);
      TREE_SIDE_EFFECTS (assign) = true;
      finish_expr_stmt (assign);
    }

  if (module_init)
    module_add_import_initializers ();

  return body;
}

/* Finish the process of running a particular set of global constructors
   or destructors.  Subroutine of do_[cd]tors.  */

static void
finish_objects (int method_type, int initp, tree body)
{
  /* Finish up.  */
  finish_compound_stmt (body);
  tree fn = finish_function (/*inline_p=*/false);

  if (method_type == 'I')
    {
      DECL_STATIC_CONSTRUCTOR (fn) = 1;
      decl_init_priority_insert (fn, initp);
    }
  else
    {
      DECL_STATIC_DESTRUCTOR (fn) = 1;
      decl_fini_priority_insert (fn, initp);
    }

  expand_or_defer_fn (fn);
}

/* The names of the parameters to the function created to handle
   initializations and destructions for objects with static storage
   duration.  */
#define INITIALIZE_P_IDENTIFIER "__initialize_p"
#define PRIORITY_IDENTIFIER "__priority"

/* The name of the function we create to handle initializations and
   destructions for objects with static storage duration.  */
#define SSDF_IDENTIFIER "__static_initialization_and_destruction"

/* The declaration for the __INITIALIZE_P argument.  */
static GTY(()) tree initialize_p_decl;

/* The declaration for the __PRIORITY argument.  */
static GTY(()) tree priority_decl;

/* The declaration for the static storage duration function.  */
static GTY(()) tree ssdf_decl;

/* All the static storage duration functions created in this
   translation unit.  */
static GTY(()) vec<tree, va_gc> *ssdf_decls;

/* A map from priority levels to information about that priority
   level.  There may be many such levels, so efficient lookup is
   important.  */
static splay_tree priority_info_map;

/* Begins the generation of the function that will handle all
   initialization and destruction of objects with static storage
   duration.  The function generated takes two parameters of type
   `int': __INITIALIZE_P and __PRIORITY.  If __INITIALIZE_P is
   nonzero, it performs initializations.  Otherwise, it performs
   destructions.  It only performs those initializations or
   destructions with the indicated __PRIORITY.  The generated function
   returns no value.

   It is assumed that this function will only be called once per
   translation unit.  */

static tree
start_static_storage_duration_function (unsigned count)
{
  tree type;
  tree body;
  char id[sizeof (SSDF_IDENTIFIER) + 1 /* '\0' */ + 32];

  /* Create the identifier for this function.  It will be of the form
     SSDF_IDENTIFIER_<number>.  */
  sprintf (id, "%s_%u", SSDF_IDENTIFIER, count);

  type = build_function_type_list (void_type_node,
				   integer_type_node, integer_type_node,
				   NULL_TREE);

  /* Create the FUNCTION_DECL itself.  */
  ssdf_decl = build_lang_decl (FUNCTION_DECL,
			       get_identifier (id),
			       type);
  TREE_PUBLIC (ssdf_decl) = 0;
  DECL_ARTIFICIAL (ssdf_decl) = 1;

  /* Put this function in the list of functions to be called from the
     static constructors and destructors.  */
  if (!ssdf_decls)
    {
      vec_alloc (ssdf_decls, 32);

      /* Take this opportunity to initialize the map from priority
	 numbers to information about that priority level.  */
      priority_info_map = splay_tree_new (splay_tree_compare_ints,
					  /*delete_key_fn=*/0,
					  /*delete_value_fn=*/
					  splay_tree_delete_pointers);

      /* We always need to generate functions for the
	 DEFAULT_INIT_PRIORITY so enter it now.  That way when we walk
	 priorities later, we'll be sure to find the
	 DEFAULT_INIT_PRIORITY.  */
      get_priority_info (DEFAULT_INIT_PRIORITY);
    }

  vec_safe_push (ssdf_decls, ssdf_decl);

  /* Create the argument list.  */
  initialize_p_decl = cp_build_parm_decl
    (ssdf_decl, get_identifier (INITIALIZE_P_IDENTIFIER), integer_type_node);
  TREE_USED (initialize_p_decl) = 1;
  priority_decl = cp_build_parm_decl
    (ssdf_decl, get_identifier (PRIORITY_IDENTIFIER), integer_type_node);
  TREE_USED (priority_decl) = 1;

  DECL_CHAIN (initialize_p_decl) = priority_decl;
  DECL_ARGUMENTS (ssdf_decl) = initialize_p_decl;

  /* Put the function in the global scope.  */
  pushdecl (ssdf_decl);

  /* Start the function itself.  This is equivalent to declaring the
     function as:

       static void __ssdf (int __initialize_p, init __priority_p);

     It is static because we only need to call this function from the
     various constructor and destructor functions for this module.  */
  start_preparsed_function (ssdf_decl,
			    /*attrs=*/NULL_TREE,
			    SF_PRE_PARSED);

  /* Set up the scope of the outermost block in the function.  */
  body = begin_compound_stmt (BCS_FN_BODY);

  return body;
}

/* Finish the generation of the function which performs initialization
   and destruction of objects with static storage duration.  After
   this point, no more such objects can be created.  */

static void
finish_static_storage_duration_function (tree body)
{
  /* Close out the function.  */
  finish_compound_stmt (body);
  expand_or_defer_fn (finish_function (/*inline_p=*/false));
}

/* Return the information about the indicated PRIORITY level.  If no
   code to handle this level has yet been generated, generate the
   appropriate prologue.  */

static priority_info
get_priority_info (int priority)
{
  priority_info pi;
  splay_tree_node n;

  n = splay_tree_lookup (priority_info_map,
			 (splay_tree_key) priority);
  if (!n)
    {
      /* Create a new priority information structure, and insert it
	 into the map.  */
      pi = XNEW (struct priority_info_s);
      pi->initializations_p = 0;
      pi->destructions_p = 0;
      splay_tree_insert (priority_info_map,
			 (splay_tree_key) priority,
			 (splay_tree_value) pi);
    }
  else
    pi = (priority_info) n->value;

  return pi;
}

/* The effective initialization priority of a DECL.  */

#define DECL_EFFECTIVE_INIT_PRIORITY(decl)				      \
	((!DECL_HAS_INIT_PRIORITY_P (decl) || DECL_INIT_PRIORITY (decl) == 0) \
	 ? DEFAULT_INIT_PRIORITY : DECL_INIT_PRIORITY (decl))

/* Whether a DECL needs a guard to protect it against multiple
   initialization.  */

#define NEEDS_GUARD_P(decl) (TREE_PUBLIC (decl) && (DECL_COMMON (decl)      \
						    || DECL_ONE_ONLY (decl) \
						    || DECL_WEAK (decl)))

/* Called from one_static_initialization_or_destruction(),
   via walk_tree.
   Walks the initializer list of a global variable and looks for
   temporary variables (DECL_NAME() == NULL and DECL_ARTIFICIAL != 0)
   and that have their DECL_CONTEXT() == NULL.
   For each such temporary variable, set their DECL_CONTEXT() to
   the current function. This is necessary because otherwise
   some optimizers (enabled by -O2 -fprofile-arcs) might crash
   when trying to refer to a temporary variable that does not have
   it's DECL_CONTECT() properly set.  */
static tree 
fix_temporary_vars_context_r (tree *node,
			      int  * /*unused*/,
			      void * /*unused1*/)
{
  gcc_assert (current_function_decl);

  if (TREE_CODE (*node) == BIND_EXPR)
    {
      tree var;

      for (var = BIND_EXPR_VARS (*node); var; var = DECL_CHAIN (var))
	if (VAR_P (var)
	  && !DECL_NAME (var)
	  && DECL_ARTIFICIAL (var)
	  && !DECL_CONTEXT (var))
	  DECL_CONTEXT (var) = current_function_decl;
    }

  return NULL_TREE;
}

/* Set up to handle the initialization or destruction of DECL.  If
   INITP is nonzero, we are initializing the variable.  Otherwise, we
   are destroying it.  */

static void
one_static_initialization_or_destruction (tree decl, tree init, bool initp)
{
  tree guard_if_stmt = NULL_TREE;
  tree guard;

  /* If we are supposed to destruct and there's a trivial destructor,
     nothing has to be done.  */
  if (!initp
      && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
    return;

  /* Trick the compiler into thinking we are at the file and line
     where DECL was declared so that error-messages make sense, and so
     that the debugger will show somewhat sensible file and line
     information.  */
  input_location = DECL_SOURCE_LOCATION (decl);

  /* Make sure temporary variables in the initialiser all have
     their DECL_CONTEXT() set to a value different from NULL_TREE.
     This can happen when global variables initializers are built.
     In that case, the DECL_CONTEXT() of the global variables _AND_ of all 
     the temporary variables that might have been generated in the
     accompanying initializers is NULL_TREE, meaning the variables have been
     declared in the global namespace.
     What we want to do here is to fix that and make sure the DECL_CONTEXT()
     of the temporaries are set to the current function decl.  */
  cp_walk_tree_without_duplicates (&init,
				   fix_temporary_vars_context_r,
				   NULL);

  /* Because of:

       [class.access.spec]

       Access control for implicit calls to the constructors,
       the conversion functions, or the destructor called to
       create and destroy a static data member is performed as
       if these calls appeared in the scope of the member's
       class.

     we pretend we are in a static member function of the class of
     which the DECL is a member.  */
  if (member_p (decl))
    {
      DECL_CONTEXT (current_function_decl) = DECL_CONTEXT (decl);
      DECL_STATIC_FUNCTION_P (current_function_decl) = 1;
    }

  /* Assume we don't need a guard.  */
  guard = NULL_TREE;
  /* We need a guard if this is an object with external linkage that
     might be initialized in more than one place.  (For example, a
     static data member of a template, when the data member requires
     construction.)  */
  if (NEEDS_GUARD_P (decl))
    {
      tree guard_cond;

      guard = get_guard (decl);

      /* When using __cxa_atexit, we just check the GUARD as we would
	 for a local static.  */
      if (flag_use_cxa_atexit)
	{
	  /* When using __cxa_atexit, we never try to destroy
	     anything from a static destructor.  */
	  gcc_assert (initp);
	  guard_cond = get_guard_cond (guard, false);
	}
      /* If we don't have __cxa_atexit, then we will be running
	 destructors from .fini sections, or their equivalents.  So,
	 we need to know how many times we've tried to initialize this
	 object.  We do initializations only if the GUARD is zero,
	 i.e., if we are the first to initialize the variable.  We do
	 destructions only if the GUARD is one, i.e., if we are the
	 last to destroy the variable.  */
      else if (initp)
	guard_cond
	  = cp_build_binary_op (input_location,
				EQ_EXPR,
				cp_build_unary_op (PREINCREMENT_EXPR,
						   guard,
						   /*noconvert=*/true,
						   tf_warning_or_error),
				integer_one_node,
				tf_warning_or_error);
      else
	guard_cond
	  = cp_build_binary_op (input_location,
				EQ_EXPR,
				cp_build_unary_op (PREDECREMENT_EXPR,
						   guard,
						   /*noconvert=*/true,
						   tf_warning_or_error),
				integer_zero_node,
				tf_warning_or_error);

      guard_if_stmt = begin_if_stmt ();
      finish_if_stmt_cond (guard_cond, guard_if_stmt);
    }


  /* If we're using __cxa_atexit, we have not already set the GUARD,
     so we must do so now.  */
  if (guard && initp && flag_use_cxa_atexit)
    finish_expr_stmt (set_guard (guard));

  /* Perform the initialization or destruction.  */
  if (initp)
    {
      if (init)
	{
	  finish_expr_stmt (init);
	  if (sanitize_flags_p (SANITIZE_ADDRESS, decl))
	    {
	      varpool_node *vnode = varpool_node::get (decl);
	      if (vnode)
		vnode->dynamically_initialized = 1;
	    }
	}

      /* If we're using __cxa_atexit, register a function that calls the
	 destructor for the object.  */
      if (flag_use_cxa_atexit)
	finish_expr_stmt (register_dtor_fn (decl));
    }
  else
    finish_expr_stmt (build_cleanup (decl));

  /* Finish the guard if-stmt, if necessary.  */
  if (guard)
    {
      finish_then_clause (guard_if_stmt);
      finish_if_stmt (guard_if_stmt);
    }

  /* Now that we're done with DECL we don't need to pretend to be a
     member of its class any longer.  */
  DECL_CONTEXT (current_function_decl) = NULL_TREE;
  DECL_STATIC_FUNCTION_P (current_function_decl) = 0;
}

/* Generate code to do the initialization or destruction of the decls in VARS,
   a TREE_LIST of VAR_DECL with static storage duration.
   Whether initialization or destruction is performed is specified by INITP.  */

static void
do_static_initialization_or_destruction (tree vars, bool initp)
{
  tree node, init_if_stmt, cond;

  /* Build the outer if-stmt to check for initialization or destruction.  */
  init_if_stmt = begin_if_stmt ();
  cond = initp ? integer_one_node : integer_zero_node;
  cond = cp_build_binary_op (input_location,
			     EQ_EXPR,
			     initialize_p_decl,
			     cond,
			     tf_warning_or_error);
  finish_if_stmt_cond (cond, init_if_stmt);

  /* To make sure dynamic construction doesn't access globals from other
     compilation units where they might not be yet constructed, for
     -fsanitize=address insert __asan_before_dynamic_init call that
     prevents access to either all global variables that need construction
     in other compilation units, or at least those that haven't been
     initialized yet.  Variables that need dynamic construction in
     the current compilation unit are kept accessible.  */
  if (initp && (flag_sanitize & SANITIZE_ADDRESS))
    finish_expr_stmt (asan_dynamic_init_call (/*after_p=*/false));

  node = vars;
  do {
    tree decl = TREE_VALUE (node);
    tree priority_if_stmt;
    int priority;
    priority_info pi;

    /* If we don't need a destructor, there's nothing to do.  Avoid
       creating a possibly empty if-stmt.  */
    if (!initp && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
      {
	node = TREE_CHAIN (node);
	continue;
      }

    /* Remember that we had an initialization or finalization at this
       priority.  */
    priority = DECL_EFFECTIVE_INIT_PRIORITY (decl);
    pi = get_priority_info (priority);
    if (initp)
      pi->initializations_p = 1;
    else
      pi->destructions_p = 1;

    /* Conditionalize this initialization on being in the right priority
       and being initializing/finalizing appropriately.  */
    priority_if_stmt = begin_if_stmt ();
    cond = cp_build_binary_op (input_location,
			       EQ_EXPR,
			       priority_decl,
			       build_int_cst (NULL_TREE, priority),
			       tf_warning_or_error);
    finish_if_stmt_cond (cond, priority_if_stmt);

    /* Process initializers with same priority.  */
    for (; node
	   && DECL_EFFECTIVE_INIT_PRIORITY (TREE_VALUE (node)) == priority;
	 node = TREE_CHAIN (node))
      /* Do one initialization or destruction.  */
      one_static_initialization_or_destruction (TREE_VALUE (node),
						TREE_PURPOSE (node), initp);

    /* Finish up the priority if-stmt body.  */
    finish_then_clause (priority_if_stmt);
    finish_if_stmt (priority_if_stmt);

  } while (node);

  /* Revert what __asan_before_dynamic_init did by calling
     __asan_after_dynamic_init.  */
  if (initp && (flag_sanitize & SANITIZE_ADDRESS))
    finish_expr_stmt (asan_dynamic_init_call (/*after_p=*/true));

  /* Finish up the init/destruct if-stmt body.  */
  finish_then_clause (init_if_stmt);
  finish_if_stmt (init_if_stmt);
}

/* VARS is a list of variables with static storage duration which may
   need initialization and/or finalization.  Remove those variables
   that don't really need to be initialized or finalized, and return
   the resulting list.  The order in which the variables appear in
   VARS is in reverse order of the order in which they should actually
   be initialized.  The list we return is in the unreversed order;
   i.e., the first variable should be initialized first.  */

static tree
prune_vars_needing_no_initialization (tree *vars)
{
  tree *var = vars;
  tree result = NULL_TREE;

  while (*var)
    {
      tree t = *var;
      tree decl = TREE_VALUE (t);
      tree init = TREE_PURPOSE (t);

      /* Deal gracefully with error.  */
      if (error_operand_p (decl))
	{
	  var = &TREE_CHAIN (t);
	  continue;
	}

      /* The only things that can be initialized are variables.  */
      gcc_assert (VAR_P (decl));

      /* If this object is not defined, we don't need to do anything
	 here.  */
      if (DECL_EXTERNAL (decl))
	{
	  var = &TREE_CHAIN (t);
	  continue;
	}

      /* Also, if the initializer already contains errors, we can bail
	 out now.  */
      if (init && TREE_CODE (init) == TREE_LIST
	  && value_member (error_mark_node, init))
	{
	  var = &TREE_CHAIN (t);
	  continue;
	}

      /* This variable is going to need initialization and/or
	 finalization, so we add it to the list.  */
      *var = TREE_CHAIN (t);
      TREE_CHAIN (t) = result;
      result = t;
    }

  return result;
}

/* Make sure we have told the back end about all the variables in
   VARS.  */

static void
write_out_vars (tree vars)
{
  tree v;

  for (v = vars; v; v = TREE_CHAIN (v))
    {
      tree var = TREE_VALUE (v);
      if (!var_finalized_p (var))
	{
	  import_export_decl (var);
	  rest_of_decl_compilation (var, 1, 1);
	}
    }
}

/* Generate a static constructor (if CONSTRUCTOR_P) or destructor
   (otherwise) that will initialize all global objects with static
   storage duration having the indicated PRIORITY.  */

static void
generate_ctor_or_dtor_function (bool constructor_p, int priority,
				location_t *locus)
{
  input_location = *locus;

  /* We use `I' to indicate initialization and `D' to indicate
     destruction.  */
  char function_key = constructor_p ? 'I' : 'D';

  /* We emit the function lazily, to avoid generating empty
     global constructors and destructors.  */
  tree body = NULL_TREE;

  if (constructor_p && priority == DEFAULT_INIT_PRIORITY)
    {
      bool objc = c_dialect_objc () && objc_static_init_needed_p ();

      /* We may have module initialization to emit and/or insert
	 before other intializations.  */
      if (module_initializer_kind () || objc)
	body = start_objects (function_key, priority);

      /* For Objective-C++, we may need to initialize metadata found
         in this module.  This must be done _before_ any other static
         initializations.  */
      if (objc)
	objc_generate_static_init_call (NULL_TREE);
    }

  /* Call the static storage duration function with appropriate
     arguments.  */
  tree fndecl;
  size_t i;
  FOR_EACH_VEC_SAFE_ELT (ssdf_decls, i, fndecl)
    {
      /* Calls to pure or const functions will expand to nothing.  */
      if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE)))
	{
	  if (! body)
	    body = start_objects (function_key, priority);

	  tree call = cp_build_function_call_nary (fndecl, tf_warning_or_error,
						   build_int_cst (NULL_TREE,
								  constructor_p),
						   build_int_cst (NULL_TREE,
								  priority),
						   NULL_TREE);
	  finish_expr_stmt (call);
	}
    }

  /* Close out the function.  */
  if (body)
    finish_objects (function_key, priority, body);
}

/* Generate constructor and destructor functions for the priority
   indicated by N.  */

static int
generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
{
  location_t *locus = (location_t *) data;
  int priority = (int) n->key;
  priority_info pi = (priority_info) n->value;

  /* Generate the functions themselves, but only if they are really
     needed.  */
  if (pi->initializations_p)
    generate_ctor_or_dtor_function (/*constructor_p=*/true, priority, locus);
  if (pi->destructions_p)
    generate_ctor_or_dtor_function (/*constructor_p=*/false, priority, locus);

  /* Keep iterating.  */
  return 0;
}

/* Return C++ property of T, based on given operation OP.  */

static int
cpp_check (tree t, cpp_operation op)
{
  switch (op)
    {
      case HAS_DEPENDENT_TEMPLATE_ARGS:
	{
	  tree ti = CLASSTYPE_TEMPLATE_INFO (t);
	  if (!ti)
	    return 0;
	  ++processing_template_decl;
	  const bool dep = any_dependent_template_arguments_p (TI_ARGS (ti));
	  --processing_template_decl;
	  return dep;
	}
      case IS_ABSTRACT:
	return DECL_PURE_VIRTUAL_P (t);
      case IS_ASSIGNMENT_OPERATOR:
	return DECL_ASSIGNMENT_OPERATOR_P (t);
      case IS_CONSTRUCTOR:
	return DECL_CONSTRUCTOR_P (t);
      case IS_DESTRUCTOR:
	return DECL_DESTRUCTOR_P (t);
      case IS_COPY_CONSTRUCTOR:
	return DECL_COPY_CONSTRUCTOR_P (t);
      case IS_MOVE_CONSTRUCTOR:
	return DECL_MOVE_CONSTRUCTOR_P (t);
      case IS_TEMPLATE:
	return TREE_CODE (t) == TEMPLATE_DECL;
      case IS_TRIVIAL:
	return trivial_type_p (t);
      default:
        return 0;
    }
}

/* Collect source file references recursively, starting from NAMESPC.  */

static void 
collect_source_refs (tree namespc) 
{
  /* Iterate over names in this name space.  */
  for (tree t = NAMESPACE_LEVEL (namespc)->names; t; t = TREE_CHAIN (t))
    if (DECL_IS_UNDECLARED_BUILTIN (t))
      ;
    else if (TREE_CODE (t) == NAMESPACE_DECL && !DECL_NAMESPACE_ALIAS (t))
      collect_source_refs (t);
    else
      collect_source_ref (DECL_SOURCE_FILE (t));
}

/* Collect decls relevant to SOURCE_FILE from all namespaces recursively,
   starting from NAMESPC.  */

static void
collect_ada_namespace (tree namespc, const char *source_file)
{
  tree decl = NAMESPACE_LEVEL (namespc)->names;

  /* Collect decls from this namespace.  This will skip
     NAMESPACE_DECLs (both aliases and regular, it cannot tell).  */
  collect_ada_nodes (decl, source_file);

  /* Now scan for namespace children, and dump them.  */
  for (; decl; decl = TREE_CHAIN (decl))
    if (TREE_CODE (decl) == NAMESPACE_DECL && !DECL_NAMESPACE_ALIAS (decl))
      collect_ada_namespace (decl, source_file);
}

/* Returns true iff there is a definition available for variable or
   function DECL.  */

bool
decl_defined_p (tree decl)
{
  if (TREE_CODE (decl) == FUNCTION_DECL)
    return (DECL_INITIAL (decl) != NULL_TREE
	    /* A pending instantiation of a friend temploid is defined.  */
	    || (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)
		&& DECL_INITIAL (DECL_TEMPLATE_RESULT
				 (DECL_TI_TEMPLATE (decl)))));
  else
    {
      gcc_assert (VAR_P (decl));
      return !DECL_EXTERNAL (decl);
    }
}

/* Nonzero for a VAR_DECL whose value can be used in a constant expression.

      [expr.const]

      An integral constant-expression can only involve ... const
      variables of integral or enumeration types initialized with
      constant expressions ...

      C++0x also allows constexpr variables and temporaries initialized
      with constant expressions.  We handle the former here, but the latter
      are just folded away in cxx_eval_constant_expression.

   The standard does not require that the expression be non-volatile.
   G++ implements the proposed correction in DR 457.  */

bool
decl_constant_var_p (tree decl)
{
  if (!decl_maybe_constant_var_p (decl))
    return false;

  /* We don't know if a template static data member is initialized with
     a constant expression until we instantiate its initializer.  Even
     in the case of a constexpr variable, we can't treat it as a
     constant until its initializer is complete in case it's used in
     its own initializer.  */
  maybe_instantiate_decl (decl);
  return DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl);
}

/* Returns true if DECL could be a symbolic constant variable, depending on
   its initializer.  */

bool
decl_maybe_constant_var_p (tree decl)
{
  tree type = TREE_TYPE (decl);
  if (!VAR_P (decl))
    return false;
  if (DECL_DECLARED_CONSTEXPR_P (decl) && !TREE_THIS_VOLATILE (decl))
    return true;
  if (DECL_HAS_VALUE_EXPR_P (decl))
    /* A proxy isn't constant.  */
    return false;
  if (TYPE_REF_P (type))
    /* References can be constant.  */;
  else if (CP_TYPE_CONST_NON_VOLATILE_P (type)
	   && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
    /* And const integers.  */;
  else
    return false;

  if (DECL_INITIAL (decl)
      && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
    /* We know the initializer, and it isn't constant.  */
    return false;
  else
    return true;
}

/* Complain that DECL uses a type with no linkage.  In C++98 mode this is
   called from grokfndecl and grokvardecl; in all modes it is called from
   cp_write_global_declarations.  */

void
no_linkage_error (tree decl)
{
  if (cxx_dialect >= cxx11
      && (decl_defined_p (decl)
	  /* Treat templates which limit_bad_template_recursion decided
	     not to instantiate as if they were defined.  */
	  || (errorcount + sorrycount > 0
	      && DECL_LANG_SPECIFIC (decl)
	      && DECL_TEMPLATE_INFO (decl)
	      && warning_suppressed_p (decl /* What warning? */))))
    /* In C++11 it's ok if the decl is defined.  */
    return;

  if (DECL_LANG_SPECIFIC (decl) && DECL_MODULE_IMPORT_P (decl))
    /* An imported decl is ok.  */
    return;

  tree t = no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false);
  if (t == NULL_TREE)
    /* The type that got us on no_linkage_decls must have gotten a name for
       linkage purposes.  */;
  else if (CLASS_TYPE_P (t) && TYPE_BEING_DEFINED (t))
    // FIXME: This is now invalid, as a DR to c++98
    /* The type might end up having a typedef name for linkage purposes.  */
    vec_safe_push (no_linkage_decls, decl);
  else if (TYPE_UNNAMED_P (t))
    {
      bool d = false;
      auto_diagnostic_group grp;
      if (cxx_dialect >= cxx11)
	d = permerror (DECL_SOURCE_LOCATION (decl), "%q#D, declared using "
		       "unnamed type, is used but never defined", decl);
      else if (DECL_EXTERN_C_P (decl))
	/* Allow this; it's pretty common in C.  */;
      else if (VAR_P (decl))
	/* DRs 132, 319 and 389 seem to indicate types with
	   no linkage can only be used to declare extern "C"
	   entities.  Since it's not always an error in the
	   ISO C++ 90 Standard, we only issue a warning.  */
	d = warning_at (DECL_SOURCE_LOCATION (decl), 0, "unnamed type "
			"with no linkage used to declare variable %q#D with "
			"linkage", decl);
      else
	d = permerror (DECL_SOURCE_LOCATION (decl), "unnamed type with no "
		       "linkage used to declare function %q#D with linkage",
		       decl);
      if (d && is_typedef_decl (TYPE_NAME (t)))
	inform (DECL_SOURCE_LOCATION (TYPE_NAME (t)), "%q#D does not refer "
		"to the unqualified type, so it is not used for linkage",
		TYPE_NAME (t));
    }
  else if (cxx_dialect >= cxx11)
    {
      if (VAR_P (decl) || !DECL_PURE_VIRTUAL_P (decl))
	permerror (DECL_SOURCE_LOCATION (decl),
		   "%q#D, declared using local type "
		   "%qT, is used but never defined", decl, t);
    }
  else if (VAR_P (decl))
    warning_at (DECL_SOURCE_LOCATION (decl), 0, "type %qT with no linkage "
		"used to declare variable %q#D with linkage", t, decl);
  else
    permerror (DECL_SOURCE_LOCATION (decl), "type %qT with no linkage used "
	       "to declare function %q#D with linkage", t, decl);
}

/* Collect declarations from all namespaces relevant to SOURCE_FILE.  */

static void
collect_all_refs (const char *source_file)
{
  collect_ada_namespace (global_namespace, source_file);
}

/* Clear DECL_EXTERNAL for NODE.  */

static bool
clear_decl_external (struct cgraph_node *node, void * /*data*/)
{
  DECL_EXTERNAL (node->decl) = 0;
  return false;
}

/* Build up the function to run dynamic initializers for thread_local
   variables in this translation unit and alias the init functions for the
   individual variables to it.  */

static void
handle_tls_init (void)
{
  tree vars = prune_vars_needing_no_initialization (&tls_aggregates);
  if (vars == NULL_TREE)
    return;

  location_t loc = DECL_SOURCE_LOCATION (TREE_VALUE (vars));

  write_out_vars (vars);

  tree guard = build_decl (loc, VAR_DECL, get_identifier ("__tls_guard"),
			   boolean_type_node);
  TREE_PUBLIC (guard) = false;
  TREE_STATIC (guard) = true;
  DECL_ARTIFICIAL (guard) = true;
  DECL_IGNORED_P (guard) = true;
  TREE_USED (guard) = true;
  CP_DECL_THREAD_LOCAL_P (guard) = true;
  set_decl_tls_model (guard, decl_default_tls_model (guard));
  pushdecl_top_level_and_finish (guard, NULL_TREE);

  tree fn = get_local_tls_init_fn (loc);
  start_preparsed_function (fn, NULL_TREE, SF_PRE_PARSED);
  tree body = begin_function_body ();
  tree if_stmt = begin_if_stmt ();
  tree cond = cp_build_unary_op (TRUTH_NOT_EXPR, guard, false,
				 tf_warning_or_error);
  finish_if_stmt_cond (cond, if_stmt);
  finish_expr_stmt (cp_build_modify_expr (loc, guard, NOP_EXPR,
					  boolean_true_node,
					  tf_warning_or_error));
  for (; vars; vars = TREE_CHAIN (vars))
    {
      tree var = TREE_VALUE (vars);
      tree init = TREE_PURPOSE (vars);
      one_static_initialization_or_destruction (var, init, true);

      /* Output init aliases even with -fno-extern-tls-init.  */
      if (TARGET_SUPPORTS_ALIASES && TREE_PUBLIC (var))
	{
          tree single_init_fn = get_tls_init_fn (var);
	  if (single_init_fn == NULL_TREE)
	    continue;
	  cgraph_node *alias
	    = cgraph_node::get_create (fn)->create_same_body_alias
		(single_init_fn, fn);
	  gcc_assert (alias != NULL);
	}
    }

  finish_then_clause (if_stmt);
  finish_if_stmt (if_stmt);
  finish_function_body (body);
  expand_or_defer_fn (finish_function (/*inline_p=*/false));
}

/* We're at the end of compilation, so generate any mangling aliases that
   we've been saving up, if DECL is going to be output and ID2 isn't
   already taken by another declaration.  */

static void
generate_mangling_alias (tree decl, tree id2)
{
  struct cgraph_node *n = NULL;

  if (TREE_CODE (decl) == FUNCTION_DECL)
    {
      n = cgraph_node::get (decl);
      if (!n)
	/* Don't create an alias to an unreferenced function.  */
	return;
    }

  tree *slot
    = mangled_decls->find_slot_with_hash (id2, IDENTIFIER_HASH_VALUE (id2),
					  INSERT);

  /* If there's a declaration already using this mangled name,
     don't create a compatibility alias that conflicts.  */
  if (*slot)
    return;

  tree alias = make_alias_for (decl, id2);
  *slot = alias;

  DECL_IGNORED_P (alias) = 1;
  TREE_PUBLIC (alias) = TREE_PUBLIC (decl);
  DECL_VISIBILITY (alias) = DECL_VISIBILITY (decl);
  if (vague_linkage_p (decl))
    DECL_WEAK (alias) = 1;

  if (n)
    n->create_same_body_alias (alias, decl);
  else
    varpool_node::create_extra_name_alias (alias, decl);
}

/* Note that we might want to emit an alias with the symbol ID2 for DECL at
   the end of translation, for compatibility across bugs in the mangling
   implementation.  */

void
note_mangling_alias (tree decl, tree id2)
{
  if (TARGET_SUPPORTS_ALIASES)
    {
      if (!defer_mangling_aliases)
	generate_mangling_alias (decl, id2);
      else
	{
	  vec_safe_push (mangling_aliases, decl);
	  vec_safe_push (mangling_aliases, id2);
	}
    }
}

/* Emit all mangling aliases that were deferred up to this point.  */

void
generate_mangling_aliases ()
{
  while (!vec_safe_is_empty (mangling_aliases))
    {
      tree id2 = mangling_aliases->pop();
      tree decl = mangling_aliases->pop();
      generate_mangling_alias (decl, id2);
    }
  defer_mangling_aliases = false;
}

/* Record a mangling of DECL, whose DECL_ASSEMBLER_NAME has just been
   set.  NEED_WARNING is true if we must warn about collisions.  We do
   this to spot changes in mangling that may require compatibility
   aliases.  */

void
record_mangling (tree decl, bool need_warning)
{
  if (!mangled_decls)
    mangled_decls = hash_table<mangled_decl_hash>::create_ggc (499);

  gcc_checking_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
  tree id = DECL_ASSEMBLER_NAME_RAW (decl);
  tree *slot
    = mangled_decls->find_slot_with_hash (id, IDENTIFIER_HASH_VALUE (id),
					  INSERT);

  /* If this is already an alias, remove the alias, because the real
     decl takes precedence.  */
  if (*slot && DECL_ARTIFICIAL (*slot) && DECL_IGNORED_P (*slot))
    if (symtab_node *n = symtab_node::get (*slot))
      if (n->cpp_implicit_alias)
	{
	  n->remove ();
	  *slot = NULL_TREE;
	}

  if (!*slot)
    *slot = decl;
  else if (need_warning)
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"mangling of %q#D as %qE conflicts with a previous mangle",
		decl, id);
      inform (DECL_SOURCE_LOCATION (*slot),
	      "previous mangling %q#D", *slot);
      inform (DECL_SOURCE_LOCATION (decl),
	      "a later %<-fabi-version=%> (or =0)"
	      " avoids this error with a change in mangling");
      *slot = decl;
    }
}

/* The mangled name of DECL is being forcibly changed to NAME.  Remove
   any existing knowledge of DECL's mangled name meaning DECL.  */

void
overwrite_mangling (tree decl, tree name)
{
  if (tree id = DECL_ASSEMBLER_NAME_RAW (decl))
    if ((TREE_CODE (decl) == VAR_DECL
	 || TREE_CODE (decl) == FUNCTION_DECL)
	&& mangled_decls)
      if (tree *slot
	  = mangled_decls->find_slot_with_hash (id, IDENTIFIER_HASH_VALUE (id),
						NO_INSERT))
	if (*slot == decl)
	  {
	    mangled_decls->clear_slot (slot);

	    /* If this is an alias, remove it from the symbol table.  */
	    if (DECL_ARTIFICIAL (decl) && DECL_IGNORED_P (decl))
	      if (symtab_node *n = symtab_node::get (decl))
		if (n->cpp_implicit_alias)
		  n->remove ();
	  }

  DECL_ASSEMBLER_NAME_RAW (decl) = name;
}

/* The entire file is now complete.  If requested, dump everything
   to a file.  */

static void
dump_tu (void)
{
  dump_flags_t flags;
  if (FILE *stream = dump_begin (raw_dump_id, &flags))
    {
      dump_node (global_namespace, flags & ~TDF_SLIM, stream);
      dump_end (raw_dump_id, stream);
    }
}

static location_t locus_at_end_of_parsing;

/* Check the deallocation functions for CODE to see if we want to warn that
   only one was defined.  */

static void
maybe_warn_sized_delete (enum tree_code code)
{
  tree sized = NULL_TREE;
  tree unsized = NULL_TREE;

  for (ovl_iterator iter (get_global_binding (ovl_op_identifier (false, code)));
       iter; ++iter)
    {
      tree fn = *iter;
      /* We're only interested in usual deallocation functions.  */
      if (!usual_deallocation_fn_p (fn))
	continue;
      if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
	unsized = fn;
      else
	sized = fn;
    }
  if (DECL_INITIAL (unsized) && !DECL_INITIAL (sized))
    warning_at (DECL_SOURCE_LOCATION (unsized), OPT_Wsized_deallocation,
		"the program should also define %qD", sized);
  else if (!DECL_INITIAL (unsized) && DECL_INITIAL (sized))
    warning_at (DECL_SOURCE_LOCATION (sized), OPT_Wsized_deallocation,
		"the program should also define %qD", unsized);
}

/* Check the global deallocation functions to see if we want to warn about
   defining unsized without sized (or vice versa).  */

static void
maybe_warn_sized_delete ()
{
  if (!flag_sized_deallocation || !warn_sized_deallocation)
    return;
  maybe_warn_sized_delete (DELETE_EXPR);
  maybe_warn_sized_delete (VEC_DELETE_EXPR);
}

/* Earlier we left PTRMEM_CST in variable initializers alone so that we could
   look them up when evaluating non-type template parameters.  Now we need to
   lower them to something the back end can understand.  */

static void
lower_var_init ()
{
  varpool_node *node;
  FOR_EACH_VARIABLE (node)
    {
      tree d = node->decl;
      if (tree init = DECL_INITIAL (d))
	DECL_INITIAL (d) = cplus_expand_constant (init);
    }
}

/* This routine is called at the end of compilation.
   Its job is to create all the code needed to initialize and
   destroy the global aggregates.  We do the destruction
   first, since that way we only need to reverse the decls once.  */

void
c_parse_final_cleanups (void)
{
  size_t i;
  tree decl;

  locus_at_end_of_parsing = input_location;
  at_eof = 1;

  /* Bad parse errors.  Just forget about it.  */
  if (! global_bindings_p () || current_class_type
      || !vec_safe_is_empty (decl_namespace_list))
    return;

  /* 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)
    {
      /* Mangle all symbols at PCH creation time.  */
      symtab_node *node;
      FOR_EACH_SYMBOL (node)
	if (! is_a <varpool_node *> (node)
	    || ! DECL_HARD_REGISTER (node->decl))
	  DECL_ASSEMBLER_NAME (node->decl);
      c_common_write_pch ();
      dump_tu ();
      /* Ensure even the callers don't try to finalize the CU.  */
      flag_syntax_only = 1;
      return;
    }

  timevar_stop (TV_PHASE_PARSING);
  timevar_start (TV_PHASE_DEFERRED);

  symtab->process_same_body_aliases ();

  /* Handle -fdump-ada-spec[-slim] */
  if (flag_dump_ada_spec || flag_dump_ada_spec_slim)
    {
      collect_source_ref (main_input_filename);
      if (!flag_dump_ada_spec_slim)
	collect_source_refs (global_namespace);

      dump_ada_specs (collect_all_refs, cpp_check);
    }

  /* FIXME - huh?  was  input_line -= 1;*/

  /* We now have to write out all the stuff we put off writing out.
     These include:

       o Template specializations that we have not yet instantiated,
	 but which are needed.
       o Initialization and destruction for non-local objects with
	 static storage duration.  (Local objects with static storage
	 duration are initialized when their scope is first entered,
	 and are cleaned up via atexit.)
       o Virtual function tables.

     All of these may cause others to be needed.  For example,
     instantiating one function may cause another to be needed, and
     generating the initializer for an object may cause templates to be
     instantiated, etc., etc.  */

  emit_support_tinfos ();

  /* Track vtables we want to emit that refer to consteval functions.  */
  auto_vec<tree> consteval_vtables;

  int retries = 0;
  unsigned ssdf_count = 0;
  for (bool reconsider = true; reconsider; retries++)
    {
      reconsider = false;

      /* If there are templates that we've put off instantiating, do
	 them now.  */
      instantiate_pending_templates (retries);
      ggc_collect ();

      if (header_module_p ())
	/* A header modules initializations are handled in its
	   importer.  */
	continue;

      /* Write out virtual tables as required.  Writing out the
	 virtual table for a template class may cause the
	 instantiation of members of that class.  If we write out
	 vtables then we remove the class from our list so we don't
	 have to look at it again.  */
      tree t;
      for (i = keyed_classes->length ();
	   keyed_classes->iterate (--i, &t);)
	if (maybe_emit_vtables (t, consteval_vtables))
	  {
	    reconsider = true;
	    keyed_classes->unordered_remove (i);
	  }
      /* The input_location may have been changed during marking of
	 vtable entries.  */
      input_location = locus_at_end_of_parsing;

      /* Write out needed type info variables.  We have to be careful
	 looping through unemitted decls, because emit_tinfo_decl may
	 cause other variables to be needed. New elements will be
	 appended, and we remove from the vector those that actually
	 get emitted.  */
      for (i = unemitted_tinfo_decls->length ();
	   unemitted_tinfo_decls->iterate (--i, &t);)
	if (emit_tinfo_decl (t))
	  {
	    reconsider = true;
	    unemitted_tinfo_decls->unordered_remove (i);
	  }

      /* The list of objects with static storage duration is built up
	 in reverse order.  We clear STATIC_AGGREGATES so that any new
	 aggregates added during the initialization of these will be
	 initialized in the correct order when we next come around the
	 loop.  */
      if (tree vars = prune_vars_needing_no_initialization (&static_aggregates))
	{
	  if (flag_openmp)
	    /* Add initializer information from VARS into
	       DYNAMIC_INITIALIZERS.  */
	    for (t = vars; t; t = TREE_CHAIN (t))
	      hash_map_safe_put<hm_ggc> (dynamic_initializers,
					 TREE_VALUE (t), TREE_PURPOSE (t));

	  /* We need to start a new initialization function each time
	     through the loop.  That's because we need to know which
	     vtables have been referenced, and TREE_SYMBOL_REFERENCED
	     isn't computed until a function is finished, and written
	     out.  That's a deficiency in the back end.  When this is
	     fixed, these initialization functions could all become
	     inline, with resulting performance improvements.  */
	  tree ssdf_body;

	  /* Make sure the back end knows about all the variables.  */
	  write_out_vars (vars);

	  /* Set the line and file, so that it is obviously not from
	     the source file.  */
	  input_location = locus_at_end_of_parsing;
	  ssdf_body = start_static_storage_duration_function (ssdf_count);

	  /* First generate code to do all the initializations.  */
	  if (vars)
	    do_static_initialization_or_destruction (vars, /*initp=*/true);

	  /* Then, generate code to do all the destructions.  Do these
	     in reverse order so that the most recently constructed
	     variable is the first destroyed.  If we're using
	     __cxa_atexit, then we don't need to do this; functions
	     were registered at initialization time to destroy the
	     local statics.  */
	  if (!flag_use_cxa_atexit && vars)
	    {
	      vars = nreverse (vars);
	      do_static_initialization_or_destruction (vars, /*initp=*/false);
	    }
	  else
	    vars = NULL_TREE;

	  /* Finish up the static storage duration function for this
	     round.  */
	  input_location = locus_at_end_of_parsing;
	  finish_static_storage_duration_function (ssdf_body);

	  /* All those initializations and finalizations might cause
	     us to need more inline functions, more template
	     instantiations, etc.  */
	  reconsider = true;
	  ssdf_count++;
	}

      /* Now do the same for thread_local variables.  */
      handle_tls_init ();

      /* Go through the set of inline functions whose bodies have not
	 been emitted yet.  If out-of-line copies of these functions
	 are required, emit them.  */
      FOR_EACH_VEC_SAFE_ELT (deferred_fns, i, decl)
	{
	  /* Does it need synthesizing?  */
	  if (DECL_DEFAULTED_FN (decl) && ! DECL_INITIAL (decl)
	      && (! DECL_REALLY_EXTERN (decl) || possibly_inlined_p (decl)))
	    {
	      /* Even though we're already at the top-level, we push
		 there again.  That way, when we pop back a few lines
		 hence, all of our state is restored.  Otherwise,
		 finish_function doesn't clean things up, and we end
		 up with CURRENT_FUNCTION_DECL set.  */
	      push_to_top_level ();
	      /* The decl's location will mark where it was first
		 needed.  Save that so synthesize method can indicate
		 where it was needed from, in case of error  */
	      input_location = DECL_SOURCE_LOCATION (decl);
	      synthesize_method (decl);
	      pop_from_top_level ();
	      reconsider = true;
	    }

	  if (!DECL_INITIAL (decl) && decl_tls_wrapper_p (decl))
	    generate_tls_wrapper (decl);

	  if (!DECL_SAVED_TREE (decl))
	    continue;

	  cgraph_node *node = cgraph_node::get_create (decl);

	  /* We lie to the back end, pretending that some functions
	     are not defined when they really are.  This keeps these
	     functions from being put out unnecessarily.  But, we must
	     stop lying when the functions are referenced, or if they
	     are not comdat since they need to be put out now.  If
	     DECL_INTERFACE_KNOWN, then we have already set
	     DECL_EXTERNAL appropriately, so there's no need to check
	     again, and we do not want to clear DECL_EXTERNAL if a
	     previous call to import_export_decl set it.

	     This is done in a separate for cycle, because if some
	     deferred function is contained in another deferred
	     function later in deferred_fns varray,
	     rest_of_compilation would skip this function and we
	     really cannot expand the same function twice.  */
	  import_export_decl (decl);
	  if (DECL_NOT_REALLY_EXTERN (decl)
	      && DECL_INITIAL (decl)
	      && decl_needed_p (decl))
	    {
	      if (node->cpp_implicit_alias)
		node = node->get_alias_target ();

	      node->call_for_symbol_thunks_and_aliases (clear_decl_external,
						      NULL, true);
	      /* If we mark !DECL_EXTERNAL one of the symbols in some comdat
		 group, we need to mark all symbols in the same comdat group
		 that way.  */
	      if (node->same_comdat_group)
		for (cgraph_node *next
		       = dyn_cast<cgraph_node *> (node->same_comdat_group);
		     next != node;
		     next = dyn_cast<cgraph_node *> (next->same_comdat_group))
		  next->call_for_symbol_thunks_and_aliases (clear_decl_external,
							  NULL, true);
	    }

	  /* If we're going to need to write this function out, and
	     there's already a body for it, create RTL for it now.
	     (There might be no body if this is a method we haven't
	     gotten around to synthesizing yet.)  */
	  if (!DECL_EXTERNAL (decl)
	      && decl_needed_p (decl)
	      && !TREE_ASM_WRITTEN (decl)
	      && !node->definition)
	    {
	      /* We will output the function; no longer consider it in this
		 loop.  */
	      DECL_DEFER_OUTPUT (decl) = 0;
	      /* Generate RTL for this function now that we know we
		 need it.  */
	      expand_or_defer_fn (decl);
	      reconsider = true;
	    }
	}

      if (wrapup_namespace_globals ())
	reconsider = true;

      /* Static data members are just like namespace-scope globals.  */
      FOR_EACH_VEC_SAFE_ELT (pending_statics, i, decl)
	{
	  if (var_finalized_p (decl) || DECL_REALLY_EXTERN (decl)
	      /* Don't write it out if we haven't seen a definition.  */
	      || DECL_IN_AGGR_P (decl))
	    continue;
	  import_export_decl (decl);
	  /* If this static data member is needed, provide it to the
	     back end.  */
	  if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl))
	    DECL_EXTERNAL (decl) = 0;
	}

      if (vec_safe_length (pending_statics) != 0
	  && wrapup_global_declarations (pending_statics->address (),
					 pending_statics->length ()))
	reconsider = true;
    }

  finish_module_processing (parse_in);

  lower_var_init ();

  generate_mangling_aliases ();

  /* All used inline functions must have a definition at this point.  */
  FOR_EACH_VEC_SAFE_ELT (deferred_fns, i, decl)
    {
      if (/* Check online inline functions that were actually used.  */
	  DECL_ODR_USED (decl) && DECL_DECLARED_INLINE_P (decl)
	  /* If the definition actually was available here, then the
	     fact that the function was not defined merely represents
	     that for some reason (use of a template repository,
	     #pragma interface, etc.) we decided not to emit the
	     definition here.  */
	  && !DECL_INITIAL (decl)
	  /* A defaulted fn in a header module can be synthesized on
	     demand later.  (In non-header modules we should have
	     synthesized it above.)  */
	  && !(DECL_DEFAULTED_FN (decl) && header_module_p ())
	  /* Don't complain if the template was defined.  */
	  && !(DECL_TEMPLATE_INSTANTIATION (decl)
	       && DECL_INITIAL (DECL_TEMPLATE_RESULT
				(template_for_substitution (decl))))
	  && warning_at (DECL_SOURCE_LOCATION (decl), 0,
			 "inline function %qD used but never defined", decl))
	/* Avoid a duplicate warning from check_global_declaration.  */
	suppress_warning (decl, OPT_Wunused);
    }

  /* So must decls that use a type with no linkage.  */
  FOR_EACH_VEC_SAFE_ELT (no_linkage_decls, i, decl)
    no_linkage_error (decl);

  maybe_warn_sized_delete ();

  /* Then, do the Objective-C stuff.  This is where all the
     Objective-C module stuff gets generated (symtab,
     class/protocol/selector lists etc).  This must be done after C++
     templates, destructors etc. so that selectors used in C++
     templates are properly allocated.  */
  if (c_dialect_objc ())
    objc_write_global_declarations ();

  /* We give C linkage to static constructors and destructors.  */
  push_lang_context (lang_name_c);

  /* Generate initialization and destruction functions for all
     priorities for which they are required.  */
  if (priority_info_map)
    splay_tree_foreach (priority_info_map,
			generate_ctor_and_dtor_functions_for_priority,
			/*data=*/&locus_at_end_of_parsing);
  else if ((c_dialect_objc () && objc_static_init_needed_p ())
	   || module_initializer_kind ())
    generate_ctor_or_dtor_function (/*constructor_p=*/true,
				    DEFAULT_INIT_PRIORITY,
				    &locus_at_end_of_parsing);

  /* We're done with the splay-tree now.  */
  if (priority_info_map)
    splay_tree_delete (priority_info_map);

  fini_modules ();

  /* Generate any missing aliases.  */
  maybe_apply_pending_pragma_weaks ();

  /* We're done with static constructors, so we can go back to "C++"
     linkage now.  */
  pop_lang_context ();

  if (flag_vtable_verify)
    {
      vtv_recover_class_info ();
      vtv_compute_class_hierarchy_transitive_closure ();
      vtv_build_vtable_verify_fndecl ();
    }

  perform_deferred_noexcept_checks ();

  fini_constexpr ();
  cp_tree_c_finish_parsing ();
  clear_consteval_vfns (consteval_vtables);

  /* The entire file is now complete.  If requested, dump everything
     to a file.  */
  dump_tu ();

  if (flag_detailed_statistics)
    {
      dump_tree_statistics ();
      dump_time_statistics ();
    }

  timevar_stop (TV_PHASE_DEFERRED);
  timevar_start (TV_PHASE_PARSING);

  /* Indicate that we're done with front end processing.  */
  at_eof = 2;
}

/* Perform any post compilation-proper cleanups for the C++ front-end.
   This should really go away.  No front-end should need to do
   anything past the compilation process.  */

void
cxx_post_compilation_parsing_cleanups (void)
{
  timevar_start (TV_PHASE_LATE_PARSING_CLEANUPS);

  if (flag_vtable_verify)
    {
      /* Generate the special constructor initialization function that
         calls __VLTRegisterPairs, and give it a very high
         initialization priority.  This must be done after
         finalize_compilation_unit so that we have accurate
         information about which vtable will actually be emitted.  */
      vtv_generate_init_routine ();
    }

  input_location = locus_at_end_of_parsing;

  if (flag_checking)
    validate_conversion_obstack ();

  timevar_stop (TV_PHASE_LATE_PARSING_CLEANUPS);
}

/* FN is an OFFSET_REF, DOTSTAR_EXPR or MEMBER_REF indicating the
   function to call in parse-tree form; it has not yet been
   semantically analyzed.  ARGS are the arguments to the function.
   They have already been semantically analyzed.  This may change
   ARGS.  */

tree
build_offset_ref_call_from_tree (tree fn, vec<tree, va_gc> **args,
				 tsubst_flags_t complain)
{
  tree orig_fn;
  vec<tree, va_gc> *orig_args = NULL;
  tree expr;
  tree object;

  orig_fn = fn;
  object = TREE_OPERAND (fn, 0);

  if (processing_template_decl)
    {
      gcc_assert (TREE_CODE (fn) == DOTSTAR_EXPR
		  || TREE_CODE (fn) == MEMBER_REF);
      if (type_dependent_expression_p (fn)
	  || any_type_dependent_arguments_p (*args))
	return build_min_nt_call_vec (fn, *args);

      orig_args = make_tree_vector_copy (*args);

      /* Transform the arguments and add the implicit "this"
	 parameter.  That must be done before the FN is transformed
	 because we depend on the form of FN.  */
      make_args_non_dependent (*args);
      object = build_non_dependent_expr (object);
      if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
	{
	  if (TREE_CODE (fn) == DOTSTAR_EXPR)
	    object = cp_build_addr_expr (object, complain);
	  vec_safe_insert (*args, 0, object);
	}
      /* Now that the arguments are done, transform FN.  */
      fn = build_non_dependent_expr (fn);
    }

  /* A qualified name corresponding to a bound pointer-to-member is
     represented as an OFFSET_REF:

	struct B { void g(); };
	void (B::*p)();
	void B::g() { (this->*p)(); }  */
  if (TREE_CODE (fn) == OFFSET_REF)
    {
      tree object_addr = cp_build_addr_expr (object, complain);
      fn = TREE_OPERAND (fn, 1);
      fn = get_member_function_from_ptrfunc (&object_addr, fn,
					     complain);
      vec_safe_insert (*args, 0, object_addr);
    }

  if (CLASS_TYPE_P (TREE_TYPE (fn)))
    expr = build_op_call (fn, args, complain);
  else
    expr = cp_build_function_call_vec (fn, args, complain);
  if (processing_template_decl && expr != error_mark_node)
    expr = build_min_non_dep_call_vec (expr, orig_fn, orig_args);

  if (orig_args != NULL)
    release_tree_vector (orig_args);

  return expr;
}


void
check_default_args (tree x)
{
  tree arg = TYPE_ARG_TYPES (TREE_TYPE (x));
  bool saw_def = false;
  bool noted_first_def = false;
  int idx_of_first_default_arg = 0;
  location_t loc_of_first_default_arg = UNKNOWN_LOCATION;
  int i = 0 - (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE);
  tree fndecl = STRIP_TEMPLATE (x);
  auto_diagnostic_group d;
  for (; arg && arg != void_list_node; arg = TREE_CHAIN (arg), ++i)
    {
      if (TREE_PURPOSE (arg))
	{
	  if (!saw_def)
	    {
	      saw_def = true;
	      idx_of_first_default_arg = i;
	      location_t loc = get_fndecl_argument_location (fndecl, i);
	      if (loc != DECL_SOURCE_LOCATION (x))
		loc_of_first_default_arg = loc;
	    }
	}
      else if (saw_def && !PACK_EXPANSION_P (TREE_VALUE (arg)))
	{
	  error_at (get_fndecl_argument_location (fndecl, i),
		    "default argument missing for parameter %P of %q#D", i, x);
	  if (loc_of_first_default_arg != UNKNOWN_LOCATION
	      && !noted_first_def)
	    {
	      inform (loc_of_first_default_arg,
		      "...following parameter %P which has a default argument",
		      idx_of_first_default_arg);
	      noted_first_def = true;
	    }
	  TREE_PURPOSE (arg) = error_mark_node;
	}
    }
}

/* Return true if function DECL can be inlined.  This is used to force
   instantiation of methods that might be interesting for inlining.  */
bool
possibly_inlined_p (tree decl)
{
  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
  if (DECL_UNINLINABLE (decl))
    return false;
  if (!optimize)
    return DECL_DECLARED_INLINE_P (decl);
  /* When optimizing, we might inline everything when flatten
     attribute or heuristics inlining for size or autoinlining
     is used.  */
  return true;
}

/* Normally, we can wait until instantiation-time to synthesize DECL.
   However, if DECL is a static data member initialized with a constant
   or a constexpr function, we need it right now because a reference to
   such a data member or a call to such function is not value-dependent.
   For a function that uses auto in the return type, we need to instantiate
   it to find out its type.  For OpenMP user defined reductions, we need
   them instantiated for reduction clauses which inline them by hand
   directly.  */

void
maybe_instantiate_decl (tree decl)
{
  if (DECL_LANG_SPECIFIC (decl)
      && DECL_TEMPLATE_INFO (decl)
      && (decl_maybe_constant_var_p (decl)
	  || (TREE_CODE (decl) == FUNCTION_DECL
	      && DECL_OMP_DECLARE_REDUCTION_P (decl))
	  || undeduced_auto_decl (decl))
      && !DECL_DECLARED_CONCEPT_P (decl)
      && !uses_template_parms (DECL_TI_ARGS (decl)))
    {
      /* Instantiating a function will result in garbage collection.  We
	 must treat this situation as if we were within the body of a
	 function so as to avoid collecting live data only referenced from
	 the stack (such as overload resolution candidates).  */
      ++function_depth;
      instantiate_decl (decl, /*defer_ok=*/false,
			/*expl_inst_class_mem_p=*/false);
      --function_depth;
    }
}

/* Error if the DECL is unavailable (unless this is currently suppressed).
   Maybe warn if DECL is deprecated, subject to COMPLAIN.  Returns true if
   an error or warning was emitted.  */

bool
cp_handle_deprecated_or_unavailable (tree decl, tsubst_flags_t complain)
{
  if (!decl)
    return false;

  if ((complain & tf_error)
      && deprecated_state != UNAVAILABLE_DEPRECATED_SUPPRESS)
    {
      if (TREE_UNAVAILABLE (decl))
	{
	  error_unavailable_use (decl, NULL_TREE);
	  return true;
	}
      else
	{
	  /* Perhaps this is an unavailable typedef.  */
	  if (TYPE_P (decl)
	      && TYPE_NAME (decl)
	      && TREE_UNAVAILABLE (TYPE_NAME (decl)))
	    {
	      decl = TYPE_NAME (decl);
	      /* Don't error within members of a unavailable type.  */
	      if (TYPE_P (decl)
		  && currently_open_class (decl))
		return false;

	      error_unavailable_use (decl, NULL_TREE);
	      return true;
	    }
	}
      /* Carry on to consider deprecatedness.  */
    }

  if (!(complain & tf_warning)
      || deprecated_state == DEPRECATED_SUPPRESS
      || deprecated_state == UNAVAILABLE_DEPRECATED_SUPPRESS)
    return false;

  if (!TREE_DEPRECATED (decl))
    {
      /* Perhaps this is a deprecated typedef.  */
      if (TYPE_P (decl) && TYPE_NAME (decl))
	decl = TYPE_NAME (decl);

      if (!TREE_DEPRECATED (decl))
	return false;
    }

  /* Don't warn within members of a deprecated type.  */
  if (TYPE_P (decl)
      && currently_open_class (decl))
    return false;

  bool warned = false;
  if (cxx_dialect >= cxx11
      && DECL_P (decl)
      && DECL_ARTIFICIAL (decl)
      && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
      && copy_fn_p (decl))
    {
      /* Don't warn if the flag was disabled around the class definition
	 (c++/94492).  */
      if (warning_enabled_at (DECL_SOURCE_LOCATION (decl),
			      OPT_Wdeprecated_copy))
	{
	  auto_diagnostic_group d;
	  tree ctx = DECL_CONTEXT (decl);
	  tree other = classtype_has_depr_implicit_copy (ctx);
	  int opt = (DECL_DESTRUCTOR_P (other)
		     ? OPT_Wdeprecated_copy_dtor
		     : OPT_Wdeprecated_copy);
	  warned = warning (opt, "implicitly-declared %qD is deprecated",
			    decl);
	  if (warned)
	    inform (DECL_SOURCE_LOCATION (other),
		    "because %qT has user-provided %qD",
		    ctx, other);
	}
    }
  else
    warned = warn_deprecated_use (decl, NULL_TREE);

  return warned;
}

/* Like above, but takes into account outer scopes.  */

void
cp_warn_deprecated_use_scopes (tree scope)
{
  while (scope
	 && scope != error_mark_node
	 && scope != global_namespace)
    {
      if ((TREE_CODE (scope) == NAMESPACE_DECL || OVERLOAD_TYPE_P (scope))
	  && cp_handle_deprecated_or_unavailable (scope))
	return;
      if (TYPE_P (scope))
	scope = CP_TYPE_CONTEXT (scope);
      else
	scope = CP_DECL_CONTEXT (scope);
    }
}

/* True if DECL or its enclosing scope have unbound template parameters.  */

bool
decl_dependent_p (tree decl)
{
  if (DECL_FUNCTION_SCOPE_P (decl)
      || TREE_CODE (decl) == CONST_DECL
      || TREE_CODE (decl) == USING_DECL
      || TREE_CODE (decl) == FIELD_DECL)
    decl = CP_DECL_CONTEXT (decl);
  if (tree tinfo = get_template_info (decl))
    if (any_dependent_template_arguments_p (TI_ARGS (tinfo)))
      return true;
  if (LAMBDA_FUNCTION_P (decl)
      && dependent_type_p (DECL_CONTEXT (decl)))
    return true;
  return false;
}

/* Mark DECL (either a _DECL or a BASELINK) as "used" in the program.
   If DECL is a specialization or implicitly declared class member,
   generate the actual definition.  Return false if something goes
   wrong, true otherwise.  */

bool
mark_used (tree decl, tsubst_flags_t complain)
{
  /* If we're just testing conversions or resolving overloads, we
     don't want any permanent effects like forcing functions to be
     output or instantiating templates.  */
  if ((complain & tf_conv))
    return true;

  /* If DECL is a BASELINK for a single function, then treat it just
     like the DECL for the function.  Otherwise, if the BASELINK is
     for an overloaded function, we don't know which function was
     actually used until after overload resolution.  */
  if (BASELINK_P (decl))
    {
      decl = BASELINK_FUNCTIONS (decl);
      if (really_overloaded_fn (decl))
	return true;
      decl = OVL_FIRST (decl);
    }

  if (!DECL_P (decl))
    return true;

  /* Set TREE_USED for the benefit of -Wunused.  */
  TREE_USED (decl) = true;

  /* And for structured bindings also the underlying decl.  */
  if (DECL_DECOMPOSITION_P (decl) && DECL_DECOMP_BASE (decl))
    TREE_USED (DECL_DECOMP_BASE (decl)) = true;

  if (TREE_CODE (decl) == TEMPLATE_DECL)
    return true;

  if (DECL_CLONED_FUNCTION_P (decl))
    TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1;

  /* Mark enumeration types as used.  */
  if (TREE_CODE (decl) == CONST_DECL)
    used_types_insert (DECL_CONTEXT (decl));

  if (TREE_CODE (decl) == FUNCTION_DECL
      && !maybe_instantiate_noexcept (decl, complain))
    return false;

  if (TREE_CODE (decl) == FUNCTION_DECL
      && DECL_DELETED_FN (decl))
    {
      if (DECL_ARTIFICIAL (decl)
	  && DECL_CONV_FN_P (decl)
	  && LAMBDA_TYPE_P (DECL_CONTEXT (decl)))
	/* We mark a lambda conversion op as deleted if we can't
	   generate it properly; see maybe_add_lambda_conv_op.  */
	sorry ("converting lambda that uses %<...%> to function pointer");
      else if (complain & tf_error)
	{
	  error ("use of deleted function %qD", decl);
	  if (!maybe_explain_implicit_delete (decl))
	    inform (DECL_SOURCE_LOCATION (decl), "declared here");
	}
      return false;
    }

  if (VAR_OR_FUNCTION_DECL_P (decl) && DECL_LOCAL_DECL_P (decl))
    {
      if (!DECL_LANG_SPECIFIC (decl))
	/* An unresolved dependent local extern.  */
	return true;

      DECL_ODR_USED (decl) = 1;
      auto alias = DECL_LOCAL_DECL_ALIAS (decl);
      if (!alias || alias == error_mark_node)
	return true;

      /* Process the underlying decl.  */
      decl = alias;
      TREE_USED (decl) = true;
    }

  cp_handle_deprecated_or_unavailable (decl, complain);

  /* We can only check DECL_ODR_USED on variables or functions with
     DECL_LANG_SPECIFIC set, and these are also the only decls that we
     might need special handling for.  */
  if (!VAR_OR_FUNCTION_DECL_P (decl)
      || DECL_LANG_SPECIFIC (decl) == NULL
      || DECL_THUNK_P (decl))
    {
      if (!decl_dependent_p (decl)
	  && !require_deduced_type (decl, complain))
	return false;
      return true;
    }

  /* We only want to do this processing once.  We don't need to keep trying
     to instantiate inline templates, because unit-at-a-time will make sure
     we get them compiled before functions that want to inline them.  */
  if (DECL_ODR_USED (decl))
    return true;

  if (flag_concepts && TREE_CODE (decl) == FUNCTION_DECL
      && !constraints_satisfied_p (decl))
    {
      if (complain & tf_error)
	{
	  auto_diagnostic_group d;
	  error ("use of function %qD with unsatisfied constraints",
		 decl);
	  location_t loc = DECL_SOURCE_LOCATION (decl);
	  inform (loc, "declared here");
	  diagnose_constraints (loc, decl, NULL_TREE);
	}
      return false;
    }

  /* Normally, we can wait until instantiation-time to synthesize DECL.
     However, if DECL is a static data member initialized with a constant
     or a constexpr function, we need it right now because a reference to
     such a data member or a call to such function is not value-dependent.
     For a function that uses auto in the return type, we need to instantiate
     it to find out its type.  For OpenMP user defined reductions, we need
     them instantiated for reduction clauses which inline them by hand
     directly.  */
  maybe_instantiate_decl (decl);

  if (processing_template_decl || in_template_function ())
    return true;

  /* Check this too in case we're within instantiate_non_dependent_expr.  */
  if (DECL_TEMPLATE_INFO (decl)
      && uses_template_parms (DECL_TI_ARGS (decl)))
    return true;

  if (!require_deduced_type (decl, complain))
    return false;

  if (builtin_pack_fn_p (decl))
    {
      error ("use of built-in parameter pack %qD outside of a template",
	     DECL_NAME (decl));
      return false;
    }

  /* If we don't need a value, then we don't need to synthesize DECL.  */
  if (cp_unevaluated_operand || in_discarded_stmt)
    return true;

  DECL_ODR_USED (decl) = 1;
  if (DECL_CLONED_FUNCTION_P (decl))
    DECL_ODR_USED (DECL_CLONED_FUNCTION (decl)) = 1;

  /* DR 757: A type without linkage shall not be used as the type of a
     variable or function with linkage, unless
   o the variable or function has extern "C" linkage (7.5 [dcl.link]), or
   o the variable or function is not used (3.2 [basic.def.odr]) or is
   defined in the same translation unit.  */
  if (cxx_dialect > cxx98
      && decl_linkage (decl) != lk_none
      && !DECL_EXTERN_C_P (decl)
      && !DECL_ARTIFICIAL (decl)
      && !decl_defined_p (decl)
      && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false))
    vec_safe_push (no_linkage_decls, decl);

  if (TREE_CODE (decl) == FUNCTION_DECL
      && DECL_DECLARED_INLINE_P (decl)
      && !DECL_INITIAL (decl)
      && !DECL_ARTIFICIAL (decl)
      && !DECL_PURE_VIRTUAL_P (decl))
    /* Remember it, so we can check it was defined.  */
    note_vague_linkage_fn (decl);

  /* Is it a synthesized method that needs to be synthesized?  */
  if (TREE_CODE (decl) == FUNCTION_DECL
      && DECL_DEFAULTED_FN (decl)
      /* A function defaulted outside the class is synthesized either by
	 cp_finish_decl or instantiate_decl.  */
      && !DECL_DEFAULTED_OUTSIDE_CLASS_P (decl)
      && ! DECL_INITIAL (decl))
    {
      /* Defer virtual destructors so that thunks get the right
	 linkage.  */
      if (DECL_VIRTUAL_P (decl) && !at_eof)
	{
	  note_vague_linkage_fn (decl);
	  return true;
	}

      /* Remember the current location for a function we will end up
	 synthesizing.  Then we can inform the user where it was
	 required in the case of error.  */
      if (decl_remember_implicit_trigger_p (decl))
	DECL_SOURCE_LOCATION (decl) = input_location;

      /* Synthesizing an implicitly defined member function will result in
	 garbage collection.  We must treat this situation as if we were
	 within the body of a function so as to avoid collecting live data
	 on the stack (such as overload resolution candidates).

         We could just let c_parse_final_cleanups handle synthesizing
         this function by adding it to deferred_fns, but doing
         it at the use site produces better error messages.  */
      ++function_depth;
      synthesize_method (decl);
      --function_depth;
      /* If this is a synthesized method we don't need to
	 do the instantiation test below.  */
    }
  else if (VAR_OR_FUNCTION_DECL_P (decl)
	   && DECL_TEMPLATE_INFO (decl)
           && !DECL_DECLARED_CONCEPT_P (decl)
	   && (!DECL_EXPLICIT_INSTANTIATION (decl)
	       || always_instantiate_p (decl)))
    /* If this is a function or variable that is an instance of some
       template, we now know that we will need to actually do the
       instantiation. We check that DECL is not an explicit
       instantiation because that is not checked in instantiate_decl.

       We put off instantiating functions in order to improve compile
       times.  Maintaining a stack of active functions is expensive,
       and the inliner knows to instantiate any functions it might
       need.  Therefore, we always try to defer instantiation.  */
    {
      ++function_depth;
      instantiate_decl (decl, /*defer_ok=*/true,
			/*expl_inst_class_mem_p=*/false);
      --function_depth;
    }

  return true;
}

bool
mark_used (tree decl)
{
  return mark_used (decl, tf_warning_or_error);
}

tree
vtv_start_verification_constructor_init_function (void)
{
  return start_objects ('I', MAX_RESERVED_INIT_PRIORITY - 1);
}

tree
vtv_finish_verification_constructor_init_function (tree function_body)
{
  tree fn;

  finish_compound_stmt (function_body);
  fn = finish_function (/*inline_p=*/false);
  DECL_STATIC_CONSTRUCTOR (fn) = 1;
  decl_init_priority_insert (fn, MAX_RESERVED_INIT_PRIORITY - 1);

  return fn;
}

#include "gt-cp-decl2.h"
