OSDN Git Service

* tree-ssa-alias.c (dump_mem_ref_stats): Do not call
[pf3gnuchains/gcc-fork.git] / gcc / attribs.c
index cbfe664..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,25 +77,25 @@ init_attributes (void)
          /* The name must not begin and end with __.  */
          const char *name = attribute_tables[i][j].name;
          int len = strlen (name);
-         if (name[0] == '_' && name[1] == '_'
-             && name[len - 1] == '_' && name[len - 2] == '_')
-           abort ();
+
+         gcc_assert (!(name[0] == '_' && name[1] == '_'
+                       && name[len - 1] == '_' && name[len - 2] == '_'));
+
          /* The minimum and maximum lengths must be consistent.  */
-         if (attribute_tables[i][j].min_length < 0)
-           abort ();
-         if (attribute_tables[i][j].max_length != -1
-             && (attribute_tables[i][j].max_length
-                 < attribute_tables[i][j].min_length))
-           abort ();
+         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.  */
-         if (attribute_tables[i][j].decl_required
-             && attribute_tables[i][j].type_required)
-           abort ();
+         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.  */
-         if (attribute_tables[i][j].function_type_required
-             && !attribute_tables[i][j].type_required)
-           abort ();
+         gcc_assert (!attribute_tables[i][j].function_type_required
+                     || attribute_tables[i][j].type_required);
        }
     }
 
@@ -105,9 +105,8 @@ init_attributes (void)
       int j, k;
       for (j = 0; attribute_tables[i][j].name != NULL; j++)
        for (k = j + 1; attribute_tables[i][k].name != NULL; k++)
-         if (!strcmp (attribute_tables[i][j].name,
-                      attribute_tables[i][k].name))
-           abort ();
+         gcc_assert (strcmp (attribute_tables[i][j].name,
+                             attribute_tables[i][k].name));
     }
   /* Check that no name occurs in more than one table.  */
   for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
@@ -117,9 +116,8 @@ init_attributes (void)
       for (j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
        for (k = 0; attribute_tables[i][k].name != NULL; k++)
          for (l = 0; attribute_tables[j][l].name != NULL; l++)
-           if (!strcmp (attribute_tables[i][k].name,
-                        attribute_tables[j][l].name))
-             abort ();
+           gcc_assert (strcmp (attribute_tables[i][k].name,
+                               attribute_tables[j][l].name));
     }
 #endif
 
@@ -174,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;
        }
@@ -182,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;
        }
@@ -199,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;
            }
@@ -229,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;
@@ -245,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),
@@ -261,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)
        {
@@ -327,114 +328,13 @@ decl_attributes (tree *node, tree attributes, int flags)
          fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
          if (DECL_P (*node))
            TREE_TYPE (*node) = fn_ptr_tmp;
-         else if (TREE_CODE (*node) == POINTER_TYPE)
-           *node = fn_ptr_tmp;
-         else
-           abort ();
-       }
-    }
-
-  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;
+             gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
+             *node = fn_ptr_tmp;
            }
        }
-      /* 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;
+  return returned_attrs;
 }