OSDN Git Service

Make unsafe vector float optimizations dependent on -ffast-math.
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index 8ca5b08..e867ebb 100644 (file)
@@ -71,11 +71,14 @@ enum decl_context
 \f
 /* Nonzero if we have seen an invalid cross reference
    to a struct, union, or enum, but not yet printed the message.  */
-
 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;
+
 /* While defining an enum type, this is 1 plus the last enumerator
    constant value.  Note that will do not have to save this or `enum_overflow'
    around nested function definition since such a definition could only
@@ -105,13 +108,9 @@ static location_t current_function_prototype_locus;
 
 static GTY(()) struct stmt_tree_s c_stmt_tree;
 
-/* The current scope statement stack.  */
-
-static GTY(()) tree c_scope_stmt_stack;
-
 /* State saving variables.  */
-int c_in_iteration_stmt;
-int c_in_case_stmt;
+tree c_break_label;
+tree c_cont_label;
 
 /* Linked list of TRANSLATION_UNIT_DECLS for the translation units
    included in this invocation.  Note that the current translation
@@ -156,16 +155,23 @@ bool c_override_global_bindings_to_false;
    chained together by the ->prev field, which (as the name implies)
    runs in reverse order.  All the decls in a given namespace bound to
    a given identifier are chained by the ->shadowed field, which runs
-   from inner to outer scopes.  Finally, the ->contour field points
-   back to the relevant scope structure; this is mainly used to make
-   decls in the externals scope invisible (see below).
+   from inner to outer scopes.
 
    The ->decl field usually points to a DECL node, but there are two
    exceptions.  In the namespace of type tags, the bound entity is a
    RECORD_TYPE, UNION_TYPE, or ENUMERAL_TYPE node.  If an undeclared
    identifier is encountered, it is bound to error_mark_node to
    suppress further errors about that identifier in the current
-   function.  */
+   function.
+
+   The depth field is copied from the scope structure that holds this
+   decl.  It is used to preserve the proper ordering of the ->shadowed
+   field (see bind()) and also for a handful of special-case checks.
+   Finally, the invisible bit is true for a decl which should be
+   ignored for purposes of normal name lookup, and the nested bit is
+   true for a decl that's been bound a second time in an inner scope;
+   in all such cases, the binding in the outer scope will have its
+   invisible bit true.  */
 
 struct c_binding GTY((chain_next ("%h.prev")))
 {
@@ -173,8 +179,15 @@ struct c_binding GTY((chain_next ("%h.prev")))
   tree id;                     /* the identifier it's bound to */
   struct c_binding *prev;      /* the previous decl in this scope */
   struct c_binding *shadowed;  /* the innermost decl shadowed by this one */
-  struct c_scope *contour;     /* the scope in which this decl is bound */
+  unsigned int depth : 28;      /* depth of this scope */
+  BOOL_BITFIELD invisible : 1;  /* normal lookup should ignore this binding */
+  BOOL_BITFIELD nested : 1;     /* do not set DECL_CONTEXT when popping */
+  /* two free bits */
 };
+#define B_IN_SCOPE(b1, b2) ((b1)->depth == (b2)->depth)
+#define B_IN_CURRENT_SCOPE(b) ((b)->depth == current_scope->depth)
+#define B_IN_FILE_SCOPE(b) ((b)->depth == 1 /*file_scope->depth*/)
+#define B_IN_EXTERNAL_SCOPE(b) ((b)->depth == 0 /*external_scope->depth*/)
 
 #define I_SYMBOL_BINDING(node) \
   (((struct lang_identifier *)IDENTIFIER_NODE_CHECK(node))->symbol_binding)
@@ -364,7 +377,8 @@ static bool next_is_function_body;
 
 /* Functions called automatically at the beginning and end of execution.  */
 
-tree static_ctors, static_dtors;
+static GTY(()) tree static_ctors;
+static GTY(()) tree static_dtors;
 
 /* Forward declarations.  */
 static tree lookup_name_in_scope (tree, struct c_scope *);
@@ -404,7 +418,7 @@ c_print_identifier (FILE *file, tree node, int indent)
    which may be any of several kinds of DECL or TYPE or error_mark_node,
    in the scope SCOPE.  */
 static void
-bind (tree name, tree decl, struct c_scope *scope)
+bind (tree name, tree decl, struct c_scope *scope, bool invisible, bool nested)
 {
   struct c_binding *b, **here;
 
@@ -414,12 +428,14 @@ bind (tree name, tree decl, struct c_scope *scope)
       binding_freelist = b->prev;
     }
   else
-    b = ggc_alloc (sizeof (struct c_binding));
+    b = GGC_NEW (struct c_binding);
 
   b->shadowed = 0;
   b->decl = decl;
   b->id = name;
-  b->contour = scope;
+  b->depth = scope->depth;
+  b->invisible = invisible;
+  b->nested = nested;
 
   b->prev = scope->bindings;
   scope->bindings = b;
@@ -447,7 +463,7 @@ bind (tree name, tree decl, struct c_scope *scope)
   /* Locate the appropriate place in the chain of shadowed decls
      to insert this binding.  Normally, scope == current_scope and
      this does nothing.  */
-  while (*here && (*here)->contour->depth > scope->depth)
+  while (*here && (*here)->depth > scope->depth)
     here = &(*here)->shadowed;
 
   b->shadowed = *here;
@@ -463,10 +479,7 @@ free_binding_and_advance (struct c_binding *b)
 {
   struct c_binding *prev = b->prev;
 
-  b->id = 0;
-  b->decl = 0;
-  b->contour = 0;
-  b->shadowed = 0;
+  memset (b, 0, sizeof (struct c_binding));
   b->prev = binding_freelist;
   binding_freelist = b;
 
@@ -590,7 +603,7 @@ push_scope (void)
          scope_freelist = scope->outer;
        }
       else
-       scope = ggc_alloc_cleared (sizeof (struct c_scope));
+       scope = GGC_CNEW (struct c_scope);
 
       scope->keep          = keep_next_level_flag;
       scope->outer         = current_scope;
@@ -603,12 +616,22 @@ push_scope (void)
          scope->depth--;
          sorry ("GCC supports only %u nested scopes\n", scope->depth);
        }
-      
+
       current_scope        = scope;
       keep_next_level_flag = false;
     }
 }
 
+/* Set the TYPE_CONTEXT of all of TYPE's variants to CONTEXT.  */
+
+static void
+set_type_context (tree type, tree context)
+{
+  for (type = TYPE_MAIN_VARIANT (type); type;
+       type = TYPE_NEXT_VARIANT (type))
+    TYPE_CONTEXT (type) = context;
+}
+
 /* Exit a scope.  Restore the state of the identifier-decl mappings
    that were in effect when this scope was entered.  Return a BLOCK
    node containing all the DECLs in this scope that are of interest
@@ -688,7 +711,7 @@ pop_scope (void)
          /* Labels go in BLOCK_VARS.  */
          TREE_CHAIN (p) = BLOCK_VARS (block);
          BLOCK_VARS (block) = p;
+
 #ifdef ENABLE_CHECKING
          if (I_LABEL_BINDING (b->id) != b) abort ();
 #endif
@@ -698,7 +721,7 @@ pop_scope (void)
        case ENUMERAL_TYPE:
        case UNION_TYPE:
        case RECORD_TYPE:
-         TYPE_CONTEXT (p) = context;
+         set_type_context (p, context);
 
          /* Types may not have tag-names, in which case the type
             appears in the bindings list with b->id NULL.  */
@@ -723,9 +746,7 @@ pop_scope (void)
          goto common_symbol;
 
        case VAR_DECL:
-         /* Warnings for unused variables.  Keep this in sync with
-            stmt.c:warn_about_unused_variables, which we cannot use
-            since it expects a different data structure.  */
+         /* Warnings for unused variables.  */
          if (warn_unused_variable
              && !TREE_USED (p)
              && !DECL_IN_SYSTEM_HEADER (p)
@@ -743,14 +764,22 @@ pop_scope (void)
        common_symbol:
          /* All of these go in BLOCK_VARS, but only if this is the
             binding in the home scope.  */
-         if (!C_DECL_IN_EXTERNAL_SCOPE (p) || scope == external_scope)
+         if (!b->nested)
            {
              TREE_CHAIN (p) = BLOCK_VARS (block);
              BLOCK_VARS (block) = p;
            }
-         /* If this is the file scope, must set DECL_CONTEXT on these.  */
-         if (!C_DECL_IN_EXTERNAL_SCOPE (p) && scope == file_scope)
-           DECL_CONTEXT (p) = context;
+         /* 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)
+           {
+             DECL_CONTEXT (p) = context;
+             if (TREE_CODE (p) == TYPE_DECL)
+               set_type_context (TREE_TYPE (p), context);
+           }
 
          /* Fall through.  */
          /* Parameters go in DECL_ARGUMENTS, not BLOCK_VARS, and have
@@ -776,7 +805,7 @@ pop_scope (void)
        }
     }
 
-  
+
   /* Dispose of the block that we just made inside some higher level.  */
   if ((scope->function_body || scope == file_scope) && context)
     {
@@ -811,13 +840,17 @@ push_file_scope (void)
 {
   tree decl;
 
+  if (file_scope)
+    return;
+
   push_scope ();
   file_scope = current_scope;
 
   start_fname_decls ();
 
   for (decl = visible_builtins; decl; decl = TREE_CHAIN (decl))
-    bind (DECL_NAME (decl), decl, file_scope);
+    bind (DECL_NAME (decl), decl, file_scope,
+         /*invisible=*/false, /*nested=*/true);
 }
 
 void
@@ -833,17 +866,18 @@ pop_file_scope (void)
      still works without it.  */
   finish_fname_decls ();
 
-  /* Kludge: don't actually pop the file scope if generating a
-     precompiled header, so that macros and local symbols are still
-     visible to the PCH generator.  */
+  /* This is the point to write out a PCH if we're doing that.
+     In that case we do not want to do anything else.  */
   if (pch_file)
-    return;
+    {
+      c_common_write_pch ();
+      return;
+    }
 
-  /* And pop off the file scope.  */
+  /* Pop off the file scope and close this translation unit.  */
   pop_scope ();
   file_scope = 0;
-
-  cpp_undef_all (parse_in);
+  cgraph_finalize_compilation_unit ();
 }
 
 /* Insert BLOCK at the end of the list of subblocks of the current
@@ -870,7 +904,7 @@ pushtag (tree name, tree type)
   /* Record the identifier as the type's name if it has none.  */
   if (name && !TYPE_NAME (type))
     TYPE_NAME (type) = name;
-  bind (name, type, current_scope);
+  bind (name, type, current_scope, /*invisible=*/false, /*nested=*/false);
 
   /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the
      tagged type we just added to the current scope.  This fake
@@ -936,7 +970,7 @@ diagnose_arglist_conflict (tree newdecl, tree olddecl,
   tree t;
 
   if (TREE_CODE (olddecl) != FUNCTION_DECL
-      || !comptypes (TREE_TYPE (oldtype), TREE_TYPE (newtype), COMPARE_STRICT)
+      || !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)))
@@ -1008,7 +1042,7 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
 
       /* Type for passing arg must be consistent with that declared
         for the arg.  */
