OSDN Git Service

libgo: Define CC_FOR_BUILD in Makefile.
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index c2c2a89..3ed3c46 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -34,36 +34,32 @@ along with GCC; see the file COPYING3.  If not see
 #include "intl.h"
 #include "tree.h"
 #include "tree-inline.h"
-#include "rtl.h"
 #include "flags.h"
 #include "function.h"
 #include "output.h"
-#include "expr.h"
 #include "c-tree.h"
 #include "toplev.h"
-#include "ggc.h"
 #include "tm_p.h"
 #include "cpplib.h"
 #include "target.h"
 #include "debug.h"
 #include "opts.h"
 #include "timevar.h"
-#include "c-common.h"
-#include "c-pragma.h"
+#include "c-family/c-common.h"
+#include "c-family/c-objc.h"
+#include "c-family/c-pragma.h"
+#include "c-lang.h"
 #include "langhooks.h"
 #include "tree-mudflap.h"
-#include "gimple.h"
 #include "tree-iterator.h"
-#include "diagnostic.h"
+#include "diagnostic-core.h"
 #include "tree-dump.h"
 #include "cgraph.h"
 #include "hashtab.h"
-#include "libfuncs.h"
-#include "except.h"
 #include "langhooks-def.h"
 #include "pointer-set.h"
-#include "gimple.h"
 #include "plugin.h"
+#include "c-family/c-ada-spec.h"
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
@@ -91,9 +87,6 @@ tree pending_invalid_xref;
 /* File and line to appear in the eventual error message.  */
 location_t pending_invalid_xref_location;
 
-/* True means we've initialized exception handling.  */
-bool c_eh_initialized_p;
-
 /* The file and line that the prototype came from if this is an
    old-style definition; used for diagnostics in
    store_parm_decls_oldstyle.  */
@@ -126,21 +119,6 @@ static GTY(()) struct stmt_tree_s c_stmt_tree;
 tree c_break_label;
 tree c_cont_label;
 
-/* True if we are currently parsing the fields of a struct or
-   union.  */
-
-static bool in_struct;
-
-/* A list of types defined in the current struct or union.  */
-
-static VEC(tree,heap) *struct_types;
-
-/* Linked list of TRANSLATION_UNIT_DECLS for the translation units
-   included in this invocation.  Note that the current translation
-   unit is not included in this list.  */
-
-static GTY(()) tree all_translation_units;
-
 /* A list of decls to be made automatically visible in each file scope.  */
 static GTY(()) tree visible_builtins;
 
@@ -169,10 +147,6 @@ static int warn_about_return_type;
 
 static bool undef_nested_function;
 
-/* True means global_bindings_p should return false even if the scope stack
-   says we are in file scope.  */
-bool c_override_global_bindings_to_false;
-
 \f
 /* Each c_binding structure describes one binding of an identifier to
    a decl.  All the decls in a scope - irrespective of namespace - are
@@ -223,7 +197,7 @@ struct GTY((chain_next ("%h.prev"))) c_binding {
   BOOL_BITFIELD invisible : 1;  /* normal lookup should ignore this binding */
   BOOL_BITFIELD nested : 1;     /* do not set DECL_CONTEXT when popping */
   BOOL_BITFIELD inner_comp : 1; /* incomplete array completed in inner scope */
-  /* one free bit */
+  BOOL_BITFIELD in_struct : 1; /* currently defined as struct field */
   location_t locus;            /* location for nested bindings */
 };
 #define B_IN_SCOPE(b1, b2) ((b1)->depth == (b2)->depth)
@@ -264,7 +238,7 @@ extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate
 /* The resulting tree type.  */
 
 union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
-       chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) TREE_CHAIN (&%h.generic))")))  lang_tree_node
+       chain_next ("(union lang_tree_node *) c_tree_chain_next (&%h.generic)"))) lang_tree_node
  {
   union tree_node GTY ((tag ("0"),
                        desc ("tree_node_structure (&%h)")))
@@ -426,6 +400,13 @@ struct GTY((chain_next ("%h.outer"))) c_scope {
      up searching for labels when popping scopes, particularly since
      labels are normally only found at function scope.  */
   BOOL_BITFIELD has_label_bindings : 1;
+
+  /* True if we should issue a warning if a goto statement crosses any
+     of the bindings.  We still need to check the list of bindings to
+     find the specific ones we need to warn about.  This is true if
+     decl_jump_unsafe would return true for any of the bindings.  This
+     is used to avoid looping over all the bindings unnecessarily.  */
+  BOOL_BITFIELD has_jump_unsafe_decl : 1;
 };
 
 /* The scope currently in effect.  */
@@ -513,6 +494,34 @@ static bool keep_next_level_flag;
 
 static bool next_is_function_body;
 
+/* A VEC of pointers to c_binding structures.  */
+
+typedef struct c_binding *c_binding_ptr;
+DEF_VEC_P(c_binding_ptr);
+DEF_VEC_ALLOC_P(c_binding_ptr,heap);
+
+/* Information that we keep for a struct or union while it is being
+   parsed.  */
+
+struct c_struct_parse_info
+{
+  /* If warn_cxx_compat, a list of types defined within this
+     struct.  */
+  VEC(tree,heap) *struct_types;
+  /* If warn_cxx_compat, a list of field names which have bindings,
+     and which are defined in this struct, but which are not defined
+     in any enclosing struct.  This is used to clear the in_struct
+     field of the c_bindings structure.  */
+  VEC(c_binding_ptr,heap) *fields;
+  /* If warn_cxx_compat, a list of typedef names used when defining
+     fields in this struct.  */
+  VEC(tree,heap) *typedefs_seen;
+};
+
+/* Information for the struct or union currently being parsed, or
+   NULL if not parsing a struct or union.  */
+static struct c_struct_parse_info *struct_parse_info;
+
 /* Forward declarations.  */
 static tree lookup_name_in_scope (tree, struct c_scope *);
 static tree c_make_fname_decl (location_t, tree, int);
@@ -543,11 +552,38 @@ add_stmt (tree t)
 
   /* Add T to the statement-tree.  Non-side-effect statements need to be
      recorded during statement expressions.  */
+  if (!building_stmt_list_p ())
+    push_stmt_list ();
   append_to_statement_list_force (t, &cur_stmt_list);
 
   return t;
 }
 \f
+/* Return true if we will want to say something if a goto statement
+   crosses DECL.  */
+
+static bool
+decl_jump_unsafe (tree decl)
+{
+  if (error_operand_p (decl))
+    return false;
+
+  /* Always warn about crossing variably modified types.  */
+  if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == TYPE_DECL)
+      && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
+    return true;
+
+  /* Otherwise, only warn if -Wgoto-misses-init and this is an
+     initialized automatic decl.  */
+  if (warn_jump_misses_init
+      && TREE_CODE (decl) == VAR_DECL
+      && !TREE_STATIC (decl)
+      && DECL_INITIAL (decl) != NULL_TREE)
+    return true;
+
+  return false;
+}
+\f
 
 void
 c_print_identifier (FILE *file, tree node, int indent)
@@ -559,7 +595,7 @@ c_print_identifier (FILE *file, tree node, int indent)
     {
       tree rid = ridpointers[C_RID_CODE (node)];
       indent_to (file, indent + 4);
-      fprintf (file, "rid %p \"%s\"",
+      fprintf (file, "rid " HOST_PTR_PRINTF " \"%s\"",
               (void *) rid, IDENTIFIER_POINTER (rid));
     }
 }
@@ -579,7 +615,7 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible,
       binding_freelist = b->prev;
     }
   else
-    b = GGC_NEW (struct c_binding);
+    b = ggc_alloc_c_binding ();
 
   b->shadowed = 0;
   b->decl = decl;
@@ -588,6 +624,7 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible,
   b->invisible = invisible;
   b->nested = nested;
   b->inner_comp = 0;
+  b->in_struct = 0;
   b->locus = locus;
 
   b->u.type = NULL;
@@ -595,6 +632,9 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible,
   b->prev = scope->bindings;
   scope->bindings = b;
 
+  if (decl_jump_unsafe (decl))
+    scope->has_jump_unsafe_decl = 1;
+
   if (!name)
     return;
 
@@ -692,7 +732,7 @@ void
 record_inline_static (location_t loc, tree func, tree decl,
                      enum c_inline_static_type type)
 {
-  struct c_inline_static *csi = GGC_NEW (struct c_inline_static);
+  struct c_inline_static *csi = ggc_alloc_c_inline_static ();
   csi->location = loc;
   csi->function = func;
   csi->static_decl = decl;
@@ -751,31 +791,6 @@ set_spot_bindings (struct c_spot_bindings *p, bool defining)
   p->left_stmt_expr = false;
 }
 
-/* Return true if we will want to say something if a goto statement
-   crosses DECL.  */
-
-static bool
-decl_jump_unsafe (tree decl)
-{
-  if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
-    return false;
-
-  /* Always warn about crossing variably modified types.  */
-  if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == TYPE_DECL)
-      && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
-    return true;
-
-  /* Otherwise, only warn if -Wgoto-misses-init and this is an
-     initialized automatic decl.  */
-  if (warn_jump_misses_init
-      && TREE_CODE (decl) == VAR_DECL
-      && !TREE_STATIC (decl)
-      && DECL_INITIAL (decl) != NULL_TREE)
-    return true;
-
-  return false;
-}
-
 /* Update spot bindings P as we pop out of SCOPE.  Return true if we
    should push decls for a label.  */
 
@@ -828,14 +843,12 @@ objc_mark_locals_volatile (void *enclosing_blk)
     }
 }
 
-/* Nonzero if we are currently in file scope.  */
+/* Return true if we are in the global binding level.  */
 
-int
+bool
 global_bindings_p (void)
 {
-  return (current_scope == file_scope && !c_override_global_bindings_to_false
-         ? -1
-         : 0);
+  return current_scope == file_scope;
 }
 
 void
@@ -916,7 +929,7 @@ push_scope (void)
          scope_freelist = scope->outer;
        }
       else
-       scope = GGC_CNEW (struct c_scope);
+       scope = ggc_alloc_cleared_c_scope ();
 
       /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes.  */
       if (current_scope)
@@ -962,6 +975,7 @@ update_label_decls (struct c_scope *scope)
            {
              struct c_label_vars *label_vars;
              struct c_binding *b1;
+             bool hjud;
              unsigned int ix;
              struct c_goto_bindings *g;
 
@@ -970,26 +984,32 @@ update_label_decls (struct c_scope *scope)
              label_vars = b->u.label;
 
              b1 = label_vars->label_bindings.bindings_in_scope;
+             if (label_vars->label_bindings.scope == NULL)
+               hjud = false;
+             else
+               hjud = label_vars->label_bindings.scope->has_jump_unsafe_decl;
              if (update_spot_bindings (scope, &label_vars->label_bindings))
                {
                  /* This label is defined in this scope.  */
-                 for (; b1 != NULL;  b1 = b1->prev)
+                 if (hjud)
                    {
-                     /* A goto from later in the function to this
-                        label will never see the initialization of
-                        B1, if any.  Save it to issue a warning if
-                        needed.  */
-                     if (decl_jump_unsafe (b1->decl))
-                       VEC_safe_push (tree, gc, label_vars->decls_in_scope,
-                                      b1->decl);
+                     for (; b1 != NULL; b1 = b1->prev)
+                       {
+                         /* A goto from later in the function to this
+                            label will never see the initialization
+                            of B1, if any.  Save it to issue a
+                            warning if needed.  */
+                         if (decl_jump_unsafe (b1->decl))
+                           VEC_safe_push (tree, gc,
+                                          label_vars->decls_in_scope,
+                                          b1->decl);
+                       }
                    }
                }
 
              /* Update the bindings of any goto statements associated
                 with this label.  */
-             for (ix = 0;
-                  VEC_iterate (c_goto_bindings_p, label_vars->gotos, ix, g);
-                  ++ix)
+             FOR_EACH_VEC_ELT (c_goto_bindings_p, label_vars->gotos, ix, g)
                update_spot_bindings (scope, &g->goto_bindings);
            }
        }
@@ -1062,10 +1082,7 @@ pop_scope (void)
     context = current_function_decl;
   else if (scope == file_scope)
     {
-      tree file_decl = build_decl (UNKNOWN_LOCATION,
-                                  TRANSLATION_UNIT_DECL, 0, 0);
-      TREE_CHAIN (file_decl) = all_translation_units;
-      all_translation_units = file_decl;
+      tree file_decl = build_translation_unit_decl (NULL_TREE);
       context = file_decl;
     }
   else
@@ -1084,11 +1101,11 @@ pop_scope (void)
              error ("label %q+D used but not defined", p);
              DECL_INITIAL (p) = error_mark_node;
            }
-         else 
+         else
            warn_for_unused_label (p);
 
          /* Labels go in BLOCK_VARS.  */
-         TREE_CHAIN (p) = BLOCK_VARS (block);
+         DECL_CHAIN (p) = BLOCK_VARS (block);
          BLOCK_VARS (block) = p;
          gcc_assert (I_LABEL_BINDING (b->id) == b);
          I_LABEL_BINDING (b->id) = b->shadowed;
@@ -1146,14 +1163,21 @@ pop_scope (void)
 
        case VAR_DECL:
          /* Warnings for unused variables.  */
-         if (!TREE_USED (p)
+         if ((!TREE_USED (p) || !DECL_READ_P (p))
              && !TREE_NO_WARNING (p)
              && !DECL_IN_SYSTEM_HEADER (p)
              && DECL_NAME (p)
              && !DECL_ARTIFICIAL (p)
              && scope != file_scope
              && scope != external_scope)
-           warning (OPT_Wunused_variable, "unused variable %q+D", p);
+           {
+             if (!TREE_USED (p))
+               warning (OPT_Wunused_variable, "unused variable %q+D", p);
+             else if (DECL_CONTEXT (p) == current_function_decl)
+               warning_at (DECL_SOURCE_LOCATION (p),
+                           OPT_Wunused_but_set_variable,
+                           "variable %qD set but not used", p);
+           }
 
          if (b->inner_comp)
            {
@@ -1169,7 +1193,7 @@ pop_scope (void)
             binding in the home scope.  */
          if (!b->nested)
            {
-             TREE_CHAIN (p) = BLOCK_VARS (block);
+             DECL_CHAIN (p) = BLOCK_VARS (block);
              BLOCK_VARS (block) = p;
            }
          else if (VAR_OR_FUNCTION_DECL_P (p))
@@ -1192,18 +1216,17 @@ pop_scope (void)
                }
              if (b->locus != UNKNOWN_LOCATION)
                DECL_SOURCE_LOCATION (extp) = b->locus;
-             TREE_CHAIN (extp) = BLOCK_VARS (block);
+             DECL_CHAIN (extp) = BLOCK_VARS (block);
              BLOCK_VARS (block) = extp;
            }
-         /* If this is the file scope, and we are processing more
-            than one translation unit in this compilation, set
-            DECL_CONTEXT of each decl to the TRANSLATION_UNIT_DECL.
-            This makes same_translation_unit_p work, and causes
-            static declarations to be given disambiguating suffixes.  */
-         if (scope == file_scope && num_in_fnames > 1)
+         /* If this is the file scope set DECL_CONTEXT of each decl to
+            the TRANSLATION_UNIT_DECL.  This makes same_translation_unit_p
+            work.  */
+         if (scope == file_scope)
            {
              DECL_CONTEXT (p) = context;
-             if (TREE_CODE (p) == TYPE_DECL)
+             if (TREE_CODE (p) == TYPE_DECL
+                 && TREE_TYPE (p) != error_mark_node)
                set_type_context (TREE_TYPE (p), context);
            }
 
@@ -1274,7 +1297,7 @@ push_file_scope (void)
 
   start_fname_decls ();
 
-  for (decl = visible_builtins; decl; decl = TREE_CHAIN (decl))
+  for (decl = visible_builtins; decl; decl = DECL_CHAIN (decl))
     bind (DECL_NAME (decl), decl, file_scope,
          /*invisible=*/false, /*nested=*/true, DECL_SOURCE_LOCATION (decl));
 }
@@ -1307,7 +1330,6 @@ pop_file_scope (void)
   file_scope = 0;
 
   maybe_apply_pending_pragma_weaks ();
-  cgraph_finalize_compilation_unit ();
 }
 \f
 /* Adjust the bindings for the start of a statement expression.  */
@@ -1334,9 +1356,7 @@ c_bindings_start_stmt_expr (struct c_spot_bindings* switch_bindings)
            continue;
          label_vars = b->u.label;
          ++label_vars->label_bindings.stmt_exprs;
-         for (ix = 0;
-              VEC_iterate (c_goto_bindings_p, label_vars->gotos, ix, g);
-              ++ix)
+         FOR_EACH_VEC_ELT (c_goto_bindings_p, label_vars->gotos, ix, g)
            ++g->goto_bindings.stmt_exprs;
        }
     }
@@ -1374,9 +1394,7 @@ c_bindings_end_stmt_expr (struct c_spot_bindings *switch_bindings)
              label_vars->label_bindings.left_stmt_expr = true;
              label_vars->label_bindings.stmt_exprs = 0;
            }
