OSDN Git Service

* g++.old-deja/g++.benjamin/16077.C: Adjust warnings.
[pf3gnuchains/gcc-fork.git] / gcc / c-common.c
index 75c2911..983cd29 100644 (file)
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "real.h"
 #include "flags.h"
@@ -29,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "c-pragma.h"
 #include "rtl.h"
 #include "ggc.h"
+#include "varray.h"
 #include "expr.h"
 #include "c-common.h"
 #include "diagnostic.h"
@@ -188,11 +191,38 @@ enum c_language_kind c_language;
 
 tree c_global_trees[CTI_MAX];
 
+/* Nonzero if we can read a PCH file now.  */
+
+int allow_pch = 1;
+\f
 /* Switches common to the C front ends.  */
 
 /* Nonzero if prepreprocessing only.  */
+
 int flag_preprocess_only;
 
+/* Nonzero means don't output line number information.  */
+
+char flag_no_line_commands;
+
+/* Nonzero causes -E output not to be done, but directives such as
+   #define that have side effects are still obeyed.  */
+
+char flag_no_output;
+
+/* Nonzero means dump macros in some fashion.  */
+
+char flag_dump_macros;
+
+/* Nonzero means pass #include lines through to the output.  */
+
+char flag_dump_includes;
+
+/* The file name to which we should write a precompiled header, or
+   NULL if no header will be written in this compile.  */
+
+const char *pch_file;
+
 /* Nonzero if an ISO standard was selected.  It rejects macros in the
    user's namespace.  */
 int flag_iso;
@@ -860,7 +890,7 @@ const struct attribute_spec c_common_attribute_table[] =
 };
 
 /* Give the specifications for the format attributes, used by C and all
-   descendents.  */
+   descendants.  */
 
 const struct attribute_spec c_common_format_attribute_table[] =
 {
@@ -1048,13 +1078,18 @@ finish_fname_decls ()
   
   if (body)
     {
-      /* They were called into existence, so add to statement tree.  */
-      body = chainon (body,
-                     TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)));
-      body = build_stmt (COMPOUND_STMT, body);
-      
-      COMPOUND_STMT_NO_SCOPE (body) = 1;
-      TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)) = body;
+      /* They were called into existence, so add to statement tree.  Add
+        the DECL_STMTs inside the outermost scope.  */
+      tree *p = &DECL_SAVED_TREE (current_function_decl);
+      /* Skip the dummy EXPR_STMT and any EH_SPEC_BLOCK.  */
+      while (TREE_CODE (*p) != COMPOUND_STMT)
+       p = &TREE_CHAIN (*p);
+      p = &COMPOUND_BODY (*p);
+      if (TREE_CODE (*p) == SCOPE_STMT)
+       p = &TREE_CHAIN (*p);
+
+      body = chainon (body, *p);
+      *p = body;
     }
   
   for (ix = 0; fname_vars[ix].decl; ix++)
@@ -1077,7 +1112,7 @@ finish_fname_decls ()
   saved_function_name_decls = stack;
 }
 
-/* Return the text name of the current function, suitable prettified
+/* Return the text name of the current function, suitably prettified
    by PRETTY_P.  */
 
 const char *
@@ -1161,7 +1196,7 @@ fname_decl (rid, id)
     }
   if (!ix && !current_function_decl)
     pedwarn_with_decl (decl, "`%s' is not defined outside of function scope");
-  
+
   return decl;
 }
 
@@ -2800,6 +2835,7 @@ c_common_truthvalue_conversion (expr)
     case ABS_EXPR:
     case FLOAT_EXPR:
     case FFS_EXPR:
+    case POPCOUNT_EXPR:
       /* These don't change whether an object is nonzero or zero.  */
       return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0));
 
@@ -2977,7 +3013,7 @@ c_common_get_alias_set (t)
   if (! TYPE_P (t))
     return -1;
 