-      else if (! comptypes (oldargtype, newargtype, COMPARE_STRICT))
+      else if (! comptypes (oldargtype, newargtype))
        {
          error ("%Jprototype for '%D' declares arg %d with incompatible type",
                 newdecl, newdecl, i);
@@ -1090,7 +1124,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       return false;
     }
 
-  if (!comptypes (oldtype, newtype, COMPARE_STRICT))
+  if (!comptypes (oldtype, newtype))
     {
       if (TREE_CODE (olddecl) == FUNCTION_DECL
          && DECL_BUILT_IN (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl))
@@ -1099,7 +1133,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
             This is for the ffs and fprintf builtins.  */
          tree trytype = match_builtin_function_types (newtype, oldtype);
 
-         if (trytype && comptypes (newtype, trytype, COMPARE_STRICT))
+         if (trytype && comptypes (newtype, trytype))
            *oldtypep = oldtype = trytype;
          else
            {
@@ -1112,7 +1146,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
            }
        }
       else if (TREE_CODE (olddecl) == FUNCTION_DECL
-              && DECL_SOURCE_LINE (olddecl) == 0)
+              && DECL_IS_BUILTIN (olddecl))
        {
          /* A conflicting function declaration for a predeclared
             function that isn't actually built in.  Objective C uses
@@ -1138,7 +1172,10 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
        }
       else
        {
-         error ("%Jconflicting types for '%D'", newdecl, newdecl);
+         if (TYPE_QUALS (newtype) != TYPE_QUALS (oldtype))
+           error ("%J conflicting type qualifiers for '%D'", newdecl, newdecl);
+         else
+           error ("%Jconflicting types for '%D'", newdecl, newdecl);
          diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype);
          locate_old_decl (olddecl, error);
          return false;
@@ -1152,7 +1189,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
     {
       if (DECL_IN_SYSTEM_HEADER (newdecl) || DECL_IN_SYSTEM_HEADER (olddecl))
        return true;  /* Allow OLDDECL to continue in use.  */
-      
+
       error ("%Jredefinition of typedef '%D'", newdecl, newdecl);
       locate_old_decl (olddecl, error);
       return false;
@@ -1182,14 +1219,15 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
          /* Discard the old built-in function.  */
          return false;
        }
-      
+
       if (DECL_INITIAL (newdecl))
        {
          if (DECL_INITIAL (olddecl)
              && !(DECL_DECLARED_INLINE_P (olddecl)
                   && DECL_EXTERNAL (olddecl)
                   && !(DECL_DECLARED_INLINE_P (newdecl)
-                       && DECL_EXTERNAL (newdecl))))
+                       && DECL_EXTERNAL (newdecl)
+                       && same_translation_unit_p (olddecl, newdecl))))
            {
              error ("%Jredefinition of '%D'", newdecl, newdecl);
              locate_old_decl (olddecl, error);
@@ -1206,33 +1244,47 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
          locate_old_decl (olddecl, error);
          return false;
        }
-      /* Mismatched non-static and static is considered poor style.
-         We only diagnose static then non-static if -Wtraditional,
-        because it is the most convenient way to get some effects
-        (see e.g.  what unwind-dw2-fde-glibc.c does to the definition
-        of _Unwind_Find_FDE in unwind-dw2-fde.c).  Revisit?  */
+      /* A non-static declaration (even an "extern") followed by a
+        static declaration is undefined behavior per C99 6.2.2p3-5,7.
+        The same is true for a static forward declaration at block
+        scope followed by a non-static declaration/definition at file
+        scope.  Static followed by non-static at the same scope is
+        not undefined behavior, and is the most convenient way to get
+        some effects (see e.g.  what unwind-dw2-fde-glibc.c does to
+        the definition of _Unwind_Find_FDE in unwind-dw2-fde.c), but
+        we do diagnose it if -Wtraditional. */
       if (TREE_PUBLIC (olddecl) && !TREE_PUBLIC (newdecl))
        {
-         /* A static function declaration for a predeclared function
-            that isn't actually built in, silently overrides the
-            default.  Objective C uses these.  See also above.
-            FIXME: Make Objective C use normal builtins.  */
-         if (TREE_CODE (olddecl) == FUNCTION_DECL
-             && DECL_SOURCE_LINE (olddecl) == 0)
-           return false;
-         else
+         /* Two exceptions to the rule.  If olddecl is an extern
+            inline, or a predeclared function that isn't actually
+            built in, newdecl silently overrides olddecl.  The latter
+            occur only in Objective C; see also above.  (FIXME: Make
+            Objective C use normal builtins.)  */
+         if (!DECL_IS_BUILTIN (olddecl)
+             && !(DECL_EXTERNAL (olddecl)
+                  && DECL_DECLARED_INLINE_P (olddecl)))
            {
-             warning ("%Jstatic declaration of '%D' follows "
-                      "non-static declaration", newdecl, newdecl);
-             warned = true;
+             error ("%Jstatic declaration of '%D' follows "
+                    "non-static declaration", newdecl, newdecl);
+             locate_old_decl (olddecl, error);
            }
+         return false;
        }
-      else if (TREE_PUBLIC (newdecl) && !TREE_PUBLIC (olddecl)
-              && warn_traditional)
+      else if (TREE_PUBLIC (newdecl) && !TREE_PUBLIC (olddecl))
        {
-         warning ("%Jnon-static declaration of '%D' follows "
-                  "static declaration", newdecl, newdecl);
-         warned = true;
+         if (DECL_CONTEXT (olddecl))
+           {
+             error ("%Jnon-static declaration of '%D' follows "
+                    "static declaration", newdecl, newdecl);
+             locate_old_decl (olddecl, error);
+             return false;
+           }
+         else if (warn_traditional)
+           {
+             warning ("%Jnon-static declaration of '%D' follows "
+                      "static declaration", newdecl, newdecl);
+             warned = true;
+           }
        }
     }
   else if (TREE_CODE (newdecl) == VAR_DECL)
@@ -1260,13 +1312,34 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
          return false;
        }
 
-      /* Objects declared at file scope: if at least one is 'extern',
-        it's fine (6.2.2p4); otherwise the linkage must agree (6.2.2p7).  */
-      if (DECL_FILE_SCOPE_P (newdecl))
+      /* Objects declared at file scope: if the first declaration had
+        external linkage (even if it was an external reference) the
+        second must have external linkage as well, or the behavior is
+        undefined.  If the first declaration had internal linkage, then
+        the second must too, or else be an external reference (in which
+        case the composite declaration still has internal linkage).
+        As for function declarations, we warn about the static-then-
+        extern case only for -Wtraditional.  See generally 6.2.2p3-5,7.  */
+      if (DECL_FILE_SCOPE_P (newdecl)
+         && TREE_PUBLIC (newdecl) != TREE_PUBLIC (olddecl))
        {
-         if (!DECL_EXTERNAL (newdecl)
-             && !DECL_EXTERNAL (olddecl)
-             && TREE_PUBLIC (newdecl) != TREE_PUBLIC (olddecl))
+         if (DECL_EXTERNAL (newdecl))
+           {
+             if (!DECL_FILE_SCOPE_P (olddecl))
+               {
+                 error ("%Jextern declaration of %qD follows "
+                        "declaration with no linkage", newdecl, newdecl);
+                 locate_old_decl (olddecl, error);
+                 return false;
+               }
+             else if (warn_traditional)
+               {
+                 warning ("%Jnon-static declaration of '%D' follows "
+                          "static declaration", newdecl, newdecl);
+                 warned = true;
+               }
+           }
+         else
            {
              if (TREE_PUBLIC (newdecl))
                error ("%Jnon-static declaration of '%D' follows "
@@ -1281,12 +1354,10 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
        }
       /* Two objects with the same name declared at the same block
         scope must both be external references (6.7p3).  */
-      else if (DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl)
-              && (!DECL_EXTERNAL (newdecl) || !DECL_EXTERNAL (olddecl)))
+      else if (!DECL_FILE_SCOPE_P (newdecl))
        {
          if (DECL_EXTERNAL (newdecl))
-           error ("%Jextern declaration of '%D' follows "
-                  "declaration with no linkage", newdecl, newdecl);
+           abort ();
          else if (DECL_EXTERNAL (olddecl))
            error ("%Jdeclaration of '%D' with no linkage follows "
                   "extern declaration", newdecl, newdecl);
@@ -1300,9 +1371,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
     }
 
   /* warnings */
-  /* All decls must agree on a non-default visibility.  */
-  if (DECL_VISIBILITY (newdecl) != VISIBILITY_DEFAULT
-      && DECL_VISIBILITY (olddecl) != VISIBILITY_DEFAULT
+  /* All decls must agree on a visibility.  */
+  if (DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY_SPECIFIED (olddecl)
       && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
     {
       warning ("%Jredeclaration of '%D' with different visibility "
@@ -1330,8 +1400,11 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 
       /* Inline declaration after use or definition.
         ??? Should we still warn about this now we have unit-at-a-time
-        mode and can get it right?  */
-      if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl))
+        mode and can get it right?
+        Definitely don't complain if the decls are in different translation
+        units.  */
+      if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl)
+         && same_translation_unit_p (olddecl, newdecl))
        {
          if (TREE_USED (olddecl))
            {
@@ -1365,28 +1438,6 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
          locate_old_decl (olddecl, error);
          return false;
        }
-
-      /* These bits are only type qualifiers when applied to objects.  */
-      if (TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl))
-       {
-         if (TREE_THIS_VOLATILE (newdecl))
-           pedwarn ("%Jvolatile declaration of '%D' follows "
-                    "non-volatile declaration", newdecl, newdecl);
-         else
-           pedwarn ("%Jnon-volatile declaration of '%D' follows "
-                    "volatile declaration", newdecl, newdecl);
-         pedwarned = true;
-       }
-      if (TREE_READONLY (newdecl) != TREE_READONLY (olddecl))
-       {
-         if (TREE_READONLY (newdecl))
-           pedwarn ("%Jconst declaration of '%D' follows "
-                    "non-const declaration", newdecl, newdecl);
-         else
-           pedwarn ("%Jnon-const declaration of '%D' follows "
-                    "const declaration", newdecl, newdecl);
-         pedwarned = true;
-       }
     }
 
   /* Optional warning for completely redundant decls.  */
@@ -1396,6 +1447,11 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
         definition.  */
       && !(TREE_CODE (newdecl) == FUNCTION_DECL
           && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl))
+      /* Don't warn about redundant redeclarations of builtins. */
+      && !(TREE_CODE (newdecl) == FUNCTION_DECL
+          && !DECL_BUILT_IN (newdecl)
+          && DECL_BUILT_IN (olddecl)
+          && !C_DECL_DECLARED_BUILTIN (olddecl))
       /* Don't warn about an extern followed by a definition.  */
       && !(DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl))
       /* Don't warn about forward parameter decls.  */
@@ -1452,7 +1508,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
   /* Merge the data types specified in the two decls.  */
   TREE_TYPE (newdecl)
     = TREE_TYPE (olddecl)
-    = common_type (newtype, oldtype);
+    = composite_type (newtype, oldtype);
 
   /* Lay the type out, unless already done.  */
   if (oldtype != TREE_TYPE (newdecl))
