OSDN Git Service

PR c++/20646
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 4f1aa1f..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.
@@ -66,7 +66,7 @@ static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
 static void record_unknown_type (tree, const char *);
 static tree builtin_function_1 (const char *, tree, tree,
                                enum built_in_function code,
-                                enum built_in_class cl, const char *,
+                               enum built_in_class cl, const char *,
                                tree);
 static tree build_library_fn_1 (tree, enum tree_code, tree);
 static int member_function_or_else (tree, tree, enum overload_flags);
@@ -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;
@@ -306,7 +300,7 @@ current_tmpl_spec_kind (int n_class_scopes)
     /* We've not seen enough template headers to match all the
        specialized classes present.  For example:
 
-         template <class T> void R<T>::S<T>::f(int);
+        template <class T> void R<T>::S<T>::f(int);
 
        This is invalid; there needs to be one set of template
        parameters for each class.  */
@@ -315,7 +309,7 @@ current_tmpl_spec_kind (int n_class_scopes)
     /* We're processing a non-template declaration (even though it may
        be a member of a template class.)  For example:
 
-         template <class T> void S<T>::f(int);
+        template <class T> void S<T>::f(int);
 
        The `class T' maches the `S<T>', leaving no template headers
        corresponding to the `f'.  */
@@ -323,14 +317,14 @@ current_tmpl_spec_kind (int n_class_scopes)
   else if (n_template_parm_scopes > n_class_scopes + 1)
     /* We've got too many template headers.  For example:
 
-         template <> template <class T> void f (T);
+        template <> template <class T> void f (T);
 
        There need to be more enclosing classes.  */
     return tsk_excessive_parms;
   else
     /* This must be a template.  It's of the form:
 
-         template <class T> template <class U> void S<T>::f(U);
+        template <class T> template <class U> void S<T>::f(U);
 
        This is a specialization if the innermost level was a
        specialization; otherwise it's just a definition of the
@@ -358,18 +352,18 @@ 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
-         location.file = input_filename;
+         location.file = input_filename;
          location.line = 0;
 #endif
          /* Avoid crashing later.  */
          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);
@@ -419,19 +413,17 @@ objc_mark_locals_volatile (void *enclosing_blk)
   struct cp_binding_level *scope;
 
   for (scope = current_binding_level;
-       scope && scope != enclosing_blk && scope->kind == sk_block;
+       scope && scope != enclosing_blk;
        scope = scope->level_chain)
     {
       tree decl;
 
       for (decl = scope->names; decl; decl = TREE_CHAIN (decl))
-        {
-         if (TREE_CODE (decl) == VAR_DECL)
-           {
-              DECL_REGISTER (decl) = 0;
-              TREE_THIS_VOLATILE (decl) = 1;
-           }
-        }
+       objc_volatilize_decl (decl);
+
+      /* Do not climb up past the current function.  */
+      if (scope->kind == sk_function_parms)
+       break;
     }
 }
 
@@ -565,13 +557,13 @@ poplevel (int keep, int reverse, int functionbody)
          && ! TREE_USED (decl)
          && ! DECL_IN_SYSTEM_HEADER (decl)
          && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
-       warning ("%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))
     {
       if (leaving_for_scope && TREE_CODE (link) == VAR_DECL
-          && DECL_NAME (link))
+         && DECL_NAME (link))
        {
          tree name = DECL_NAME (link);
          cxx_binding *ob;
@@ -588,8 +580,8 @@ poplevel (int keep, int reverse, int functionbody)
          if (ob && ob->scope == current_binding_level->level_chain)
            /* We have something like:
 
-                int i;
-                for (int i; ;);
+                int i;
+                for (int i; ;);
 
               and we are leaving the `for' scope.  There's no reason to
               keep the binding of the inner `i' in this case.  */
@@ -616,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
@@ -635,14 +630,14 @@ poplevel (int keep, int reverse, int functionbody)
       else
        {
          tree name;
-         
+
          /* Remove the binding.  */
          decl = link;
 
          if (TREE_CODE (decl) == TREE_LIST)
            decl = TREE_VALUE (decl);
          name = decl;
-         
+
          if (TREE_CODE (name) == OVERLOAD)
            name = OVL_FUNCTION (name);
 
@@ -786,9 +781,9 @@ int
 wrapup_globals_for_namespace (tree namespace, void* data)
 {
   struct cp_binding_level *level = NAMESPACE_LEVEL (namespace);
-  varray_type statics = level->static_decls;
-  tree *vec = &VARRAY_TREE (statics, 0);
-  int len = VARRAY_ACTIVE_SIZE (statics);
+  VEC(tree,gc) *statics = level->static_decls;
+  tree *vec = VEC_address (tree, statics);
+  int len = VEC_length (tree, statics);
   int last_time = (data != 0);
 
   if (last_time)
@@ -832,15 +827,13 @@ push_local_name (tree decl)
   tree t, name;
 
   timevar_push (TV_NAME_LOOKUP);
-  if (!local_names)
-    VARRAY_TREE_INIT (local_names, 8, "local_names");
 
   name = DECL_NAME (decl);
 
-  nelts = VARRAY_ACTIVE_SIZE (local_names);
+  nelts = VEC_length (tree, local_names);
   for (i = 0; i < nelts; i++)
     {
-      t = VARRAY_TREE (local_names, i);
+      t = VEC_index (tree, local_names, i);
       if (DECL_NAME (t) == name)
        {
          if (!DECL_LANG_SPECIFIC (decl))
@@ -851,13 +844,13 @@ push_local_name (tree decl)
          else
            DECL_DISCRIMINATOR (decl) = 1;
 
-         VARRAY_TREE (local_names, i) = decl;
+         VEC_replace (tree, local_names, i, decl);
          timevar_pop (TV_NAME_LOOKUP);
          return;
        }
     }
 
-  VARRAY_PUSH_TREE (local_names, decl);
+  VEC_safe_push (tree, gc, local_names, decl);
   timevar_pop (TV_NAME_LOOKUP);
 }
 \f
@@ -894,15 +887,15 @@ decls_match (tree newdecl, tree olddecl)
        return 0;
 
       if (TREE_CODE (f1) != TREE_CODE (f2))
-        return 0;
+       return 0;
 
       if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2)))
        {
          if (p2 == NULL_TREE && DECL_EXTERN_C_P (olddecl)
              && (DECL_BUILT_IN (olddecl)
 #ifndef NO_IMPLICIT_EXTERN_C
-                 || (DECL_IN_SYSTEM_HEADER (newdecl) && !DECL_CLASS_SCOPE_P (newdecl))
-                 || (DECL_IN_SYSTEM_HEADER (olddecl) && !DECL_CLASS_SCOPE_P (olddecl))
+                 || (DECL_IN_SYSTEM_HEADER (newdecl) && !DECL_CLASS_SCOPE_P (newdecl))
+                 || (DECL_IN_SYSTEM_HEADER (olddecl) && !DECL_CLASS_SCOPE_P (olddecl))
 #endif
              ))
            {
@@ -913,11 +906,11 @@ decls_match (tree newdecl, tree olddecl)
 #ifndef NO_IMPLICIT_EXTERN_C
          else if (p1 == NULL_TREE
                   && (DECL_EXTERN_C_P (olddecl)
-                      && DECL_IN_SYSTEM_HEADER (olddecl)
-                      && !DECL_CLASS_SCOPE_P (olddecl))
+                      && DECL_IN_SYSTEM_HEADER (olddecl)
+                      && !DECL_CLASS_SCOPE_P (olddecl))
                   && (DECL_EXTERN_C_P (newdecl)
-                      && DECL_IN_SYSTEM_HEADER (newdecl)
-                      && !DECL_CLASS_SCOPE_P (newdecl)))
+                      && DECL_IN_SYSTEM_HEADER (newdecl)
+                      && !DECL_CLASS_SCOPE_P (newdecl)))
            {
              types_match = self_promoting_args_p (p2);
              TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
@@ -948,6 +941,12 @@ decls_match (tree newdecl, tree olddecl)
     }
   else
     {
+      /* Need to check scope for variable declaration (VAR_DECL).
+        For typedef (TYPE_DECL), scope is ignored.  */
+      if (TREE_CODE (newdecl) == VAR_DECL
+         && CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl))
+       return 0;
+
       if (TREE_TYPE (newdecl) == error_mark_node)
        types_match = TREE_TYPE (olddecl) == error_mark_node;
       else if (TREE_TYPE (olddecl) == NULL_TREE)
@@ -1001,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.
@@ -1049,18 +1048,19 @@ duplicate_decls (tree newdecl, tree olddecl)
               && DECL_UNINLINABLE (olddecl)
               && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
        {
-         warning ("%Jfunction %qD redeclared as inline", newdecl, newdecl);
-         warning ("%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 ("%Jfunction %qD redeclared with attribute noinline",
-                  newdecl, newdecl);
-         warning ("%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);
        }
     }
 
@@ -1070,9 +1070,9 @@ duplicate_decls (tree newdecl, tree olddecl)
     {
       if (TREE_CODE (newdecl) != FUNCTION_DECL)
        {
-          /* Avoid warnings redeclaring anticipated built-ins.  */
-          if (DECL_ANTICIPATED (olddecl))
-            return NULL_TREE;
+         /* Avoid warnings redeclaring anticipated built-ins.  */
+         if (DECL_ANTICIPATED (olddecl))
+           return NULL_TREE;
 
          /* If you declare a built-in or predefined function name as static,
             the old definition is overridden, but optionally warn this was a
@@ -1080,29 +1080,29 @@ duplicate_decls (tree newdecl, tree olddecl)
          if (! TREE_PUBLIC (newdecl))
            {
              if (warn_shadow)
-                warning ("shadowing %s function %q#D",
-                         DECL_BUILT_IN (olddecl) ? "built-in" : "library",
-                         olddecl);
+               warning (0, "shadowing %s function %q#D",
+                        DECL_BUILT_IN (olddecl) ? "built-in" : "library",
+                        olddecl);
              /* Discard the old built-in function.  */
              return NULL_TREE;
            }
          /* If the built-in is not ansi, then programs can override
             it even globally without an error.  */
          else if (! DECL_BUILT_IN (olddecl))
-           warning ("library function %q#D redeclared as non-function %q#D",
-                     olddecl, newdecl);
+           warning (0, "library function %q#D redeclared as non-function %q#D",
+                    olddecl, newdecl);
          else
            {
              error ("declaration of %q#D", newdecl);
              error ("conflicts with built-in declaration %q#D",
-                     olddecl);
+                    olddecl);
            }
          return NULL_TREE;
        }
       else if (!types_match)
        {
-          /* Avoid warnings redeclaring anticipated built-ins.  */
-          if (DECL_ANTICIPATED (olddecl))
+         /* Avoid warnings redeclaring anticipated built-ins.  */
+         if (DECL_ANTICIPATED (olddecl))
            {
              /* Deal with fileptr_type_node.  FILE type is not known
                 at the time we create the builtins.  */
@@ -1146,14 +1146,14 @@ duplicate_decls (tree newdecl, tree olddecl)
 
              if (TREE_PUBLIC (newdecl))
                {
-                 warning ("new declaration %q#D", newdecl);
-                 warning ("ambiguates built-in declaration %q#D",
-                           olddecl);
+                 warning (0, "new declaration %q#D", newdecl);
+                 warning (0, "ambiguates built-in declaration %q#D",
+                          olddecl);
                }
              else if (warn_shadow)
-               warning ("shadowing %s function %q#D",
-                         DECL_BUILT_IN (olddecl) ? "built-in" : "library",
-                         olddecl);
+               warning (0, "shadowing %s function %q#D",
+                        DECL_BUILT_IN (olddecl) ? "built-in" : "library",
+                        olddecl);
            }
          else
            /* Discard the old built-in function.  */
@@ -1221,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;
     }
@@ -1241,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
@@ -1256,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;
        }