-  /* The C standard guarantess that any object may be accessed via an
+  /* The C standard guarantees that any object may be accessed via an
      lvalue that has character type.  */
   if (t == char_type_node
       || t == signed_char_type_node
@@ -3090,7 +3126,7 @@ c_sizeof_or_alignof_type (type, op, complain)
      TYPE_IS_SIZETYPE means that certain things (like overflow) will
      never happen.  However, this node should really have type
      `size_t', which is just a typedef for an ordinary integer type.  */
-  value = fold (build1 (NOP_EXPR, c_size_type_node, value));
+  value = fold (build1 (NOP_EXPR, size_type_node, value));
   my_friendly_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (value)), 20001021);
   
   return value;
@@ -3141,7 +3177,7 @@ c_alignof_expr (expr)
   else
     return c_alignof (TREE_TYPE (expr));
 
-  return fold (build1 (NOP_EXPR, c_size_type_node, t));
+  return fold (build1 (NOP_EXPR, size_type_node, t));
 }
 \f
 /* Handle C and C++ default attributes.  */
@@ -3185,6 +3221,7 @@ c_common_nodes_and_builtins ()
 #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
 #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
 #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
+#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
 #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
 #include "builtin-types.def"
 #undef DEF_PRIMITIVE_TYPE
@@ -3196,6 +3233,7 @@ c_common_nodes_and_builtins ()
 #undef DEF_FUNCTION_TYPE_VAR_0
 #undef DEF_FUNCTION_TYPE_VAR_1
 #undef DEF_FUNCTION_TYPE_VAR_2
+#undef DEF_FUNCTION_TYPE_VAR_3
 #undef DEF_POINTER_TYPE
     BT_LAST
   };
@@ -3284,10 +3322,10 @@ c_common_nodes_and_builtins ()
   /* `unsigned long' is the standard type for sizeof.
      Note that stddef.h uses `unsigned long',
      and this must agree, even if long and int are the same size.  */
-  c_size_type_node =
+  size_type_node =
     TREE_TYPE (identifier_global_value (get_identifier (SIZE_TYPE)));
-  signed_size_type_node = c_common_signed_type (c_size_type_node);
-  set_sizetype (c_size_type_node);
+  signed_size_type_node = c_common_signed_type (size_type_node);
+  set_sizetype (size_type_node);
 
   build_common_tree_nodes_2 (flag_short_double);
 
@@ -3390,8 +3428,6 @@ c_common_nodes_and_builtins ()
     = build_pointer_type (build_qualified_type
                          (char_type_node, TYPE_QUAL_CONST));
 
-  (*targetm.init_builtins) ();
-
   /* This is special for C++ so functions can be overloaded.  */
   wchar_type_node = get_identifier (MODIFIED_WCHAR_TYPE);
   wchar_type_node = TREE_TYPE (identifier_global_value (wchar_type_node));
@@ -3515,6 +3551,19 @@ c_common_nodes_and_builtins ()
                  tree_cons (NULL_TREE,                         \
                             builtin_types[(int) ARG2],         \
                             NULL_TREE)));
+
+#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3)                \
+   builtin_types[(int) ENUM]                                           \
+    = build_function_type                                              \
+      (builtin_types[(int) RETURN],                                    \
+       tree_cons (NULL_TREE,                                           \
+                 builtin_types[(int) ARG1],                            \
+                 tree_cons (NULL_TREE,                                 \
+                            builtin_types[(int) ARG2],                 \
+                            tree_cons (NULL_TREE,                      \
+                                       builtin_types[(int) ARG3],      \
+                                       NULL_TREE))));
+
 #define DEF_POINTER_TYPE(ENUM, TYPE)                   \
   builtin_types[(int) ENUM]                            \
     = build_pointer_type (builtin_types[(int) TYPE]);
@@ -3526,13 +3575,15 @@ c_common_nodes_and_builtins ()
 #undef DEF_FUNCTION_TYPE_4
 #undef DEF_FUNCTION_TYPE_VAR_0
 #undef DEF_FUNCTION_TYPE_VAR_1
+#undef DEF_FUNCTION_TYPE_VAR_2
+#undef DEF_FUNCTION_TYPE_VAR_3
 #undef DEF_POINTER_TYPE
 
   if (!c_attrs_initialized)
     c_init_attributes ();
 
 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE,                  \
-                   BOTH_P, FALLBACK_P, NONANSI_P, ATTRS)               \
+                   BOTH_P, FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT)     \
   if (NAME)                                                            \
     {                                                                  \
       tree decl;                                                       \
@@ -3559,10 +3610,14 @@ c_common_nodes_and_builtins ()
                                   built_in_attributes[(int) ATTRS]);   \
                                                                        \
       built_in_decls[(int) ENUM] = decl;                               \
+      if (IMPLICIT)                                                    \
+        implicit_built_in_decls[(int) ENUM] = decl;                    \
     }                                                                  
 #include "builtins.def"
 #undef DEF_BUILTIN
 
+  (*targetm.init_builtins) ();
+
   main_identifier_node = get_identifier ("main");
 }
 
@@ -4490,9 +4545,9 @@ c_expand_builtin_printf (arglist, target, tmode, modifier, ignore, unlocked)
      int unlocked;
 {
   tree fn_putchar = unlocked ?
-    built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] : built_in_decls[BUILT_IN_PUTCHAR];
+    implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] : implicit_built_in_decls[BUILT_IN_PUTCHAR];
   tree fn_puts = unlocked ?
-    built_in_decls[BUILT_IN_PUTS_UNLOCKED] : built_in_decls[BUILT_IN_PUTS];
+    implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED] : implicit_built_in_decls[BUILT_IN_PUTS];
   tree fn, format_arg, stripped_string;
 
   /* If the return value is used, or the replacement _DECL isn't
@@ -4594,9 +4649,9 @@ c_expand_builtin_fprintf (arglist, target, tmode, modifier, ignore, unlocked)
      int unlocked;
 {
   tree fn_fputc = unlocked ?
-    built_in_decls[BUILT_IN_FPUTC_UNLOCKED] : built_in_decls[BUILT_IN_FPUTC];
+    implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED] : implicit_built_in_decls[BUILT_IN_FPUTC];
   tree fn_fputs = unlocked ?
-    built_in_decls[BUILT_IN_FPUTS_UNLOCKED] : built_in_decls[BUILT_IN_FPUTS];
+    implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED] : implicit_built_in_decls[BUILT_IN_FPUTS];
   tree fn, format_arg, stripped_string;
 
   /* If the return value is used, or the replacement _DECL isn't
@@ -4877,6 +4932,18 @@ builtin_define_float_constants (name_prefix, fp_suffix, type)
       sprintf (buf, "0.0%s", fp_suffix);
       builtin_define_with_value (name, buf, 0);
     }
+
+  /* For C++ std::numeric_limits<T>::has_infinity.  */
+  sprintf (name, "__%s_HAS_INFINITY__", name_prefix);
+  builtin_define_with_int_value (name, 
+                                MODE_HAS_INFINITIES (TYPE_MODE (type)));
+  /* For C++ std::numeric_limits<T>::has_quiet_NaN.  We do not have a
+     predicate to distinguish a target that has both quiet and
+     signalling NaNs from a target that has only quiet NaNs or only
+     signalling NaNs, so we assume that a target that has any kind of
+     NaN has quiet NaNs.  */
+  sprintf (name, "__%s_HAS_QUIET_NAN__", name_prefix);
+  builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type)));
 }
 
 /* Hook that registers front end and target-specific built-ins.  */
@@ -5106,8 +5173,9 @@ builtin_define_with_hex_fp_value (macro, type, digits, hex_str, fp_suffix)
   cpp_define (parse_in, buf);
 }
 
-/* Define MAX for TYPE based on the precision of the type, which is assumed
-   to be signed.  IS_LONG is 1 for type "long" and 2 for "long long".  */
+/* Define MAX for TYPE based on the precision of the type.  IS_LONG is
+   1 for type "long" and 2 for "long long".  We have to handle
+   unsigned types, since wchar_t might be unsigned.  */
 
 static void
 builtin_define_type_max (macro, type, is_long)
@@ -5115,41 +5183,37 @@ builtin_define_type_max (macro, type, is_long)
      tree type;
      int is_long;
 {
-  const char *value;
+  static const char *const values[]
+    = { "127", "255",
+       "32767", "65535",
+       "2147483647", "4294967295",
+       "9223372036854775807", "18446744073709551615",
+       "170141183460469231731687303715884105727",
+       "340282366920938463463374607431768211455" };
+  static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" };
+
+  const char *value, *suffix;
   char *buf;
-  size_t mlen, vlen, extra;
+  size_t idx;
 
   /* Pre-rendering the values mean we don't have to futz with printing a
      multi-word decimal value.  There are also a very limited number of
      precisions that we support, so it's really a waste of time.  */
   switch (TYPE_PRECISION (type))
     {
-    case 8:
-      value = "127";
-      break;
-    case 16:
-      value = "32767";
-      break;
-    case 32:
-      value = "2147483647";
-      break;
-    case 64:
-      value = "9223372036854775807";
-      break;
-    case 128:
-      value = "170141183460469231731687303715884105727";
-      break;
-    default:
-      abort ();
+    case 8:    idx = 0; break;
+    case 16:   idx = 2; break;
+    case 32:   idx = 4; break;
+    case 64:   idx = 6; break;
+    case 128:  idx = 8; break;
+    default:    abort ();
     }
 
-  mlen = strlen (macro);
-  vlen = strlen (value);
-  extra = 2 + is_long;
-  buf = alloca (mlen + vlen + extra);
+  value = values[idx + TREE_UNSIGNED (type)];
+  suffix = suffixes[is_long * 2 + TREE_UNSIGNED (type)];
 
-  sprintf (buf, "%s=%s%s", macro, value,
-          (is_long == 1 ? "L" : is_long == 2 ? "LL" : ""));
+  buf = alloca (strlen (macro) + 1 + strlen (value) + strlen (suffix) + 1);
+  sprintf (buf, "%s=%s%s", macro, value, suffix);
 
   cpp_define (parse_in, buf);
 }
@@ -5386,16 +5450,19 @@ handle_always_inline_attribute (node, name, args, flags, no_add_attrs)
    struct attribute_spec.handler.  */
 
 static tree
-handle_used_attribute (node, name, args, flags, no_add_attrs)
-     tree *node;
+handle_used_attribute (pnode, name, args, flags, no_add_attrs)
+     tree *pnode;
      tree name;
      tree args ATTRIBUTE_UNUSED;
      int flags ATTRIBUTE_UNUSED;
      bool *no_add_attrs;
 {
-  if (TREE_CODE (*node) == FUNCTION_DECL)
-    TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (*node))
-      = TREE_USED (*node) = 1;
+  tree node = *pnode;
+
+  if (TREE_CODE (node) == FUNCTION_DECL
+      || (TREE_CODE (node) == VAR_DECL && TREE_STATIC (node)))
+    TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (node))
+      = TREE_USED (node) = 1;
   else
     {
       warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
@@ -5604,6 +5671,7 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs)
       int len = strlen (p);
       enum machine_mode mode = VOIDmode;
       tree typefm;
+      tree ptr_type;
 
       if (len > 4 && p[0] == '_' && p[1] == '_'
          && p[len - 1] == '_' && p[len - 2] == '_')
@@ -5633,6 +5701,10 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs)
       else if (0 == (typefm = (*lang_hooks.types.type_for_mode)
                     (mode, TREE_UNSIGNED (type))))
        error ("no data type for mode `%s'", p);
+      else if ((TREE_CODE (type) == POINTER_TYPE
+               || TREE_CODE (type) == REFERENCE_TYPE)
+              && !(*targetm.valid_pointer_mode) (mode))
+       error ("invalid pointer mode `%s'", p);
       else
        {
          /* If this is a vector, make sure we either have hardware
@@ -5645,6 +5717,19 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs)
              return NULL_TREE;
            }
 
+         if (TREE_CODE (type) == POINTER_TYPE)
+           {
+             ptr_type = build_pointer_type_for_mode (TREE_TYPE (type),
+                                                     mode);
+             *node = ptr_type;
+           }
+         else if (TREE_CODE (type) == REFERENCE_TYPE)
+           {
+             ptr_type = build_reference_type_for_mode (TREE_TYPE (type),
+                                                       mode);
+             *node = ptr_type;
+           }
+         else
          *node = typefm;
          /* No need to layout the type here.  The caller should do this.  */
        }
@@ -5891,9 +5976,10 @@ handle_visibility_attribute (node, name, args, flags, no_add_attrs)
        }
       if (strcmp (TREE_STRING_POINTER (id), "hidden")
          && strcmp (TREE_STRING_POINTER (id), "protected")
-         && strcmp (TREE_STRING_POINTER (id), "internal"))
+         && strcmp (TREE_STRING_POINTER (id), "internal")
+         && strcmp (TREE_STRING_POINTER (id), "default"))
        {
-         error ("visibility arg must be one of \"hidden\", \"protected\" or \"internal\"");
+         error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
          *no_add_attrs = true;
          return NULL_TREE;
        }
@@ -6123,7 +6209,7 @@ handle_deprecated_attribute (node, name, args, flags, no_add_attrs)
    The normal mechanism to prevent duplicates is to use type_hash_canon, but
    since we want to distinguish types that are essentially identical (except
    for their debug representation), we use a local list here.  */
-static tree vector_type_node_list = 0;
+static GTY(()) tree vector_type_node_list = 0;
 
 /* Handle a "vector_size" attribute; arguments as in
    struct attribute_spec.handler.  */
@@ -6322,7 +6408,7 @@ handle_nonnull_attribute (node, name, args, flags, no_add_attrs)
   unsigned HOST_WIDE_INT attr_arg_num;
 
   /* If no arguments are specified, all pointer arguments should be
-     non-null.  Veryify a full prototype is given so that the arguments
+     non-null.  Verify a full prototype is given so that the arguments
      will have the correct types when we actually check them later.  */
   if (! args)
     {