-         for (ix = 0;
-              VEC_iterate (c_goto_bindings_p, label_vars->gotos, ix, g);
-              ++ix)
+         FOR_EACH_VEC_ELT (c_goto_bindings_p, label_vars->gotos, ix, g)
            {
              --g->goto_bindings.stmt_exprs;
              if (g->goto_bindings.stmt_exprs < 0)
@@ -1498,9 +1516,8 @@ diagnose_arglist_conflict (tree newdecl, tree olddecl,
 
   if (TREE_CODE (olddecl) != FUNCTION_DECL
       || !comptypes (TREE_TYPE (oldtype), TREE_TYPE (newtype))
-      || !((TYPE_ARG_TYPES (oldtype) == 0 && DECL_INITIAL (olddecl) == 0)
-          ||
-          (TYPE_ARG_TYPES (newtype) == 0 && DECL_INITIAL (newdecl) == 0)))
+      || !((!prototype_p (oldtype) && DECL_INITIAL (olddecl) == 0)
+          || (!prototype_p (newtype) && DECL_INITIAL (newdecl) == 0)))
     return;
 
   t = TYPE_ARG_TYPES (oldtype);
@@ -1729,8 +1746,35 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
        }
       else
        {
-         if (TYPE_QUALS (newtype) != TYPE_QUALS (oldtype))
-           error ("conflicting type qualifiers for %q+D", newdecl);
+         int new_quals = TYPE_QUALS (newtype);
+         int old_quals = TYPE_QUALS (oldtype);
+
+         if (new_quals != old_quals)
+           {
+             addr_space_t new_addr = DECODE_QUAL_ADDR_SPACE (new_quals);
+             addr_space_t old_addr = DECODE_QUAL_ADDR_SPACE (old_quals);
+             if (new_addr != old_addr)
+               {
+                 if (ADDR_SPACE_GENERIC_P (new_addr))
+                   error ("conflicting named address spaces (generic vs %s) "
+                          "for %q+D",
+                          c_addr_space_name (old_addr), newdecl);
+                 else if (ADDR_SPACE_GENERIC_P (old_addr))
+                   error ("conflicting named address spaces (%s vs generic) "
+                          "for %q+D",
+                          c_addr_space_name (new_addr), newdecl);
+                 else
+                   error ("conflicting named address spaces (%s vs %s) "
+                          "for %q+D",
+                          c_addr_space_name (new_addr),
+                          c_addr_space_name (old_addr),
+                          newdecl);
+               }
+
+             if (CLEAR_QUAL_ADDR_SPACE (new_quals)
+                 != CLEAR_QUAL_ADDR_SPACE (old_quals))
+               error ("conflicting type qualifiers for %q+D", newdecl);
+           }
          else
            error ("conflicting types for %q+D", newdecl);
          diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype);
@@ -1741,18 +1785,44 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 
   /* Redeclaration of a type is a constraint violation (6.7.2.3p1),
      but silently ignore the redeclaration if either is in a system
-     header.  (Conflicting redeclarations were handled above.)  */
+     header.  (Conflicting redeclarations were handled above.)  This
+     is allowed for C1X if the types are the same, not just
+     compatible.  */
   if (TREE_CODE (newdecl) == TYPE_DECL)
     {
+      bool types_different = false;
+      int comptypes_result;
+
+      comptypes_result
+       = comptypes_check_different_types (oldtype, newtype, &types_different);
+
+      if (comptypes_result != 1 || types_different)
+       {
+         error ("redefinition of typedef %q+D with different type", newdecl);
+         locate_old_decl (olddecl);
+         return false;
+       }
+
       if (DECL_IN_SYSTEM_HEADER (newdecl)
          || DECL_IN_SYSTEM_HEADER (olddecl)
          || TREE_NO_WARNING (newdecl)
          || TREE_NO_WARNING (olddecl))
        return true;  /* Allow OLDDECL to continue in use.  */
 
-      error ("redefinition of typedef %q+D", newdecl);
-      locate_old_decl (olddecl);
-      return false;
+      if (variably_modified_type_p (newtype, NULL))
+       {
+         error ("redefinition of typedef %q+D with variably modified type",
+                newdecl);
+         locate_old_decl (olddecl);
+       }
+      else if (pedantic && !flag_isoc1x)
+       {
+         pedwarn (input_location, OPT_pedantic,
+                  "redefinition of typedef %q+D", newdecl);
+         locate_old_decl (olddecl);
+       }
+
+      return true;
     }
 
   /* Function declarations can either be 'static' or 'extern' (no
@@ -1773,7 +1843,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
          && !C_DECL_DECLARED_BUILTIN (olddecl)
          && (!TREE_PUBLIC (newdecl)
              || (DECL_INITIAL (newdecl)
-                 && !TYPE_ARG_TYPES (TREE_TYPE (newdecl)))))
+                 && !prototype_p (TREE_TYPE (newdecl)))))
        {
          warning (OPT_Wshadow, "declaration of %q+D shadows "
                   "a built-in function", newdecl);
@@ -1810,7 +1880,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       /* If we have a prototype after an old-style function definition,
         the argument types must be checked specially.  */
       else if (DECL_INITIAL (olddecl)
-              && !TYPE_ARG_TYPES (oldtype) && TYPE_ARG_TYPES (newtype)
+              && !prototype_p (oldtype) && prototype_p (newtype)
               && TYPE_ACTUAL_ARG_TYPES (oldtype)
               && !validate_proto_after_old_defn (newdecl, newtype, oldtype))
        {
@@ -1853,7 +1923,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
            }
          else if (warn_traditional)
            {
-             warned |= warning (OPT_Wtraditional, 
+             warned |= warning (OPT_Wtraditional,
                                 "non-static declaration of %q+D "
                                 "follows static declaration", newdecl);
            }
@@ -1870,9 +1940,10 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
                                        DECL_ATTRIBUTES (olddecl)) != NULL;
          if (newa != olda)
            {
-             error ("%<gnu_inline%> attribute present on %q+D",
-                    newa ? newdecl : olddecl);
-             error ("%Jbut not here", newa ? olddecl : newdecl);
+             error_at (input_location, "%<gnu_inline%> attribute present on %q+D",
+                       newa ? newdecl : olddecl);
+             error_at (DECL_SOURCE_LOCATION (newa ? olddecl : newdecl),
+                       "but not here");
            }
        }
     }
@@ -1930,7 +2001,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
                }
              else if (warn_traditional)
                {
-                 warned |= warning (OPT_Wtraditional, 
+                 warned |= warning (OPT_Wtraditional,
                                     "non-static declaration of %q+D "
                                     "follows static declaration", newdecl);
                }
@@ -1971,6 +2042,18 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 
          return false;
        }
+
+      /* C++ does not permit a decl to appear multiple times at file
+        scope.  */
+      if (warn_cxx_compat
+         && DECL_FILE_SCOPE_P (newdecl)
+         && !DECL_EXTERNAL (newdecl)
+         && !DECL_EXTERNAL (olddecl))
+       warned |= warning_at (DECL_SOURCE_LOCATION (newdecl),
+                             OPT_Wc___compat,
+                             ("duplicate declaration of %qD is "
+                              "invalid in C++"),
+                             newdecl);
     }
 
   /* warnings */
@@ -1989,14 +2072,14 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       if (DECL_DECLARED_INLINE_P (newdecl)
          && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
        {
-         warned |= warning (OPT_Wattributes, 
+         warned |= warning (OPT_Wattributes,
                             "inline declaration of %qD follows "
                             "declaration with attribute noinline", newdecl);
        }
       else if (DECL_DECLARED_INLINE_P (olddecl)
               && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
        {
-         warned |= warning (OPT_Wattributes, 
+         warned |= warning (OPT_Wattributes,
                             "declaration of %q+D with attribute "
                             "noinline follows inline declaration ", newdecl);
        }
@@ -2066,9 +2149,9 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
   bool new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
                            && DECL_INITIAL (newdecl) != 0);
   bool new_is_prototype = (TREE_CODE (newdecl) == FUNCTION_DECL
-                          && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0);
+                          && prototype_p (TREE_TYPE (newdecl)));
   bool old_is_prototype = (TREE_CODE (olddecl) == FUNCTION_DECL
-                          && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) != 0);
+                          && prototype_p (TREE_TYPE (olddecl)));
   bool extern_changed = false;
 
   /* For real parm decl following a forward decl, rechain the old decl
@@ -2311,9 +2394,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
          DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
          DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
          DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
-         gimple_set_body (newdecl, gimple_body (olddecl));
          DECL_ARGUMENTS (newdecl) = copy_list (DECL_ARGUMENTS (olddecl));
-         for (t = DECL_ARGUMENTS (newdecl); t ; t = TREE_CHAIN (t))
+         for (t = DECL_ARGUMENTS (newdecl); t ; t = DECL_CHAIN (t))
            DECL_CONTEXT (t) = newdecl;
 
          /* See if we've got a function to instantiate from.  */
@@ -2323,16 +2405,23 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
        }
     }
 
-   extern_changed = DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl);
+  extern_changed = DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl);
 
-   /* Merge the USED information.  */
-   if (TREE_USED (olddecl))
-     TREE_USED (newdecl) = 1;
-   else if (TREE_USED (newdecl))
-     TREE_USED (olddecl) = 1;
+  /* Merge the USED information.  */
+  if (TREE_USED (olddecl))
+    TREE_USED (newdecl) = 1;
+  else if (TREE_USED (newdecl))
+    TREE_USED (olddecl) = 1;
+  if (TREE_CODE (olddecl) == VAR_DECL || TREE_CODE (olddecl) == PARM_DECL)
+    DECL_READ_P (newdecl) |= DECL_READ_P (olddecl);
+  if (DECL_PRESERVE_P (olddecl))
+    DECL_PRESERVE_P (newdecl) = 1;
+  else if (DECL_PRESERVE_P (newdecl))
+    DECL_PRESERVE_P (olddecl) = 1;
 
   /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