@@ -1265,14 +1264,14 @@ duplicate_decls (tree newdecl, tree olddecl)
          if (DECL_EXTERN_C_P (newdecl) && DECL_EXTERN_C_P (olddecl))
            {
              error ("declaration of C function %q#D conflicts with",
-                     newdecl);
-             cp_error_at ("previous declaration %q#D here", olddecl);
+                    newdecl);
+             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;
@@ -1280,9 +1279,8 @@ 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);
-          return error_mark_node;
+         error ("%q+D has a previous declaration as %q#D", olddecl, olddecl);
+         return error_mark_node;
        }
     }
   else if (TREE_CODE (newdecl) == FUNCTION_DECL
@@ -1314,27 +1312,27 @@ duplicate_decls (tree newdecl, tree olddecl)
   else if (TREE_CODE (newdecl) == NAMESPACE_DECL)
     {
       /* In [namespace.alias] we have:
-        
-           In a declarative region, a namespace-alias-definition can be
+
+          In a declarative region, a namespace-alias-definition can be
           used to redefine a namespace-alias declared in that declarative
           region to refer only to the namespace to which it already
           refers.
-          
+
         Therefore, if we encounter a second alias directive for the same
         alias, we can just ignore the second directive.  */
       if (DECL_NAMESPACE_ALIAS (newdecl)
-         && (DECL_NAMESPACE_ALIAS (newdecl) 
+         && (DECL_NAMESPACE_ALIAS (newdecl)
              == DECL_NAMESPACE_ALIAS (olddecl)))
        return olddecl;
       /* [namespace.alias]
 
-         A namespace-name or namespace-alias shall not be declared as
+        A namespace-name or namespace-alias shall not be declared as
         the name of any other entity in the same declarative region.
         A namespace-name defined at global scope shall not be
         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
@@ -1344,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
@@ -1356,8 +1353,8 @@ 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 ("%Jfollows non-prototype definition here", olddecl);
+         warning (0, "prototype for %q+#D", newdecl);
+         warning (0, "%Jfollows non-prototype definition here", olddecl);
        }
       else if (TREE_CODE (olddecl) == FUNCTION_DECL
               && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl))
@@ -1369,10 +1366,10 @@ 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));
+                    DECL_LANGUAGE (newdecl));
            }
        }
 
@@ -1396,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",
+                          i, newdecl);
+                   error ("after previous specification in %q+#D",
                                 olddecl);
                  }
              }
@@ -1412,8 +1408,8 @@ duplicate_decls (tree newdecl, tree olddecl)
              && ! DECL_DECLARED_INLINE_P (olddecl)
              && TREE_ADDRESSABLE (olddecl) && warn_inline)
            {
-             warning ("%q#D was used before it was declared inline", newdecl);
-             warning ("%Jprevious non-inline declaration here", olddecl);
+             warning (0, "%q#D was used before it was declared inline", newdecl);
+             warning (0, "%Jprevious non-inline declaration here", olddecl);
            }
        }
     }
@@ -1456,8 +1452,8 @@ duplicate_decls (tree newdecl, tree olddecl)
       new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
 
       /* Optionally warn about more than one declaration for the same
-         name, but don't warn about a function declaration followed by a
-         definition.  */
+        name, but don't warn about a function declaration followed by a
+        definition.  */
       if (warn_redundant_decls && ! DECL_ARTIFICIAL (olddecl)
          && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)
          /* Don't warn about extern decl followed by definition.  */
@@ -1465,8 +1461,8 @@ duplicate_decls (tree newdecl, tree olddecl)
          /* Don't warn about friends, let add_friend take care of it.  */
          && ! (DECL_FRIEND_P (newdecl) || DECL_FRIEND_P (olddecl)))
        {
-         warning ("redundant redeclaration of %qD in same scope", newdecl);
-         cp_warning_at ("previous declaration of %qD", olddecl);
+         warning (0, "redundant redeclaration of %qD in same scope", newdecl);
+         warning (0, "previous declaration of %q+D", olddecl);
        }
     }
 
@@ -1557,11 +1553,11 @@ duplicate_decls (tree newdecl, tree olddecl)
              && ! DECL_IS_BUILTIN (olddecl)
              && flag_exceptions
              && !comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl)),
-                                    TYPE_RAISES_EXCEPTIONS (TREE_TYPE (olddecl)), 1))
+                                    TYPE_RAISES_EXCEPTIONS (TREE_TYPE (olddecl)), 1))
            {
              error ("declaration of %qF throws different exceptions",
-                     newdecl);
-             cp_error_at ("than previous declaration %qF", olddecl);
+                    newdecl);
+             error ("than previous declaration %q+F", olddecl);
            }
        }
       TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype;
@@ -1608,7 +1604,7 @@ duplicate_decls (tree newdecl, tree olddecl)
        }
 
       /* Merge the section attribute.
-         We want to issue an error if the sections conflict but that must be
+        We want to issue an error if the sections conflict but that must be
         done later in decl_attributes since we are called before attributes
         are assigned.  */
       if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
@@ -1669,13 +1665,14 @@ duplicate_decls (tree newdecl, tree olddecl)
       DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
       DECL_TEMPLATE_INSTANTIATED (newdecl)
        |= DECL_TEMPLATE_INSTANTIATED (olddecl);
-      /* If the OLDDECL is an implicit instantiation, then the NEWDECL
-        must be too.  But, it may not yet be marked as such if the
-        caller has created NEWDECL, but has not yet figured out that
-        it is a redeclaration.  */
-      if (DECL_IMPLICIT_INSTANTIATION (olddecl)
-         && !DECL_USE_TEMPLATE (newdecl))
-       SET_DECL_IMPLICIT_INSTANTIATION (newdecl);
+
+      /* If the OLDDECL is an instantiation and/or specialization,
+        then the NEWDECL must be too.  But, it may not yet be marked
+        as such if the caller has created NEWDECL, but has not yet
+        figured out that it is a redeclaration.  */
+      if (!DECL_USE_TEMPLATE (newdecl))
+       DECL_USE_TEMPLATE (newdecl) = DECL_USE_TEMPLATE (olddecl);
+
       /* Don't really know how much of the language-specific
         values we should copy from old to new.  */
       DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
@@ -1685,7 +1682,7 @@ duplicate_decls (tree newdecl, tree olddecl)
       DECL_REPO_AVAILABLE_P (newdecl) = DECL_REPO_AVAILABLE_P (olddecl);
       DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
       DECL_INITIALIZED_IN_CLASS_P (newdecl)
-        |= DECL_INITIALIZED_IN_CLASS_P (olddecl);
+       |= DECL_INITIALIZED_IN_CLASS_P (olddecl);
       olddecl_friend = DECL_FRIEND_P (olddecl);
 
       /* Only functions have DECL_BEFRIENDING_CLASSES.  */
@@ -1796,13 +1793,14 @@ duplicate_decls (tree newdecl, tree olddecl)
   COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
 
   /* Warn about conflicting visibility specifications.  */
-  if (DECL_VISIBILITY_SPECIFIED (olddecl) 
+  if (DECL_VISIBILITY_SPECIFIED (olddecl)
       && DECL_VISIBILITY_SPECIFIED (newdecl)
       && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
     {
-      warning ("%J%qD: visibility attribute ignored because it",
-              newdecl, newdecl);
-      warning ("%Jconflicts with previous declaration here", olddecl);
+      warning (OPT_Wattributes, "%q+D: visibility attribute ignored "
+              "because it", newdecl);
+      warning (OPT_Wattributes, "%Jconflicts with previous "
+              "declaration here", olddecl);
     }
   /* Choose the declaration which specified visibility.  */
   if (DECL_VISIBILITY_SPECIFIED (olddecl))
@@ -1810,12 +1808,19 @@ 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.  */
   if (DECL_LANG_SPECIFIC (olddecl))
     {
-      gcc_assert (DECL_LANG_SPECIFIC (olddecl) 
+      gcc_assert (DECL_LANG_SPECIFIC (olddecl)
                  != DECL_LANG_SPECIFIC (newdecl));
       ggc_free (DECL_LANG_SPECIFIC (olddecl));
     }
@@ -1824,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:
 
@@ -1858,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;
@@ -1920,11 +1950,12 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       /* If both functions come from different namespaces, this is not
         a redeclaration - this is a conflict with a used function.  */
       if (DECL_NAMESPACE_SCOPE_P (olddecl)
-         && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl))
+         && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)
+         && ! decls_match (olddecl, newdecl))
        return "%qD conflicts with used function";
 
       /* We'll complain about linkage mismatches in
-         warn_extern_redeclared_static.  */
+        warn_extern_redeclared_static.  */
 
       /* Defining the same name twice is no good.  */
       if (DECL_INITIAL (olddecl) != NULL_TREE
@@ -2121,8 +2152,8 @@ decl_jump_unsafe (tree decl)
 
 static void
 check_previous_goto_1 (tree decl,
-                       struct cp_binding_level* level,
-                       tree names, const location_t *locus)
+                      struct cp_binding_level* level,
+                      tree names, const location_t *locus)
 {
   int identified = 0;
   int saw_eh = 0;
@@ -2151,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)
@@ -2253,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;
     }
@@ -2267,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)
@@ -2362,9 +2391,16 @@ void
 pop_switch (void)
 {
   struct cp_switch *cs = switch_stack;
+  location_t switch_location;
 
   /* Emit warnings as needed.  */
-  c_do_switch_warnings (cs->cases, cs->switch_stmt);
+  if (EXPR_HAS_LOCATION (cs->switch_stmt))
+    switch_location = EXPR_LOCATION (cs->switch_stmt);
+  else
+    switch_location = input_location;
+  c_do_switch_warnings (cs->cases, switch_location,
+                       SWITCH_STMT_TYPE (cs->switch_stmt),
+                       SWITCH_STMT_COND (cs->switch_stmt));
 
   splay_tree_delete (cs->cases);
   switch_stack = switch_stack->next;
@@ -2452,7 +2488,7 @@ typename_compare (const void * k1, const void * k2)
 
 /* Build a TYPENAME_TYPE.  If the type is `typename T::t', CONTEXT is
    the type of `T', NAME is the IDENTIFIER_NODE for `t'.
+
    Returns the new TYPENAME_TYPE.  */
 
 static GTY ((param_is (union tree_node))) htab_t typename_htab;
@@ -2471,7 +2507,7 @@ build_typename_type (tree context, tree name, tree fullname,
     typename_htab = htab_create_ggc (61, &typename_hash,
                                     &typename_compare, NULL);
 
-  ti.scope = FROB_CONTEXT (context); 
+  ti.scope = FROB_CONTEXT (context);
   ti.name = name;
   ti.template_id = fullname;
   ti.enum_p = tag_type == enum_type;
@@ -2493,7 +2529,7 @@ build_typename_type (tree context, tree name, tree fullname,
       TYPENAME_TYPE_FULLNAME (t) = ti.template_id;
       TYPENAME_IS_ENUM_P (t) = ti.enum_p;
       TYPENAME_IS_CLASS_P (t) = ti.class_p;
-      
+
       /* Build the corresponding TYPE_DECL.  */
       d = build_decl (TYPE_DECL, name, t);
       TYPE_NAME (TREE_TYPE (d)) = d;
@@ -2504,7 +2540,7 @@ build_typename_type (tree context, tree name, tree fullname,
       /* Store it in the hash table.  */
       *e = t;
     }
-      
+
   return t;
 }
 
@@ -2570,7 +2606,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
            {
              if (complain & tf_error)
                error ("no class template named %q#T in %q#T",
-                       name, context);
+                      name, context);
              return error_mark_node;
            }
 
@@ -2581,11 +2617,11 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
                                        TREE_OPERAND (fullname, 1),
                                        NULL_TREE, context,
                                        /*entering_scope=*/0,
-                                       tf_error | tf_warning | tf_user);
+                                       tf_error | tf_warning | tf_user);
        }
       else
        {
-          tree t;
+         tree t;
 
          if (!IS_AGGR_TYPE (context))
            {
@@ -2628,7 +2664,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
 }
 
 /* Resolve `CONTEXT::template NAME'.  Returns a TEMPLATE_DECL if the name
-   can be resolved or an UNBOUND_CLASS_TEMPLATE, unless an error occurs, 
+   can be resolved or an UNBOUND_CLASS_TEMPLATE, unless an error occurs,
    in which case error_mark_node is returned.
 
    If PARM_LIST is non-NULL, also make sure that the template parameter
@@ -2670,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;
        }
@@ -2706,8 +2742,8 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
 
 void
 record_builtin_type (enum rid rid_index,
-                     const char* name,
-                     tree type)
+                    const char* name,
+                    tree type)
 {
   tree rname = NULL_TREE, tname = NULL_TREE;
   tree tdecl = NULL_TREE;
@@ -2794,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
@@ -2872,7 +2908,7 @@ cxx_init_decl_processing (void)
   /* Enter the global namespace.  */
   gcc_assert (global_namespace == NULL_TREE);
   global_namespace = build_lang_decl (NAMESPACE_DECL, global_scope_name,
-                                      void_type_node);
+                                     void_type_node);
   begin_scope (sk_namespace, global_namespace);
 
   current_lang_name = NULL_TREE;
