OSDN Git Service

* c-decl.c (c_decode_option): Don't handle -lang-objc.
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index c1093ce..98aae30 100644 (file)
@@ -41,11 +41,7 @@ Boston, MA 02111-1307, USA.  */
 #include "defaults.h"
 #include "ggc.h"
 #include "tm_p.h"
-
-#if USE_CPPLIB
 #include "cpplib.h"
-extern cpp_reader parse_in;
-#endif
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
@@ -347,7 +343,7 @@ int flag_no_asm;
 
 int flag_traditional;
 
-/* Nonzero means enable C89 Amendment 1 features, other than digraphs.  */
+/* Nonzero means enable C89 Amendment 1 features.  */
 
 int flag_isoc94 = 0;
 
@@ -355,10 +351,6 @@ int flag_isoc94 = 0;
 
 int flag_isoc99 = 0;
 
-/* Nonzero means accept digraphs.  */
-
-int flag_digraphs = 1;
-
 /* Nonzero means that we have builtin functions, and main is an int */
 
 int flag_hosted = 1;
@@ -510,20 +502,15 @@ c_decode_option (argc, argv)
      char **argv;
 {
   int strings_processed;
+  const char *option_value = NULL;
   char *p = argv[0];
-#if USE_CPPLIB
-  strings_processed = cpp_handle_option (&parse_in, argc, argv);
-#else
-  strings_processed = 0;
-#endif /* ! USE_CPPLIB */
 
-  if (!strcmp (p, "-lang-objc"))
-    c_language = clk_objective_c;
-  else if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
+  strings_processed = cpp_handle_option (parse_in, argc, argv);
+
+  if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
     {
       flag_traditional = 1;
       flag_writable_strings = 1;
-      flag_digraphs = 0;
     }
   else if (!strcmp (p, "-fallow-single-precision"))
     flag_allow_single_precision = 1;
@@ -544,7 +531,6 @@ c_decode_option (argc, argv)
     {
       flag_traditional = 0;
       flag_writable_strings = 0;
-      flag_digraphs = 1;
     }
   else if (!strncmp (p, "-std=", 5))
     {
@@ -564,9 +550,8 @@ c_decode_option (argc, argv)
          || !strcmp (argstart, "c89"))
        {
        iso_1990:
-         flag_digraphs = 0;
          flag_isoc94 = 0;
-       iso_1990_digraphs:
+       iso_1994:
          flag_traditional = 0;
          flag_writable_strings = 0;
          flag_no_asm = 1;
@@ -576,9 +561,8 @@ c_decode_option (argc, argv)
        }
       else if (!strcmp (argstart, "iso9899:199409"))
        {
-         flag_digraphs = 1;
          flag_isoc94 = 1;
-         goto iso_1990_digraphs;
+         goto iso_1994;
        }
       else if (!strcmp (argstart, "iso9899:199x")
               || !strcmp (argstart, "iso9899:1999")
@@ -591,7 +575,6 @@ c_decode_option (argc, argv)
          flag_no_nonansi_builtin = 1;
          flag_noniso_default_format_attributes = 0;
          flag_isoc99 = 1;
-         flag_digraphs = 1;
          flag_isoc94 = 1;
        }
       else if (!strcmp (argstart, "gnu89"))
@@ -602,7 +585,6 @@ c_decode_option (argc, argv)
          flag_no_nonansi_builtin = 0;
          flag_noniso_default_format_attributes = 1;
          flag_isoc99 = 0;
-         flag_digraphs = 1;
          flag_isoc94 = 0;
        }
       else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99"))
@@ -613,7 +595,6 @@ c_decode_option (argc, argv)
          flag_no_nonansi_builtin = 0;
          flag_noniso_default_format_attributes = 1;
          flag_isoc99 = 1;
-         flag_digraphs = 1;
          flag_isoc94 = 1;
        }
       else
@@ -667,6 +648,14 @@ c_decode_option (argc, argv)
     flag_no_builtin = 0;
   else if (!strcmp (p, "-fno-builtin"))
     flag_no_builtin = 1;
+  else if ((option_value
+           = skip_leading_substring (p, "-fdump-translation-unit-")))
+    {
+      if (p[22] == '\0')
+       error ("no file specified with -fdump-translation-unit");
+      else
+       flag_dump_translation_unit = option_value;
+    }
   else if (!strcmp (p, "-ansi"))
     goto iso_1990;
   else if (!strcmp (p, "-Werror-implicit-function-declaration"))
