OSDN Git Service

PR c++/34513
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index e265f67..033ff2e 100644 (file)
@@ -375,7 +375,7 @@ static GTY((deletable)) struct c_binding *binding_freelist;
   struct c_scope *s_ = (scope);                                \
   tree d_ = (decl);                                    \
   if (s_->list##_last)                                 \
-    TREE_CHAIN (s_->list##_last) = d_;                 \
+    BLOCK_CHAIN (s_->list##_last) = d_;                        \
   else                                                 \
     s_->list = d_;                                     \
   s_->list##_last = d_;                                        \
@@ -386,7 +386,7 @@ static GTY((deletable)) struct c_binding *binding_freelist;
   struct c_scope *t_ = (tscope);                               \
   struct c_scope *f_ = (fscope);                               \
   if (t_->to##_last)                                           \
-    TREE_CHAIN (t_->to##_last) = f_->from;                     \
+    BLOCK_CHAIN (t_->to##_last) = f_->from;                    \
   else                                                         \
     t_->to = f_->from;                                         \
   t_->to##_last = f_->from##_last;                             \
@@ -407,7 +407,7 @@ static tree lookup_name_in_scope (tree, struct c_scope *);
 static tree c_make_fname_decl (tree, int);
 static tree grokdeclarator (const struct c_declarator *,
                            struct c_declspecs *,
-                           enum decl_context, bool, tree *,
+                           enum decl_context, bool, tree *, tree *,
                            enum deprecated_states);
 static tree grokparms (struct c_arg_info *, bool);
 static void layout_array_type (tree);
@@ -693,7 +693,7 @@ pop_scope (void)
       TREE_USED (block) = 1;
 
       /* In each subblock, record that this is its superior.  */
-      for (p = scope->blocks; p; p = TREE_CHAIN (p))
+      for (p = scope->blocks; p; p = BLOCK_CHAIN (p))
        BLOCK_SUPERCONTEXT (p) = block;
 
       BLOCK_VARS (block) = 0;
@@ -1670,6 +1670,9 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
        }
     }
 
+  /* Keep the old rtl since we can safely use it.  */
+  if (HAS_RTL_P (olddecl))
+    COPY_DECL_RTL (olddecl, newdecl);
 
   /* Merge the type qualifiers.  */
   if (TREE_READONLY (newdecl))
@@ -2071,10 +2074,6 @@ pushdecl (tree x)
   struct c_binding *b;
   bool nested = false;
 
-  /* Functions need the lang_decl data.  */
-  if (TREE_CODE (x) == FUNCTION_DECL && !DECL_LANG_SPECIFIC (x))
-    DECL_LANG_SPECIFIC (x) = GGC_CNEW (struct lang_decl);
-
   /* Must set DECL_CONTEXT for everything not at file scope or
      DECL_FILE_SCOPE_P won't work.  Local externs don't count
      unless they have initializers (which generate code).  */
@@ -2846,7 +2845,6 @@ c_builtin_function (tree decl)
   tree   id = DECL_NAME (decl);
 
   const char *name = IDENTIFIER_POINTER (id);
-  DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl);
   C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0);
 
   /* Should never be called on a symbol with a preexisting meaning.  */
@@ -3086,20 +3084,13 @@ build_array_declarator (tree expr, struct c_declspecs *quals, bool static_p,
 
 /* Set the contained declarator of an array declarator.  DECL is the
    declarator, as constructed by build_array_declarator; INNER is what
-   appears on the left of the [].  ABSTRACT_P is true if it is an
-   abstract declarator, false otherwise; this is used to reject static
-   and type qualifiers in abstract declarators, where they are not in
-   the C99 grammar (subject to possible change in DR#289).  */
+   appears on the left of the [].  */
 
 struct c_declarator *
 set_array_declarator_inner (struct c_declarator *decl,
-                           struct c_declarator *inner, bool abstract_p)
+                           struct c_declarator *inner)
 {
   decl->declarator = inner;
-  if (abstract_p && (decl->u.array.quals != TYPE_UNQUALIFIED
-                    || decl->u.array.attrs != NULL_TREE
-                    || decl->u.array.static_p))
-    error ("static or type qualifiers in abstract declarator");
   return decl;
 }
 
@@ -3141,7 +3132,7 @@ groktypename (struct c_type_name *type_name)
   type_name->specs->attrs = NULL_TREE;
 
   type = grokdeclarator (type_name->declarator, type_name->specs, TYPENAME,
-                        false, NULL, DEPRECATED_NORMAL);
+                        false, NULL, &attrs, DEPRECATED_NORMAL);
 
   /* Apply attributes.  */
   decl_attributes (&type, attrs, 0);
@@ -3178,7 +3169,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
     deprecated_state = DEPRECATED_SUPPRESS;
 
   decl = grokdeclarator (declarator, declspecs,
-                        NORMAL, initialized, NULL,
+                        NORMAL, initialized, NULL, &attributes,
                         deprecated_state);
   if (!decl)
     return 0;
@@ -3667,10 +3658,11 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
 tree
 grokparm (const struct c_parm *parm)
 {
+  tree attrs = parm->attrs;
   tree decl = grokdeclarator (parm->declarator, parm->specs, PARM, false,
-                             NULL, DEPRECATED_NORMAL);
+                             NULL, &attrs, DEPRECATED_NORMAL);
 
-  decl_attributes (&decl, parm->attrs, 0);
+  decl_attributes (&decl, attrs, 0);
 
   return decl;
 }