@@ -3128,12 +3164,12 @@ cp_make_fname_decl (tree id, int type_dep)
 
 static tree
 builtin_function_1 (const char* name,
-                    tree type,
-                    tree context,
+                   tree type,
+                   tree context,
                    enum built_in_function code,
-                    enum built_in_class class,
-                    const char* libname,
-                    tree attrs)
+                   enum built_in_class class,
+                   const char* libname,
+                   tree attrs)
 {
   tree decl = build_library_fn_1 (get_identifier (name), ERROR_MARK, type);
   DECL_BUILT_IN_CLASS (decl) = class;
@@ -3180,11 +3216,11 @@ builtin_function_1 (const char* name,
 
 tree
 builtin_function (const char* name,
-                  tree type,
-                  int code,
-                  enum built_in_class cl,
-                  const char* libname,
-                  tree attrs)
+                 tree type,
+                 int code,
+                 enum built_in_class cl,
+                 const char* libname,
+                 tree attrs)
 {
   /* All builtins that don't begin with an '_' should additionally
      go in the 'std' namespace.  */
@@ -3209,7 +3245,6 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
   DECL_EXTERNAL (fn) = 1;
   TREE_PUBLIC (fn) = 1;
   DECL_ARTIFICIAL (fn) = 1;
-  TREE_NOTHROW (fn) = 1;
   SET_OVERLOADED_OPERATOR_CODE (fn, operator_code);
   SET_DECL_LANGUAGE (fn, lang_c);
   /* Runtime library routines are, by definition, available in an
@@ -3226,7 +3261,9 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
 tree
 build_library_fn (tree name, tree type)
 {
-  return build_library_fn_1 (name, ERROR_MARK, type);
+  tree fn = build_library_fn_1 (name, ERROR_MARK, type);
+  TREE_NOTHROW (fn) = 1;
+  return fn;
 }
 
 /* Returns the _DECL for a library function with C++ linkage.  */
@@ -3358,18 +3395,15 @@ fixup_anonymous_aggr (tree t)
            type = TREE_TYPE (field);
            if (CLASS_TYPE_P (type))
              {
-               if (TYPE_NEEDS_CONSTRUCTING (type))
-                 cp_error_at ("member %q#D with constructor not allowed "
-                               "in anonymous aggregate",
-                              field);
+               if (TYPE_NEEDS_CONSTRUCTING (type))
+                 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);
              }
          }
     }
@@ -3417,26 +3451,26 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
           && TYPE_ANONYMOUS_P (declared_type))
     {
       /* 7/3 In a simple-declaration, the optional init-declarator-list
-         can be omitted only when declaring a class (clause 9) or
-         enumeration (7.2), that is, when the decl-specifier-seq contains
-         either a class-specifier, an elaborated-type-specifier with
-         a class-key (9.1), or an enum-specifier.  In these cases and
-         whenever a class-specifier or enum-specifier is present in the
-         decl-specifier-seq, the identifiers in these specifiers are among
-         the names being declared by the declaration (as class-name,
-         enum-names, or enumerators, depending on the syntax).  In such
-         cases, and except for the declaration of an unnamed bit-field (9.6),
-         the decl-specifier-seq shall introduce one or more names into the
-         program, or shall redeclare a name introduced by a previous
-         declaration.  [Example:
-             enum { };            // ill-formed
-             typedef class { };   // ill-formed
-         --end example]  */
+        can be omitted only when declaring a class (clause 9) or
+        enumeration (7.2), that is, when the decl-specifier-seq contains
+        either a class-specifier, an elaborated-type-specifier with
+        a class-key (9.1), or an enum-specifier.  In these cases and
+        whenever a class-specifier or enum-specifier is present in the
+        decl-specifier-seq, the identifiers in these specifiers are among
+        the names being declared by the declaration (as class-name,
+        enum-names, or enumerators, depending on the syntax).  In such
+        cases, and except for the declaration of an unnamed bit-field (9.6),
+        the decl-specifier-seq shall introduce one or more names into the
+        program, or shall redeclare a name introduced by a previous
+        declaration.  [Example:
+            enum { };                  // ill-formed
+            typedef class { };         // ill-formed
+        --end example]  */
       if (saw_typedef)
-        {
-          error ("missing type-name in typedef-declaration");
-          return NULL_TREE;
-        }
+       {
+         error ("missing type-name in typedef-declaration");
+         return NULL_TREE;
+       }
       /* Anonymous unions are objects, so they can have specifiers.  */;
       SET_ANON_AGGR_TYPE_P (declared_type);
 
@@ -3495,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));
 
     }
 
@@ -3558,9 +3591,9 @@ groktypename (cp_decl_specifier_seq *type_specifiers,
 tree
 start_decl (const cp_declarator *declarator,
            cp_decl_specifier_seq *declspecs,
-            int initialized,
-            tree attributes,
-            tree prefix_attributes, 
+           int initialized,
+           tree attributes,
+           tree prefix_attributes,
            tree *pushed_scope_p)
 {
   tree decl;
@@ -3568,7 +3601,7 @@ start_decl (const cp_declarator *declarator,
   tree context;
 
   *pushed_scope_p = NULL_TREE;
+
   /* This should only be done once on the top most decl.  */
   if (have_extern_spec)
     {
@@ -3601,7 +3634,7 @@ start_decl (const cp_declarator *declarator,
   if (context)
     {
       *pushed_scope_p = push_scope (context);
-  
+
       /* We are only interested in class contexts, later.  */
       if (TREE_CODE (context) == NAMESPACE_DECL)
        context = NULL_TREE;
@@ -3631,8 +3664,8 @@ start_decl (const cp_declarator *declarator,
     {
       if (! toplevel_bindings_p ()
          && DECL_EXTERNAL (decl))
-       warning ("declaration of %q#D has %<extern%> and is initialized",
-                 decl);
+       warning (0, "declaration of %q#D has %<extern%> and is initialized",
+                decl);
       DECL_EXTERNAL (decl) = 0;
       if (toplevel_bindings_p ())
        TREE_STATIC (decl) = 1;
@@ -3647,14 +3680,13 @@ start_decl (const cp_declarator *declarator,
   cplus_decl_attributes (&decl, attributes, 0);
 
   /* If #pragma weak was used, mark the decl weak now.  */
-  if (global_scope_p (current_binding_level))
-    maybe_apply_pragma_weak (decl);
+  maybe_apply_pragma_weak (decl);
 
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DECLARED_INLINE_P (decl)
       && DECL_UNINLINABLE (decl)
       && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
-    warning ("%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)))
     {
@@ -3669,7 +3701,7 @@ start_decl (const cp_declarator *declarator,
                {
                  if (!same_type_p (DECL_CONTEXT (field), context))
                    pedwarn ("ISO C++ does not permit %<%T::%D%> "
-                             "to be defined as %<%T::%D%>",
+                            "to be defined as %<%T::%D%>",
                             DECL_CONTEXT (field), DECL_NAME (decl),
                             context, DECL_NAME (decl));
                  DECL_CONTEXT (decl) = DECL_CONTEXT (field);
@@ -3703,28 +3735,28 @@ start_decl (const cp_declarator *declarator,
 
       /* cp_finish_decl sets DECL_EXTERNAL if DECL_IN_AGGR_P is set.  */
       DECL_IN_AGGR_P (decl) = 0;
-      if ((DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
-         || CLASSTYPE_TEMPLATE_INSTANTIATION (context))
-       {
-         /* Do not mark DECL as an explicit specialization if it was
-            not already marked as an instantiation; a declaration
-            should never be marked as a specialization unless we know
-            what template is being specialized.  */ 
-         if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
-           SET_DECL_TEMPLATE_SPECIALIZATION (decl);
+      /* Do not mark DECL as an explicit specialization if it was not
+        already marked as an instantiation; a declaration should
+        never be marked as a specialization unless we know what
+        template is being specialized.  */
+      if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
+       {
+         SET_DECL_TEMPLATE_SPECIALIZATION (decl);
+
          /* [temp.expl.spec] An explicit specialization of a static data
             member of a template is a definition if the declaration
             includes an initializer; otherwise, it is a declaration.
 
             We check for processing_specialization so this only applies
             to the new specialization syntax.  */
-         if (DECL_INITIAL (decl) == NULL_TREE && processing_specialization)
+         if (!DECL_INITIAL (decl)
+             && processing_specialization)
            DECL_EXTERNAL (decl) = 1;
        }
 
       if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
        pedwarn ("declaration of %q#D outside of class is not definition",
-                 decl);
+                decl);
     }
 
   /* Enter this declaration into the symbol table.  */
@@ -3742,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
 
@@ -3823,14 +3855,6 @@ start_decl_1 (tree decl)
      instantiation has occurred that TYPE_HAS_NONTRIVIAL_DESTRUCTOR
      will be set correctly.  */
   maybe_push_cleanup_level (type);
-
-  /* An object declared 'const' is only readonly after it is
-     initialized.  We don't have any way of expressing this currently,
-     so we need to be conservative and unset TREE_READONLY for types
-     with constructors.  Otherwise aliasing code will ignore stores in
-     an inline constructor.  */
-   if (TYPE_NEEDS_CONSTRUCTING (type))
-     TREE_READONLY (decl) = 0;
 }
 
 /* Handle initialization of references.  DECL, TYPE, and INIT have the
@@ -3860,7 +3884,7 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
   if (TREE_CODE (init) == CONSTRUCTOR)
     {
       error ("ISO C++ forbids use of initializer list to "
-             "initialize reference %qD", decl);
+            "initialize reference %qD", decl);
       return NULL_TREE;
     }
 
@@ -3914,7 +3938,8 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
         But let's leave it here to ease the eventual merge.  */
       int do_default = !DECL_EXTERNAL (decl);
       tree initializer = init ? init : DECL_INITIAL (decl);
-      int failure = complete_array_type (type, initializer, do_default);
+      int failure = cp_complete_array_type (&TREE_TYPE (decl), initializer,
+                                           do_default);
 
       if (failure == 1)
        error ("initializer fails to determine size of %qD", decl);
@@ -3931,11 +3956,11 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
            DECL_EXTERNAL (decl) = 1;
        }
 
-      if (pedantic && TYPE_DOMAIN (type) != NULL_TREE
-         && tree_int_cst_lt (TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
-                             integer_zero_node))
+      if (failure == 3)
        error ("zero-size array %qD", decl);
 
+      cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl);
+
       layout_decl (decl, 0);
     }
 }
@@ -3947,9 +3972,6 @@ static void
 layout_var_decl (tree decl)
 {
   tree type = TREE_TYPE (decl);
-#if 0
-  tree ttype = target_type (type);
-#endif
 
   /* If we haven't already layed out this declaration, do so now.
      Note that we must not call complete type for an external object
@@ -4048,11 +4070,11 @@ 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 ("%J  you can work around this by removing "
-                       "the initializer",
+             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);
            }
        }
@@ -4081,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
@@ -4098,137 +4132,210 @@ 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);
-  HOST_WIDE_INT max_index_cst = 0;
-  HOST_WIDE_INT index;
+  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)
-    /* HWI is either 32bit or 64bit, so it must be enough to represent the
-       array size.  */
-    max_index_cst = tree_low_cst (max_index, 1);
+    {
+      if (host_integerp (max_index, 1))
+       max_index_cst = tree_low_cst (max_index, 1);
+      /* sizetype is sign extended, not zero extended.  */
+      else
+       max_index_cst = tree_low_cst (fold_convert (size_type_node, max_index),
+                                     1);
+    }
 
   /* 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_assert (TREE_CODE (designated_index) == INTEGER_CST);
-             if (sized_array_p
-                 && tree_int_cst_lt (max_index, designated_index))
-               {
-                 error ("Designated initializer %qE larger than array "
-                        "size", designated_index);
-                 TREE_PURPOSE (element_init) = NULL_TREE;
-               }
-             else
-               index = tree_low_cst (designated_index, 1);
-           }
+           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_vector (tree type, reshape_iter *d)
+{
+  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 (tree type, tree *initp)
+reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
 {
-  tree inits;
-  tree old_init;
-  tree old_init_value;
+  tree field;
   tree new_init;
-  bool brace_enclosed_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]
 
@@ -4239,137 +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;
     }
 
-  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;
+      /* 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)
-       warning ("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,13 +4554,13 @@ 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, "
-                         "not by %<{...}%>",
+                        "not by %<{...}%>",
                         decl);
                  init = error_mark_node;
                }
@@ -4508,7 +4595,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
                  && DECL_INITIAL (decl)
                  && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST
                  && PAREN_STRING_LITERAL_P (DECL_INITIAL (decl)))
-               warning ("array %qD initialized by parenthesized string literal %qE",
+               warning (0, "array %qD initialized by parenthesized string literal %qE",
                         decl, DECL_INITIAL (decl));
              init = NULL;
            }
@@ -4545,6 +4632,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
 {
   int toplev = toplevel_bindings_p ();
   int defer_p;
+  const char *filename;
 
   /* Set the DECL_ASSEMBLER_NAME for the object.  */
   if (asmspec)
@@ -4594,17 +4682,19 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
 
   /* We try to defer namespace-scope static constants so that they are
      not emitted into the object file unnecessarily.  */
+  filename = input_filename;
   if (!DECL_VIRTUAL_P (decl)
       && TREE_READONLY (decl)
       && DECL_INITIAL (decl) != NULL_TREE
       && DECL_INITIAL (decl) != error_mark_node
+      && filename != NULL
       && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))
       && toplev
       && !TREE_PUBLIC (decl))
     {
       /* Fool with the linkage of static consts according to #pragma
         interface.  */
-      struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename));
+      struct c_fileinfo *finfo = get_fileinfo (lbasename (filename));
       if (!finfo->interface_unknown && !TREE_PUBLIC (decl))
        {
          TREE_PUBLIC (decl) = 1;
@@ -4691,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);
@@ -4714,7 +4804,6 @@ void
 cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
 {
   tree type;
-  tree ttype = NULL_TREE;
   tree cleanup;
   const char *asmspec = NULL;
   int was_readonly = 0;
@@ -4757,9 +4846,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
   if (type == error_mark_node)
     goto finish_end;
 
-  if (TYPE_HAS_MUTABLE_P (type))
-    TREE_READONLY (decl) = 0;
-
   if (processing_template_decl)
     {
       /* Add this declaration to the statement-tree.  */
@@ -4772,7 +4858,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
          && !DECL_PRETTY_FUNCTION_P (decl)
          && !dependent_type_p (TREE_TYPE (decl)))
        maybe_deduce_size_from_array_init (decl, init);
-      
+
       goto finish_end;
     }
 
@@ -4786,7 +4872,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
          && IS_AGGR_TYPE (type) && DECL_NAME (decl))
        {
          if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type)
-           warning ("shadowing previous type declaration of %q#D", decl);
+           warning (0, "shadowing previous type declaration of %q#D", decl);
          set_identifier_type_value (DECL_NAME (decl), decl);
        }
 
@@ -4802,27 +4888,20 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
       goto finish_end;
     }
 
-  if (TREE_CODE (decl) != FUNCTION_DECL)
-    ttype = target_type (type);
-
-
-  /* Currently, GNU C++ puts constants in text space, making them
-     impossible to initialize.  In the future, one would hope for
-     an operating system which understood the difference between
-     initialization and the running of a program.  */
-  if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl))
+  /* A reference will be modified here, as it is initialized.  */
+  if (! DECL_EXTERNAL (decl)
+      && TREE_READONLY (decl)
+      && TREE_CODE (type) == REFERENCE_TYPE)
     {
       was_readonly = 1;
-      if (TYPE_NEEDS_CONSTRUCTING (type)
-         || TREE_CODE (type) == REFERENCE_TYPE)
-       TREE_READONLY (decl) = 0;
+      TREE_READONLY (decl) = 0;
     }
 
   if (TREE_CODE (decl) == VAR_DECL)
     {
       /* 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
@@ -4836,12 +4915,22 @@ 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);
              init = NULL_TREE;
            }
+         if (DECL_EXTERNAL (decl) && init)
+           {
+             /* The static data member cannot be initialized by a
+                non-constant when being declared.  */
+             error ("%qD cannot be initialized by a non-constant expression"
+                    " when being declared", decl);
+             DECL_INITIALIZED_IN_CLASS_P (decl) = 0;
+             init = NULL_TREE;
+           }
+
          /* Handle:
 
             [dcl.init]
@@ -4931,7 +5020,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
              else if (!TREE_STATIC (decl))
                initialize_local_var (decl, init);
            }
-         
+
          /* If a variable is defined, and then a subsequent
             definition with external linkage is encountered, we will
             get here twice for the same variable.  We want to avoid
@@ -4941,8 +5030,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
             initializer.  It is not legal to redeclare a static data
             member, so this issue does not arise in that case.  */
          if (var_definition_p && TREE_STATIC (decl))
-           expand_static_init (decl, init); 
-       } 
+           expand_static_init (decl, init);
+       }
     }
 
   /* If a CLEANUP_STMT was created to destroy a temporary bound to a
@@ -5008,6 +5097,7 @@ get_atexit_node (void)
   tree fn_type;
   tree fn_ptr_type;
   const char *name;
+  bool use_aeabi_atexit;
 
   if (atexit_node)
     return atexit_node;
@@ -5021,6 +5111,7 @@ get_atexit_node (void)
         We build up the argument types and then then function type
         itself.  */
 
