OSDN Git Service

PR c++/20646
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 44b45fc..e2bd165 100644 (file)
@@ -17,8 +17,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 
 /* Process declarations and symbol lookup for C++ front end.
@@ -114,7 +114,7 @@ static void store_parm_decls (tree);
 static void initialize_local_var (tree, tree);
 static void expand_static_init (tree, tree);
 static tree next_initializable_field (tree);
-static tree reshape_init (tree, tree *);
+static tree reshape_init (tree, tree);
 
 /* Erroneous argument lists can use this *IFF* they do not modify it.  */
 tree error_mark_list;
@@ -128,12 +128,6 @@ tree error_mark_list;
        tree vtable_entry_type;
        tree delta_type_node;
        tree __t_desc_type_node;
-       tree ti_desc_type_node;
-       tree bltn_desc_type_node, ptr_desc_type_node;
-       tree ary_desc_type_node, func_desc_type_node, enum_desc_type_node;
-       tree class_desc_type_node, si_class_desc_type_node, vmi_class_desc_type_node;
-       tree ptm_desc_type_node;
-       tree base_desc_type_node;
 
        tree class_type_node;
        tree unknown_type_node;
@@ -358,7 +352,7 @@ pop_label (tree label, tree old_value)
        {
          location_t location;
 
-         cp_error_at ("label %qD used but not defined", label);
+         error ("label %q+D used but not defined", label);
 #ifdef USE_MAPPED_LOCATION
          location = input_location; /* FIXME want (input_filename, (line)0) */
 #else
@@ -369,7 +363,7 @@ pop_label (tree label, tree old_value)
          define_label (location, DECL_NAME (label));
        }
       else if (warn_unused_label && !TREE_USED (label))
-       cp_warning_at ("label %qD defined but not used", label);
+       warning (0, "label %q+D defined but not used", label);
     }
 
   SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), old_value);
@@ -563,7 +557,7 @@ poplevel (int keep, int reverse, int functionbody)
          && ! TREE_USED (decl)
          && ! DECL_IN_SYSTEM_HEADER (decl)
          && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
-       warning (0, "%Junused variable %qD", decl, decl);
+       warning (0, "unused variable %q+D", decl);
 
   /* Remove declarations for all the DECLs in this level.  */
   for (link = decls; link; link = TREE_CHAIN (link))
@@ -614,7 +608,10 @@ poplevel (int keep, int reverse, int functionbody)
              /* Keep track of what should have happened when we
                 popped the binding.  */
              if (ob && ob->value)
-               DECL_SHADOWED_FOR_VAR (link) = ob->value;
+               {
+                 SET_DECL_SHADOWED_FOR_VAR (link, ob->value);
+                 DECL_HAS_SHADOWED_FOR_VAR_P (link) = 1;
+               }
 
              /* Add it to the list of dead variables in the next
                 outermost binding to that we can remove these when we
@@ -1003,7 +1000,7 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl)
 
   name = DECL_ASSEMBLER_NAME (newdecl);
   pedwarn ("%qD was declared %<extern%> and later %<static%>", newdecl);
-  cp_pedwarn_at ("previous declaration of %qD", olddecl);
+  pedwarn ("previous declaration of %q+D", olddecl);
 }
 
 /* If NEWDECL is a redeclaration of OLDDECL, merge the declarations.
@@ -1051,19 +1048,19 @@ duplicate_decls (tree newdecl, tree olddecl)
               && DECL_UNINLINABLE (olddecl)
               && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
        {
-         warning (OPT_Wattributes, "%Jfunction %qD redeclared as inline",
-                  newdecl, newdecl);
-         warning (OPT_Wattributes, "%Jprevious declaration of %qD "
-                  "with attribute noinline", olddecl, olddecl);
+         warning (OPT_Wattributes, "function %q+D redeclared as inline",
+                  newdecl);
+         warning (OPT_Wattributes, "previous declaration of %q+D "
+                  "with attribute noinline", olddecl);
        }
       else if (DECL_DECLARED_INLINE_P (olddecl)
               && DECL_UNINLINABLE (newdecl)
               && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
        {
-         warning (OPT_Wattributes, "%Jfunction %qD redeclared with "
-                  "attribute noinline", newdecl, newdecl);
-         warning (OPT_Wattributes, "%Jprevious declaration of %qD was inline",
-                  olddecl, olddecl);
+         warning (OPT_Wattributes, "function %q+D redeclared with "
+                  "attribute noinline", newdecl);
+         warning (OPT_Wattributes, "previous declaration of %q+D was inline",
+                  olddecl);
        }
     }
 
@@ -1224,7 +1221,7 @@ duplicate_decls (tree newdecl, tree olddecl)
       error ("%q#D redeclared as different kind of symbol", newdecl);
       if (TREE_CODE (olddecl) == TREE_LIST)
        olddecl = TREE_VALUE (olddecl);
-      cp_error_at ("previous declaration of %q#D", olddecl);
+      error ("previous declaration of %q+#D", olddecl);
 
       return error_mark_node;
     }
@@ -1244,8 +1241,7 @@ duplicate_decls (tree newdecl, tree olddecl)
              || TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
            {
              error ("declaration of template %q#D", newdecl);
-             cp_error_at ("conflicts with previous declaration %q#D",
-                          olddecl);
+             error ("conflicts with previous declaration %q+#D", olddecl);
            }
          else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL
                   && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
@@ -1259,7 +1255,7 @@ duplicate_decls (tree newdecl, tree olddecl)
                                   TREE_TYPE (TREE_TYPE (olddecl))))
            {
              error ("new declaration %q#D", newdecl);
-             cp_error_at ("ambiguates old declaration %q#D", olddecl);
+             error ("ambiguates old declaration %q+#D", olddecl);
            }
          return NULL_TREE;
        }
@@ -1269,13 +1265,13 @@ duplicate_decls (tree newdecl, tree olddecl)
            {
              error ("declaration of C function %q#D conflicts with",
                     newdecl);
-             cp_error_at ("previous declaration %q#D here", olddecl);
+             error ("previous declaration %q+#D here", olddecl);
            }
          else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
                              TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
            {
              error ("new declaration %q#D", newdecl);
-             cp_error_at ("ambiguates old declaration %q#D", olddecl);
+             error ("ambiguates old declaration %q+#D", olddecl);
            }
          else
            return NULL_TREE;
@@ -1283,8 +1279,7 @@ duplicate_decls (tree newdecl, tree olddecl)
       else
        {
          error ("conflicting declaration %q#D", newdecl);
-         cp_error_at ("%qD has a previous declaration as %q#D",
-                      olddecl, olddecl);
+         error ("%q+D has a previous declaration as %q#D", olddecl, olddecl);
          return error_mark_node;
        }
     }
@@ -1337,7 +1332,7 @@ duplicate_decls (tree newdecl, tree olddecl)
         declared as the name of any other entity in any global scope
         of the program.  */
       error ("declaration of namespace %qD conflicts with", newdecl);
