OSDN Git Service

2006-10-03 Paul Thomas <pault@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / attribs.c
index 8174f39..7377c57 100644 (file)
@@ -1,6 +1,6 @@
 /* Functions dealing with attribute handling, used by most front ends.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004 Free Software Foundation, Inc.
+   2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -16,8 +16,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -77,21 +77,21 @@ init_attributes (void)
          /* The name must not begin and end with __.  */
          const char *name = attribute_tables[i][j].name;
          int len = strlen (name);
-         
+
          gcc_assert (!(name[0] == '_' && name[1] == '_'
                        && name[len - 1] == '_' && name[len - 2] == '_'));
-         
+
          /* The minimum and maximum lengths must be consistent.  */
          gcc_assert (attribute_tables[i][j].min_length >= 0);
-         
+
          gcc_assert (attribute_tables[i][j].max_length == -1
                      || (attribute_tables[i][j].max_length
                          >= attribute_tables[i][j].min_length));
-         
+
          /* An attribute cannot require both a DECL and a TYPE.  */
          gcc_assert (!attribute_tables[i][j].decl_required
                      || !attribute_tables[i][j].type_required);
-         
+
          /* If an attribute requires a function type, in particular
             it requires a type.  */
          gcc_assert (!attribute_tables[i][j].function_type_required
@@ -172,7 +172,7 @@ decl_attributes (tree *node, tree attributes, int flags)
 
       if (spec == NULL)
        {
-         warning ("`%s' attribute directive ignored",
+         warning (OPT_Wattributes, "%qs attribute directive ignored",
                   IDENTIFIER_POINTER (name));
          continue;
        }
@@ -180,7 +180,7 @@ decl_attributes (tree *node, tree attributes, int flags)
               || (spec->max_length >= 0
                   && list_length (args) > spec->max_length))
        {
-         error ("wrong number of arguments specified for `%s' attribute",
+         error ("wrong number of arguments specified for %qs attribute",
                 IDENTIFIER_POINTER (name));
          continue;
        }
@@ -197,7 +197,7 @@ decl_attributes (tree *node, tree attributes, int flags)
            }
          else
            {
-             warning ("`%s' attribute does not apply to types",
+             warning (OPT_Wattributes, "%qs attribute does not apply to types",
                       IDENTIFIER_POINTER (name));
              continue;
            }
@@ -227,8 +227,8 @@ decl_attributes (tree *node, tree attributes, int flags)
                 pull out the target type now, frob it as appropriate, and
                 rebuild the pointer type later.
 
-                This would all be simpler if attributes were part of the
-                declarator, grumble grumble.  */
+                This would all be simpler if attributes were part of the
+                declarator, grumble grumble.  */
              fn_ptr_tmp = TREE_TYPE (*anode);
              anode = &fn_ptr_tmp;
              flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
@@ -243,12 +243,21 @@ decl_attributes (tree *node, tree attributes, int flags)
          if (TREE_CODE (*anode) != FUNCTION_TYPE
              && TREE_CODE (*anode) != METHOD_TYPE)
            {
-             warning ("`%s' attribute only applies to function types",
+             warning (OPT_Wattributes,
+                      "%qs attribute only applies to function types",
                       IDENTIFIER_POINTER (name));
              continue;
            }
        }
 
+      if (TYPE_P (*anode)
+         && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
+         && TYPE_SIZE (*anode) != NULL_TREE)
+       {
+         warning (OPT_Wattributes, "type attributes ignored after type is already defined");
+         continue;
+       }
+
       if (spec->handler != NULL)
        returned_attrs = chainon ((*spec->handler) (anode, name, args,
                                                    flags, &no_add_attrs),
@@ -259,13 +268,7 @@ decl_attributes (tree *node, tree attributes, int flags)
          && (TREE_CODE (*node) == VAR_DECL
              || TREE_CODE (*node) == PARM_DECL
              || TREE_CODE (*node) == RESULT_DECL))
-       {
-         /* Force a recalculation of mode and size.  */
-         DECL_MODE (*node) = VOIDmode;
-         DECL_SIZE (*node) = 0;
-
-         layout_decl (*node, 0);
-       }
+       relayout_decl (*node);
 
       if (!no_add_attrs)
        {
@@ -335,105 +338,3 @@ decl_attributes (tree *node, tree attributes, int flags)
 
   return returned_attrs;
 }
-
-/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
-   lists.  SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE).
-
-   The head of the declspec list is stored in DECLSPECS.
-   The head of the attribute list is stored in PREFIX_ATTRIBUTES.
-
-   Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of
-   the list elements.  We drop the containing TREE_LIST nodes and link the
-   resulting attributes together the way decl_attributes expects them.  */
-
-void
-split_specs_attrs (tree specs_attrs, tree *declspecs, tree *prefix_attributes)
-{
-  tree t, s, a, next, specs, attrs;
-
-  /* This can happen after an __extension__ in pedantic mode.  */
-  if (specs_attrs != NULL_TREE
-      && TREE_CODE (specs_attrs) == INTEGER_CST)
-    {
-      *declspecs = NULL_TREE;
-      *prefix_attributes = NULL_TREE;
-      return;
-    }
-
-  /* This can happen in c++ (eg: decl: typespec initdecls ';').  */
-  if (specs_attrs != NULL_TREE
-      && TREE_CODE (specs_attrs) != TREE_LIST)
-    {
-      *declspecs = specs_attrs;
-      *prefix_attributes = NULL_TREE;
-      return;
-    }
-
-  /* Remember to keep the lists in the same order, element-wise.  */
-
-  specs = s = NULL_TREE;
-  attrs = a = NULL_TREE;
-  for (t = specs_attrs; t; t = next)
-    {
-      next = TREE_CHAIN (t);
-      /* Declspecs have a non-NULL TREE_VALUE.  */
-      if (TREE_VALUE (t) != NULL_TREE)
-       {
-         if (specs == NULL_TREE)
-           specs = s = t;
-         else
-           {
-             TREE_CHAIN (s) = t;
-             s = t;
-           }
-       }
-      /* The TREE_PURPOSE may also be empty in the case of
-        __attribute__(()).  */
-      else if (TREE_PURPOSE (t) != NULL_TREE)
-       {
-         if (attrs == NULL_TREE)
-           attrs = a = TREE_PURPOSE (t);
-         else
-           {
-             TREE_CHAIN (a) = TREE_PURPOSE (t);
-             a = TREE_PURPOSE (t);
-           }
-         /* More attrs can be linked here, move A to the end.  */
-         while (TREE_CHAIN (a) != NULL_TREE)
-           a = TREE_CHAIN (a);
-       }
-    }
-
-  /* Terminate the lists.  */
-  if (s != NULL_TREE)
-    TREE_CHAIN (s) = NULL_TREE;
-  if (a != NULL_TREE)
-    TREE_CHAIN (a) = NULL_TREE;
-
-  /* All done.  */
-  *declspecs = specs;
-  *prefix_attributes = attrs;
-}
-
-/* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes.
-   This function is used by the parser when a rule will accept attributes
-   in a particular position, but we don't want to support that just yet.
-
-   A warning is issued for every ignored attribute.  */
-
-tree
-strip_attrs (tree specs_attrs)
-{
-  tree specs, attrs;
-
-  split_specs_attrs (specs_attrs, &specs, &attrs);
-
-  while (attrs)
-    {
-      warning ("`%s' attribute ignored",
-              IDENTIFIER_POINTER (TREE_PURPOSE (attrs)));
-      attrs = TREE_CHAIN (attrs);
-    }
-
-  return specs;
-}