@@ -1517,9 +1573,12 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
      Currently, it can only be defined in the prototype.  */
   COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
 
-  /* If either declaration has a nondefault visibility, use it.  */
-  if (DECL_VISIBILITY (olddecl) != VISIBILITY_DEFAULT)
-    DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
+  /* Use visibility of whichever declaration had it specified */
+  if (DECL_VISIBILITY_SPECIFIED (olddecl))
+    {
+      DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
+      DECL_VISIBILITY_SPECIFIED (newdecl) = 1;
+    }
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
@@ -1635,18 +1694,17 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
        }
     }
 
-  /* This bit must not get wiped out.  */
-  C_DECL_IN_EXTERNAL_SCOPE (newdecl) |= C_DECL_IN_EXTERNAL_SCOPE (olddecl);
-
   /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
-     But preserve OLDDECL's DECL_UID.  */
+     But preserve OLDDECL's DECL_UID and DECL_CONTEXT.  */
   {
     unsigned olddecl_uid = DECL_UID (olddecl);
+    tree olddecl_context = DECL_CONTEXT (olddecl);
 
     memcpy ((char *) olddecl + sizeof (struct tree_common),
            (char *) newdecl + sizeof (struct tree_common),
            sizeof (struct tree_decl) - sizeof (struct tree_common));
     DECL_UID (olddecl) = olddecl_uid;
+    DECL_CONTEXT (olddecl) = olddecl_context;
   }
 
   /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
@@ -1656,7 +1714,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
       && (TREE_CODE (olddecl) == FUNCTION_DECL
          || (TREE_CODE (olddecl) == VAR_DECL
              && TREE_STATIC (olddecl))))
-    make_decl_rtl (olddecl, NULL);
+    make_decl_rtl (olddecl);
 }
 
 /* Handle when a new declaration NEWDECL has the same name as an old
@@ -1677,48 +1735,51 @@ duplicate_decls (tree newdecl, tree olddecl)
   merge_decls (newdecl, olddecl, newtype, oldtype);
   return true;
 }
-  
+
 \f
-/* Check whether decl-node NEW shadows an existing declaration.  */
+/* Check whether decl-node NEW_DECL shadows an existing declaration.  */
 static void
-warn_if_shadowing (tree new)
+warn_if_shadowing (tree new_decl)
 {
   struct c_binding *b;
 
   /* Shadow warnings wanted?  */
   if (!warn_shadow
       /* No shadow warnings for internally generated vars.  */
-      || DECL_SOURCE_LINE (new) == 0
+      || DECL_IS_BUILTIN (new_decl)
       /* No shadow warnings for vars made for inlining.  */
-      || DECL_FROM_INLINE (new)
+      || DECL_FROM_INLINE (new_decl)
       /* Don't warn about the parm names in function declarator
         within a function declarator.  It would be nice to avoid
         warning in any function declarator in a declaration, as
         opposed to a definition, but there is no way to tell
         it's not a definition at this point.  */
-      || (TREE_CODE (new) == PARM_DECL && current_scope->outer->parm_flag))
+      || (TREE_CODE (new_decl) == PARM_DECL && current_scope->outer->parm_flag))
     return;
 
-  /* Is anything being shadowed?  Do not be confused by a second binding
-     to the same decl in the externals scope.  */
-  for (b = I_SYMBOL_BINDING (DECL_NAME (new)); b; b = b->shadowed)
-    if (b->decl && b->decl != new && b->contour != external_scope)
+  /* Is anything being shadowed?  Invisible decls do not count.  */
+  for (b = I_SYMBOL_BINDING (DECL_NAME (new_decl)); b; b = b->shadowed)
+    if (b->decl && b->decl != new_decl && !b->invisible)
       {
-       tree old = b->decl;
+       tree old_decl = b->decl;
 
-       if (TREE_CODE (old) == PARM_DECL)
-         warning ("%Jdeclaration of '%D' shadows a parameter", new, new);
-       else if (DECL_FILE_SCOPE_P (old))
+       if (TREE_CODE (old_decl) == PARM_DECL)
+         warning ("%Jdeclaration of '%D' shadows a parameter",
+                  new_decl, new_decl);
+       else if (DECL_FILE_SCOPE_P (old_decl))
          warning ("%Jdeclaration of '%D' shadows a global declaration",
-                  new, new);
-       else if (TREE_CODE (old) == FUNCTION_DECL && DECL_BUILT_IN (old))
+                  new_decl, new_decl);
+       else if (TREE_CODE (old_decl) == FUNCTION_DECL
+                && DECL_BUILT_IN (old_decl))
          warning ("%Jdeclaration of '%D' shadows a built-in function",
-                  new, new);
+                  new_decl, new_decl);
        else
-         warning ("%Jdeclaration of '%D' shadows a previous local", new, new);
+         warning ("%Jdeclaration of '%D' shadows a previous local",
+                  new_decl, new_decl);
 
-       if (TREE_CODE (old) != FUNCTION_DECL || !DECL_BUILT_IN (old))
-         warning ("%Jshadowed declaration is here", old);
+       if (TREE_CODE (old_decl) != FUNCTION_DECL
+           || ! DECL_BUILT_IN (old_decl))
+         warning ("%Jshadowed declaration is here", old_decl);
 
        break;
       }
@@ -1772,7 +1833,7 @@ warn_if_shadowing (tree new)
 static void
 clone_underlying_type (tree x)
 {
-  if (DECL_SOURCE_LINE (x) == 0)
+  if (DECL_IS_BUILTIN (x))
     {
       if (TYPE_NAME (TREE_TYPE (x)) == 0)
        TYPE_NAME (TREE_TYPE (x)) = x;
@@ -1803,10 +1864,11 @@ pushdecl (tree x)
   tree name = DECL_NAME (x);
   struct c_scope *scope = current_scope;
   struct c_binding *b;
+  bool nested = false;
 
   /* Functions need the lang_decl data.  */
   if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x))
-    DECL_LANG_SPECIFIC (x) = ggc_alloc_cleared (sizeof (struct lang_decl));
+    DECL_LANG_SPECIFIC (x) = GGC_CNEW (struct lang_decl);
 
   /* Must set DECL_CONTEXT for everything not at file scope or
      DECL_FILE_SCOPE_P won't work.  Local externs don't count
@@ -1819,7 +1881,7 @@ pushdecl (tree x)
   /* Anonymous decls are just inserted in the scope.  */
   if (!name)
     {
-      bind (name, x, scope);
+      bind (name, x, scope, /*invisible=*/false, /*nested=*/false);
       return x;
     }
 
@@ -1831,7 +1893,7 @@ pushdecl (tree x)
      diagnostics).  In particular, we should not consider possible
      duplicates in the external scope, or shadowing.  */
   b = I_SYMBOL_BINDING (name);
-  if (b && b->contour == scope)
+  if (b && B_IN_SCOPE (b, scope))
     {
       if (duplicate_decls (x, b->decl))
        return b->decl;
@@ -1856,10 +1918,9 @@ pushdecl (tree x)
       if (warn_nested_externs
          && scope != file_scope
          && !DECL_IN_SYSTEM_HEADER (x))
-       warning ("nested extern declaration of `%s'",
-                IDENTIFIER_POINTER (name));
+       warning ("nested extern declaration of '%D'", x);
 
-      while (b && b->contour != external_scope)
+      while (b && !B_IN_EXTERNAL_SCOPE (b))
        b = b->shadowed;
 
       /* The point of the same_translation_unit_p check here is,
@@ -1868,17 +1929,40 @@ pushdecl (tree x)
         they are in different translation units.  In any case,
         the static does not go in the externals scope.  */
       if (b
-         && (DECL_EXTERNAL (x) || TREE_PUBLIC (x)
-             || same_translation_unit_p (x, b->decl))
+         && (TREE_PUBLIC (x) || same_translation_unit_p (x, b->decl))
          && duplicate_decls (x, b->decl))
        {
-         bind (name, b->decl, scope);
+         bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true);
          return b->decl;
        }
-      else if (DECL_EXTERNAL (x) || TREE_PUBLIC (x))
+      else if (TREE_PUBLIC (x))
        {
-         C_DECL_IN_EXTERNAL_SCOPE (x) = 1;
-         bind (name, x, external_scope);
+         bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false);
+         nested = true;
+       }
+    }
+  /* Similarly, a declaration of a function with static linkage at
+     block scope must be checked against any existing declaration
+     of that function at file scope.  */
+  else if (TREE_CODE (x) == FUNCTION_DECL && scope != file_scope
+          && !TREE_PUBLIC (x) && !DECL_INITIAL (x))
+    {
+      if (warn_nested_externs && !DECL_IN_SYSTEM_HEADER (x))
+       warning ("nested static declaration of '%D'", x);
+
+      while (b && !B_IN_FILE_SCOPE (b))
+       b = b->shadowed;
+
+      if (b && same_translation_unit_p (x, b->decl)
+         && duplicate_decls (x, b->decl))
+       {
+         bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true);
+         return b->decl;
+       }
+      else
+       {
+         bind (name, x, file_scope, /*invisible=*/true, /*nested=*/false);
+         nested = true;
        }
     }
 
@@ -1888,7 +1972,7 @@ pushdecl (tree x)
   if (TREE_CODE (x) == TYPE_DECL)
     clone_underlying_type (x);
 
-  bind (name, x, scope);
+  bind (name, x, scope, /*invisible=*/false, nested);
 
   /* If x's type is incomplete because it's based on a
      structure or union which has not yet been fully declared,
@@ -1928,6 +2012,7 @@ tree
 pushdecl_top_level (tree x)
 {
   tree name;
+  bool nested = false;
 
   if (TREE_CODE (x) != VAR_DECL)
     abort ();
@@ -1937,13 +2022,13 @@ pushdecl_top_level (tree x)
   if (I_SYMBOL_BINDING (name))
     abort ();
 
-  if (DECL_EXTERNAL (x) || TREE_PUBLIC (x))
+  if (TREE_PUBLIC (x))
     {
-      C_DECL_IN_EXTERNAL_SCOPE (x) = 1;
-      bind (name, x, external_scope);
+      bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false);
+      nested = true;
     }
   if (file_scope)
-    bind (name, x, file_scope);
+    bind (name, x, file_scope, /*invisible=*/false, nested);
 
   return x;
 }
@@ -1980,9 +2065,10 @@ implicitly_declare (tree functionid)
         in the external scope because they're pushed before the file
         scope gets created.  Catch this here and rebind them into the
         file scope.  */
-      if (!DECL_BUILT_IN (decl) && DECL_SOURCE_LINE (decl) == 0)
+      if (!DECL_BUILT_IN (decl) && DECL_IS_BUILTIN (decl))
        {
-         bind (functionid, decl, file_scope);
+         bind (functionid, decl, file_scope,
+               /*invisible=*/false, /*nested=*/true);
          return decl;
        }
       else
@@ -1996,7 +2082,25 @@ implicitly_declare (tree functionid)
              implicit_decl_warning (functionid, decl);
              C_DECL_IMPLICIT (decl) = 1;
            }