+      use_aeabi_atexit = targetm.cxx.use_aeabi_atexit ();
       /* First, build the pointer-to-function type for the first
         argument.  */
       arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
@@ -5028,18 +5119,29 @@ get_atexit_node (void)
       fn_ptr_type = build_pointer_type (fn_type);
       /* Then, build the rest of the argument types.  */
       arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
-      arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
-      arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types);
+      if (use_aeabi_atexit)
+       {
+         arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types);
+         arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
+       }
+      else
+       {
+         arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
+         arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types);
+       }
       /* And the final __cxa_atexit type.  */
       fn_type = build_function_type (integer_type_node, arg_types);
       fn_ptr_type = build_pointer_type (fn_type);
-      name = "__cxa_atexit";
+      if (use_aeabi_atexit)
+       name = "__aeabi_atexit";
+      else
+       name = "__cxa_atexit";
     }
   else
     {
       /* The declaration for `atexit' is:
 
-           int atexit (void (*)());
+          int atexit (void (*)());
 
         We build up the argument types and then then function type
         itself.  */
@@ -5194,8 +5296,16 @@ register_dtor_fn (tree decl)
       args = tree_cons (NULL_TREE,
                        build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0),
                        NULL_TREE);
-      args = tree_cons (NULL_TREE, null_pointer_node, args);
-      args = tree_cons (NULL_TREE, cleanup, args);
+      if (targetm.cxx.use_aeabi_atexit ())
+       {
+         args = tree_cons (NULL_TREE, cleanup, args);
+         args = tree_cons (NULL_TREE, null_pointer_node, args);
+       }
+      else
+       {
+         args = tree_cons (NULL_TREE, null_pointer_node, args);
+         args = tree_cons (NULL_TREE, cleanup, args);
+       }
     }
   else
     args = tree_cons (NULL_TREE, cleanup, NULL_TREE);
@@ -5230,16 +5340,16 @@ expand_static_init (tree decl, tree init)
       /* Emit code to perform this initialization but once.  This code
         looks like:
 
-           static <type> guard;
-           if (!guard.first_byte) {
+          static <type> guard;
+          if (!guard.first_byte) {
             if (__cxa_guard_acquire (&guard)) {
               bool flag = false;
               try {
-                // Do initialization.
-                flag = true; __cxa_guard_release (&guard);
-                // Register variable for destruction at end of program.
+                // Do initialization.
+                flag = true; __cxa_guard_release (&guard);
+                // Register variable for destruction at end of program.
               } catch {
-                if (!flag) __cxa_guard_abort (&guard);
+                if (!flag) __cxa_guard_abort (&guard);
               }
           }
 
@@ -5250,11 +5360,11 @@ expand_static_init (tree decl, tree init)
 
           [stmt.dcl]
 
-          If the initialization exits by throwing an exception, the  
+          If the initialization exits by throwing an exception, the
           initialization is not complete, so it will be tried again
           the next time control enters the declaration.
 
-         This process should be thread-safe, too; multiple threads
+        This process should be thread-safe, too; multiple threads
         should not be able to initialize the variable more than
         once.  */
 
@@ -5305,15 +5415,15 @@ expand_static_init (tree decl, tree init)
          flag = TARGET_EXPR_SLOT (begin);
 
          TARGET_EXPR_CLEANUP (begin)
-           = build (COND_EXPR, void_type_node, flag,
-                    void_zero_node,
-                    build_call (abort_fn, guard_addr_list));
+           = build3 (COND_EXPR, void_type_node, flag,
+                     void_zero_node,
+                     build_call (abort_fn, guard_addr_list));
          CLEANUP_EH_ONLY (begin) = 1;
 
          /* Do the initialization itself.  */
          init = add_stmt_to_compound (begin, init);
          init = add_stmt_to_compound
-           (init, build (MODIFY_EXPR, void_type_node, flag, boolean_true_node));
+           (init, build2 (MODIFY_EXPR, void_type_node, flag, boolean_true_node));
          init = add_stmt_to_compound
            (init, build_call (release_fn, guard_addr_list));
        }
@@ -5347,102 +5457,52 @@ expand_static_init (tree decl, tree init)
 \f
 /* Make TYPE a complete type based on INITIAL_VALUE.
    Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
-   2 if there was no information (in which case assume 0 if DO_DEFAULT).  */
+   2 if there was no information (in which case assume 0 if DO_DEFAULT),
+   3 if the initializer list is empty (in pedantic mode). */
 
 int
-complete_array_type (tree type, tree initial_value, int do_default)
+cp_complete_array_type (tree *ptype, tree initial_value, bool do_default)
 {
-  tree maxindex = NULL_TREE;
-  int value = 0;
+  int failure;
+  tree type, elt_type;
 
   if (initial_value)
     {
       /* An array of character type can be initialized from a
-        brace-enclosed string constant.  */
-      if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type)))
-         && 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));
+        brace-enclosed string constant.
 
-      /* Note MAXINDEX is really the maximum index, one less than the
-        size.  */
-      if (TREE_CODE (initial_value) == STRING_CST)
-       {
-         int eltsize
-           = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
-         maxindex = build_int_cst (NULL_TREE,
-                                   (TREE_STRING_LENGTH (initial_value)
-                                    / eltsize) - 1);
-       }
-      else if (TREE_CODE (initial_value) == CONSTRUCTOR)
-       {
-         tree elts = CONSTRUCTOR_ELTS (initial_value);
-
-         maxindex = ssize_int (-1);
-         for (; elts; elts = TREE_CHAIN (elts))
-           {
-             if (TREE_PURPOSE (elts))
-               maxindex = TREE_PURPOSE (elts);
-             else
-               maxindex = size_binop (PLUS_EXPR, maxindex, ssize_int (1));
-           }
-       }
-      else
+        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
+         && !VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (initial_value)))
        {
-         /* Make an error message unless that happened already.  */
-         if (initial_value != error_mark_node)
-           value = 1;
-         else
-           initial_value = NULL_TREE;
+         VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initial_value);
+         tree value = VEC_index (constructor_elt, v, 0)->value;
 
-         /* Prevent further error messages.  */
-         maxindex = build_int_cst (NULL_TREE, 0);
+         if (TREE_CODE (value) == STRING_CST
+             && VEC_length (constructor_elt, v) == 1)
+           initial_value = value;
        }
     }
 
-  if (!maxindex)
-    {
-      if (do_default)
-       maxindex = build_int_cst (NULL_TREE, 0);
-      value = 2;
-    }
+  failure = complete_array_type (ptype, initial_value, do_default);
 
-  if (maxindex)
+  /* We can create the array before the element type is complete, which
+     means that we didn't have these two bits set in the original type
+     either.  In completing the type, we are expected to propagate these
+     bits.  See also complete_type which does the same thing for arrays
+     of fixed size.  */
+  type = *ptype;
+  if (TYPE_DOMAIN (type))
     {
-      tree itype;
-      tree domain;
-      tree elt_type;
-
-      domain = build_index_type (maxindex);
-      TYPE_DOMAIN (type) = domain;
-
-      if (initial_value)
-        itype = TREE_TYPE (initial_value);
-      else
-       itype = NULL;
-      if (itype && !TYPE_DOMAIN (itype))
-       TYPE_DOMAIN (itype) = domain;
-      /* The type of the main variant should never be used for arrays
-        of different sizes.  It should only ever be completed with the
-        size of the array.  */
-      if (! TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)))
-       TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = domain;
-
       elt_type = TREE_TYPE (type);
-      TYPE_NEEDS_CONSTRUCTING (type)
-       = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type));
+      TYPE_NEEDS_CONSTRUCTING (type) = TYPE_NEEDS_CONSTRUCTING (elt_type);
       TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
-       = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type));
+       = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (elt_type);
     }
 
-  /* Lay out the type now that we can get the real answer.  */
-
-  layout_type (type);
-
-  return value;
+  return failure;
 }
 \f
 /* Return zero if something is declared to be a member of type
@@ -5470,12 +5530,12 @@ member_function_or_else (tree ctype, tree cur_type, enum overload_flags flags)
 
 static void
 bad_specifiers (tree object,
-                const char* type,
-                int virtualp,
-                int quals,
-                int inlinep,
-                int friendp,
-                int raises)
+               const char* type,
+               int virtualp,
+               int quals,
+               int inlinep,
+               int friendp,
+               int raises)
 {
   if (virtualp)
     error ("%qD declared as a %<virtual%> %s", object, type);
@@ -5483,16 +5543,16 @@ bad_specifiers (tree object,
     error ("%qD declared as an %<inline%> %s", object, type);
   if (quals)
     error ("%<const%> and %<volatile%> function specifiers on "
-           "%qD invalid in %s declaration",
-           object, type);
+          "%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.
@@ -5515,22 +5575,22 @@ bad_specifiers (tree object,
 
 static tree
 grokfndecl (tree ctype,
-            tree type,
-            tree declarator,
+           tree type,
+           tree declarator,
            tree parms,
-            tree orig_declarator,
-            int virtualp,
-            enum overload_flags flags,
+           tree orig_declarator,
+           int virtualp,
+           enum overload_flags flags,
            cp_cv_quals quals,
-            tree raises,
-            int check,
-            int friendp,
-            int publicp,
-            int inlinep,
+           tree raises,
+           int check,
+           int friendp,
+           int publicp,
+           int inlinep,
            special_function_kind sfk,
-            int funcdef_flag,
-            int template_count,
-            tree in_namespace,
+           int funcdef_flag,
+           int template_count,
+           tree in_namespace,
            tree* attrlist)
 {
   tree decl;
@@ -5619,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
@@ -5654,7 +5714,7 @@ grokfndecl (tree ctype,
     }
 
   if (IDENTIFIER_OPNAME_P (DECL_NAME (decl)))
-    grok_op_properties (decl, friendp, /*complain=*/true);
+    grok_op_properties (decl, /*complain=*/true);
 
   if (ctype && decl_function_context (decl))
     DECL_NO_STATIC_CHAIN (decl) = 1;