-      cp_error_at ("previous declaration of namespace %qD here", olddecl);
+      error ("previous declaration of namespace %q+D here", olddecl);
       return error_mark_node;
     }
   else
@@ -1347,10 +1342,9 @@ duplicate_decls (tree newdecl, tree olddecl)
        {
          error (errmsg, newdecl);
          if (DECL_NAME (olddecl) != NULL_TREE)
-           cp_error_at ((DECL_INITIAL (olddecl)
-                         && namespace_bindings_p ())
-                        ? "%q#D previously defined here"
-                        : "%q#D previously declared here", olddecl);
+           error ((DECL_INITIAL (olddecl) && namespace_bindings_p ())
+                        ? "%q+#D previously defined here"
+                        : "%q+#D previously declared here", olddecl);
          return error_mark_node;
        }
       else if (TREE_CODE (olddecl) == FUNCTION_DECL
@@ -1359,7 +1353,7 @@ duplicate_decls (tree newdecl, tree olddecl)
               && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != NULL_TREE)
        {
          /* Prototype decl follows defn w/o prototype.  */
-         cp_warning_at ("prototype for %q#D", newdecl);
+         warning (0, "prototype for %q+#D", newdecl);
          warning (0, "%Jfollows non-prototype definition here", olddecl);
        }
       else if (TREE_CODE (olddecl) == FUNCTION_DECL
@@ -1372,8 +1366,8 @@ duplicate_decls (tree newdecl, tree olddecl)
            SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
          else
            {
-             cp_error_at ("previous declaration of %q#D with %qL linkage",
-                          olddecl, DECL_LANGUAGE (olddecl));
+             error ("previous declaration of %q+#D with %qL linkage",
+                    olddecl, DECL_LANGUAGE (olddecl));
              error ("conflicts with new declaration with %qL linkage",
                     DECL_LANGUAGE (newdecl));
            }
@@ -1399,14 +1393,13 @@ duplicate_decls (tree newdecl, tree olddecl)
                  {
                    pedwarn ("default argument given for parameter %d of %q#D",
                             i, newdecl);
-                   cp_pedwarn_at ("after previous specification in %q#D",
-                                  olddecl);
+                   pedwarn ("after previous specification in %q+#D", olddecl);
                  }
                else
                  {
                    error ("default argument given for parameter %d of %q#D",
                           i, newdecl);
-                   cp_error_at ("after previous specification in %q#D",
+                   error ("after previous specification in %q+#D",
                                 olddecl);
                  }
              }
@@ -1469,7 +1462,7 @@ duplicate_decls (tree newdecl, tree olddecl)
          && ! (DECL_FRIEND_P (newdecl) || DECL_FRIEND_P (olddecl)))
        {
          warning (0, "redundant redeclaration of %qD in same scope", newdecl);
-         cp_warning_at ("previous declaration of %qD", olddecl);
+         warning (0, "previous declaration of %q+D", olddecl);
        }
     }
 
@@ -1564,7 +1557,7 @@ duplicate_decls (tree newdecl, tree olddecl)
            {
              error ("declaration of %qF throws different exceptions",
                     newdecl);
-             cp_error_at ("than previous declaration %qF", olddecl);
+             error ("than previous declaration %q+F", olddecl);
            }
        }
       TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype;
@@ -1804,8 +1797,8 @@ duplicate_decls (tree newdecl, tree olddecl)
       && DECL_VISIBILITY_SPECIFIED (newdecl)
       && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
     {
-      warning (OPT_Wattributes, "%J%qD: visibility attribute ignored "
-              "because it", newdecl, newdecl);
+      warning (OPT_Wattributes, "%q+D: visibility attribute ignored "
+              "because it", newdecl);
       warning (OPT_Wattributes, "%Jconflicts with previous "
               "declaration here", olddecl);
     }
@@ -1815,6 +1808,13 @@ duplicate_decls (tree newdecl, tree olddecl)
       DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
       DECL_VISIBILITY_SPECIFIED (newdecl) = 1;
     }
+  /* Init priority used to be merged from newdecl to olddecl by the memcpy, 
+     so keep this behavior.  */
+  if (TREE_CODE (newdecl) == VAR_DECL && DECL_HAS_INIT_PRIORITY_P (newdecl))
+    {
+      SET_DECL_INIT_PRIORITY (olddecl, DECL_INIT_PRIORITY (newdecl));
+      DECL_HAS_INIT_PRIORITY_P (olddecl) = 1;
+    }
 
   /* The DECL_LANG_SPECIFIC information in OLDDECL will be replaced
      with that from NEWDECL below.  */
