OSDN Git Service

* loop-unroll.c (analyze_insns_in_loop): Remove preheader.
[pf3gnuchains/gcc-fork.git] / gcc / c-common.c
index a699cbc..d26c8b1 100644 (file)
@@ -1,6 +1,6 @@
 /* Subroutines shared by all languages that are variants of C.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -269,7 +269,6 @@ int flag_const_strings;
 /* Nonzero means to treat bitfields as signed unless they say `unsigned'.  */
 
 int flag_signed_bitfields = 1;
-int explicit_flag_signed_bitfields;
 
 /* Nonzero means warn about deprecated conversion from string constant to
    `char *'.  */
@@ -483,14 +482,6 @@ tree *ridpointers;
 
 tree (*make_fname_decl) (tree, int);
 
-/* If non-NULL, the address of a language-specific function that
-   returns 1 for language-specific statement codes.  */
-int (*lang_statement_code_p) (enum tree_code);
-
-/* If non-NULL, the address of a language-specific function that takes
-   any action required right before expand_function_end is called.  */
-void (*lang_expand_function_end) (void);
-
 /* Nonzero means the expression being parsed will never be evaluated.
    This is a count, since unevaluated expressions can nest.  */
 int skip_evaluation;
@@ -546,6 +537,7 @@ static tree handle_tls_model_attribute (tree *, tree, tree, int,
 static tree handle_no_instrument_function_attribute (tree *, tree,
                                                     tree, int, bool *);
 static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
+static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
 static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
                                             bool *);
 static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
@@ -616,6 +608,8 @@ const struct attribute_spec c_common_attribute_table[] =
                              handle_no_instrument_function_attribute },
   { "malloc",                 0, 0, true,  false, false,
                              handle_malloc_attribute },
