FreeBSD/contrib/gcc/cp/decl.c
/* Build and install a CONST_DECL for an enumeration constant of the
   enumeration type ENUMTYPE whose NAME and VALUE (if any) are provided.
   Assignment of sequential values by default is handled here.  */
Build and install a CONST_DECL for an enumeration constant of the
enumeration type ENUMTYPE whose NAME and VALUE (if any) are provided.
Assignment of sequential values by default is handled here.
Build and install a CONST_DECL for an enumeration constant of the enumeration type ENUMTYPE whose NAME and VALUE ( if any ) are provided . Assignment of sequential values by default is handled here .
void
build_enumerator (tree name, tree value, tree enumtype)
{
  tree decl;
  tree context;
  tree type;
  if (value == error_mark_node)
    value = NULL_TREE;
  if (value)
    STRIP_TYPE_NOPS (value);
  if (! processing_template_decl)
    {
      if (value != NULL_TREE)
	{
	  value = integral_constant_value (value);
	  if (TREE_CODE (value) == INTEGER_CST)
	    {
	      value = perform_integral_promotions (value);
	      constant_expression_warning (value);
	    }
	  else
	    {
	      error ("enumerator value for %qD not integer constant", name);
	      value = NULL_TREE;
	    }
	}
      if (value == NULL_TREE)
	{
	  if (TYPE_VALUES (enumtype))
	    {
	      HOST_WIDE_INT hi;
	      unsigned HOST_WIDE_INT lo;
	      tree prev_value;
	      bool overflowed;
	      prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
	      overflowed = add_double (TREE_INT_CST_LOW (prev_value),
				       TREE_INT_CST_HIGH (prev_value),
				       1, 0, &lo, &hi);
	      value = build_int_cst_wide (TREE_TYPE (prev_value), lo, hi);
	      overflowed |= !int_fits_type_p (value, TREE_TYPE (prev_value));
	      if (overflowed)
		{
		  error ("overflow in enumeration values at %qD", name);
		  value = error_mark_node;
		}
	    }
	  else
	    value = integer_zero_node;
	}
      STRIP_TYPE_NOPS (value);
    }
  context = current_scope ();
  type = value ? TREE_TYPE (value) : NULL_TREE;
  if (context && context == current_class_type)
    decl = build_lang_decl (CONST_DECL, name, type);
  else
    decl = build_decl (CONST_DECL, name, type);
  DECL_CONTEXT (decl) = FROB_CONTEXT (context);
  TREE_CONSTANT (decl) = 1;
  TREE_INVARIANT (decl) = 1;
  TREE_READONLY (decl) = 1;
  DECL_INITIAL (decl) = value;
  if (context && context == current_class_type)
    finish_member_declaration (decl);
  else
    pushdecl (decl);
  TYPE_VALUES (enumtype) = tree_cons (name, decl, TYPE_VALUES (enumtype));
}
void build_enumerator ( tree name , tree value , tree enumtype ) { tree decl ; tree context ; tree type ; if ( value == error_mark_node ) value = NULL_TREE ; if ( value ) STRIP_TYPE_NOPS ( value ) ; if ( ! processing_template_decl ) { if ( value != NULL_TREE ) { value = integral_constant_value ( value ) ; if ( TREE_CODE ( value ) == INTEGER_CST ) { value = perform_integral_promotions ( value ) ; constant_expression_warning ( value ) ; } else { error ( " " , name ) ; value = NULL_TREE ; } } if ( value == NULL_TREE ) { if ( TYPE_VALUES ( enumtype ) ) { HOST_WIDE_INT hi ; unsigned HOST_WIDE_INT lo ; tree prev_value ; bool overflowed ; prev_value = DECL_INITIAL ( TREE_VALUE ( TYPE_VALUES ( enumtype ) ) ) ; overflowed = add_double ( TREE_INT_CST_LOW ( prev_value ) , TREE_INT_CST_HIGH ( prev_value ) , 1 , 0 , & lo , & hi ) ; value = build_int_cst_wide ( TREE_TYPE ( prev_value ) , lo , hi ) ; overflowed |= ! int_fits_type_p ( value , TREE_TYPE ( prev_value ) ) ; if ( overflowed ) { error ( " " , name ) ; value = error_mark_node ; } } else value = integer_zero_node ; } STRIP_TYPE_NOPS ( value ) ; } context = current_scope ( ) ; type = value ? TREE_TYPE ( value ) : NULL_TREE ; if ( context && context == current_class_type ) decl = build_lang_decl ( CONST_DECL , name , type ) ; else decl = build_decl ( CONST_DECL , name , type ) ; DECL_CONTEXT ( decl ) = FROB_CONTEXT ( context ) ; TREE_CONSTANT ( decl ) = 1 ; TREE_INVARIANT ( decl ) = 1 ; TREE_READONLY ( decl ) = 1 ; DECL_INITIAL ( decl ) = value ; if ( context && context == current_class_type ) finish_member_declaration ( decl ) ; else pushdecl ( decl ) ; TYPE_VALUES ( enumtype ) = tree_cons ( name , decl , TYPE_VALUES ( enumtype ) ) ; }
Build and install a CONST_DECL for an enumeration constant of the
enumeration type ENUMTYPE whose NAME and VALUE (if any) are provided.
Build and install a CONST_DECL for an enumeration constant of the enumeration type ENUMTYPE whose NAME and VALUE ( if any ) are provided .
/* If the VALUE was erroneous, pretend it wasn't there; that will
     result in the enum being assigned the next value in sequence.  */ /* Remove no-op casts from the value.  */ /* Validate and default VALUE.  */ /* Default based on previous value.  */ /* The next value is the previous value plus one.  We can
		 safely assume that the previous value is an INTEGER_CST.
		 add_double doesn't know the type of the target expression,
		 so we must check with int_fits_type_p as well.  */ /* Remove no-op casts from the value.  */ /* C++ associates enums with global, function, or class declarations.  */ /* Build the actual enumeration constant.  Note that the enumeration
    constants have the type of their initializers until the
    enumeration is complete:

      [ dcl.enum ]

      Following the closing brace of an enum-specifier, each enumer-
      ator has the type of its enumeration.  Prior to the closing
      brace, the type of each enumerator is the type of its
      initializing value.

    In finish_enum we will reset the type.  Of course, if we're
    processing a template, there may be no value.  */ /* This enum declaration is local to the class.  We need the full
       lang_decl so that we can record DECL_CLASS_CONTEXT, for example.  */ /* It's a global enum, or it's local to a function.  (Note local to
      a function could mean local to a class method.  */ /* In something like `struct S { enum E { i = 7 }; };' we put `i'
       on the TYPE_FIELDS list for `S'.  (That's so that you can say
       things like `S::i' later.)  */ /* Add this enumeration constant to the list for this type.  */