-     But preserve OLDDECL's DECL_UID and DECL_CONTEXT.  */
+     But preserve OLDDECL's DECL_UID, DECL_CONTEXT and
+     DECL_ARGUMENTS (if appropriate).  */
   {
     unsigned olddecl_uid = DECL_UID (olddecl);
     tree olddecl_context = DECL_CONTEXT (olddecl);
@@ -2346,9 +2435,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
     switch (TREE_CODE (olddecl))
       {
       case FUNCTION_DECL:
-       gimple_set_body (olddecl, gimple_body (newdecl));
-       /* fall through */
-
       case FIELD_DECL:
       case VAR_DECL:
       case PARM_DECL:
@@ -2457,7 +2543,8 @@ warn_if_shadowing (tree new_decl)
          warning (OPT_Wshadow, "declaration of %q+D shadows a previous local",
                   new_decl);
 
-       warning (OPT_Wshadow, "%Jshadowed declaration is here", old_decl);
+       warning_at (DECL_SOURCE_LOCATION (old_decl), OPT_Wshadow,
+                   "shadowed declaration is here");
 
        break;
       }
@@ -2753,8 +2840,8 @@ implicit_decl_warning (tree id, tree olddecl)
       if (flag_isoc99)
        warned = pedwarn (input_location, OPT_Wimplicit_function_declaration,
                          "implicit declaration of function %qE", id);
-      else 
-       warned = warning (OPT_Wimplicit_function_declaration, 
+      else
+       warned = warning (OPT_Wimplicit_function_declaration,
                          G_("implicit declaration of function %qE"), id);
       if (olddecl && warned)
        locate_old_decl (olddecl);
@@ -2880,17 +2967,17 @@ undeclared_variable (location_t loc, tree id)
 
   if (current_function_decl == 0)
     {
-      error ("%H%qE undeclared here (not in a function)", &loc, id);
+      error_at (loc, "%qE undeclared here (not in a function)", id);
       scope = current_scope;
     }
   else
     {
-      error ("%H%qE undeclared (first use in this function)", &loc, id);
-
+      if (!objc_diagnose_private_ivar (id))
+        error_at (loc, "%qE undeclared (first use in this function)", id);
       if (!already)
        {
-         error ("%H(Each undeclared identifier is reported only once", &loc);
-         error ("%Hfor each function it appears in.)", &loc);
+          inform (loc, "each undeclared identifier is reported only"
+                  " once for each function it appears in");
          already = true;
        }
 
@@ -2916,7 +3003,7 @@ make_label (location_t location, tree name, bool defining,
   DECL_CONTEXT (label) = current_function_decl;
   DECL_MODE (label) = VOIDmode;
 
-  label_vars = GGC_NEW (struct c_label_vars);
+  label_vars = ggc_alloc_c_label_vars ();
   label_vars->shadowed = NULL;
   set_spot_bindings (&label_vars->label_bindings, defining);
   label_vars->decls_in_scope = make_tree_vector ();
@@ -2937,7 +3024,7 @@ lookup_label (tree name)
   tree label;
   struct c_label_vars *label_vars;
 
-  if (current_function_decl == 0)
+  if (current_function_scope == 0)
     {
       error ("label %qE referenced outside of any function", name);
       return 0;
@@ -3014,7 +3101,7 @@ lookup_label_for_goto (location_t loc, tree name)
     {
       struct c_goto_bindings *g;
 
-      g = GGC_NEW (struct c_goto_bindings);
+      g = ggc_alloc_c_goto_bindings ();
       g->loc = loc;
       set_spot_bindings (&g->goto_bindings, true);
       VEC_safe_push (c_goto_bindings_p, gc, label_vars->gotos, g);
@@ -3029,7 +3116,7 @@ lookup_label_for_goto (location_t loc, tree name)
        ...
        goto lab;
      Issue a warning or error.  */
-  for (ix = 0; VEC_iterate (tree, label_vars->decls_in_scope, ix, decl); ++ix)
+  FOR_EACH_VEC_ELT (tree, label_vars->decls_in_scope, ix, decl)
     warn_about_goto (loc, label, decl);
 
   if (label_vars->label_bindings.left_stmt_expr)
@@ -3081,9 +3168,7 @@ check_earlier_gotos (tree label, struct c_label_vars* label_vars)
   unsigned int ix;
   struct c_goto_bindings *g;
 
-  for (ix = 0;
-       VEC_iterate (c_goto_bindings_p, label_vars->gotos, ix, g);
-       ++ix)
+  FOR_EACH_VEC_ELT (c_goto_bindings_p, label_vars->gotos, ix, g)
     {
       struct c_binding *b;
       struct c_scope *scope;
@@ -3091,12 +3176,15 @@ check_earlier_gotos (tree label, struct c_label_vars* label_vars)
       /* We have a goto to this label.  The goto is going forward.  In
         g->scope, the goto is going to skip any binding which was
         defined after g->bindings_in_scope.  */
-      for (b = g->goto_bindings.scope->bindings;
-          b != g->goto_bindings.bindings_in_scope;
-          b = b->prev)
+      if (g->goto_bindings.scope->has_jump_unsafe_decl)
        {
-         if (decl_jump_unsafe (b->decl))
-           warn_about_goto (g->loc, label, b->decl);
+         for (b = g->goto_bindings.scope->bindings;
+              b != g->goto_bindings.bindings_in_scope;
+              b = b->prev)
+           {
+             if (decl_jump_unsafe (b->decl))
+               warn_about_goto (g->loc, label, b->decl);
+           }
        }
 
       /* We also need to warn about decls defined in any scopes
@@ -3106,14 +3194,17 @@ check_earlier_gotos (tree label, struct c_label_vars* label_vars)
           scope = scope->outer)
        {
          gcc_assert (scope != NULL);
-         if (scope == label_vars->label_bindings.scope)
-           b = label_vars->label_bindings.bindings_in_scope;
-         else
-           b = scope->bindings;
-         for (; b != NULL; b = b->prev)
+         if (scope->has_jump_unsafe_decl)
            {
-             if (decl_jump_unsafe (b->decl))
-               warn_about_goto (g->loc, label, b->decl);
+             if (scope == label_vars->label_bindings.scope)
+               b = label_vars->label_bindings.bindings_in_scope;
+             else
+               b = scope->bindings;
+             for (; b != NULL; b = b->prev)
+               {
+                 if (decl_jump_unsafe (b->decl))
+                   warn_about_goto (g->loc, label, b->decl);
+               }
            }
        }
 
@@ -3229,6 +3320,10 @@ c_check_switch_jump_warnings (struct c_spot_bindings *switch_bindings,
       struct c_binding *b;
 
       gcc_assert (scope != NULL);
+
+      if (!scope->has_jump_unsafe_decl)
+       continue;
+
       for (b = scope->bindings; b != NULL; b = b->prev)
        {
          if (decl_jump_unsafe (b->decl))
@@ -3324,8 +3419,8 @@ void
 pending_xref_error (void)
 {
   if (pending_invalid_xref != 0)
-    error ("%H%qE defined as wrong kind of tag",
-          &pending_invalid_xref_location, pending_invalid_xref);
+    error_at (pending_invalid_xref_location, "%qE defined as wrong kind of tag",
+             pending_invalid_xref);
   pending_invalid_xref = 0;
 }
 
@@ -3383,8 +3478,6 @@ c_init_decl_processing (void)
      using preprocessed headers.  */
   input_location = BUILTINS_LOCATION;
 
-  build_common_tree_nodes (flag_signed_char, false);
-
   c_common_nodes_and_builtins ();
 
   /* In C, comparisons and TRUTH_* expressions have type int.  */
@@ -3438,14 +3531,14 @@ c_make_fname_decl (location_t loc, tree id, int type_dep)
 
   if (current_function_decl
       /* For invalid programs like this:
-        
+
          void foo()
          const char* p = __FUNCTION__;
-        
+
         the __FUNCTION__ is believed to appear in K&R style function
         parameter declarator.  In that case we still don't have
         function_scope.  */
-      && (!errorcount || current_function_scope))
+      && (!seen_error () || current_function_scope))
     {
       DECL_CONTEXT (decl) = current_function_decl;
       bind (id, decl, current_function_scope,
@@ -3464,7 +3557,7 @@ c_builtin_function (tree decl)
   tree   id = DECL_NAME (decl);
 
   const char *name = IDENTIFIER_POINTER (id);
-  C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0);
+  C_DECL_BUILTIN_PROTOTYPE (decl) = prototype_p (type);
 
   /* Should never be called on a symbol with a preexisting meaning.  */
   gcc_assert (!I_SYMBOL_BINDING (id));
@@ -3476,7 +3569,7 @@ c_builtin_function (tree decl)
      needing to be explicitly declared.  See push_file_scope.  */
   if (name[0] == '_' && (name[1] == '_' || ISUPPER (name[1])))
     {
-      TREE_CHAIN (decl) = visible_builtins;
+      DECL_CHAIN (decl) = visible_builtins;
       visible_builtins = decl;
     }
 
@@ -3490,7 +3583,7 @@ c_builtin_function_ext_scope (tree decl)
   tree   id = DECL_NAME (decl);
 
   const char *name = IDENTIFIER_POINTER (id);
-  C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0);
+  C_DECL_BUILTIN_PROTOTYPE (decl) = prototype_p (type);
 
   /* Should never be called on a symbol with a preexisting meaning.  */
   gcc_assert (!I_SYMBOL_BINDING (id));
@@ -3502,7 +3595,7 @@ c_builtin_function_ext_scope (tree decl)
      needing to be explicitly declared.  See push_file_scope.  */
   if (name[0] == '_' && (name[1] == '_' || ISUPPER (name[1])))
     {
-      TREE_CHAIN (decl) = visible_builtins;
+      DECL_CHAIN (decl) = visible_builtins;
       visible_builtins = decl;
     }
 
@@ -3560,7 +3653,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
                  warned = 1;
                }
            }
-         else if (!declspecs->tag_defined_p
+         else if (declspecs->typespec_kind != ctsk_tagdef
+                   && declspecs->typespec_kind != ctsk_tagfirstref
                   && declspecs->storage_class != csc_none)
            {
              if (warned != 1)
@@ -3570,10 +3664,12 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
              warned = 1;
              pending_xref_error ();
            }
-         else if (!declspecs->tag_defined_p
+         else if (declspecs->typespec_kind != ctsk_tagdef
+                   && declspecs->typespec_kind != ctsk_tagfirstref
                   && (declspecs->const_p
                       || declspecs->volatile_p
-                      || declspecs->restrict_p))
+                      || declspecs->restrict_p
+                      || declspecs->address_space))
            {
              if (warned != 1)
                pedwarn (input_location, 0,
@@ -3644,7 +3740,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
 
   if (!warned && !in_system_header && (declspecs->const_p
                                       || declspecs->volatile_p
-                                      || declspecs->restrict_p))
+                                      || declspecs->restrict_p
+                                      || declspecs->address_space))
     {
       warning (0, "useless type qualifier in empty declaration");
       warned = 2;
@@ -3667,7 +3764,8 @@ quals_from_declspecs (const struct c_declspecs *specs)
 {
   int quals = ((specs->const_p ? TYPE_QUAL_CONST : 0)
               | (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0)
-              | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0));
+              | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0)
+              | (ENCODE_QUAL_ADDR_SPACE (specs->address_space)));
   gcc_assert (!specs->type
              && !specs->decl_attr
              && specs->typespec_word == cts_none
@@ -3844,7 +3942,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
     return 0;
 
   if (expr)
-    add_stmt (expr);
+    add_stmt (fold_convert (void_type_node, expr));
 
   if (TREE_CODE (decl) != FUNCTION_DECL && MAIN_NAME_P (DECL_NAME (decl)))
     warning (OPT_Wmain, "%q+D is usually a function", decl);
@@ -3921,7 +4019,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
      prototypes file (if requested).  */
 
   if (TREE_CODE (decl) == FUNCTION_DECL)
-    gen_aux_info_record (decl, 0, 0, TYPE_ARG_TYPES (TREE_TYPE (decl)) != 0);
+    gen_aux_info_record (decl, 0, 0, prototype_p (TREE_TYPE (decl)));
 
   /* ANSI specifies that a tentative definition which is not merged with
      a non-tentative definition behaves exactly like a definition with an
@@ -3967,7 +4065,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
       if (ce->kind == cdk_function)
        {
          tree args = ce->u.arg_info->parms;
-         for (; args; args = TREE_CHAIN (args))
+         for (; args; args = DECL_CHAIN (args))
            {
              tree type = TREE_TYPE (args);
              if (type && INTEGRAL_TYPE_P (type)
@@ -3996,6 +4094,11 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
     record_inline_static (input_location, current_function_decl,
                          decl, csi_modifiable);
 
+  if (c_dialect_objc () 
+      && (TREE_CODE (decl) == VAR_DECL
+          || TREE_CODE (decl) == FUNCTION_DECL))
+      objc_check_global_decl (decl);
+
   /* Add this decl to the current scope.
      TEM may equal DECL or it may be a previous decl of the same name.  */
   tem = pushdecl (decl);
@@ -4009,21 +4112,33 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
   return tem;
 }
 
-/* Initialize EH if not initialized yet and exceptions are enabled.  */
+/* Subroutine of finish_decl. TYPE is the type of an uninitialized object
+   DECL or the non-array element type if DECL is an uninitialized array.
+   If that type has a const member, diagnose this. */
 
-void
-c_maybe_initialize_eh (void)
+static void
+diagnose_uninitialized_cst_member (tree decl, tree type)
 {
-  if (!flag_exceptions || c_eh_initialized_p)
-    return;
+  tree field;
+  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+    {
+      tree field_type;
+      if (TREE_CODE (field) != FIELD_DECL)
+       continue;
+      field_type = strip_array_types (TREE_TYPE (field));
 
-  c_eh_initialized_p = true;
-  eh_personality_libfunc
-    = init_one_libfunc (USING_SJLJ_EXCEPTIONS
-                       ? "__gcc_personality_sj0"
-                       : "__gcc_personality_v0");
-  default_init_unwind_resume_libfunc ();
-  using_eh_for_cleanups ();
+      if (TYPE_QUALS (field_type) & TYPE_QUAL_CONST)
+       {
+         warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
+                     "uninitialized const member in %qT is invalid in C++",
+                     strip_array_types (TREE_TYPE (decl)));
+         inform (DECL_SOURCE_LOCATION (field), "%qD should be initialized", field);
+       }
+
+      if (TREE_CODE (field_type) == RECORD_TYPE
+         || TREE_CODE (field_type) == UNION_TYPE)
+       diagnose_uninitialized_cst_member (decl, field_type);
+    }
 }
 
 /* Finish processing of a declaration;
@@ -4049,6 +4164,13 @@ finish_decl (tree decl, location_t init_loc, tree init,
   if (asmspec_tree)
     asmspec = TREE_STRING_POINTER (asmspec_tree);
 
+  if (TREE_CODE (decl) == VAR_DECL
+      && TREE_STATIC (decl)
+      && global_bindings_p ())
+    /* So decl is a global variable. Record the types it uses
+       so that we can decide later to emit debug info for them.  */
+    record_types_used_by_current_var_decl (decl);
+
   /* If `start_decl' didn't like having an initialization, ignore it now.  */
   if (init != 0 && DECL_INITIAL (decl) == 0)
     init = 0;
@@ -4118,7 +4240,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
                b_ext = b_ext->shadowed;
              if (b_ext)
                {
-                 if (b_ext->u.type)
+                 if (b_ext->u.type && comptypes (b_ext->u.type, type))
                    b_ext->u.type = composite_type (b_ext->u.type, type);
                  else
                    b_ext->u.type = type;
@@ -4177,7 +4299,10 @@ finish_decl (tree decl, location_t init_loc, tree init,
        }
 
       if (TREE_USED (type))
-       TREE_USED (decl) = 1;
+       {
+         TREE_USED (decl) = 1;
+         DECL_READ_P (decl) = 1;
+       }
     }
 
   /* If this is a function and an assembler name is specified, reset DECL_RTL
@@ -4232,6 +4357,8 @@ finish_decl (tree decl, location_t init_loc, tree init,
               when a tentative file-scope definition is seen.
               But at end of compilation, do output code for them.  */
            DECL_DEFER_OUTPUT (decl) = 1;
+         if (asmspec && C_DECL_REGISTER (decl))
+           DECL_HARD_REGISTER (decl) = 1;
          rest_of_decl_compilation (decl, true, 0);
        }
       else
@@ -4297,12 +4424,6 @@ finish_decl (tree decl, location_t init_loc, tree init,
       rest_of_decl_compilation (decl, DECL_FILE_SCOPE_P (decl), 0);
     }
 
-  /* At the end of a declaration, throw away any variable type sizes
-     of types defined inside that declaration.  There is no use
-     computing them in the following function definition.  */
-  if (current_scope == file_scope)
-    get_pending_sizes ();
-
   /* Install a cleanup (aka destructor) if one was given.  */
   if (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl))
     {
@@ -4325,23 +4446,39 @@ finish_decl (tree decl, location_t init_loc, tree init,
          /* Don't warn about decl unused; the cleanup uses it.  */
          TREE_USED (decl) = 1;
          TREE_USED (cleanup_decl) = 1;
-
-         /* Initialize EH, if we've been told to do so.  */
-         c_maybe_initialize_eh ();
+         DECL_READ_P (decl) = 1;
 
          push_cleanup (decl, cleanup, false);
        }
     }
+
+  if (warn_cxx_compat
+      && TREE_CODE (decl) == VAR_DECL
+      && !DECL_EXTERNAL (decl)
+      && DECL_INITIAL (decl) == NULL_TREE)
+    {
+      type = strip_array_types (type);
+      if (TREE_READONLY (decl))
+       warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
+                   "uninitialized const %qD is invalid in C++", decl);
+      else if ((TREE_CODE (type) == RECORD_TYPE
+               || TREE_CODE (type) == UNION_TYPE)
+              && C_TYPE_FIELDS_READONLY (type))
+       diagnose_uninitialized_cst_member (decl, type);
+    }
 }
 
-/* Given a parsed parameter declaration, decode it into a PARM_DECL.  */
+/* Given a parsed parameter declaration, decode it into a PARM_DECL.
+   EXPR is NULL or a pointer to an expression that needs to be
+   evaluated for the side effects of array size expressions in the
+   parameters.  */
 
 tree
-grokparm (const struct c_parm *parm)
+grokparm (const struct c_parm *parm, tree *expr)
 {
   tree attrs = parm->attrs;
   tree decl = grokdeclarator (parm->declarator, parm->specs, PARM, false,
-                             NULL, &attrs, NULL, NULL, DEPRECATED_NORMAL);
+                             NULL, &attrs, expr, NULL, DEPRECATED_NORMAL);
 
   decl_attributes (&decl, attrs, 0);
 
@@ -4349,16 +4486,18 @@ grokparm (const struct c_parm *parm)
 }
 
 /* Given a parsed parameter declaration, decode it into a PARM_DECL
-   and push that on the current scope.  */
+   and push that on the current scope.  EXPR is a pointer to an
+   expression that needs to be evaluated for the side effects of array
+   size expressions in the parameters.  */
 
 void
-push_parm_decl (const struct c_parm *parm)
+push_parm_decl (const struct c_parm *parm, tree *expr)
 {
   tree attrs = parm->attrs;
   tree decl;
 
   decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, NULL,
-                        &attrs, NULL, NULL, DEPRECATED_NORMAL);
+                        &attrs, expr, NULL, DEPRECATED_NORMAL);
   decl_attributes (&decl, attrs, 0);
 
   decl = pushdecl (decl);
@@ -4402,7 +4541,8 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const)
   tree complit;
   tree stmt;
 
-  if (type == error_mark_node)
+  if (type == error_mark_node
+      || init == error_mark_node)
     return error_mark_node;
 
   decl = build_decl (loc, VAR_DECL, NULL_TREE, type);
@@ -4411,6 +4551,7 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const)
   TREE_STATIC (decl) = (current_scope == file_scope);
   DECL_CONTEXT (decl) = current_function_decl;
   TREE_USED (decl) = 1;
+  DECL_READ_P (decl) = 1;
   TREE_TYPE (decl) = type;
   TREE_READONLY (decl) = TYPE_READONLY (type);
   store_init_value (loc, decl, init, NULL_TREE);
@@ -4461,7 +4602,9 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const)
 void
 check_compound_literal_type (location_t loc, struct c_type_name *type_name)
 {
-  if (warn_cxx_compat && type_name->specs->tag_defined_p)
+  if (warn_cxx_compat
+      && (type_name->specs->typespec_kind == ctsk_tagdef
+          || type_name->specs->typespec_kind == ctsk_tagfirstref))
     warning_at (loc, OPT_Wc___compat,
                "defining a type in a compound literal is invalid in C++");
 }
@@ -4479,8 +4622,8 @@ flexible_array_type_p (tree type)
       x = TYPE_FIELDS (type);
       if (x == NULL_TREE)
        return false;
-      while (TREE_CHAIN (x) != NULL_TREE)
-       x = TREE_CHAIN (x);
+      while (DECL_CHAIN (x) != NULL_TREE)
+       x = DECL_CHAIN (x);
       if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
          && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
          && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE
@@ -4488,7 +4631,7 @@ flexible_array_type_p (tree type)
        return true;
       return false;
     case UNION_TYPE:
-      for (x = TYPE_FIELDS (type); x != NULL_TREE; x = TREE_CHAIN (x))
+      for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x))
        {
          if (flexible_array_type_p (TREE_TYPE (x)))
            return true;
@@ -4513,14 +4656,26 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
 
   /* Detect and ignore out of range field width and process valid
      field widths.  */
-  if (!INTEGRAL_TYPE_P (TREE_TYPE (*width))
-      || TREE_CODE (*width) != INTEGER_CST)
+  if (!INTEGRAL_TYPE_P (TREE_TYPE (*width)))
     {
       error ("bit-field %qs width not an integer constant", name);
       *width = integer_one_node;
     }
   else
     {
+      if (TREE_CODE (*width) != INTEGER_CST)
+       {
+         *width = c_fully_fold (*width, false, NULL);
+         if (TREE_CODE (*width) == INTEGER_CST)
+           pedwarn (input_location, OPT_pedantic,
+                    "bit-field %qs width not an integer constant expression",
+                    name);
+       }
+      if (TREE_CODE (*width) != INTEGER_CST)
+       {
+         error ("bit-field %qs width not an integer constant", name);
+         *width = integer_one_node;
+       }
       constant_expression_warning (*width);
       if (tree_int_cst_sgn (*width) < 0)
        {
@@ -4557,7 +4712,7 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
     {
       error ("width of %qs exceeds its type", name);
       w = max_width;
-      *width = build_int_cst (NULL_TREE, w);
+      *width = build_int_cst (integer_type_node, w);
     }
   else
     w = tree_low_cst (*width, 1);
@@ -4596,7 +4751,7 @@ warn_variable_length_array (tree name, tree size)
        }
       else
        {
-         if (name) 
+         if (name)
            pedwarn (input_location, OPT_Wvla,
                     "ISO C90 forbids variable length array %qE",
                     name);
@@ -4629,34 +4784,6 @@ warn_variable_length_array (tree name, tree size)
     }
 }
 
-/* Given a size SIZE that may not be a constant, return a SAVE_EXPR to
-   serve as the actual size-expression for a type or decl.  This is
-   like variable_size in stor-layout.c, but we make global_bindings_p
-   return negative to avoid calls to that function from outside the
-   front end resulting in errors at file scope, then call this version
-   instead from front-end code.  */
-
-static tree
-c_variable_size (tree size)
-{
-  tree save;
-
-  if (TREE_CONSTANT (size))
-    return size;
-
-  size = save_expr (size);
-
-  save = skip_simple_arithmetic (size);
-
-  if (cfun && cfun->dont_save_pending_sizes_p)
-    return size;
-
-  if (!global_bindings_p ())
-    put_pending_size (save);
-
-  return size;
-}
-
 /* Given declspecs and a declarator,
    determine the name and type of the object declared
    and construct a ..._DECL node for it.
@@ -4713,7 +4840,7 @@ grokdeclarator (const struct c_declarator *declarator,
   tree name = NULL_TREE;
   bool funcdef_flag = false;
   bool funcdef_syntax = false;
-  int size_varies = 0;
+  bool size_varies = false;
   tree decl_attr = declspecs->decl_attr;
   int array_ptr_quals = TYPE_UNQUALIFIED;
   tree array_ptr_attrs = NULL_TREE;
@@ -4723,11 +4850,15 @@ grokdeclarator (const struct c_declarator *declarator,
   bool bitfield = width != NULL;
   tree element_type;
   struct c_arg_info *arg_info = 0;
+  addr_space_t as1, as2, address_space;
   location_t loc = UNKNOWN_LOCATION;
   const char *errmsg;
   tree expr_dummy;
   bool expr_const_operands_dummy;
+  enum c_declarator_kind first_non_attr_kind;
 
+  if (TREE_CODE (type) == ERROR_MARK)
+    return error_mark_node;
   if (expr == NULL)
     expr = &expr_dummy;
   if (expr_const_operands == NULL)
@@ -4744,6 +4875,7 @@ grokdeclarator (const struct c_declarator *declarator,
   {
     const struct c_declarator *decl = declarator;
 
+    first_non_attr_kind = cdk_attrs;
     while (decl)
       switch (decl->kind)
        {
@@ -4755,6 +4887,8 @@ grokdeclarator (const struct c_declarator *declarator,
        case cdk_pointer:
          funcdef_syntax = (decl->kind == cdk_function);
          decl = decl->declarator;
+         if (first_non_attr_kind == cdk_attrs)
+           first_non_attr_kind = decl->kind;
          break;
 
        case cdk_attrs:
@@ -4765,6 +4899,8 @@ grokdeclarator (const struct c_declarator *declarator,
          loc = decl->id_loc;
          if (decl->u.id)
            name = decl->u.id;
+         if (first_non_attr_kind == cdk_attrs)
+           first_non_attr_kind = decl->kind;
          decl = 0;
          break;
 
@@ -4807,7 +4943,7 @@ grokdeclarator (const struct c_declarator *declarator,
       type = integer_type_node;
     }
 
-  size_varies = C_TYPE_VARIABLE_SIZE (type);
+  size_varies = C_TYPE_VARIABLE_SIZE (type) != 0;
 
   /* Diagnose defaulting to "int".  */
 
@@ -4822,11 +4958,11 @@ grokdeclarator (const struct c_declarator *declarator,
       else
        {
          if (name)
-           pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wimplicit_int, 
+           pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wimplicit_int,
                         "type defaults to %<int%> in declaration of %qE",
                         name);
          else
-           pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int, 
+           pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int,
                         "type defaults to %<int%> in type name");
        }
     }