+  { "returns_twice",          0, 0, true,  false, false,
+                             handle_returns_twice_attribute },
   { "no_stack_limit",         0, 0, true,  false, false,
                              handle_no_limit_stack_attribute },
   { "pure",                   0, 0, true,  false, false,
@@ -871,12 +865,7 @@ fix_string_type (tree value)
   i_type = build_index_type (build_int_cst (NULL_TREE, nchars - 1));
   a_type = build_array_type (e_type, i_type);
   if (flag_const_strings)
-    {
-      /* bleah, c_build_qualified_type should set TYPE_MAIN_VARIANT.  */
-      tree qa_type = c_build_qualified_type (a_type, TYPE_QUAL_CONST);
-      TYPE_MAIN_VARIANT (qa_type) = a_type;
-      a_type = qa_type;
-    }
+    a_type = c_build_qualified_type (a_type, TYPE_QUAL_CONST);
 
   TREE_TYPE (value) = a_type;
   TREE_CONSTANT (value) = 1;
@@ -1620,12 +1609,36 @@ c_common_type_for_mode (enum machine_mode mode, int unsignedp)
     return void_type_node;
 
   if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
-    return unsignedp ? make_unsigned_type (mode) : make_signed_type (mode);
+    return (unsignedp
+           ? make_unsigned_type (GET_MODE_PRECISION (mode))
+           : make_signed_type (GET_MODE_PRECISION (mode)));
 
   if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
-    return unsignedp ? make_unsigned_type (mode) : make_signed_type (mode);
+    return (unsignedp
+           ? make_unsigned_type (GET_MODE_PRECISION (mode))
+           : make_signed_type (GET_MODE_PRECISION (mode)));
+
+  if (COMPLEX_MODE_P (mode))
+    {
+      enum machine_mode inner_mode;
+      tree inner_type;
 
-  if (VECTOR_MODE_P (mode))
+      if (mode == TYPE_MODE (complex_float_type_node))
+       return complex_float_type_node;
+      if (mode == TYPE_MODE (complex_double_type_node))
+       return complex_double_type_node;
+      if (mode == TYPE_MODE (complex_long_double_type_node))
+       return complex_long_double_type_node;
+
+      if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp)
+       return complex_integer_type_node;
+
+      inner_mode = GET_MODE_INNER (mode);
+      inner_type = c_common_type_for_mode (inner_mode, unsignedp);
+      if (inner_type != NULL_TREE)
+       return build_complex_type (inner_type);
+    }
+  else if (VECTOR_MODE_P (mode))
     {
       enum machine_mode inner_mode = GET_MODE_INNER (mode);
       tree inner_type = c_common_type_for_mode (inner_mode, unsignedp);
@@ -2326,12 +2339,17 @@ c_common_truthvalue_conversion (tree expr)
     case TRUTH_AND_EXPR:
     case TRUTH_OR_EXPR:
     case TRUTH_XOR_EXPR:
-    case TRUTH_NOT_EXPR:
       if (TREE_TYPE (expr) != truthvalue_type_node)
        return build2 (TREE_CODE (expr), truthvalue_type_node,
                       TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
       return expr;
 
+    case TRUTH_NOT_EXPR:
+      if (TREE_TYPE (expr) != truthvalue_type_node)
+       return build1 (TREE_CODE (expr), truthvalue_type_node,
+                      TREE_OPERAND (expr, 0));
+      return expr;
+
     case ERROR_MARK:
       return expr;
 
@@ -2487,9 +2505,28 @@ c_build_qualified_type (tree type, int type_quals)
     return type;
 
   if (TREE_CODE (type) == ARRAY_TYPE)
-    return build_array_type (c_build_qualified_type (TREE_TYPE (type),
-                                                    type_quals),
-                            TYPE_DOMAIN (type));
+    {
+      tree t;
+      tree element_type = c_build_qualified_type (TREE_TYPE (type),
+                                                 type_quals);
+
+      /* See if we already have an identically qualified type.  */
+      for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+       {
+         if (TYPE_QUALS (strip_array_types (t)) == type_quals
+             && TYPE_NAME (t) == TYPE_NAME (type)
+             && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
+             && attribute_list_equal (TYPE_ATTRIBUTES (t),
+                                      TYPE_ATTRIBUTES (type)))
+           break;
+       }
+      if (!t)
+       {
+         t = build_variant_type_copy (type);
+         TREE_TYPE (t) = element_type;
+       }
+      return t;
+    }
 
   /* A restrict-qualified pointer type must be a pointer to object or
      incomplete type.  Note that the use of POINTER_TYPE_P also allows
@@ -3189,9 +3226,9 @@ c_common_nodes_and_builtins (void)
 
   c_init_attributes ();
 
-#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE,                  \
-                   BOTH_P, FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT)     \
-  if (NAME)                                                            \
+#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
+                   NONANSI_P, ATTRS, IMPLICIT, COND)                   \
+  if (NAME && COND)                                                    \
     {                                                                  \
       tree decl;                                                       \
                                                                        \
@@ -3224,6 +3261,8 @@ c_common_nodes_and_builtins (void)
 #include "builtins.def"
 #undef DEF_BUILTIN
 
+  build_common_builtin_nodes ();
+
   targetm.init_builtins ();
   if (flag_mudflap)
     mudflap_init ();
@@ -3233,7 +3272,7 @@ c_common_nodes_and_builtins (void)
 
 /* Look up the function in built_in_decls that corresponds to DECL
    and set ASMSPEC as its user assembler name.  DECL must be a
-   function decl that declares a builtin. */
+   function decl that declares a builtin.  */
 
 void
 set_builtin_user_assembler_name (tree decl, const char *asmspec)
@@ -3659,7 +3698,7 @@ match_case_to_enum (splay_tree_node node, void *data)
 /* Handle -Wswitch*.  Called from the front end after parsing the switch
    construct.  */
 /* ??? Should probably be somewhere generic, since other languages besides
-   C and C++ would want this.  We'd want to agree on the datastructure,
+   C and C++ would want this.  We'd want to agree on the data structure,
    however, which is a problem.  Alternately, we operate on gimplified
    switch_exprs, which I don't especially like.  At the moment, however,
    C/C++ are the only tree-ssa languages that support enumerations at all,
@@ -3680,7 +3719,7 @@ c_do_switch_warnings (splay_tree cases, tree switch_stmt)
   else
     switch_location = input_location;
 
-  type = SWITCH_TYPE (switch_stmt);
+  type = SWITCH_STMT_TYPE (switch_stmt);
 
   default_node = splay_tree_lookup (cases, (splay_tree_key) NULL);
   if (warn_switch_default && !default_node)
@@ -3692,7 +3731,7 @@ c_do_switch_warnings (splay_tree cases, tree switch_stmt)
      default case, or when -Wswitch-enum was specified.  */
   if (((warn_switch && !default_node) || warn_switch_enum)
       && type && TREE_CODE (type) == ENUMERAL_TYPE
-      && TREE_CODE (SWITCH_COND (switch_stmt)) != INTEGER_CST)
+      && TREE_CODE (SWITCH_STMT_COND (switch_stmt)) != INTEGER_CST)
     {
       tree chain;
 
@@ -4751,6 +4790,24 @@ handle_malloc_attribute (tree *node, tree name, tree ARG_UNUSED (args),
   return NULL_TREE;
 }
 
+/* Handle a "returns_twice" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_returns_twice_attribute (tree *node, tree name, tree ARG_UNUSED (args),
+                        int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) == FUNCTION_DECL)
+    DECL_IS_RETURNS_TWICE (*node) = 1;
+  else
+    {
+      warning ("%qs attribute ignored", IDENTIFIER_POINTER (name));
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Handle a "no_limit_stack" attribute; arguments as in
    struct attribute_spec.handler.  */
 
@@ -5588,6 +5645,27 @@ c_warn_unused_result (tree *top_p)
     }
 }
 
+/* Convert a character from the host to the target execution character
+   set.  cpplib handles this, mostly.  */
+
+HOST_WIDE_INT
+c_common_to_target_charset (HOST_WIDE_INT c)
+{
+  /* Character constants in GCC proper are sign-extended under -fsigned-char,
+     zero-extended under -fno-signed-char.  cpplib insists that characters
+     and character constants are always unsigned.  Hence we must convert
+     back and forth.  */
+  cppchar_t uc = ((cppchar_t)c) & ((((cppchar_t)1) << CHAR_BIT)-1);
+
+  uc = cpp_host_to_exec_charset (parse_in, uc);
+
+  if (flag_signed_char)
+    return ((HOST_WIDE_INT)uc) << (HOST_BITS_PER_WIDE_INT - CHAR_TYPE_SIZE)
+                              >> (HOST_BITS_PER_WIDE_INT - CHAR_TYPE_SIZE);
+  else
+    return uc;
+}
+
 /* Build the result of __builtin_offsetof.  EXPR is a nested sequence of
    component references, with an INDIRECT_REF at the bottom; much like
    the traditional rendering of offsetof as a macro.  Returns the folded