@@ -3681,11 +3673,12 @@ grokparm (const struct c_parm *parm)
 void
 push_parm_decl (const struct c_parm *parm)
 {
+  tree attrs = parm->attrs;
   tree decl;
 
   decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, NULL,
-                        DEPRECATED_NORMAL);
-  decl_attributes (&decl, parm->attrs, 0);
+                        &attrs, DEPRECATED_NORMAL);
+  decl_attributes (&decl, attrs, 0);
 
   decl = pushdecl (decl);
 
@@ -3856,10 +3849,7 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
       && type_mv != boolean_type_node)
     pedwarn ("type of bit-field %qs is a GCC extension", name);
 
-  if (type_mv == boolean_type_node)
-    max_width = CHAR_TYPE_SIZE;
-  else
-    max_width = TYPE_PRECISION (*type);
+  max_width = TYPE_PRECISION (*type);
 
   if (0 < compare_tree_int (*width, max_width))
     {
@@ -3957,6 +3947,9 @@ warn_variable_length_array (const char *name, tree size)
    INITIALIZED is true if the decl has an initializer.
    WIDTH is non-NULL for bit-fields, and is a pointer to an INTEGER_CST node
    representing the width of the bit-field.
+   DECL_ATTRS points to the list of attributes that should be added to this
+     decl.  Any nested attributes that belong on the decl itself will be
+     added to this list.
    DEPRECATED_STATE is a deprecated_states value indicating whether
    deprecation warnings should be suppressed.
 
@@ -3971,7 +3964,7 @@ static tree
 grokdeclarator (const struct c_declarator *declarator,
                struct c_declspecs *declspecs,
                enum decl_context decl_context, bool initialized, tree *width,
-               enum deprecated_states deprecated_state)
+               tree *decl_attrs, enum deprecated_states deprecated_state)
 {
   tree type = declspecs->type;
   bool threadp = declspecs->thread_p;
@@ -4615,6 +4608,7 @@ grokdeclarator (const struct c_declarator *declarator,
          gcc_unreachable ();
        }
     }
+  *decl_attrs = chainon (returned_attrs, *decl_attrs);
 
   /* Now TYPE has the actual type, apart from any qualifiers in
      TYPE_QUALS.  */
