OSDN Git Service

2007-09-06 Laurynas Biveinis <laurynas.biveinis@gmail.com>
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index ce93ac5..bb790a2 100644 (file)
@@ -1819,6 +1819,11 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
 
          DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
            = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
+
+         DECL_DISREGARD_INLINE_LIMITS (newdecl)
+           = DECL_DISREGARD_INLINE_LIMITS (olddecl)
+           = (DECL_DISREGARD_INLINE_LIMITS (newdecl)
+              || DECL_DISREGARD_INLINE_LIMITS (olddecl));
        }
 
       if (DECL_BUILT_IN (olddecl))
@@ -1930,7 +1935,7 @@ duplicate_decls (tree newdecl, tree olddecl)
 
   if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, &oldtype))
     {
-      /* Avoid `unused variable' and other warnings warnings for OLDDECL.  */
+      /* Avoid `unused variable' and other warnings for OLDDECL.  */
       TREE_NO_WARNING (olddecl) = 1;
       return false;
     }
@@ -2028,11 +2033,7 @@ warn_if_shadowing (tree new_decl)
 
     Obviously, we don't want to generate a duplicate ..._TYPE node if
     the TYPE_DECL node that we are now processing really represents a
-    standard built-in type.
-
-    Since all standard types are effectively declared at line zero
-    in the source file, we can easily check to see if we are working
-    on a standard type by checking the current value of lineno.  */
+    standard built-in type.  */
 
 static void
 clone_underlying_type (tree x)
@@ -2811,7 +2812,7 @@ c_make_fname_decl (tree id, int type_dep)
   DECL_ARTIFICIAL (decl) = 1;
 
   init = build_string (length + 1, name);
-  free (CONST_CAST (name));
+  free (CONST_CAST (char *, name));
   TREE_TYPE (init) = type;
   DECL_INITIAL (decl) = init;
 
@@ -4718,6 +4719,8 @@ grokdeclarator (const struct c_declarator *declarator,
              type = c_build_qualified_type (type, type_quals);
            type = build_pointer_type (type);
            type_quals = array_ptr_quals;
+           if (type_quals)
+             type = c_build_qualified_type (type, type_quals);
 
            /* We don't yet implement attributes in this context.  */
            if (array_ptr_attrs != NULL_TREE)
@@ -6775,6 +6778,11 @@ finish_function (void)
   /* Finalize the ELF visibility for the function.  */
   c_determine_visibility (fndecl);
 
+  /* For GNU C extern inline functions disregard inline limits.  */
+  if (DECL_EXTERNAL (fndecl) 
+      && DECL_DECLARED_INLINE_P (fndecl))
+    DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1;
+
   /* Genericize before inlining.  Delay genericizing nested functions
      until their parent function is genericized.  Since finalizing
      requires GENERIC, delay that as well.  */
@@ -6812,7 +6820,7 @@ finish_function (void)
   /* We're leaving the context of this function, so zap cfun.
      It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
      tree_rest_of_compilation.  */
-  cfun = NULL;
+  set_cfun (NULL);
   current_function_decl = NULL;
 }
 \f
@@ -6977,7 +6985,7 @@ current_stmt_tree (void)
    C.  */
 
 int
-anon_aggr_type_p (tree ARG_UNUSED (node))
+anon_aggr_type_p (const_tree ARG_UNUSED (node))
 {
   return 0;
 }
@@ -7134,6 +7142,7 @@ build_null_declspecs (void)
   ret->const_p = false;
   ret->volatile_p = false;
   ret->restrict_p = false;
+  ret->saturating_p = false;
   return ret;
 }
 
