FreeBSD/contrib/gcc/cp/decl.c
/* After processing and defining all the values of an enumeration type,
   install their decls in the enumeration type and finish it off.
   ENUMTYPE is the type object and VALUES a list of name-value pairs.  */
After processing and defining all the values of an enumeration type,
install their decls in the enumeration type and finish it off.
ENUMTYPE is the type object and VALUES a list of name-value pairs.
After processing and defining all the values of an enumeration type install their decls in the enumeration type and finish it off . ENUMTYPE is the type object and VALUES a list of name - value pairs .
void
finish_enum (tree enumtype)
{
  tree values;
  tree decl;
  tree value;
  tree minnode;
  tree maxnode;
  tree t;
  bool unsignedp;
  bool use_short_enum;
  int lowprec;
  int highprec;
  int precision;
  integer_type_kind itk;
  tree underlying_type = NULL_TREE;
  TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
  if (processing_template_decl)
    {
      for (values = TYPE_VALUES (enumtype);
	   values;
	   values = TREE_CHAIN (values))
	TREE_TYPE (TREE_VALUE (values)) = enumtype;
      if (at_function_scope_p ())
	add_stmt (build_min (TAG_DEFN, enumtype));
      return;
    }
  if (TYPE_VALUES (enumtype))
    {
      minnode = maxnode = NULL_TREE;
      for (values = TYPE_VALUES (enumtype);
	   values;
	   values = TREE_CHAIN (values))
	{
	  decl = TREE_VALUE (values);
	  TREE_TYPE (decl) = enumtype;
	  value = DECL_INITIAL (decl);
	  if (value == error_mark_node)
	    value = integer_zero_node;
	  if (!minnode)
	    minnode = maxnode = value;
	  else if (tree_int_cst_lt (maxnode, value))
	    maxnode = value;
	  else if (tree_int_cst_lt (value, minnode))
	    minnode = value;
	}
    }
  else
    minnode = maxnode = integer_zero_node;
  unsignedp = tree_int_cst_sgn (minnode) >= 0;
  lowprec = min_precision (minnode, unsignedp);
  highprec = min_precision (maxnode, unsignedp);
  precision = MAX (lowprec, highprec);
  use_short_enum = flag_short_enums
    || lookup_attribute ("packed", TYPE_ATTRIBUTES (enumtype));
  for (itk = (use_short_enum ? itk_char : itk_int);
       itk != itk_none;
       itk++)
    {
      underlying_type = integer_types[itk];
      if (TYPE_PRECISION (underlying_type) >= precision
	  && TYPE_UNSIGNED (underlying_type) == unsignedp)
	break;
    }
  if (itk == itk_none)
    {
      error ("no integral type can represent all of the enumerator values "
	     "for %qT", enumtype);
      precision = TYPE_PRECISION (long_long_integer_type_node);
      underlying_type = integer_types[itk_unsigned_long_long];
    }
  TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type);
  set_min_and_max_values_for_integral_type (enumtype, precision, unsignedp);
  TYPE_SIZE (enumtype) = TYPE_SIZE (underlying_type);
  TYPE_SIZE_UNIT (enumtype) = TYPE_SIZE_UNIT (underlying_type);
  TYPE_MODE (enumtype) = TYPE_MODE (underlying_type);
  TYPE_ALIGN (enumtype) = TYPE_ALIGN (underlying_type);
  TYPE_USER_ALIGN (enumtype) = TYPE_USER_ALIGN (underlying_type);
  TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (underlying_type);
  for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
    {
      location_t saved_location;
      decl = TREE_VALUE (values);
      saved_location = input_location;
      input_location = DECL_SOURCE_LOCATION (decl);
      value = perform_implicit_conversion (underlying_type,
					   DECL_INITIAL (decl));
      input_location = saved_location;
      value = copy_node (value);
      TREE_TYPE (value) = enumtype;
      DECL_INITIAL (decl) = value;
      TREE_VALUE (values) = value;
    }
  for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t))
    {
      TYPE_VALUES (t) = TYPE_VALUES (enumtype);
      TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (enumtype);
      TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (enumtype);
      TYPE_SIZE (t) = TYPE_SIZE (enumtype);
      TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (enumtype);
      TYPE_MODE (t) = TYPE_MODE (enumtype);
      TYPE_PRECISION (t) = TYPE_PRECISION (enumtype);
      TYPE_ALIGN (t) = TYPE_ALIGN (enumtype);
      TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (enumtype);
      TYPE_UNSIGNED (t) = TYPE_UNSIGNED (enumtype);
    }
  rest_of_type_compilation (enumtype, namespace_bindings_p ());
}
void finish_enum ( tree enumtype ) { tree values ; tree decl ; tree value ; tree minnode ; tree maxnode ; tree t ; bool unsignedp ; bool use_short_enum ; int lowprec ; int highprec ; int precision ; integer_type_kind itk ; tree underlying_type = NULL_TREE ; TYPE_VALUES ( enumtype ) = nreverse ( TYPE_VALUES ( enumtype ) ) ; if ( processing_template_decl ) { for ( values = TYPE_VALUES ( enumtype ) ; values ; values = TREE_CHAIN ( values ) ) TREE_TYPE ( TREE_VALUE ( values ) ) = enumtype ; if ( at_function_scope_p ( ) ) add_stmt ( build_min ( TAG_DEFN , enumtype ) ) ; return ; } if ( TYPE_VALUES ( enumtype ) ) { minnode = maxnode = NULL_TREE ; for ( values = TYPE_VALUES ( enumtype ) ; values ; values = TREE_CHAIN ( values ) ) { decl = TREE_VALUE ( values ) ; TREE_TYPE ( decl ) = enumtype ; value = DECL_INITIAL ( decl ) ; if ( value == error_mark_node ) value = integer_zero_node ; if ( ! minnode ) minnode = maxnode = value ; else if ( tree_int_cst_lt ( maxnode , value ) ) maxnode = value ; else if ( tree_int_cst_lt ( value , minnode ) ) minnode = value ; } } else minnode = maxnode = integer_zero_node ; unsignedp = tree_int_cst_sgn ( minnode ) >= 0 ; lowprec = min_precision ( minnode , unsignedp ) ; highprec = min_precision ( maxnode , unsignedp ) ; precision = MAX ( lowprec , highprec ) ; use_short_enum = flag_short_enums || lookup_attribute ( " " , TYPE_ATTRIBUTES ( enumtype ) ) ; for ( itk = ( use_short_enum ? itk_char : itk_int ) ; itk != itk_none ; itk ++ ) { underlying_type = integer_types [ itk ] ; if ( TYPE_PRECISION ( underlying_type ) >= precision && TYPE_UNSIGNED ( underlying_type ) == unsignedp ) break ; } if ( itk == itk_none ) { error ( " " " " , enumtype ) ; precision = TYPE_PRECISION ( long_long_integer_type_node ) ; underlying_type = integer_types [ itk_unsigned_long_long ] ; } TYPE_PRECISION ( enumtype ) = TYPE_PRECISION ( underlying_type ) ; set_min_and_max_values_for_integral_type ( enumtype , precision , unsignedp ) ; TYPE_SIZE ( enumtype ) = TYPE_SIZE ( underlying_type ) ; TYPE_SIZE_UNIT ( enumtype ) = TYPE_SIZE_UNIT ( underlying_type ) ; TYPE_MODE ( enumtype ) = TYPE_MODE ( underlying_type ) ; TYPE_ALIGN ( enumtype ) = TYPE_ALIGN ( underlying_type ) ; TYPE_USER_ALIGN ( enumtype ) = TYPE_USER_ALIGN ( underlying_type ) ; TYPE_UNSIGNED ( enumtype ) = TYPE_UNSIGNED ( underlying_type ) ; for ( values = TYPE_VALUES ( enumtype ) ; values ; values = TREE_CHAIN ( values ) ) { location_t saved_location ; decl = TREE_VALUE ( values ) ; saved_location = input_location ; input_location = DECL_SOURCE_LOCATION ( decl ) ; value = perform_implicit_conversion ( underlying_type , DECL_INITIAL ( decl ) ) ; input_location = saved_location ; value = copy_node ( value ) ; TREE_TYPE ( value ) = enumtype ; DECL_INITIAL ( decl ) = value ; TREE_VALUE ( values ) = value ; } for ( t = TYPE_MAIN_VARIANT ( enumtype ) ; t ; t = TYPE_NEXT_VARIANT ( t ) ) { TYPE_VALUES ( t ) = TYPE_VALUES ( enumtype ) ; TYPE_MIN_VALUE ( t ) = TYPE_MIN_VALUE ( enumtype ) ; TYPE_MAX_VALUE ( t ) = TYPE_MAX_VALUE ( enumtype ) ; TYPE_SIZE ( t ) = TYPE_SIZE ( enumtype ) ; TYPE_SIZE_UNIT ( t ) = TYPE_SIZE_UNIT ( enumtype ) ; TYPE_MODE ( t ) = TYPE_MODE ( enumtype ) ; TYPE_PRECISION ( t ) = TYPE_PRECISION ( enumtype ) ; TYPE_ALIGN ( t ) = TYPE_ALIGN ( enumtype ) ; TYPE_USER_ALIGN ( t ) = TYPE_USER_ALIGN ( enumtype ) ; TYPE_UNSIGNED ( t ) = TYPE_UNSIGNED ( enumtype ) ; } rest_of_type_compilation ( enumtype , namespace_bindings_p ( ) ) ; }
After processing and defining all the values of an enumeration type,
install their decls in the enumeration type and finish it off.
After processing and defining all the values of an enumeration type install their decls in the enumeration type and finish it off .
/* We built up the VALUES in reverse order.  */ /* For an enum defined in a template, just set the type of the values;
     all further processing is postponed until the template is
     instantiated.  We need to set the type so that tsubst of a CONST_DECL
     works.  */ /* Determine the minimum and maximum values of the enumerators.  */ /* [dcl.enum]: Following the closing brace of an enum-specifier,
	     each enumerator has the type of its enumeration.  Prior to the
	     closing brace, the type of each enumerator is the type of its
	     initializing value.  */ /* Update the minimum and maximum values, if appropriate.  */ /* Figure out what the minimum and maximum values of the
	     enumerators are.  */ /* [dcl.enum]

       If the enumerator-list is empty, the underlying type is as if
       the enumeration had a single enumerator with value 0.  */ /* Compute the number of bits require to represent all values of the
     enumeration.  We must do this before the type of MINNODE and
     MAXNODE are transformed, since min_precision relies on the
     TREE_TYPE of the value it is passed.  */ /* Determine the underlying type of the enumeration.

       [dcl.enum]

       The underlying type of an enumeration is an integral type that
       can represent all the enumerator values defined in the
       enumeration.  It is implementation-defined which integral type is
       used as the underlying type for an enumeration except that the
       underlying type shall not be larger than int unless the value of
       an enumerator cannot fit in an int or unsigned int.

     We use "int" or an "unsigned int" as the underlying type, even if
     a smaller integral type would work, unless the user has
     explicitly requested that we use the smallest possible type.  The
     user can request that for all enumerations with a command line
     flag, or for just one enumeration with an attribute.  */ /* DR 377

	 IF no integral type can represent all the enumerator values, the
	 enumeration is ill-formed.  */ /* Compute the minium and maximum values for the type.

     [dcl.enum]

     For an enumeration where emin is the smallest enumerator and emax
     is the largest, the values of the enumeration are the values of the
     underlying type in the range bmin to bmax, where bmin and bmax are,
     respectively, the smallest and largest values of the smallest bit-
     field that can store emin and emax.  */ /* The middle-end currently assumes that types with TYPE_PRECISION
     narrower than their underlying type are suitably zero or sign
     extended to fill their mode.  g++ doesn't make these guarantees.
     Until the middle-end can represent such paradoxical types, we
     set the TYPE_PRECISION to the width of the underlying type.  */ /* [dcl.enum]

     The value of sizeof() applied to an enumeration type, an object
     of an enumeration type, or an enumerator, is the value of sizeof()
     applied to the underlying type.  */ /* Convert each of the enumerators to the type of the underlying
     type of the enumeration.  */ /* Do not clobber shared ints.  */ /* Fix up all variant types of this enum type.  */ /* Finish debugging output for this type.  */