-         bind (functionid, decl, current_scope);
+         if (DECL_BUILT_IN (decl))
+           {
+             if (!comptypes (default_function_type, TREE_TYPE (decl)))
+               {
+                 warning ("incompatible implicit declaration of built-in"
+                          " function %qD", decl);
+               }
+           }
+         else
+           {
+             if (!comptypes (default_function_type, TREE_TYPE (decl)))
+               {
+                 error ("incompatible implicit declaration of function %qD",
+                        decl);
+                 locate_old_decl (decl, error);
+               }
+           }
+         bind (functionid, decl, current_scope,
+               /*invisible=*/false, /*nested=*/true);
          return decl;
        }
     }
@@ -2013,7 +2117,7 @@ implicitly_declare (tree functionid)
   decl = pushdecl (decl);
 
   /* No need to call objc_check_decl here - it's a function type.  */
-  rest_of_decl_compilation (decl, NULL, 0, 0);
+  rest_of_decl_compilation (decl, 0, 0);
 
   /* Write a record describing this implicit function declaration
      to the prototypes file (if requested).  */
@@ -2056,7 +2160,7 @@ undeclared_variable (tree id)
          will be nonnull but current_function_scope will be null.  */
       scope = current_function_scope ? current_function_scope : current_scope;
     }
-  bind (id, error_mark_node, scope);
+  bind (id, error_mark_node, scope, /*invisible=*/false, /*nested=*/false);
 }
 \f
 /* Subroutine of lookup_label, declare_label, define_label: construct a
@@ -2110,7 +2214,8 @@ lookup_label (tree name)
   label = make_label (name, input_location);
 
   /* Ordinary labels go in the current function scope.  */
-  bind (name, label, current_function_scope);
+  bind (name, label, current_function_scope,
+       /*invisible=*/false, /*nested=*/false);
   return label;
 }
 
@@ -2126,7 +2231,7 @@ declare_label (tree name)
 
   /* Check to make sure that the label hasn't already been declared
      at this scope */
-  if (b && b->contour == current_scope)
+  if (b && B_IN_CURRENT_SCOPE (b))
     {
       error ("duplicate label declaration `%s'", IDENTIFIER_POINTER (name));
       locate_old_decl (b->decl, error);
@@ -2139,7 +2244,8 @@ declare_label (tree name)
   C_DECLARED_LABEL_FLAG (label) = 1;
 
   /* Declared labels go in the current scope.  */
-  bind (name, label, current_scope);
+  bind (name, label, current_scope,
+       /*invisible=*/false, /*nested=*/false);
   return label;
 }
 
@@ -2179,7 +2285,8 @@ define_label (location_t location, tree name)
       label = make_label (name, location);
 
       /* Ordinary labels go in the current function scope.  */
-      bind (name, label, current_function_scope);
+      bind (name, label, current_function_scope,
+           /*invisible=*/false, /*nested=*/false);
     }
 
   if (warn_traditional && !in_system_header && lookup_name (name))
@@ -2215,9 +2322,9 @@ lookup_tag (enum tree_code code, tree name, int thislevel_only)
       /* For our purposes, a tag in the external scope is the same as
         a tag in the file scope.  (Primarily relevant to Objective-C
         and its builtin structure tags, which get pushed before the
-        file scope is created.)  */ 
-      if (b->contour == current_scope
-         || (current_scope == file_scope && b->contour == external_scope))
+        file scope is created.)  */
+      if (B_IN_CURRENT_SCOPE (b)
+         || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b)))
        thislevel = 1;
     }
 
@@ -2265,7 +2372,7 @@ tree
 lookup_name (tree name)
 {
   struct c_binding *b = I_SYMBOL_BINDING (name);
-  if (b && (b->contour != external_scope || TREE_CODE (b->decl) == TYPE_DECL))
+  if (b && !b->invisible)
     return b->decl;
   return 0;
 }
@@ -2278,7 +2385,7 @@ lookup_name_in_scope (tree name, struct c_scope *scope)
   struct c_binding *b;
 
   for (b = I_SYMBOL_BINDING (name); b; b = b->shadowed)
-    if (b->contour == scope)
+    if (B_IN_SCOPE (b, scope))
       return b->decl;
   return 0;
 }
@@ -2307,8 +2414,12 @@ c_init_decl_processing (void)
   /* Declarations from c_common_nodes_and_builtins must not be associated
      with this input file, lest we get differences between using and not
      using preprocessed headers.  */
-  input_location.file = "<internal>";
+#ifdef USE_MAPPED_LOCATION
+  input_location = BUILTINS_LOCATION;
+#else
+  input_location.file = "<built-in>";
   input_location.line = 0;
+#endif
 
   build_common_tree_nodes (flag_signed_char);
 
@@ -2362,6 +2473,7 @@ c_make_fname_decl (tree id, int type_dep)
   DECL_ARTIFICIAL (decl) = 1;
 
   init = build_string (length + 1, name);
+  free ((char *) name);
   TREE_TYPE (init) = type;
   DECL_INITIAL (decl) = init;
 
@@ -2370,7 +2482,8 @@ c_make_fname_decl (tree id, int type_dep)
   if (current_function_decl)
     {
       DECL_CONTEXT (decl) = current_function_decl;
-      bind (id, decl, current_function_scope);
+      bind (id, decl, current_function_scope,
+           /*invisible=*/false, /*nested=*/false);
     }
 
   finish_decl (decl, init, NULL_TREE);
@@ -2389,26 +2502,24 @@ c_make_fname_decl (tree id, int type_dep)
 
 tree
 builtin_function (const char *name, tree type, int function_code,
-                 enum built_in_class class, const char *library_name,
+                 enum built_in_class cl, const char *library_name,
                  tree attrs)
 {
   tree id = get_identifier (name);
   tree decl = build_decl (FUNCTION_DECL, id, type);
   TREE_PUBLIC (decl) = 1;
   DECL_EXTERNAL (decl) = 1;
-  DECL_LANG_SPECIFIC (decl) = ggc_alloc_cleared (sizeof (struct lang_decl));
-  DECL_BUILT_IN_CLASS (decl) = class;
+  DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl);
+  DECL_BUILT_IN_CLASS (decl) = cl;
   DECL_FUNCTION_CODE (decl) = function_code;
   if (library_name)
     SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
-  make_decl_rtl (decl, NULL);
 
   /* Should never be called on a symbol with a preexisting meaning.  */
   if (I_SYMBOL_BINDING (id))
     abort ();
 
-  C_DECL_IN_EXTERNAL_SCOPE (decl) = 1;
-  bind (id, decl, external_scope);
+  bind (id, decl, external_scope, /*invisible=*/true, /*nested=*/false);
 
   /* Builtins in the implementation namespace are made visible without
      needing to be explicitly declared.  See push_file_scope.  */
@@ -2441,12 +2552,10 @@ shadow_tag (tree declspecs)
   shadow_tag_warned (declspecs, 0);
 }
 
+/* WARNED is 1 if we have done a pedwarn, 2 if we have done a warning,
+   but no pedwarn.  */
 void
 shadow_tag_warned (tree declspecs, int warned)
-
-
-     /* 1 => we have done a pedwarn.  2 => we have done a warning, but
-       no pedwarn.  */
 {
   int found_tag = 0;
   tree link;
@@ -2528,7 +2637,7 @@ tree
 build_array_declarator (tree expr, tree quals, int static_p, int vla_unspec_p)
 {
   tree decl;
-  decl = build_nt (ARRAY_REF, NULL_TREE, expr);
+  decl = build_nt (ARRAY_REF, NULL_TREE, expr, NULL_TREE, NULL_TREE);
   TREE_TYPE (decl) = quals;
   TREE_STATIC (decl) = (static_p ? 1 : 0);
   if (pedantic && !flag_isoc99)
@@ -2562,33 +2671,33 @@ set_array_declarator_type (tree decl, tree type, int abstract_p)
 /* Decode a "typename", such as "int **", returning a ..._TYPE node.  */
 
 tree
-groktypename (tree typename)
+groktypename (tree type_name)
 {
   tree specs, attrs;
 
-  if (TREE_CODE (typename) != TREE_LIST)
-    return typename;
+  if (TREE_CODE (type_name) != TREE_LIST)
+    return type_name;
 
-  split_specs_attrs (TREE_PURPOSE (typename), &specs, &attrs);
+  split_specs_attrs (TREE_PURPOSE (type_name), &specs, &attrs);
 
-  typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0,
+  type_name = grokdeclarator (TREE_VALUE (type_name), specs, TYPENAME, 0,
                             NULL);
 
   /* Apply attributes.  */
-  decl_attributes (&typename, attrs, 0);
+  decl_attributes (&type_name, attrs, 0);
 
-  return typename;
+  return type_name;
 }
 
 /* Return a PARM_DECL node for a given pair of specs and declarator.  */
 
 tree
-groktypename_in_parm_context (tree typename)
+groktypename_in_parm_context (tree type_name)
 {
-  if (TREE_CODE (typename) != TREE_LIST)
-    return typename;
-  return grokdeclarator (TREE_VALUE (typename),
-                        TREE_PURPOSE (typename),
+  if (TREE_CODE (type_name) != TREE_LIST)
+    return type_name;
+  return grokdeclarator (TREE_VALUE (type_name),
+                        TREE_PURPOSE (type_name),
                         PARM, 0, NULL);
 }
 
@@ -2682,7 +2791,6 @@ start_decl (tree declarator, tree declspecs, int initialized, tree attributes)
 
   if (initialized)
     {
-      DECL_EXTERNAL (decl) = 0;
       if (current_scope == file_scope)
        TREE_STATIC (decl) = 1;
 
@@ -2732,7 +2840,7 @@ start_decl (tree declarator, tree declspecs, int initialized, tree attributes)
          for (; args; args = TREE_CHAIN (args))
            {
              tree type = TREE_TYPE (args);
-             if (INTEGRAL_TYPE_P (type)
+             if (type && INTEGRAL_TYPE_P (type)
                  && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
                DECL_ARG_TYPE (args) = integer_type_node;
            }
@@ -2749,6 +2857,9 @@ start_decl (tree declarator, tree declspecs, int initialized, tree attributes)
      TEM may equal DECL or it may be a previous decl of the same name.  */
   tem = pushdecl (decl);
 
+  if (initialized)
+    DECL_EXTERNAL (tem) = 0;
+
   return tem;
 }
 
@@ -2782,8 +2893,8 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
     store_init_value (decl, init);
 
   if (c_dialect_objc () && (TREE_CODE (decl) == VAR_DECL
-                   || TREE_CODE (decl) == FUNCTION_DECL
-                   || TREE_CODE (decl) == FIELD_DECL))
+                           || TREE_CODE (decl) == FUNCTION_DECL
+                           || TREE_CODE (decl) == FIELD_DECL))
     objc_check_decl (decl);
 
   /* Deduce size of array from initialization, if not already known.  */
@@ -2824,7 +2935,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
         in the array, because we start counting at zero.  Therefore,
         warn only if the value is less than zero.  */
       else if (pedantic && TYPE_DOMAIN (type) != 0
-             && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
+              && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
        error ("%Jzero or negative size array '%D'", decl, decl);
 
       layout_decl (decl, 0);
@@ -2840,22 +2951,20 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
          /* Don't give an error if we already gave one earlier.  */
          && TREE_TYPE (decl) != error_mark_node
          && (TREE_STATIC (decl)
-             ?
-               /* A static variable with an incomplete type
-                  is an error if it is initialized.
-                  Also if it is not file scope.
-                  Otherwise, let it through, but if it is not `extern'
-                  then it may cause an error message later.  */
-               (DECL_INITIAL (decl) != 0
+             /* A static variable with an incomplete type
+                is an error if it is initialized.
+                Also if it is not file scope.
+                Otherwise, let it through, but if it is not `extern'
+                then it may cause an error message later.  */
+             ? (DECL_INITIAL (decl) != 0
                 || !DECL_FILE_SCOPE_P (decl))
-             :
-               /* An automatic variable with an incomplete type
-                  is an error.  */
-               !DECL_EXTERNAL (decl)))
-       {
-         error ("%Jstorage size of '%D' isn't known", decl, decl);
-         TREE_TYPE (decl) = error_mark_node;
-       }
+             /* An automatic variable with an incomplete type
+                is an error.  */
+             : !DECL_EXTERNAL (decl)))
+        {
+          error ("%Jstorage size of '%D' isn't known", decl, decl);
+          TREE_TYPE (decl) = error_mark_node;
+        }
 
       if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
          && DECL_SIZE (decl) != 0)
@@ -2875,37 +2984,28 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
      was a normal built-in.  */
   if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
     {
-      /* ASMSPEC is given, and not the name of a register.  Mark the
-      name with a star so assemble_name won't munge it.  */
-      char *starred = alloca (strlen (asmspec) + 2);
-      starred[0] = '*';
-      strcpy (starred + 1, asmspec);
-
       if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
        {
          tree builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
-         SET_DECL_RTL (builtin, NULL_RTX);
-         SET_DECL_ASSEMBLER_NAME (builtin, get_identifier (starred));
-#ifdef TARGET_MEM_FUNCTIONS
-         if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMCPY)
-           init_block_move_fn (starred);
-         else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMSET)
-           init_block_clear_fn (starred);
-#else
-         if (DECL_FUNCTION_CODE (decl) == BUILT_IN_BCOPY)
-           init_block_move_fn (starred);
-         else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_BZERO)
-           init_block_clear_fn (starred);
-#endif
-       }
-      SET_DECL_RTL (decl, NULL_RTX);
-      change_decl_assembler_name (decl, get_identifier (starred));
+         set_user_assembler_name (builtin, asmspec);
+          if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMCPY)
+            init_block_move_fn (asmspec);
+          else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMSET)
+            init_block_clear_fn (asmspec);
+        }
+      set_user_assembler_name (decl, asmspec);
     }
 
   /* If #pragma weak was used, mark the decl weak now.  */
   if (current_scope == file_scope)
     maybe_apply_pragma_weak (decl);
 