@@ -1829,13 +1829,16 @@ duplicate_decls (tree newdecl, tree olddecl)
     {
       int function_size;
 
-      function_size = sizeof (struct tree_decl);
+      function_size = sizeof (struct tree_decl_common);
 
       memcpy ((char *) olddecl + sizeof (struct tree_common),
              (char *) newdecl + sizeof (struct tree_common),
              function_size - sizeof (struct tree_common));
 
-      if (DECL_TEMPLATE_INSTANTIATION (newdecl))
+      memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
+             (char *) newdecl + sizeof (struct tree_decl_common),
+             sizeof (struct tree_function_decl) - sizeof (struct tree_decl_common));
+      if (DECL_TEMPLATE_INFO (newdecl))
        /* If newdecl is a template instantiation, it is possible that
           the following sequence of events has occurred:
 
@@ -1863,12 +1866,34 @@ duplicate_decls (tree newdecl, tree olddecl)
     }
   else
     {
+      size_t size = tree_code_size (TREE_CODE (olddecl));
       memcpy ((char *) olddecl + sizeof (struct tree_common),
              (char *) newdecl + sizeof (struct tree_common),
-             sizeof (struct tree_decl) - sizeof (struct tree_common)
-             + TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *));
+             sizeof (struct tree_decl_common) - sizeof (struct tree_common));
+      switch (TREE_CODE (olddecl))       
+       {
+       case LABEL_DECL:
+       case VAR_DECL:
+       case RESULT_DECL:
+       case PARM_DECL:
+       case FIELD_DECL:
+       case TYPE_DECL:
+       case CONST_DECL:
+         {
+           memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
+                   (char *) newdecl + sizeof (struct tree_decl_common),
+                   size - sizeof (struct tree_decl_common)
+                   + TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *));
+         }
+         break;
+       default:
+         memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
+                 (char *) newdecl + sizeof (struct tree_decl_common),
+                 sizeof (struct tree_decl_non_common) - sizeof (struct tree_decl_common)
+                 + TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *));
+         break;
+       }
     }
-
   DECL_UID (olddecl) = olddecl_uid;
   if (olddecl_friend)
     DECL_FRIEND_P (olddecl) = 1;
@@ -2157,11 +2182,9 @@ check_previous_goto_1 (tree decl,
            }
 
          if (problem > 1)
-           cp_error_at ("  crosses initialization of %q#D",
-                        new_decls);
+           error ("  crosses initialization of %q+#D", new_decls);
          else
-           cp_pedwarn_at ("  enters scope of non-POD %q#D",
-                          new_decls);
+           pedwarn ("  enters scope of non-POD %q+#D", new_decls);
        }
 
       if (b == level)
@@ -2259,7 +2282,7 @@ check_goto (tree decl)
   if ((lab->in_try_scope || lab->in_catch_scope || lab->bad_decls)
       && !identified)
     {
-      cp_pedwarn_at ("jump to label %qD", decl);
+      pedwarn ("jump to label %q+D", decl);
       pedwarn ("  from here");
       identified = 1;
     }
@@ -2273,9 +2296,9 @@ check_goto (tree decl)
        /* Can't skip init of __exception_info.  */
        error ("%J  enters catch block", b);
       else if (u > 1)
-       cp_error_at ("  skips initialization of %q#D", b);
+       error ("  skips initialization of %q+#D", b);
       else
-       cp_pedwarn_at ("  enters scope of non-POD %q#D", b);
+       pedwarn ("  enters scope of non-POD %q+#D", b);
     }
 
   if (lab->in_try_scope)
@@ -2683,7 +2706,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
          if (complain & tf_error)
            {
              error ("template parameters do not match template");
-             cp_error_at ("%qD declared here", tmpl);
+             error ("%q+D declared here", tmpl);
            }
          return error_mark_node;
        }
@@ -2807,7 +2830,7 @@ record_unknown_type (tree type, const char* name)
   TYPE_MODE (type) = TYPE_MODE (void_type_node);
 }
 
-/* An string for which we should create an IDENTIFIER_NODE at
+/* A string for which we should create an IDENTIFIER_NODE at
    startup.  */
 
 typedef struct predefined_identifier
@@ -3373,17 +3396,14 @@ fixup_anonymous_aggr (tree t)
            if (CLASS_TYPE_P (type))
              {
                if (TYPE_NEEDS_CONSTRUCTING (type))
-                 cp_error_at ("member %q#D with constructor not allowed "
-                              "in anonymous aggregate",
-                              field);
+                 error ("member %q+#D with constructor not allowed "
+                        "in anonymous aggregate", field);
                if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
-                 cp_error_at ("member %q#D with destructor not allowed "
-                              "in anonymous aggregate",
-                              field);
+                 error ("member %q+#D with destructor not allowed "
+                        "in anonymous aggregate", field);
                if (TYPE_HAS_COMPLEX_ASSIGN_REF (type))
-                 cp_error_at ("member %q#D with copy assignment operator "
-                              "not allowed in anonymous aggregate",
-                              field);
+                 error ("member %q+#D with copy assignment operator "
+                        "not allowed in anonymous aggregate", field);
              }
          }
     }
@@ -3509,10 +3529,9 @@ shadow_tag (cp_decl_specifier_seq *declspecs)
 
   if (declspecs->attributes)
     {
-      cp_warning_at ("attribute ignored in declaration of %q#T", t);
-      cp_warning_at ("attribute for %q#T must follow the %qs keyword",
-                    t,
-                    class_key_or_enum_as_string (t));
+      warning (0, "attribute ignored in declaration of %q+#T", t);
+      warning (0, "attribute for %q+#T must follow the %qs keyword",
+              t, class_key_or_enum_as_string (t));
 
     }
 