@@ -7196,7 +7205,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
        }
       if ((int) i <= (int) RID_LAST_MODIFIER)
        {
-         /* "long", "short", "signed", "unsigned" or "_Complex".  */
+         /* "long", "short", "signed", "unsigned", "_Complex" or "_Sat".  */
          bool dupe = false;
          switch (i)
            {
@@ -7356,9 +7365,55 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
              else if (specs->typespec_word == cts_dfloat128)
                error ("both %<complex%> and %<_Decimal128%> in "
                       "declaration specifiers");
+             else if (specs->typespec_word == cts_fract)
+               error ("both %<complex%> and %<_Fract%> in "
+                      "declaration specifiers");
+             else if (specs->typespec_word == cts_accum)
+               error ("both %<complex%> and %<_Accum%> in "
+                      "declaration specifiers");
+             else if (specs->saturating_p)
+               error ("both %<complex%> and %<_Sat%> in "
+                      "declaration specifiers");
              else
                specs->complex_p = true;
              break;
+           case RID_SAT:
+             dupe = specs->saturating_p;
+             if (pedantic)
+               pedwarn ("ISO C does not support saturating types");
+             if (specs->typespec_word == cts_void)
+               error ("both %<_Sat%> and %<void%> in "
+                      "declaration specifiers");
+             else if (specs->typespec_word == cts_bool)
+               error ("both %<_Sat%> and %<_Bool%> in "
+                      "declaration specifiers");
+             else if (specs->typespec_word == cts_char)
+               error ("both %<_Sat%> and %<char%> in "
+                      "declaration specifiers");
+             else if (specs->typespec_word == cts_int)
+               error ("both %<_Sat%> and %<int%> in "
+                      "declaration specifiers");
+             else if (specs->typespec_word == cts_float)
+               error ("both %<_Sat%> and %<float%> in "
+                      "declaration specifiers");
+             else if (specs->typespec_word == cts_double)
+               error ("both %<_Sat%> and %<double%> in "
+                      "declaration specifiers");
+              else if (specs->typespec_word == cts_dfloat32)
+               error ("both %<_Sat%> and %<_Decimal32%> in "
+                      "declaration specifiers");
+             else if (specs->typespec_word == cts_dfloat64)
+               error ("both %<_Sat%> and %<_Decimal64%> in "
+                      "declaration specifiers");
+             else if (specs->typespec_word == cts_dfloat128)
+               error ("both %<_Sat%> and %<_Decimal128%> in "
+                      "declaration specifiers");
+             else if (specs->complex_p)
+               error ("both %<_Sat%> and %<complex%> in "
+                      "declaration specifiers");
+             else
+               specs->saturating_p = true;
+             break;
            default:
              gcc_unreachable ();
            }
@@ -7370,7 +7425,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
        }
       else
        {
-         /* "void", "_Bool", "char", "int", "float" or "double".  */
+         /* "void", "_Bool", "char", "int", "float", "double", "_Decimal32",
+            "_Decimal64", "_Decimal128", "_Fract" or "_Accum".  */
          if (specs->typespec_word != cts_none)
            {
              error ("two or more data types in declaration specifiers");
@@ -7394,6 +7450,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
              else if (specs->complex_p)
                error ("both %<complex%> and %<void%> in "
                       "declaration specifiers");
+             else if (specs->saturating_p)
+               error ("both %<_Sat%> and %<void%> in "
+                      "declaration specifiers");
              else
                specs->typespec_word = cts_void;
              return specs;
@@ -7413,6 +7472,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
              else if (specs->complex_p)
                error ("both %<complex%> and %<_Bool%> in "
                       "declaration specifiers");
+             else if (specs->saturating_p)
+               error ("both %<_Sat%> and %<_Bool%> in "
+                      "declaration specifiers");
              else
                specs->typespec_word = cts_bool;
              return specs;
@@ -7423,11 +7485,18 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
              else if (specs->short_p)
                error ("both %<short%> and %<char%> in "
                       "declaration specifiers");
+             else if (specs->saturating_p)
+               error ("both %<_Sat%> and %<char%> in "
+                      "declaration specifiers");
              else
                specs->typespec_word = cts_char;
              return specs;
            case RID_INT:
-             specs->typespec_word = cts_int;
+             if (specs->saturating_p)
+               error ("both %<_Sat%> and %<int%> in "
+                      "declaration specifiers");
+             else
+               specs->typespec_word = cts_int;
              return specs;
            case RID_FLOAT:
              if (specs->long_p)
@@ -7442,6 +7511,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
              else if (specs->unsigned_p)
                error ("both %<unsigned%> and %<float%> in "
                       "declaration specifiers");
+             else if (specs->saturating_p)
+               error ("both %<_Sat%> and %<float%> in "
+                      "declaration specifiers");
              else
                specs->typespec_word = cts_float;
              return specs;
@@ -7458,6 +7530,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
              else if (specs->unsigned_p)
                error ("both %<unsigned%> and %<double%> in "
                       "declaration specifiers");
+             else if (specs->saturating_p)
+               error ("both %<_Sat%> and %<double%> in "
+                      "declaration specifiers");
              else
                specs->typespec_word = cts_double;
              return specs;
@@ -7490,6 +7565,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
                 else if (specs->complex_p)
                   error ("both %<complex%> and %<%s%> in "
                          "declaration specifiers", str);
+                else if (specs->saturating_p)
+                  error ("both %<_Sat%> and %<%s%> in "
+                         "declaration specifiers", str);
                else if (i == RID_DFLOAT32)
                  specs->typespec_word = cts_dfloat32;
                else if (i == RID_DFLOAT64)
@@ -7502,6 +7580,27 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
              if (pedantic)
                pedwarn ("ISO C does not support decimal floating point");
              return specs;
+           case RID_FRACT:
+           case RID_ACCUM:
+             {
+               const char *str;
+               if (i == RID_FRACT)
+                 str = "_Fract";
+               else
+                 str = "_Accum";
+                if (specs->complex_p)
+                  error ("both %<complex%> and %<%s%> in "
+                         "declaration specifiers", str);
+               else if (i == RID_FRACT)
+                   specs->typespec_word = cts_fract;
+               else
+                   specs->typespec_word = cts_accum;
+             }
+             if (!targetm.fixed_point_supported_p ())
+               error ("fixed-point types not supported for this target");
+             if (pedantic)
+               pedwarn ("ISO C does not support fixed-point types");
+             return specs;
            default:
              /* ObjC reserved word "id", handled below.  */
              break;
@@ -7673,6 +7772,8 @@ finish_declspecs (struct c_declspecs *specs)
      "_Complex short" is equivalent to "_Complex short int".  */
   if (specs->typespec_word == cts_none)
     {
+      if (specs->saturating_p)
+       error ("%<_Sat%> is used without %<_Fract%> or %<_Accum%>");
       if (specs->long_p || specs->short_p
          || specs->signed_p || specs->unsigned_p)
        {
@@ -7792,6 +7893,88 @@ finish_declspecs (struct c_declspecs *specs)
       else
        specs->type = dfloat128_type_node;
       break;
+    case cts_fract:
+       gcc_assert (!specs->complex_p);
+       if (specs->saturating_p)
+       {
+         if (specs->long_long_p)
+           specs->type = specs->unsigned_p
+                         ? sat_unsigned_long_long_fract_type_node
+                         : sat_long_long_fract_type_node;
+         else if (specs->long_p)
+           specs->type = specs->unsigned_p
+                         ? sat_unsigned_long_fract_type_node
+                         : sat_long_fract_type_node;
+         else if (specs->short_p)
+           specs->type = specs->unsigned_p
+                         ? sat_unsigned_short_fract_type_node
+                         : sat_short_fract_type_node;
+         else
+           specs->type = specs->unsigned_p
+                         ? sat_unsigned_fract_type_node
+                         : sat_fract_type_node;
+          }
+      else
+       {
+         if (specs->long_long_p)
+           specs->type = specs->unsigned_p
+                         ? unsigned_long_long_fract_type_node
+                         : long_long_fract_type_node;
+         else if (specs->long_p)
+           specs->type = specs->unsigned_p
+                         ? unsigned_long_fract_type_node
+                         : long_fract_type_node;
+         else if (specs->short_p)
+           specs->type = specs->unsigned_p
+                         ? unsigned_short_fract_type_node
+                         : short_fract_type_node;
+         else
+           specs->type = specs->unsigned_p
+                         ? unsigned_fract_type_node
+                         : fract_type_node;
+          }
+      break;
+    case cts_accum:
+       gcc_assert (!specs->complex_p);
+       if (specs->saturating_p)
+       {
+         if (specs->long_long_p)
+           specs->type = specs->unsigned_p
+                         ? sat_unsigned_long_long_accum_type_node
+                         : sat_long_long_accum_type_node;
+         else if (specs->long_p)
+           specs->type = specs->unsigned_p
+                         ? sat_unsigned_long_accum_type_node
+                         : sat_long_accum_type_node;
+         else if (specs->short_p)
+           specs->type = specs->unsigned_p
+                         ? sat_unsigned_short_accum_type_node
+                         : sat_short_accum_type_node;
+         else
+           specs->type = specs->unsigned_p
+                         ? sat_unsigned_accum_type_node
+                         : sat_accum_type_node;
+          }
+      else
+       {
+         if (specs->long_long_p)
+           specs->type = specs->unsigned_p
+                         ? unsigned_long_long_accum_type_node
+                         : long_long_accum_type_node;
+         else if (specs->long_p)
+           specs->type = specs->unsigned_p
+                         ? unsigned_long_accum_type_node
+                         : long_accum_type_node;
+         else if (specs->short_p)
+           specs->type = specs->unsigned_p
+                         ? unsigned_short_accum_type_node
+                         : short_accum_type_node;
+         else
+           specs->type = specs->unsigned_p
+                         ? unsigned_accum_type_node
+                         : accum_type_node;
+          }
+      break;
     default:
       gcc_unreachable ();
     }