+  /* If this is a variable definition, determine its ELF visibility.  */
+  if (TREE_CODE (decl) == VAR_DECL 
+      && TREE_STATIC (decl) 
+      && !DECL_EXTERNAL (decl))
+    c_determine_visibility (decl);
+
   /* Output the assembler code and/or RTL code for variables and functions,
      unless the type is an undefined structure or union.
      If not, it will get done when the type is completed.  */
@@ -2916,6 +3016,25 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
       if (c_dialect_objc ())
        objc_check_decl (decl);
 
+      if (asmspec) 
+       {
+         /* If this is not a static variable, issue a warning.
+            It doesn't make any sense to give an ASMSPEC for an
+            ordinary, non-register local variable.  Historically,
+            GCC has accepted -- but ignored -- the ASMSPEC in
+            this case.  */
+         if (! DECL_FILE_SCOPE_P (decl)
+             && TREE_CODE (decl) == VAR_DECL
+             && !C_DECL_REGISTER (decl)
+             && !TREE_STATIC (decl))
+           warning ("%Jignoring asm-specifier for non-static local "
+                    "variable '%D'", decl, decl);
+         else if (C_DECL_REGISTER (decl))
+           change_decl_assembler_name (decl, get_identifier (asmspec));
+         else
+           set_user_assembler_name (decl, asmspec);
+       }
+      
       if (DECL_FILE_SCOPE_P (decl))
        {
          if (DECL_INITIAL (decl) == NULL_TREE
@@ -2924,44 +3043,44 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
               when a tentative file-scope definition is seen.
               But at end of compilation, do output code for them.  */
            DECL_DEFER_OUTPUT (decl) = 1;
-         rest_of_decl_compilation (decl, asmspec, true, 0);
+         rest_of_decl_compilation (decl, true, 0);
        }
       else
        {
-         /* This is a local variable.  If there is an ASMSPEC, the
-            user has requested that we handle it specially.  */
-         if (asmspec)
+         /* In conjunction with an ASMSPEC, the `register'
+            keyword indicates that we should place the variable
+            in a particular register.  */
+         if (asmspec && C_DECL_REGISTER (decl))
            {
-             /* In conjunction with an ASMSPEC, the `register'
-                keyword indicates that we should place the variable
-                in a particular register.  */
-             if (C_DECL_REGISTER (decl))
-               {
-                 DECL_HARD_REGISTER (decl) = 1;
-                 /* This cannot be done for a structure with volatile
-                    fields, on which DECL_REGISTER will have been
-                    reset.  */
-                 if (!DECL_REGISTER (decl))
-                   error ("cannot put object with volatile field into register");
-               }
-
-             /* If this is not a static variable, issue a warning.
-                It doesn't make any sense to give an ASMSPEC for an
-                ordinary, non-register local variable.  Historically,
-                GCC has accepted -- but ignored -- the ASMSPEC in
-                this case.  */
-             if (TREE_CODE (decl) == VAR_DECL
-                 && !C_DECL_REGISTER (decl)
-                 && !TREE_STATIC (decl))
-               warning ("%Jignoring asm-specifier for non-static local "
-                         "variable '%D'", decl, decl);
-             else
-               change_decl_assembler_name (decl, get_identifier (asmspec));
+             DECL_HARD_REGISTER (decl) = 1;
+             /* This cannot be done for a structure with volatile
+                fields, on which DECL_REGISTER will have been
+                reset.  */
+             if (!DECL_REGISTER (decl))
+               error ("cannot put object with volatile field into register");
            }
 
          if (TREE_CODE (decl) != FUNCTION_DECL)
-           add_decl_stmt (decl);
+           {
+             /* If we're building a variable sized type, and we might be
+                reachable other than via the top of the current binding
+                level, then create a new BIND_EXPR so that we deallocate
+                the object at the right time.  */
+             /* Note that DECL_SIZE can be null due to errors.  */
+             if (DECL_SIZE (decl)
+                 && !TREE_CONSTANT (DECL_SIZE (decl))
+                 && STATEMENT_LIST_HAS_LABEL (cur_stmt_list))
+               {
+                 tree bind;
+                 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+                 TREE_SIDE_EFFECTS (bind) = 1;
+                 add_stmt (bind);
+                 BIND_EXPR_BODY (bind) = push_stmt_list ();
+               }
+             add_stmt (build_stmt (DECL_EXPR, decl));
+           }
        }
+  
 
       if (!DECL_FILE_SCOPE_P (decl))
        {
@@ -2981,15 +3100,15 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
 
   /* If this was marked 'used', be sure it will be output.  */
   if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
-    mark_referenced (DECL_ASSEMBLER_NAME (decl));
+    mark_decl_referenced (decl);
 
   if (TREE_CODE (decl) == TYPE_DECL)
     {
       if (!DECL_FILE_SCOPE_P (decl)
-         && variably_modified_type_p (TREE_TYPE (decl)))
-       add_decl_stmt (decl);
+         && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
+       add_stmt (build_stmt (DECL_EXPR, decl));
 
-      rest_of_decl_compilation (decl, NULL, DECL_FILE_SCOPE_P (decl), 0);
+      rest_of_decl_compilation (decl, DECL_FILE_SCOPE_P (decl), 0);
     }
 
   /* At the end of a declaration, throw away any variable type sizes
@@ -3004,8 +3123,6 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
       tree attr = lookup_attribute ("cleanup", DECL_ATTRIBUTES (decl));
       if (attr)
        {
-         static bool eh_initialized_p;
-
          tree cleanup_id = TREE_VALUE (TREE_VALUE (attr));
          tree cleanup_decl = lookup_name (cleanup_id);
          tree cleanup;
@@ -3017,11 +3134,12 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
 
          /* 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.  */
-         if (flag_exceptions && !eh_initialized_p)
+         if (flag_exceptions && !c_eh_initialized_p)
            {
-             eh_initialized_p = true;
+             c_eh_initialized_p = true;
              eh_personality_libfunc
                = init_one_libfunc (USING_SJLJ_EXCEPTIONS
                                    ? "__gcc_personality_sj0"
@@ -3029,7 +3147,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
              using_eh_for_cleanups ();
            }
 
-         add_stmt (build_stmt (CLEANUP_STMT, decl, cleanup));
+         push_cleanup (decl, cleanup, false);
        }
     }
 }
@@ -3042,11 +3160,6 @@ push_parm_decl (tree parm)
 {
   tree decl;
 
-  /* Don't attempt to expand sizes while parsing this decl.
-     (We can get here with i_s_e 1 somehow from Objective-C.)  */
-  int save_immediate_size_expand = immediate_size_expand;
-  immediate_size_expand = 0;
-
   decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)),
                         TREE_PURPOSE (TREE_PURPOSE (parm)),
                         PARM, 0, NULL);
@@ -3055,8 +3168,6 @@ push_parm_decl (tree parm)
   decl = pushdecl (decl);
 
   finish_decl (decl, NULL_TREE, NULL_TREE);
-
-  immediate_size_expand = save_immediate_size_expand;
 }
 
 /* Mark all the parameter declarations to date as forward decls.
@@ -3090,7 +3201,7 @@ build_compound_literal (tree type, tree init)
 {
   /* We do not use start_decl here because we have a type, not a declarator;
      and do not use finish_decl because the decl should be stored inside
-     the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_STMT.  */
+     the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_EXPR.  */
   tree decl = build_decl (VAR_DECL, NULL_TREE, type);
   tree complit;
   tree stmt;
@@ -3114,7 +3225,7 @@ build_compound_literal (tree type, tree init)
   if (type == error_mark_node || !COMPLETE_TYPE_P (type))
     return error_mark_node;
 
-  stmt = build_stmt (DECL_STMT, decl);
+  stmt = build_stmt (DECL_EXPR, decl);
   complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
   TREE_SIDE_EFFECTS (complit) = 1;
 
@@ -3134,7 +3245,7 @@ build_compound_literal (tree type, tree init)
       DECL_COMDAT (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
       pushdecl (decl);
-      rest_of_decl_compilation (decl, NULL, 1, 0);
+      rest_of_decl_compilation (decl, 1, 0);
     }
 
   return complit;