@@ -3667,7 +3686,7 @@ start_decl (const cp_declarator *declarator,
       && DECL_DECLARED_INLINE_P (decl)
       && DECL_UNINLINABLE (decl)
       && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
-    warning (0, "%Jinline function %qD given attribute noinline", decl, decl);
+    warning (0, "inline function %q+D given attribute noinline", decl);
 
   if (context && COMPLETE_TYPE_P (complete_type (context)))
     {
@@ -3755,7 +3774,7 @@ start_decl (const cp_declarator *declarator,
      produce errors about redefs; to do this we force variables into the
      data segment.  */
   DECL_COMMON (tem) = ((TREE_CODE (tem) != VAR_DECL
-                       || !DECL_THREAD_LOCAL (tem))
+                       || !DECL_THREAD_LOCAL_P (tem))
                       && (flag_conserve_space || ! TREE_PUBLIC (tem)));
 #endif
 
@@ -4051,9 +4070,9 @@ maybe_commonize_var (tree decl)
                 be merged.  */
              TREE_PUBLIC (decl) = 0;
              DECL_COMMON (decl) = 0;
-             cp_warning_at ("sorry: semantics of inline function static "
-                            "data %q#D are wrong (you'll wind up "
-                            "with multiple copies)", decl);
+             warning (0, "sorry: semantics of inline function static "
+                      "data %q+#D are wrong (you'll wind up "
+                      "with multiple copies)", decl);
              warning (0, "%J  you can work around this by removing "
                       "the initializer",
                       decl);
@@ -4084,6 +4103,18 @@ check_for_uninitialized_const_var (tree decl)
     error ("uninitialized const %qD", decl);
 }
 
+\f
+/* Structure holding the current initializer being processed by reshape_init.
+   CUR is a pointer to the current element being processed, END is a pointer
+   after the last element present in the initializer.  */
+typedef struct reshape_iterator_t
+{
+  constructor_elt *cur;
+  constructor_elt *end;
+} reshape_iter;
+
+static tree reshape_init_r (tree, reshape_iter *, bool);
+
 /* FIELD is a FIELD_DECL or NULL.  In the former case, the value
    returned is the next FIELD_DECL (possibly FIELD itself) that can be
    initialized.  If there are no more such fields, the return value
@@ -4101,22 +4132,23 @@ next_initializable_field (tree field)
   return field;
 }
 
-/* Subroutine of reshape_init. Reshape the constructor for an array. INITP
-   is the pointer to the old constructor list (to the CONSTRUCTOR_ELTS of
-   the CONSTRUCTOR we are processing), while NEW_INIT is the CONSTRUCTOR we
-   are building.
-   ELT_TYPE is the element type of the array. MAX_INDEX is an INTEGER_CST
-   representing the size of the array minus one (the maximum index), or
-   NULL_TREE if the array was declared without specifying the size.  */
+/* Subroutine of reshape_init_array and reshape_init_vector, which does
+   the actual work. ELT_TYPE is the element type of the array. MAX_INDEX is an
+   INTEGER_CST representing the size of the array minus one (the maximum index),
+   or NULL_TREE if the array was declared without specifying the size. D is
+   the iterator within the constructor.  */
 
-static bool
-reshape_init_array (tree elt_type, tree max_index,
-                   tree *initp, tree new_init)
+static tree
+reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
 {
+  tree new_init;
   bool sized_array_p = (max_index != NULL_TREE);
   unsigned HOST_WIDE_INT max_index_cst = 0;
   unsigned HOST_WIDE_INT index;
 
+  /* The initializer for an array is always a CONSTRUCTOR.  */
+  new_init = build_constructor (NULL_TREE, NULL);
+
   if (sized_array_p)
     {
       if (host_integerp (max_index, 1))
@@ -4129,104 +4161,181 @@ reshape_init_array (tree elt_type, tree max_index,
 
   /* Loop until there are no more initializers.  */
   for (index = 0;
-       *initp && (!sized_array_p || index <= max_index_cst);
+       d->cur != d->end && (!sized_array_p || index <= max_index_cst);
        ++index)
     {
-      tree element_init;
-      tree designated_index;
+      tree elt_init;
 
-      element_init = reshape_init (elt_type, initp);
-      if (element_init == error_mark_node)
-       return false;
-      TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init);
-      CONSTRUCTOR_ELTS (new_init) = element_init;
-      designated_index = TREE_PURPOSE (element_init);
-      if (designated_index)
+      if (d->cur->index)
        {
          /* Handle array designated initializers (GNU extension).  */
-         if (TREE_CODE (designated_index) == IDENTIFIER_NODE)
+         if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE)
            {
              error ("name %qD used in a GNU-style designated "
-                    "initializer for an array", designated_index);
-             TREE_PURPOSE (element_init) = NULL_TREE;
+                    "initializer for an array", d->cur->index);
            }
          else
            gcc_unreachable ();
        }
+
+      elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false);
+      CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), NULL_TREE, elt_init);
     }
 
-  return true;
+  return new_init;
 }
 
-/* Undo the brace-elision allowed by [dcl.init.aggr] in a
-   brace-enclosed aggregate initializer.
+/* Subroutine of reshape_init_r, processes the initializers for arrays.
+   Parameters are the same of reshape_init_r.  */
 
-   *INITP is one of a list of initializers describing a brace-enclosed
-   initializer for an entity of the indicated aggregate TYPE.  It may
-   not presently match the shape of the TYPE; for example:
+static tree
+reshape_init_array (tree type, reshape_iter *d)
+{
+  tree max_index = NULL_TREE;
 
-     struct S { int a; int b; };
-     struct S a[] = { 1, 2, 3, 4 };
+  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
 
-   Here *INITP will point to TREE_LIST of four elements, rather than a
-   list of two elements, each itself a list of two elements.  This
-   routine transforms INIT from the former form into the latter.  The
-   revised initializer is returned.  */
+  if (TYPE_DOMAIN (type))
+    max_index = array_type_nelts (type);
+
+  return reshape_init_array_1 (TREE_TYPE (type), max_index, d);
+}
+
+/* Subroutine of reshape_init_r, processes the initializers for vectors.
+   Parameters are the same of reshape_init_r.  */
 
 static tree