@@ -4647,9 +4641,9 @@ grokdeclarator (const struct c_declarator *declarator,
       if (type_quals)
        type = c_build_qualified_type (type, type_quals);
       decl = build_decl (TYPE_DECL, declarator->u.id, type);
+      DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
       if (declspecs->explicit_signed_p)
        C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
-      decl_attributes (&decl, returned_attrs, 0);
       if (declspecs->inline_p)
        pedwarn ("typedef %q+D declared %<inline%>", decl);
       return decl;
@@ -4669,7 +4663,6 @@ grokdeclarator (const struct c_declarator *declarator,
        pedwarn ("ISO C forbids const or volatile function types");
       if (type_quals)
        type = c_build_qualified_type (type, type_quals);
-      decl_attributes (&type, returned_attrs, 0);
       return type;
     }
 
@@ -4744,6 +4737,7 @@ grokdeclarator (const struct c_declarator *declarator,
        type_as_written = type;
 
        decl = build_decl (PARM_DECL, declarator->u.id, type);
+       DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
        if (size_varies)
          C_DECL_VARIABLE_SIZE (decl) = 1;
 
@@ -4783,6 +4777,7 @@ grokdeclarator (const struct c_declarator *declarator,
          }
        type = c_build_qualified_type (type, type_quals);
        decl = build_decl (FIELD_DECL, declarator->u.id, type);
+       DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
        DECL_NONADDRESSABLE_P (decl) = bitfield;
        if (bitfield && !declarator->u.id)
          TREE_NO_WARNING (decl) = 1;
@@ -4819,10 +4814,9 @@ grokdeclarator (const struct c_declarator *declarator,
          }
 
        decl = build_decl (FUNCTION_DECL, declarator->u.id, type);
+       DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
        decl = build_decl_attribute_variant (decl, decl_attr);
 
-       DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl);
-
        if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl))
          pedwarn ("ISO C forbids qualified function types");
 
@@ -4987,8 +4981,6 @@ grokdeclarator (const struct c_declarator *declarator,
      name of a variable.  Thus, if it's known before this, die horribly.  */
     gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl));
 
-    decl_attributes (&decl, returned_attrs, 0);
-
     return decl;
   }
 }
@@ -5390,6 +5382,7 @@ start_struct (enum tree_code code, tree name)
 /* Process the specs, declarator and width (NULL if omitted)
    of a structure component, returning a FIELD_DECL node.
    WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node.
+   DECL_ATTRS is as for grokdeclarator.
 
    This is done during the parsing of the struct declaration.
    The FIELD_DECL nodes are chained together and the lot of them
@@ -5397,7 +5390,7 @@ start_struct (enum tree_code code, tree name)
 
 tree
 grokfield (struct c_declarator *declarator, struct c_declspecs *declspecs,
-          tree width)
+          tree width, tree *decl_attrs)
 {
   tree value;
 
@@ -5450,7 +5443,8 @@ grokfield (struct c_declarator *declarator, struct c_declspecs *declspecs,
     }
 
   value = grokdeclarator (declarator, declspecs, FIELD, false,
-                         width ? &width : NULL, DEPRECATED_NORMAL);
+                         width ? &width : NULL, decl_attrs,
+                         DEPRECATED_NORMAL);
 
   finish_decl (value, NULL_TREE, NULL_TREE);
   DECL_INITIAL (value) = width;
@@ -6091,7 +6085,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
   c_break_label = c_cont_label = size_zero_node;
 
   decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, true, NULL,
-                         DEPRECATED_NORMAL);
+                         &attributes, DEPRECATED_NORMAL);
 
   /* If the declarator is not suitable for a function definition,
      cause a syntax error.  */
@@ -6634,7 +6628,7 @@ store_parm_decls (void)
   gen_aux_info_record (fndecl, 1, 0, proto);
 
   /* Initialize the RTL code for the function.  */
-  allocate_struct_function (fndecl);
+  allocate_struct_function (fndecl, false);
 
   /* Begin the statement tree for this function.  */
   DECL_SAVED_TREE (fndecl) = push_stmt_list ();
@@ -6799,7 +6793,7 @@ finish_function (void)
             This should be cleaned up later and this conditional removed.  */
          if (cgraph_global_info_ready)
            {
-             c_expand_body (fndecl);
+             cgraph_add_new_function (fndecl, false);
              return;
            }
 
@@ -6820,7 +6814,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
@@ -7773,9 +7767,12 @@ finish_declspecs (struct c_declspecs *specs)
   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)
+       {
+         error ("%<_Sat%> is used without %<_Fract%> or %<_Accum%>");
+         specs->typespec_word = cts_fract;
+       }
+      else if (specs->long_p || specs->short_p
+              || specs->signed_p || specs->unsigned_p)
        {
          specs->typespec_word = cts_int;
        }