@@ -3104,6 +3093,19 @@ init_decl_processing ()
   boolean_true_node = integer_one_node;
   boolean_false_node = integer_zero_node;
 
+  /* With GCC, C99's _Bool is always of size 1.  */
+  c_bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
+  TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE);
+  TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0);
+  TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node;
+  TYPE_PRECISION (c_bool_type_node) = 1;
+  pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"),
+                       c_bool_type_node));
+  c_bool_false_node = build_int_2 (0, 0);
+  TREE_TYPE (c_bool_false_node) = c_bool_type_node;
+  c_bool_true_node = build_int_2 (1, 0);
+  TREE_TYPE (c_bool_true_node) = c_bool_type_node;
+
   string_type_node = build_pointer_type (char_type_node);
   const_string_type_node
     = build_pointer_type (build_type_variant (char_type_node, 1, 0));
@@ -3612,7 +3614,7 @@ finish_decl (decl, init, asmspec_tree)
 {
   register tree type = TREE_TYPE (decl);
   int was_incomplete = (DECL_SIZE (decl) == 0);
-  char *asmspec = 0;
+  const char *asmspec = 0;
 
   /* If a name was specified, get the string.   */
   if (asmspec_tree)
@@ -3749,7 +3751,10 @@ finish_decl (decl, init, asmspec_tree)
       else
        {
          if (asmspec)
-           DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
+           {
+             DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
+             DECL_C_HARD_REGISTER (decl) = 1;
+           }
          add_decl_stmt (decl);
        }
 
@@ -4472,27 +4477,53 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                    }
                }
 
-             /* Convert size to index_type, so that if it is a variable
-                the computations will be done in the proper mode.  */
-             itype = fold (build (MINUS_EXPR, index_type,
-                                  convert (index_type, size),
-                                  convert (index_type, size_one_node)));
-
-             /* If that overflowed, the array is too big.
-                ??? While a size of INT_MAX+1 technically shouldn't cause
-                an overflow (because we subtract 1), the overflow is recorded
-                during the conversion to index_type, before the subtraction.
-                Handling this case seems like an unnecessary complication.  */
-             if (TREE_OVERFLOW (itype))
+             if (integer_zerop (size))
                {
-                 error ("size of array `%s' is too large", name);
-                 type = error_mark_node;
-                 continue;
+                 /* A zero-length array cannot be represented with an
+                    unsigned index type, which is what we'll get with
+                    build_index_type.  Create an open-ended range instead.  */
+                 itype = build_range_type (sizetype, size, NULL_TREE);
                }
+             else
+               {
+                 /* Compute the maximum valid index, that is, size - 1.
+                    Do the calculation in index_type, so that if it is
+                    a variable the computations will be done in the
+                    proper mode.  */
+                 itype = fold (build (MINUS_EXPR, index_type,
+                                      convert (index_type, size),
+                                      convert (index_type, size_one_node)));
+
+                 /* If that overflowed, the array is too big.
+                    ??? While a size of INT_MAX+1 technically shouldn't
+                    cause an overflow (because we subtract 1), the overflow
+                    is recorded during the conversion to index_type, before
+                    the subtraction.  Handling this case seems like an
+                    unnecessary complication.  */
+                 if (TREE_OVERFLOW (itype))
+                   {
+                     error ("size of array `%s' is too large", name);
+                     type = error_mark_node;
+                     continue;
+                   }
+
+                 if (size_varies)
+                   itype = variable_size (itype);
+                 itype = build_index_type (itype);
+               }
+           }
+         else if (decl_context == FIELD)
+           {
+             /* ??? Need to check somewhere that this is a structure
+                and not a union, that this field is last, and that 
+                this structure has at least one other named member.  */
+
+             if (pedantic && !flag_isoc99 && !in_system_header)
+               pedwarn ("ISO C89 does not support flexible array members");
 
-             if (size_varies)
-               itype = variable_size (itype);
-             itype = build_index_type (itype);
+             /* ISO C99 Flexible array members are effectively identical
+                to GCC's zero-length array extension.  */
+             itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
            }
 
 #if 0