@@ -4853,6 +4989,10 @@ grokdeclarator (const struct c_declarator *declarator,
   constp = declspecs->const_p + TYPE_READONLY (element_type);
   restrictp = declspecs->restrict_p + TYPE_RESTRICT (element_type);
   volatilep = declspecs->volatile_p + TYPE_VOLATILE (element_type);
+  as1 = declspecs->address_space;
+  as2 = TYPE_ADDR_SPACE (element_type);
+  address_space = ADDR_SPACE_GENERIC_P (as1)? as2 : as1;
+
   if (pedantic && !flag_isoc99)
     {
       if (constp > 1)
@@ -4862,11 +5002,19 @@ grokdeclarator (const struct c_declarator *declarator,
       if (volatilep > 1)
        pedwarn (loc, OPT_pedantic, "duplicate %<volatile%>");
     }
-  if (!flag_gen_aux_info && (TYPE_QUALS (element_type)))
+
+  if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) && as1 != as2)
+    error_at (loc, "conflicting named address spaces (%s vs %s)",
+             c_addr_space_name (as1), c_addr_space_name (as2));
+
+  if ((TREE_CODE (type) == ARRAY_TYPE
+       || first_non_attr_kind == cdk_array)
+      && TYPE_QUALS (element_type))
     type = TYPE_MAIN_VARIANT (type);
   type_quals = ((constp ? TYPE_QUAL_CONST : 0)
                | (restrictp ? TYPE_QUAL_RESTRICT : 0)
-               | (volatilep ? TYPE_QUAL_VOLATILE : 0));
+               | (volatilep ? TYPE_QUAL_VOLATILE : 0)
+               | ENCODE_QUAL_ADDR_SPACE (address_space));
 
   /* Warn about storage classes that are invalid for certain
      kinds of declarations (parameters, typenames, etc.).  */
@@ -4878,8 +5026,8 @@ grokdeclarator (const struct c_declarator *declarator,
          || storage_class == csc_typedef))
     {
       if (storage_class == csc_auto)
-       pedwarn (loc, 
-                (current_scope == file_scope) ? 0 : OPT_pedantic, 
+       pedwarn (loc,
+                (current_scope == file_scope) ? 0 : OPT_pedantic,
                 "function definition declared %<auto%>");
       if (storage_class == csc_register)
        error_at (loc, "function definition declared %<register%>");
@@ -5140,7 +5288,7 @@ grokdeclarator (const struct c_declarator *declarator,
                                   "variably modified %qE at file scope",
                                   name);
                        else
-                         this_size_varies = size_varies = 1;
+                         this_size_varies = size_varies = true;
                        warn_variable_length_array (name, size);
                      }
                  }
@@ -5155,7 +5303,7 @@ grokdeclarator (const struct c_declarator *declarator,
                    /* Make sure the array size remains visibly
                       nonconstant even if it is (eg) a const variable
                       with known value.  */
-                   this_size_varies = size_varies = 1;
+                   this_size_varies = size_varies = true;
                    warn_variable_length_array (name, size);
                  }
 