@@ -5683,8 +5743,8 @@ grokfndecl (tree ctype,
            {
              /* Something like `template <class T> friend void f<T>()'.  */
              error ("invalid use of template-id %qD in declaration "
-                     "of primary template",
-                     orig_declarator);
+                    "of primary template",
+                    orig_declarator);
              return NULL_TREE;
            }
 
@@ -5693,17 +5753,17 @@ grokfndecl (tree ctype,
             the information in the TEMPLATE_ID_EXPR.  */
          SET_DECL_IMPLICIT_INSTANTIATION (decl);
 
-          if (TREE_CODE (fns) == COMPONENT_REF)
-            {
-              /* Due to bison parser ickiness, we will have already looked
-                 up an operator_name or PFUNCNAME within the current class
-                 (see template_id in parse.y). If the current class contains
-                 such a name, we'll get a COMPONENT_REF here. Undo that.  */
+         if (TREE_CODE (fns) == COMPONENT_REF)
+           {
+             /* Due to bison parser ickiness, we will have already looked
+                up an operator_name or PFUNCNAME within the current class
+                (see template_id in parse.y). If the current class contains
+                such a name, we'll get a COMPONENT_REF here. Undo that.  */
 
-              gcc_assert (TREE_TYPE (TREE_OPERAND (fns, 0))
+             gcc_assert (TREE_TYPE (TREE_OPERAND (fns, 0))
                          == current_class_type);
-              fns = TREE_OPERAND (fns, 1);
-            }
+             fns = TREE_OPERAND (fns, 1);
+           }
          gcc_assert (TREE_CODE (fns) == IDENTIFIER_NODE
                      || TREE_CODE (fns) == OVERLOAD);
          DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE);
@@ -5711,16 +5771,16 @@ grokfndecl (tree ctype,
          if (has_default_arg)
            {
              error ("default arguments are not allowed in declaration "
-                     "of friend template specialization %qD",
-                     decl);
+                    "of friend template specialization %qD",
+                    decl);
              return NULL_TREE;
            }
 
          if (inlinep)
            {
              error ("%<inline%> is not allowed in declaration of friend "
-                     "template specialization %qD",
-                     decl);
+                    "template specialization %qD",
+                    decl);
              return NULL_TREE;
            }
        }
@@ -5769,7 +5829,7 @@ grokfndecl (tree ctype,
                                (processing_template_decl
                                 > template_class_depth (ctype))
                                ? current_template_parms
-                               : NULL_TREE); 
+                               : NULL_TREE);
 
       if (old_decl && TREE_CODE (old_decl) == TEMPLATE_DECL)
        /* Because grokfndecl is always supposed to return a
@@ -5851,11 +5911,11 @@ set_linkage_for_static_data_member (tree decl)
 
 static tree
 grokvardecl (tree type,
-             tree name,
+            tree name,
             const cp_decl_specifier_seq *declspecs,
-             int initialized,
-             int constp,
-             tree scope)
+            int initialized,
+            int constp,
+            tree scope)
 {
   tree decl;
   tree explicit_scope;
@@ -5924,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.  */
@@ -5938,8 +5998,7 @@ grokvardecl (tree type,
         declare an entity with linkage.
 
         Only check this for public decls for now.  */
-      tree t1 = TREE_TYPE (decl);
-      tree t = no_linkage_check (t1, /*relaxed_p=*/false);
+      tree t = no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false);
       if (t)
        {
          if (TYPE_ANONYMOUS_P (t))
@@ -5947,31 +6006,26 @@ grokvardecl (tree type,
              if (DECL_EXTERN_C_P (decl))
                /* Allow this; it's pretty common in C.  */
                  ;
-             else if (same_type_ignoring_top_level_qualifiers_p(t1, t))
-               /* This is something like "enum { a = 3 } x;", which is
-                  well formed.  The enum doesn't have "a name with no
-                  linkage", because it has no name.  See closed CWG issue
-                  132.
-
-                  Note that while this construct is well formed in C++03
-                  it is likely to become ill formed in C++0x.  See open
-                  CWG issue 389 and related issues.  */
-               ;
              else
                {
-                 /* It's a typedef referring to an anonymous type.  */
-                 pedwarn ("non-local variable %q#D uses anonymous type",
+                 /* DRs 132, 319 and 389 seem to indicate types with
+                    no linkage can only be used to declare extern "C"
+                    entities.  Since it's not always an error in the
+                    ISO C++ 90 Standard, we only issue a warning.  */
+                 warning (0, "non-local variable %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));
+                   warning (0, "%q+#D does not refer to the unqualified "
+                            "type, so it is not used for linkage",
+                            TYPE_NAME (t));
                }
            }
          else
-           pedwarn ("non-local variable %q#D uses local type %qT", decl, t);
+           warning (0, "non-local variable %q#D uses local type %qT", decl, t);
        }
     }
+  else
+    DECL_INTERFACE_KNOWN (decl) = 1;
 
   return decl;
 }
@@ -6085,7 +6139,7 @@ check_static_variable_definition (tree decl, tree type)
   if (!ARITHMETIC_TYPE_P (type) && TREE_CODE (type) != ENUMERAL_TYPE)
     {
       error ("invalid in-class initialization of static data member "
-             "of non-integral type %qT",
+            "of non-integral type %qT",
             type);
       /* If we just return the declaration, crashes will sometimes
         occur.  We therefore return void_type_node, as if this were a
@@ -6095,11 +6149,11 @@ check_static_variable_definition (tree decl, tree type)
     }
   else if (!CP_TYPE_CONST_P (type))
     error ("ISO C++ forbids in-class initialization of non-const "
-           "static member %qD",
-           decl);
+          "static member %qD",
+          decl);
   else if (pedantic && !INTEGRAL_TYPE_P (type))
     pedwarn ("ISO C++ forbids initialization of member constant "
-             "%qD of non-integral type %qT", decl, type);
+            "%qD of non-integral type %qT", decl, type);
 
   return 0;
 }
@@ -6176,7 +6230,7 @@ compute_array_index_type (tree name, tree size)
       /* `(int) &fn' is not a valid array bound.  */
       if (name)
        error ("size of array %qD is not an integral constant-expression",
-               name);
+              name);
       else
        error ("size of array is not an integral constant-expression");
     }
@@ -6196,9 +6250,9 @@ compute_array_index_type (tree name, tree size)
       HOST_WIDE_INT saved_processing_template_decl;
 
       /* Compute the index of the largest element in the array.  It is
-        one less than the number of elements in the array.  We save
-        and restore PROCESSING_TEMPLATE_DECL so that computations in
-        cp_build_binary_op will be appropriately folded.  */
+        one less than the number of elements in the array.  We save
+        and restore PROCESSING_TEMPLATE_DECL so that computations in
+        cp_build_binary_op will be appropriately folded.  */
       saved_processing_template_decl = processing_template_decl;
       processing_template_decl = 0;
       itype = cp_build_binary_op (MINUS_EXPR,
@@ -6211,8 +6265,8 @@ compute_array_index_type (tree name, tree size)
        /* A variable sized array.  */
        itype = variable_size (itype);
       /* Make sure that there was no overflow when creating to a signed
-        index type.  (For example, on a 32-bit machine, an array with
-        size 2^32 - 1 is too big.)  */
+        index type.  (For example, on a 32-bit machine, an array with
+        size 2^32 - 1 is too big.)  */
       else if (TREE_OVERFLOW (itype))
        {
          error ("overflow in array dimension");
@@ -6304,11 +6358,11 @@ create_array_type_for_decl (tree name, tree type, tree size)
     {
       if (name)
        error ("declaration of %qD as multidimensional array must "
-               "have bounds for all dimensions except the first",
-               name);
+              "have bounds for all dimensions except the first",
+              name);
       else
        error ("multidimensional array must have bounds for all "
-               "dimensions except the first");
+              "dimensions except the first");
 
       return error_mark_node;
     }
@@ -6335,8 +6389,8 @@ create_array_type_for_decl (tree name, tree type, tree size)
 
 static tree
 check_special_function_return_type (special_function_kind sfk,
-                                    tree type,
-                                    tree optype)
+                                   tree type,
+                                   tree optype)
 {
   switch (sfk)
     {
@@ -6399,7 +6453,7 @@ check_var_type (tree identifier, tree type)
        error ("variable or field declared void");
       type = integer_type_node;
     }
-  
+
   return type;
 }
 
@@ -6445,9 +6499,9 @@ check_var_type (tree identifier, tree type)
 tree
 grokdeclarator (const cp_declarator *declarator,
                const cp_decl_specifier_seq *declspecs,
-                enum decl_context decl_context,
-                int initialized,
-                tree* attrlist)
+               enum decl_context decl_context,
+               int initialized,
+               tree* attrlist)
 {
   tree type = NULL_TREE;
   int longlong = 0;
@@ -6574,13 +6628,13 @@ grokdeclarator (const cp_declarator *declarator,
                      error ("declaration of %qD as non-function", decl);
                      return error_mark_node;
                    }
-                 else if (!qualifying_scope 
+                 else if (!qualifying_scope
                           && !(current_class_type && at_class_scope_p ()))
                    {
                      error ("declaration of %qD as non-member", decl);
                      return error_mark_node;
                    }
-                 
+
                  type = TREE_OPERAND (decl, 0);
                  name = IDENTIFIER_POINTER (constructor_name (type));
                }
@@ -6801,7 +6855,7 @@ grokdeclarator (const cp_declarator *declarator,
       else if (pedantic || ! is_main)
        pedwarn ("ISO C++ forbids declaration of %qs with no type", name);
       else if (warn_return_type)
-       warning ("ISO C++ forbids declaration of %qs with no type", name);
+       warning (0, "ISO C++ forbids declaration of %qs with no type", name);
 
       type = integer_type_node;
     }
@@ -6937,12 +6991,26 @@ grokdeclarator (const cp_declarator *declarator,
     type_quals |= TYPE_QUAL_RESTRICT;
   if (sfk == sfk_conversion && type_quals != TYPE_UNQUALIFIED)
     error ("qualifiers are not allowed on declaration of %<operator %T%>",
-           ctor_return_type);
+          ctor_return_type);
 
+  if (TREE_CODE (type) == FUNCTION_TYPE
+      && type_quals != TYPE_UNQUALIFIED)
+    {
+      /* This was an error in C++98 (cv-qualifiers cannot be added to
+        a function type), but DR 295 makes the code well-formed by
+        dropping the extra qualifiers. */
+      if (pedantic)
+       {
+         tree bad_type = build_qualified_type (type, type_quals);
+         pedwarn ("ignoring %qV qualifiers added to function type %qT",
+                  bad_type, type);
+       }
+      type_quals = TYPE_UNQUALIFIED;
+    }
   type_quals |= cp_type_quals (type);
   type = cp_build_qualified_type_real
     (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)
-                        ? tf_ignore_bad_quals : 0) | tf_error | tf_warning));
+                        ? tf_ignore_bad_quals : 0) | tf_error | tf_warning));
   /* We might have ignored or rejected some of the qualifiers.  */
   type_quals = cp_type_quals (type);
 