@@ -5422,6 +5453,7 @@ finish_struct (t, fieldlist, attributes)
       /* Detect invalid bit-field type.  */
       if (DECL_INITIAL (x)
          && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
+         && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
          && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
        {
          error_with_decl (x, "bit-field `%s' has invalid type");
@@ -5431,6 +5463,7 @@ finish_struct (t, fieldlist, attributes)
       if (DECL_INITIAL (x) && pedantic
          && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
          && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
+         && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node
          /* Accept an enum that's equivalent to int or unsigned int.  */
          && !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
               && (TYPE_PRECISION (TREE_TYPE (x))
@@ -5441,10 +5474,14 @@ finish_struct (t, fieldlist, attributes)
         field widths.  */
       if (DECL_INITIAL (x))
        {
+         int max_width;
+         if (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node)
+           max_width = CHAR_TYPE_SIZE;
+         else
+           max_width = TYPE_PRECISION (TREE_TYPE (x));
          if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
            error_with_decl (x, "negative width in bit-field `%s'");
-         else if (0 < compare_tree_int (DECL_INITIAL (x),
-                                        TYPE_PRECISION (TREE_TYPE (x))))
+         else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
            pedwarn_with_decl (x, "width of `%s' exceeds its type");
          else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
            error_with_decl (x, "zero width for bit-field `%s'");
@@ -5464,7 +5501,8 @@ finish_struct (t, fieldlist, attributes)
                                   "`%s' is narrower than values of its type");
 
              DECL_SIZE (x) = bitsize_int (width);
-             DECL_BIT_FIELD (x) = DECL_C_BIT_FIELD (x) = 1;
+             DECL_BIT_FIELD (x) = 1;
+             SET_DECL_C_BIT_FIELD (x);
 
              if (width == 0)
                {
@@ -6757,7 +6795,7 @@ c_expand_body (fndecl, nested_p)
 
   /* Initialize the RTL code for the function.  */
   current_function_decl = fndecl;
-  init_function_start (fndecl, input_filename, lineno);
+  init_function_start (fndecl, input_filename, DECL_SOURCE_LINE (fndecl));
 
   /* This function is being processed in whole-function mode.  */
   cfun->x_whole_function_mode_p = 1;
@@ -6895,6 +6933,55 @@ c_expand_body (fndecl, nested_p)
       
 }
 \f
+/* Check the declarations given in a for-loop for satisfying the C99
+   constraints.  */
+void
+check_for_loop_decls ()
+{
+  tree t;
+
+  if (!flag_isoc99)
+    {
+      /* If we get here, declarations have been used in a for loop without
+        the C99 for loop scope.  This doesn't make much sense, so don't
+        allow it.  */
+      error ("`for' loop initial declaration used outside C99 mode");
+      return;
+    }
+  /* C99 subclause 6.8.5 paragraph 3:
+
+       [#3]  The  declaration  part  of  a for statement shall only
+       declare identifiers for objects having storage class auto or
+       register.
+
+     It isn't clear whether, in this sentence, "identifiers" binds to
+     "shall only declare" or to "objects" - that is, whether all identifiers
+     declared must be identifiers for objects, or whether the restriction
+     only applies to those that are.  (A question on this in comp.std.c
+     in November 2000 received no answer.)  We implement the strictest
+     interpretation, to avoid creating an extension which later causes
+     problems.  */
+
+  for (t = gettags (); t; t = TREE_CHAIN (t))
+    {
+      if (TREE_PURPOSE (t) != 0)
+       error ("`%s %s' declared in `for' loop initial declaration",
+              (TREE_CODE (TREE_VALUE (t)) == RECORD_TYPE ? "struct"
+               : TREE_CODE (TREE_VALUE (t)) == UNION_TYPE ? "union"
+               : "enum"),
+              IDENTIFIER_POINTER (TREE_PURPOSE (t)));
+    }
+  for (t = getdecls (); t; t = TREE_CHAIN (t))
+    {
+      if (TREE_CODE (t) != VAR_DECL && DECL_NAME (t))
+       error_with_decl (t, "declaration of non-variable `%s' in `for' loop initial declaration");
+      else if (TREE_STATIC (t))
+       error_with_decl (t, "declaration of static variable `%s' in `for' loop initial declaration");
+      else if (DECL_EXTERNAL (t))
+       error_with_decl (t, "declaration of `extern' variable `%s' in `for' loop initial declaration");
+    }
+}
+\f
 /* Save and restore the variables in this file and elsewhere
    that keep track of the progress of compilation of the current function.
    Used for nested functions.  */