@@ -5173,7 +5321,7 @@ grokdeclarator (const struct c_declarator *declarator,
                       MINUS_EXPR, which allows the -1 to get folded
                       with the +1 that happens when building TYPE_SIZE.  */
                    if (size_varies)
-                     size = c_variable_size (size);
+                     size = save_expr (size);
                    if (this_size_varies && TREE_CODE (size) == INTEGER_CST)
                      size = build2 (COMPOUND_EXPR, TREE_TYPE (size),
                                     integer_zero_node, size);
@@ -5182,20 +5330,18 @@ grokdeclarator (const struct c_declarator *declarator,
                       - 1.  Do the calculation in index_type, so that
                       if it is a variable the computations will be
                       done in the proper mode.  */
-                   itype = fold_build2 (MINUS_EXPR, index_type,
-                                        convert (index_type, size),
-                                        convert (index_type,
-                                                 size_one_node));
-
-                   /* If that overflowed, the array is too big.  ???
-                      While a size of INT_MAX+1 technically shouldn't
-                      cause an overflow (because we subtract 1), the
-                      overflow is recorded during the conversion to
-                      index_type, before the subtraction.  Handling
-                      this case seems like an unnecessary
-                      complication.  */
-                   if (TREE_CODE (itype) == INTEGER_CST
-                       && TREE_OVERFLOW (itype))
+                   itype = fold_build2_loc (loc, MINUS_EXPR, index_type,
+                                            convert (index_type, size),
+                                            convert (index_type,
+                                                     size_one_node));
+
+                   /* The above overflows when size does not fit
+                      in index_type.
+                      ???  While a size of INT_MAX+1 technically shouldn't
+                      cause an overflow (because we subtract 1), handling
+                      this case seems like an unnecessary complication.  */
+                   if (TREE_CODE (size) == INTEGER_CST
+                       && !int_fits_type_p (size, index_type))
                      {
                        if (name)
                          error_at (loc, "size of array %qE is too large",
@@ -5227,7 +5373,7 @@ grokdeclarator (const struct c_declarator *declarator,
                     the field variably modified, not through being
                     something other than a declaration with function
                     prototype scope.  */
-                 size_varies = 1;
+                 size_varies = true;
                else
                  {
                    const struct c_declarator *t = declarator;
@@ -5251,7 +5397,7 @@ grokdeclarator (const struct c_declarator *declarator,
                if (array_parm_vla_unspec_p)
                  {
                    itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
-                   size_varies = 1;
+                   size_varies = true;
                  }
              }
            else if (decl_context == TYPENAME)
@@ -5265,11 +5411,11 @@ grokdeclarator (const struct c_declarator *declarator,
                       otherwise be modified below.  */
                    itype = build_range_type (sizetype, size_zero_node,
                                              NULL_TREE);
-                   size_varies = 1;
+                   size_varies = true;
                  }
              }
 
-            /* Complain about arrays of incomplete types.  */
+           /* Complain about arrays of incomplete types.  */
            if (!COMPLETE_TYPE_P (type))
              {
                error_at (loc, "array type has incomplete element type");
@@ -5282,7 +5428,14 @@ grokdeclarator (const struct c_declarator *declarator,
               it, but here we want to make sure we don't ever
               modify the shared type, so we gcc_assert (itype)
               below.  */
-             type = build_array_type (type, itype);
+             {
+               addr_space_t as = DECODE_QUAL_ADDR_SPACE (type_quals);
+               if (!ADDR_SPACE_GENERIC_P (as) && as != TYPE_ADDR_SPACE (type))
+                 type = build_qualified_type (type,
+                                              ENCODE_QUAL_ADDR_SPACE (as));
+
+               type = build_array_type (type, itype);
+             }
 
            if (type != error_mark_node)
              {
@@ -5305,15 +5458,19 @@ grokdeclarator (const struct c_declarator *declarator,
                if (size && integer_zerop (size))
                  {
                    gcc_assert (itype);
+                   type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
                    TYPE_SIZE (type) = bitsize_zero_node;
                    TYPE_SIZE_UNIT (type) = size_zero_node;
+                   SET_TYPE_STRUCTURAL_EQUALITY (type);
                  }
                if (array_parm_vla_unspec_p)
                  {
                    gcc_assert (itype);
                    /* The type is complete.  C99 6.7.5.2p4  */
+                   type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
                    TYPE_SIZE (type) = bitsize_zero_node;
                    TYPE_SIZE_UNIT (type) = size_zero_node;
+                   SET_TYPE_STRUCTURAL_EQUALITY (type);
                  }
              }
 
@@ -5349,7 +5506,7 @@ grokdeclarator (const struct c_declarator *declarator,
            if (type == error_mark_node)
              continue;
 
-           size_varies = 0;
+           size_varies = false;
 
            /* Warn about some types functions can't return.  */
            if (TREE_CODE (type) == FUNCTION_TYPE)
@@ -5383,8 +5540,6 @@ grokdeclarator (const struct c_declarator *declarator,
               inner layer of declarator.  */
            arg_info = declarator->u.arg_info;
            arg_types = grokparms (arg_info, really_funcdef);
-           if (really_funcdef)
-             put_pending_sizes (arg_info->pending_sizes);
 
            /* Type qualifiers before the return type of the function
               qualify the return type, not the function type.  */
@@ -5414,12 +5569,11 @@ grokdeclarator (const struct c_declarator *declarator,
               the formal parameter list of this FUNCTION_TYPE to point to
               the FUNCTION_TYPE node itself.  */
            {
-             tree link;
+             c_arg_tag *tag;
+             unsigned ix;
 
-             for (link = arg_info->tags;
-                  link;
-                  link = TREE_CHAIN (link))
-               TYPE_CONTEXT (TREE_VALUE (link)) = type;
+             FOR_EACH_VEC_ELT_REVERSE (c_arg_tag, arg_info->tags, ix, tag)
+               TYPE_CONTEXT (tag->type) = type;
            }
            break;
          }
@@ -5434,7 +5588,7 @@ grokdeclarator (const struct c_declarator *declarator,
                       "ISO C forbids qualified function types");
            if (type_quals)
              type = c_build_qualified_type (type, type_quals);
-           size_varies = 0;
+           size_varies = false;
 
            /* When the pointed-to type involves components of variable size,
               care must be taken to ensure that the size evaluation code is
@@ -5488,6 +5642,59 @@ grokdeclarator (const struct c_declarator *declarator,
   /* Now TYPE has the actual type, apart from any qualifiers in
      TYPE_QUALS.  */
 
+  /* Warn about address space used for things other than static memory or
+     pointers.  */
+  address_space = DECODE_QUAL_ADDR_SPACE (type_quals);
+  if (!ADDR_SPACE_GENERIC_P (address_space))
+    {
+      if (decl_context == NORMAL)
+       {
+         switch (storage_class)
+           {
+           case csc_auto:
+             error ("%qs combined with %<auto%> qualifier for %qE",
+                    c_addr_space_name (address_space), name);
+             break;
+           case csc_register:
+             error ("%qs combined with %<register%> qualifier for %qE",
+                    c_addr_space_name (address_space), name);
+             break;
+           case csc_none:
+             if (current_function_scope)
+               {
+                 error ("%qs specified for auto variable %qE",
+                        c_addr_space_name (address_space), name);
+                 break;
+               }
+             break;
+           case csc_static:
+           case csc_extern:
+           case csc_typedef:
+             break;
+           default:
+             gcc_unreachable ();
+           }
+       }
+      else if (decl_context == PARM && TREE_CODE (type) != ARRAY_TYPE)
+       {
+         if (name)
+           error ("%qs specified for parameter %qE",
+                  c_addr_space_name (address_space), name);
+         else
+           error ("%qs specified for unnamed parameter",
+                  c_addr_space_name (address_space));
+       }
+      else if (decl_context == FIELD)
+       {
+         if (name)
+           error ("%qs specified for structure field %qE",
+                  c_addr_space_name (address_space), name);
+         else
+           error ("%qs specified for structure field",
+                  c_addr_space_name (address_space));
+       }
+    }
+
   /* Check the type and width of a bit-field.  */
   if (bitfield)
     check_bitfield_type_and_width (&type, width, name);
@@ -5620,7 +5827,7 @@ grokdeclarator (const struct c_declarator *declarator,
              warning_at (loc, OPT_Wattributes,
                          "attributes in parameter array declarator ignored");
 
-           size_varies = 0;
+           size_varies = false;
          }
        else if (TREE_CODE (type) == FUNCTION_TYPE)
          {
@@ -5692,7 +5899,7 @@ grokdeclarator (const struct c_declarator *declarator,
        if (storage_class == csc_register || threadp)
          {
            error_at (loc, "invalid storage class for function %qE", name);
-          }
+         }
        else if (current_scope != file_scope)
          {
            /* Function declaration not at file scope.  Storage
@@ -5721,12 +5928,6 @@ grokdeclarator (const struct c_declarator *declarator,
          pedwarn (loc, OPT_pedantic,
                   "ISO C forbids qualified function types");
 
-       /* GNU C interprets a volatile-qualified function type to indicate
-          that the function does not return.  */
-       if ((type_quals & TYPE_QUAL_VOLATILE)
-           && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
-         warning_at (loc, 0, "%<noreturn%> function returns non-void value");
-
        /* Every function declaration is an external reference
           (DECL_EXTERNAL) except for those which are not at file
           scope and are explicitly declared "auto".  This is
@@ -5875,6 +6076,19 @@ grokdeclarator (const struct c_declarator *declarator,
      name of a variable.  Thus, if it's known before this, die horribly.  */
     gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl));
 
+    if (warn_cxx_compat
+       && TREE_CODE (decl) == VAR_DECL
+       && TREE_PUBLIC (decl)
+       && TREE_STATIC (decl)
+       && (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
+           || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE
+           || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
+       && TYPE_NAME (TREE_TYPE (decl)) == NULL_TREE)
+      warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
+                 ("non-local variable %qD with anonymous type is "
+                  "questionable in C++"),
+                 decl);
+
     return decl;
   }
 }
@@ -5915,9 +6129,13 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
   else if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == IDENTIFIER_NODE)
     {
       if (!funcdef_flag)
-       pedwarn (input_location, 0, "parameter names (without types) in function declaration");
+       {
+         pedwarn (input_location, 0, "parameter names (without types) in function declaration");
+         arg_info->parms = NULL_TREE;
+       }
+      else
+       arg_info->parms = arg_info->types;
 
-      arg_info->parms = arg_info->types;
       arg_info->types = 0;
       return 0;
     }
@@ -5938,7 +6156,7 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
 
       for (parm = arg_info->parms, typelt = arg_types, parmno = 1;
           parm;
-          parm = TREE_CHAIN (parm), typelt = TREE_CHAIN (typelt), parmno++)
+          parm = DECL_CHAIN (parm), typelt = TREE_CHAIN (typelt), parmno++)
        {
          type = TREE_VALUE (typelt);
          if (type == error_mark_node)
@@ -5949,23 +6167,28 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
              if (funcdef_flag)
                {
                  if (DECL_NAME (parm))
-                   error ("parameter %u (%q+D) has incomplete type",
-                          parmno, parm);
+                   error_at (input_location,
+                             "parameter %u (%q+D) has incomplete type",
+                             parmno, parm);
                  else
-                   error ("%Jparameter %u has incomplete type",
-                          parm, parmno);
+                   error_at (DECL_SOURCE_LOCATION (parm),
+                             "parameter %u has incomplete type",
+                             parmno);
 
                  TREE_VALUE (typelt) = error_mark_node;
                  TREE_TYPE (parm) = error_mark_node;
+                 arg_types = NULL_TREE;
                }
              else if (VOID_TYPE_P (type))
                {
                  if (DECL_NAME (parm))
-                   warning (0, "parameter %u (%q+D) has void type",
-                            parmno, parm);
+                   warning_at (input_location, 0,
+                               "parameter %u (%q+D) has void type",
+                               parmno, parm);
                  else
-                   warning (0, "%Jparameter %u has void type",
-                            parm, parmno);
+                   warning_at (DECL_SOURCE_LOCATION (parm), 0,
+                               "parameter %u has void type",
+                               parmno);
                }
            }
 
@@ -5975,6 +6198,7 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
              error (errmsg);
              TREE_VALUE (typelt) = error_mark_node;
              TREE_TYPE (parm) = error_mark_node;
+             arg_types = NULL_TREE;
            }
 
          if (DECL_NAME (parm) && TREE_USED (parm))
@@ -5984,33 +6208,47 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
     }
 }
 
+/* Allocate and initialize a c_arg_info structure from the parser's
+   obstack.  */
+
+struct c_arg_info *
+build_arg_info (void)
+{
+  struct c_arg_info *ret = XOBNEW (&parser_obstack, struct c_arg_info);
+  ret->parms = NULL_TREE;
+  ret->tags = NULL;
+  ret->types = NULL_TREE;
+  ret->others = NULL_TREE;
+  ret->pending_sizes = NULL;
+  ret->had_vla_unspec = 0;
+  return ret;
+}
+
 /* Take apart the current scope and return a c_arg_info structure with
    info on a parameter list just parsed.
 
    This structure is later fed to 'grokparms' and 'store_parm_decls'.
 
    ELLIPSIS being true means the argument list ended in '...' so don't
-   append a sentinel (void_list_node) to the end of the type-list.  */
+   append a sentinel (void_list_node) to the end of the type-list.
+
+   EXPR is NULL or an expression that needs to be evaluated for the
+   side effects of array size expressions in the parameters.  */
 
 struct c_arg_info *
-get_parm_info (bool ellipsis)
+get_parm_info (bool ellipsis, tree expr)
 {
   struct c_binding *b = current_scope->bindings;
-  struct c_arg_info *arg_info = XOBNEW (&parser_obstack,
-                                       struct c_arg_info);
+  struct c_arg_info *arg_info = build_arg_info ();
+
   tree parms    = 0;
-  tree tags     = 0;
+  VEC(c_arg_tag,gc) *tags = NULL;
   tree types    = 0;
   tree others   = 0;
 
   static bool explained_incomplete_types = false;
   bool gave_void_only_once_err = false;
 
-  arg_info->parms = 0;
-  arg_info->tags = 0;
-  arg_info->types = 0;
-  arg_info->others = 0;
-  arg_info->pending_sizes = 0;
   arg_info->had_vla_unspec = current_scope->had_vla_unspec;
 
   /* The bindings in this scope must not get put into a block.
@@ -6053,6 +6291,7 @@ get_parm_info (bool ellipsis)
     {
       tree decl = b->decl;
       tree type = TREE_TYPE (decl);
+      c_arg_tag *tag;
       const char *keyword;
 
       switch (TREE_CODE (decl))
@@ -6079,7 +6318,7 @@ get_parm_info (bool ellipsis)
          else
            {
              /* Valid parameter, add it to the list.  */
-             TREE_CHAIN (decl) = parms;
+             DECL_CHAIN (decl) = parms;
              parms = decl;
 
              /* Since there is a prototype, args are passed in their
@@ -6126,7 +6365,9 @@ get_parm_info (bool ellipsis)
                }
            }
 
-         tags = tree_cons (b->id, decl, tags);
+         tag = VEC_safe_push (c_arg_tag, gc, tags, NULL);
+         tag->id = b->id;
+         tag->type = decl;
          break;
 
        case CONST_DECL:
@@ -6138,7 +6379,12 @@ get_parm_info (bool ellipsis)
             type itself.  FUNCTION_DECLs appear when there is an implicit
             function declaration in the parameter list.  */
 
-         TREE_CHAIN (decl) = others;
+         /* When we reinsert this decl in the function body, we need
+            to reconstruct whether it was marked as nested.  */
+         gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
+                     ? b->nested
+                     : !b->nested);
+         DECL_CHAIN (decl) = others;
          others = decl;
          /* fall through */
 
@@ -6166,7 +6412,7 @@ get_parm_info (bool ellipsis)
   arg_info->tags = tags;
   arg_info->types = types;
   arg_info->others = others;
-  arg_info->pending_sizes = get_pending_sizes ();
+  arg_info->pending_sizes = expr;
   return arg_info;
 }
 \f
@@ -6276,16 +6522,14 @@ xref_tag (enum tree_code code, tree name)
    LOC is the location of the struct's definition.
    CODE says which kind of tag NAME ought to be.
 
-   This stores the current value of the file static IN_STRUCT in
-   *ENCLOSING_IN_STRUCT, and sets IN_STRUCT to true.  Similarly, this
-   sets STRUCT_TYPES in *ENCLOSING_STRUCT_TYPES, and sets STRUCT_TYPES
-   to an empty vector.  The old values are restored in
-   finish_struct.  */
+   This stores the current value of the file static STRUCT_PARSE_INFO
+   in *ENCLOSING_STRUCT_PARSE_INFO, and points STRUCT_PARSE_INFO at a
+   new c_struct_parse_info structure.  The old value of
+   STRUCT_PARSE_INFO is restored in finish_struct.  */
 
 tree
 start_struct (location_t loc, enum tree_code code, tree name,
-             bool *enclosing_in_struct,
-             VEC(tree,heap) **enclosing_struct_types)
+             struct c_struct_parse_info **enclosing_struct_parse_info)
 {
   /* If there is already a tag defined at this scope
      (as a forward reference), just return it.  */
@@ -6333,10 +6577,11 @@ start_struct (location_t loc, enum tree_code code, tree name,
   C_TYPE_BEING_DEFINED (ref) = 1;
   TYPE_PACKED (ref) = flag_pack_struct;
 
-  *enclosing_in_struct = in_struct;
-  *enclosing_struct_types = struct_types;
-  in_struct = true;
-  struct_types = VEC_alloc(tree, heap, 0);
+  *enclosing_struct_parse_info = struct_parse_info;
+  struct_parse_info = XNEW (struct c_struct_parse_info);
+  struct_parse_info->struct_types = VEC_alloc (tree, heap, 0);
+  struct_parse_info->fields = VEC_alloc (c_binding_ptr, heap, 0);
+  struct_parse_info->typedefs_seen = VEC_alloc (tree, heap, 0);
 
   /* FIXME: This will issue a warning for a use of a type defined
      within a statement expr used within sizeof, et. al.  This is not
@@ -6379,13 +6624,15 @@ grokfield (location_t loc,
         is the anonymous union extension.  Similarly for struct.
 
         If this is something of the form "struct foo;", then
-          If MS extensions are enabled, this is handled as an
-            anonymous struct.
+          If MS or Plan 9 extensions are enabled, this is handled as
+            an anonymous struct.
           Otherwise this is a forward declaration of a structure tag.
 
         If this is something of the form "foo;" and foo is a TYPE_DECL, then
-          If MS extensions are enabled and foo names a structure, then
-            again this is an anonymous struct.
+          If foo names a structure or union without a tag, then this
+            is an anonymous struct (this is permitted by C1X).
+          If MS or Plan 9 extensions are enabled and foo names a
+            structure, then again this is an anonymous struct.
           Otherwise this is an error.
 
         Oh what a horrid tangled web we weave.  I wonder if MS consciously
@@ -6398,12 +6645,12 @@ grokfield (location_t loc,
       bool ok = false;
 
       if (type_ok
-         && (flag_ms_extensions || !declspecs->typedef_p))
+         && (flag_ms_extensions
+             || flag_plan9_extensions
+             || !declspecs->typedef_p))
        {
-         if (flag_ms_extensions)
+         if (flag_ms_extensions || flag_plan9_extensions)
            ok = true;
-         else if (flag_iso)
-           ok = false;
          else if (TYPE_NAME (type) == NULL)
            ok = true;
          else
@@ -6414,7 +6661,15 @@ grokfield (location_t loc,
          pedwarn (loc, 0, "declaration does not declare anything");
          return NULL_TREE;
        }
-      pedwarn (loc, OPT_pedantic, "ISO C doesn%'t support unnamed structs/unions");
+      if (!flag_isoc1x)
+       {
+         if (flag_isoc99)
+           pedwarn (loc, OPT_pedantic,
+                    "ISO C99 doesn%'t support unnamed structs/unions");
+         else
+           pedwarn (loc, OPT_pedantic,
+                    "ISO C90 doesn%'t support unnamed structs/unions");
+       }
     }
 
   value = grokdeclarator (declarator, declspecs, FIELD, false,
@@ -6424,9 +6679,112 @@ grokfield (location_t loc,
   finish_decl (value, loc, NULL_TREE, NULL_TREE, NULL_TREE);
   DECL_INITIAL (value) = width;
 
+  if (warn_cxx_compat && DECL_NAME (value) != NULL_TREE)
+    {
+      /* If we currently have a binding for this field, set the
+        in_struct field in the binding, so that we warn about lookups
+        which find it.  */
+      struct c_binding *b = I_SYMBOL_BINDING (DECL_NAME (value));
+      if (b != NULL)
+       {
+         /* If the in_struct field is not yet set, push it on a list
+            to be cleared when this struct is finished.  */
+         if (!b->in_struct)
+           {
+             VEC_safe_push (c_binding_ptr, heap,
+                            struct_parse_info->fields, b);
+             b->in_struct = 1;
+           }
+       }
+    }
+
   return value;
 }
 \f
+/* Subroutine of detect_field_duplicates: return whether X and Y,
+   which are both fields in the same struct, have duplicate field
+   names.  */
+
+static bool
+is_duplicate_field (tree x, tree y)
+{
+  if (DECL_NAME (x) != NULL_TREE && DECL_NAME (x) == DECL_NAME (y))
+    return true;
+
+  /* When using -fplan9-extensions, an anonymous field whose name is a
+     typedef can duplicate a field name.  */
+  if (flag_plan9_extensions
+      && (DECL_NAME (x) == NULL_TREE || DECL_NAME (y) == NULL_TREE))
+    {
+      tree xt, xn, yt, yn;
+
+      xt = TREE_TYPE (x);
+      if (DECL_NAME (x) != NULL_TREE)
+       xn = DECL_NAME (x);
+      else if ((TREE_CODE (xt) == RECORD_TYPE || TREE_CODE (xt) == UNION_TYPE)
+              && TYPE_NAME (xt) != NULL_TREE
+              && TREE_CODE (TYPE_NAME (xt)) == TYPE_DECL)
+       xn = DECL_NAME (TYPE_NAME (xt));
+      else
+       xn = NULL_TREE;
+
+      yt = TREE_TYPE (y);
+      if (DECL_NAME (y) != NULL_TREE)
+       yn = DECL_NAME (y);
+      else if ((TREE_CODE (yt) == RECORD_TYPE || TREE_CODE (yt) == UNION_TYPE)
+              && TYPE_NAME (yt) != NULL_TREE
+              && TREE_CODE (TYPE_NAME (yt)) == TYPE_DECL)
+       yn = DECL_NAME (TYPE_NAME (yt));
+      else
+       yn = NULL_TREE;
+
+      if (xn != NULL_TREE && xn == yn)
+       return true;
+    }
+
+  return false;
+}
+
+/* Subroutine of detect_field_duplicates: add the fields of FIELDLIST
+   to HTAB, giving errors for any duplicates.  */
+
+static void
+detect_field_duplicates_hash (tree fieldlist, htab_t htab)
+{
+  tree x, y;
+  void **slot;
+
+  for (x = fieldlist; x ; x = DECL_CHAIN (x))
+    if ((y = DECL_NAME (x)) != 0)
+      {
+       slot = htab_find_slot (htab, y, INSERT);
+       if (*slot)
+         {
+           error ("duplicate member %q+D", x);
+           DECL_NAME (x) = NULL_TREE;
+         }
+       *slot = y;
+      }
+    else if (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+            || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)
+      {
+       detect_field_duplicates_hash (TYPE_FIELDS (TREE_TYPE (x)), htab);
+
+       /* When using -fplan9-extensions, an anonymous field whose
+          name is a typedef can duplicate a field name.  */
+       if (flag_plan9_extensions
+           && TYPE_NAME (TREE_TYPE (x)) != NULL_TREE
+           && TREE_CODE (TYPE_NAME (TREE_TYPE (x))) == TYPE_DECL)
+         {
+           tree xn = DECL_NAME (TYPE_NAME (TREE_TYPE (x)));
+           slot = htab_find_slot (htab, xn, INSERT);
+           if (*slot)
+             error ("duplicate member %q+D", TYPE_NAME (TREE_TYPE (x)));
+           *slot = xn;
+         }
+      }
+}
+
 /* Generate an error for any duplicate field names in FIELDLIST.  Munge
    the list such that this does not present a problem later.  */
 
@@ -6436,27 +6794,53 @@ detect_field_duplicates (tree fieldlist)
   tree x, y;
   int timeout = 10;
 
+  /* If the struct is the list of instance variables of an Objective-C
+     class, then we need to check all the instance variables of
+     superclasses when checking for duplicates (since you can't have
+     an instance variable in a subclass with the same name as an
+     instance variable in a superclass).  We pass on this job to the
+     Objective-C compiler.  objc_detect_field_duplicates() will return
+     false if we are not checking the list of instance variables and
+     the C frontend should proceed with the standard field duplicate
+     checks.  If we are checking the list of instance variables, the
+     ObjC frontend will do the check, emit the errors if needed, and
+     then return true.  */
+  if (c_dialect_objc ())
+    if (objc_detect_field_duplicates (false))
+      return;
+
   /* First, see if there are more than "a few" fields.
      This is trivially true if there are zero or one fields.  */
-  if (!fieldlist)
-    return;
-  x = TREE_CHAIN (fieldlist);
-  if (!x)
+  if (!fieldlist || !DECL_CHAIN (fieldlist))
     return;
+  x = fieldlist;
   do {
     timeout--;
-    x = TREE_CHAIN (x);
+    if (DECL_NAME (x) == NULL_TREE
+       && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+           || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE))
+      timeout = 0;
+    x = DECL_CHAIN (x);
   } while (timeout > 0 && x);
 
-  /* If there were "few" fields, avoid the overhead of allocating
-     a hash table.  Instead just do the nested traversal thing.  */
+  /* If there were "few" fields and no anonymous structures or unions,
+     avoid the overhead of allocating a hash table.  Instead just do
+     the nested traversal thing.  */
   if (timeout > 0)
     {
-      for (x = TREE_CHAIN (fieldlist); x ; x = TREE_CHAIN (x))
-       if (DECL_NAME (x))
+      for (x = DECL_CHAIN (fieldlist); x; x = DECL_CHAIN (x))
+       /* When using -fplan9-extensions, we can have duplicates
+          between typedef names and fields.  */
+       if (DECL_NAME (x)
+           || (flag_plan9_extensions
+               && DECL_NAME (x) == NULL_TREE
+               && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+                   || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)
+               && TYPE_NAME (TREE_TYPE (x)) != NULL_TREE
+               && TREE_CODE (TYPE_NAME (TREE_TYPE (x))) == TYPE_DECL))
          {
            for (y = fieldlist; y != x; y = TREE_CHAIN (y))
-             if (DECL_NAME (y) == DECL_NAME (x))
+             if (is_duplicate_field (y, x))
                {
                  error ("duplicate member %q+D", x);
                  DECL_NAME (x) = NULL_TREE;
@@ -6466,43 +6850,83 @@ detect_field_duplicates (tree fieldlist)
   else
     {
       htab_t htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
-      void **slot;
-
-      for (x = fieldlist; x ; x = TREE_CHAIN (x))
-       if ((y = DECL_NAME (x)) != 0)
-         {
-           slot = htab_find_slot (htab, y, INSERT);
-           if (*slot)
-             {
-               error ("duplicate member %q+D", x);
-               DECL_NAME (x) = NULL_TREE;
-             }
-           *slot = y;
-         }
 
+      detect_field_duplicates_hash (fieldlist, htab);
       htab_delete (htab);
     }
 }
 
+/* Finish up struct info used by -Wc++-compat.  */
+
+static void
+warn_cxx_compat_finish_struct (tree fieldlist)
+{
+  unsigned int ix;
+  tree x;
+  struct c_binding *b;
+
+  /* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in
+     the current struct.  We do this now at the end of the struct
+     because the flag is used to issue visibility warnings, and we
+     only want to issue those warnings if the type is referenced
+     outside of the struct declaration.  */
+  FOR_EACH_VEC_ELT (tree, struct_parse_info->struct_types, ix, x)
+    C_TYPE_DEFINED_IN_STRUCT (x) = 1;
+
+  /* The TYPEDEFS_SEEN field of STRUCT_PARSE_INFO is a list of
+     typedefs used when declaring fields in this struct.  If the name
+     of any of the fields is also a typedef name then the struct would
+     not parse in C++, because the C++ lookup rules say that the
+     typedef name would be looked up in the context of the struct, and
+     would thus be the field rather than the typedef.  */
+  if (!VEC_empty (tree, struct_parse_info->typedefs_seen)
+      && fieldlist != NULL_TREE)
+    {
+      /* Use a pointer_set using the name of the typedef.  We can use
+        a pointer_set because identifiers are interned.  */
+      struct pointer_set_t *tset = pointer_set_create ();
+
+      FOR_EACH_VEC_ELT (tree, struct_parse_info->typedefs_seen, ix, x)
+       pointer_set_insert (tset, DECL_NAME (x));
+
+      for (x = fieldlist; x != NULL_TREE; x = DECL_CHAIN (x))
+       {
+         if (DECL_NAME (x) != NULL_TREE
+             && pointer_set_contains (tset, DECL_NAME (x)))
+           {
+             warning_at (DECL_SOURCE_LOCATION (x), OPT_Wc___compat,
+                         ("using %qD as both field and typedef name is "
+                          "invalid in C++"),
+                         x);
+             /* FIXME: It would be nice to report the location where
+                the typedef name is used.  */
+           }
+       }
+
+      pointer_set_destroy (tset);
+    }
+
+  /* For each field which has a binding and which was not defined in
+     an enclosing struct, clear the in_struct field.  */
+  FOR_EACH_VEC_ELT (c_binding_ptr, struct_parse_info->fields, ix, b)
+    b->in_struct = 0;
+}
+
 /* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
    LOC is the location of the RECORD_TYPE or UNION_TYPE's definition.
    FIELDLIST is a chain of FIELD_DECL nodes for the fields.
    ATTRIBUTES are attributes to be applied to the structure.
 
-   ENCLOSING_IN_STRUCT is the value of IN_STRUCT, and
-   ENCLOSING_STRUCT_TYPES is the value of STRUCT_TYPES, when the
-   struct was started.  This sets the C_TYPE_DEFINED_IN_STRUCT flag
-   for any type defined in the current struct.  */
+   ENCLOSING_STRUCT_PARSE_INFO is the value of STRUCT_PARSE_INFO when
+   the struct was started.  */
 
 tree
 finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
-              bool enclosing_in_struct,
-              VEC(tree,heap) *enclosing_struct_types)
+              struct c_struct_parse_info *enclosing_struct_parse_info)
 {
   tree x;
   bool toplevel = file_scope == current_scope;
   int saw_named_field;
-  unsigned int ix;
 
   /* If this type was previously laid out as a forward reference,
      make sure we lay it out again.  */
@@ -6513,9 +6937,15 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
 
   if (pedantic)
     {
-      for (x = fieldlist; x; x = TREE_CHAIN (x))
-       if (DECL_NAME (x) != 0)
-         break;
+      for (x = fieldlist; x; x = DECL_CHAIN (x))
+       {
+         if (DECL_NAME (x) != 0)
+           break;
+         if (flag_isoc1x
+             && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+                 || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE))
+           break;
+       }
 
       if (x == 0)
        {
@@ -6544,7 +6974,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
      until now.)  */
 
   saw_named_field = 0;
-  for (x = fieldlist; x; x = TREE_CHAIN (x))
+  for (x = fieldlist; x; x = DECL_CHAIN (x))
     {
       if (TREE_TYPE (x) == error_mark_node)
        continue;
@@ -6557,9 +6987,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
       else
        {
          /* A field that is pseudo-const makes the structure likewise.  */
-         tree t1 = TREE_TYPE (x);
-         while (TREE_CODE (t1) == ARRAY_TYPE)
-           t1 = TREE_TYPE (t1);
+         tree t1 = strip_array_types (TREE_TYPE (x));
          if ((TREE_CODE (t1) == RECORD_TYPE || TREE_CODE (t1) == UNION_TYPE)
              && C_TYPE_FIELDS_READONLY (t1))
            C_TYPE_FIELDS_READONLY (t) = 1;
@@ -6596,30 +7024,31 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
          if (TREE_CODE (t) == UNION_TYPE)
            {
              error_at (DECL_SOURCE_LOCATION (x),
-                       "%Jflexible array member in union", x);
+                       "flexible array member in union");
              TREE_TYPE (x) = error_mark_node;
            }
-         else if (TREE_CHAIN (x) != NULL_TREE)
+         else if (DECL_CHAIN (x) != NULL_TREE)
            {
              error_at (DECL_SOURCE_LOCATION (x),
-                       "%Jflexible array member not at end of struct", x);
+                       "flexible array member not at end of struct");
              TREE_TYPE (x) = error_mark_node;
            }
          else if (!saw_named_field)
            {
              error_at (DECL_SOURCE_LOCATION (x),
-                       "%Jflexible array member in otherwise empty struct",
-                       x);
+                       "flexible array member in otherwise empty struct");
              TREE_TYPE (x) = error_mark_node;
            }
        }
 
