FreeBSD/contrib/gcc/cp/decl.c
/* Called when a declaration is seen that contains no names to declare.
   If its type is a reference to a structure, union or enum inherited
   from a containing scope, shadow that tag name for the current scope
   with a forward reference.
   If its type defines a new named structure or union
   or defines an enum, it is valid but we need not do anything here.
   Otherwise, it is an error.

   C++: may have to grok the declspecs to learn about static,
   complain for anonymous unions.

   Returns the TYPE declared -- or NULL_TREE if none.  */
Called when a declaration is seen that contains no names to declare.
If its type is a reference to a structure, union or enum inherited
from a containing scope, shadow that tag name for the current scope
with a forward reference.
If its type defines a new named structure or union
or defines an enum, it is valid but we need not do anything here.
Otherwise, it is an error.

C++: may have to grok the declspecs to learn about static,
complain for anonymous unions.

Returns the TYPE declared -- or NULL_TREE if none.
Called when a declaration is seen that contains no names to declare . If its type is a reference to a structure union or enum inherited from a containing scope shadow that tag name for the current scope with a forward reference . If its type defines a new named structure or union or defines an enum it is valid but we need not do anything here . Otherwise it is an error . C ++ : may have to grok the declspecs to learn about static complain for anonymous unions . Returns the TYPE declared -- or NULL_TREE if none .
tree
shadow_tag (cp_decl_specifier_seq *declspecs)
{
  tree t = check_tag_decl (declspecs);
  if (!t)
    return NULL_TREE;
  if (declspecs->attributes)
    {
      warning (0, "attribute ignored in declaration of %q+#T", t);
      warning (0, "attribute for %q+#T must follow the %qs keyword",
	       t, class_key_or_enum_as_string (t));
    }
  if (maybe_process_partial_specialization (t) == error_mark_node)
    return NULL_TREE;
  if (ANON_AGGR_TYPE_P (t))
    {
      fixup_anonymous_aggr (t);
      if (TYPE_FIELDS (t))
	{
	  tree decl = grokdeclarator (NULL,
				      declspecs, NORMAL, 0, NULL);
	  finish_anon_union (decl);
	}
    }
  return t;
}
tree shadow_tag ( cp_decl_specifier_seq * declspecs ) { tree t = check_tag_decl ( declspecs ) ; if ( ! t ) return NULL_TREE ; if ( declspecs -> attributes ) { warning ( 0 , " " , t ) ; warning ( 0 , " " , t , class_key_or_enum_as_string ( t ) ) ; } if ( maybe_process_partial_specialization ( t ) == error_mark_node ) return NULL_TREE ; if ( ANON_AGGR_TYPE_P ( t ) ) { fixup_anonymous_aggr ( t ) ; if ( TYPE_FIELDS ( t ) ) { tree decl = grokdeclarator ( NULL , declspecs , NORMAL , 0 , NULL ) ; finish_anon_union ( decl ) ; } } return t ; }
Called when a declaration is seen that contains no names to declare.
Called when a declaration is seen that contains no names to declare .
/* This is where the variables in an anonymous union are
     declared.  An anonymous union declaration looks like:
     union { ... } ;
     because there is no declarator after the union, the parser
     sends that declaration here.  */ /*declarator=*/