@@ -6996,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
@@ -7026,30 +7097,7 @@ grokdeclarator (const cp_declarator *declarator,
       else
        {
          if (decl_context == FIELD)
-           {
-             tree tmp = NULL_TREE;
-             int op = 0;
-
-             if (declarator)
-               {
-                 /* Avoid trying to get an operand off an identifier node.  */
-                 if (declarator->kind != cdk_id)
-                   tmp = declarator->declarator->u.id.unqualified_name;
-                 else
-                   tmp = declarator->u.id.unqualified_name;
-                 op = IDENTIFIER_OPNAME_P (tmp);
-                 if (IDENTIFIER_TYPENAME_P (tmp))
-                   {
-                     if (is_typename_at_global_scope (tmp))
-                       name = IDENTIFIER_POINTER (tmp);
-                     else
-                       name = "<invalid operator>";
-                   }
-               }
-             error ("storage class specified for %s %qs",
-                    op ? "member operator" : "field",
-                    name);
-           }
+           error ("storage class specified for %qs", name);
          else
            {
              if (decl_context == PARM || decl_context == CATCHPARM)
@@ -7072,7 +7120,7 @@ grokdeclarator (const cp_declarator *declarator,
          /* It's common practice (and completely valid) to have a const
             be initialized and declared extern.  */
          if (!(type_quals & TYPE_QUAL_CONST))
-           warning ("%qs initialized and declared %<extern%>", name);
+           warning (0, "%qs initialized and declared %<extern%>", name);
        }
       else
        error ("%qs has both %<extern%> and initializer", name);
@@ -7127,9 +7175,7 @@ grokdeclarator (const cp_declarator *declarator,
 
   /* Determine the type of the entity declared by recurring on the
      declarator.  */
-  for (;
-       declarator && declarator->kind != cdk_id;
-       declarator = declarator->declarator)
+  for (; declarator; declarator = declarator->declarator)
     {
       const cp_declarator *inner_declarator;
       tree attrs;
@@ -7137,8 +7183,6 @@ grokdeclarator (const cp_declarator *declarator,
       if (type == error_mark_node)
        return error_mark_node;
 
-      inner_declarator = declarator->declarator;
-
       attrs = declarator->attributes;
       if (attrs)
        {
@@ -7156,6 +7200,11 @@ grokdeclarator (const cp_declarator *declarator,
                                            attr_flags);
        }
 
+      if (declarator->kind == cdk_id)
+       break;
+
+      inner_declarator = declarator->declarator;
+
       switch (declarator->kind)
        {
        case cdk_array:
@@ -7172,7 +7221,7 @@ grokdeclarator (const cp_declarator *declarator,
               Make sure we have a valid type for the function to return.  */
 
            /* We now know that the TYPE_QUALS don't apply to the
-               decl, but to its return type.  */
+              decl, but to its return type.  */
            type_quals = TYPE_UNQUALIFIED;
 
            /* Warn about some types functions can't return.  */
@@ -7234,7 +7283,7 @@ grokdeclarator (const cp_declarator *declarator,
                          return void_type_node;
                      }
                  }
-               else            /* It's a constructor.  */
+               else /* It's a constructor.  */
                  {
                    if (explicitp == 1)
                      explicitp = 2;
@@ -7282,8 +7331,8 @@ grokdeclarator (const cp_declarator *declarator,
                  error ("friend declaration not in class definition");
                if (current_function_decl && funcdef_flag)
                  error ("can't define friend function %qs in a local "
-                         "class definition",
-                         name);
+                        "class definition",
+                        name);
              }
 
            arg_types = grokparms (declarator->u.function.parameters,
@@ -7300,6 +7349,7 @@ grokdeclarator (const cp_declarator *declarator,
              }
 
            type = build_function_type (type, arg_types);
+           type = cp_build_qualified_type (type, quals);
          }
          break;
 
@@ -7332,7 +7382,15 @@ grokdeclarator (const cp_declarator *declarator,
              && (TREE_CODE (type) == FUNCTION_TYPE
                  || (quals && TREE_CODE (type) == METHOD_TYPE)))
            {
-             tree dummy = build_decl (TYPE_DECL, NULL_TREE, type);
+             tree dummy;
+
+             /* If the type is a FUNCTION_TYPE, pick up the
+                qualifiers from that function type. No other
+                qualifiers may be supplied. */
+             if (TREE_CODE (type) == FUNCTION_TYPE)
+               quals = cp_type_quals (type);
+
+             dummy = build_decl (TYPE_DECL, NULL_TREE, type);
              grok_method_quals (declarator->u.pointer.class_type,
                                 dummy, quals);
              type = TREE_TYPE (dummy);
@@ -7458,7 +7516,7 @@ grokdeclarator (const cp_declarator *declarator,
          else
            {
              error ("cannot declare member function %<%T::%s%> within %<%T%>",
-                    ctype, name, current_class_type);
+                    ctype, name, current_class_type);
              return error_mark_node;
            }
        }
@@ -7498,6 +7556,7 @@ grokdeclarator (const cp_declarator *declarator,
 
   if (TREE_CODE (type) == ARRAY_TYPE
       && COMPLETE_TYPE_P (type)
+      && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
       && TREE_OVERFLOW (TYPE_SIZE (type)))
     {
       error ("size of array %qs is too large", name);
@@ -7520,7 +7579,7 @@ grokdeclarator (const cp_declarator *declarator,
   if (explicitp == 1 || (explicitp && friendp))
     {
       /* [dcl.fct.spec] The explicit specifier shall only be used in
-         declarations of constructors within a class definition.  */
+        declarations of constructors within a class definition.  */
       error ("only declarations of constructors can be %<explicit%>");
       explicitp = 0;
     }
@@ -7528,21 +7587,21 @@ grokdeclarator (const cp_declarator *declarator,
   if (storage_class == sc_mutable)
     {
       if (decl_context != FIELD || friendp)
-        {
+       {
          error ("non-member %qs cannot be declared %<mutable%>", name);
          storage_class = sc_none;
-        }
+       }
       else if (decl_context == TYPENAME || declspecs->specs[(int)ds_typedef])
        {
          error ("non-object member %qs cannot be declared %<mutable%>", name);
          storage_class = sc_none;
        }
       else if (TREE_CODE (type) == FUNCTION_TYPE
-               || TREE_CODE (type) == METHOD_TYPE)
-        {
+              || TREE_CODE (type) == METHOD_TYPE)
+       {
          error ("function %qs cannot be declared %<mutable%>", name);
          storage_class = sc_none;
-        }
+       }
       else if (staticp)
        {
          error ("static %qs cannot be declared %<mutable%>", name);
@@ -7577,7 +7636,7 @@ grokdeclarator (const cp_declarator *declarator,
          if (!current_function_decl)
            DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
          else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (current_function_decl)
-                  || (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P 
+                  || (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P
                       (current_function_decl)))
            /* The TYPE_DECL is "abstract" because there will be
               clones of this constructor/destructor, and there will
@@ -7629,11 +7688,12 @@ grokdeclarator (const cp_declarator *declarator,
        {
          if (ctype == NULL_TREE)
            {
-             if (TREE_CODE (type) != METHOD_TYPE)
-               error ("%Jinvalid type qualifier for non-member function type",
-                      decl);
-             else
+             if (TREE_CODE (type) == METHOD_TYPE)
                ctype = TYPE_METHOD_BASETYPE (type);
+             /* Any qualifiers on a function type typedef have
+                already been dealt with. */
+             else if (TREE_CODE (type) == FUNCTION_TYPE)
+               quals = TYPE_UNQUALIFIED;
            }
          if (ctype != NULL_TREE)
            grok_method_quals (ctype, decl, quals);
@@ -7676,6 +7736,23 @@ grokdeclarator (const cp_declarator *declarator,
        }
 
       parms = nreverse (decls);
+
+      if (decl_context != TYPENAME)
+       {
+         /* A cv-qualifier-seq shall only be part of the function type
+            for a non-static member function. [8.3.5/4 dcl.fct] */
+         if (cp_type_quals (type) != TYPE_UNQUALIFIED
+             && (current_class_type == NULL_TREE || staticp) )
+           {
+             error ("qualified function types cannot be used to declare %s functions",
+                    (staticp? "static member" : "free"));
+             type = TYPE_MAIN_VARIANT (type);
+           }
+
+         /* The qualifiers on the function type become the qualifiers on
+            the non-static member function. */
+         quals |= cp_type_quals (type);
+       }
     }
 
   /* If this is a type name (such as, in a cast or sizeof),
@@ -7708,11 +7785,11 @@ grokdeclarator (const cp_declarator *declarator,
              if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
                pedwarn ("template parameters cannot be friends");
              else if (TREE_CODE (type) == TYPENAME_TYPE)
-               pedwarn ("friend declaration requires class-key, "
+               pedwarn ("friend declaration requires class-key, "
                         "i.e. %<friend class %T::%D%>",
                         TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type));
              else
-               pedwarn ("friend declaration requires class-key, "
+               pedwarn ("friend declaration requires class-key, "
                         "i.e. %<friend %#T%>",
                         type);
            }
@@ -7726,7 +7803,7 @@ grokdeclarator (const cp_declarator *declarator,
                                   /*complain=*/true);
              else
                error ("trying to make class %qT a friend of global scope",
-                       type);
+                      type);
 
              type = void_type_node;
            }
@@ -7736,9 +7813,9 @@ grokdeclarator (const cp_declarator *declarator,
          if (ctype == NULL_TREE)
            {
              if (TREE_CODE (type) != METHOD_TYPE)
-               error ("invalid qualifiers on non-member function type");
+               error ("invalid qualifiers on non-member function type");
              else
-               ctype = TYPE_METHOD_BASETYPE (type);
+               ctype = TYPE_METHOD_BASETYPE (type);
            }
          if (ctype)
            {
@@ -7859,7 +7936,7 @@ grokdeclarator (const cp_declarator *declarator,
                    if (virtualp)
                      {
                        error ("%qD cannot be declared virtual, since it "
-                               "is always static",
+                              "is always static",
                               unqualified_id);
                        virtualp = 0;
                      }
@@ -7872,11 +7949,11 @@ grokdeclarator (const cp_declarator *declarator,
 
            /* Check that the name used for a destructor makes sense.  */
            if (sfk == sfk_destructor
-               && !same_type_p (TREE_OPERAND 
+               && !same_type_p (TREE_OPERAND
                                 (id_declarator->u.id.unqualified_name, 0),
                                 ctype))
              {
-               error ("declaration of %qD as member of %qT", 
+               error ("declaration of %qD as member of %qT",
                       id_declarator->u.id.unqualified_name,
                       ctype);
                return error_mark_node;
@@ -7942,8 +8019,8 @@ grokdeclarator (const cp_declarator *declarator,
                               unqualified_id,
                               virtualp, flags, quals, raises,
                               friendp ? -1 : 0, friendp, 1, 0, sfk,
-                              funcdef_flag, template_count, in_namespace, 
-                              attrlist); 
+                              funcdef_flag, template_count, in_namespace,
+                              attrlist);
            if (decl == NULL_TREE)
              return NULL_TREE;
          }
@@ -7964,7 +8041,7 @@ grokdeclarator (const cp_declarator *declarator,
                && declspecs->type
                && declspecs->type == type)
              error ("  in instantiation of template %qT",
-                     current_class_type);
+                    current_class_type);
 
            type = error_mark_node;
            decl = NULL_TREE;
@@ -7974,7 +8051,7 @@ grokdeclarator (const cp_declarator *declarator,
            if (friendp)
              {
                error ("%qE is neither function nor member function; "
-                       "cannot be declared friend", unqualified_id);
+                      "cannot be declared friend", unqualified_id);
                friendp = 0;
              }
            decl = NULL_TREE;
@@ -7984,8 +8061,8 @@ grokdeclarator (const cp_declarator *declarator,
          {
            /* Friends are treated specially.  */
            if (ctype == current_class_type)
-             warning ("member functions are implicitly friends of their class");
-           else if (decl && DECL_NAME (decl))
+             warning (0, "member functions are implicitly friends of their class");
+           else if (decl && DECL_NAME (decl))
              {
                if (template_class_depth (current_class_type) == 0)
                  {
@@ -8100,10 +8177,10 @@ grokdeclarator (const cp_declarator *declarator,
          {
            if (storage_class == sc_static)
              pedwarn ("%<static%> specified invalid for function %qs "
-                       "declared out of global scope", name);
+                      "declared out of global scope", name);
            else
              pedwarn ("%<inline%> specifier invalid for function %qs "
-                       "declared out of global scope", name);
+                      "declared out of global scope", name);
          }
 
        if (ctype == NULL_TREE)
@@ -8142,7 +8219,7 @@ grokdeclarator (const cp_declarator *declarator,
            if (TREE_CODE (type) == METHOD_TYPE)
              {
                pedwarn ("cannot declare member function %qD to have "
-                         "static linkage", decl);
+                        "static linkage", decl);
                invalid_static = 1;
              }
            else if (current_function_decl)
@@ -8177,9 +8254,9 @@ grokdeclarator (const cp_declarator *declarator,
            DECL_CONTEXT (decl) = ctype;
            if (staticp == 1)
              {
-                pedwarn ("%<static%> may not be used when defining "
-                         "(as opposed to declaring) a static data member");
-               staticp = 0;
+               pedwarn ("%<static%> may not be used when defining "
+                        "(as opposed to declaring) a static data member");
+               staticp = 0;
                storage_class = sc_none;
              }
            if (storage_class == sc_register && TREE_STATIC (decl))
@@ -8189,9 +8266,9 @@ grokdeclarator (const cp_declarator *declarator,
              }
            if (storage_class == sc_extern && pedantic)
              {
-               pedwarn ("cannot explicitly declare member %q#D to have "
-                         "extern linkage",
-                         decl);
+               pedwarn ("cannot explicitly declare member %q#D to have "
+                        "extern linkage",
+                        decl);
                storage_class = sc_none;
              }
          }
@@ -8211,7 +8288,7 @@ grokdeclarator (const cp_declarator *declarator,
        when processing a template; we'll do this for the instantiated
        declaration based on the type of DECL.  */
     if (!processing_template_decl)
-      c_apply_type_quals_to_decl (type_quals, decl);
+      cp_apply_type_quals_to_decl (type_quals, decl);
 
     return decl;
   }
@@ -8229,11 +8306,11 @@ require_complete_types_for_parms (tree parms)
       if (dependent_type_p (TREE_TYPE (parms)))
        continue;
       if (VOID_TYPE_P (TREE_TYPE (parms)))
-        /* grokparms will have already issued an error.  */
-        TREE_TYPE (parms) = error_mark_node;
+       /* grokparms will have already issued an error.  */
+       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));
        }
     }
@@ -8333,10 +8410,10 @@ check_default_argument (tree decl, tree arg)
     {
       if (decl)
        error ("default argument for %q#D has type %qT",
-               decl, TREE_TYPE (arg));
+              decl, TREE_TYPE (arg));
       else
        error ("default argument for parameter of type %qT has type %qT",
-               decl_type, TREE_TYPE (arg));
+              decl_type, TREE_TYPE (arg));
 
       return error_mark_node;
     }
@@ -8386,32 +8463,32 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms)
       tree decl;
 
       if (parm == no_parameters)
-        break;
+       break;
 
       attrs = parm->decl_specifiers.attributes;
       parm->decl_specifiers.attributes = NULL_TREE;
       decl = grokdeclarator (parm->declarator, &parm->decl_specifiers,
                             PARM, init != NULL_TREE, &attrs);
       if (! decl || TREE_TYPE (decl) == error_mark_node)
-        continue;
+       continue;
 
       if (attrs)
        cplus_decl_attributes (&decl, attrs, 0);
 
       type = TREE_TYPE (decl);
       if (VOID_TYPE_P (type))
-        {
-          if (same_type_p (type, void_type_node)
-              && !DECL_NAME (decl) && !result && !parm->next && !ellipsis)
-            /* this is a parmlist of `(void)', which is ok.  */
-            break;
-          cxx_incomplete_type_error (decl, type);
+       {
+         if (same_type_p (type, void_type_node)
+             && !DECL_NAME (decl) && !result && !parm->next && !ellipsis)
+           /* this is a parmlist of `(void)', which is ok.  */
+           break;
+         cxx_incomplete_type_error (decl, type);
          /* It's not a good idea to actually create parameters of
             type `void'; other parts of the compiler assume that a
             void type terminates the parameter list.  */
          type = error_mark_node;
          TREE_TYPE (decl) = error_mark_node;
-        }
+       }
 
       if (type != error_mark_node)
        {
@@ -8433,20 +8510,20 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms)
              tree t = TREE_TYPE (type);
              int ptr = TYPE_PTR_P (type);
 
-              while (1)
-                {
-                  if (TYPE_PTR_P (t))
-                    ptr = 1;
-                  else if (TREE_CODE (t) != ARRAY_TYPE)
-                    break;
-                  else if (!TYPE_DOMAIN (t))
-                   break;
-                 t = TREE_TYPE (t);
-               }
+             while (1)
+               {
+                 if (TYPE_PTR_P (t))
+                   ptr = 1;
+                 else if (TREE_CODE (t) != ARRAY_TYPE)
+                   break;
+                 else if (!TYPE_DOMAIN (t))
+                   break;
+                 t = TREE_TYPE (t);
+               }
              if (TREE_CODE (t) == ARRAY_TYPE)
                error ("parameter %qD includes %s to array of unknown "
-                       "bound %qT",
-                       decl, ptr ? "pointer" : "reference", t);
+                      "bound %qT",
+                      decl, ptr ? "pointer" : "reference", t);
            }
 
          if (!any_error && init)
@@ -8496,7 +8573,7 @@ copy_fn_p (tree d)
 
   gcc_assert (DECL_FUNCTION_MEMBER_P (d));
 
-  if (DECL_TEMPLATE_INFO (d) 
+  if (DECL_TEMPLATE_INFO (d)
       && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d)))
     /* Instantiations of template member functions are never copy
        functions.  Note that member functions of templated classes are
@@ -8547,11 +8624,11 @@ void grok_special_member_properties (tree decl)
        {
          /* [class.copy]
 
-            A non-template constructor for class X is a copy
-            constructor if its first parameter is of type X&, const
-            X&, volatile X& or const volatile X&, and either there
-            are no other parameters or else all other parameters have
-            default arguments.  */
+            A non-template constructor for class X is a copy
+            constructor if its first parameter is of type X&, const
+            X&, volatile X& or const volatile X&, and either there
+            are no other parameters or else all other parameters have
+            default arguments.  */
          TYPE_HAS_INIT_REF (DECL_CONTEXT (decl)) = 1;
          if (ctor > 1)
            TYPE_HAS_CONST_INIT_REF (DECL_CONTEXT (decl)) = 1;
@@ -8563,9 +8640,9 @@ void grok_special_member_properties (tree decl)
     {
       /* [class.copy]
 
-        A non-template assignment operator for class X is a copy
-        assignment operator if its parameter is of type X, X&, const
-        X&, volatile X& or const volatile X&.  */
+        A non-template assignment operator for class X is a copy
+        assignment operator if its parameter is of type X, X&, const
+        X&, volatile X& or const volatile X&.  */
 
       int assop = copy_fn_p (decl);
 
@@ -8590,19 +8667,19 @@ grok_ctor_properties (tree ctype, tree decl)
     {
       /* [class.copy]
 
-        A declaration of a constructor for a class X is ill-formed if
-        its first parameter is of type (optionally cv-qualified) X
-        and either there are no other parameters or else all other
-        parameters have default arguments.
-
-        We *don't* complain about member template instantiations that
-        have this form, though; they can occur as we try to decide
-        what constructor to use during overload resolution.  Since
-        overload resolution will never prefer such a constructor to
-        the non-template copy constructor (which is either explicitly
-        or implicitly defined), there's no need to worry about their
-        existence.  Theoretically, they should never even be
-        instantiated, but that's hard to forestall.  */
+        A declaration of a constructor for a class X is ill-formed if
+        its first parameter is of type (optionally cv-qualified) X
+        and either there are no other parameters or else all other
+        parameters have default arguments.
+
+        We *don't* complain about member template instantiations that
+        have this form, though; they can occur as we try to decide
+        what constructor to use during overload resolution.  Since
+        overload resolution will never prefer such a constructor to
+        the non-template copy constructor (which is either explicitly
+        or implicitly defined), there's no need to worry about their
+        existence.  Theoretically, they should never even be
+        instantiated, but that's hard to forestall.  */
       error ("invalid constructor; you probably meant %<%T (const %T&)%>",
                ctype, ctype);
       return 0;
@@ -8618,7 +8695,7 @@ ambi_op_p (enum tree_code code)
 {
   return (code == INDIRECT_REF
          || code == ADDR_EXPR
-         || code == CONVERT_EXPR
+         || code == UNARY_PLUS_EXPR
          || code == NEGATE_EXPR
          || code == PREINCREMENT_EXPR
          || code == PREDECREMENT_EXPR);
@@ -8635,12 +8712,11 @@ unary_op_p (enum tree_code code)
          || code == TYPE_EXPR);
 }
 
-/* DECL is a declaration for an overloaded operator.  Returns true if
-   the declaration is valid; false otherwise.  If COMPLAIN is true,
+/* DECL is a declaration for an overloaded operator.  If COMPLAIN is true,
    errors are issued for invalid declarations.  */
 
-bool
-grok_op_properties (tree decl, int friendp, bool complain)
+void
+grok_op_properties (tree decl, bool complain)
 {
   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
   tree argtype;
@@ -8648,10 +8724,7 @@ grok_op_properties (tree decl, int friendp, bool complain)
   tree name = DECL_NAME (decl);
   enum tree_code operator_code;
   int arity;
-  bool ok;
-
-  /* Assume that the declaration is valid.  */
-  ok = true;
+  tree class_type;
 
   /* Count the number of arguments.  */
   for (argtype = argtypes, arity = 0;
@@ -8659,8 +8732,9 @@ grok_op_properties (tree decl, int friendp, bool complain)
        argtype = TREE_CHAIN (argtype))
     ++arity;
 
-  if (current_class_type == NULL_TREE)
-    friendp = 1;
+  class_type = DECL_CONTEXT (decl);
+  if (class_type && !CLASS_TYPE_P (class_type))
+    class_type = NULL_TREE;
 
   if (DECL_CONV_FN_P (decl))
     operator_code = TYPE_EXPR;
@@ -8689,30 +8763,28 @@ grok_op_properties (tree decl, int friendp, bool complain)
   gcc_assert (operator_code != LAST_CPLUS_TREE_CODE);
   SET_OVERLOADED_OPERATOR_CODE (decl, operator_code);
 
-  if (! friendp)
-    {
-      switch (operator_code)
-       {
-       case NEW_EXPR:
-         TYPE_HAS_NEW_OPERATOR (current_class_type) = 1;
-         break;
+  if (class_type)
+    switch (operator_code)
+      {
+      case NEW_EXPR:
+       TYPE_HAS_NEW_OPERATOR (class_type) = 1;
+       break;
 
-       case DELETE_EXPR:
-         TYPE_GETS_DELETE (current_class_type) |= 1;
-         break;
+      case DELETE_EXPR:
+       TYPE_GETS_DELETE (class_type) |= 1;
+       break;
 
-       case VEC_NEW_EXPR:
-         TYPE_HAS_ARRAY_NEW_OPERATOR (current_class_type) = 1;
-         break;
+      case VEC_NEW_EXPR:
+       TYPE_HAS_ARRAY_NEW_OPERATOR (class_type) = 1;
+       break;
 
-       case VEC_DELETE_EXPR:
-         TYPE_GETS_DELETE (current_class_type) |= 2;
-         break;
+      case VEC_DELETE_EXPR:
+       TYPE_GETS_DELETE (class_type) |= 2;
+       break;
 
-       default:
-         break;
-       }
-    }
+      default:
+       break;
+      }
 
     /* [basic.std.dynamic.allocation]/1:
 
@@ -8749,14 +8821,20 @@ grok_op_properties (tree decl, int friendp, bool complain)
              || operator_code == COMPONENT_REF
              || operator_code == ARRAY_REF
              || operator_code == NOP_EXPR)
-           error ("%qD must be a nonstatic member function", decl);
+           {
+             error ("%qD must be a nonstatic member function", decl);
+             return;
+           }
          else
            {
              tree p;
 
              if (DECL_STATIC_FUNCTION_P (decl))
-               error ("%qD must be either a non-static member "
-                       "function or a non-member function", decl);
+               {
+                 error ("%qD must be either a non-static member "
+                        "function or a non-member function", decl);
+                 return;
+               }
 
              for (p = argtypes; p && p != void_list_node; p = TREE_CHAIN (p))
                {
@@ -8771,12 +8849,11 @@ grok_op_properties (tree decl, int friendp, bool complain)
              if (!p || p == void_list_node)
                {
                  if (!complain)
-                   return false;
+                   return;
 
                  error ("%qD must have an argument of class or "
                         "enumerated type",
                         decl);
-                 ok = false;
                }
            }
        }
@@ -8784,34 +8861,40 @@ grok_op_properties (tree decl, int friendp, bool complain)
       /* There are no restrictions on the arguments to an overloaded
         "operator ()".  */
       if (operator_code == CALL_EXPR)
-       return ok;
+       return;
 
-      if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl))
+      /* Warn about conversion operators that will never be used.  */
+      if (IDENTIFIER_TYPENAME_P (name)
+         && ! DECL_TEMPLATE_INFO (decl)
+         && warn_conversion
+         /* Warn only declaring the function; there is no need to
+            warn again about out-of-class definitions.  */
+         && class_type == current_class_type)
        {
          tree t = TREE_TYPE (name);
-         if (! friendp)
-           {
-             int ref = (TREE_CODE (t) == REFERENCE_TYPE);
-             const char *what = 0;
+         int ref = (TREE_CODE (t) == REFERENCE_TYPE);
+         const char *what = 0;
 
-             if (ref)
-               t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
+         if (ref)
+           t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
 
-             if (TREE_CODE (t) == VOID_TYPE)
-               what = "void";
-             else if (t == current_class_type)
+         if (TREE_CODE (t) == VOID_TYPE)
+           what = "void";
+         else if (class_type)
+           {
+             if (t == class_type)
                what = "the same type";
              /* Don't force t to be complete here.  */
              else if (IS_AGGR_TYPE (t)
                       && COMPLETE_TYPE_P (t)
-                      && DERIVED_FROM_P (t, current_class_type))
+                      && DERIVED_FROM_P (t, class_type))
                what = "a base class";
-
-             if (what && warn_conversion)
-               warning ("conversion to %s%s will never use a type "
-                         "conversion operator",
-                        ref ? "a reference to " : "", what);
            }
+
+         if (what)
+           warning (0, "conversion to %s%s will never use a type "
+                    "conversion operator",
+                    ref ? "a reference to " : "", what);
        }
       if (operator_code == COND_EXPR)
        {
@@ -8838,7 +8921,7 @@ grok_op_properties (tree decl, int friendp, bool complain)
                  operator_code = BIT_AND_EXPR;
                  break;
 
-               case CONVERT_EXPR:
+               case UNARY_PLUS_EXPR:
                  operator_code = PLUS_EXPR;
                  break;
 
@@ -8900,13 +8983,13 @@ grok_op_properties (tree decl, int friendp, bool complain)
                  if (TREE_CODE (ret) != REFERENCE_TYPE
                      || !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)),
                                       arg))
-                   warning ("prefix %qD should return %qT", decl,
-                             build_reference_type (arg));
+                   warning (0, "prefix %qD should return %qT", decl,
+                            build_reference_type (arg));
                }
              else
                {
                  if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg))
-                   warning ("postfix %qD should return %qT", decl, arg);
+                   warning (0, "postfix %qD should return %qT", decl, arg);
                }
            }
        }