@@ -3158,22 +3269,22 @@ complete_array_type (tree type, tree initial_value, int do_default)
        {
          int eltsize
            = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
-         maxindex = build_int_2 ((TREE_STRING_LENGTH (initial_value)
-                                  / eltsize) - 1, 0);
+         maxindex = build_int_cst (NULL_TREE,
+                                   (TREE_STRING_LENGTH (initial_value)
+                                    / eltsize) - 1, 0);
        }
       else if (TREE_CODE (initial_value) == CONSTRUCTOR)
        {
          tree elts = CONSTRUCTOR_ELTS (initial_value);
-         maxindex = build_int_2 (-1, -1);
+         maxindex = build_int_cst (NULL_TREE, -1, -1);
          for (; elts; elts = TREE_CHAIN (elts))
            {
              if (TREE_PURPOSE (elts))
                maxindex = TREE_PURPOSE (elts);
              else
-               maxindex = fold (build (PLUS_EXPR, integer_type_node,
-                                       maxindex, integer_one_node));
+               maxindex = fold (build2 (PLUS_EXPR, integer_type_node,
+                                        maxindex, integer_one_node));
            }
-         maxindex = copy_node (maxindex);
        }
       else
        {
@@ -3182,14 +3293,14 @@ complete_array_type (tree type, tree initial_value, int do_default)
            value = 1;
 
          /* Prevent further error messages.  */
-         maxindex = build_int_2 (0, 0);
+         maxindex = build_int_cst (NULL_TREE, 0, 0);
        }
     }
 
   if (!maxindex)
     {
       if (do_default)
-       maxindex = build_int_2 (0, 0);
+       maxindex = build_int_cst (NULL_TREE, 0, 0);
       value = 2;
     }
 
@@ -3197,7 +3308,7 @@ complete_array_type (tree type, tree initial_value, int do_default)
     {
       TYPE_DOMAIN (type) = build_index_type (maxindex);
       if (!TREE_TYPE (maxindex))
-       TREE_TYPE (maxindex) = TYPE_DOMAIN (type);
+       abort ();
     }
 
   /* Lay out the type now that we can get the real answer.  */
@@ -3300,7 +3411,7 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
     {
       error ("width of `%s' exceeds its type", name);
       w = max_width;
-      *width = build_int_2 (w, 0);
+      *width = build_int_cst (NULL_TREE, w, 0);
     }
   else
     w = tree_low_cst (*width, 1);
@@ -3308,7 +3419,7 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
   if (TREE_CODE (*type) == ENUMERAL_TYPE)
     {
       struct lang_type *lt = TYPE_LANG_SPECIFIC (*type);
-      if (!lt 
+      if (!lt
           || w < min_precision (lt->enum_min, TYPE_UNSIGNED (*type))
          || w < min_precision (lt->enum_max, TYPE_UNSIGNED (*type)))
        warning ("`%s' is narrower than values of its type", name);
@@ -3927,7 +4038,7 @@ grokdeclarator (tree declarator, tree declspecs,
              type = error_mark_node;
            }
 
-         if (pedantic && flexible_array_type_p (type))
+         if (pedantic && !in_system_header && flexible_array_type_p (type))
            pedwarn ("invalid use of structure with flexible array member");
 
          if (size == error_mark_node)
@@ -3993,9 +4104,9 @@ grokdeclarator (tree declarator, tree declspecs,
                     Do the calculation in index_type, so that if it is
                     a variable the computations will be done in the
                     proper mode.  */
-                 itype = fold (build (MINUS_EXPR, index_type,
-                                      convert (index_type, size),
-                                      convert (index_type, size_one_node)));
+                 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
@@ -4011,20 +4122,7 @@ grokdeclarator (tree declarator, tree declspecs,
                    }
 
                  if (size_varies)
-                   {
-                     /* We must be able to distinguish the
-                        SAVE_EXPR_CONTEXT for the variably-sized type
-                        so that we can set it correctly in
-                        set_save_expr_context.  The convention is
-                        that all SAVE_EXPRs that need to be reset
-                        have NULL_TREE for their SAVE_EXPR_CONTEXT.  */
-                     tree cfd = current_function_decl;
-                     if (decl_context == PARM)
-                       current_function_decl = NULL_TREE;
-                     itype = variable_size (itype);
-                     if (decl_context == PARM)
-                       current_function_decl = cfd;
-                   }
+                   itype = variable_size (itype);
                  itype = build_index_type (itype);
                }
            }
@@ -4078,12 +4176,17 @@ grokdeclarator (tree declarator, tree declspecs,
        }
       else if (TREE_CODE (declarator) == CALL_EXPR)
        {
-         /* Say it's a definition only for the CALL_EXPR closest to
-            the identifier.  */
-         bool really_funcdef = (funcdef_flag
-                                && (TREE_CODE (TREE_OPERAND (declarator, 0))
-                                    == IDENTIFIER_NODE));
+         /* Say it's a definition only for the declarator closest to
+            the identifier, apart possibly from some attributes.  */
+         bool really_funcdef = false;
          tree arg_types;
+         if (funcdef_flag)
+           {
+             tree t = TREE_OPERAND (declarator, 0);
+             while (TREE_CODE (t) == TREE_LIST)
+               t = TREE_VALUE (t);
+             really_funcdef = (TREE_CODE (t) == IDENTIFIER_NODE);
+           }
 
          /* Declaring a function type.
             Make sure we have a valid type for the function to return.  */
@@ -4114,21 +4217,15 @@ grokdeclarator (tree declarator, tree declspecs,
             qualify the return type, not the function type.  */
          if (type_quals)
            {
-             /* Type qualifiers on a function return type are normally
-                permitted by the standard but have no effect, so give a
-                warning at -Wextra.  Qualifiers on a void return type have
-                meaning as a GNU extension, and are banned on function
-                definitions in ISO C.  FIXME: strictly we shouldn't
-                pedwarn for qualified void return types except on function
-                definitions, but not doing so could lead to the undesirable
-                state of a "volatile void" function return type not being
-                warned about, and a use of the function being compiled
-                with GNU semantics, with no diagnostics under -pedantic.  */
-             if (VOID_TYPE_P (type) && pedantic && !in_system_header)
-               pedwarn ("ISO C forbids qualified void function return type");
-             else if (extra_warnings
-                      && !(VOID_TYPE_P (type)
-                           && type_quals == TYPE_QUAL_VOLATILE))
+             /* Type qualifiers on a function return type are
+                normally permitted by the standard but have no
+                effect, so give a warning at -Wreturn-type.
+                Qualifiers on a void return type are banned on
+                function definitions in ISO C; GCC used to used them
+                for noreturn functions.  */
+             if (VOID_TYPE_P (type) && really_funcdef)
+               pedwarn ("function definition has qualified void return type");
+             else if (warn_return_type)
                warning ("type qualifiers ignored on function return type");
 
              type = c_build_qualified_type (type, type_quals);
@@ -4424,14 +4521,6 @@ grokdeclarator (tree declarator, tree declspecs,
       }
     else if (TREE_CODE (type) == FUNCTION_TYPE)
       {
-       /* Every function declaration is "external"
-          except for those which are inside a function body
-          in which `auto' is used.
-          That is a case not specified by ANSI C,
-          and we use it for forward declarations for nested functions.  */
-       int extern_ref = (!(specbits & (1 << (int) RID_AUTO))
-                         || current_scope == file_scope);
-
        if (specbits & (1 << (int) RID_AUTO)
            && (pedantic || current_scope == file_scope))
          pedwarn ("invalid storage class for function `%s'", name);
@@ -4451,19 +4540,27 @@ grokdeclarator (tree declarator, tree declspecs,
        decl = build_decl_attribute_variant (decl, decl_attr);
 
        DECL_LANG_SPECIFIC (decl)
-         = ggc_alloc_cleared (sizeof (struct lang_decl));
+         = GGC_CNEW (struct lang_decl);
 
        if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
          pedwarn ("ISO C forbids qualified function types");
 
-       /* GNU C interprets a `volatile void' return type to indicate
+       /* 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 ("`noreturn' function returns non-void value");
 
-       if (extern_ref)
+       /* 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
+          forbidden by standard C (C99 6.7.1p5) and is interpreted by
+          GCC to signify a forward declaration of a nested function.  */
+       if ((specbits & (1 << RID_AUTO)) && current_scope != file_scope)
+         DECL_EXTERNAL (decl) = 0;
+       else
          DECL_EXTERNAL (decl) = 1;
+
        /* Record absence of global scope for `static' or `auto'.  */
        TREE_PUBLIC (decl)
          = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
@@ -4549,7 +4646,10 @@ grokdeclarator (tree declarator, tree declspecs,
        if (inlinep)
          pedwarn ("%Jvariable '%D' declared `inline'", decl, decl);
 
-       DECL_EXTERNAL (decl) = extern_ref;
+       /* At file scope, an initialized extern declaration may follow
+          a static declaration.  In that case, DECL_EXTERNAL will be
+          reset later in start_decl.  */
+       DECL_EXTERNAL (decl) = !!(specbits & (1 << (int) RID_EXTERN));
 
        /* At file scope, the presence of a `static' or `register' storage
           class specifier, or the absence of all storage class specifiers
@@ -4841,7 +4941,7 @@ get_parm_info (bool ellipsis)
                /* The %s will be one of 'struct', 'union', or 'enum'.  */
                warning ("anonymous %s declared inside parameter list",
                         keyword);
-             
+
              if (! explained_incomplete_types)
                {
                  warning ("its scope is only this definition or declaration,"
@@ -5132,9 +5232,11 @@ finish_struct (tree t, tree fieldlist, tree attributes)
     }
 
   /* Install struct as DECL_CONTEXT of each field decl.
-     Also process specified field sizes,m which is found in the DECL_INITIAL.
-     Store 0 there, except for ": 0" fields (so we can find them
-     and delete them, below).  */
+     Also process specified field sizes, found in the DECL_INITIAL,
+     storing 0 there after the type has been changed to precision equal
+     to its width, rather than the precision of the specified standard
+     type.  (Correct layout requires the original type to have been preserved
+     until now.)  */
 
   saw_named_field = 0;
   for (x = fieldlist; x; x = TREE_CHAIN (x))
@@ -5178,8 +5280,6 @@ finish_struct (tree t, tree fieldlist, tree attributes)
          SET_DECL_C_BIT_FIELD (x);
        }
 
-      DECL_INITIAL (x) = 0;
-
       /* Detect flexible array member in an invalid context.  */
       if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
          && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
@@ -5203,7 +5303,7 @@ finish_struct (tree t, tree fieldlist, tree attributes)
            }
        }
 
-      if (pedantic && TREE_CODE (t) == RECORD_TYPE
+      if (pedantic && !in_system_header && TREE_CODE (t) == RECORD_TYPE
          && flexible_array_type_p (TREE_TYPE (x)))
        pedwarn ("%Jinvalid use of structure with flexible array member", x);
 
@@ -5220,12 +5320,21 @@ finish_struct (tree t, tree fieldlist, tree attributes)
 
   layout_type (t);
 
-  /* Delete all zero-width bit-fields from the fieldlist.  */
+  /* Give bit-fields their proper types.  */
   {
     tree *fieldlistp = &fieldlist;
     while (*fieldlistp)
-      if (TREE_CODE (*fieldlistp) == FIELD_DECL && DECL_INITIAL (*fieldlistp))
-       *fieldlistp = TREE_CHAIN (*fieldlistp);
+      if (TREE_CODE (*fieldlistp) == FIELD_DECL && DECL_INITIAL (*fieldlistp)
+         && TREE_TYPE (*fieldlistp) != error_mark_node)
+       {
+         unsigned HOST_WIDE_INT width
+           = tree_low_cst (DECL_INITIAL (*fieldlistp), 1);
+         tree type = TREE_TYPE (*fieldlistp);
+         if (width != TYPE_PRECISION (type))
+           TREE_TYPE (*fieldlistp)
+             = build_nonstandard_integer_type (width, TYPE_UNSIGNED (type));
+         DECL_INITIAL (*fieldlistp) = 0;
+       }
       else
        fieldlistp = &TREE_CHAIN (*fieldlistp);
   }
@@ -5260,8 +5369,9 @@ finish_struct (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_alloc_cleared (sizeof (struct lang_type));
-        space2 = ggc_alloc (sizeof (struct sorted_fields_type) + len * sizeof (tree));
+        space = GGC_CNEW (struct lang_type);
+        space2 = GGC_NEWVAR (struct sorted_fields_type,
+                            sizeof (struct sorted_fields_type) + len * sizeof (tree));
 
         len = 0;
        space->s = space2;
@@ -5317,7 +5427,7 @@ finish_struct (tree t, tree fieldlist, tree attributes)
          layout_decl (decl, 0);
          if (c_dialect_objc ())
            objc_check_decl (decl);
-         rest_of_decl_compilation (decl, NULL, toplevel, 0);
+         rest_of_decl_compilation (decl, toplevel, 0);
          if (! toplevel)
            expand_decl (decl);
        }
@@ -5484,7 +5594,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_alloc_cleared (sizeof (struct lang_type));
+  lt = GGC_CNEW (struct lang_type);
   lt->enum_min = minnode;
   lt->enum_max = maxnode;
   TYPE_LANG_SPECIFIC (enumtype) = lt;
@@ -5602,29 +5712,26 @@ int
 start_function (tree declspecs, tree declarator, tree attributes)
 {
   tree decl1, old_decl;
-  tree restype;
-  int old_immediate_size_expand = immediate_size_expand;
+  tree restype, resdecl;
 
   current_function_returns_value = 0;  /* Assume, until we see it does.  */
   current_function_returns_null = 0;
   current_function_returns_abnormally = 0;
   warn_about_return_type = 0;
   current_extern_inline = 0;
-  c_in_iteration_stmt = 0;
-  c_in_case_stmt = 0;
+  c_switch_stack = NULL;
 
-  /* Don't expand any sizes in the return type of the function.  */
-  immediate_size_expand = 0;
+  /* Indicate no valid break/continue context by setting these variables
+     to some non-null, non-label value.  We'll notice and emit the proper
+     error message in c_finish_bc_stmt.  */
+  c_break_label = c_cont_label = size_zero_node;
 
   decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL);
 
   /* If the declarator is not suitable for a function definition,
      cause a syntax error.  */
   if (decl1 == 0)
-    {
-      immediate_size_expand = old_immediate_size_expand;
-      return 0;
-    }
+    return 0;
 
   decl_attributes (&decl1, attributes, 0);
 
@@ -5657,11 +5764,12 @@ start_function (tree declspecs, tree declarator, tree attributes)
   old_decl = lookup_name_in_scope (DECL_NAME (decl1), current_scope);
   if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
       && !DECL_BUILT_IN (old_decl)
-      && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
-         == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (old_decl))))
+      && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
+                   TREE_TYPE (TREE_TYPE (old_decl)))
       && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
     {
-      TREE_TYPE (decl1) = TREE_TYPE (old_decl);
+      TREE_TYPE (decl1) = composite_type (TREE_TYPE (old_decl),
+                                         TREE_TYPE (decl1));
       current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl);
     }
 
@@ -5788,8 +5896,6 @@ start_function (tree declspecs, tree declarator, tree attributes)
   push_scope ();
   declare_parm_level ();
 
-  make_decl_rtl (current_function_decl, NULL);
-
   restype = TREE_TYPE (TREE_TYPE (current_function_decl));
   /* Promote the value to int before returning it.  */
   if (c_promoting_integer_type_p (restype))
@@ -5802,15 +5908,11 @@ start_function (tree declspecs, tree declarator, tree attributes)
       else
        restype = integer_type_node;
     }