-reshape_init (tree type, tree *initp)
+reshape_init_vector (tree type, reshape_iter *d)
 {
-  tree inits;
-  tree old_init;
-  tree old_init_value;
+  tree max_index = NULL_TREE;
+  tree rtype;
+
+  gcc_assert (TREE_CODE (type) == VECTOR_TYPE);
+
+  if (TREE_CODE (d->cur->value) == CONSTRUCTOR
+      && TREE_HAS_CONSTRUCTOR (d->cur->value))
+    {
+      tree value = d->cur->value;
+      if (!same_type_p (TREE_TYPE (value), type))
+       {
+         error ("invalid type %qT as initializer for a vector of type %qT",
+               TREE_TYPE (d->cur->value), type);
+         value = error_mark_node;
+       }
+      ++d->cur;
+      return value;
+    }
+
+  /* For a vector, the representation type is a struct
+      containing a single member which is an array of the
+      appropriate size.  */
+  rtype = TYPE_DEBUG_REPRESENTATION_TYPE (type);
+  if (rtype && TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (rtype))))
+    max_index = array_type_nelts (TREE_TYPE (TYPE_FIELDS (rtype)));
+
+  return reshape_init_array_1 (TREE_TYPE (type), max_index, d);
+}
+
+/* Subroutine of reshape_init_r, processes the initializers for classes
+   or union. Parameters are the same of reshape_init_r.  */
+
+static tree
+reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
+{
+  tree field;
   tree new_init;
-  bool brace_enclosed_p;
-  bool string_init_p;
 
-  old_init = *initp;
-  old_init_value = (TREE_CODE (*initp) == TREE_LIST
-                   ? TREE_VALUE (*initp) : old_init);
+  gcc_assert (CLASS_TYPE_P (type));
 
-  gcc_assert (old_init_value);
+  /* The initializer for a class is always a CONSTRUCTOR.  */
+  new_init = build_constructor (NULL_TREE, NULL);
+  field = next_initializable_field (TYPE_FIELDS (type));
 
-  /* If the initializer is brace-enclosed, pull initializers from the
-     enclosed elements.  Advance past the brace-enclosed initializer
-     now.  */
-  if (TREE_CODE (old_init_value) == CONSTRUCTOR
-      && BRACE_ENCLOSED_INITIALIZER_P (old_init_value))
+  if (!field)
     {
-      *initp = TREE_CHAIN (old_init);
-      TREE_CHAIN (old_init) = NULL_TREE;
-      inits = CONSTRUCTOR_ELTS (old_init_value);
-      initp = &inits;
-      brace_enclosed_p = true;
+      /* [dcl.init.aggr]
+
+       An initializer for an aggregate member that is an
+       empty class shall have the form of an empty
+       initializer-list {}.  */
+      if (!first_initializer_p)
+       {
+         error ("initializer for %qT must be brace-enclosed", type);
+         return error_mark_node;
+       }
+      return new_init;
     }
-  else
+
+  /* Loop through the initializable fields, gathering initializers.  */
+  while (d->cur != d->end)
     {
-      inits = NULL_TREE;
-      brace_enclosed_p = false;
+      tree field_init;
+
+      /* Handle designated initializers, as an extension.  */
+      if (d->cur->index)
+       {
+         if (pedantic)
+           pedwarn ("ISO C++ does not allow designated initializers");
+       
+         field = lookup_field_1 (type, d->cur->index, /*want_type=*/false);
+
+         if (!field || TREE_CODE (field) != FIELD_DECL)
+           error ("%qT has no non-static data member named %qD", type,
+                 d->cur->index);
+       }
+
+      /* If we processed all the member of the class, we are done.  */
+      if (!field)
+       break;
+
+      field_init = reshape_init_r (TREE_TYPE (field), d,
+                                  /*first_initializer_p=*/false);
+      CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), field, field_init);
+
+      /* [dcl.init.aggr]
+
+       When a union  is  initialized with a brace-enclosed
+       initializer, the braces shall only contain an
+       initializer for the first member of the union.  */
+      if (TREE_CODE (type) == UNION_TYPE)
+       break;
+
+      field = next_initializable_field (TREE_CHAIN (field));
     }
 