@@ -8935,8 +9018,8 @@ grok_op_properties (tree decl, int friendp, bool complain)
              && (operator_code == TRUTH_ANDIF_EXPR
                  || operator_code == TRUTH_ORIF_EXPR
                  || operator_code == COMPOUND_EXPR))
-           warning ("user-defined %qD always evaluates both arguments",
-                     decl);
+           warning (0, "user-defined %qD always evaluates both arguments",
+                    decl);
        }
 
       /* Effective C++ rule 23.  */
@@ -8949,27 +9032,26 @@ grok_op_properties (tree decl, int friendp, bool complain)
              || operator_code == MULT_EXPR
              || operator_code == TRUNC_MOD_EXPR)
          && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == REFERENCE_TYPE)
-       warning ("%qD should return by value", decl);
+       warning (0, "%qD should return by value", decl);
 
       /* [over.oper]/8 */
       for (; argtypes && argtypes != void_list_node;
-          argtypes = TREE_CHAIN (argtypes))
-        if (TREE_PURPOSE (argtypes))
-          {
-            TREE_PURPOSE (argtypes) = NULL_TREE;
-            if (operator_code == POSTINCREMENT_EXPR
+         argtypes = TREE_CHAIN (argtypes))
+       if (TREE_PURPOSE (argtypes))
+         {
+           TREE_PURPOSE (argtypes) = NULL_TREE;
+           if (operator_code == POSTINCREMENT_EXPR
                || operator_code == POSTDECREMENT_EXPR)
-              {
-                if (pedantic)
-                  pedwarn ("%qD cannot have default arguments", decl);
-              }
-            else
-              error ("%qD cannot have default arguments", decl);
-          }
+             {
+               if (pedantic)
+                 pedwarn ("%qD cannot have default arguments", decl);
+             }
+           else
+             error ("%qD cannot have default arguments", decl);
+         }
 
     }
 
