FreeBSD/contrib/gcc/cp/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 `cp_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 `cp_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 ` cp_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 (const cp_declarator *declarator,
	    cp_decl_specifier_seq *declspecs,
	    int initialized,
	    tree attributes,
	    tree prefix_attributes,
	    tree *pushed_scope_p)
{
  tree decl;
  tree type, tem;
  tree context;
  tree a;
  bool was_public;
  *pushed_scope_p = NULL_TREE;
#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 
  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
  attributes = chainon (attributes, prefix_attributes);
  decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
			 &attributes);
  deprecated_state = DEPRECATED_NORMAL;
  if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE
      || decl == error_mark_node)
    return error_mark_node;
  type = TREE_TYPE (decl);
  context = DECL_CONTEXT (decl);
  if (context)
    {
      *pushed_scope_p = push_scope (context);
      if (TREE_CODE (context) == NAMESPACE_DECL)
	context = NULL_TREE;
    }
  if (initialized)
    switch (TREE_CODE (decl))
      {
      case TYPE_DECL:
	error ("typedef %qD is initialized (use __typeof__ instead)", decl);
	return error_mark_node;
      case FUNCTION_DECL:
	error ("function %q#D is initialized like a variable", decl);
	return error_mark_node;
      default:
	break;
      }
  if (initialized)
    {
      if (! toplevel_bindings_p ()
	  && DECL_EXTERNAL (decl))
	warning (0, "declaration of %q#D has %<extern%> and is initialized",
		 decl);
      DECL_EXTERNAL (decl) = 0;
      if (toplevel_bindings_p ())
	TREE_STATIC (decl) = 1;
    }
  cplus_decl_attributes (&decl, attributes, 0);
  if (initialized && DECL_DLLIMPORT_P (decl))
    {
      error ("definition of %q#D is marked %<dllimport%>", decl);
      DECL_DLLIMPORT_P (decl) = 0;
    }
  maybe_apply_pragma_weak (decl);
  if (TREE_CODE (decl) == FUNCTION_DECL
      && DECL_DECLARED_INLINE_P (decl)
      && DECL_UNINLINABLE (decl)
      && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
    warning (0, "inline function %q+D given attribute noinline", decl);
  if (context && COMPLETE_TYPE_P (complete_type (context)))
    {
      if (TREE_CODE (decl) == VAR_DECL)
	{
	  tree field = lookup_field (context, DECL_NAME (decl), 0, false);
	  if (field == NULL_TREE || TREE_CODE (field) != VAR_DECL)
	    error ("%q#D is not a static member of %q#T", decl, context);
	  else
	    {
	      if (DECL_CONTEXT (field) != context)
		{
		  if (!same_type_p (DECL_CONTEXT (field), context))
		    pedwarn ("ISO C++ does not permit %<%T::%D%> "
			     "to be defined as %<%T::%D%>",
			     DECL_CONTEXT (field), DECL_NAME (decl),
			     context, DECL_NAME (decl));
		  DECL_CONTEXT (decl) = DECL_CONTEXT (field);
		}
	      if (processing_specialization
		  && template_class_depth (context) == 0
		  && CLASSTYPE_TEMPLATE_SPECIALIZATION (context))
		error ("template header not allowed in member definition "
		       "of explicitly specialized class");
	      if (initialized && DECL_INITIALIZED_IN_CLASS_P (field))
		error ("duplicate initialization of %qD", decl);
	      if (duplicate_decls (decl, field, false))
		decl = field;
	    }
	}
      else
	{
	  tree field = check_classfn (context, decl,
				      (processing_template_decl
				       > template_class_depth (context))
				      ? current_template_parms
				      : NULL_TREE);
	  if (field && duplicate_decls (decl, field,
					false))
	    decl = field;
	}
      DECL_IN_AGGR_P (decl) = 0;
      if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
	{
	  SET_DECL_TEMPLATE_SPECIALIZATION (decl);
	  if (!initialized && processing_specialization)
	    DECL_EXTERNAL (decl) = 1;
	}
      if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
	pedwarn ("declaration of %q#D outside of class is not definition",
		 decl);
    }
  was_public = TREE_PUBLIC (decl);
  tem = maybe_push_decl (decl);
  if (processing_template_decl)
    tem = push_template_decl (tem);
  if (tem == error_mark_node)
    return error_mark_node;
  if (flag_conserve_space
      && TREE_CODE (tem) == VAR_DECL
      && TREE_PUBLIC (tem)
      && !DECL_THREAD_LOCAL_P (tem)
      && !have_global_bss_p ())
    DECL_COMMON (tem) = 1;
  if (TREE_CODE (tem) == VAR_DECL
      && DECL_NAMESPACE_SCOPE_P (tem) && !TREE_PUBLIC (tem) && !was_public
      && !DECL_THIS_STATIC (tem) && !DECL_ARTIFICIAL (tem))
    {
      gcc_assert (cp_type_readonly (TREE_TYPE (tem)));
      DECL_THIS_STATIC (tem) = 1;
    }
  if (!processing_template_decl && TREE_CODE (tem) == VAR_DECL)
    start_decl_1 (tem, initialized);
  return tem;
}
tree start_decl ( const cp_declarator * declarator , cp_decl_specifier_seq * declspecs , int initialized , tree attributes , tree prefix_attributes , tree * pushed_scope_p ) { tree decl ; tree type , tem ; tree context ; tree a ; bool was_public ; * pushed_scope_p = NULL_TREE ; #ifdef A_LESS_INEFFICENT_WAY if ( lookup_attribute ( " " , attributes ) ) deprecated_state = DEPRECATED_SUPPRESS ; else if ( lookup_attribute ( " " , attributes ) ) deprecated_state = DEPRECATED_UNAVAILABLE_SUPPRESS ; #else 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 attributes = chainon ( attributes , prefix_attributes ) ; decl = grokdeclarator ( declarator , declspecs , NORMAL , initialized , & attributes ) ; deprecated_state = DEPRECATED_NORMAL ; if ( decl == NULL_TREE || TREE_CODE ( decl ) == VOID_TYPE || decl == error_mark_node ) return error_mark_node ; type = TREE_TYPE ( decl ) ; context = DECL_CONTEXT ( decl ) ; if ( context ) { * pushed_scope_p = push_scope ( context ) ; if ( TREE_CODE ( context ) == NAMESPACE_DECL ) context = NULL_TREE ; } if ( initialized ) switch ( TREE_CODE ( decl ) ) { case TYPE_DECL : error ( " " , decl ) ; return error_mark_node ; case FUNCTION_DECL : error ( " " , decl ) ; return error_mark_node ; default : break ; } if ( initialized ) { if ( ! toplevel_bindings_p ( ) && DECL_EXTERNAL ( decl ) ) warning ( 0 , " " , decl ) ; DECL_EXTERNAL ( decl ) = 0 ; if ( toplevel_bindings_p ( ) ) TREE_STATIC ( decl ) = 1 ; } cplus_decl_attributes ( & decl , attributes , 0 ) ; if ( initialized && DECL_DLLIMPORT_P ( decl ) ) { error ( " " , decl ) ; DECL_DLLIMPORT_P ( decl ) = 0 ; } maybe_apply_pragma_weak ( decl ) ; if ( TREE_CODE ( decl ) == FUNCTION_DECL && DECL_DECLARED_INLINE_P ( decl ) && DECL_UNINLINABLE ( decl ) && lookup_attribute ( " " , DECL_ATTRIBUTES ( decl ) ) ) warning ( 0 , " " , decl ) ; if ( context && COMPLETE_TYPE_P ( complete_type ( context ) ) ) { if ( TREE_CODE ( decl ) == VAR_DECL ) { tree field = lookup_field ( context , DECL_NAME ( decl ) , 0 , false ) ; if ( field == NULL_TREE || TREE_CODE ( field ) != VAR_DECL ) error ( " " , decl , context ) ; else { if ( DECL_CONTEXT ( field ) != context ) { if ( ! same_type_p ( DECL_CONTEXT ( field ) , context ) ) pedwarn ( " " " " , DECL_CONTEXT ( field ) , DECL_NAME ( decl ) , context , DECL_NAME ( decl ) ) ; DECL_CONTEXT ( decl ) = DECL_CONTEXT ( field ) ; } if ( processing_specialization && template_class_depth ( context ) == 0 && CLASSTYPE_TEMPLATE_SPECIALIZATION ( context ) ) error ( " " " " ) ; if ( initialized && DECL_INITIALIZED_IN_CLASS_P ( field ) ) error ( " " , decl ) ; if ( duplicate_decls ( decl , field , false ) ) decl = field ; } } else { tree field = check_classfn ( context , decl , ( processing_template_decl > template_class_depth ( context ) ) ? current_template_parms : NULL_TREE ) ; if ( field && duplicate_decls ( decl , field , false ) ) decl = field ; } DECL_IN_AGGR_P ( decl ) = 0 ; if ( DECL_LANG_SPECIFIC ( decl ) && DECL_USE_TEMPLATE ( decl ) ) { SET_DECL_TEMPLATE_SPECIALIZATION ( decl ) ; if ( ! initialized && processing_specialization ) DECL_EXTERNAL ( decl ) = 1 ; } if ( DECL_EXTERNAL ( decl ) && ! DECL_TEMPLATE_SPECIALIZATION ( decl ) ) pedwarn ( " " , decl ) ; } was_public = TREE_PUBLIC ( decl ) ; tem = maybe_push_decl ( decl ) ; if ( processing_template_decl ) tem = push_template_decl ( tem ) ; if ( tem == error_mark_node ) return error_mark_node ; if ( flag_conserve_space && TREE_CODE ( tem ) == VAR_DECL && TREE_PUBLIC ( tem ) && ! DECL_THREAD_LOCAL_P ( tem ) && ! have_global_bss_p ( ) ) DECL_COMMON ( tem ) = 1 ; if ( TREE_CODE ( tem ) == VAR_DECL && DECL_NAMESPACE_SCOPE_P ( tem ) && ! TREE_PUBLIC ( tem ) && ! was_public && ! DECL_THIS_STATIC ( tem ) && ! DECL_ARTIFICIAL ( tem ) ) { gcc_assert ( cp_type_readonly ( TREE_TYPE ( tem ) ) ) ; DECL_THIS_STATIC ( tem ) = 1 ; } if ( ! processing_template_decl && TREE_CODE ( tem ) == VAR_DECL ) start_decl_1 ( tem , initialized ) ; return tem ; }
Decode a declarator in an ordinary declaration or data definition.
Decode a declarator in an ordinary declaration or data definition .
/* APPLE LOCAL "unavailable" attribute (radar 2809697) */ /* 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) */ /* We are only interested in class contexts, later.  */ /* Is it valid for this decl to have an initializer at all?
       If not, set INITIALIZED to zero, which will indirectly
       tell `cp_finish_decl' to ignore the initializer once it is parsed.  */ /* Set attributes here so if duplicate decl, will have proper attributes.  */ /* Dllimported symbols cannot be defined.  Static data members (which
     can be initialized in-class and dllimported) go through grokfield,
     not here, so we don't need to exclude those decls when checking for
     a definition.  */ /* If #pragma weak was used, mark the decl weak now.  */ /* Static data member are tricky; an in-class initialization
		 still doesn't provide a definition, so the in-class
		 declaration will have DECL_EXTERNAL set, but will have an
		 initialization.  Thus, duplicate_decls won't warn
		 about this situation, and so we check here.  */ /*newdecl_is_friend=*/ /*newdecl_is_friend=*/ /* cp_finish_decl sets DECL_EXTERNAL if DECL_IN_AGGR_P is set.  */ /* Do not mark DECL as an explicit specialization if it was not
	 already marked as an instantiation; a declaration should
	 never be marked as a specialization unless we know what
	 template is being specialized.  */ /* [temp.expl.spec] An explicit specialization of a static data
	     member of a template is a definition if the declaration
	     includes an initializer; otherwise, it is a declaration.

	     We check for processing_specialization so this only applies
	     to the new specialization syntax.  */ /* Enter this declaration into the symbol table.  */ /* Tell the back-end to use or not use .common as appropriate.  If we say
     -fconserve-space, we want this to save .data space, at the expense of
     wrong semantics.  If we say -fno-conserve-space, we want this to
     produce errors about redefs; to do this we force variables into the
     data segment.  */ /* This is a const variable with implicit 'static'.  Set
	 DECL_THIS_STATIC so we can tell it from variables that are
	 !TREE_PUBLIC because of the anonymous namespace.  */