+  return new_init;
+}
+
+/* Subroutine of reshape_init, which processes a single initializer (part of
+   a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the
+   iterator within the CONSTRUCTOR which points to the initializer to process.
+   FIRST_INITIALIZER_P is true if this is the first initializer of the
+   CONSTRUCTOR node.  */
+
+static tree
+reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
+{
+  tree init = d->cur->value;
+
   /* A non-aggregate type is always initialized with a single
      initializer.  */
   if (!CP_AGGREGATE_TYPE_P (type))
-      {
-       *initp = TREE_CHAIN (old_init);
-       TREE_CHAIN (old_init) = NULL_TREE;
-       /* It is invalid to initialize a non-aggregate type with a
-          brace-enclosed initializer.  */
-       if (brace_enclosed_p)
-         {
-           error ("brace-enclosed initializer used to initialize %qT",
-                  type);
-           if (TREE_CODE (old_init) == TREE_LIST)
-             TREE_VALUE (old_init) = error_mark_node;
-           else
-             old_init = error_mark_node;
-         }
-
-       return old_init;
-      }
+    {
+      /* It is invalid to initialize a non-aggregate type with a
+        brace-enclosed initializer.
+        We need to check for BRACE_ENCLOSED_INITIALIZER_P here because
+        of g++.old-deja/g++.mike/p7626.C: a pointer-to-member constant is
+        a CONSTRUCTOR (with a record type).  */
+      if (TREE_CODE (init) == CONSTRUCTOR
+         && BRACE_ENCLOSED_INITIALIZER_P (init))  /* p7626.C */
+       {
+         error ("braces around scalar initializer for type %qT", type);
+         init = error_mark_node;
+       }
+       
+      d->cur++;
+      return init;
+    }
 
   /* [dcl.init.aggr]
 
@@ -4237,139 +4346,124 @@ reshape_init (tree type, tree *initp)
      non-empty subaggregate, brace elision is assumed and the
      initializer is considered for the initialization of the first
      member of the subaggregate.  */
-  if (!brace_enclosed_p
-      && can_convert_arg (type, TREE_TYPE (old_init_value), old_init_value))
+  if (TREE_CODE (init) != CONSTRUCTOR
+      && can_convert_arg (type, TREE_TYPE (init), init))
     {
-      *initp = TREE_CHAIN (old_init);
-      TREE_CHAIN (old_init) = NULL_TREE;
-      return old_init;
+      d->cur++;
+      return init;
     }
 
-  string_init_p = false;
-  if (TREE_CODE (old_init_value) == STRING_CST
-      && TREE_CODE (type) == ARRAY_TYPE
+  /* [dcl.init.string]
+
+      A char array (whether plain char, signed char, or unsigned char)
+      can be initialized by a string-literal (optionally enclosed in
+      braces); a wchar_t array can be initialized by a wide
+      string-literal (optionally enclosed in braces).  */
+  if (TREE_CODE (type) == ARRAY_TYPE
       && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))))
     {
-      /* [dcl.init.string]
+      tree str_init = init;
 
-        A char array (whether plain char, signed char, or unsigned char)
-        can be initialized by a string-literal (optionally enclosed in
-        braces); a wchar_t array can be initialized by a wide
-        string-literal (optionally enclosed in braces).  */
-      new_init = old_init;
-      /* Move past the initializer.  */
-      *initp = TREE_CHAIN (old_init);
-      TREE_CHAIN (old_init) = NULL_TREE;
-      string_init_p = true;
+      /* Strip one level of braces if and only if they enclose a single
+         element (as allowed by [dcl.init.string]).  */
+      if (!first_initializer_p
+         && TREE_CODE (str_init) == CONSTRUCTOR
+         && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (str_init)) == 1)
+       {
+         str_init = VEC_index (constructor_elt,
+                               CONSTRUCTOR_ELTS (str_init), 0)->value;
+       }
+  
+      /* If it's a string literal, then it's the initializer for the array
+         as a whole. Otherwise, continue with normal initialization for
+        array types (one value per array element).  */
+      if (TREE_CODE (str_init) == STRING_CST)
+       {
+         d->cur++;
+         return str_init;
+       }
     }
-  else
-    {
-      /* Build a CONSTRUCTOR to hold the contents of the aggregate.  */
-      new_init = build_constructor (NULL_TREE, NULL_TREE);
 
-      if (CLASS_TYPE_P (type))
+  /* The following cases are about aggregates. If we are not within a full
+     initializer already, and there is not a CONSTRUCTOR, it means that there
+     is a missing set of braces (that is, we are processing the case for
+     which reshape_init exists).  */
+  if (!first_initializer_p)
+    {
+      if (TREE_CODE (init) == CONSTRUCTOR)
        {
-         tree field;
-
-         field = next_initializable_field (TYPE_FIELDS (type));
-
-         if (!field)
+         /* For a nested compound literal, there is no need to reshape since
+            brace elision is not allowed. Even if we decided to allow it,
+            we should add a call to reshape_init in finish_compound_literal,
+            before calling digest_init, so changing this code would still
+            not be necessary.  */
+         if (!TREE_HAS_CONSTRUCTOR (init))
            {
-             /* [dcl.init.aggr]
-
-                An initializer for an aggregate member that is an
-                empty class shall have the form of an empty
-                initializer-list {}.  */
-             if (!brace_enclosed_p)
-               {
-                 error ("initializer for %qT must be brace-enclosed", type);
-                 return error_mark_node;
-               }
+             ++d->cur;
+             gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
+             return reshape_init (type, init);
            }
          else
-           {
-             /* Loop through the initializable fields, gathering
-                initializers.  */
-             while (*initp)
-               {
-                 tree field_init;
+           gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (init));
+       }
 
-                 /* Handle designated initializers, as an extension.  */
-                 if (TREE_PURPOSE (*initp))
-                   {
-                     if (pedantic)
-                       pedwarn ("ISO C++ does not allow designated initializers");
-                     field = lookup_field_1 (type, TREE_PURPOSE (*initp),
-                                             /*want_type=*/false);
-                     if (!field || TREE_CODE (field) != FIELD_DECL)
-                       error ("%qT has no non-static data member named %qD",
-                              type, TREE_PURPOSE (*initp));
-                   }
-                 if (!field)
-                   break;
+      warning (OPT_Wmissing_braces, "missing braces around initializer for %qT",
+              type);
+    }
 
-                 field_init = reshape_init (TREE_TYPE (field), initp);
-                 if (field_init == error_mark_node)
-                   return error_mark_node;
-                 TREE_CHAIN (field_init) = CONSTRUCTOR_ELTS (new_init);
-                 CONSTRUCTOR_ELTS (new_init) = field_init;
-                 /* [dcl.init.aggr]
-
-                    When a union  is  initialized with a brace-enclosed
-                    initializer, the braces shall only contain an
-                    initializer for the first member of the union.  */
-                 if (TREE_CODE (type) == UNION_TYPE)
-                   break;
-                 field = next_initializable_field (TREE_CHAIN (field));
-               }
-           }
-       }
-      else if (TREE_CODE (type) == ARRAY_TYPE
-              || TREE_CODE (type) == VECTOR_TYPE)
-       {
-           /* If the bound of the array is known, take no more initializers
-             than are allowed.  */
-           tree max_index = NULL_TREE;
-           if (TREE_CODE (type) == ARRAY_TYPE)
-             {
-               if (TYPE_DOMAIN (type))
-                 max_index = array_type_nelts (type);
-             }
-           else
-             {
-               /* For a vector, the representation type is a struct
-                 containing a single member which is an array of the
-                 appropriate size.  */
-               tree rtype = TYPE_DEBUG_REPRESENTATION_TYPE (type);
-               if (rtype && TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (rtype))))
-                 max_index = array_type_nelts (TREE_TYPE (TYPE_FIELDS
-                                                          (rtype)));
-             }
+  /* Dispatch to specialized routines.  */
+  if (CLASS_TYPE_P (type))
+    return reshape_init_class (type, d, first_initializer_p);
+  else if (TREE_CODE (type) == ARRAY_TYPE)
+    return reshape_init_array (type, d);
+  else if (TREE_CODE (type) == VECTOR_TYPE)
+    return reshape_init_vector (type, d);
+  else
+    gcc_unreachable();
+}
 
