FreeBSD/contrib/gcc/c-decl.c
/* Decode a declarator in an ordinary declaration or data definition.
   This is called as soon as the type information and variable name
   have been parsed, before parsing the initializer if any.
   Here we create the ..._DECL node, fill in its type,
   and put it on the list of decls for the current context.
   The ..._DECL node is returned as the value.

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

   Function definitions do not come here; they go to start_function
   instead.  However, external and forward declarations of functions
   do go through here.  Structure field declarations are done by
   grokfield and not through here.  */
Decode a declarator in an ordinary declaration or data definition.
This is called as soon as the type information and variable name
have been parsed, before parsing the initializer if any.
Here we create the ..._DECL node, fill in its type,
and put it on the list of decls for the current context.
The ..._DECL node is returned as the value.

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

Function definitions do not come here; they go to start_function
instead.  However, external and forward declarations of functions
do go through here.  Structure field declarations are done by
grokfield and not through here.
Decode a declarator in an ordinary declaration or data definition . This is called as soon as the type information and variable name have been parsed before parsing the initializer if any . Here we create the ... _DECL node fill in its type and put it on the list of decls for the current context . The ... _DECL node is returned as the value . for arrays where the length is not specified the type is left null to be filled in by ` finish_decl ' . Function definitions do not come here ; they go to start_function instead . However external and forward declarations of functions do go through here . Structure field declarations are done by grokfield and not through here .
tree
start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
	    bool initialized, tree attributes)
{
  tree decl;
  tree tem;
#ifdef A_LESS_INEFFICENT_WAY 
  if (lookup_attribute ("deprecated", attributes))
    deprecated_state = DEPRECATED_SUPPRESS;
  else if (lookup_attribute ("unavailable", attributes))
    deprecated_state = DEPRECATED_UNAVAILABLE_SUPPRESS;
#else 
  tree a;
  for (a = attributes; a; a = TREE_CHAIN (a))
    {
      tree name = TREE_PURPOSE (a);
      if (TREE_CODE (name) == IDENTIFIER_NODE)
        if (is_attribute_p ("deprecated", name))
	  {
	    deprecated_state = DEPRECATED_SUPPRESS;
	    break;
	  }
        if (is_attribute_p ("unavailable", name))
	  {
	    deprecated_state = DEPRECATED_UNAVAILABLE_SUPPRESS;
	    break;
	  }
    }
#endif
  decl = grokdeclarator (declarator, declspecs,
			 NORMAL, initialized, NULL);
  if (!decl)
    return 0;
  deprecated_state = DEPRECATED_NORMAL;
  if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
      && MAIN_NAME_P (DECL_NAME (decl)))
    warning (OPT_Wmain, "%q+D is usually a function", decl);
  if (initialized)
    switch (TREE_CODE (decl))
      {
      case TYPE_DECL:
	error ("typedef %qD is initialized (use __typeof__ instead)", decl);
	initialized = 0;
	break;
      case FUNCTION_DECL:
	error ("function %qD is initialized like a variable", decl);
	initialized = 0;
	break;
      case PARM_DECL:
	error ("parameter %qD is initialized", decl);
	initialized = 0;
	break;
      default:
	if (TREE_TYPE (decl) == error_mark_node)
	  initialized = 0;
	else if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
	  {
	    if (TREE_CODE (TYPE_SIZE (TREE_TYPE (decl))) != INTEGER_CST
		|| C_DECL_VARIABLE_SIZE (decl))
	      {
		error ("variable-sized object may not be initialized");
		initialized = 0;
	      }
	  }
	else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
	  {
	    error ("variable %qD has initializer but incomplete type", decl);
	    initialized = 0;
	  }
	else if (C_DECL_VARIABLE_SIZE (decl))
	  {
	    error ("variable-sized object may not be initialized");
	    initialized = 0;
	  }
      }
  if (initialized)
    {
      if (current_scope == file_scope)
	TREE_STATIC (decl) = 1;
      DECL_INITIAL (decl) = error_mark_node;
    }
  if (TREE_CODE (decl) == FUNCTION_DECL)
    gen_aux_info_record (decl, 0, 0, TYPE_ARG_TYPES (TREE_TYPE (decl)) != 0);
  if (TREE_CODE (decl) == VAR_DECL
      && !initialized
      && TREE_PUBLIC (decl)
      && !DECL_THREAD_LOCAL_P (decl)
      && !flag_no_common)
    DECL_COMMON (decl) = 1;
  decl_attributes (&decl, attributes, 0);
  if (declspecs->inline_p
      && !flag_gnu89_inline
      && TREE_CODE (decl) == FUNCTION_DECL
      && lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl)))
    {
      if (declspecs->storage_class == csc_auto && current_scope != file_scope)
	;
      else if (declspecs->storage_class != csc_static)
	DECL_EXTERNAL (decl) = !DECL_EXTERNAL (decl);
    }
  if (TREE_CODE (decl) == FUNCTION_DECL
      && targetm.calls.promote_prototypes (TREE_TYPE (decl)))
    {
      struct c_declarator *ce = declarator;
      if (ce->kind == cdk_pointer)
	ce = declarator->declarator;
      if (ce->kind == cdk_function)
	{
	  tree args = ce->u.arg_info->parms;
	  for (; args; args = TREE_CHAIN (args))
	    {
	      tree type = TREE_TYPE (args);
	      if (type && INTEGRAL_TYPE_P (type)
		  && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
		DECL_ARG_TYPE (args) = integer_type_node;
	    }
	}
    }
  if (TREE_CODE (decl) == FUNCTION_DECL
      && DECL_DECLARED_INLINE_P (decl)
      && DECL_UNINLINABLE (decl)
      && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
    warning (OPT_Wattributes, "inline function %q+D given attribute noinline",
	     decl);
  if (TREE_CODE (decl) == VAR_DECL
      && current_scope != file_scope
      && TREE_STATIC (decl)
      && !TREE_READONLY (decl)
      && DECL_DECLARED_INLINE_P (current_function_decl)
      && DECL_EXTERNAL (current_function_decl))
    pedwarn ("%q+D is static but declared in inline function %qD "
	     "which is not static", decl, current_function_decl);
  tem = pushdecl (decl);
  if (initialized && DECL_EXTERNAL (tem))
    {
      DECL_EXTERNAL (tem) = 0;
      TREE_STATIC (tem) = 1;
    }
  return tem;
}
tree start_decl ( struct c_declarator * declarator , struct c_declspecs * declspecs , bool initialized , tree attributes ) { tree decl ; tree tem ; #ifdef A_LESS_INEFFICENT_WAY if ( lookup_attribute ( " " , attributes ) ) deprecated_state = DEPRECATED_SUPPRESS ; else if ( lookup_attribute ( " " , attributes ) ) deprecated_state = DEPRECATED_UNAVAILABLE_SUPPRESS ; #else tree a ; for ( a = attributes ; a ; a = TREE_CHAIN ( a ) ) { tree name = TREE_PURPOSE ( a ) ; if ( TREE_CODE ( name ) == IDENTIFIER_NODE ) if ( is_attribute_p ( " " , name ) ) { deprecated_state = DEPRECATED_SUPPRESS ; break ; } if ( is_attribute_p ( " " , name ) ) { deprecated_state = DEPRECATED_UNAVAILABLE_SUPPRESS ; break ; } } #endif decl = grokdeclarator ( declarator , declspecs , NORMAL , initialized , NULL ) ; if ( ! decl ) return 0 ; deprecated_state = DEPRECATED_NORMAL ; if ( warn_main > 0 && TREE_CODE ( decl ) != FUNCTION_DECL && MAIN_NAME_P ( DECL_NAME ( decl ) ) ) warning ( OPT_Wmain , " " , decl ) ; if ( initialized ) switch ( TREE_CODE ( decl ) ) { case TYPE_DECL : error ( " " , decl ) ; initialized = 0 ; break ; case FUNCTION_DECL : error ( " " , decl ) ; initialized = 0 ; break ; case PARM_DECL : error ( " " , decl ) ; initialized = 0 ; break ; default : if ( TREE_TYPE ( decl ) == error_mark_node ) initialized = 0 ; else if ( COMPLETE_TYPE_P ( TREE_TYPE ( decl ) ) ) { if ( TREE_CODE ( TYPE_SIZE ( TREE_TYPE ( decl ) ) ) != INTEGER_CST || C_DECL_VARIABLE_SIZE ( decl ) ) { error ( " " ) ; initialized = 0 ; } } else if ( TREE_CODE ( TREE_TYPE ( decl ) ) != ARRAY_TYPE ) { error ( " " , decl ) ; initialized = 0 ; } else if ( C_DECL_VARIABLE_SIZE ( decl ) ) { error ( " " ) ; initialized = 0 ; } } if ( initialized ) { if ( current_scope == file_scope ) TREE_STATIC ( decl ) = 1 ; DECL_INITIAL ( decl ) = error_mark_node ; } if ( TREE_CODE ( decl ) == FUNCTION_DECL ) gen_aux_info_record ( decl , 0 , 0 , TYPE_ARG_TYPES ( TREE_TYPE ( decl ) ) != 0 ) ; if ( TREE_CODE ( decl ) == VAR_DECL && ! initialized && TREE_PUBLIC ( decl ) && ! DECL_THREAD_LOCAL_P ( decl ) && ! flag_no_common ) DECL_COMMON ( decl ) = 1 ; decl_attributes ( & decl , attributes , 0 ) ; if ( declspecs -> inline_p && ! flag_gnu89_inline && TREE_CODE ( decl ) == FUNCTION_DECL && lookup_attribute ( " " , DECL_ATTRIBUTES ( decl ) ) ) { if ( declspecs -> storage_class == csc_auto && current_scope != file_scope ) ; else if ( declspecs -> storage_class != csc_static ) DECL_EXTERNAL ( decl ) = ! DECL_EXTERNAL ( decl ) ; } if ( TREE_CODE ( decl ) == FUNCTION_DECL && targetm . calls . promote_prototypes ( TREE_TYPE ( decl ) ) ) { struct c_declarator * ce = declarator ; if ( ce -> kind == cdk_pointer ) ce = declarator -> declarator ; if ( ce -> kind == cdk_function ) { tree args = ce -> u . arg_info -> parms ; for ( ; args ; args = TREE_CHAIN ( args ) ) { tree type = TREE_TYPE ( args ) ; if ( type && INTEGRAL_TYPE_P ( type ) && TYPE_PRECISION ( type ) < TYPE_PRECISION ( integer_type_node ) ) DECL_ARG_TYPE ( args ) = integer_type_node ; } } } if ( TREE_CODE ( decl ) == FUNCTION_DECL && DECL_DECLARED_INLINE_P ( decl ) && DECL_UNINLINABLE ( decl ) && lookup_attribute ( " " , DECL_ATTRIBUTES ( decl ) ) ) warning ( OPT_Wattributes , " " , decl ) ; if ( TREE_CODE ( decl ) == VAR_DECL && current_scope != file_scope && TREE_STATIC ( decl ) && ! TREE_READONLY ( decl ) && DECL_DECLARED_INLINE_P ( current_function_decl ) && DECL_EXTERNAL ( current_function_decl ) ) pedwarn ( " " " " , decl , current_function_decl ) ; tem = pushdecl ( decl ) ; if ( initialized && DECL_EXTERNAL ( tem ) ) { DECL_EXTERNAL ( tem ) = 0 ; TREE_STATIC ( tem ) = 1 ; } return tem ; }
Decode a declarator in an ordinary declaration or data definition.
Decode a declarator in an ordinary declaration or data definition .
/* An object declared as __attribute__((deprecated)) suppresses
     warnings of uses of other deprecated items.  */ /* APPLE LOCAL begin "unavailable" attribute (radar 2809697) */ /* An object declared as __attribute__((unavailable)) suppresses
     any reports of being declared with unavailable or deprecated
     items.  An object declared as __attribute__((deprecated))
     suppresses warnings of uses of other deprecated items.  */ /* which I really don't want to do!  */ /* a more efficient way doing what lookup_attribute would do */ /* APPLE LOCAL end "unavailable" attribute (radar 2809697) */ /* Is it valid for this decl to have an initializer at all?
       If not, set INITIALIZED to zero, which will indirectly
       tell 'finish_decl' to ignore the initializer once it is parsed.  */ /* DECL_INITIAL in a PARM_DECL is really DECL_ARG_TYPE.  */ /* Don't allow initializations for incomplete types except for
	   arrays which might be completed by the initialization.  */ /* This can happen if the array size is an undefined macro.
	   We already gave a warning, so we don't need another one.  */ /* A complete type is ok if size is fixed.  */ /* Although C99 is unclear about whether incomplete arrays
	       of VLAs themselves count as VLAs, it does not make
	       sense to permit them to be initialized given that
	       ordinary VLAs may not be initialized.  */ /* Tell 'pushdecl' this is an initialized decl
	 even though we don't yet have the initializer expression.
	 Also tell 'finish_decl' it may store the real initializer.  */ /* If this is a function declaration, write a record describing it to the
     prototypes file (if requested).  */ /* ANSI specifies that a tentative definition which is not merged with
     a non-tentative definition behaves exactly like a definition with an
     initializer equal to zero.  (Section 3.7.2)

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

     Thread-local variables are never common, since there's no entrenched
     body of code to break, and it allows more efficient variable references
     in the presence of dynamic linking.  */ /* Set attributes here so if duplicate decl, will have proper attributes.  */ /* Handle gnu_inline attribute.  */ /* C99 6.7.4p3: An inline definition of a function with external
     linkage shall not contain a definition of a modifiable object
     with static storage duration...  */ /* Add this decl to the current scope.
     TEM may equal DECL or it may be a previous decl of the same name.  */