-  DECL_RESULT (current_function_decl)
-    = build_decl (RESULT_DECL, NULL_TREE, restype);
 
-  /* If this fcn was already referenced via a block-scope `extern' decl
-     (or an implicit decl), propagate certain information about the usage.  */
-  if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (current_function_decl)))
-    TREE_ADDRESSABLE (current_function_decl) = 1;
-
-  immediate_size_expand = old_immediate_size_expand;
+  resdecl = build_decl (RESULT_DECL, NULL_TREE, restype);
+  DECL_ARTIFICIAL (resdecl) = 1;
+  DECL_IGNORED_P (resdecl) = 1;
+  DECL_RESULT (current_function_decl) = resdecl;
 
   start_fname_decls ();
 
@@ -5853,7 +5955,8 @@ store_parm_decls_newstyle (tree fndecl, tree arg_info)
     {
       DECL_CONTEXT (decl) = current_function_decl;
       if (DECL_NAME (decl))
-       bind (DECL_NAME (decl), decl, current_scope);
+       bind (DECL_NAME (decl), decl, current_scope,
+             /*invisible=*/false, /*nested=*/false);
       else
        error ("%Jparameter name omitted", decl);
     }
@@ -5866,13 +5969,15 @@ store_parm_decls_newstyle (tree fndecl, tree arg_info)
     {
       DECL_CONTEXT (decl) = current_function_decl;
       if (DECL_NAME (decl))
-       bind (DECL_NAME (decl), decl, current_scope);
+       bind (DECL_NAME (decl), decl, current_scope,
+             /*invisible=*/false, /*nested=*/false);
     }
 
   /* And all the tag declarations.  */
   for (decl = tags; decl; decl = TREE_CHAIN (decl))
     if (TREE_PURPOSE (decl))
-      bind (TREE_PURPOSE (decl), TREE_VALUE (decl), current_scope);
+      bind (TREE_PURPOSE (decl), TREE_VALUE (decl), current_scope,
+           /*invisible=*/false, /*nested=*/false);
 }
 
 /* Subroutine of store_parm_decls which handles old-style function
@@ -5908,7 +6013,7 @@ store_parm_decls_oldstyle (tree fndecl, tree arg_info)
        }
 
       b = I_SYMBOL_BINDING (TREE_VALUE (parm));
-      if (b && b->contour == current_scope)
+      if (b && B_IN_CURRENT_SCOPE (b))
        {
          decl = b->decl;
          /* If we got something other than a PARM_DECL it is an error.  */
@@ -6026,8 +6131,7 @@ store_parm_decls_oldstyle (tree fndecl, tree arg_info)
             declared for the arg.  ISO C says we take the unqualified
             type for parameters declared with qualified type.  */
          if (! comptypes (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)),
-                          TYPE_MAIN_VARIANT (TREE_VALUE (type)),
-                          COMPARE_STRICT))
+                          TYPE_MAIN_VARIANT (TREE_VALUE (type))))
            {
              if (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
                  == TYPE_MAIN_VARIANT (TREE_VALUE (type)))
@@ -6099,25 +6203,6 @@ store_parm_decls_oldstyle (tree fndecl, tree arg_info)
     }
 }
 
