OSDN Git Service

(handle_braces): Rework last change.
[pf3gnuchains/gcc-fork.git] / gcc / c-common.c
index c74a1a8..1e2f6c5 100644 (file)
@@ -37,6 +37,10 @@ Boston, MA 02111-1307, USA.  */
 
 extern struct obstack permanent_obstack;
 
+/* Nonzero means the expression being parsed will never be evaluated.
+   This is a count, since unevaluated expressions can nest.  */
+int skip_evaluation;
+
 enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
            A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
            A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS};
@@ -284,7 +288,7 @@ init_attributes ()
 /* Process the attributes listed in ATTRIBUTES and PREFIX_ATTRIBUTES
    and install them in NODE, which is either a DECL (including a TYPE_DECL)
    or a TYPE.  PREFIX_ATTRIBUTES can appear after the declaration specifiers
-   and declaration modifiers but before the declaration proper. */
+   and declaration modifiers but before the declaration proper.  */
 
 void
 decl_attributes (node, attributes, prefix_attributes)
@@ -498,7 +502,8 @@ decl_attributes (node, attributes, prefix_attributes)
              && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
            {
              if (TREE_CODE (decl) == VAR_DECL 
-                 && current_function_decl != NULL_TREE)
+                 && current_function_decl != NULL_TREE
+                 && ! TREE_STATIC (decl))
                error_with_decl (decl,
                  "section attribute cannot be specified for local variables");
              /* The decl may have already been given a section attribute from
@@ -645,7 +650,7 @@ decl_attributes (node, attributes, prefix_attributes)
                if (first_arg_num != 0)
                  {
                    /* Verify that first_arg_num points to the last arg,
-                      the ... */
+                      the ...  */
                    while (argument)
                      arg_num++, argument = TREE_CHAIN (argument);
                  if (arg_num != first_arg_num)
@@ -732,7 +737,7 @@ decl_attributes (node, attributes, prefix_attributes)
 
        case A_ALIAS:
          if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
-             || TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl))
+             || (TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl)))
            error_with_decl (decl,
                             "`%s' defined both normally and as an alias");
          else if (decl_function_context (decl) == 0)
@@ -751,6 +756,76 @@ decl_attributes (node, attributes, prefix_attributes)
        }
     }
 }
+
+/* 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 (specs_attrs, declspecs, prefix_attributes)
+     tree specs_attrs;
+     tree *declspecs, *prefix_attributes;
+{
+  tree t, s, a, next, specs, attrs;
+
+  /* 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;
+           }
+       }
+      else
+       {
+         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;
+}
 \f
 /* Check a printf/fprintf/sprintf/scanf/fscanf/sscanf format against
    a parameter list.  */
@@ -922,7 +997,7 @@ record_function_format (name, assembler_name, is_scan,
    the number of the argument which is the format control string (starting
    from 1).  */
 
-void
+static void
 record_international_format (name, assembler_name, format_num)
       tree name;
       tree assembler_name;
@@ -1366,7 +1441,7 @@ check_format_info (info, params)
              || format_char == 'x' || format_char == 'x'))
        {
          sprintf (message,
-                  "precision and `0' flag not both allowed with `%c' format",
+                  "`0' flag ignored with precision specifier and `%c' format",
                   format_char);
          warning (message);
        }
@@ -1531,7 +1606,8 @@ overflow_warning (value)
       && TREE_OVERFLOW (value))
     {
       TREE_OVERFLOW (value) = 0;
-      warning ("integer overflow in expression");
+      if (skip_evaluation == 0)
+       warning ("integer overflow in expression");
     }
   else if ((TREE_CODE (value) == REAL_CST
            || (TREE_CODE (value) == COMPLEX_CST
@@ -1539,7 +1615,8 @@ overflow_warning (value)
           && TREE_OVERFLOW (value))
     {
       TREE_OVERFLOW (value) = 0;
-      warning ("floating point overflow in expression");
+      if (skip_evaluation == 0)
+       warning ("floating point overflow in expression");
     }
 }
 
@@ -1555,6 +1632,7 @@ unsigned_conversion_warning (result, operand)
   if (TREE_CODE (operand) == INTEGER_CST
       && TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE
       && TREE_UNSIGNED (TREE_TYPE (result))
+      && skip_evaluation == 0
       && !int_fits_type_p (operand, TREE_TYPE (result)))
     {
       if (!int_fits_type_p (operand, signed_type (TREE_TYPE (result))))
@@ -1590,10 +1668,11 @@ convert_and_check (type, expr)
                && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (expr))))
            /* If EXPR fits in the unsigned version of TYPE,
               don't warn unless pedantic.  */
-           if (pedantic
-               || TREE_UNSIGNED (type)
-               || ! int_fits_type_p (expr, unsigned_type (type)))
-             warning ("overflow in implicit constant conversion");
+           if ((pedantic
+                || TREE_UNSIGNED (type)
+                || ! int_fits_type_p (expr, unsigned_type (type)))
+               && skip_evaluation == 0)
+               warning ("overflow in implicit constant conversion");
        }
       else
        unsigned_conversion_warning (t, expr);
@@ -2292,7 +2371,7 @@ truthvalue_conversion (expr)
       if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
          || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
        break;
-      /* fall through... */
+      /* fall through...  */
     case NOP_EXPR:
       /* If this is widening the argument, we can ignore it.  */
       if (TYPE_PRECISION (TREE_TYPE (expr))
@@ -2306,7 +2385,7 @@ truthvalue_conversion (expr)
       if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
          && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
        break;
-      /* fall through... */
+      /* fall through...  */
     case BIT_XOR_EXPR:
       /* This and MINUS_EXPR can be changed into a comparison of the
         two objects.  */