FreeBSD/contrib/gcc/c-common.c
/* Handle an "visibility" attribute; arguments as in
   struct attribute_spec.handler.  */
Handle an "visibility" attribute; arguments as in
struct attribute_spec.handler.
Handle an " visibility " attribute ; arguments as in struct attribute_spec . handler .
static tree
handle_visibility_attribute (tree *node, tree name, tree args,
			     int ARG_UNUSED (flags),
			     bool *ARG_UNUSED (no_add_attrs))
{
  tree decl = *node;
  tree id = TREE_VALUE (args);
  enum symbol_visibility vis;
  if (TYPE_P (*node))
    {
      if (TREE_CODE (*node) == ENUMERAL_TYPE)
	;
      else if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
	{
	  warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
		   name);
	  return NULL_TREE;
	}
      else if (TYPE_FIELDS (*node))
	{
	  error ("%qE attribute ignored because %qT is already defined",
		 name, *node);
	  return NULL_TREE;
	}
    }
  else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      return NULL_TREE;
    }
  if (TREE_CODE (id) != STRING_CST)
    {
      error ("visibility argument not a string");
      return NULL_TREE;
    }
  if (TYPE_P (decl))
    {
      decl = TYPE_NAME (decl);
      if (!decl)
	return NULL_TREE;
      if (TREE_CODE (decl) == IDENTIFIER_NODE)
	{
	   warning (OPT_Wattributes, "%qE attribute ignored on types",
		    name);
	   return NULL_TREE;
	}
    }
  if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
    vis = VISIBILITY_DEFAULT;
  else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
    vis = VISIBILITY_INTERNAL;
  else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
    vis = VISIBILITY_HIDDEN;
  else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
    vis = VISIBILITY_PROTECTED;
  else
    {
      error ("visibility argument must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
      vis = VISIBILITY_DEFAULT;
    }
  if (DECL_VISIBILITY_SPECIFIED (decl)
      && vis != DECL_VISIBILITY (decl)
      && lookup_attribute ("visibility", (TYPE_P (*node)
					  ? TYPE_ATTRIBUTES (*node)
					  : DECL_ATTRIBUTES (decl))))
    error ("%qD redeclared with different visibility", decl);
  DECL_VISIBILITY (decl) = vis;
  DECL_VISIBILITY_SPECIFIED (decl) = 1;
  return NULL_TREE;
}
static tree handle_visibility_attribute ( tree * node , tree name , tree args , int ARG_UNUSED ( flags ) , bool * ARG_UNUSED ( no_add_attrs ) ) { tree decl = * node ; tree id = TREE_VALUE ( args ) ; enum symbol_visibility vis ; if ( TYPE_P ( * node ) ) { if ( TREE_CODE ( * node ) == ENUMERAL_TYPE ) ; else if ( TREE_CODE ( * node ) != RECORD_TYPE && TREE_CODE ( * node ) != UNION_TYPE ) { warning ( OPT_Wattributes , " " , name ) ; return NULL_TREE ; } else if ( TYPE_FIELDS ( * node ) ) { error ( " " , name , * node ) ; return NULL_TREE ; } } else if ( decl_function_context ( decl ) != 0 || ! TREE_PUBLIC ( decl ) ) { warning ( OPT_Wattributes , " " , name ) ; return NULL_TREE ; } if ( TREE_CODE ( id ) != STRING_CST ) { error ( " " ) ; return NULL_TREE ; } if ( TYPE_P ( decl ) ) { decl = TYPE_NAME ( decl ) ; if ( ! decl ) return NULL_TREE ; if ( TREE_CODE ( decl ) == IDENTIFIER_NODE ) { warning ( OPT_Wattributes , " " , name ) ; return NULL_TREE ; } } if ( strcmp ( TREE_STRING_POINTER ( id ) , " " ) == 0 ) vis = VISIBILITY_DEFAULT ; else if ( strcmp ( TREE_STRING_POINTER ( id ) , " " ) == 0 ) vis = VISIBILITY_INTERNAL ; else if ( strcmp ( TREE_STRING_POINTER ( id ) , " " ) == 0 ) vis = VISIBILITY_HIDDEN ; else if ( strcmp ( TREE_STRING_POINTER ( id ) , " " ) == 0 ) vis = VISIBILITY_PROTECTED ; else { error ( " \" \" \" \" \" \" \" \" " ) ; vis = VISIBILITY_DEFAULT ; } if ( DECL_VISIBILITY_SPECIFIED ( decl ) && vis != DECL_VISIBILITY ( decl ) && lookup_attribute ( " " , ( TYPE_P ( * node ) ? TYPE_ATTRIBUTES ( * node ) : DECL_ATTRIBUTES ( decl ) ) ) ) error ( " " , decl ) ; DECL_VISIBILITY ( decl ) = vis ; DECL_VISIBILITY_SPECIFIED ( decl ) = 1 ; return NULL_TREE ; }
Handle an "visibility" attribute; arguments as in
struct attribute_spec.handler.
Handle an " visibility " attribute ; arguments as in struct attribute_spec . handler .
/* OK */ /*  If this is a type, set the visibility on the type decl.  */ /* Go ahead and attach the attribute to the node as well.  This is needed
     so we can determine whether we have VISIBILITY_DEFAULT because the
     visibility was not specified, or because it was explicitly overridden
     from the containing scope.  */