-         if (!reshape_init_array (TREE_TYPE (type), max_index,
-                                  initp, new_init))
-           return error_mark_node;
-       }
-      else
-       gcc_unreachable ();
+/* Undo the brace-elision allowed by [dcl.init.aggr] in a
+   brace-enclosed aggregate initializer.
 
-      /* The initializers were placed in reverse order in the
-        CONSTRUCTOR.  */
-      CONSTRUCTOR_ELTS (new_init) = nreverse (CONSTRUCTOR_ELTS (new_init));
+   INIT is the CONSTRUCTOR containing the list of initializers describing
+   a brace-enclosed initializer for an entity of the indicated aggregate TYPE.
+   It may not presently match the shape of the TYPE; for example:
 
-      if (TREE_CODE (old_init) == TREE_LIST)
-       new_init = build_tree_list (TREE_PURPOSE (old_init), new_init);
-    }
+     struct S { int a; int b; };
+     struct S a[] = { 1, 2, 3, 4 };
 
-  /* If there are more initializers than necessary, issue a
-     diagnostic.  */
-  if (*initp)
-    {
-      if (brace_enclosed_p)
-       error ("too many initializers for %qT", type);
-      else if (warn_missing_braces && !string_init_p)
-       warning (0, "missing braces around initializer");
-    }
+   Here INIT will hold a VEC of four elements, rather than a
+   VEC of two elements, each itself a VEC of two elements.  This
+   routine transforms INIT from the former form into the latter.  The
+   revised CONSTRUCTOR node is returned.  */
+
+static tree
+reshape_init (tree type, tree init)
+{
+  VEC(constructor_elt, gc) *v;
+  reshape_iter d;
+  tree new_init;
+
+  gcc_assert (TREE_CODE (init) == CONSTRUCTOR);
+  gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
+
+  v = CONSTRUCTOR_ELTS (init);
+
+  /* An empty constructor does not need reshaping, and it is always a valid
+     initializer.  */
+  if (VEC_empty (constructor_elt, v))
+    return init;
+
+  /* Recurse on this CONSTRUCTOR.  */
+  d.cur = VEC_index (constructor_elt, v, 0);
+  d.end = d.cur + VEC_length (constructor_elt, v);
+
+  new_init = reshape_init_r (type, &d, true);
+
+  /* Make sure all the element of the constructor were used. Otherwise,
+     issue an error about exceeding initializers.  */
+  if (d.cur != d.end)
+    error ("too many initializers for %qT", type);
 
   return new_init;
 }