-  return ok;
 }
 \f
 /* Return a string giving the keyword associate with CODE.  */
@@ -9038,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
@@ -9047,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
@@ -9055,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
@@ -9069,7 +9151,6 @@ check_elaborated_type_specifier (enum tag_types tag_code,
           void f(class C);             // No template header here
 
         then the required template argument is missing.  */
-
       error ("template argument required for %<%s %T%>",
             tag_name (tag_code),
             DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)));
@@ -9091,7 +9172,19 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
   tree t;
   tree decl;
   if (scope == ts_global)
-    decl = lookup_name (name, 2);
+    {
+      /* First try ordinary name lookup, ignoring hidden class name
+        injected via friend declaration.  */
+      decl = lookup_name (name, 2);
+      /* If that fails, the name will be placed in the smallest
+        non-class, non-function-prototype scope according to 3.3.1/5.
+        We may already have a hidden name declared as friend in this
+        scope.  So lookup again but not ignoring hidden name.
+        If we find one, that name will be made visible rather than
+        creating a new tag.  */
+      if (!decl)
+       decl = lookup_type_scope (name, ts_within_enclosing_non_class);
+    }
   else
     decl = lookup_type_scope (name, scope);
 
@@ -9251,8 +9344,7 @@ xref_tag (enum tag_types tag_code, tree name,
        {
          t = make_aggr_type (code);
          TYPE_CONTEXT (t) = context;
-         /* pushtag only cares whether SCOPE is zero or not.  */
-         t = pushtag (name, t, scope != ts_current);
+         t = pushtag (name, t, scope);
        }
     }
   else
@@ -9266,6 +9358,20 @@ xref_tag (enum tag_types tag_code, tree name,
          error ("redeclaration of %qT as a non-template", t);
          t = error_mark_node;
        }
+
+      /* Make injected friend class visible.  */
+      if (scope != ts_within_enclosing_non_class
+         && hidden_name_p (TYPE_NAME (t)))
+       {
+         DECL_ANTICIPATED (TYPE_NAME (t)) = 0;
+         DECL_FRIEND_P (TYPE_NAME (t)) = 0;
+
+         if (TYPE_TEMPLATE_INFO (t))
+           {
+             DECL_ANTICIPATED (TYPE_TI_TEMPLATE (t)) = 0;
+             DECL_FRIEND_P (TYPE_TI_TEMPLATE (t)) = 0;
+           }
+       }
     }
 
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
@@ -9351,7 +9457,7 @@ xref_basetypes (tree ref, tree base_list)
 
   if (max_bases)
     {
-      BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, max_bases);
+      BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, max_bases);
       /* An aggregate cannot have baseclasses.  */
       CLASSTYPE_NON_AGGREGATE (ref) = 1;
 
@@ -9367,7 +9473,7 @@ xref_basetypes (tree ref, tree base_list)
 
   if (max_vbases)
     {
-      CLASSTYPE_VBASECLASSES (ref) = VEC_alloc (tree, max_vbases);
+      CLASSTYPE_VBASECLASSES (ref) = VEC_alloc (tree, gc, max_vbases);
 
       if (TYPE_FOR_JAVA (ref))
        error ("Java class %qT cannot have virtual bases", ref);
@@ -9416,7 +9522,7 @@ xref_basetypes (tree ref, tree base_list)
          CLASSTYPE_REPEATED_BASE_P (ref)
            |= CLASSTYPE_REPEATED_BASE_P (basetype);
        }
-      
+
       /* We must do this test after we've seen through a typedef
         type.  */
       if (TYPE_MARKED_P (basetype))
@@ -9507,7 +9613,7 @@ start_enum (tree name)
        name = make_anon_name ();
 
       enumtype = make_node (ENUMERAL_TYPE);
-      enumtype = pushtag (name, enumtype, 0);
+      enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
     }
 
   return enumtype;
@@ -9679,7 +9785,7 @@ finish_enum (tree enumtype)
 
       /* Do not clobber shared ints.  */
       value = copy_node (value);
-      
+
       TREE_TYPE (value) = enumtype;
       DECL_INITIAL (decl) = value;
       TREE_VALUE (values) = value;
@@ -9754,7 +9860,7 @@ build_enumerator (tree name, tree value, tree enumtype)
              bool overflowed;
 
              /* The next value is the previous value plus one.  We can
-                safely assume that the previous value is an INTEGER_CST.
+                safely assume that the previous value is an INTEGER_CST.
                 add_double doesn't know the type of the target expression,
                 so we must check with int_fits_type_p as well.  */
              prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
@@ -9887,7 +9993,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   int doing_friend = 0;
   struct cp_binding_level *bl;
   tree current_function_parms;
-  struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename));
+  struct c_fileinfo *finfo
+    = get_fileinfo (lbasename (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1))));
 
   /* Sanity check.  */
   gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE);
@@ -9914,7 +10021,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
   if (DECL_DECLARED_INLINE_P (decl1)
       && lookup_attribute ("noinline", attrs))
-    warning ("%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
@@ -9951,7 +10058,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   if (warn_ecpp
       && DECL_OVERLOADED_OPERATOR_P (decl1) == NOP_EXPR
       && TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE)
-    warning ("%<operator=%> should return a reference to %<*this%>");
+    warning (0, "%<operator=%> should return a reference to %<*this%>");
 
   /* Make the init_value nonzero so pushdecl knows this is not tentative.
      error_mark_node is replaced below (in poplevel) with the BLOCK.  */
@@ -9967,7 +10074,12 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
      class scope, current_class_type will be NULL_TREE until set above
      by push_nested_class.)  */
   if (processing_template_decl)
-    decl1 = push_template_decl (decl1);
+    {
+      /* FIXME: Handle error_mark_node more gracefully.  */
+      tree newdecl1 = push_template_decl (decl1);
+      if (newdecl1 != error_mark_node)
+       decl1 = newdecl1;
+    }
 
   /* We are now in the scope of the function being defined.  */
   current_function_decl = decl1;
@@ -9995,7 +10107,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       DECL_IGNORED_P (resdecl) = 1;
       DECL_RESULT (decl1) = resdecl;
 
-      c_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
+      cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
     }
 
   /* Initialize RTL machinery.  We cannot do this until
@@ -10134,7 +10246,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       DECL_NOT_REALLY_EXTERN (decl1) = 0;
       DECL_INTERFACE_KNOWN (decl1) = 1;
       /* If this function is in an interface implemented in this file,
-        make sure that the backend knows to emit this function 
+        make sure that the backend knows to emit this function
         here.  */
       if (!DECL_EXTERNAL (decl1))
        mark_needed (decl1);
@@ -10569,7 +10681,11 @@ finish_function (int flags)
          /* Hack.  We don't want the middle-end to warn that this
             return is unreachable, so put the statement on the
             special line 0.  */
+#ifdef USE_MAPPED_LOCATION
+         SET_EXPR_LOCATION (stmt, UNKNOWN_LOCATION);
+#else
          annotate_with_file_line (stmt, input_filename, 0);
+#endif
        }
 
       /* Finish dealing with exception specifiers.  */
@@ -10605,7 +10721,7 @@ finish_function (int flags)
       gcc_assert (errorcount);
 
       /* Throw away the broken statement tree and extra binding
-         levels.  */
+        levels.  */
       DECL_SAVED_TREE (fndecl) = alloc_stmt_list ();
 
       while (current_binding_level->kind != sk_function_parms)
@@ -10675,7 +10791,7 @@ finish_function (int flags)
       /* Structor return values (if any) are set by the compiler.  */
       && !DECL_CONSTRUCTOR_P (fndecl)
       && !DECL_DESTRUCTOR_P (fndecl))
-    warning ("no return statement in function returning non-void");
+    warning (0, "no return statement in function returning non-void");
 
   /* Store the end of the function, so that we get good line number
      info for the epilogue.  */
@@ -10753,7 +10869,7 @@ finish_function (int flags)
 
 tree
 start_method (cp_decl_specifier_seq *declspecs,
-              const cp_declarator *declarator, tree attrlist)
+             const cp_declarator *declarator, tree attrlist)
 {
   tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
                                &attrlist);
@@ -10868,7 +10984,7 @@ finish_method (tree decl)
      for String.cc in libg++.  */
   if (DECL_FRIEND_P (fndecl))
     {
-      VEC_safe_push (tree, CLASSTYPE_INLINE_FRIENDS (current_class_type),
+      VEC_safe_push (tree, gc, CLASSTYPE_INLINE_FRIENDS (current_class_type),
                     fndecl);
       decl = void_type_node;
     }
@@ -10918,16 +11034,11 @@ complete_vars (tree type)
       if (same_type_p (type, TREE_PURPOSE (*list)))
        {
          tree var = TREE_VALUE (*list);
+         tree type = TREE_TYPE (var);
          /* Complete the type of the variable.  The VAR_DECL itself
             will be laid out in expand_expr.  */
-         complete_type (TREE_TYPE (var));
-         /* An object declared 'const' is only readonly after it is
-            initialized.  We don't have any way of expressing this currently,
-            so we need to be conservative and unset TREE_READONLY for types
-            with constructors.  Otherwise aliasing code will ignore stores in
-            an inline constructor.  */
-         if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (var)))
-           TREE_READONLY (var) = 0;
+         complete_type (type);
+         cp_apply_type_quals_to_decl (cp_type_quals (type), var);
          /* Remove this entry from the list.  */
          *list = TREE_CHAIN (*list);
        }
@@ -11061,7 +11172,7 @@ cp_tree_node_structure (union lang_tree_node * t)
     case TEMPLATE_PARM_INDEX:  return TS_CP_TPI;
     case TINST_LEVEL:          return TS_CP_TINST_LEVEL;
     case PTRMEM_CST:           return TS_CP_PTRMEM;
-    case BASELINK:              return TS_CP_BASELINK;
+    case BASELINK:             return TS_CP_BASELINK;
     default:                   return TS_CP_GENERIC;
     }
 }
@@ -11096,7 +11207,22 @@ cxx_comdat_group (tree decl)
   /* For all other DECLs, the COMDAT group is the mangled name of the
      declaration itself.  */
   else
-    name = DECL_ASSEMBLER_NAME (decl);
+    {
+      while (DECL_THUNK_P (decl))
+       {
+         /* If TARGET_USE_LOCAL_THUNK_ALIAS_P, use_thunk puts the thunk
+            into the same section as the target function.  In that case
+            we must return target's name.  */
+         tree target = THUNK_TARGET (decl);
+         if (TARGET_USE_LOCAL_THUNK_ALIAS_P (target)
+             && DECL_SECTION_NAME (target) != NULL
+             && DECL_ONE_ONLY (target))
+           decl = target;
+         else
+           break;
+       }
+      name = DECL_ASSEMBLER_NAME (decl);
+    }
 
   return IDENTIFIER_POINTER (name);
 }