-      if (pedantic && !in_system_header && TREE_CODE (t) == RECORD_TYPE
+      if (pedantic && TREE_CODE (t) == RECORD_TYPE
          && flexible_array_type_p (TREE_TYPE (x)))
-       pedwarn (loc, OPT_pedantic, 
-                "%Jinvalid use of structure with flexible array member", x);
+       pedwarn (DECL_SOURCE_LOCATION (x), OPT_pedantic,
+                "invalid use of structure with flexible array member");
 
-      if (DECL_NAME (x))
+      if (DECL_NAME (x)
+         || TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+         || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)
        saw_named_field = 1;
     }
 
@@ -6651,7 +7080,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
          DECL_INITIAL (*fieldlistp) = 0;
        }
       else
-       fieldlistp = &TREE_CHAIN (*fieldlistp);
+       fieldlistp = &DECL_CHAIN (*fieldlistp);
   }
 
   /* Now we have the truly final field list.
@@ -6665,7 +7094,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
   {
     int len = 0;
 
-    for (x = fieldlist; x; x = TREE_CHAIN (x))
+    for (x = fieldlist; x; x = DECL_CHAIN (x))
       {
        if (len > 15 || DECL_NAME (x) == NULL)
          break;
@@ -6684,14 +7113,14 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
          ensure that this lives as long as the rest of the struct decl.
          All decls in an inline function need to be saved.  */
 
-       space = GGC_CNEW (struct lang_type);
-       space2 = GGC_NEWVAR (struct sorted_fields_type,
-                            sizeof (struct sorted_fields_type) + len * sizeof (tree));
+       space = ggc_alloc_cleared_lang_type (sizeof (struct lang_type));
+       space2 = ggc_alloc_sorted_fields_type
+         (sizeof (struct sorted_fields_type) + len * sizeof (tree));
 
        len = 0;
        space->s = space2;
        field_array = &space2->elts[0];
-       for (x = fieldlist; x; x = TREE_CHAIN (x))
+       for (x = fieldlist; x; x = DECL_CHAIN (x))
          {
            field_array[len++] = x;
 
@@ -6722,10 +7151,10 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
   /* If this was supposed to be a transparent union, but we can't
      make it one, warn and turn off the flag.  */
   if (TREE_CODE (t) == UNION_TYPE
-      && TYPE_TRANSPARENT_UNION (t)
+      && TYPE_TRANSPARENT_AGGR (t)
       && (!TYPE_FIELDS (t) || TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t))))
     {
-      TYPE_TRANSPARENT_UNION (t) = 0;
+      TYPE_TRANSPARENT_AGGR (t) = 0;
       warning_at (loc, 0, "union cannot be made transparent");
     }
 
@@ -6750,33 +7179,37 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
     }
   C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)) = 0;
 
+  /* Update type location to the one of the definition, instead of e.g.
+     a forward declaration.  */
+  if (TYPE_STUB_DECL (t))
+    DECL_SOURCE_LOCATION (TYPE_STUB_DECL (t)) = loc;
+
   /* Finish debugging output for this type.  */
   rest_of_type_compilation (t, toplevel);
 
   /* If we're inside a function proper, i.e. not file-scope and not still
      parsing parameters, then arrange for the size of a variable sized type
      to be bound now.  */
-  if (cur_stmt_list && variably_modified_type_p (t, NULL_TREE))
+  if (building_stmt_list_p () && variably_modified_type_p (t, NULL_TREE))
     add_stmt (build_stmt (loc,
                          DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t)));
 
-  /* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in
-     the current struct.  We do this now at the end of the struct
-     because the flag is used to issue visibility warnings when using
-     -Wc++-compat, and we only want to issue those warnings if the
-     type is referenced outside of the struct declaration.  */
-  for (ix = 0; VEC_iterate (tree, struct_types, ix, x); ++ix)
-    C_TYPE_DEFINED_IN_STRUCT (x) = 1;
+  if (warn_cxx_compat)
+    warn_cxx_compat_finish_struct (fieldlist);
 
-  VEC_free (tree, heap, struct_types);
+  VEC_free (tree, heap, struct_parse_info->struct_types);
+  VEC_free (c_binding_ptr, heap, struct_parse_info->fields);
+  VEC_free (tree, heap, struct_parse_info->typedefs_seen);
+  XDELETE (struct_parse_info);
 
-  in_struct = enclosing_in_struct;
-  struct_types = enclosing_struct_types;
+  struct_parse_info = enclosing_struct_parse_info;
 
   /* If this struct is defined inside a struct, add it to
-     STRUCT_TYPES.  */
-  if (in_struct && !in_sizeof && !in_typeof && !in_alignof)
-    VEC_safe_push (tree, heap, struct_types, t);
+     struct_types.  */
+  if (warn_cxx_compat
+      && struct_parse_info != NULL
+      && !in_sizeof && !in_typeof && !in_alignof)
+    VEC_safe_push (tree, heap, struct_parse_info->struct_types, t);
 
   return t;
 }
@@ -6963,7 +7396,7 @@ finish_enum (tree enumtype, tree values, tree attributes)
 
   /* Record the min/max values so that we can warn about bit-field
      enumerations that are too small for the values.  */
-  lt = GGC_CNEW (struct lang_type);
+  lt = ggc_alloc_cleared_lang_type (sizeof (struct lang_type));
   lt->enum_min = minnode;
   lt->enum_max = maxnode;
   TYPE_LANG_SPECIFIC (enumtype) = lt;
@@ -6990,21 +7423,24 @@ finish_enum (tree enumtype, tree values, tree attributes)
   rest_of_type_compilation (enumtype, toplevel);
 
   /* If this enum is defined inside a struct, add it to
-     STRUCT_TYPES.  */
-  if (in_struct && !in_sizeof && !in_typeof && !in_alignof)
-    VEC_safe_push (tree, heap, struct_types, enumtype);
+     struct_types.  */
+  if (warn_cxx_compat
+      && struct_parse_info != NULL
+      && !in_sizeof && !in_typeof && !in_alignof)
+    VEC_safe_push (tree, heap, struct_parse_info->struct_types, enumtype);
 
   return enumtype;
 }
 
 /* Build and install a CONST_DECL for one value of the
    current enumeration type (one that was begun with start_enum).
-   LOC is the location of the enumerator.
+   DECL_LOC is the location of the enumerator.
+   LOC is the location of the '=' operator if any, DECL_LOC otherwise.
    Return a tree-list containing the CONST_DECL and its value.
    Assignment of sequential values by default is handled here.  */
 
 tree