@@ -4436,20 +4530,13 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
     init = grok_reference_init (decl, type, init, cleanup);
   else if (init)
     {
+      /* Do not reshape constructors of vectors (they don't need to be
+         reshaped.  */
       if (TREE_CODE (init) == CONSTRUCTOR
-         && BRACE_ENCLOSED_INITIALIZER_P (init))
+         && !TREE_HAS_CONSTRUCTOR (init)
+         && !TREE_TYPE (init))  /* ptrmemfunc */
        {
-         /* [dcl.init] paragraph 13,
-            If T is a scalar type, then a declaration of the form
-            T x = { a };
-            is equivalent to
-            T x = a;
-
-            reshape_init will complain about the extra braces,
-            and doesn't do anything useful in the case where TYPE is
-            scalar, so just don't call it.  */
-         if (CP_AGGREGATE_TYPE_P (type))
-           init = reshape_init (type, &init);
+         init = reshape_init (type, init);
 
          if ((*targetm.vector_opaque_p) (type))
            {
@@ -4467,9 +4554,9 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
        {
          if (TREE_CODE (type) == ARRAY_TYPE)
            goto initialize_aggr;
-         else if (TREE_CODE (init) == CONSTRUCTOR
-                  && BRACE_ENCLOSED_INITIALIZER_P (init))
+         else if (TREE_CODE (init) == CONSTRUCTOR)
            {
+             gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
              if (TYPE_NON_AGGREGATE_CLASS (type))
                {
                  error ("%qD must be initialized by constructor, "
@@ -4694,7 +4781,7 @@ initialize_local_var (tree decl, tree init)
 void
 initialize_artificial_var (tree decl, tree init)
 {
-  DECL_INITIAL (decl) = build_constructor (NULL_TREE, init);
+  DECL_INITIAL (decl) = build_constructor_from_list (NULL_TREE, init);
   DECL_INITIALIZED_P (decl) = 1;
   determine_visibility (decl);
   layout_var_decl (decl);
@@ -4814,7 +4901,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
     {
       /* Only PODs can have thread-local storage.  Other types may require
         various kinds of non-trivial initialization.  */
-      if (DECL_THREAD_LOCAL (decl) && !pod_type_p (TREE_TYPE (decl)))
+      if (DECL_THREAD_LOCAL_P (decl) && !pod_type_p (TREE_TYPE (decl)))
        error ("%qD cannot be thread-local because it has non-POD type %qT",
               decl, TREE_TYPE (decl));
       /* Convert the initializer to the type of DECL, if we have not
@@ -4828,7 +4915,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
        {
          init = check_initializer (decl, init, flags, &cleanup);
          /* Thread-local storage cannot be dynamically initialized.  */
-         if (DECL_THREAD_LOCAL (decl) && init)
+         if (DECL_THREAD_LOCAL_P (decl) && init)
            {
              error ("%qD is thread-local and so cannot be dynamically "
                     "initialized", decl);
@@ -5382,14 +5469,21 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default)
   if (initial_value)
     {
       /* An array of character type can be initialized from a
-        brace-enclosed string constant.  */
+        brace-enclosed string constant.
+
+        FIXME: this code is duplicated from reshape_init. Probably
+        we should just call reshape_init here?  */
       if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (*ptype)))
          && TREE_CODE (initial_value) == CONSTRUCTOR
-         && CONSTRUCTOR_ELTS (initial_value)
-         && (TREE_CODE (TREE_VALUE (CONSTRUCTOR_ELTS (initial_value)))
-             == STRING_CST)
-         && TREE_CHAIN (CONSTRUCTOR_ELTS (initial_value)) == NULL_TREE)
-       initial_value = TREE_VALUE (CONSTRUCTOR_ELTS (initial_value));
+         && !VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (initial_value)))
+       {
+         VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initial_value);
+         tree value = VEC_index (constructor_elt, v, 0)->value;
+
+         if (TREE_CODE (value) == STRING_CST
+             && VEC_length (constructor_elt, v) == 1)
+           initial_value = value;
+       }
     }
 
   failure = complete_array_type (ptype, initial_value, do_default);
@@ -5452,13 +5546,13 @@ bad_specifiers (tree object,
           "%qD invalid in %s declaration",
           object, type);
   if (friendp)
-    cp_error_at ("%qD declared as a friend", object);
+    error ("%q+D declared as a friend", object);
   if (raises
       && (TREE_CODE (object) == TYPE_DECL
          || (!TYPE_PTRFN_P (TREE_TYPE (object))
              && !TYPE_REFFN_P (TREE_TYPE (object))
              && !TYPE_PTRMEMFUNC_P (TREE_TYPE (object)))))
-    cp_error_at ("%qD declared with an exception specification", object);
+    error ("%q+D declared with an exception specification", object);
 }
 
 /* CTYPE is class type, or null if non-class.
@@ -5585,9 +5679,9 @@ grokfndecl (tree ctype,
                  pedwarn ("non-local function %q#D uses anonymous type",
                              decl);
                  if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
-                   cp_pedwarn_at ("%q#D does not refer to the unqualified "
-                                  "type, so it is not used for linkage",
-                                  TYPE_NAME (t));
+                   pedwarn ("%q+#D does not refer to the unqualified "
+                            "type, so it is not used for linkage",
+                            TYPE_NAME (t));
                }
            }
          else
@@ -5890,7 +5984,7 @@ grokvardecl (tree type,
   if (declspecs->specs[(int)ds_thread])
     {
       if (targetm.have_tls)
-       DECL_THREAD_LOCAL (decl) = 1;
+       DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
       else
        /* A mere warning is sure to result in improper semantics
           at runtime.  Don't bother to allow this to compile.  */
@@ -5921,9 +6015,9 @@ grokvardecl (tree type,
                  warning (0, "non-local variable %q#D uses anonymous type",
                           decl);
                  if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
-                   cp_warning_at ("%q#D does not refer to the unqualified "
-                                  "type, so it is not used for linkage",
-                                  TYPE_NAME (t));
+                   warning (0, "%q+#D does not refer to the unqualified "
+                            "type, so it is not used for linkage",
+                            TYPE_NAME (t));
                }
            }
          else
@@ -6970,7 +7064,10 @@ grokdeclarator (const cp_declarator *declarator,
   /* Warn about storage classes that are invalid for certain
      kinds of declarations (parameters, typenames, etc.).  */
   if (declspecs->multiple_storage_classes_p)
-    error ("multiple storage classes in declaration of %qs", name);
+    {
+      error ("multiple storage classes in declaration of %qs", name);
+      storage_class = sc_none;
+    }
   else if (thread_p
           && ((storage_class
                && storage_class != sc_extern
@@ -8213,7 +8310,7 @@ require_complete_types_for_parms (tree parms)
        TREE_TYPE (parms) = error_mark_node;
       else if (complete_type_or_else (TREE_TYPE (parms), parms))
        {
-         layout_decl (parms, 0);
+         relayout_decl (parms);
          DECL_ARG_TYPE (parms) = type_passed_as (TREE_TYPE (parms));
        }
     }
@@ -9023,7 +9120,7 @@ check_elaborated_type_specifier (enum tag_types tag_code,
           && tag_code != typename_type)
     {
       error ("using typedef-name %qD after %qs", decl, tag_name (tag_code));
-      cp_error_at ("%qD has a previous declaration here", decl);
+      error ("%q+D has a previous declaration here", decl);
       return error_mark_node;
     }
   else if (TREE_CODE (type) != RECORD_TYPE
@@ -9032,7 +9129,7 @@ check_elaborated_type_specifier (enum tag_types tag_code,
           && tag_code != typename_type)
     {
       error ("%qT referred to as %qs", type, tag_name (tag_code));
-      cp_error_at ("%qT has a previous declaration here", type);
+      error ("%q+T has a previous declaration here", type);
       return error_mark_node;
     }
   else if (TREE_CODE (type) != ENUMERAL_TYPE
@@ -9040,7 +9137,7 @@ check_elaborated_type_specifier (enum tag_types tag_code,
           && tag_code != typename_type)
     {
       error ("%qT referred to as enum", type);
-      cp_error_at ("%qT has a previous declaration here", type);
+      error ("%q+T has a previous declaration here", type);
       return error_mark_node;
     }
   else if (!allow_template_p
@@ -9924,7 +10021,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
   if (DECL_DECLARED_INLINE_P (decl1)
       && lookup_attribute ("noinline", attrs))
-    warning (0, "%Jinline function %qD given attribute noinline", decl1, decl1);
+    warning (0, "inline function %q+D given attribute noinline", decl1);
 
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1))
     /* This is a constructor, we must ensure that any default args