-/* A subroutine of store_parm_decls called via walk_tree.  Mark all
-   decls non-local.  */
-
-static tree
-set_decl_nonlocal (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
-{
-  tree t = *tp;
-
-  if (DECL_P (t))
-    {
-      DECL_NONLOCAL (t) = 1;
-      *walk_subtrees = 0;
-    }
-  else if (TYPE_P (t))
-    *walk_subtrees = 0;
-
-  return NULL;
-}
-
 /* Store the parameter declarations into the current function declaration.
    This is called after parsing the parameter declarations, before
    digesting the body of the function.
@@ -6130,9 +6215,6 @@ store_parm_decls (void)
 {
   tree fndecl = current_function_decl;
 
-  /* The function containing FNDECL, if any.  */
-  tree context = decl_function_context (fndecl);
-
   /* The argument information block for FNDECL.  */
   tree arg_info = DECL_ARGUMENTS (fndecl);
 
@@ -6161,38 +6243,21 @@ store_parm_decls (void)
   allocate_struct_function (fndecl);
 
   /* Begin the statement tree for this function.  */
-  begin_stmt_tree (&DECL_SAVED_TREE (fndecl));
-
-  /* If this is a nested function, save away the sizes of any
-     variable-size types so that we can expand them when generating
-     RTL.  */
-  if (context)
-    {
-      tree t;
-
-      DECL_LANG_SPECIFIC (fndecl)->pending_sizes
-       = nreverse (get_pending_sizes ());
-      for (t = DECL_LANG_SPECIFIC (fndecl)->pending_sizes;
-          t;
-          t = TREE_CHAIN (t))
-       {
-         /* We will have a nonlocal use of whatever variables are
-            buried inside here.  */
-         walk_tree (&TREE_OPERAND (TREE_VALUE (t), 0),
-                    set_decl_nonlocal, NULL, NULL);
-
-         SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = context;
-       }
-    }
+  DECL_SAVED_TREE (fndecl) = push_stmt_list ();
 
-  /* This function is being processed in whole-function mode.  */
-  cfun->x_whole_function_mode_p = 1;
+  /* ??? Insert the contents of the pending sizes list into the function
+     to be evaluated.  This just changes mis-behaviour until assign_parms
+     phase ordering problems are resolved.  */
+  {
+    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.  */
-  immediate_size_expand = 0;
   cfun->x_dont_save_pending_sizes_p = 1;
 }
 \f
@@ -6233,22 +6298,6 @@ finish_function (void)
 {
   tree fndecl = current_function_decl;
 
-  /* When a function declaration is totally empty, e.g.
-        void foo(void) { }
-     (the argument list is irrelevant) the compstmt rule will not
-     bother calling push_scope/pop_scope, which means we get here with
-     the scope stack out of sync.  Detect this situation by noticing
-     that current_scope is still as store_parm_decls left it, and do
-     a dummy push/pop to get back to consistency.
-     Note that the call to push_scope does not actually push another
-     scope - see there for details.  */
-
-  if (current_scope->parm_flag && next_is_function_body)
-    {
-      push_scope ();
-      pop_scope ();
-    }
-
   if (TREE_CODE (fndecl) == FUNCTION_DECL
       && targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
     {
@@ -6282,20 +6331,15 @@ finish_function (void)
        }
       else
        {
-#ifdef DEFAULT_MAIN_RETURN
-         /* Make it so that `main' always returns success by default.  */
-         DEFAULT_MAIN_RETURN;
-#else
          if (flag_isoc99)
-           c_expand_return (integer_zero_node);
-#endif
+           c_finish_return (integer_zero_node);
        }
     }
 
-  finish_fname_decls ();
-
   /* Tie off the statement tree for this function.  */
-  finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
+  DECL_SAVED_TREE (fndecl) = pop_stmt_list (DECL_SAVED_TREE (fndecl));
+
+  finish_fname_decls ();
 
   /* Complain if there's just no return statement.  */
   if (warn_return_type
@@ -6332,10 +6376,13 @@ finish_function (void)
       && !targetm.have_ctors_dtors)
     static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
 
+  /* Finalize the ELF visibility for the function.  */
+  c_determine_visibility (fndecl);
+
   /* Genericize before inlining.  Delay genericizing nested functions
      until their parent function is genericized.  Since finalizing
      requires GENERIC, delay that as well.  */
-     
+
   if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node)
     {
       if (!decl_function_context (fndecl))
@@ -6360,47 +6407,26 @@ finish_function (void)
   current_function_decl = NULL;
 }
 
-/* Generate the RTL for the body of FNDECL.  If NESTED_P is nonzero,
-   then we are already in the process of generating RTL for another
-   function.  */
+/* Generate the RTL for the body of FNDECL.  */
 
-static void
-c_expand_body_1 (tree fndecl, int nested_p)
+void
+c_expand_body (tree fndecl)
 {
-  if (nested_p)
-    {
-      /* Make sure that we will evaluate variable-sized types involved
-        in our function's type.  */
-      expand_pending_sizes (DECL_LANG_SPECIFIC (fndecl)->pending_sizes);
 
-      /* Squirrel away our current state.  */
-      push_function_context ();
-    }
-    
-  tree_rest_of_compilation (fndecl, nested_p);
+  if (!DECL_INITIAL (fndecl)
+      || DECL_INITIAL (fndecl) == error_mark_node)
+    return;
 
-  if (nested_p)
-    /* Return to the enclosing function.  */
-    pop_function_context ();
+  tree_rest_of_compilation (fndecl, false);
 
   if (DECL_STATIC_CONSTRUCTOR (fndecl)
       && targetm.have_ctors_dtors)
     targetm.asm_out.constructor (XEXP (DECL_RTL (fndecl), 0),
-                                DEFAULT_INIT_PRIORITY);
+                                 DEFAULT_INIT_PRIORITY);
   if (DECL_STATIC_DESTRUCTOR (fndecl)
       && targetm.have_ctors_dtors)
     targetm.asm_out.destructor (XEXP (DECL_RTL (fndecl), 0),
-                               DEFAULT_INIT_PRIORITY);
-}
-
-/* Like c_expand_body_1 but only for unnested functions.  */
-
-void
-c_expand_body (tree fndecl)
-{
-
-  if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node)
-    c_expand_body_1 (fndecl, 0);
+                                DEFAULT_INIT_PRIORITY);
 }
 \f
 /* Check the declarations given in a for-loop for satisfying the C99
@@ -6474,13 +6500,13 @@ void
 c_push_function_context (struct function *f)
 {
   struct language_function *p;
-  p = ggc_alloc (sizeof (struct language_function));
+  p = GGC_NEW (struct language_function);
   f->language = p;
 
   p->base.x_stmt_tree = c_stmt_tree;
-  p->base.x_scope_stmt_stack = c_scope_stmt_stack;
-  p->x_in_iteration_stmt = c_in_iteration_stmt;
-  p->x_in_case_stmt = c_in_case_stmt;
+  p->x_break_label = c_break_label;
+  p->x_cont_label = c_cont_label;
+  p->x_switch_stack = c_switch_stack;
   p->returns_value = current_function_returns_value;
   p->returns_null = current_function_returns_null;
   p->returns_abnormally = current_function_returns_abnormally;
@@ -6506,9 +6532,9 @@ c_pop_function_context (struct function *f)
     }
 
   c_stmt_tree = p->base.x_stmt_tree;
-  c_scope_stmt_stack = p->base.x_scope_stmt_stack;
-  c_in_iteration_stmt = p->x_in_iteration_stmt;
-  c_in_case_stmt = p->x_in_case_stmt;
+  c_break_label = p->x_break_label;
+  c_cont_label = p->x_cont_label;
+  c_switch_stack = p->x_switch_stack;
   current_function_returns_value = p->returns_value;
   current_function_returns_null = p->returns_null;
   current_function_returns_abnormally = p->returns_abnormally;
@@ -6528,7 +6554,7 @@ c_dup_lang_specific_decl (tree decl)
   if (!DECL_LANG_SPECIFIC (decl))
     return;
 
-  ld = ggc_alloc (sizeof (struct lang_decl));
+  ld = GGC_NEW (struct lang_decl);
   memcpy (ld, DECL_LANG_SPECIFIC (decl), sizeof (struct lang_decl));
   DECL_LANG_SPECIFIC (decl) = ld;
 }
@@ -6558,19 +6584,11 @@ current_stmt_tree (void)
   return &c_stmt_tree;
 }
 
-/* Returns the stack of SCOPE_STMTs for the current function.  */
-
-tree *
-current_scope_stmt_stack (void)
-{
-  return &c_scope_stmt_stack;
-}
-
 /* Nonzero if TYPE is an anonymous union or struct type.  Always 0 in
    C.  */
 
 int
-anon_aggr_type_p (tree node ATTRIBUTE_UNUSED)
+anon_aggr_type_p (tree ARG_UNUSED (node))
 {
   return 0;
 }
@@ -6582,48 +6600,6 @@ extract_interface_info (void)
 {
 }
 
-/* Return a new COMPOUND_STMT, after adding it to the current
-   statement tree.  */
-
-tree
-c_begin_compound_stmt (void)
-{
-  tree stmt;
-
-  /* Create the COMPOUND_STMT.  */
-  stmt = add_stmt (build_stmt (COMPOUND_STMT, NULL_TREE));
-
-  return stmt;
-}
-
-/* Expand DECL if it declares an entity not handled by the
-   common code.  */
-
-int
-c_expand_decl (tree decl)
-{
-  if (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl))
-    {
-      /* Let the back-end know about this variable.  */
-      if (!anon_aggr_type_p (TREE_TYPE (decl)))
-       emit_local_var (decl);
-      else
-       expand_anon_union_decl (decl, NULL_TREE, 
-                               DECL_ANON_UNION_ELEMS (decl));
-    }
-  else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
-    make_rtl_for_local_static (decl);
-  /* Expand nested functions.  */
-  else if (TREE_CODE (decl) == FUNCTION_DECL
-          && DECL_CONTEXT (decl) == current_function_decl
-          && DECL_SAVED_TREE (decl))
-    c_expand_body_1 (decl, 1);
-  else
-    return 0;
-
-  return 1;
-}
-
 /* Return the global value of T as a symbol.  */
 
 tree
@@ -6632,7 +6608,7 @@ identifier_global_value   (tree t)
   struct c_binding *b;
 
   for (b = I_SYMBOL_BINDING (t); b; b = b->shadowed)
-    if (b->contour == file_scope || b->contour == external_scope)
+    if (B_IN_FILE_SCOPE (b) || B_IN_EXTERNAL_SCOPE (b))
       return b->decl;
 
   return 0;
@@ -6644,12 +6620,15 @@ identifier_global_value (tree t)
 void
 record_builtin_type (enum rid rid_index, const char *name, tree type)
 {
-  tree id;
+  tree id, decl;
   if (name == 0)
     id = ridpointers[(int) rid_index];
   else
     id = get_identifier (name);
-  pushdecl (build_decl (TYPE_DECL, id, type));
+  decl = build_decl (TYPE_DECL, id, type);
+  pushdecl (decl);
+  if (debug_hooks->type_decl)
+    debug_hooks->type_decl (decl, false);
 }
 
 /* Build the void_list_node (void_type_node having been created).  */
@@ -6680,58 +6659,84 @@ make_pointer_declarator (tree type_quals_attrs, tree target)
   return build1 (INDIRECT_REF, quals, itarget);
 }
 
-/* A wrapper around lhd_set_decl_assembler_name that gives static
-   variables their C names if they are at file scope and only one
-   translation unit is being compiled, for backwards compatibility
-   with certain bizarre assembler hacks (like crtstuff.c).  */
-
-void
-c_static_assembler_name (tree decl)
+/* Synthesize a function which calls all the global ctors or global
+   dtors in this file.  This is only used for targets which do not
+   support .ctors/.dtors sections.  FIXME: Migrate into cgraph.  */
+static void
+build_cdtor (int method_type, tree cdtors)
 {
-  if (num_in_fnames == 1
-      && !TREE_PUBLIC (decl) && DECL_CONTEXT (decl)
-      && TREE_CODE (DECL_CONTEXT (decl)) == TRANSLATION_UNIT_DECL)
-    SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
-  else
-    lhd_set_decl_assembler_name (decl);
+  tree body = 0;
+
+  if (!cdtors)
+    return;
+
+  for (; cdtors; cdtors = TREE_CHAIN (cdtors))
+    append_to_statement_list (build_function_call (TREE_VALUE (cdtors), 0),
+                             &body);
+
+  cgraph_build_static_cdtor (method_type, body, DEFAULT_INIT_PRIORITY);
 }
 
-/* Perform final processing on file-scope data.  */
+/* Perform final processing on one file scope's declarations (or the
+   external scope's declarations), GLOBALS.  */
 static void
 c_write_global_declarations_1 (tree globals)
 {
   size_t len = list_length (globals);
-  tree *vec = xmalloc (sizeof (tree) * len);
+  tree *vec = XNEWVEC (tree, len);
   size_t i;
   tree decl;
-  
+
   /* Process the decls in the order they were written.  */
   for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
     vec[i] = decl;
 
   wrapup_global_declarations (vec, len);
   check_global_declarations (vec, len);
-      
+
   free (vec);
 }
 
 void
 c_write_global_declarations (void)
 {
-  tree t;
+  tree ext_block, t;
 
   /* We don't want to do this if generating a PCH.  */
   if (pch_file)
     return;
 
-  /* Process all file scopes in this compilation.  */
+  /* Don't waste time on further processing if -fsyntax-only or we've
+     encountered errors.  */
+  if (flag_syntax_only || errorcount || sorrycount || cpp_errors (parse_in))
+    return;
+
+  /* Close the external scope.  */
+  ext_block = pop_scope ();
+  external_scope = 0;
+  if (current_scope)
+    abort ();
+
+  /* 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))
     c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t)));
-
-  /* Now do the same for the externals scope.  */
-  t = pop_scope ();
-  if (t)
-    c_write_global_declarations_1 (BLOCK_VARS (t));
+  c_write_global_declarations_1 (BLOCK_VARS (ext_block));
+
+  /* Generate functions to call static constructors and destructors
+     for targets that do not support .ctors/.dtors sections.  These
+     functions have magic names which are detected by collect2.  */
+  build_cdtor ('I', static_ctors); static_ctors = 0;
+  build_cdtor ('D', static_dtors); static_dtors = 0;
+
+  /* We're done parsing; proceed to optimize and emit assembly.
+     FIXME: shouldn't be the front end's responsibility to call this.  */
+  cgraph_optimize ();
+
+  /* Presently this has to happen after cgraph_optimize.
+     FIXME: shouldn't be the front end's responsibility to call this.  */
+  if (flag_mudflap)
+    mudflap_finish_file ();
 }
 
 #include "gt-c-decl.h"