-build_enumerator (location_t loc,
+build_enumerator (location_t decl_loc, location_t loc,
                  struct c_enum_contents *the_enum, tree name, tree value)
 {
   tree decl, type;
@@ -7061,7 +7497,7 @@ build_enumerator (location_t loc,
      (6.4.4.3/2 in the C99 Standard).  GCC allows any integer type as
      an extension.  */
   else if (!int_fits_type_p (value, integer_type_node))
-    pedwarn (loc, OPT_pedantic, 
+    pedwarn (loc, OPT_pedantic,
             "ISO C restricts enumerator values to range of %<int%>");
 
   /* The ISO C Standard mandates enumerators to have type int, even
@@ -7078,9 +7514,8 @@ build_enumerator (location_t loc,
 
   /* Set basis for default for next value.  */
   the_enum->enum_next_value
-    = build_binary_op
-         (EXPR_HAS_LOCATION (value) ? EXPR_LOCATION (value) : input_location,
-        PLUS_EXPR, value, integer_one_node, 0);
+    = build_binary_op (EXPR_LOC_OR_HERE (value),
+                      PLUS_EXPR, value, integer_one_node, 0);
   the_enum->enum_overflow = tree_int_cst_lt (the_enum->enum_next_value, value);
 
   /* Now create a declaration for the enum value name.  */
@@ -7092,7 +7527,7 @@ build_enumerator (location_t loc,
                                  >= TYPE_PRECISION (integer_type_node)
                                  && TYPE_UNSIGNED (type)));
 
-  decl = build_decl (loc, CONST_DECL, name, type);
+  decl = build_decl (decl_loc, CONST_DECL, name, type);
   DECL_INITIAL (decl) = convert (type, value);
   pushdecl (decl);
 
@@ -7173,7 +7608,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
     }
 
   if (warn_about_return_type)
-    pedwarn_c99 (loc, flag_isoc99 ? 0 
+    pedwarn_c99 (loc, flag_isoc99 ? 0
                 : (warn_return_type ? OPT_Wreturn_type : OPT_Wimplicit_int),
                 "return type defaults to %<int%>");
 
@@ -7181,6 +7616,10 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
      error_mark_node is replaced below (in pop_scope) with the BLOCK.  */
   DECL_INITIAL (decl1) = error_mark_node;
 
+  /* A nested function is not global.  */
+  if (current_function_decl != 0)
+    TREE_PUBLIC (decl1) = 0;
+
   /* If this definition isn't a prototype and we had a prototype declaration
      before, copy the arg type info from that prototype.  */
   old_decl = lookup_name_in_scope (DECL_NAME (decl1), current_scope);
@@ -7189,7 +7628,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
   current_function_prototype_locus = UNKNOWN_LOCATION;
   current_function_prototype_built_in = false;
   current_function_prototype_arg_types = NULL_TREE;
-  if (TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
+  if (!prototype_p (TREE_TYPE (decl1)))
     {
       if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
          && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
@@ -7238,7 +7677,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
   /* Optionally warn of old-fashioned def with no previous prototype.  */
   if (warn_strict_prototypes
       && old_decl != error_mark_node
-      && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
+      && !prototype_p (TREE_TYPE (decl1))
       && C_DECL_ISNT_PROTOTYPE (old_decl))
     warning_at (loc, OPT_Wstrict_prototypes,
                "function declaration isn%'t a prototype");
@@ -7256,7 +7695,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
           && old_decl != 0
           && old_decl != error_mark_node
           && TREE_USED (old_decl)
-          && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
+          && !prototype_p (TREE_TYPE (old_decl)))
     warning_at (loc, OPT_Wmissing_prototypes,
                "%qD was used with no prototype before its definition", decl1);
   /* Optionally warn of any global def with no previous declaration.  */
@@ -7281,10 +7720,6 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
      (This does not mean `static' in the C sense!)  */
   TREE_STATIC (decl1) = 1;
 
-  /* A nested function is not global.  */
-  if (current_function_decl != 0)
-    TREE_PUBLIC (decl1) = 0;
-
   /* This is the earliest point at which we might know the assembler
      name of the function.  Thus, if it's set before this, die horribly.  */
   gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl1));
@@ -7335,11 +7770,14 @@ static void
 store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info)
 {
   tree decl;
+  c_arg_tag *tag;
+  unsigned ix;
 
   if (current_scope->bindings)
     {
-      error ("%Jold-style parameter declarations in prototyped "
-            "function definition", fndecl);
+      error_at (DECL_SOURCE_LOCATION (fndecl),
+               "old-style parameter declarations in prototyped "
+               "function definition");
 
       /* Get rid of the old-style declarations.  */
       pop_scope ();
@@ -7351,13 +7789,12 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info)
      its parameter list).  */
   else if (!in_system_header && !current_function_scope
           && arg_info->types != error_mark_node)
-    warning (OPT_Wtraditional,
-            "%Jtraditional C rejects ISO C style function definitions",
-            fndecl);
+    warning_at (DECL_SOURCE_LOCATION (fndecl), OPT_Wtraditional,
+               "traditional C rejects ISO C style function definitions");
 
   /* Now make all the parameter declarations visible in the function body.
      We can bypass most of the grunt work of pushdecl.  */
-  for (decl = arg_info->parms; decl; decl = TREE_CHAIN (decl))
+  for (decl = arg_info->parms; decl; decl = DECL_CHAIN (decl))
     {
       DECL_CONTEXT (decl) = current_function_decl;
       if (DECL_NAME (decl))
@@ -7369,25 +7806,27 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info)
            warn_if_shadowing (decl);
        }
       else
-       error ("%Jparameter name omitted", decl);
+       error_at (DECL_SOURCE_LOCATION (decl), "parameter name omitted");
     }
 
   /* Record the parameter list in the function declaration.  */
   DECL_ARGUMENTS (fndecl) = arg_info->parms;
 
   /* Now make all the ancillary declarations visible, likewise.  */
-  for (decl = arg_info->others; decl; decl = TREE_CHAIN (decl))
+  for (decl = arg_info->others; decl; decl = DECL_CHAIN (decl))
     {
       DECL_CONTEXT (decl) = current_function_decl;
       if (DECL_NAME (decl))
        bind (DECL_NAME (decl), decl, current_scope,
-             /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION);
+             /*invisible=*/false,
+             /*nested=*/(TREE_CODE (decl) == FUNCTION_DECL),
+             UNKNOWN_LOCATION);
     }
 
   /* And all the tag declarations.  */
-  for (decl = arg_info->tags; decl; decl = TREE_CHAIN (decl))
-    if (TREE_PURPOSE (decl))
-      bind (TREE_PURPOSE (decl), TREE_VALUE (decl), current_scope,
+  FOR_EACH_VEC_ELT_REVERSE (c_arg_tag, arg_info->tags, ix, tag)
+    if (tag->id)
+      bind (tag->id, tag->type, current_scope,
            /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION);
 }
 
@@ -7422,6 +7861,9 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
       if (b && B_IN_CURRENT_SCOPE (b))
        {
          decl = b->decl;
+         /* Skip erroneous parameters.  */
+         if (decl == error_mark_node)
+           continue;
          /* If we got something other than a PARM_DECL it is an error.  */
          if (TREE_CODE (decl) != PARM_DECL)
            error_at (DECL_SOURCE_LOCATION (decl),
@@ -7470,7 +7912,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
          if (flag_isoc99)
            pedwarn (DECL_SOURCE_LOCATION (decl),
                     0, "type of %qD defaults to %<int%>", decl);
-         else 
+         else
            warning_at (DECL_SOURCE_LOCATION (decl),
                        OPT_Wmissing_parameter_type,
                        "type of %qD defaults to %<int%>", decl);
@@ -7526,10 +7968,10 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
       for (parm = TREE_CHAIN (parm); parm; parm = TREE_CHAIN (parm))
        if (TREE_PURPOSE (parm))
          {
-           TREE_CHAIN (last) = TREE_PURPOSE (parm);
+           DECL_CHAIN (last) = TREE_PURPOSE (parm);
            last = TREE_PURPOSE (parm);
          }
-      TREE_CHAIN (last) = 0;
+      DECL_CHAIN (last) = 0;
     }
 
   pointer_set_destroy (seen_args);
@@ -7545,7 +7987,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
             type = current_function_prototype_arg_types;
           parm || (type && TREE_VALUE (type) != error_mark_node
                    && (TYPE_MAIN_VARIANT (TREE_VALUE (type)) != void_type_node));
-          parm = TREE_CHAIN (parm), type = TREE_CHAIN (type))
+          parm = DECL_CHAIN (parm), type = TREE_CHAIN (type))
        {
          if (parm == 0 || type == 0
              || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
@@ -7636,7 +8078,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
     {
       tree actual = 0, last = 0, type;
 
-      for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm))
+      for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
        {
          type = tree_cons (NULL_TREE, DECL_ARG_TYPE (parm), NULL_TREE);
          if (last)
@@ -7725,43 +8167,13 @@ store_parm_decls (void)
      because we throw away the array type in favor of a pointer type, and
      thus won't naturally see the SAVE_EXPR containing the increment.  All
      other pending sizes would be handled by gimplify_parameters.  */
-  {
-    tree t;
-    for (t = nreverse (get_pending_sizes ()); t ; t = TREE_CHAIN (t))
-      add_stmt (TREE_VALUE (t));
-  }
-
-  /* Even though we're inside a function body, we still don't want to
-     call expand_expr to calculate the size of a variable-sized array.
-     We haven't necessarily assigned RTL to all variables yet, so it's
-     not safe to try to expand expressions involving them.  */
-  cfun->dont_save_pending_sizes_p = 1;
+  if (arg_info->pending_sizes)
+    add_stmt (arg_info->pending_sizes);
 }
 \f
-/* Emit diagnostics that require gimple input for detection.  Operate on
-   FNDECL and all its nested functions.  */
-
-static void
-c_gimple_diagnostics_recursively (tree fndecl)
-{
-  struct cgraph_node *cgn;
-  gimple_seq body = gimple_body (fndecl);
-
-  /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
-  c_warn_unused_result (body);
-
-  /* Notice when OpenMP structured block constraints are violated.  */
-  if (flag_openmp)
-    diagnose_omp_structured_block_errors (fndecl);
-
-  /* Finalize all nested functions now.  */
-  cgn = cgraph_node (fndecl);
-  for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
-    c_gimple_diagnostics_recursively (cgn->decl);
-}
 
 /* Finish up a function declaration and compile that function
-   all the way to assembler language output.  The free the storage
+   all the way to assembler language output.  Then free the storage
    for the function definition.
 
    This is called after parsing the body of the function definition.  */
@@ -7770,12 +8182,15 @@ void
 finish_function (void)
 {
   tree fndecl = current_function_decl;
+  
+  if (c_dialect_objc ())
+    objc_finish_function ();
 
   if (TREE_CODE (fndecl) == FUNCTION_DECL
       && targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
     {
       tree args = DECL_ARGUMENTS (fndecl);
-      for (; args; args = TREE_CHAIN (args))
+      for (; args; args = DECL_CHAIN (args))
        {
          tree type = TREE_TYPE (args);
          if (INTEGRAL_TYPE_P (type)
@@ -7816,6 +8231,8 @@ finish_function (void)
       && !current_function_returns_value && !current_function_returns_null
       /* Don't complain if we are no-return.  */
       && !current_function_returns_abnormally
+      /* Don't complain if we are declared noreturn.  */
+      && !TREE_THIS_VOLATILE (fndecl)
       /* Don't warn for main().  */
       && !MAIN_NAME_P (DECL_NAME (fndecl))
       /* Or if they didn't actually specify a return type.  */
@@ -7829,6 +8246,25 @@ finish_function (void)
       TREE_NO_WARNING (fndecl) = 1;
     }
 
+  /* Complain about parameters that are only set, but never otherwise used.  */
+  if (warn_unused_but_set_parameter)
+    {
+      tree decl;
+
+      for (decl = DECL_ARGUMENTS (fndecl);
+          decl;
+          decl = DECL_CHAIN (decl))
+       if (TREE_USED (decl)
+           && TREE_CODE (decl) == PARM_DECL
+           && !DECL_READ_P (decl)
+           && DECL_NAME (decl)
+           && !DECL_ARTIFICIAL (decl)
+           && !TREE_NO_WARNING (decl))
+         warning_at (DECL_SOURCE_LOCATION (decl),
+                     OPT_Wunused_but_set_parameter,
+                     "parameter %qD set but not used", decl);
+    }
+
   /* Store the end of the function, so that we get good line number
      info for the epilogue.  */
   cfun->function_end_locus = input_location;
@@ -7837,7 +8273,7 @@ finish_function (void)
   c_determine_visibility (fndecl);
 
   /* For GNU C extern inline functions disregard inline limits.  */
-  if (DECL_EXTERNAL (fndecl) 
+  if (DECL_EXTERNAL (fndecl)
       && DECL_DECLARED_INLINE_P (fndecl))
     DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1;
 
@@ -7850,8 +8286,8 @@ finish_function (void)
     {
       if (!decl_function_context (fndecl))
        {
+         invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
          c_genericize (fndecl);
-         c_gimple_diagnostics_recursively (fndecl);
 
          /* ??? Objc emits functions after finalizing the compilation unit.
             This should be cleaned up later and this conditional removed.  */
@@ -7867,7 +8303,7 @@ finish_function (void)
          /* Register this function with cgraph just far enough to get it
            added to our parent's nested function list.  Handy, since the
            C front end doesn't have such a list.  */
-         (void) cgraph_node (fndecl);
+         (void) cgraph_get_create_node (fndecl);
        }
     }
 
@@ -7883,16 +8319,23 @@ finish_function (void)
 \f
 /* Check the declarations given in a for-loop for satisfying the C99
    constraints.  If exactly one such decl is found, return it.  LOC is
-   the location of the opening parenthesis of the for loop.  */
+   the location of the opening parenthesis of the for loop.  The last
+   parameter allows you to control the "for loop initial declarations
+   are only allowed in C99 mode".  Normally, you should pass
+   flag_isoc99 as that parameter.  But in some cases (Objective-C
+   foreach loop, for example) we want to run the checks in this
+   function even if not in C99 mode, so we allow the caller to turn
+   off the error about not being in C99 mode.
+*/
 
 tree
-check_for_loop_decls (location_t loc)
+check_for_loop_decls (location_t loc, bool turn_off_iso_c99_error)
 {
   struct c_binding *b;
   tree one_decl = NULL_TREE;
   int n_decls = 0;
 
-  if (!flag_isoc99)
+  if (!turn_off_iso_c99_error)
     {
       static bool hint = true;
       /* If we get here, declarations have been used in a for loop without
@@ -7979,10 +8422,12 @@ void
 c_push_function_context (void)
 {
   struct language_function *p;
-  p = GGC_NEW (struct language_function);
+  p = ggc_alloc_language_function ();
   cfun->language = p;
 
   p->base.x_stmt_tree = c_stmt_tree;
+  c_stmt_tree.x_cur_stmt_list
+    = VEC_copy (tree, gc, c_stmt_tree.x_cur_stmt_list);
   p->x_break_label = c_break_label;
   p->x_cont_label = c_cont_label;
   p->x_switch_stack = c_switch_stack;
@@ -8027,21 +8472,6 @@ c_pop_function_context (void)
   warn_about_return_type = p->warn_about_return_type;
 }
 
-/* Copy the DECL_LANG_SPECIFIC data associated with DECL.  */
-
-void
-c_dup_lang_specific_decl (tree decl)
-{
-  struct lang_decl *ld;
-
-  if (!DECL_LANG_SPECIFIC (decl))
-    return;
-
-  ld = GGC_NEW (struct lang_decl);
-  memcpy (ld, DECL_LANG_SPECIFIC (decl), sizeof (struct lang_decl));
-  DECL_LANG_SPECIFIC (decl) = ld;
-}
-
 /* The functions below are required for functionality of doing
    function at once processing in the C front end. Currently these
    functions are not called from anywhere in the C front end, but as
@@ -8193,10 +8623,9 @@ build_null_declspecs (void)
   ret->storage_class = csc_none;
   ret->expr_const_operands = true;
   ret->declspecs_seen_p = false;
-  ret->type_seen_p = false;
+  ret->typespec_kind = ctsk_none;
   ret->non_sc_seen_p = false;
   ret->typedef_p = false;
-  ret->tag_defined_p = false;
   ret->explicit_signed_p = false;
   ret->deprecated_p = false;
   ret->default_int_p = false;
@@ -8212,9 +8641,29 @@ build_null_declspecs (void)
   ret->volatile_p = false;
   ret->restrict_p = false;
   ret->saturating_p = false;
+  ret->address_space = ADDR_SPACE_GENERIC;
   return ret;
 }
 
+/* Add the address space ADDRSPACE to the declaration specifiers
+   SPECS, returning SPECS.  */
+
+struct c_declspecs *
+declspecs_add_addrspace (struct c_declspecs *specs, addr_space_t as)
+{
+  specs->non_sc_seen_p = true;
+  specs->declspecs_seen_p = true;
+
+  if (!ADDR_SPACE_GENERIC_P (specs->address_space)
+      && specs->address_space != as)
+    error ("incompatible address space qualifiers %qs and %qs",
+          c_addr_space_name (as),
+          c_addr_space_name (specs->address_space));
+  else
+    specs->address_space = as;
+  return specs;
+}
+
 /* Add the type qualifier QUAL to the declaration specifiers SPECS,
    returning SPECS.  */
 
@@ -8254,12 +8703,13 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual)
    returning SPECS.  */
 
 struct c_declspecs *
-declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
+declspecs_add_type (location_t loc, struct c_declspecs *specs,
+                   struct c_typespec spec)
 {
   tree type = spec.spec;
   specs->non_sc_seen_p = true;
   specs->declspecs_seen_p = true;
-  specs->type_seen_p = true;
+  specs->typespec_kind = spec.kind;
   if (TREE_DEPRECATED (type))
     specs->deprecated_p = true;
 
@@ -8271,7 +8721,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
       enum rid i = C_RID_CODE (type);
       if (specs->type)
        {
-         error ("two or more data types in declaration specifiers");
+         error_at (loc, "two or more data types in declaration specifiers");
          return specs;
        }
       if ((int) i <= (int) RID_LAST_MODIFIER)
@@ -8283,203 +8733,271 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
            case RID_LONG:
              if (specs->long_long_p)
                {
-                 error ("%<long long long%> is too long for GCC");
+                 error_at (loc, "%<long long long%> is too long for GCC");
                  break;
                }
              if (specs->long_p)
                {
                  if (specs->typespec_word == cts_double)
                    {
-                     error ("both %<long long%> and %<double%> in "
-                            "declaration specifiers");
+                     error_at (loc,
+                               ("both %<long long%> and %<double%> in "
+                                "declaration specifiers"));
                      break;
                    }
-                 pedwarn_c90 (input_location, OPT_Wlong_long, 
+                 pedwarn_c90 (loc, OPT_Wlong_long,
                               "ISO C90 does not support %<long long%>");
                  specs->long_long_p = 1;
                  break;
                }
              if (specs->short_p)
-               error ("both %<long%> and %<short%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<short%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_void)
-               error ("both %<long%> and %<void%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<void%> in "
+                          "declaration specifiers"));
+             else if (specs->typespec_word == cts_int128)
+                 error_at (loc,
+                           ("both %<long%> and %<__int128%> in "
+                            "declaration specifiers"));
              else if (specs->typespec_word == cts_bool)
-               error ("both %<long%> and %<_Bool%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<_Bool%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_char)
-               error ("both %<long%> and %<char%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<char%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_float)
-               error ("both %<long%> and %<float%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<float%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat32)
-               error ("both %<long%> and %<_Decimal32%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<_Decimal32%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat64)
-               error ("both %<long%> and %<_Decimal64%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<_Decimal64%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat128)
-               error ("both %<long%> and %<_Decimal128%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<_Decimal128%> in "
+                          "declaration specifiers"));
              else
                specs->long_p = true;
              break;
            case RID_SHORT:
              dupe = specs->short_p;
              if (specs->long_p)
-               error ("both %<long%> and %<short%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<short%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_void)
-               error ("both %<short%> and %<void%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<short%> and %<void%> in "
+                          "declaration specifiers"));
+             else if (specs->typespec_word == cts_int128)
+               error_at (loc,
+                         ("both %<short%> and %<__int128%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_bool)
-               error ("both %<short%> and %<_Bool%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<short%> and %<_Bool%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_char)
-               error ("both %<short%> and %<char%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<short%> and %<char%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_float)
-               error ("both %<short%> and %<float%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<short%> and %<float%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_double)
-               error ("both %<short%> and %<double%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<short%> and %<double%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat32)
-                error ("both %<short%> and %<_Decimal32%> in "
-                      "declaration specifiers");
+                error_at (loc,
+                         ("both %<short%> and %<_Decimal32%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat64)
-               error ("both %<short%> and %<_Decimal64%> in "
-                                       "declaration specifiers");
+               error_at (loc,
+                         ("both %<short%> and %<_Decimal64%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat128)
-               error ("both %<short%> and %<_Decimal128%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<short%> and %<_Decimal128%> in "
+                          "declaration specifiers"));
              else
                specs->short_p = true;
              break;
            case RID_SIGNED:
              dupe = specs->signed_p;
              if (specs->unsigned_p)
-               error ("both %<signed%> and %<unsigned%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<unsigned%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_void)
-               error ("both %<signed%> and %<void%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<void%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_bool)
-               error ("both %<signed%> and %<_Bool%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<_Bool%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_float)
-               error ("both %<signed%> and %<float%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<float%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_double)
-               error ("both %<signed%> and %<double%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<double%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat32)
-               error ("both %<signed%> and %<_Decimal32%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<_Decimal32%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat64)
-               error ("both %<signed%> and %<_Decimal64%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<_Decimal64%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat128)
-               error ("both %<signed%> and %<_Decimal128%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<_Decimal128%> in "
+                          "declaration specifiers"));
              else
                specs->signed_p = true;
              break;
            case RID_UNSIGNED:
              dupe = specs->unsigned_p;
              if (specs->signed_p)
-               error ("both %<signed%> and %<unsigned%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<unsigned%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_void)
-               error ("both %<unsigned%> and %<void%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<unsigned%> and %<void%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_bool)
-               error ("both %<unsigned%> and %<_Bool%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<unsigned%> and %<_Bool%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_float)
-               error ("both %<unsigned%> and %<float%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<unsigned%> and %<float%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_double)
-               error ("both %<unsigned%> and %<double%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<unsigned%> and %<double%> in "
+                          "declaration specifiers"));
               else if (specs->typespec_word == cts_dfloat32)
-               error ("both %<unsigned%> and %<_Decimal32%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<unsigned%> and %<_Decimal32%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat64)
-               error ("both %<unsigned%> and %<_Decimal64%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<unsigned%> and %<_Decimal64%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat128)
-               error ("both %<unsigned%> and %<_Decimal128%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<unsigned%> and %<_Decimal128%> in "
+                          "declaration specifiers"));
              else
                specs->unsigned_p = true;
              break;
            case RID_COMPLEX:
              dupe = specs->complex_p;
              if (!flag_isoc99 && !in_system_header)
-               pedwarn (input_location, OPT_pedantic, "ISO C90 does not support complex types");
+               pedwarn (loc, OPT_pedantic,
+                        "ISO C90 does not support complex types");
              if (specs->typespec_word == cts_void)
-               error ("both %<complex%> and %<void%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<complex%> and %<void%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_bool)
-               error ("both %<complex%> and %<_Bool%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<complex%> and %<_Bool%> in "
+                          "declaration specifiers"));
               else if (specs->typespec_word == cts_dfloat32)
-               error ("both %<complex%> and %<_Decimal32%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<complex%> and %<_Decimal32%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat64)
-               error ("both %<complex%> and %<_Decimal64%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<complex%> and %<_Decimal64%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat128)
-               error ("both %<complex%> and %<_Decimal128%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<complex%> and %<_Decimal128%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_fract)
-               error ("both %<complex%> and %<_Fract%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<complex%> and %<_Fract%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_accum)
-               error ("both %<complex%> and %<_Accum%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<complex%> and %<_Accum%> in "
+                          "declaration specifiers"));
              else if (specs->saturating_p)
-               error ("both %<complex%> and %<_Sat%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<complex%> and %<_Sat%> in "
+                          "declaration specifiers"));
              else
                specs->complex_p = true;
              break;
            case RID_SAT:
              dupe = specs->saturating_p;
-             pedwarn (input_location, OPT_pedantic, "ISO C does not support saturating types");
-             if (specs->typespec_word == cts_void)
-               error ("both %<_Sat%> and %<void%> in "
-                      "declaration specifiers");
+             pedwarn (loc, OPT_pedantic,
+                      "ISO C does not support saturating types");
+             if (specs->typespec_word == cts_int128)
+               {
+                 error_at (loc,
+                           ("both %<_Sat%> and %<__int128%> in "
+                            "declaration specifiers"));
+               }
+             else if (specs->typespec_word == cts_void)
+               error_at (loc,
+                         ("both %<_Sat%> and %<void%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_bool)
-               error ("both %<_Sat%> and %<_Bool%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<_Bool%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_char)
-               error ("both %<_Sat%> and %<char%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<char%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_int)
-               error ("both %<_Sat%> and %<int%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<int%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_float)
-               error ("both %<_Sat%> and %<float%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<float%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_double)
-               error ("both %<_Sat%> and %<double%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<double%> in "
+                          "declaration specifiers"));
               else if (specs->typespec_word == cts_dfloat32)
-               error ("both %<_Sat%> and %<_Decimal32%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<_Decimal32%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat64)
-               error ("both %<_Sat%> and %<_Decimal64%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<_Decimal64%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_dfloat128)
-               error ("both %<_Sat%> and %<_Decimal128%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<_Decimal128%> in "
+                          "declaration specifiers"));
              else if (specs->complex_p)
-               error ("both %<_Sat%> and %<complex%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<complex%> in "
+                          "declaration specifiers"));
              else
                specs->saturating_p = true;
              break;
@@ -8488,127 +9006,179 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
            }
 
          if (dupe)
-           error ("duplicate %qE", type);
+           error_at (loc, "duplicate %qE", type);
 
          return specs;
        }
       else
        {
          /* "void", "_Bool", "char", "int", "float", "double", "_Decimal32",
-            "_Decimal64", "_Decimal128", "_Fract" or "_Accum".  */
+            "__int128", "_Decimal64", "_Decimal128", "_Fract" or "_Accum".  */
          if (specs->typespec_word != cts_none)
            {
-             error ("two or more data types in declaration specifiers");
+             error_at (loc,
+                       "two or more data types in declaration specifiers");
              return specs;
            }
          switch (i)
            {
+           case RID_INT128:
+             if (int128_integer_type_node == NULL_TREE)
+               {
+                 error_at (loc, "%<__int128%> is not supported for this target");
+                 return specs;
+               }
+             if (!in_system_header)
+               pedwarn (loc, OPT_pedantic,
+                        "ISO C does not support %<__int128%> type");
+
+             if (specs->long_p)
+               error_at (loc,
+                         ("both %<__int128%> and %<long%> in "
+                          "declaration specifiers"));
+             else if (specs->saturating_p)
+               error_at (loc,
+                         ("both %<_Sat%> and %<__int128%> in "
+                          "declaration specifiers"));
+             else if (specs->short_p)
+               error_at (loc,
+                         ("both %<__int128%> and %<short%> in "
+                          "declaration specifiers"));
+             else
+               specs->typespec_word = cts_int128;
+             return specs;
            case RID_VOID:
              if (specs->long_p)
-               error ("both %<long%> and %<void%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<void%> in "
+                          "declaration specifiers"));
              else if (specs->short_p)
-               error ("both %<short%> and %<void%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<short%> and %<void%> in "
+                          "declaration specifiers"));
              else if (specs->signed_p)
-               error ("both %<signed%> and %<void%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<void%> in "
+                          "declaration specifiers"));
              else if (specs->unsigned_p)
-               error ("both %<unsigned%> and %<void%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<unsigned%> and %<void%> in "
+                          "declaration specifiers"));
              else if (specs->complex_p)
-               error ("both %<complex%> and %<void%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<complex%> and %<void%> in "
+                          "declaration specifiers"));
              else if (specs->saturating_p)
-               error ("both %<_Sat%> and %<void%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<void%> in "
+                          "declaration specifiers"));
              else
                specs->typespec_word = cts_void;
              return specs;
            case RID_BOOL:
              if (specs->long_p)
-               error ("both %<long%> and %<_Bool%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<_Bool%> in "
+                          "declaration specifiers"));
              else if (specs->short_p)
-               error ("both %<short%> and %<_Bool%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<short%> and %<_Bool%> in "
+                          "declaration specifiers"));
              else if (specs->signed_p)
-               error ("both %<signed%> and %<_Bool%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<_Bool%> in "
+                          "declaration specifiers"));
              else if (specs->unsigned_p)
-               error ("both %<unsigned%> and %<_Bool%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<unsigned%> and %<_Bool%> in "
+                          "declaration specifiers"));
              else if (specs->complex_p)
-               error ("both %<complex%> and %<_Bool%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<complex%> and %<_Bool%> in "
+                          "declaration specifiers"));
              else if (specs->saturating_p)
-               error ("both %<_Sat%> and %<_Bool%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<_Bool%> in "
+                          "declaration specifiers"));
              else
                specs->typespec_word = cts_bool;
              return specs;
            case RID_CHAR:
              if (specs->long_p)
-               error ("both %<long%> and %<char%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<char%> in "
+                          "declaration specifiers"));
              else if (specs->short_p)
-               error ("both %<short%> and %<char%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<short%> and %<char%> in "
+                          "declaration specifiers"));
              else if (specs->saturating_p)
-               error ("both %<_Sat%> and %<char%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<char%> in "
+                          "declaration specifiers"));
              else
                specs->typespec_word = cts_char;
              return specs;
            case RID_INT:
              if (specs->saturating_p)
-               error ("both %<_Sat%> and %<int%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<int%> in "
+                          "declaration specifiers"));
              else
                specs->typespec_word = cts_int;
              return specs;
            case RID_FLOAT:
              if (specs->long_p)
-               error ("both %<long%> and %<float%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long%> and %<float%> in "
+                          "declaration specifiers"));
              else if (specs->short_p)
-               error ("both %<short%> and %<float%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<short%> and %<float%> in "
+                          "declaration specifiers"));
              else if (specs->signed_p)
-               error ("both %<signed%> and %<float%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<float%> in "
+                          "declaration specifiers"));
              else if (specs->unsigned_p)
-               error ("both %<unsigned%> and %<float%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<unsigned%> and %<float%> in "
+                          "declaration specifiers"));
              else if (specs->saturating_p)
-               error ("both %<_Sat%> and %<float%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<float%> in "
+                          "declaration specifiers"));
              else
                specs->typespec_word = cts_float;
              return specs;
            case RID_DOUBLE:
              if (specs->long_long_p)
-               error ("both %<long long%> and %<double%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<long long%> and %<double%> in "
+                          "declaration specifiers"));
              else if (specs->short_p)
-               error ("both %<short%> and %<double%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<short%> and %<double%> in "
+                          "declaration specifiers"));
              else if (specs->signed_p)
-               error ("both %<signed%> and %<double%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<signed%> and %<double%> in "
+                          "declaration specifiers"));
              else if (specs->unsigned_p)
-               error ("both %<unsigned%> and %<double%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<unsigned%> and %<double%> in "
+                          "declaration specifiers"));
              else if (specs->saturating_p)
-               error ("both %<_Sat%> and %<double%> in "
-                      "declaration specifiers");
+               error_at (loc,
+                         ("both %<_Sat%> and %<double%> in "
+                          "declaration specifiers"));
              else
                specs->typespec_word = cts_double;
              return specs;
            case RID_DFLOAT32:
            case RID_DFLOAT64:
            case RID_DFLOAT128:
-             { 
+             {
                const char *str;
                if (i == RID_DFLOAT32)
                  str = "_Decimal32";
@@ -8617,26 +9187,40 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
                else
                  str = "_Decimal128";
                if (specs->long_long_p)
-                 error ("both %<long long%> and %<%s%> in "
-                        "declaration specifiers", str);
+                 error_at (loc,
+                           ("both %<long long%> and %<%s%> in "
+                            "declaration specifiers"),
+                           str);
                if (specs->long_p)
-                 error ("both %<long%> and %<%s%> in "
-                        "declaration specifiers", str);
+                 error_at (loc,
+                           ("both %<long%> and %<%s%> in "
+                            "declaration specifiers"),
+                           str);
                else if (specs->short_p)
-                 error ("both %<short%> and %<%s%> in "
-                        "declaration specifiers", str);
+                 error_at (loc,
+                           ("both %<short%> and %<%s%> in "
+                            "declaration specifiers"),
+                           str);
                else if (specs->signed_p)
-                 error ("both %<signed%> and %<%s%> in "
-                        "declaration specifiers", str);
+                 error_at (loc,
+                           ("both %<signed%> and %<%s%> in "
+                            "declaration specifiers"),
+                           str);
                else if (specs->unsigned_p)
-                 error ("both %<unsigned%> and %<%s%> in "
-                        "declaration specifiers", str);
+                 error_at (loc,
+                           ("both %<unsigned%> and %<%s%> in "
+                            "declaration specifiers"),
+                           str);
                 else if (specs->complex_p)
-                  error ("both %<complex%> and %<%s%> in "
-                         "declaration specifiers", str);
+                  error_at (loc,
+                           ("both %<complex%> and %<%s%> in "
+                            "declaration specifiers"),
+                           str);
                 else if (specs->saturating_p)
-                  error ("both %<_Sat%> and %<%s%> in "
-                         "declaration specifiers", str);
+                  error_at (loc,
+                           ("both %<_Sat%> and %<%s%> in "
+                            "declaration specifiers"),
+                           str);
                else if (i == RID_DFLOAT32)
                  specs->typespec_word = cts_dfloat32;
                else if (i == RID_DFLOAT64)
@@ -8645,8 +9229,10 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
                  specs->typespec_word = cts_dfloat128;
              }
              if (!targetm.decimal_float_supported_p ())
-               error ("decimal floating point not supported for this target");
-             pedwarn (input_location, OPT_pedantic, 
+               error_at (loc,
+                         ("decimal floating point not supported "
+                          "for this target"));
+             pedwarn (loc, OPT_pedantic,
                       "ISO C does not support decimal floating point");
              return specs;
            case RID_FRACT:
@@ -8658,16 +9244,19 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
                else
                  str = "_Accum";
                 if (specs->complex_p)
-                  error ("both %<complex%> and %<%s%> in "
-                         "declaration specifiers", str);
+                  error_at (loc,
+                           ("both %<complex%> and %<%s%> in "
+                            "declaration specifiers"),
+                           str);
                else if (i == RID_FRACT)
                    specs->typespec_word = cts_fract;
                else
                    specs->typespec_word = cts_accum;
              }
              if (!targetm.fixed_point_supported_p ())
-               error ("fixed-point types not supported for this target");
-             pedwarn (input_location, OPT_pedantic, 
+               error_at (loc,
+                         "fixed-point types not supported for this target");
+             pedwarn (loc, OPT_pedantic,
                       "ISO C does not support fixed-point types");
              return specs;
            default:
@@ -8685,7 +9274,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
   if (specs->type || specs->typespec_word != cts_none
       || specs->long_p || specs->short_p || specs->signed_p
       || specs->unsigned_p || specs->complex_p)
-    error ("two or more data types in declaration specifiers");
+    error_at (loc, "two or more data types in declaration specifiers");
   else if (TREE_CODE (type) == TYPE_DECL)
     {
       if (TREE_TYPE (type) == error_mark_node)
@@ -8696,23 +9285,34 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
          specs->decl_attr = DECL_ATTRIBUTES (type);
          specs->typedef_p = true;
          specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type);
+
+         /* If this typedef name is defined in a struct, then a C++
+            lookup would return a different value.  */
+         if (warn_cxx_compat
+             && I_SYMBOL_BINDING (DECL_NAME (type))->in_struct)
+           warning_at (loc, OPT_Wc___compat,
+                       "C++ lookup of %qD would return a field, not a type",
+                       type);
+
+         /* If we are parsing a struct, record that a struct field
+            used a typedef.  */
+         if (warn_cxx_compat && struct_parse_info != NULL)
+           VEC_safe_push (tree, heap, struct_parse_info->typedefs_seen, type);
        }
     }
   else if (TREE_CODE (type) == IDENTIFIER_NODE)
     {
       tree t = lookup_name (type);
       if (!t || TREE_CODE (t) != TYPE_DECL)
-       error ("%qE fails to be a typedef or built in type", type);
+       error_at (loc, "%qE fails to be a typedef or built in type", type);
       else if (TREE_TYPE (t) == error_mark_node)
        ;
       else
        specs->type = TREE_TYPE (t);
     }
-  else if (TREE_CODE (type) != ERROR_MARK)
+  else
     {
-      if (spec.kind == ctsk_tagdef || spec.kind == ctsk_tagfirstref)
-       specs->tag_defined_p = true;
-      if (spec.kind == ctsk_typeof)
+      if (TREE_CODE (type) != ERROR_MARK && spec.kind == ctsk_typeof)
        {
          specs->typedef_p = true;
          if (spec.expr)
@@ -8745,7 +9345,7 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
              && C_IS_RESERVED_WORD (scspec));
   i = C_RID_CODE (scspec);
   if (specs->non_sc_seen_p)
-    warning (OPT_Wold_style_declaration, 
+    warning (OPT_Wold_style_declaration,
              "%qE is not at beginning of declaration", scspec);
   switch (i)
     {
@@ -8842,6 +9442,10 @@ finish_declspecs (struct c_declspecs *specs)
       gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p
                  && !specs->signed_p && !specs->unsigned_p
                  && !specs->complex_p);
+
+      /* Set a dummy type.  */
+      if (TREE_CODE (specs->type) == ERROR_MARK)
+        specs->type = integer_type_node;
       return specs;
     }
 
@@ -8867,7 +9471,7 @@ finish_declspecs (struct c_declspecs *specs)
       else if (specs->complex_p)
        {
          specs->typespec_word = cts_double;
-         pedwarn (input_location, OPT_pedantic, 
+         pedwarn (input_location, OPT_pedantic,
                   "ISO C does not support plain %<complex%> meaning "
                   "%<double complex%>");
        }
@@ -8912,7 +9516,20 @@ finish_declspecs (struct c_declspecs *specs)
        specs->type = char_type_node;
       if (specs->complex_p)
        {
-         pedwarn (input_location, OPT_pedantic, 
+         pedwarn (input_location, OPT_pedantic,
+                  "ISO C does not support complex integer types");
+         specs->type = build_complex_type (specs->type);
+       }
+      break;
+    case cts_int128:
+      gcc_assert (!specs->long_p && !specs->short_p && !specs->long_long_p);
+      gcc_assert (!(specs->signed_p && specs->unsigned_p));
+      specs->type = (specs->unsigned_p
+                    ? int128_unsigned_type_node
+                    : int128_integer_type_node);
+      if (specs->complex_p)
+       {
+         pedwarn (input_location, OPT_pedantic,
                   "ISO C does not support complex integer types");
          specs->type = build_complex_type (specs->type);
        }
@@ -8938,7 +9555,7 @@ finish_declspecs (struct c_declspecs *specs)
                       : integer_type_node);
       if (specs->complex_p)
        {
-         pedwarn (input_location, OPT_pedantic, 
+         pedwarn (input_location, OPT_pedantic,
                   "ISO C does not support complex integer types");
          specs->type = build_complex_type (specs->type);
        }
@@ -9082,7 +9699,7 @@ c_write_global_declarations_1 (tree globals)
   bool reconsider;
 
   /* Process the decls in the order they were written.  */
-  for (decl = globals; decl; decl = TREE_CHAIN (decl))
+  for (decl = globals; decl; decl = DECL_CHAIN (decl))
     {
       /* Check for used but undefined static functions using the C
         standard's definition of "used", and set TREE_NO_WARNING so
@@ -9103,12 +9720,12 @@ c_write_global_declarations_1 (tree globals)
   do
     {
       reconsider = false;
-      for (decl = globals; decl; decl = TREE_CHAIN (decl))
+      for (decl = globals; decl; decl = DECL_CHAIN (decl))
        reconsider |= wrapup_global_declaration_2 (decl);
     }
   while (reconsider);
 
-  for (decl = globals; decl; decl = TREE_CHAIN (decl))
+  for (decl = globals; decl; decl = DECL_CHAIN (decl))
     check_global_declaration_1 (decl);
 }
 
@@ -9120,10 +9737,49 @@ c_write_global_declarations_2 (tree globals)
 {
   tree decl;
 
-  for (decl = globals; decl ; decl = TREE_CHAIN (decl))
+  for (decl = globals; decl ; decl = DECL_CHAIN (decl))
     debug_hooks->global_decl (decl);
 }
 
+/* Callback to collect a source_ref from a DECL.  */
+
+static void
+collect_source_ref_cb (tree decl)
+{
+  if (!DECL_IS_BUILTIN (decl))
+    collect_source_ref (LOCATION_FILE (decl_sloc (decl, false)));
+}
+
+/* Collect all references relevant to SOURCE_FILE.  */
+
+static void
+collect_all_refs (const char *source_file)
+{
+  tree t;
+  unsigned i;
+
+  FOR_EACH_VEC_ELT (tree, all_translation_units, i, t)
+    collect_ada_nodes (BLOCK_VARS (DECL_INITIAL (t)), source_file);
+}
+
+/* Iterate over all global declarations and call CALLBACK.  */
+
+static void
+for_each_global_decl (void (*callback) (tree decl))
+{
+  tree t;
+  tree decls;
+  tree decl;
+  unsigned i;
+
+  FOR_EACH_VEC_ELT (tree, all_translation_units, i, t)
+    { 
+      decls = DECL_INITIAL (t);
+      for (decl = BLOCK_VARS (decls); decl; decl = TREE_CHAIN (decl))
+       callback (decl);
+    }
+}
+
 /* Preserve the external declarations scope across a garbage collect.  */
 static GTY(()) tree ext_block;
 
@@ -9131,21 +9787,37 @@ void
 c_write_global_declarations (void)
 {
   tree t;
+  unsigned i;
 
   /* We don't want to do this if generating a PCH.  */
   if (pch_file)
     return;
 
-  /* Don't waste time on further processing if -fsyntax-only or we've
-     encountered errors.  */
-  if (flag_syntax_only || errorcount || sorrycount)
-    return;
+  timevar_start (TV_PHASE_DEFERRED);
+
+  /* Do the Objective-C stuff.  This is where all the Objective-C
+     module stuff gets generated (symtab, class/protocol/selector
+     lists etc).  */
+  if (c_dialect_objc ())
+    objc_write_global_declarations ();
 
   /* Close the external scope.  */
   ext_block = pop_scope ();
   external_scope = 0;
   gcc_assert (!current_scope);
 
+  /* Handle -fdump-ada-spec[-slim]. */
+  if (dump_enabled_p (TDI_ada))
+    {
+      /* Build a table of files to generate specs for */
+      if (get_dump_file_info (TDI_ada)->flags & TDF_SLIM)
+       collect_source_ref (main_input_filename);
+      else
+       for_each_global_decl (collect_source_ref_cb);
+
+      dump_ada_specs (collect_all_refs, NULL);
+    }
+
   if (ext_block)
     {
       tree tmp = BLOCK_VARS (ext_block);
@@ -9160,26 +9832,52 @@ c_write_global_declarations (void)
 
   /* Process all file scopes in this compilation, and the external_scope,
      through wrapup_global_declarations and check_global_declarations.  */
-  for (t = all_translation_units; t; t = TREE_CHAIN (t))
+  FOR_EACH_VEC_ELT (tree, all_translation_units, i, t)
     c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t)));
   c_write_global_declarations_1 (BLOCK_VARS (ext_block));
 
+  timevar_stop (TV_PHASE_DEFERRED);
+  timevar_start (TV_PHASE_CGRAPH);
+
   /* We're done parsing; proceed to optimize and emit assembly.
      FIXME: shouldn't be the front end's responsibility to call this.  */
-  cgraph_optimize ();
+  cgraph_finalize_compilation_unit ();
+
+  timevar_stop (TV_PHASE_CGRAPH);
+  timevar_start (TV_PHASE_DBGINFO);
 
   /* After cgraph has had a chance to emit everything that's going to
      be emitted, output debug information for globals.  */
-  if (errorcount == 0 && sorrycount == 0)
+  if (!seen_error ())
     {
       timevar_push (TV_SYMOUT);
-      for (t = all_translation_units; t; t = TREE_CHAIN (t))
+      FOR_EACH_VEC_ELT (tree, all_translation_units, i, t)
        c_write_global_declarations_2 (BLOCK_VARS (DECL_INITIAL (t)));
       c_write_global_declarations_2 (BLOCK_VARS (ext_block));
       timevar_pop (TV_SYMOUT);
     }
 
   ext_block = NULL;
+  timevar_stop (TV_PHASE_DBGINFO);
+}
+
+/* Register reserved keyword WORD as qualifier for address space AS.  */
+
+void
+c_register_addr_space (const char *word, addr_space_t as)
+{
+  int rid = RID_FIRST_ADDR_SPACE + as;
+  tree id;
+
+  /* Address space qualifiers are only supported
+     in C with GNU extensions enabled.  */
+  if (c_dialect_objc () || flag_no_asm)
+    return;
+
+  id = get_identifier (word);
+  C_SET_RID_CODE (id, rid);
+  C_IS_RESERVED_WORD (id) = 1;
+  ridpointers [rid] = id;
 }
 
 #include "gt-c-decl.h"