This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[tree-ssa] Merge in Zack's c-decl.c rewrite


This fixes a half-dozen or so failures building FC2 with the tree-ssa
compiler.

There are two regressions introduced with this patch -- both of which are
also regressing in the mainline since the introduction of Zack's patch.

One is in the Objective-C testsuite (comp-types-1.m), the other in the
C++ testsuite (g++-bprob-1.C).

Basically I merged in all the changes to c-decl.c from the mainline to the
branch plus any directly related changes.

Bootstrapped and regression tested (with regressions noted above, which
match mainline) on i686-pc-linux-gnu.  Also verified this fixed a half-dozen
or so failures building FC2 with the tree-ssa compiler.

Index: ChangeLog.tree-ssa
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/ChangeLog.tree-ssa,v
retrieving revision 1.1.2.1292
diff -c -p -r1.1.2.1292 ChangeLog.tree-ssa
*** ChangeLog.tree-ssa	24 Mar 2004 06:28:35 -0000	1.1.2.1292
--- ChangeLog.tree-ssa	24 Mar 2004 18:40:25 -0000
***************
*** 1,3 ****
--- 1,8 ----
+ 2004-03-24  Jeff Law  <law@redhat.com>
+ 
+ 	* c-mudflap (mflang_flush_calls): Use push_scope/pop_scope instead
+ 	of pushlevel and poplevel.
+ 
  2004-03-23  Richard Henderson  <rth@redhat.com>
  
  	PR middle-end/14694
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ChangeLog,v
retrieving revision 1.14646.2.152
diff -c -p -r1.14646.2.152 ChangeLog
*** ChangeLog	22 Mar 2004 22:54:49 -0000	1.14646.2.152
--- ChangeLog	24 Mar 2004 18:24:33 -0000
***************
*** 1,13 ****
--- 1,194 ----
+ 2004-03-23  Zack Weinberg  <zack@codesourcery.com>
+ 
+ 	PR 12267, 12391, 12560, 13129, 14114, 14133
+ 	* c-tree.h: Forward declare struct c_binding.  Declare
+ 	c_override_bindings_to_false.  Update prototypes.
+ 	(struct lang_identifier): Update comments.  Change fields to be
+ 	struct c_binding *.
+ 	(IDENTIFIER_SYMBOL_VALUE, IDENTIFIER_TAG_VALUE)
+ 	(IDENTIFIER_LABEL_VALUE, C_DECL_INVISIBLE)
+ 	(KEEP_NO, KEEP_YES, KEEP_MAYBE): Delete.
+ 	(C_DECL_IN_EXTERNAL_SCOPE, C_DECL_DECLARED_BUILTIN): New.
+ 	* c-common.h: Update prototypes.
+ 	* c-decl.c (struct c_scope): Update commentary.  Remove names,
+ 	names_last, parms, parms_last, tags, and shadowed fields.  Add
+ 	bindings and depth fields.
+ 	(scope_freelist): Move to more appropriate location.
+ 	(c_print_identifier): Update for changes to struct lang_identifier.
+ 	(objc_mark_locals_volatile): Update for new bindings structures.
+ 	(global_bindings_p): Honor c_override_global_bindings_to_false.
+ 	(pushlevel): Rename to push_scope; take no arguments; use the
+ 	scope_freelist; initialize scope->depth and check for overflow.
+ 	(poplevel): Rename to pop_scope; totally rewritten for new bindings
+ 	structures.
+ 	(diagnose_mismatched_decls): Use C_DECL_DECLARED_BUILTIN, not
+ 	C_DECL_INVISIBLE, for certain decisions.  Adjust some diagnostics.
+ 	Improve some commentary.  Adjust handling of forward parm decls.
+ 	(merge_decls): Set C_DECL_DECLARED_BUILTIN when appropriate.
+ 	Preserve C_DECL_IN_EXTERNAL_SCOPE.
+ 	(warn_if_shadowing): Correct indentation.  Improve diagnostics.
+ 	(pushdecl): Remove unnecessary assertion.  Short-circuit anonymous
+ 	decls.  Rewrite for new bindings structures.  Improve commentary.
+ 	Eliminate the copy_node call.
+ 	(implicit_decl_warning): Use the "diag" idiom (as seen in
+ 	locate_old_decl) to reduce code duplication; call locate_old_decl
+ 	if appropriate.  Relocate to remove need for forward declaration.
+ 	(implicitly_declare): Adjust for new bindings structures.  Kludge
+ 	around Objective-C not-really-builtin functions.
+ 	(undeclared_variable): Improve diagnostics.  If current_function_decl
+ 	is nonnull but current_function_scope is null, use current_scope.
+ 	Use bind.
+ 	(lookup_tag): Adjust for new bindings structures.  Kludge around
+ 	Objective-C's tag declarations that wind up in the external scope.
+ 	(lookup_name): Adjust for new bindings structures.  Kludge around
+ 	c-common.c's pseudo-typedefs that wind up in the external scope.
+ 	(lookup_name_current_level): Rename lookup_name_in_scope; take a
+ 	second argument indicating the scope to examine; rewrite for
+ 	new bindings structures.
+ 	(c_init_decl_processing): Adjust for renamed functions.  Do not
+ 	initialize current_file_decl, first_builtin_decl, last_builtin_decl.
+ 	First scope pushed is the external scope, not the global scope.
+ 	(builtin_function): Use bind, not pushdecl.  Adjust other bits
+ 	for new data structures.  Keep track of builtins that should be
+ 	made visible automatically.
+ 	(start_decl): Adjust diagnostics.  Remove unnecessary call to
+ 	expand_decl.
+ 	(grokparms): Return 0 if arg_types is error_mark_node.
+ 	(get_parm_info): Rename "void_at_end" argument to "ellipsis", with
+ 	reversed sense.  Rewrite for new bindings structures.  Do not
+ 	leave any decls in the scope, to prevent pop_scope from doing
+ 	contradictory things with them.
+ 	(finish_struct, finish_enum): Remove redundant diagnostics.
+ 	(build_enumerator): Don't cascade diagnostics for error_mark_node.
+ 	Mark location where -pedantic changes the meaning of the program.
+ 	(store_parm_decls_newstyle, store_parm_decls_oldstyle): Load the
+ 	parameter decls into the function's scope structure using bind.
+ 	Warn here about function definitions in the wrong style.
+ 	Adjust diagnostics.
+ 	(store_parm_decls): Correct the determination of whether a
+ 	function was defined with a prototype.
+ 	(c_write_global_declarations): Operate on all file decls and on
+ 	the external scope.  Split body of the loop to...
+ 	(c_write_global_declarations_1): ... this new function, to avoid
+ 	code duplication.
+ 	(truly_local_externals, first_builtin_decl, last_builtin_decl)
+ 	(make_scope, pop_scope, in_parm_level_p, set_block)
+ 	(any_external_decl, record_external_decl, bind_label, getdecls)
+ 	(link_hash_hash, link_hash_eq, merge_translation_unit_decls)
+ 	(c_reset_state): Delete.
+ 	(visible_builtins, c_override_global_bindings_to_false)
+ 	(c_binding, I_SYMBOL_BINDING, I_SYMBOL_DECL, I_TAG_BINDING)
+ 	(I_TAG_DECL, I_LABEL_BINDING, I_LABEL_DECL, file_scope)
+ 	(external_scope, binding_freelist, bind, free_binding_and_advance)
+ 	(push_file_scope, pop_file_scope): New.
+ 	(pushtag, pushdecl_top_level, lookup_label, declare_label)
+ 	(define_label, c_make_fname_decl, finish_decl)
+ 	(mark_forward_parm_decls, build_compound_literal)
+ 	(grokdeclarator, start_function, check_for_loop_decls)
+ 	(identifier_global_value, record_builtin_type): Minor adjustments
+ 	for new bindings structures.  Improve diagnostics and commentary.
+ 	* c-objc-common.c (start_cdtor, finish_cdtor): Adjust calls to
+ 	pushlevel/poplevel respectively.
+ 	(c_objc_common_finish_file): Don't call merge_translation_unit_decls.
+ 	* c-opts.c (c_common_parse_file): Remove spurious ATTRIBUTE_UNUSED.
+ 	Warn about YYDEBUG not being defined only if -dy.  Remove no-longer-
+ 	correct loop over multiple translation units; call fatal_error if
+ 	requested to compile more than one file at once.  (This disables
+ 	IMA temporarily - an up-front error being preferable to a crash.)
+ 	* c-parse.in (pushlevel, poplevel rules): Rename push_scope, pop_scope.
+ 	(all actions): Adjust calls to pushlevel/poplevel.
+ 	(parsing_iso_function_signature): Delete.
+ 	(extdef_1): Fold into extdef.
+ 	(old_style_parm_decls_1): Fold into old_style_parm_decls.  Don't
+ 	warn here about function definitions in the wrong style.
+ 	(after_tyle_declarator, parm_declarator_starttypename)
+ 	(parm_declarator_nostarttypename, notype_declarator): Remove
+ 	commented-out productions.
+ 	(parmlist_1, parmlist_2): Use make_node, not tree_cons, to create
+ 	an empty TREE_LIST node.  Adjust calls to get_parm_info.
+ 	(parmlist_2 : ELLIPSIS): Tag the arg-info block with error_mark_node
+ 	to suppress -Wold-style-definition after this error.
+ 	(c_parse_file): Don't clear the binding stack or call
+ 	finish_fname_decls here.  Correct comment.
+ 	* c-typeck.c (same_translation_unit_p): Export.
+ 	(common_type): Use c_override_global_bindings_to_false, not
+ 	pushlevel/poplevel/declare_parm_level.
+ 	* c-lang.c: Override LANG_HOOKS_CLEAR_BINDING_STACK,
+ 	LANG_HOOKS_PUSHLEVEL, LANG_HOOKS_POPLEVEL, LANG_HOOKS_SET_BLOCK,
+ 	and LANG_HOOKS_GETDECLS with do-nothing stubs.
+ 	* objc/objc-lang.c: Likewise.
+ 	* objc/objc-act.c: Adjust all calls to pushlevel, poplevel,
+ 	get_parm_info.
+ 	(OBJC_VOID_AT_END): Delete; replace all uses
+ 	with void_list_node.
+ 	(generate_forward_declaration_to_string_table): Delete.
+ 	* objc/objc-act.h (OCTI_STRG_DECL, UOBJC_STRINGS_decl): Delete.
+ 
+ 	* coverage.c (create_coverage): Don't pushdecl anything.
+ 	* langhooks.c (lhd_clear_binding_stack): Call
+ 	lang_hooks.decls.poplevel, not poplevel.
+ 	* tree.c (list_length): If ENABLE_TREE_CHECKING, abort on a
+ 	circular list rather than going into an infinite loop.
+ 
  2004-03-22  Diego Novillo  <dnovillo@redhat.com>
  
  	* c-typeck.c (same_translation_unit_p): Fix pasto.
  
+ 2004-03-22  Jakub Jelinek  <jakub@redhat.com>
+                                                                              

+         PR c/14069
+         * c-decl.c (finish_struct): Change type of incorrect flexible array
+         field into error_mark_node.
+                                                                              

+ 2004-03-20  Kazu Hirata  <kazu@cs.umass.edu>
+                                                                              

+ 	* c-decl.c: Replace calls via (*targetm.foo) () with targetm.foo ().
+ 
+ 2004-03-19  Kazu Hirata  <kazu@cs.umass.edu>
+                                                                              

+ 	* c-decl.c: Replace calls via (*targetm.foo) () with targetm.foo ().
+                                                                              

  2004-03-18  Mark Mitchell  <mark@codesourcery.com>
   
  	* c-decl.c (grokdeclarator): Do not complain about redeclaring
  	visible "static" identifiers "extern" in a local scope.
  	* dwarf2out.c (loc_descriptor_from_tree): Handle pre- and
  	post-increments/decrements.
+ 
+ 2004-03-10  Richard Henderson  <rth@redhat.com>
+                                                                              

+ 	PR c/14517
+ 	* c-decl.c (grokdeclarator): Don't warn for duplicate qualifiers
+ 	except for pedantic c90 mode.
+                                                                              

+ 2004-03-09  Zack Weinberg  <zack@codesourcery.com>
+                                                                              

+ 	* c-decl.c (last_function_parms, last_function_parm_tags)
+ 	(last_function_parm_others, current_function_parms)
+ 	(current_function_parm_tags, current_function_parm_others):
+ 	Delete.
+ 	(ARG_INFO_PARMS, ARG_INFO_TAGS, ARG_INFO_TYPES, ARG_INFO_OTHERS):
+ 	New macros.
+ 	(grokdeclarator): For function definitions, save the arg-info
+ 	block from the declarator in DECL_ARGUMENTS.
+ 	(grokparms): Do not write to last_function_parm*.  Use ARG_INFO_*
+ 	macros to operate on arg-info block.  Can assume ARG_INFO_PARMS
+ 	contains only PARM_DECLs.  Improve diagnostics.
+ 	(get_parm_info): Use ARG_INFO_* macros.  Improve comments and
+ 	diagnostics.  Disable some expensive checks if not ENABLE_CHECKING.
+ 	(store_parm_decls_newstyle): Take the function to operate on,
+ 	and an arg-info block, as arguments; don't get anything from
+ 	current_function_* globals.
+ 	(store_parm_decls_oldstyle): Likewise.
+ 	(store_parm_decls): Pass fndecl and its arg-info block down to
+ 	store_parm_decls_newstyle/oldstyle.  Send functions with empty
+ 	argument lists through store_parm_decls_newstyle to reduce
+ 	overhead.
+ 	(pushdecl): Comment on the problems with the call to copy_node.
+ 	Clear DECL_ARGUMENTS of the old node after copying it, if it
+ 	is an arg-info block instead of a chain of decls.
+ 	(start_function): Do not manipulate current_function_parm* or
+ 	last_function_parm*.
  
  2004-03-09  Andrew Pinski  <apinski@apple.com>
  
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.141.2.48
diff -c -p -r1.141.2.48 c-common.h
*** c-common.h	2 Mar 2004 18:41:22 -0000	1.141.2.48
--- c-common.h	24 Mar 2004 18:24:34 -0000
*************** extern void (*lang_expand_function_end) 
*** 327,332 ****
--- 327,334 ----
     noreturn attribute.  */
  extern int (*lang_missing_noreturn_ok_p) (tree);
  
+ extern void push_file_scope (void);
+ extern void pop_file_scope (void);
  extern int yyparse (void);
  extern stmt_tree current_stmt_tree (void);
  extern tree *current_scope_stmt_stack (void);
*************** extern int self_promoting_args_p (tree);
*** 948,956 ****
  extern tree strip_array_types (tree);
  extern tree strip_pointer_operator (tree);
  
- /* This function resets the parsers' state in preparation for parsing
-    a new file.  */
- extern void c_reset_state (void);
  /* This is the basic parsing function.  */
  extern void c_parse_file (void);
  /* This is misnamed, it actually performs end-of-compilation processing.  */
--- 950,955 ----
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.334.2.87
diff -c -p -r1.334.2.87 c-decl.c
*** c-decl.c	18 Mar 2004 22:52:29 -0000	1.334.2.87
--- c-decl.c	24 Mar 2004 18:24:47 -0000
*************** static tree enum_next_value;
*** 88,124 ****
  
  static int enum_overflow;
  
! /* Parsing a function declarator leaves a list of parameter names
!    or a chain of parameter decls here.  */
! 
! static tree last_function_parms;
! 
! /* ... and a chain of structure and enum types declared in the
!    parmlist here.  */
! 
! static tree last_function_parm_tags;
! 
! /* ... and a chain of all non-parameter declarations (such as
!    CONST_DECLs from enumerations) here.  */
! 
! static tree last_function_parm_others;
! 
! /* After parsing the declarator that starts a function definition,
!    `start_function' puts the list of parameter names or chain of decls here
!    for `store_parm_decls' to find.  */
! 
! static tree current_function_parms;
! 
! /* Similar, for last_function_parm_tags.  */
! 
! static tree current_function_parm_tags;
! 
! /* And for last_function_parm_others.  */
! 
! static tree current_function_parm_others;
! 
! /* Similar, for the file and line that the prototype came from if this is
!    an old-style definition.  */
  
  static location_t current_function_prototype_locus;
  
--- 88,103 ----
  
  static int enum_overflow;
  
! /* These #defines are for clarity in working with the information block
!    returned by get_parm_info.  */
! #define ARG_INFO_PARMS(args)  TREE_PURPOSE(args)
! #define ARG_INFO_TAGS(args)   TREE_VALUE(args)
! #define ARG_INFO_TYPES(args)  TREE_CHAIN(args)
! #define ARG_INFO_OTHERS(args) TREE_TYPE(args)
! 
! /* The file and line that the prototype came from if this is an
!    old-style definition; used for diagnostics in
!    store_parm_decls_oldstyle.  */
  
  static location_t current_function_prototype_locus;
  
*************** static GTY(()) tree c_scope_stmt_stack;
*** 134,147 ****
  int c_in_iteration_stmt;
  int c_in_case_stmt;
  
! /* A list of external DECLs that appeared at block scope when there was
!    some other global meaning for that identifier.  */
! static GTY(()) tree truly_local_externals;
! 
! /* All the builtins; this is a subset of the entries of global_scope.  */
! 
! static GTY(()) tree first_builtin_decl;
! static GTY(()) tree last_builtin_decl;
  
  /* Set to 0 at beginning of a function definition, set to 1 if
     a return statement that specifies a return value is seen.  */
--- 113,120 ----
  int c_in_iteration_stmt;
  int c_in_case_stmt;
  
! /* A list of decls to be made automatically visible in each file scope.  */
! static GTY(()) tree visible_builtins;
  
  /* Set to 0 at beginning of a function definition, set to 1 if
     a return statement that specifies a return value is seen.  */
*************** static int warn_about_return_type;
*** 166,175 ****
  /* Nonzero when starting a function declared `extern inline'.  */
  
  static int current_extern_inline;
  
! /* Each c_scope structure describes the complete contents of one scope.
!    Three scopes are distinguished specially: the innermost or current
!    scope, the innermost function scope, and the outermost or file scope.
  
     Most declarations are recorded in the current scope.
  
--- 139,194 ----
  /* Nonzero when starting a function declared `extern inline'.  */
  
  static int current_extern_inline;
+ 
+ /* 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;
+ 
  
! /* Each c_binding structure describes one binding of an identifier to
!    a decl.  All the decls in a scope - irrespective of namespace - are
!    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).
! 
!    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.  */
! 
! struct c_binding GTY(())
! {
!   tree decl;			/* the decl bound */
!   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 */
! };
! 
! #define I_SYMBOL_BINDING(node) \
!   (((struct lang_identifier *)IDENTIFIER_NODE_CHECK(node))->symbol_binding)
! #define I_SYMBOL_DECL(node) \
!  (I_SYMBOL_BINDING(node) ? I_SYMBOL_BINDING(node)->decl : 0)
! 
! #define I_TAG_BINDING(node) \
!   (((struct lang_identifier *)IDENTIFIER_NODE_CHECK(node))->tag_binding)
! #define I_TAG_DECL(node) \
!  (I_TAG_BINDING(node) ? I_TAG_BINDING(node)->decl : 0)
! 
! #define I_LABEL_BINDING(node) \
!   (((struct lang_identifier *)IDENTIFIER_NODE_CHECK(node))->label_binding)
! #define I_LABEL_DECL(node) \
!  (I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)
! 
! /* Each c_scope structure describes the complete contents of one
!    scope.  Four scopes are distinguished specially: the innermost or
!    current scope, the innermost function scope, the file scope (always
!    the second to outermost) and the outermost or external scope.
  
     Most declarations are recorded in the current scope.
  
*************** static int current_extern_inline;
*** 179,196 ****
     hence the 'innermost' qualifier.)  Explicitly declared labels
     (using the __label__ extension) appear in the current scope.
  
!    Being in the global scope (current_scope == global_scope) causes
     special behavior in several places below.  Also, under some
     conditions the Objective-C front end records declarations in the
!    global scope even though that isn't the current scope.
  
!    The order of the names, parms, and blocks lists matters, and they
!    are frequently appended to.  To avoid having to walk all the way to
!    the end of the list on each insertion, or reverse the lists later,
!    we maintain a pointer to the last list entry for each of the lists.
  
-    The order of the tags, shadowed, and shadowed_tags
-    lists does not matter, so we just prepend to these lists.  */
  
  struct c_scope GTY(())
  {
--- 198,234 ----
     hence the 'innermost' qualifier.)  Explicitly declared labels
     (using the __label__ extension) appear in the current scope.
  
!    Being in the file scope (current_scope == file_scope) causes
     special behavior in several places below.  Also, under some
     conditions the Objective-C front end records declarations in the
!    file scope even though that isn't the current scope.
  
!    All declarations with external linkage are recorded in the external
!    scope, even if they aren't visible there; this models the fact that
!    such declarations are visible to the entire program, and (with a
!    bit of cleverness, see pushdecl) allows diagnosis of some violations
!    of C99 6.2.2p7 and 6.2.7p2:
! 
!      If, within the same translation unit, the same identifier appears
!      with both internal and external linkage, the behavior is
!      undefined.
! 
!      All declarations that refer to the same object or function shall
!      have compatible type; otherwise, the behavior is undefined.
! 
!    Initially only the built-in declarations, which describe compiler
!    intrinsic functions plus a subset of the standard library, are in
!    this scope.
! 
!    The order of the blocks list matters, and it is frequently appended
!    to.  To avoid having to walk all the way to the end of the list on
!    each insertion, or reverse the list later, we maintain a pointer to
!    the last list entry.  (FIXME: It should be feasible to use a reversed
!    list here.)
! 
!    The bindings list is strictly in reverse order of declarations;
!    pop_scope relies on this.  */
  
  
  struct c_scope GTY(())
  {
*************** struct c_scope GTY(())
*** 200,234 ****
    /* The next outermost function scope.  */
    struct c_scope *outer_function;
  
!   /* All variables, constants, functions, labels, and typedef names.  */
!   tree names;
!   tree names_last;
! 
!   /* All parameter declarations.  Used only in the outermost scope of
!      a function.  */
!   tree parms;
!   tree parms_last;
! 
!   /* All structure, union, and enum type tags.  */
!   tree tags;
! 
!   /* For each scope, a list of shadowed outer-scope definitions
!      to be restored when this scope is popped.
!      Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and
!      whose TREE_VALUE is its old definition (a kind of ..._DECL node).  */
!   tree shadowed;
! 
!   /* For each scope, a list of shadowed outer-scope tag definitions
!      to be restored when this scope is popped.
!      Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and
!      whose TREE_VALUE is its old definition (a kind of ..._TYPE node).  */
!   tree shadowed_tags;
  
    /* For each scope (except the global one), a chain of BLOCK nodes
       for all the scopes that were entered and exited one level down.  */
    tree blocks;
    tree blocks_last;
  
    /* True if we are currently filling this scope with parameter
       declarations.  */
    BOOL_BITFIELD parm_flag : 1;
--- 238,255 ----
    /* The next outermost function scope.  */
    struct c_scope *outer_function;
  
!   /* All bindings in this scope.  */
!   struct c_binding *bindings;
  
    /* For each scope (except the global one), a chain of BLOCK nodes
       for all the scopes that were entered and exited one level down.  */
    tree blocks;
    tree blocks_last;
  
+   /* The depth of this scope.  Used to keep the ->shadowed chain of
+      bindings sorted innermost to outermost.  */
+   unsigned int depth : 28;
+ 
    /* True if we are currently filling this scope with parameter
       declarations.  */
    BOOL_BITFIELD parm_flag : 1;
*************** struct c_scope GTY(())
*** 252,271 ****
  
  static GTY(()) struct c_scope *current_scope;
  
- /* A chain of c_scope structures awaiting reuse.  */
- 
- static GTY((deletable (""))) struct c_scope *scope_freelist;
- 
  /* The innermost function scope.  Ordinary (not explicitly declared)
     labels, bindings to error_mark_node, and the lazily-created
     bindings of __func__ and its friends get this scope.  */
  
  static GTY(()) struct c_scope *current_function_scope;
  
! /* The outermost scope, corresponding to the C "file scope".  This is
!    created when the compiler is started and exists through the entire run.  
*/
  
! static GTY(()) struct c_scope *global_scope;
  
  /* Append VAR to LIST in scope SCOPE.  */
  #define SCOPE_LIST_APPEND(scope, list, decl) do {	\
--- 273,300 ----
  
  static GTY(()) struct c_scope *current_scope;
  
  /* The innermost function scope.  Ordinary (not explicitly declared)
     labels, bindings to error_mark_node, and the lazily-created
     bindings of __func__ and its friends get this scope.  */
  
  static GTY(()) struct c_scope *current_function_scope;
  
! /* The C file scope.  This is reset for each input translation unit.  */
! 
! static GTY(()) struct c_scope *file_scope;
! 
! /* The outermost scope.  This is used for all declarations with
!    external linkage, and only these, hence the name.  */
! 
! static GTY(()) struct c_scope *external_scope;
! 
! /* A chain of c_scope structures awaiting reuse.  */
! 
! static GTY((deletable (""))) struct c_scope *scope_freelist;
! 
! /* A chain of c_binding structures awaiting reuse.  */
  
! static GTY((deletable (""))) struct c_binding *binding_freelist;
  
  /* Append VAR to LIST in scope SCOPE.  */
  #define SCOPE_LIST_APPEND(scope, list, decl) do {	\
*************** static GTY(()) struct c_scope *global_sc
*** 293,299 ****
  
  static bool keep_next_level_flag;
  
! /* True means the next call to pushlevel will be the outermost scope
     of a function body, so do not push a new scope, merely cease
     expecting parameter decls.  */
  
--- 322,328 ----
  
  static bool keep_next_level_flag;
  
! /* True means the next call to push_scope will be the outermost scope
     of a function body, so do not push a new scope, merely cease
     expecting parameter decls.  */
  
*************** static bool next_is_function_body;
*** 304,332 ****
  tree static_ctors, static_dtors;
  
  /* Forward declarations.  */
! 
! static struct c_scope *make_scope (void);
! static void pop_scope (void);
! static tree make_label (tree, location_t);
! static void bind_label (tree, tree, struct c_scope *);
! static void implicit_decl_warning (tree);
! static tree lookup_tag (enum tree_code, tree, int);
! static tree lookup_name_current_level (tree);
  static tree grokdeclarator (tree, tree, enum decl_context, int, tree *);
  static tree grokparms (tree, int);
  static void layout_array_type (tree);
- static void store_parm_decls_newstyle (void);
- static void store_parm_decls_oldstyle (void);
- static tree c_make_fname_decl (tree, int);
- static void c_expand_body_1 (tree, int);
- static tree any_external_decl (tree);
- static void record_external_decl (tree);
- static void warn_if_shadowing (tree, tree);
- static void check_bitfield_type_and_width (tree *, tree *, const char *);
- static void clone_underlying_type (tree);
- static bool flexible_array_type_p (tree);
- static hashval_t link_hash_hash	(const void *);
- static int link_hash_eq (const void *, const void *);
  
  /* States indicating how grokdeclarator() should handle declspecs marked
     with __attribute__((deprecated)).  An object declared as
--- 333,343 ----
  tree static_ctors, static_dtors;
  
  /* Forward declarations.  */
! static tree lookup_name_in_scope (tree, struct c_scope *);
! static tree c_make_fname_decl (tree, int);
  static tree grokdeclarator (tree, tree, enum decl_context, int, tree *);
  static tree grokparms (tree, int);
  static void layout_array_type (tree);
  
  /* States indicating how grokdeclarator() should handle declspecs marked
     with __attribute__((deprecated)).  An object declared as
*************** static enum deprecated_states deprecated
*** 343,351 ****
  void
  c_print_identifier (FILE *file, tree node, int indent)
  {
!   print_node (file, "symbol", IDENTIFIER_SYMBOL_VALUE (node), indent + 4);
!   print_node (file, "tag", IDENTIFIER_TAG_VALUE (node), indent + 4);
!   print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
    if (C_IS_RESERVED_WORD (node))
      {
        tree rid = ridpointers[C_RID_CODE (node)];
--- 354,362 ----
  void
  c_print_identifier (FILE *file, tree node, int indent)
  {
!   print_node (file, "symbol", I_SYMBOL_DECL (node), indent + 4);
!   print_node (file, "tag", I_TAG_DECL (node), indent + 4);
!   print_node (file, "label", I_LABEL_DECL (node), indent + 4);
    if (C_IS_RESERVED_WORD (node))
      {
        tree rid = ridpointers[C_RID_CODE (node)];
*************** c_print_identifier (FILE *file, tree nod
*** 354,359 ****
--- 365,444 ----
  	       (void *) rid, IDENTIFIER_POINTER (rid));
      }
  }
+ 
+ /* Establish a binding between NAME, an IDENTIFIER_NODE, and DECL,
+    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)
+ {
+   struct c_binding *b, **here;
+ 
+   if (binding_freelist)
+     {
+       b = binding_freelist;
+       binding_freelist = b->prev;
+     }
+   else
+     b = ggc_alloc (sizeof (struct c_binding));
+ 
+   b->shadowed = 0;
+   b->decl = decl;
+   b->id = name;
+   b->contour = scope;
+ 
+   b->prev = scope->bindings;
+   scope->bindings = b;
+ 
+   if (!name)
+     return;
+ 
+   switch (TREE_CODE (decl))
+     {
+     case LABEL_DECL:     here = &I_LABEL_BINDING (name);   break;
+     case ENUMERAL_TYPE:
+     case UNION_TYPE:
+     case RECORD_TYPE:    here = &I_TAG_BINDING (name);     break;
+     case VAR_DECL:
+     case FUNCTION_DECL:
+     case TYPE_DECL:
+     case CONST_DECL:
+     case PARM_DECL:
+     case ERROR_MARK:     here = &I_SYMBOL_BINDING (name);  break;
+ 
+     default:
+       abort ();
+     }
+ 
+   /* 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)
+     here = &(*here)->shadowed;
+ 
+   b->shadowed = *here;
+   *here = b;
+ }
+ 
+ /* Clear the binding structure B, stick it on the binding_freelist,
+    and return the former value of b->prev.  This is used by pop_scope
+    and get_parm_info to iterate destructively over all the bindings
+    from a given scope.  */
+ static struct c_binding *
+ 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;
+   b->prev = binding_freelist;
+   binding_freelist = b;
+ 
+   return prev;
+ }
+ 
  
  /* Hook called at end of compilation to assume 1 elt
     for a file-scope tentative array defn that wasn't complete before.  */
*************** c_finish_incomplete_decl (tree decl)
*** 378,417 ****
      }
  }
  
- /* Reuse or create a struct for this scope.  */
- 
- static struct c_scope *
- make_scope (void)
- {
-   struct c_scope *result;
-   if (scope_freelist)
-     {
-       result = scope_freelist;
-       scope_freelist = result->outer;
-     }
-   else
-     result = ggc_alloc_cleared (sizeof (struct c_scope));
- 
-   return result;
- }
- 
- /* Remove the topmost scope from the stack and add it to the
-    free list, updating current_function_scope if necessary.  */
- 
- static void
- pop_scope (void)
- {
-   struct c_scope *scope = current_scope;
- 
-   current_scope = scope->outer;
-   if (scope->function_body)
-     current_function_scope = scope->outer_function;
- 
-   memset (scope, 0, sizeof (struct c_scope));
-   scope->outer = scope_freelist;
-   scope_freelist = scope;
- }
- 
  /* The Objective-C front-end often needs to determine the current scope.  */
  
  void *
--- 463,468 ----
*************** void
*** 427,456 ****
  objc_mark_locals_volatile (void *enclosing_blk)
  {
    struct c_scope *scope;
  
    for (scope = current_scope;
         scope && scope != enclosing_blk;
         scope = scope->outer)
      {
!       tree decl;
! 
!       for (decl = scope->names; decl; decl = TREE_CHAIN (decl))
  	{
! 	  DECL_REGISTER (decl) = 0;
! 	  TREE_THIS_VOLATILE (decl) = 1;
  	}
        /* Do not climb up past the current function.  */
        if (scope->function_body)
  	break;
      }
  }
  
! /* Nonzero if we are currently in the global scope.  */
  
  int
  global_bindings_p (void)
  {
!   return current_scope == global_scope;
  }
  
  void
--- 478,511 ----
  objc_mark_locals_volatile (void *enclosing_blk)
  {
    struct c_scope *scope;
+   struct c_binding *b;
  
    for (scope = current_scope;
         scope && scope != enclosing_blk;
         scope = scope->outer)
      {
!       for (b = scope->bindings; b; b = b->prev)
  	{
! 	  if (TREE_CODE (b->decl) == VAR_DECL
! 	      || TREE_CODE (b->decl) == PARM_DECL)
! 	    {
! 	      DECL_REGISTER (b->decl) = 0;
! 	      TREE_THIS_VOLATILE (b->decl) = 1;
! 	    }
  	}
+ 
        /* Do not climb up past the current function.  */
        if (scope->function_body)
  	break;
      }
  }
  
! /* Nonzero if we are currently in file scope.  */
  
  int
  global_bindings_p (void)
  {
!   return current_scope == file_scope && !c_override_global_bindings_to_false;
  }
  
  void
*************** declare_parm_level (void)
*** 467,485 ****
    current_scope->parm_flag = true;
  }
  
- /* Nonzero if currently making parm declarations.  */
- 
- int
- in_parm_level_p (void)
- {
-   return current_scope->parm_flag;
- }
- 
- /* Enter a new scope.  The dummy parameter is for signature
-    compatibility with lang_hooks.decls.pushlevel.  */
- 
  void
! pushlevel (int dummy ATTRIBUTE_UNUSED)
  {
    if (next_is_function_body)
      {
--- 522,529 ----
    current_scope->parm_flag = true;
  }
  
  void
! push_scope (void)
  {
    if (next_is_function_body)
      {
*************** pushlevel (int dummy ATTRIBUTE_UNUSED)
*** 504,552 ****
      }
    else
      {
!       struct c_scope *scope = make_scope ();
  
        scope->keep          = keep_next_level_flag;
        scope->outer         = current_scope;
        current_scope        = scope;
        keep_next_level_flag = false;
      }
  }
  
  /* Exit a scope.  Restore the state of the identifier-decl mappings
!    that were in effect when this scope was entered.
! 
!    If KEEP is KEEP_YES (1), this scope had explicit declarations, so
!    create a BLOCK node to record its declarations and subblocks for
!    debugging output.  If KEEP is KEEP_MAYBE, do so only if the names
!    or tags lists are nonempty.
! 
!    The second parameter is ignored; it is present only for
!    signature compatibility with lang_hooks.decls.poplevel.
! 
!    If FUNCTIONBODY is nonzero, this level is the body of a function,
!    even if current_scope->function_body is not set.  This is used
!    by language-independent code that generates synthetic functions,
!    and cannot set current_scope->function_body.
! 
!    FIXME: Eliminate the need for all arguments.  */
  
  tree
! poplevel (int keep, int dummy ATTRIBUTE_UNUSED, int functionbody)
  {
    struct c_scope *scope = current_scope;
!   tree block;
!   tree decl;
!   tree p;
! 
!   /* The following line does not use |= due to a bug in HP's C compiler.  */
!   scope->function_body = scope->function_body | functionbody;
  
!   if (keep == KEEP_MAYBE)
!     keep = (scope->names || scope->tags);
! 
!   keep |= scope->keep;
!   keep |= scope->function_body;
  
    /* If appropriate, create a BLOCK to record the decls for the life
       of this function.  */
--- 548,593 ----
      }
    else
      {
!       struct c_scope *scope;
!       if (scope_freelist)
! 	{
! 	  scope = scope_freelist;
! 	  scope_freelist = scope->outer;
! 	}
!       else
! 	scope = ggc_alloc_cleared (sizeof (struct c_scope));
  
        scope->keep          = keep_next_level_flag;
        scope->outer         = current_scope;
+       scope->depth	   = current_scope ? (current_scope->depth + 1) : 0;
+ 
+       /* Check for scope depth overflow.  Unlikely (2^28 == 268,435,456) but
+ 	 possible.  */
+       if (current_scope && scope->depth == 0)
+ 	{
+ 	  scope->depth--;
+ 	  sorry ("GCC supports only %u nested scopes\n", scope->depth);
+ 	}
+       
        current_scope        = scope;
        keep_next_level_flag = false;
      }
  }
  
  /* 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
!    to debug info generation.  */
  
  tree
! pop_scope (void)
  {
    struct c_scope *scope = current_scope;
!   tree block, context, p;
!   struct c_binding *b;
  
!   bool functionbody = scope->function_body;
!   bool keep = functionbody || scope->keep || scope->bindings;
  
    /* If appropriate, create a BLOCK to record the decls for the life
       of this function.  */
*************** poplevel (int keep, int dummy ATTRIBUTE_
*** 554,581 ****
    if (keep)
      {
        block = make_node (BLOCK);
-       BLOCK_VARS (block) = scope->names;
        BLOCK_SUBBLOCKS (block) = scope->blocks;
        TREE_USED (block) = 1;
-     }
  
!   /* In each subblock, record that this is its superior.  */
!   for (p = scope->blocks; p; p = TREE_CHAIN (p))
!     BLOCK_SUPERCONTEXT (p) = block;
  
!   /* Clear out the variable bindings in this scope.
  
!      Propagate TREE_ADDRESSABLE from nested functions to their
!      containing functions.
  
!      Issue warnings for unused variables and labels, and errors for
!      undefined labels, if there are any.  */
  
!   for (p = scope->names; p; p = TREE_CHAIN (p))
      {
        switch (TREE_CODE (p))
  	{
  	case LABEL_DECL:
  	  if (TREE_USED (p) && !DECL_INITIAL (p))
  	    {
  	      error ("%Jlabel `%D' used but not defined", p, p);
--- 595,638 ----
    if (keep)
      {
        block = make_node (BLOCK);
        BLOCK_SUBBLOCKS (block) = scope->blocks;
        TREE_USED (block) = 1;
  
!       /* In each subblock, record that this is its superior.  */
!       for (p = scope->blocks; p; p = TREE_CHAIN (p))
! 	BLOCK_SUPERCONTEXT (p) = block;
  
!       BLOCK_VARS (block) = 0;
!     }
  
!   /* The TYPE_CONTEXTs for all of the tagged types belonging to this
!      scope must be set so that they point to the appropriate
!      construct, i.e.  either to the current FUNCTION_DECL node, or
!      else to the BLOCK node we just constructed.
  
!      Note that for tagged types whose scope is just the formal
!      parameter list for some function type specification, we can't
!      properly set their TYPE_CONTEXTs here, because we don't have a
!      pointer to the appropriate FUNCTION_TYPE node readily available
!      to us.  For those cases, the TYPE_CONTEXTs of the relevant tagged
!      type nodes get set in `grokdeclarator' as soon as we have created
!      the FUNCTION_TYPE node which will represent the "scope" for these
!      "parameter list local" tagged types.  */
!   if (scope->function_body)
!     context = current_function_decl;
!   else if (scope == file_scope)
!     context = current_file_decl;
!   else
!     context = block;
  
!   /* Clear all bindings in this scope.  */
!   for (b = scope->bindings; b; b = free_binding_and_advance (b))
      {
+       p = b->decl;
        switch (TREE_CODE (p))
  	{
  	case LABEL_DECL:
+ 	  /* Warnings for unused labels, errors for undefined labels.  */
  	  if (TREE_USED (p) && !DECL_INITIAL (p))
  	    {
  	      error ("%Jlabel `%D' used but not defined", p, p);
*************** poplevel (int keep, int dummy ATTRIBUTE_
*** 588,681 ****
  	      else
  		warning ("%Jlabel `%D' declared but not defined", p, p);
  	    }
  
! 	  IDENTIFIER_LABEL_VALUE (DECL_NAME (p)) = 0;
! 	  break;
  
  	case FUNCTION_DECL:
  	  if (! TREE_ASM_WRITTEN (p)
  	      && DECL_INITIAL (p) != 0
  	      && TREE_ADDRESSABLE (p)
  	      && DECL_ABSTRACT_ORIGIN (p) != 0
  	      && DECL_ABSTRACT_ORIGIN (p) != p)
  	    TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (p)) = 1;
! 	  goto normal;
  
  	case VAR_DECL:
! 	  /* Keep this in sync with stmt.c:warn_about_unused_variables.
! 	     No warnings when the global scope is popped because the
! 	     global scope isn't popped for the last translation unit,
! 	     so the warnings are done in c_write_global_declaration.  */
! 	  if (warn_unused_variable && scope != global_scope
  	      && !TREE_USED (p)
  	      && !DECL_IN_SYSTEM_HEADER (p)
  	      && DECL_NAME (p)
! 	      && !DECL_ARTIFICIAL (p))
  	    warning ("%Junused variable `%D'", p, p);
  	  /* Fall through.  */
  
! 	default:
! 	normal:
! 	  if (DECL_NAME (p))
  	    {
! 	      if (DECL_EXTERNAL (p) && scope != global_scope)
! 		/* External decls stay in the symbol-value slot but are
! 		   inaccessible.  */
! 		C_DECL_INVISIBLE (p) = 1;
! 	      else
! 		IDENTIFIER_SYMBOL_VALUE (DECL_NAME (p)) = 0;
  	    }
  	  break;
  	}
      }
  
!   /* Clear out the parameter bindings in this scope, if any.
!      Unused-parameter warnings are handled by function.c.  */
!   for (p = scope->parms; p; p = TREE_CHAIN (p))
!     if (DECL_NAME (p))
!       IDENTIFIER_SYMBOL_VALUE (DECL_NAME (p)) = 0;
! 
!   /* Clear out the tag-meanings declared in this scope.
! 
!      Set the TYPE_CONTEXTs for all of the tagged types belonging to
!      this scope so that they point to the appropriate construct, i.e.
!      either to the current FUNCTION_DECL node, or else to the BLOCK
!      node we just constructed.
! 
!      Note that for tagged types whose scope is just the formal
!      parameter list for some function type specification, we can't
!      properly set their TYPE_CONTEXTs here, because we don't have a
!      pointer to the appropriate FUNCTION_TYPE node readily available
!      to us.  For those cases, the TYPE_CONTEXTs of the relevant tagged
!      type nodes get set in `grokdeclarator' as soon as we have created
!      the FUNCTION_TYPE node which will represent the "scope" for these
!      "parameter list local" tagged types.  */
! 
!   decl = scope->function_body ? current_function_decl : block;
!   for (p = scope->tags; p; p = TREE_CHAIN (p))
      {
!       if (TREE_PURPOSE (p))
! 	IDENTIFIER_TAG_VALUE (TREE_PURPOSE (p)) = 0;
!       if (decl)
! 	TYPE_CONTEXT (TREE_VALUE (p)) = decl;
      }
- 
-   /* Restore all name- and label-meanings from outer scopes that were
-      shadowed by this scope.  */
-   for (p = scope->shadowed; p; p = TREE_CHAIN (p))
-     if (TREE_VALUE (p) && TREE_CODE (TREE_VALUE (p)) == LABEL_DECL)
-       IDENTIFIER_LABEL_VALUE (TREE_PURPOSE (p)) = TREE_VALUE (p);
-     else
-       IDENTIFIER_SYMBOL_VALUE (TREE_PURPOSE (p)) = TREE_VALUE (p);
- 
-   /* Restore all tag-meanings from outer scopes that were shadowed by
-      this scope.  */
-   for (p = scope->shadowed_tags; p; p = TREE_CHAIN (p))
-     IDENTIFIER_TAG_VALUE (TREE_PURPOSE (p)) = TREE_VALUE (p);
- 
-   /* Dispose of the block that we just made inside some higher level.  */
-   if (scope->function_body && current_function_decl)
-     DECL_INITIAL (current_function_decl) = block;
    else if (scope->outer)
      {
        if (block)
--- 645,745 ----
  	      else
  		warning ("%Jlabel `%D' declared but not defined", p, p);
  	    }
+ 	  /* 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
+  	  I_LABEL_BINDING (b->id) = b->shadowed;
+  	  break;
  
! 	case ENUMERAL_TYPE:
! 	case UNION_TYPE:
! 	case RECORD_TYPE:
! 	  TYPE_CONTEXT (p) = context;
! 
! 	  /* Types may not have tag-names, in which case the type
! 	     appears in the bindings list with b->id NULL.  */
! 	  if (b->id)
! 	    {
! #ifdef ENABLE_CHECKING
! 	      if (I_TAG_BINDING (b->id) != b) abort ();
! #endif
! 	      I_TAG_BINDING (b->id) = b->shadowed;
! 	    }
!   	  break;
  
  	case FUNCTION_DECL:
+ 	  /* Propagate TREE_ADDRESSABLE from nested functions to their
+ 	     containing functions.  */
  	  if (! TREE_ASM_WRITTEN (p)
  	      && DECL_INITIAL (p) != 0
  	      && TREE_ADDRESSABLE (p)
  	      && DECL_ABSTRACT_ORIGIN (p) != 0
  	      && DECL_ABSTRACT_ORIGIN (p) != p)
  	    TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (p)) = 1;
! 	  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.  */
! 	  if (warn_unused_variable
  	      && !TREE_USED (p)
  	      && !DECL_IN_SYSTEM_HEADER (p)
  	      && DECL_NAME (p)
! 	      && !DECL_ARTIFICIAL (p)
! 	      && (scope != file_scope
! 		  || (TREE_STATIC (p) && !TREE_PUBLIC (p)
! 		      && !TREE_THIS_VOLATILE (p)))
! 	      && scope != external_scope)
  	    warning ("%Junused variable `%D'", p, p);
+ 
  	  /* Fall through.  */
+ 	case TYPE_DECL:
+ 	case CONST_DECL:
+ 	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)
+ 	    {
+ 	      TREE_CHAIN (p) = BLOCK_VARS (block);
+ 	      BLOCK_VARS (block) = p;
+ 	    }
  
! 	  /* Fall through.  */
! 	  /* Parameters go in DECL_ARGUMENTS, not BLOCK_VARS, and have
! 	     already been put there by store_parm_decls.  Unused-
! 	     parameter warnings are handled by function.c.
! 	     error_mark_node obviously does not go in BLOCK_VARS and
! 	     does not get unused-variable warnings.  */
! 	case PARM_DECL:
! 	case ERROR_MARK:
! 	  /* It is possible for a decl not to have a name.  We get
! 	     here with b->id NULL in this case.  */
! 	  if (b->id)
  	    {
! #ifdef ENABLE_CHECKING
! 	      if (I_SYMBOL_BINDING (b->id) != b) abort ();
! #endif
! 	      I_SYMBOL_BINDING (b->id) = b->shadowed;
  	    }
  	  break;
+ 
+ 	default:
+ 	  abort ();
  	}
      }
  
!   
!   /* Dispose of the block that we just made inside some higher level.  */
!   if ((scope->function_body || scope == file_scope) && context)
      {
!       DECL_INITIAL (context) = block;
!       BLOCK_SUPERCONTEXT (block) = context;
      }
    else if (scope->outer)
      {
        if (block)
*************** poplevel (int keep, int dummy ATTRIBUTE_
*** 688,698 ****
      }
  
    /* Pop the current scope, and free the structure for reuse.  */
!   pop_scope ();
  
    return block;
  }
  
  /* Insert BLOCK at the end of the list of subblocks of the current
     scope.  This is used when a BIND_EXPR is expanded, to handle the
     BLOCK node inside the BIND_EXPR.  */
--- 752,811 ----
      }
  
    /* Pop the current scope, and free the structure for reuse.  */
!   current_scope = scope->outer;
!   if (scope->function_body)
!     current_function_scope = scope->outer_function;
! 
!   memset (scope, 0, sizeof (struct c_scope));
!   scope->outer = scope_freelist;
!   scope_freelist = scope;
  
    return block;
  }
  
+ void
+ push_file_scope (void)
+ {
+   tree decl;
+   tree file_decl = build_decl (TRANSLATION_UNIT_DECL, 0, 0);
+   TREE_CHAIN (file_decl) = current_file_decl;
+   current_file_decl = file_decl;
+ 
+   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);
+ }
+ 
+ void
+ pop_file_scope (void)
+ {
+   /* In case there were missing closebraces, get us back to the global
+      binding level.  */
+   while (current_scope != file_scope)
+     pop_scope ();
+ 
+   /* __FUNCTION__ is defined at file scope ("").  This
+      call may not be necessary as my tests indicate it
+      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.  */
+   if (pch_file)
+     return;
+ 
+   /* And pop off the file scope.  */
+   pop_scope ();
+   file_scope = 0;
+ 
+   cpp_undef_all (parse_in);
+ }
+ 
  /* Insert BLOCK at the end of the list of subblocks of the current
     scope.  This is used when a BIND_EXPR is expanded, to handle the
     BLOCK node inside the BIND_EXPR.  */
*************** insert_block (tree block)
*** 703,717 ****
    TREE_USED (block) = 1;
    SCOPE_LIST_APPEND (current_scope, blocks, block);
  }
- 
- /* Set the BLOCK node for the innermost scope (the one we are
-    currently in).  The RTL expansion machinery requires us to provide
-    this hook, but it is not useful in function-at-a-time mode.  */
- 
- void
- set_block (tree block ATTRIBUTE_UNUSED)
- {
- }
  
  /* Push a definition or a declaration of struct, union or enum tag "name".
     "type" should be the type node.
--- 816,821 ----
*************** set_block (tree block ATTRIBUTE_UNUSED)
*** 720,743 ****
     Note that the definition may really be just a forward reference.
     In that case, the TYPE_SIZE will be zero.  */
  
! void
  pushtag (tree name, tree type)
  {
-   struct c_scope *b = current_scope;
- 
    /* Record the identifier as the type's name if it has none.  */
!   if (name)
!     {
!       if (TYPE_NAME (type) == 0)
! 	TYPE_NAME (type) = name;
! 
!       if (IDENTIFIER_TAG_VALUE (name))
! 	b->shadowed_tags = tree_cons (name, IDENTIFIER_TAG_VALUE (name),
! 				      b->shadowed_tags);
!       IDENTIFIER_TAG_VALUE (name) = type;
!     }
! 
!   b->tags = tree_cons (name, type, b->tags);
  
    /* 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
--- 824,836 ----
     Note that the definition may really be just a forward reference.
     In that case, the TYPE_SIZE will be zero.  */
  
! static void
  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);
  
    /* 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
*************** pushtag (tree name, tree type)
*** 749,755 ****
    TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, type));
  
    /* An approximation for now, so we can tell this is a function-scope tag.
!      This will be updated in poplevel.  */
    TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_STUB_DECL (type));
  }
  
--- 842,848 ----
    TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, type));
  
    /* An approximation for now, so we can tell this is a function-scope tag.
!      This will be updated in pop_scope.  */
    TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_STUB_DECL (type));
  }
  
*************** diagnose_mismatched_decls (tree newdecl,
*** 940,947 ****
       unless OLDDECL is a builtin.  OLDDECL will be discarded in any case.  */
    if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
      {
!       if (TREE_CODE (olddecl) != FUNCTION_DECL
!           || !DECL_BUILT_IN (olddecl) || !C_DECL_INVISIBLE (olddecl))
  	{
  	  error ("%J'%D' redeclared as different kind of symbol",
  		 newdecl, newdecl);
--- 1033,1041 ----
       unless OLDDECL is a builtin.  OLDDECL will be discarded in any case.  */
    if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
      {
!       if (!(TREE_CODE (olddecl) == FUNCTION_DECL
! 	    && DECL_BUILT_IN (olddecl)
! 	    && !C_DECL_DECLARED_BUILTIN (olddecl)))
  	{
  	  error ("%J'%D' redeclared as different kind of symbol",
  		 newdecl, newdecl);
*************** diagnose_mismatched_decls (tree newdecl,
*** 951,957 ****
  	warning ("%Jbuilt-in function '%D' declared as non-function",
  		 newdecl, newdecl);
        else if (warn_shadow)
! 	warning ("%Jshadowing built-in function '%D'",
  		 newdecl, newdecl);
        return false;
      }
--- 1045,1051 ----
  	warning ("%Jbuilt-in function '%D' declared as non-function",
  		 newdecl, newdecl);
        else if (warn_shadow)
! 	warning ("%Jdeclaration of '%D' shadows a built-in function",
  		 newdecl, newdecl);
        return false;
      }
*************** diagnose_mismatched_decls (tree newdecl,
*** 959,965 ****
    if (!comptypes (oldtype, newtype, COMPARE_STRICT))
      {
        if (TREE_CODE (olddecl) == FUNCTION_DECL
! 	  && DECL_BUILT_IN (olddecl) && C_DECL_INVISIBLE (olddecl))
  	{
  	  /* Accept harmless mismatch in function types.
  	     This is for the ffs and fprintf builtins.  */
--- 1053,1059 ----
    if (!comptypes (oldtype, newtype, COMPARE_STRICT))
      {
        if (TREE_CODE (olddecl) == FUNCTION_DECL
! 	  && DECL_BUILT_IN (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl))
  	{
  	  /* Accept harmless mismatch in function types.
  	     This is for the ffs and fprintf builtins.  */
*************** diagnose_mismatched_decls (tree newdecl,
*** 1037,1049 ****
  	 can't validate the argument list) the built-in definition is
  	 overridden, but optionally warn this was a bad choice of name.  */
        if (DECL_BUILT_IN (olddecl)
! 	  && C_DECL_INVISIBLE (olddecl)
  	  && (!TREE_PUBLIC (newdecl)
  	      || (DECL_INITIAL (newdecl)
  		  && !TYPE_ARG_TYPES (TREE_TYPE (newdecl)))))
  	{
  	  if (warn_shadow)
! 	    warning ("%Jshadowing built-in function '%D'", newdecl, newdecl);
  	  /* Discard the old built-in function.  */
  	  return false;
  	}
--- 1131,1144 ----
  	 can't validate the argument list) the built-in definition is
  	 overridden, but optionally warn this was a bad choice of name.  */
        if (DECL_BUILT_IN (olddecl)
! 	  && !C_DECL_DECLARED_BUILTIN (olddecl)
  	  && (!TREE_PUBLIC (newdecl)
  	      || (DECL_INITIAL (newdecl)
  		  && !TYPE_ARG_TYPES (TREE_TYPE (newdecl)))))
  	{
  	  if (warn_shadow)
! 	    warning ("%Jdeclaration of '%D' shadows a built-in function",
! 		     newdecl, newdecl);
  	  /* Discard the old built-in function.  */
  	  return false;
  	}
*************** diagnose_mismatched_decls (tree newdecl,
*** 1214,1221 ****
      }
    else /* PARM_DECL, VAR_DECL */
      {
!       /* Redeclaration of a PARM_DECL is invalid unless this is the
! 	 real position of a forward-declared parameter (GCC extension).  */
        if (TREE_CODE (newdecl) == PARM_DECL
  	  && (!TREE_ASM_WRITTEN (olddecl) || TREE_ASM_WRITTEN (newdecl)))
  	{
--- 1309,1323 ----
      }
    else /* PARM_DECL, VAR_DECL */
      {
!       /* Redeclaration of a parameter is a constraint violation (this is
! 	 not explicitly stated, but follows from C99 6.7p3 [no more than
! 	 one declaration of the same identifier with no linkage in the
! 	 same scope, except type tags] and 6.2.2p6 [parameters have no
! 	 linkage]).  We must check for a forward parameter declaration,
! 	 indicated by TREE_ASM_WRITTEN on the old declaration - this is
! 	 an extension, the mandatory diagnostic for which is handled by
! 	 mark_forward_parm_decls.  */
! 
        if (TREE_CODE (newdecl) == PARM_DECL
  	  && (!TREE_ASM_WRITTEN (olddecl) || TREE_ASM_WRITTEN (newdecl)))
  	{
*************** merge_decls (tree newdecl, tree olddecl,
*** 1282,1298 ****
    int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
  			   && DECL_INITIAL (newdecl) != 0);
  
!   /* For real parm decl following a forward decl, return 1 so old decl
!      will be reused.  Only allow this to happen once.  */
    if (TREE_CODE (newdecl) == PARM_DECL
        && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
      {
        TREE_ASM_WRITTEN (olddecl) = 0;
-       return;
      }
  
    DECL_ATTRIBUTES (newdecl)
!     = (*targetm.merge_decl_attributes) (olddecl, newdecl);
  
    /* Merge the data types specified in the two decls.  */
    TREE_TYPE (newdecl)
--- 1384,1413 ----
    int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
  			   && DECL_INITIAL (newdecl) != 0);
  
!   /* For real parm decl following a forward decl, rechain the old decl
!      in its new location and clear TREE_ASM_WRITTEN (it's not a
!      forward decl anymore).  */
    if (TREE_CODE (newdecl) == PARM_DECL
        && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
      {
+       struct c_binding *b, **here;
+ 
+       for (here = &current_scope->bindings; *here; here = &(*here)->prev)
+ 	if ((*here)->decl == olddecl)
+ 	  goto found;
+       abort ();
+ 
+     found:
+       b = *here;
+       *here = b->prev;
+       b->prev = current_scope->bindings;
+       current_scope->bindings = b;
+ 
        TREE_ASM_WRITTEN (olddecl) = 0;
      }
  
    DECL_ATTRIBUTES (newdecl)
!     = targetm.merge_decl_attributes (olddecl, newdecl);
  
    /* Merge the data types specified in the two decls.  */
    TREE_TYPE (newdecl)
*************** merge_decls (tree newdecl, tree olddecl,
*** 1445,1453 ****
  
        if (DECL_BUILT_IN (olddecl))
  	{
! 	  /* If redeclaring a builtin function, it stays built in.  */
  	  DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
  	  DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
  	}
  
        /* Also preserve various other info from the definition.  */
--- 1560,1570 ----
  
        if (DECL_BUILT_IN (olddecl))
  	{
! 	  /* If redeclaring a builtin function, it stays built in.
! 	     But it gets tagged as having been declared.  */
  	  DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
  	  DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
+ 	  C_DECL_DECLARED_BUILTIN (newdecl) = 1;
  	}
  
        /* Also preserve various other info from the definition.  */
*************** merge_decls (tree newdecl, tree olddecl,
*** 1478,1483 ****
--- 1595,1603 ----
  	}
      }
  
+   /* 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.  */
    {
*************** merge_decls (tree newdecl, tree olddecl,
*** 1509,1515 ****
  static bool
  duplicate_decls (tree newdecl, tree olddecl)
  {
!   tree newtype = NULL_TREE, oldtype = NULL_TREE;
  
    if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, &oldtype))
      return false;
--- 1629,1635 ----
  static bool
  duplicate_decls (tree newdecl, tree olddecl)
  {
!   tree newtype = NULL, oldtype = NULL;
  
    if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, &oldtype))
      return false;
*************** duplicate_decls (tree newdecl, tree oldd
*** 1519,1587 ****
  }
    
  
! /* Return any external DECL associated with ID, whether or not it is
!    currently in scope.  */
! 
! static tree
! any_external_decl (tree id)
! {
!   tree decl = IDENTIFIER_SYMBOL_VALUE (id);
!   tree t;
! 
!   if (decl == 0 || TREE_CODE (decl) == ERROR_MARK)
!     return 0;
!   else if (TREE_CODE (decl) != TYPE_DECL && DECL_EXTERNAL (decl))
!     return decl;
! 
!   t = purpose_member (id, truly_local_externals);
!   if (t)
!     return TREE_VALUE (t);
! 
!   return 0;
! }
! 
! /* Record an external decl DECL.  This only does something if a
!    shadowing decl already exists.  */
  static void
! record_external_decl (tree decl)
  {
!   tree name = DECL_NAME (decl);
!   if (!IDENTIFIER_SYMBOL_VALUE (name))
!     return;
  
!   truly_local_externals = tree_cons (name, decl, truly_local_externals);
! }
! 
! /* Check whether decl-node X shadows an existing declaration.
!    OLD is the old IDENTIFIER_SYMBOL_VALUE of the DECL_NAME of X,
!    which might be a NULL_TREE.  */
! static void
! warn_if_shadowing (tree x, tree old)
! {
!   /* Nothing to shadow?  */
!   if (old == 0
!       /* Shadow warnings not wanted?  */
!       || !warn_shadow
        /* No shadow warnings for internally generated vars.  */
!       || DECL_SOURCE_LINE (x) == 0
        /* No shadow warnings for vars made for inlining.  */
!       || DECL_FROM_INLINE (x)
        /* 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.  */
!       || (TREE_CODE (x) == PARM_DECL && current_scope->outer->parm_flag))
      return;
  
!   if (TREE_CODE (old) == PARM_DECL)
!     warning ("%Jdeclaration of '%D' shadows a parameter", x, x);
!   else if (DECL_FILE_SCOPE_P (old))
!     warning ("%Jdeclaration of '%D' shadows a global declaration", x, x);
!   else
!     warning ("%Jdeclaration of '%D' shadows a previous local", x, x);
  
!   warning ("%Jshadowed declaration is here", old);
  }
  
  
--- 1639,1687 ----
  }
    
  
! /* Check whether decl-node NEW shadows an existing declaration.  */
  static void
! warn_if_shadowing (tree new)
  {
!   struct c_binding *b;
  
!   /* Shadow warnings wanted?  */
!   if (!warn_shadow
        /* No shadow warnings for internally generated vars.  */
!       || DECL_SOURCE_LINE (new) == 0
        /* No shadow warnings for vars made for inlining.  */
!       || DECL_FROM_INLINE (new)
        /* 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))
      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)
!       {
! 	tree old = b->decl;
! 
! 	if (TREE_CODE (old) == PARM_DECL)
! 	  warning ("%Jdeclaration of '%D' shadows a parameter", new, new);
! 	else if (DECL_FILE_SCOPE_P (old))
! 	  warning ("%Jdeclaration of '%D' shadows a global declaration",
! 		   new, new);
! 	else if (TREE_CODE (old) == FUNCTION_DECL && DECL_BUILT_IN (old))
! 	  warning ("%Jdeclaration of '%D' shadows a built-in function",
! 		   new, new);
! 	else
! 	  warning ("%Jdeclaration of '%D' shadows a previous local", new, new);
  
! 	if (TREE_CODE (old) != FUNCTION_DECL || !DECL_BUILT_IN (old))
! 	  warning ("%Jshadowed declaration is here", old);
! 
! 	break;
!       }
  }
  
  
*************** pushdecl (tree x)
*** 1662,1673 ****
  {
    tree name = DECL_NAME (x);
    struct c_scope *scope = current_scope;
! 
! #ifdef ENABLE_CHECKING
!   if (error_mark_node == 0)
!     /* Called too early.  */
!     abort ();
! #endif
  
    /* Functions need the lang_decl data.  */
    if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x))
--- 1762,1768 ----
  {
    tree name = DECL_NAME (x);
    struct c_scope *scope = current_scope;
!   struct c_binding *b;
  
    /* Functions need the lang_decl data.  */
    if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x))
*************** pushdecl (tree x)
*** 1683,1793 ****
    else
      DECL_CONTEXT (x) = current_function_decl;
  
!   if (name)
      {
!       tree old;
  
        if (warn_nested_externs
! 	  && scope != global_scope
! 	  && DECL_EXTERNAL (x)
  	  && !DECL_IN_SYSTEM_HEADER (x))
  	warning ("nested extern declaration of `%s'",
  		 IDENTIFIER_POINTER (name));
  
!       old = lookup_name_current_level (name);
!       if (old && duplicate_decls (x, old))
! 	{
! 	  /* For PARM_DECLs, old may be a forward declaration.
! 	     If so, we want to remove it from its old location
! 	     (in the variables chain) and rechain it in the
! 	     location given by the new declaration.  */
! 	  if (TREE_CODE (x) == PARM_DECL)
! 	    {
! 	      tree *p;
! 	      for (p = &scope->names; *p; p = &TREE_CHAIN (*p))
! 		if (*p == old)
! 		  {
! 		    *p = TREE_CHAIN (old);
! 		    SCOPE_LIST_APPEND (scope, parms, old);
! 		    break;
! 		  }
! 	    }
! 	  return old;
! 	}
!       if (DECL_EXTERNAL (x) || scope == global_scope)
! 	{
! 	  /* Find and check against a previous, not-in-scope, external
! 	     decl for this identifier.  (C99 6.2.7p2: All declarations
! 	     that refer to the same object or function shall have
! 	     compatible type; otherwise, the behavior is undefined.)  */
!  	  tree ext = any_external_decl (name);
! 	  if (ext)
! 	    {
! 	      if (duplicate_decls (x, ext))
! 		x = copy_node (ext);
! 	    }
! 	  else
! 	    record_external_decl (x);
! 	}
! 
!       if (TREE_CODE (x) == TYPE_DECL)
! 	clone_underlying_type (x);
  
!       /* If storing a local value, there may already be one
! 	 (inherited).  If so, record it for restoration when this
! 	 scope ends.  Take care not to do this if we are replacing an
! 	 older decl in the same scope (i.e.  duplicate_decls returned
! 	 false, above).  */
!       if (scope != global_scope
! 	  && IDENTIFIER_SYMBOL_VALUE (name)
! 	  && IDENTIFIER_SYMBOL_VALUE (name) != old)
! 	{
! 	  warn_if_shadowing (x, IDENTIFIER_SYMBOL_VALUE (name));
! 	  scope->shadowed = tree_cons (name, IDENTIFIER_SYMBOL_VALUE (name),
! 				       scope->shadowed);
! 	}
! 
!       /* Install the new declaration in the requested scope.  */
!       IDENTIFIER_SYMBOL_VALUE (name) = x;
!       C_DECL_INVISIBLE (x) = 0;
! 
!       /* If x's type is incomplete because it's based on a
! 	 structure or union which has not yet been fully declared,
! 	 attach it to that structure or union type, so we can go
! 	 back and complete the variable declaration later, if the
! 	 structure or union gets fully declared.
! 
! 	 If the input is erroneous, we can have error_mark in the type
! 	 slot (e.g. "f(void a, ...)") - that doesn't count as an
! 	 incomplete type.  */
!       if (TREE_TYPE (x) != error_mark_node
! 	  && !COMPLETE_TYPE_P (TREE_TYPE (x)))
! 	{
! 	  tree element = TREE_TYPE (x);
! 
! 	  while (TREE_CODE (element) == ARRAY_TYPE)
! 	    element = TREE_TYPE (element);
! 	  element = TYPE_MAIN_VARIANT (element);
! 
! 	  if ((TREE_CODE (element) == RECORD_TYPE
! 	       || TREE_CODE (element) == UNION_TYPE)
! 	      && (TREE_CODE (x) != TYPE_DECL
! 		  || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
! 	      && !COMPLETE_TYPE_P (element))
! 	    C_TYPE_INCOMPLETE_VARS (element)
! 	      = tree_cons (NULL_TREE, x, C_TYPE_INCOMPLETE_VARS (element));
  	}
      }
  
!   if (TREE_CODE (x) == PARM_DECL)
!     SCOPE_LIST_APPEND (scope, parms, x);
!   else
!     SCOPE_LIST_APPEND (scope, names, x);
! 
    return x;
  }
  
! /* Record X as belonging to the global scope (C99 "file scope").
     This is used only internally by the Objective-C front end,
     and is limited to its needs.  duplicate_decls is not called;
     if there is any preexisting decl for this identifier, it is an ICE.  */
--- 1778,1887 ----
    else
      DECL_CONTEXT (x) = current_function_decl;
  
!   /* Anonymous decls are just inserted in the scope.  */
!   if (!name)
      {
!       bind (name, x, scope);
!       return x;
!     }
  
+   /* First, see if there is another declaration with the same name in
+      the current scope.  If there is, duplicate_decls may do all the
+      work for us.  If duplicate_decls returns false, that indicates
+      two incompatible decls in the same scope; we are to silently
+      replace the old one (duplicate_decls has issued all appropriate
+      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 (duplicate_decls (x, b->decl))
+ 	return b->decl;
+       else
+ 	goto skip_external_and_shadow_checks;
+     }
+ 
+   /* All declarations with external linkage, and all external
+      references, go in the external scope, no matter what scope is
+      current.  However, the binding in that scope is ignored for
+      purposes of normal name lookup.  A separate binding structure is
+      created in the requested scope; this governs the normal
+      visibility of the symbol.
+ 
+      The binding in the externals scope is used exclusively for
+      detecting duplicate declarations of the same object, no matter
+      what scope they are in; this is what we do here.  (C99 6.2.7p2:
+      All declarations that refer to the same object or function shall
+      have compatible type; otherwise, the behavior is undefined.)  */
+   if (DECL_EXTERNAL (x) || scope == file_scope)
+     {
        if (warn_nested_externs
! 	  && scope != file_scope
  	  && !DECL_IN_SYSTEM_HEADER (x))
  	warning ("nested extern declaration of `%s'",
  		 IDENTIFIER_POINTER (name));
  
!       while (b && b->contour != external_scope)
! 	b = b->shadowed;
  
!       /* The point of the same_translation_unit_p check here is,
! 	 we want to detect a duplicate decl for a construct like
! 	 foo() { extern bar(); } ... static bar();  but not if
! 	 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))
! 	  && duplicate_decls (x, b->decl))
! 	{
! 	  bind (name, b->decl, scope);
! 	  return b->decl;
! 	}
!       else if (DECL_EXTERNAL (x) || TREE_PUBLIC (x))
! 	{
! 	  C_DECL_IN_EXTERNAL_SCOPE (x) = 1;
! 	  bind (name, x, external_scope);
  	}
      }
  
!   warn_if_shadowing (x);
! 
!  skip_external_and_shadow_checks:
!   if (TREE_CODE (x) == TYPE_DECL)
!     clone_underlying_type (x);
! 
!   bind (name, x, scope);
! 
!   /* If x's type is incomplete because it's based on a
!      structure or union which has not yet been fully declared,
!      attach it to that structure or union type, so we can go
!      back and complete the variable declaration later, if the
!      structure or union gets fully declared.
! 
!      If the input is erroneous, we can have error_mark in the type
!      slot (e.g. "f(void a, ...)") - that doesn't count as an
!      incomplete type.  */
!   if (TREE_TYPE (x) != error_mark_node
!       && !COMPLETE_TYPE_P (TREE_TYPE (x)))
!     {
!       tree element = TREE_TYPE (x);
! 
!       while (TREE_CODE (element) == ARRAY_TYPE)
! 	element = TREE_TYPE (element);
!       element = TYPE_MAIN_VARIANT (element);
! 
!       if ((TREE_CODE (element) == RECORD_TYPE
! 	   || TREE_CODE (element) == UNION_TYPE)
! 	  && (TREE_CODE (x) != TYPE_DECL
! 	      || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
! 	  && !COMPLETE_TYPE_P (element))
! 	C_TYPE_INCOMPLETE_VARS (element)
! 	  = tree_cons (NULL_TREE, x, C_TYPE_INCOMPLETE_VARS (element));
!     }
    return x;
  }
  
! /* Record X as belonging to file scope.
     This is used only internally by the Objective-C front end,
     and is limited to its needs.  duplicate_decls is not called;
     if there is any preexisting decl for this identifier, it is an ICE.  */
*************** pushdecl_top_level (tree x)
*** 1802,1845 ****
  
    name = DECL_NAME (x);
  
!   if (IDENTIFIER_SYMBOL_VALUE (name))
      abort ();
  
    DECL_CONTEXT (x) = current_file_decl;
!   IDENTIFIER_SYMBOL_VALUE (name) = x;
  
-   SCOPE_LIST_APPEND (global_scope, names, x);
    return x;
  }
  
  /* Generate an implicit declaration for identifier FUNCTIONID as a
     function of type int ().  */
  
  tree
  implicitly_declare (tree functionid)
  {
!   tree decl = any_external_decl (functionid);
  
    if (decl)
      {
!       /* Implicit declaration of a function already declared
! 	 (somehow) in a different scope, or as a built-in.
! 	 If this is the first time this has happened, warn;
! 	 then recycle the old declaration.  */
!       if (!C_DECL_IMPLICIT (decl))
! 	{
! 	  implicit_decl_warning (DECL_NAME (decl));
! 	  if (! DECL_FILE_SCOPE_P (decl))
! 	    warning ("%Jprevious declaration of '%D'", decl, decl);
! 	  C_DECL_IMPLICIT (decl) = 1;
! 	}
!       /* If this function is global, then it must already be in the
! 	 global scope, so there's no need to push it again.  */
!       if (current_scope == global_scope)
! 	return decl;
!       /* If this is a local declaration, make a copy; we can't have
! 	 the same DECL listed in two different scopes.  */
!       return pushdecl (copy_node (decl));
      }
  
    /* Not seen before.  */
--- 1896,1967 ----
  
    name = DECL_NAME (x);
  
!   if (I_SYMBOL_BINDING (name))
      abort ();
  
    DECL_CONTEXT (x) = current_file_decl;
!   if (DECL_EXTERNAL (x) || TREE_PUBLIC (x))
!     {
!       C_DECL_IN_EXTERNAL_SCOPE (x) = 1;
!       bind (name, x, external_scope);
!     }
!   if (file_scope)
!     bind (name, x, file_scope);
  
    return x;
  }
  
+ static void
+ implicit_decl_warning (tree id, tree olddecl)
+ {
+   void (*diag) (const char *, ...);
+   switch (mesg_implicit_function_declaration)
+     {
+     case 0: return;
+     case 1: diag = warning; break;
+     case 2: diag = error;   break;
+     default: abort ();
+     }
+ 
+   diag (N_("implicit declaration of function '%E'"), id);
+   if (olddecl)
+     locate_old_decl (olddecl, diag);
+ }
+ 
  /* Generate an implicit declaration for identifier FUNCTIONID as a
     function of type int ().  */
  
  tree
  implicitly_declare (tree functionid)
  {
!   tree decl = lookup_name_in_scope (functionid, external_scope);
  
    if (decl)
      {
!       /* FIXME: Objective-C has weird not-really-builtin functions
! 	 which are supposed to be visible automatically.  They wind up
! 	 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)
! 	{
! 	  bind (functionid, decl, file_scope);
! 	  return decl;
! 	}
!       else
! 	{
! 	  /* Implicit declaration of a function already declared
! 	     (somehow) in a different scope, or as a built-in.
! 	     If this is the first time this has happened, warn;
! 	     then recycle the old declaration.  */
! 	  if (!C_DECL_IMPLICIT (decl))
! 	    {
! 	      implicit_decl_warning (functionid, decl);
! 	      C_DECL_IMPLICIT (decl) = 1;
! 	    }
! 	  bind (functionid, decl, current_scope);
! 	  return decl;
! 	}
      }
  
    /* Not seen before.  */
*************** implicitly_declare (tree functionid)
*** 1847,1853 ****
    DECL_EXTERNAL (decl) = 1;
    TREE_PUBLIC (decl) = 1;
    C_DECL_IMPLICIT (decl) = 1;
!   implicit_decl_warning (functionid);
  
    /* C89 says implicit declarations are in the innermost block.
       So we record the decl in the standard fashion.  */
--- 1969,1975 ----
    DECL_EXTERNAL (decl) = 1;
    TREE_PUBLIC (decl) = 1;
    C_DECL_IMPLICIT (decl) = 1;
!   implicit_decl_warning (functionid, 0);
  
    /* C89 says implicit declarations are in the innermost block.
       So we record the decl in the standard fashion.  */
*************** implicitly_declare (tree functionid)
*** 1866,1881 ****
    return decl;
  }
  
- static void
- implicit_decl_warning (tree id)
- {
-   const char *name = IDENTIFIER_POINTER (id);
-   if (mesg_implicit_function_declaration == 2)
-     error ("implicit declaration of function `%s'", name);
-   else if (mesg_implicit_function_declaration == 1)
-     warning ("implicit declaration of function `%s'", name);
- }
- 
  /* Issue an error message for a reference to an undeclared variable
     ID, including a reference to a builtin outside of function-call
     context.  Establish a binding of the identifier to error_mark_node
--- 1988,1993 ----
*************** undeclared_variable (tree id)
*** 1889,1902 ****
  
    if (current_function_decl == 0)
      {
!       error ("`%s' undeclared here (not in a function)",
! 	     IDENTIFIER_POINTER (id));
        scope = current_scope;
      }
    else
      {
!       error ("`%s' undeclared (first use in this function)",
! 	     IDENTIFIER_POINTER (id));
  
        if (! already)
  	{
--- 2001,2012 ----
  
    if (current_function_decl == 0)
      {
!       error ("'%E' undeclared here (not in a function)", id);
        scope = current_scope;
      }
    else
      {
!       error ("'%E' undeclared (first use in this function)", id);
  
        if (! already)
  	{
*************** undeclared_variable (tree id)
*** 1905,1916 ****
  	  already = true;
  	}
  
!       scope = current_function_scope;
      }
! 
!   scope->shadowed = tree_cons (id, IDENTIFIER_SYMBOL_VALUE (id),
! 			       scope->shadowed);
!   IDENTIFIER_SYMBOL_VALUE (id) = error_mark_node;
  }
  
  /* Subroutine of lookup_label, declare_label, define_label: construct a
--- 2015,2025 ----
  	  already = true;
  	}
  
!       /* If we are parsing old-style parameter decls, current_function_decl
!          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);
  }
  
  /* Subroutine of lookup_label, declare_label, define_label: construct a
*************** make_label (tree name, location_t locati
*** 1928,1947 ****
    return label;
  }
  
- /* Another subroutine of lookup_label, declare_label, define_label:
-    set up the binding of name to LABEL_DECL in the given SCOPE.  */
- 
- static void
- bind_label (tree name, tree label, struct c_scope *scope)
- {
-   if (IDENTIFIER_LABEL_VALUE (name))
-     scope->shadowed = tree_cons (name, IDENTIFIER_LABEL_VALUE (name),
- 				 scope->shadowed);
-   IDENTIFIER_LABEL_VALUE (name) = label;
- 
-   SCOPE_LIST_APPEND (scope, names, label);
- }
- 
  /* Get the LABEL_DECL corresponding to identifier NAME as a label.
     Create one if none exists so far for the current function.
     This is called when a label is used in a goto expression or
--- 2037,2042 ----
*************** lookup_label (tree name)
*** 1962,1968 ****
    /* Use a label already defined or ref'd with this name, but not if
       it is inherited from a containing function and wasn't declared
       using __label__.  */
!   label = IDENTIFIER_LABEL_VALUE (name);
    if (label && (DECL_CONTEXT (label) == current_function_decl
  		|| C_DECLARED_LABEL_FLAG (label)))
      {
--- 2057,2063 ----
    /* Use a label already defined or ref'd with this name, but not if
       it is inherited from a containing function and wasn't declared
       using __label__.  */
!   label = I_LABEL_DECL (name);
    if (label && (DECL_CONTEXT (label) == current_function_decl
  		|| C_DECLARED_LABEL_FLAG (label)))
      {
*************** lookup_label (tree name)
*** 1978,1984 ****
    label = make_label (name, input_location);
  
    /* Ordinary labels go in the current function scope.  */
!   bind_label (name, label, current_function_scope);
    return label;
  }
  
--- 2073,2079 ----
    label = make_label (name, input_location);
  
    /* Ordinary labels go in the current function scope.  */
!   bind (name, label, current_function_scope);
    return label;
  }
  
*************** lookup_label (tree name)
*** 1989,2014 ****
  tree
  declare_label (tree name)
  {
!   tree label = IDENTIFIER_LABEL_VALUE (name);
!   tree dup;
  
    /* Check to make sure that the label hasn't already been declared
       at this scope */
!   for (dup = current_scope->names; dup; dup = TREE_CHAIN (dup))
!     if (dup == label)
!       {
! 	error ("duplicate label declaration `%s'", IDENTIFIER_POINTER (name));
! 	error ("%Jthis is a previous declaration", dup);
  
! 	/* Just use the previous declaration.  */
! 	return dup;
!       }
  
    label = make_label (name, input_location);
    C_DECLARED_LABEL_FLAG (label) = 1;
  
    /* Declared labels go in the current scope.  */
!   bind_label (name, label, current_scope);
    return label;
  }
  
--- 2084,2108 ----
  tree
  declare_label (tree name)
  {
!   struct c_binding *b = I_LABEL_BINDING (name);
!   tree label;
  
    /* Check to make sure that the label hasn't already been declared
       at this scope */
!   if (b && b->contour == current_scope)
!     {
!       error ("duplicate label declaration `%s'", IDENTIFIER_POINTER (name));
!       locate_old_decl (b->decl, error);
  
!       /* Just use the previous declaration.  */
!       return b->decl;
!     }
  
    label = make_label (name, input_location);
    C_DECLARED_LABEL_FLAG (label) = 1;
  
    /* Declared labels go in the current scope.  */
!   bind (name, label, current_scope);
    return label;
  }
  
*************** declare_label (tree name)
*** 2019,2031 ****
  tree
  define_label (location_t location, tree name)
  {
-   tree label;
- 
    /* Find any preexisting label with this name.  It is an error
       if that label has already been defined in this function, or
       if there is a containing function with a declared label with
       the same name.  */
!   label = IDENTIFIER_LABEL_VALUE (name);
  
    if (label
        && ((DECL_CONTEXT (label) == current_function_decl
--- 2113,2123 ----
  tree
  define_label (location_t location, tree name)
  {
    /* Find any preexisting label with this name.  It is an error
       if that label has already been defined in this function, or
       if there is a containing function with a declared label with
       the same name.  */
!   tree label = I_LABEL_DECL (name);
  
    if (label
        && ((DECL_CONTEXT (label) == current_function_decl
*************** define_label (location_t location, tree 
*** 2034,2043 ****
  	      && C_DECLARED_LABEL_FLAG (label))))
      {
        error ("%Hduplicate label `%D'", &location, label);
!       if (DECL_INITIAL (label))
! 	error ("%J`%D' previously defined here", label, label);
!       else
! 	error ("%J`%D' previously declared here", label, label);
        return 0;
      }
    else if (label && DECL_CONTEXT (label) == current_function_decl)
--- 2126,2132 ----
  	      && C_DECLARED_LABEL_FLAG (label))))
      {
        error ("%Hduplicate label `%D'", &location, label);
!       locate_old_decl (label, error);
        return 0;
      }
    else if (label && DECL_CONTEXT (label) == current_function_decl)
*************** define_label (location_t location, tree 
*** 2053,2059 ****
        label = make_label (name, location);
  
        /* Ordinary labels go in the current function scope.  */
!       bind_label (name, label, current_function_scope);
      }
  
    if (warn_traditional && !in_system_header && lookup_name (name))
--- 2142,2148 ----
        label = make_label (name, location);
  
        /* Ordinary labels go in the current function scope.  */
!       bind (name, label, current_function_scope);
      }
  
    if (warn_traditional && !in_system_header && lookup_name (name))
*************** define_label (location_t location, tree 
*** 2065,2071 ****
    DECL_INITIAL (label) = error_mark_node;
    return label;
  }
! 
  /* Return the list of declarations of the current scope.
     This hook is optional and not implemented for C.  */
  
--- 2154,2160 ----
    DECL_INITIAL (label) = error_mark_node;
    return label;
  }
! 
  /* Return the list of declarations of the current scope.
     This hook is optional and not implemented for C.  */
  
*************** getdecls (void)
*** 2086,2110 ****
  static tree
  lookup_tag (enum tree_code code, tree name, int thislevel_only)
  {
!   tree tag = IDENTIFIER_TAG_VALUE (name);
    int thislevel = 0;
  
!   if (!tag)
      return 0;
  
    /* We only care about whether it's in this level if
       thislevel_only was set or it might be a type clash.  */
!   if (thislevel_only || TREE_CODE (tag) != code)
      {
!       if (current_scope == global_scope
! 	  || purpose_member (name, current_scope->tags))
  	thislevel = 1;
      }
  
    if (thislevel_only && !thislevel)
      return 0;
  
!   if (TREE_CODE (tag) != code)
      {
        /* Definition isn't the kind we were looking for.  */
        pending_invalid_xref = name;
--- 2175,2203 ----
  static tree
  lookup_tag (enum tree_code code, tree name, int thislevel_only)
  {
!   struct c_binding *b = I_TAG_BINDING (name);
    int thislevel = 0;
  
!   if (!b || !b->decl)
      return 0;
  
    /* We only care about whether it's in this level if
       thislevel_only was set or it might be a type clash.  */
!   if (thislevel_only || TREE_CODE (b->decl) != code)
      {
!       /* 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))
  	thislevel = 1;
      }
  
    if (thislevel_only && !thislevel)
      return 0;
  
!   if (TREE_CODE (b->decl) != code)
      {
        /* Definition isn't the kind we were looking for.  */
        pending_invalid_xref = name;
*************** lookup_tag (enum tree_code code, tree na
*** 2117,2123 ****
        if (thislevel)
  	pending_xref_error ();
      }
!   return tag;
  }
  
  /* Print an error message now
--- 2210,2216 ----
        if (thislevel)
  	pending_xref_error ();
      }
!   return b->decl;
  }
  
  /* Print an error message now
*************** pending_xref_error (void)
*** 2144,2179 ****
  tree
  lookup_name (tree name)
  {
!   tree decl = IDENTIFIER_SYMBOL_VALUE (name);
!   if (decl == 0 || decl == error_mark_node)
!     return decl;
!   if (C_DECL_INVISIBLE (decl))
!     return 0;
!   return decl;
  }
  
! /* Similar to `lookup_name' but look only at the current scope.  */
  
  static tree
! lookup_name_current_level (tree name)
  {
!   tree decl = IDENTIFIER_SYMBOL_VALUE (name);
! 
!   if (decl == 0 || decl == error_mark_node || C_DECL_INVISIBLE (decl))
!     return 0;
! 
!   if (current_scope == global_scope)
!     return decl;
! 
!   /* Scan the current scope for a decl with name NAME.
!      For PARM_DECLs, we have to look at both ->parms and ->names, since
!      forward parameter declarations wind up on the ->names list.  */
!   if (TREE_CODE (decl) == PARM_DECL
!       && chain_member (decl, current_scope->parms))
!     return decl;
!   if (chain_member (decl, current_scope->names))
!     return decl;
  
    return 0;
  }
  
--- 2237,2258 ----
  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))
!     return b->decl;
!   return 0;
  }
  
! /* Similar to `lookup_name' but look only at the indicated scope.  */
  
  static tree
! 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)
+       return b->decl;
    return 0;
  }
  
*************** c_init_decl_processing (void)
*** 2194,2202 ****
  
    current_function_decl = 0;
  
!   /* Make the c_scope structure for global names.  */
!   pushlevel (0);
!   global_scope = current_scope;
  
    /* Declarations from c_common_nodes_and_builtins must not be associated
       with this input file, lest we get differences between using and not
--- 2273,2281 ----
  
    current_function_decl = 0;
  
!   /* Make the externals scope.  */
!   push_scope ();
!   external_scope = current_scope;
  
    /* Declarations from c_common_nodes_and_builtins must not be associated
       with this input file, lest we get differences between using and not
*************** c_init_decl_processing (void)
*** 2204,2212 ****
    input_location.file = "<internal>";
    input_location.line = 0;
  
-   /* Make the DECL for the toplevel file scope.  */
-   current_file_decl = build_decl (TRANSLATION_UNIT_DECL, NULL, NULL);
- 
    build_common_tree_nodes (flag_signed_char);
  
    c_common_nodes_and_builtins ();
--- 2283,2288 ----
*************** c_init_decl_processing (void)
*** 2232,2240 ****
  
    make_fname_decl = c_make_fname_decl;
    start_fname_decls ();
- 
-   first_builtin_decl = global_scope->names;
-   last_builtin_decl = global_scope->names_last;
  }
  
  /* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
--- 2308,2313 ----
*************** c_make_fname_decl (tree id, int type_dep
*** 2270,2277 ****
    if (current_function_decl)
      {
        DECL_CONTEXT (decl) = current_function_decl;
!       IDENTIFIER_SYMBOL_VALUE (id) = decl;
!       SCOPE_LIST_APPEND (current_function_scope, names, decl);
      }
  
    finish_decl (decl, init, NULL_TREE);
--- 2343,2349 ----
    if (current_function_decl)
      {
        DECL_CONTEXT (decl) = current_function_decl;
!       bind (id, decl, current_function_scope);
      }
  
    finish_decl (decl, init, NULL_TREE);
*************** builtin_function (const char *name, tree
*** 2293,2312 ****
  		  enum built_in_class class, const char *library_name,
  		  tree attrs)
  {
!   tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
!   DECL_EXTERNAL (decl) = 1;
    TREE_PUBLIC (decl) = 1;
    if (library_name)
      SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
    make_decl_rtl (decl, NULL);
-   pushdecl (decl);
-   DECL_BUILT_IN_CLASS (decl) = class;
-   DECL_FUNCTION_CODE (decl) = function_code;
  
!   /* Warn if a function in the namespace for users
!      is used without an occasion to consider it declared.  */
!   if (name[0] != '_' || name[1] != '_')
!     C_DECL_INVISIBLE (decl) = 1;
  
    /* Possibly apply some default attributes to this built-in function.  */
    if (attrs)
--- 2365,2395 ----
  		  enum built_in_class class, 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_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);
! 
!   /* Builtins in the implementation namespace are made visible without
!      needing to be explicitly declared.  See push_file_scope.  */
!   if (name[0] == '_' && (name[1] == '_' || ISUPPER (name[1])))
!     {
!       TREE_CHAIN (decl) = visible_builtins;
!       visible_builtins = decl;
!     }
  
    /* Possibly apply some default attributes to this built-in function.  */
    if (attrs)
*************** start_decl (tree declarator, tree declsp
*** 2520,2553 ****
    if (initialized)
      /* Is it valid for this decl to have an initializer at all?
         If not, set INITIALIZED to zero, which will indirectly
!        tell `finish_decl' to ignore the initializer once it is parsed.  */
      switch (TREE_CODE (decl))
        {
        case TYPE_DECL:
! 	error ("typedef `%s' is initialized (use __typeof__ instead)",
! 	       IDENTIFIER_POINTER (DECL_NAME (decl)));
  	initialized = 0;
  	break;
  
        case FUNCTION_DECL:
! 	error ("function `%s' is initialized like a variable",
! 	       IDENTIFIER_POINTER (DECL_NAME (decl)));
  	initialized = 0;
  	break;
  
        case PARM_DECL:
  	/* DECL_INITIAL in a PARM_DECL is really DECL_ARG_TYPE.  */
! 	error ("parameter `%s' is initialized",
! 	       IDENTIFIER_POINTER (DECL_NAME (decl)));
  	initialized = 0;
  	break;
  
        default:
! 	/* Don't allow initializations for incomplete types
! 	   except for arrays which might be completed by the initialization.  */
  
! 	/* This can happen if the array size is an undefined macro.  We already
! 	   gave a warning, so we don't need another one.  */
  	if (TREE_TYPE (decl) == error_mark_node)
  	  initialized = 0;
  	else if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
--- 2603,2633 ----
    if (initialized)
      /* Is it valid for this decl to have an initializer at all?
         If not, set INITIALIZED to zero, which will indirectly
!        tell 'finish_decl' to ignore the initializer once it is parsed.  */
      switch (TREE_CODE (decl))
        {
        case TYPE_DECL:
! 	error ("typedef '%D' is initialized (use __typeof__ instead)", decl);
  	initialized = 0;
  	break;
  
        case FUNCTION_DECL:
! 	error ("function '%D' is initialized like a variable", decl);
  	initialized = 0;
  	break;
  
        case PARM_DECL:
  	/* DECL_INITIAL in a PARM_DECL is really DECL_ARG_TYPE.  */
! 	error ("parameter '%D' is initialized", decl);
  	initialized = 0;
  	break;
  
        default:
! 	/* Don't allow initializations for incomplete types except for
! 	   arrays which might be completed by the initialization.  */
  
! 	/* This can happen if the array size is an undefined macro.
! 	   We already gave a warning, so we don't need another one.  */
  	if (TREE_TYPE (decl) == error_mark_node)
  	  initialized = 0;
  	else if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
*************** start_decl (tree declarator, tree declsp
*** 2563,2576 ****
  	  }
  	else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
  	  {
! 	    error ("variable `%s' has initializer but incomplete type",
! 		   IDENTIFIER_POINTER (DECL_NAME (decl)));
  	    initialized = 0;
  	  }
  	else if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
  	  {
! 	    error ("elements of array `%s' have incomplete type",
! 		   IDENTIFIER_POINTER (DECL_NAME (decl)));
  	    initialized = 0;
  	  }
        }
--- 2643,2654 ----
  	  }
  	else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
  	  {
! 	    error ("variable '%D' has initializer but incomplete type", decl);
  	    initialized = 0;
  	  }
  	else if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
  	  {
! 	    error ("elements of array '%D' have incomplete type", decl);
  	    initialized = 0;
  	  }
        }
*************** start_decl (tree declarator, tree declsp
*** 2578,2589 ****
    if (initialized)
      {
        DECL_EXTERNAL (decl) = 0;
!       if (current_scope == global_scope)
  	TREE_STATIC (decl) = 1;
  
!       /* Tell `pushdecl' this is an initialized decl
  	 even though we don't yet have the initializer expression.
! 	 Also tell `finish_decl' it may store the real initializer.  */
        DECL_INITIAL (decl) = error_mark_node;
      }
  
--- 2656,2667 ----
    if (initialized)
      {
        DECL_EXTERNAL (decl) = 0;
!       if (current_scope == file_scope)
  	TREE_STATIC (decl) = 1;
  
!       /* Tell 'pushdecl' this is an initialized decl
  	 even though we don't yet have the initializer expression.
! 	 Also tell 'finish_decl' it may store the real initializer.  */
        DECL_INITIAL (decl) = error_mark_node;
      }
  
*************** start_decl (tree declarator, tree declsp
*** 2644,2664 ****
       TEM may equal DECL or it may be a previous decl of the same name.  */
    tem = pushdecl (decl);
  
-   /* For a local variable, define the RTL now.  */
-   if (current_scope != global_scope
-       /* But not if this is a duplicate decl
- 	 and we preserved the rtl from the previous one
- 	 (which may or may not happen).  */
-       && !DECL_RTL_SET_P (tem)
-       && DECL_FILE_SCOPE_P (tem))
-     {
-       if (TREE_TYPE (tem) != error_mark_node
- 	  && (COMPLETE_TYPE_P (TREE_TYPE (tem))
- 	      || (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
- 		  && DECL_INITIAL (tem) != 0)))
- 	expand_decl (tem);
-     }
- 
    return tem;
  }
  
--- 2722,2727 ----
*************** finish_decl (tree decl, tree init, tree 
*** 2675,2681 ****
    const char *asmspec = 0;
  
    /* If a name was specified, get the string.  */
!   if (current_scope == global_scope)
      asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
    if (asmspec_tree)
      asmspec = TREE_STRING_POINTER (asmspec_tree);
--- 2738,2744 ----
    const char *asmspec = 0;
  
    /* If a name was specified, get the string.  */
!   if (current_scope == file_scope)
      asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
    if (asmspec_tree)
      asmspec = TREE_STRING_POINTER (asmspec_tree);
*************** finish_decl (tree decl, tree init, tree 
*** 2813,2819 ****
      }
  
    /* If #pragma weak was used, mark the decl weak now.  */
!   if (current_scope == global_scope)
      maybe_apply_pragma_weak (decl);
  
    /* Output the assembler code and/or RTL code for variables and functions,
--- 2876,2882 ----
      }
  
    /* If #pragma weak was used, mark the decl weak now.  */
!   if (current_scope == file_scope)
      maybe_apply_pragma_weak (decl);
  
    /* Output the assembler code and/or RTL code for variables and functions,
*************** finish_decl (tree decl, tree init, tree 
*** 2892,2898 ****
    /* 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 == global_scope)
      get_pending_sizes ();
  
    /* Install a cleanup (aka destructor) if one was given.  */
--- 2955,2961 ----
    /* 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.  */
*************** push_parm_decl (tree parm)
*** 2956,2969 ****
    immediate_size_expand = save_immediate_size_expand;
  }
  
! /* Mark all the parameter declarations to date as forward decls,
!    shift them to the variables list, and reset the parameters list.
     Also diagnose use of this extension.  */
  
  void
  mark_forward_parm_decls (void)
  {
!   tree parm;
  
    if (pedantic && !current_scope->warned_forward_parm_decls)
      {
--- 3019,3031 ----
    immediate_size_expand = save_immediate_size_expand;
  }
  
! /* Mark all the parameter declarations to date as forward decls.
     Also diagnose use of this extension.  */
  
  void
  mark_forward_parm_decls (void)
  {
!   struct c_binding *b;
  
    if (pedantic && !current_scope->warned_forward_parm_decls)
      {
*************** mark_forward_parm_decls (void)
*** 2971,2982 ****
        current_scope->warned_forward_parm_decls = true;
      }
  
!   for (parm = current_scope->parms; parm; parm = TREE_CHAIN (parm))
!     TREE_ASM_WRITTEN (parm) = 1;
! 
!   SCOPE_LIST_CONCAT (current_scope, names, current_scope, parms);
!   current_scope->parms = 0;
!   current_scope->parms_last = 0;
  }
  
  static GTY(()) int compound_literal_number;
--- 3033,3041 ----
        current_scope->warned_forward_parm_decls = true;
      }
  
!   for (b = current_scope->bindings; b; b = b->prev)
!     if (TREE_CODE (b->decl) == PARM_DECL)
!       TREE_ASM_WRITTEN (b->decl) = 1;
  }
  
  static GTY(()) int compound_literal_number;
*************** build_compound_literal (tree type, tree 
*** 2997,3006 ****
    tree stmt;
    DECL_EXTERNAL (decl) = 0;
    TREE_PUBLIC (decl) = 0;
!   TREE_STATIC (decl) = (current_scope == global_scope);
    DECL_CONTEXT (decl) = current_function_decl;
    TREE_USED (decl) = 1;
-   DECL_ARTIFICIAL (decl) = 1;
    TREE_TYPE (decl) = type;
    TREE_READONLY (decl) = TREE_READONLY (type);
    store_init_value (decl, init);
--- 3056,3064 ----
    tree stmt;
    DECL_EXTERNAL (decl) = 0;
    TREE_PUBLIC (decl) = 0;
!   TREE_STATIC (decl) = (current_scope == file_scope);
    DECL_CONTEXT (decl) = current_function_decl;
    TREE_USED (decl) = 1;
    TREE_TYPE (decl) = type;
    TREE_READONLY (decl) = TREE_READONLY (type);
    store_init_value (decl, init);
*************** grokdeclarator (tree declarator, tree de
*** 3275,3280 ****
--- 3333,3339 ----
    tree returned_attrs = NULL_TREE;
    bool bitfield = width != NULL;
    tree element_type;
+   tree arg_info = NULL_TREE;
  
    if (decl_context == FUNCDEF)
      funcdef_flag = 1, decl_context = NORMAL;
*************** grokdeclarator (tree declarator, tree de
*** 3321,3328 ****
    /* If this looks like a function definition, make it one,
       even if it occurs where parms are expected.
       Then store_parm_decls will reject it and not use it as a parm.  */
!   if (decl_context == NORMAL && !funcdef_flag
!       && current_scope->parm_flag)
      decl_context = PARM;
  
    /* Look through the decl specs and record which ones appear.
--- 3380,3386 ----
    /* If this looks like a function definition, make it one,
       even if it occurs where parms are expected.
       Then store_parm_decls will reject it and not use it as a parm.  */
!   if (decl_context == NORMAL && !funcdef_flag && current_scope->parm_flag)
      decl_context = PARM;
  
    /* Look through the decl specs and record which ones appear.
*************** grokdeclarator (tree declarator, tree de
*** 3377,3383 ****
  		{
  		  if (i == RID_CONST || i == RID_VOLATILE || i == RID_RESTRICT)
  		    {
! 		      if (!flag_isoc99)
  			pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
  		    }
  		  else
--- 3435,3441 ----
  		{
  		  if (i == RID_CONST || i == RID_VOLATILE || i == RID_RESTRICT)
  		    {
! 		      if (pedantic && !flag_isoc99)
  			pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
  		    }
  		  else
*************** grokdeclarator (tree declarator, tree de
*** 3418,3428 ****
        else if (TREE_CODE (id) == IDENTIFIER_NODE)
  	{
  	  tree t = lookup_name (id);
! 	  if (TREE_TYPE (t) == error_mark_node)
! 	    ;
! 	  else if (!t || TREE_CODE (t) != TYPE_DECL)
  	    error ("`%s' fails to be a typedef or built in type",
  		   IDENTIFIER_POINTER (id));
  	  else
  	    {
  	      type = TREE_TYPE (t);
--- 3476,3486 ----
        else if (TREE_CODE (id) == IDENTIFIER_NODE)
  	{
  	  tree t = lookup_name (id);
! 	   if (!t || TREE_CODE (t) != TYPE_DECL)
  	    error ("`%s' fails to be a typedef or built in type",
  		   IDENTIFIER_POINTER (id));
+ 	   else if (TREE_TYPE (t) == error_mark_node)
+ 	    ;
  	  else
  	    {
  	      type = TREE_TYPE (t);
*************** grokdeclarator (tree declarator, tree de
*** 3634,3645 ****
    volatilep
      = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (element_type);
    inlinep = !! (specbits & (1 << (int) RID_INLINE));
!   if (constp > 1 && ! flag_isoc99)
!     pedwarn ("duplicate `const'");
!   if (restrictp > 1 && ! flag_isoc99)
!     pedwarn ("duplicate `restrict'");
!   if (volatilep > 1 && ! flag_isoc99)
!     pedwarn ("duplicate `volatile'");
    if (! flag_gen_aux_info && (TYPE_QUALS (type)))
      type = TYPE_MAIN_VARIANT (type);
    type_quals = ((constp ? TYPE_QUAL_CONST : 0)
--- 3692,3706 ----
    volatilep
      = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (element_type);
    inlinep = !! (specbits & (1 << (int) RID_INLINE));
!   if (pedantic && !flag_isoc99)
!     {
!       if (constp > 1)
! 	pedwarn ("duplicate `const'");
!       if (restrictp > 1)
! 	pedwarn ("duplicate `restrict'");
!       if (volatilep > 1)
! 	pedwarn ("duplicate `volatile'");
!     }
    if (! flag_gen_aux_info && (TYPE_QUALS (type)))
      type = TYPE_MAIN_VARIANT (type);
    type_quals = ((constp ? TYPE_QUAL_CONST : 0)
*************** grokdeclarator (tree declarator, tree de
*** 3676,3682 ****
  		    | (1 << (int) RID_THREAD))))
        {
  	if (specbits & 1 << (int) RID_AUTO
! 	    && (pedantic || current_scope == global_scope))
  	  pedwarn ("function definition declared `auto'");
  	if (specbits & 1 << (int) RID_REGISTER)
  	  error ("function definition declared `register'");
--- 3737,3743 ----
  		    | (1 << (int) RID_THREAD))))
        {
  	if (specbits & 1 << (int) RID_AUTO
! 	    && (pedantic || current_scope == file_scope))
  	  pedwarn ("function definition declared `auto'");
  	if (specbits & 1 << (int) RID_REGISTER)
  	  error ("function definition declared `register'");
*************** grokdeclarator (tree declarator, tree de
*** 3714,3725 ****
      else if (specbits & 1 << (int) RID_EXTERN && initialized && ! 
funcdef_flag)
        {
  	/* `extern' with initialization is invalid if not at file scope.  */
! 	if (current_scope == global_scope)
  	  warning ("`%s' initialized and declared `extern'", name);
  	else
  	  error ("`%s' has both `extern' and initializer", name);
        }
!     else if (current_scope == global_scope)
        {
  	if (specbits & 1 << (int) RID_AUTO)
  	  error ("file-scope declaration of `%s' specifies `auto'", name);
--- 3775,3786 ----
      else if (specbits & 1 << (int) RID_EXTERN && initialized && ! 
funcdef_flag)
        {
  	/* `extern' with initialization is invalid if not at file scope.  */
! 	if (current_scope == file_scope)
  	  warning ("`%s' initialized and declared `extern'", name);
  	else
  	  error ("`%s' has both `extern' and initializer", name);
        }
!     else if (current_scope == file_scope)
        {
  	if (specbits & 1 << (int) RID_AUTO)
  	  error ("file-scope declaration of `%s' specifies `auto'", name);
*************** grokdeclarator (tree declarator, tree de
*** 3977,3982 ****
--- 4038,4048 ----
  	}
        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));
  	  tree arg_types;
  
  	  /* Declaring a function type.
*************** grokdeclarator (tree declarator, tree de
*** 4001,4013 ****
  
  	  /* Construct the function type and go to the next
  	     inner layer of declarator.  */
  
- 	  arg_types = grokparms (TREE_OPERAND (declarator, 1),
- 				 funcdef_flag
- 				 /* Say it's a definition
- 				    only for the CALL_EXPR
- 				    closest to the identifier.  */
- 				 && TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE);
  	  /* Type qualifiers before the return type of the function
  	     qualify the return type, not the function type.  */
  	  if (type_quals)
--- 4067,4075 ----
  
  	  /* Construct the function type and go to the next
  	     inner layer of declarator.  */
+ 	  arg_info = TREE_OPERAND (declarator, 1);
+ 	  arg_types = grokparms (arg_info, really_funcdef);
  
  	  /* Type qualifiers before the return type of the function
  	     qualify the return type, not the function type.  */
  	  if (type_quals)
*************** grokdeclarator (tree declarator, tree de
*** 4043,4049 ****
  	  {
  	    tree link;
  
! 	    for (link = last_function_parm_tags;
  		 link;
  		 link = TREE_CHAIN (link))
  	      TYPE_CONTEXT (TREE_VALUE (link)) = type;
--- 4105,4111 ----
  	  {
  	    tree link;
  
! 	    for (link = ARG_INFO_TAGS (arg_info);
  		 link;
  		 link = TREE_CHAIN (link))
  	      TYPE_CONTEXT (TREE_VALUE (link)) = type;
*************** grokdeclarator (tree declarator, tree de
*** 4097,4108 ****
  
  	      if (erred)
  		error ("invalid type modifier within pointer declarator");
! 	      if (constp > 1 && ! flag_isoc99)
! 		pedwarn ("duplicate `const'");
! 	      if (volatilep > 1 && ! flag_isoc99)
! 		pedwarn ("duplicate `volatile'");
! 	      if (restrictp > 1 && ! flag_isoc99)
! 		pedwarn ("duplicate `restrict'");
  
  	      type_quals = ((constp ? TYPE_QUAL_CONST : 0)
  			    | (restrictp ? TYPE_QUAL_RESTRICT : 0)
--- 4159,4173 ----
  
  	      if (erred)
  		error ("invalid type modifier within pointer declarator");
! 	      if (pedantic && !flag_isoc99)
! 		{
! 		  if (constp > 1)
! 		    pedwarn ("duplicate `const'");
! 		  if (volatilep > 1)
! 		    pedwarn ("duplicate `volatile'");
! 		  if (restrictp > 1)
! 		    pedwarn ("duplicate `restrict'");
! 		}
  
  	      type_quals = ((constp ? TYPE_QUAL_CONST : 0)
  			    | (restrictp ? TYPE_QUAL_RESTRICT : 0)
*************** grokdeclarator (tree declarator, tree de
*** 4190,4196 ****
    if (VOID_TYPE_P (type) && decl_context != PARM
        && ! ((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
  	    && ((specbits & (1 << (int) RID_EXTERN))
! 		|| (current_scope == global_scope
  		    && !(specbits
  			 & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)))))))
      {
--- 4255,4261 ----
    if (VOID_TYPE_P (type) && decl_context != PARM
        && ! ((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
  	    && ((specbits & (1 << (int) RID_EXTERN))
! 		|| (current_scope == file_scope
  		    && !(specbits
  			 & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)))))))
      {
*************** grokdeclarator (tree declarator, tree de
*** 4325,4334 ****
  	   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 == global_scope);
  
  	if (specbits & (1 << (int) RID_AUTO)
! 	    && (pedantic || current_scope == global_scope))
  	  pedwarn ("invalid storage class for function `%s'", name);
  	if (specbits & (1 << (int) RID_REGISTER))
  	  error ("invalid storage class for function `%s'", name);
--- 4390,4399 ----
  	   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);
  	if (specbits & (1 << (int) RID_REGISTER))
  	  error ("invalid storage class for function `%s'", name);
*************** grokdeclarator (tree declarator, tree de
*** 4337,4343 ****
  	/* Function declaration not at file scope.
  	   Storage classes other than `extern' are not allowed
  	   and `extern' makes no difference.  */
! 	if (current_scope != global_scope
  	    && (specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_INLINE)))
  	    && pedantic)
  	  pedwarn ("invalid storage class for function `%s'", name);
--- 4402,4408 ----
  	/* Function declaration not at file scope.
  	   Storage classes other than `extern' are not allowed
  	   and `extern' makes no difference.  */
! 	if (current_scope != file_scope
  	    && (specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_INLINE)))
  	    && pedantic)
  	  pedwarn ("invalid storage class for function `%s'", name);
*************** grokdeclarator (tree declarator, tree de
*** 4363,4368 ****
--- 4428,4439 ----
  	TREE_PUBLIC (decl)
  	  = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
  
+ 	/* For a function definition, record the argument information
+ 	   block in DECL_ARGUMENTS where store_parm_decls will look
+ 	   for it.  */
+ 	if (funcdef_flag)
+ 	  DECL_ARGUMENTS (decl) = arg_info;
+ 
  	if (defaulted_int)
  	  C_FUNCTION_IMPLICIT_INT (decl) = 1;
  
*************** grokdeclarator (tree declarator, tree de
*** 4412,4431 ****
  	else if (type_quals)
  	  type = c_build_qualified_type (type, type_quals);
  
! 	/* It is invalid to create an `extern' declaration for a
  	   variable if there is a global declaration that is
! 	   `static' and the global declaration is not visible.  */
! 	if (extern_ref && current_scope != global_scope)
  	  {
! 	    tree global_decl;
  
- 	    global_decl = identifier_global_value (declarator);
  	    if (global_decl
  		&& TREE_CODE (global_decl) == VAR_DECL
- 		&& lookup_name (declarator) != global_decl
  		&& !TREE_PUBLIC (global_decl))
! 	      error ("variable previously declared `static' redeclared "
! 		     "`extern'");
  	  }
  
  	decl = build_decl (VAR_DECL, declarator, type);
--- 4483,4505 ----
  	else if (type_quals)
  	  type = c_build_qualified_type (type, type_quals);
  
! 	/* C99 6.2.2p7: It is invalid (compile-time undefined
! 	   behavior) to create an 'extern' declaration for a
  	   variable if there is a global declaration that is
! 	   'static' and the global declaration is not visible.
! 	   (If the static declaration _is_ currently visible,
! 	   the 'extern' declaration is taken to refer to that decl.) */
! 	if (extern_ref && current_scope != file_scope)
  	  {
! 	    tree global_decl  = identifier_global_value (declarator);
! 	    tree visible_decl = lookup_name (declarator);
  
  	    if (global_decl
+ 		&& global_decl != visible_decl
  		&& TREE_CODE (global_decl) == VAR_DECL
  		&& !TREE_PUBLIC (global_decl))
! 	      error ("variable previously declared 'static' redeclared "
! 		     "'extern'");
  	  }
  
  	decl = build_decl (VAR_DECL, declarator, type);
*************** grokdeclarator (tree declarator, tree de
*** 4441,4447 ****
  	   class specifier, or the absence of all storage class specifiers
  	   makes this declaration a definition (perhaps tentative).  Also,
  	   the absence of both `static' and `register' makes it public.  */
! 	if (current_scope == global_scope)
  	  {
  	    TREE_PUBLIC (decl) = !(specbits & ((1 << (int) RID_STATIC)
  					       | (1 << (int) RID_REGISTER)));
--- 4515,4521 ----
  	   class specifier, or the absence of all storage class specifiers
  	   makes this declaration a definition (perhaps tentative).  Also,
  	   the absence of both `static' and `register' makes it public.  */
! 	if (current_scope == file_scope)
  	  {
  	    TREE_PUBLIC (decl) = !(specbits & ((1 << (int) RID_STATIC)
  					       | (1 << (int) RID_REGISTER)));
*************** grokdeclarator (tree declarator, tree de
*** 4501,4510 ****
     of calls is different.  The last call to `grokparms' is always the one
     that contains the formal parameter names of a function definition.
  
-    Store in `last_function_parms' a chain of the decls of parms.
-    Also store in `last_function_parm_tags' a chain of the struct, union,
-    and enum tags declared among the parms.
- 
     Return a list of arg types to use in the FUNCTION_TYPE for this function.
  
     FUNCDEF_FLAG is nonzero for a function definition, 0 for
--- 4575,4580 ----
*************** grokdeclarator (tree declarator, tree de
*** 4512,4703 ****
     when FUNCDEF_FLAG is zero.  */
  
  static tree
! grokparms (tree parms_info, int funcdef_flag)
  {
!   tree first_parm = TREE_CHAIN (parms_info);
! 
!   last_function_parms = TREE_PURPOSE (parms_info);
!   last_function_parm_tags = TREE_VALUE (parms_info);
!   last_function_parm_others = TREE_TYPE (parms_info);
  
!   if (warn_strict_prototypes && first_parm == 0 && !funcdef_flag
        && !in_system_header)
      warning ("function declaration isn't a prototype");
  
!   if (first_parm != 0
!       && TREE_CODE (TREE_VALUE (first_parm)) == IDENTIFIER_NODE)
      {
        if (! funcdef_flag)
  	pedwarn ("parameter names (without types) in function declaration");
  
!       last_function_parms = first_parm;
        return 0;
      }
    else
      {
!       tree parm;
!       tree typelt;
!       /* If the arg types are incomplete in a declaration,
! 	 they must include undefined tags.
! 	 These tags can never be defined in the scope of the declaration,
! 	 so the types can never be completed,
! 	 and no call can be compiled successfully.  */
  
!       for (parm = last_function_parms, typelt = first_parm;
  	   parm;
! 	   parm = TREE_CHAIN (parm))
! 	/* Skip over any enumeration constants declared here.  */
! 	if (TREE_CODE (parm) == PARM_DECL)
! 	  {
! 	    /* Barf if the parameter itself has an incomplete type.  */
! 	    tree type = TREE_VALUE (typelt);
! 	    if (type == error_mark_node)
! 	      continue;
! 	    if (!COMPLETE_TYPE_P (type))
! 	      {
! 		if (funcdef_flag && DECL_NAME (parm) != 0)
! 		  error ("parameter `%s' has incomplete type",
! 			 IDENTIFIER_POINTER (DECL_NAME (parm)));
! 		else
! 		  warning ("parameter has incomplete type");
! 		if (funcdef_flag)
! 		  {
! 		    TREE_VALUE (typelt) = error_mark_node;
! 		    TREE_TYPE (parm) = error_mark_node;
! 		  }
! 	      }
! 	    typelt = TREE_CHAIN (typelt);
! 	  }
  
!       return first_parm;
      }
  }
  
! /* Return a tree_list node with info on a parameter list just parsed.
!    The TREE_PURPOSE is a list of decls of those parms.
!    The TREE_VALUE is a list of structure, union and enum tags defined.
!    The TREE_CHAIN is a list of argument types to go in the FUNCTION_TYPE.
!    The TREE_TYPE is a list of non-parameter decls which appeared with the
!    parameters.
!    This tree_list node is later fed to `grokparms'.
  
!    VOID_AT_END nonzero means append `void' to the end of the type-list.
!    Zero means the parmlist ended with an ellipsis so don't append `void'.  */
  
  tree
! get_parm_info (int void_at_end)
  {
!   tree decl, type, list;
!   tree types = 0;
!   tree *last_type = &types;
!   tree tags = current_scope->tags;
!   tree parms = current_scope->parms;
!   tree others = current_scope->names;
    static bool explained_incomplete_types = false;
    bool gave_void_only_once_err = false;
  
!   /* Just "void" (and no ellipsis) is special.  There are really no parms.
!      But if the "void" is qualified (by "const" or "volatile"), or has a
!      storage class specifier ("register"), then the behavior is undefined;
!      issue an error.  Typedefs for "void" are OK (see DR#157).  */
!   if (void_at_end && parms != 0
!       && TREE_CHAIN (parms) == 0
!       && VOID_TYPE_P (TREE_TYPE (parms))
!       && !DECL_NAME (parms))
!     {
!       if (TREE_THIS_VOLATILE (parms)
! 	  || TREE_READONLY (parms)
! 	  || DECL_REGISTER (parms))
! 	error ("\"void\" as only parameter may not be qualified");
  
!       return tree_cons (0, 0, tree_cons (0, void_type_node, 0));
!     }
  
!   /* Sanity check all of the parameter declarations.  */
!   for (decl = parms; decl; decl = TREE_CHAIN (decl))
      {
!       if (TREE_CODE (decl) != PARM_DECL)
! 	abort ();
!       if (TREE_ASM_WRITTEN (decl))
! 	abort ();
! 
!       /* Since there is a prototype, args are passed in their
! 	 declared types.  The back end may override this.  */
!       type = TREE_TYPE (decl);
!       DECL_ARG_TYPE (decl) = type;
  
!       /* Check for (..., void, ...) and issue an error.  */
!       if (VOID_TYPE_P (type) && !DECL_NAME (decl) && 
!gave_void_only_once_err)
  	{
! 	  error ("\"void\" must be the only parameter");
! 	  gave_void_only_once_err = true;
! 	}
  
!       type = build_tree_list (0, type);
!       *last_type = type;
!       last_type = &TREE_CHAIN (type);
!     }
  
!   /* Check the list of non-parameter decls for any forward parm decls
!      that never got real decls.  */
!   for (decl = others; decl; decl = TREE_CHAIN (decl))
!     if (TREE_CODE (decl) == PARM_DECL)
!       {
! 	if (!TREE_ASM_WRITTEN (decl))
! 	  abort ();
  
! 	  error ("%Jparameter \"%D\" has just a forward declaration",
! 		 decl, decl);
!       }
  
!   /* Warn about any struct, union or enum tags defined within this
!      list.  The scope of such types is limited to this declaration,
!      which is rarely if ever desirable (it's impossible to call such
!      a function with type-correct arguments).  */
!   for (decl = tags; decl; decl = TREE_CHAIN (decl))
!     {
!       enum tree_code code = TREE_CODE (TREE_VALUE (decl));
!       const char *keyword;
!       /* An anonymous union parm type is meaningful as a GNU extension.
! 	 So don't warn for that.  */
!       if (code == UNION_TYPE && TREE_PURPOSE (decl) == 0 && !pedantic)
! 	continue;
  
!       /* The keyword should not be translated.  */
!       switch (code)
! 	{
! 	case RECORD_TYPE:   keyword = "struct"; break;
! 	case UNION_TYPE:    keyword = "union";  break;
! 	case ENUMERAL_TYPE: keyword = "enum";   break;
! 	default: abort ();
! 	}
  
!       if (TREE_PURPOSE (decl))
! 	/* The first %s will be one of 'struct', 'union', or 'enum'.  */
! 	warning ("\"%s %s\" declared inside parameter list",
! 		 keyword, IDENTIFIER_POINTER (TREE_PURPOSE (decl)));
!       else
! 	/* 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,"
! 		   " which is probably not what you want");
! 	  explained_incomplete_types = true;
  	}
-     }
  
! 
!   if (void_at_end)
!     {
!       type = build_tree_list (0, void_type_node);
!       *last_type = type;
      }
  
!   list = tree_cons (parms, tags, types);
!   TREE_TYPE (list) = others;
!   return list;
  }
  
  /* Get the struct, enum or union (CODE says which) with tag NAME.
--- 4582,4841 ----
     when FUNCDEF_FLAG is zero.  */
  
  static tree
! grokparms (tree arg_info, int funcdef_flag)
  {
!   tree arg_types = ARG_INFO_TYPES (arg_info);
  
!   if (warn_strict_prototypes && arg_types == 0 && !funcdef_flag
        && !in_system_header)
      warning ("function declaration isn't a prototype");
  
!   if (arg_types == error_mark_node)
!     return 0;  /* don't set TYPE_ARG_TYPES in this case */
! 
!   else if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == 
IDENTIFIER_NODE)
      {
        if (! funcdef_flag)
  	pedwarn ("parameter names (without types) in function declaration");
  
!       ARG_INFO_PARMS (arg_info) = ARG_INFO_TYPES (arg_info);
!       ARG_INFO_TYPES (arg_info) = 0;
        return 0;
      }
    else
      {
!       tree parm, type, typelt;
!       unsigned int parmno;
! 
!       /* If the arg types are incomplete in a declaration, they must
! 	 include undefined tags.  These tags can never be defined in
! 	 the scope of the declaration, so the types can never be
! 	 completed, and no call can be compiled successfully.  */
  
!       for (parm = ARG_INFO_PARMS (arg_info), typelt = arg_types, parmno = 1;
  	   parm;
! 	   parm = TREE_CHAIN (parm), typelt = TREE_CHAIN (typelt), parmno++)
! 	{
! 	  type = TREE_VALUE (typelt);
! 	  if (type == error_mark_node)
! 	    continue;
  
! 	  if (!COMPLETE_TYPE_P (type))
! 	    {
! 	      if (funcdef_flag)
! 		{
! 		  if (DECL_NAME (parm))
! 		    error ("%Jparameter %u ('%D') has incomplete type",
! 			   parm, parmno, parm);
! 		  else
! 		    error ("%Jparameter %u has incomplete type",
! 			   parm, parmno);
! 
! 		  TREE_VALUE (typelt) = error_mark_node;
! 		  TREE_TYPE (parm) = error_mark_node;
! 		}
! 	      else
! 		{
! 		  if (DECL_NAME (parm))
! 		    warning ("%Jparameter %u ('%D') has incomplete type",
! 			     parm, parmno, parm);
! 		  else
! 		    warning ("%Jparameter %u has incomplete type",
! 			     parm, parmno);
! 		}
! 	    }
! 	}
!       return arg_types;
      }
  }
  
! /* Take apart the current scope and return a tree_list node with info
!    on a parameter list just parsed.  This tree_list node should be
!    examined using the ARG_INFO_* macros, defined above:
! 
!      ARG_INFO_PARMS:  a list of parameter decls.
!      ARG_INFO_TAGS:   a list of structure, union and enum tags defined.
!      ARG_INFO_TYPES:  a list of argument types to go in the FUNCTION_TYPE.
!      ARG_INFO_OTHERS: a list of non-parameter decls (notably enumeration
!                       constants) defined with the parameters.
  
!    This tree_list node 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.  */
  
  tree
! get_parm_info (bool ellipsis)
  {
!   struct c_binding *b = current_scope->bindings;
!   tree arg_info = make_node (TREE_LIST);
!   tree parms    = 0;
!   tree tags     = 0;
!   tree types    = 0;
!   tree others   = 0;
! 
    static bool explained_incomplete_types = false;
    bool gave_void_only_once_err = false;
  
!   /* The bindings in this scope must not get put into a block.
!      We will take care of deleting the binding nodes.  */
!   current_scope->bindings = 0;
  
!   /* This function is only called if there was *something* on the
!      parameter list.  */
! #ifdef ENABLE_CHECKING
!   if (b == 0)
!     abort ();
! #endif
  
!   /* A parameter list consisting solely of 'void' indicates that the
!      function takes no arguments.  But if the 'void' is qualified
!      (by 'const' or 'volatile'), or has a storage class specifier
!      ('register'), then the behavior is undefined; issue an error.
!      Typedefs for 'void' are OK (see DR#157).  */
!   if (b->prev == 0		            /* one binding */
!       && TREE_CODE (b->decl) == PARM_DECL   /* which is a parameter */
!       && !DECL_NAME (b->decl)               /* anonymous */
!       && VOID_TYPE_P (TREE_TYPE (b->decl))) /* of void type */
!     {
!       if (TREE_THIS_VOLATILE (b->decl)
! 	  || TREE_READONLY (b->decl)
! 	  || DECL_REGISTER (b->decl))
! 	error ("'void' as only parameter may not be qualified");
! 
!       /* There cannot be an ellipsis.  */
!       if (ellipsis)
! 	error ("'void' must be the only parameter");
! 
!       ARG_INFO_TYPES (arg_info) = void_list_node;
!       return arg_info;
!     }
! 
!   if (!ellipsis)
!     types = void_list_node;
! 
!   /* Break up the bindings list into parms, tags, types, and others;
!      apply sanity checks; purge the name-to-decl bindings.  */
!   while (b)
      {
!       tree decl = b->decl;
!       tree type = TREE_TYPE (decl);
!       const char *keyword;
  
!       switch (TREE_CODE (decl))
  	{
! 	case PARM_DECL:
! 	  if (b->id)
! 	    {
! #ifdef ENABLE_CHECKING
! 	      if (I_SYMBOL_BINDING (b->id) != b) abort ();
! #endif
! 	      I_SYMBOL_BINDING (b->id) = b->shadowed;
! 	    }
  
! 	  /* Check for forward decls that never got their actual decl.  */
! 	  if (TREE_ASM_WRITTEN (decl))
! 	    error ("%Jparameter '%D' has just a forward declaration",
! 		   decl, decl);
! 	  /* Check for (..., void, ...) and issue an error.  */
! 	  else if (VOID_TYPE_P (type) && !DECL_NAME (decl))
! 	    {
! 	      if (!gave_void_only_once_err)
! 		{
! 		  error ("'void' must be the only parameter");
! 		  gave_void_only_once_err = true;
! 		}
! 	    }
! 	  else
! 	    {
! 	      /* Valid parameter, add it to the list.  */
! 	      TREE_CHAIN (decl) = parms;
! 	      parms = decl;
! 
! 	      /* Since there is a prototype, args are passed in their
! 		 declared types.  The back end may override this later.  */
! 	      DECL_ARG_TYPE (decl) = type;
! 	      types = tree_cons (0, type, types);
! 	    }
! 	  break;
  
! 	case ENUMERAL_TYPE: keyword = "struct"; goto tag;
! 	case UNION_TYPE:    keyword = "union"; goto tag;
! 	case RECORD_TYPE:   keyword = "enum"; goto tag;
! 	tag:
! 	  /* Types may not have tag-names, in which case the type
! 	     appears in the bindings list with b->id NULL.  */
! 	  if (b->id)
! 	    {
! #ifdef ENABLE_CHECKING
! 	      if (I_TAG_BINDING (b->id) != b) abort ();
! #endif
! 	      I_TAG_BINDING (b->id) = b->shadowed;
! 	    }
  
! 	  /* Warn about any struct, union or enum tags defined in a
! 	     parameter list.  The scope of such types is limited to
! 	     the parameter list, which is rarely if ever desirable
! 	     (it's impossible to call such a function with type-
! 	     correct arguments).  An anonymous union parm type is
! 	     meaningful as a GNU extension, so don't warn for that.  */
! 	  if (TREE_CODE (decl) != UNION_TYPE || b->id != 0)
! 	    {
! 	      if (b->id)
! 		/* The %s will be one of 'struct', 'union', or 'enum'.  */
! 		warning ("'%s %E' declared inside parameter list",
! 			 keyword, b->id);
! 	      else
! 		/* 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,"
! 			   " which is probably not what you want");
! 		  explained_incomplete_types = true;
! 		}
! 	    }
  
! 	  tags = tree_cons (b->id, decl, tags);
! 	  break;
  
! 	case CONST_DECL:
! 	case TYPE_DECL:
! 	  /* CONST_DECLs appear here when we have an embedded enum,
! 	     and TYPE_DECLs appear here when we have an embedded struct
! 	     or union.  No warnings for this - we already warned about the
! 	     type itself.  */
! 	  if (b->id)
! 	    {
! #ifdef ENABLE_CHECKING
! 	      if (I_SYMBOL_BINDING (b->id) != b) abort ();
! #endif
! 	      I_SYMBOL_BINDING (b->id) = b->shadowed;
! 	    }
  
! 	  TREE_CHAIN (decl) = others;
! 	  others = decl;
! 	  break;
  
! 	  /* Other things that might be encountered.  */
! 	case LABEL_DECL:
! 	case FUNCTION_DECL:
! 	case VAR_DECL:
! 	case ERROR_MARK:
! 	default:
! 	  abort ();
  	}
  
!       b = free_binding_and_advance (b);
      }
  
!   ARG_INFO_PARMS  (arg_info) = parms;
!   ARG_INFO_TAGS   (arg_info) = tags;
!   ARG_INFO_TYPES  (arg_info) = types;
!   ARG_INFO_OTHERS (arg_info) = others;
!   return arg_info;
  }
  
  /* Get the struct, enum or union (CODE says which) with tag NAME.
*************** tree
*** 4916,4922 ****
  finish_struct (tree t, tree fieldlist, tree attributes)
  {
    tree x;
!   int toplevel = global_scope == current_scope;
    int saw_named_field;
  
    /* If this type was previously laid out as a forward reference,
--- 5054,5060 ----
  finish_struct (tree t, tree fieldlist, tree attributes)
  {
    tree x;
!   bool toplevel = file_scope == current_scope;
    int saw_named_field;
  
    /* If this type was previously laid out as a forward reference,
*************** finish_struct (tree t, tree fieldlist, t
*** 4926,4944 ****
  
    decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
  
-   /* Nameless union parm types are useful as GCC extension.  */
-   if (! (TREE_CODE (t) == UNION_TYPE && TYPE_NAME (t) == 0) && !pedantic)
-     /* Otherwise, warn about any struct or union def. in parmlist.  */
-     if (in_parm_level_p ())
-       {
- 	if (pedantic)
- 	  pedwarn ("%s defined inside parms",
- 		   TREE_CODE (t) == UNION_TYPE ? _("union") : _("structure"));
- 	else
- 	  warning ("%s defined inside parms",
- 		   TREE_CODE (t) == UNION_TYPE ? _("union") : _("structure"));
-       }
- 
    if (pedantic)
      {
        for (x = fieldlist; x; x = TREE_CHAIN (x))
--- 5064,5069 ----
*************** finish_struct (tree t, tree fieldlist, t
*** 5007,5017 ****
  	  && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
  	{
  	  if (TREE_CODE (t) == UNION_TYPE)
! 	    error ("%Jflexible array member in union", x);
  	  else if (TREE_CHAIN (x) != NULL_TREE)
! 	    error ("%Jflexible array member not at end of struct", x);
  	  else if (! saw_named_field)
! 	    error ("%Jflexible array member in otherwise empty struct", x);
  	}
  
        if (pedantic && TREE_CODE (t) == RECORD_TYPE
--- 5132,5151 ----
  	  && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
  	{
  	  if (TREE_CODE (t) == UNION_TYPE)
! 	    {
! 	      error ("%Jflexible array member in union", x);
! 	      TREE_TYPE (x) = error_mark_node;
! 	    }
  	  else if (TREE_CHAIN (x) != NULL_TREE)
! 	    {
! 	      error ("%Jflexible array member not at end of struct", x);
! 	      TREE_TYPE (x) = error_mark_node;
! 	    }
  	  else if (! saw_named_field)
! 	    {
! 	      error ("%Jflexible array member in otherwise empty struct", x);
! 	      TREE_TYPE (x) = error_mark_node;
! 	    }
  	}
  
        if (pedantic && TREE_CODE (t) == RECORD_TYPE
*************** start_enum (tree name)
*** 5205,5217 ****
  tree
  finish_enum (tree enumtype, tree values, tree attributes)
  {
!   tree pair, tem, minnode = 0, maxnode = 0;
!   int toplevel = (global_scope == current_scope);
    int precision, unsign;
    struct lang_type *lt;
  
-   if (in_parm_level_p ())
-     warning ("enum defined inside parms");
  
    decl_attributes (&enumtype, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
  
--- 5339,5350 ----
  tree
  finish_enum (tree enumtype, tree values, tree attributes)
  {
!   tree pair, tem;
!   tree minnode = 0, maxnode = 0;
    int precision, unsign;
+   bool toplevel = (file_scope == current_scope);
    struct lang_type *lt;
  
  
    decl_attributes (&enumtype, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
  
*************** build_enumerator (tree name, tree value)
*** 5344,5359 ****
  
    if (value != 0)
      {
!       if (TREE_CODE (value) == INTEGER_CST)
  	{
! 	  value = default_conversion (value);
! 	  constant_expression_warning (value);
  	}
        else
  	{
! 	  error ("enumerator value for `%s' not integer constant",
! 		 IDENTIFIER_POINTER (name));
! 	  value = 0;
  	}
      }
  
--- 5477,5495 ----
  
    if (value != 0)
      {
!       /* Don't issue more errors for error_mark_node (i.e. an
! 	 undeclared identifier) - just ignore the value expression.  */
!       if (value == error_mark_node)
! 	value = 0;
!       else if (TREE_CODE (value) != INTEGER_CST)
  	{
! 	  error ("enumerator value for '%E' is not an integer constant", name);
! 	  value = 0;
  	}
        else
  	{
! 	  value = default_conversion (value);
! 	  constant_expression_warning (value);
  	}
      }
  
*************** build_enumerator (tree name, tree value)
*** 5370,5375 ****
--- 5506,5513 ----
    if (pedantic && ! int_fits_type_p (value, integer_type_node))
      {
        pedwarn ("ISO C restricts enumerator values to range of `int'");
+       /* XXX This causes -pedantic to change the meaning of the program.
+ 	 Remove?  -zw 2004-03-15  */
        value = convert (integer_type_node, value);
      }
  
*************** start_function (tree declspecs, tree dec
*** 5455,5474 ****
    if (warn_about_return_type)
      pedwarn_c99 ("return type defaults to `int'");
  
-   /* Save the parm names or decls from this function's declarator
-      where store_parm_decls will find them.  */
-   current_function_parms = last_function_parms;
-   current_function_parm_tags = last_function_parm_tags;
-   current_function_parm_others = last_function_parm_others;
- 
    /* Make the init_value nonzero so pushdecl knows this is not tentative.
!      error_mark_node is replaced below (in poplevel) with the BLOCK.  */
    DECL_INITIAL (decl1) = error_mark_node;
  
    /* If this definition isn't a prototype and we had a prototype declaration
       before, copy the arg type info from that prototype.
       But not if what we had before was a builtin function.  */
!   old_decl = lookup_name_current_level (DECL_NAME (decl1));
    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)))
--- 5593,5606 ----
    if (warn_about_return_type)
      pedwarn_c99 ("return type defaults to `int'");
  
    /* Make the init_value nonzero so pushdecl knows this is not tentative.
!      error_mark_node is replaced below (in pop_scope) with the BLOCK.  */
    DECL_INITIAL (decl1) = error_mark_node;
  
    /* If this definition isn't a prototype and we had a prototype declaration
       before, copy the arg type info from that prototype.
       But not if what we had before was a builtin function.  */
!   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)))
*************** start_function (tree declspecs, tree dec
*** 5533,5539 ****
  #endif
  
    /* If #pragma weak was used, mark the decl weak now.  */
!   if (current_scope == global_scope)
      maybe_apply_pragma_weak (decl1);
  
    /* Warn for unlikely, improbable, or stupid declarations of `main'.  */
--- 5665,5671 ----
  #endif
  
    /* If #pragma weak was used, mark the decl weak now.  */
!   if (current_scope == file_scope)
      maybe_apply_pragma_weak (decl1);
  
    /* Warn for unlikely, improbable, or stupid declarations of `main'.  */
*************** start_function (tree declspecs, tree dec
*** 5599,5605 ****
  
    current_function_decl = pushdecl (decl1);
  
!   pushlevel (0);
    declare_parm_level ();
  
    make_decl_rtl (current_function_decl, NULL);
--- 5731,5737 ----
  
    current_function_decl = pushdecl (decl1);
  
!   push_scope ();
    declare_parm_level ();
  
    make_decl_rtl (current_function_decl, NULL);
*************** start_function (tree declspecs, tree dec
*** 5636,5734 ****
     need only record them as in effect and complain if any redundant
     old-style parm decls were written.  */
  static void
! store_parm_decls_newstyle (void)
  {
!   tree decl, last;
!   tree fndecl = current_function_decl;
!   tree parms = current_function_parms;
!   tree tags = current_function_parm_tags;
!   tree others = current_function_parm_others;
  
!   if (current_scope->parms || current_scope->names || current_scope->tags)
      {
        error ("%Jold-style parameter declarations in prototyped "
  	     "function definition", fndecl);
  
        /* Get rid of the old-style declarations.  */
!       poplevel (0, 0, 0);
!       pushlevel (0);
      }
  
    /* Now make all the parameter declarations visible in the function body.
       We can bypass most of the grunt work of pushdecl.  */
!   for (last = 0, decl = parms; decl; last = decl, decl = TREE_CHAIN (decl))
      {
        DECL_CONTEXT (decl) = current_function_decl;
!       if (DECL_NAME (decl) == 0)
! 	error ("%Jparameter name omitted", decl);
        else
! 	{
! 	  if (IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)))
! 	    current_scope->shadowed
! 	      = tree_cons (DECL_NAME (decl),
! 			   IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)),
! 			   current_scope->shadowed);
! 	  IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)) = decl;
! 	}
      }
-   current_scope->parms = parms;
-   current_scope->parms_last = last;
  
    /* Record the parameter list in the function declaration.  */
    DECL_ARGUMENTS (fndecl) = parms;
  
    /* Now make all the ancillary declarations visible, likewise.  */
!   for (last = 0, decl = others; decl; last = decl, decl = TREE_CHAIN (decl))
      {
        DECL_CONTEXT (decl) = current_function_decl;
!       if (DECL_NAME (decl)
! 	  && TYPE_MAIN_VARIANT (TREE_TYPE (decl)) != void_type_node)
! 	{
! 	  if (IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)))
! 	    current_scope->shadowed
! 	      = tree_cons (DECL_NAME (decl),
! 			   IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)),
! 			   current_scope->shadowed);
! 	  IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)) = decl;
! 	}
      }
-   current_scope->names = others;
-   current_scope->names_last = last;
  
    /* And all the tag declarations.  */
    for (decl = tags; decl; decl = TREE_CHAIN (decl))
      if (TREE_PURPOSE (decl))
!       {
! 	if (IDENTIFIER_TAG_VALUE (TREE_PURPOSE (decl)))
! 	  current_scope->shadowed_tags
! 	    = tree_cons (TREE_PURPOSE (decl),
! 			 IDENTIFIER_SYMBOL_VALUE (TREE_PURPOSE (decl)),
! 			 current_scope->shadowed_tags);
! 	IDENTIFIER_TAG_VALUE (TREE_PURPOSE (decl)) = TREE_VALUE (decl);
!       }
!   current_scope->tags = tags;
  }
  
  /* Subroutine of store_parm_decls which handles old-style function
     definitions (separate parameter list and declarations).  */
  
  static void
! store_parm_decls_oldstyle (void)
  {
    tree parm, decl, last;
!   tree fndecl = current_function_decl;
! 
!   /* This is the identifier list from the function declarator.  */
!   tree parmids = current_function_parms;
  
    /* We use DECL_WEAK as a flag to show which parameters have been
       seen already, since it is not used on PARM_DECL.  */
  #ifdef ENABLE_CHECKING
!   for (parm = current_scope->parms; parm; parm = TREE_CHAIN (parm))
!     if (DECL_WEAK (parm))
        abort ();
  #endif
  
    /* Match each formal parameter name with its declaration.  Save each
       decl in the appropriate TREE_PURPOSE slot of the parmids chain.  */
    for (parm = parmids; parm; parm = TREE_CHAIN (parm))
--- 5768,5848 ----
     need only record them as in effect and complain if any redundant
     old-style parm decls were written.  */
  static void
! store_parm_decls_newstyle (tree fndecl, tree arg_info)
  {
!   tree decl;
!   tree parms  = ARG_INFO_PARMS  (arg_info);
!   tree tags   = ARG_INFO_TAGS   (arg_info);
!   tree others = ARG_INFO_OTHERS (arg_info);
  
!   if (current_scope->bindings)
      {
        error ("%Jold-style parameter declarations in prototyped "
  	     "function definition", fndecl);
  
        /* Get rid of the old-style declarations.  */
!       pop_scope ();
!       push_scope ();
      }
+   /* Don't issue this warning for nested functions, and don't issue this
+      warning if we got here because ARG_INFO_TYPES was error_mark_node
+      (this happens when a function definition has just an ellipsis in
+      its parameter list).  */
+   else if (warn_traditional && !in_system_header
+ 	   && DECL_CONTEXT (fndecl) == current_file_decl
+ 	   && ARG_INFO_TYPES (arg_info) != error_mark_node)
+     warning ("%Jtraditional C rejects ISO C style function definitions",
+ 	     fndecl);
  
    /* Now make all the parameter declarations visible in the function body.
       We can bypass most of the grunt work of pushdecl.  */
!   for (decl = parms; decl; decl = TREE_CHAIN (decl))
      {
        DECL_CONTEXT (decl) = current_function_decl;
!       if (DECL_NAME (decl))
! 	bind (DECL_NAME (decl), decl, current_scope);
        else
! 	error ("%Jparameter name omitted", decl);
      }
  
    /* Record the parameter list in the function declaration.  */
    DECL_ARGUMENTS (fndecl) = parms;
  
    /* Now make all the ancillary declarations visible, likewise.  */
!   for (decl = others; decl; decl = TREE_CHAIN (decl))
      {
        DECL_CONTEXT (decl) = current_function_decl;
!       if (DECL_NAME (decl))
! 	bind (DECL_NAME (decl), decl, current_scope);
      }
  
    /* 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);
  }
  
  /* Subroutine of store_parm_decls which handles old-style function
     definitions (separate parameter list and declarations).  */
  
  static void
! store_parm_decls_oldstyle (tree fndecl, tree arg_info)
  {
+   struct c_binding *b;
    tree parm, decl, last;
!   tree parmids = ARG_INFO_PARMS (arg_info);
  
    /* We use DECL_WEAK as a flag to show which parameters have been
       seen already, since it is not used on PARM_DECL.  */
  #ifdef ENABLE_CHECKING
!   for (b = current_scope->bindings; b; b = b->prev)
!     if (TREE_CODE (b->decl) == PARM_DECL && DECL_WEAK (b->decl))
        abort ();
  #endif
  
+   if (warn_old_style_definition && !in_system_header)
+     warning ("%Jold-style function definition", fndecl);
+ 
    /* Match each formal parameter name with its declaration.  Save each
       decl in the appropriate TREE_PURPOSE slot of the parmids chain.  */
    for (parm = parmids; parm; parm = TREE_CHAIN (parm))
*************** store_parm_decls_oldstyle (void)
*** 5740,5756 ****
  	  continue;
  	}
  
!       decl = IDENTIFIER_SYMBOL_VALUE (TREE_VALUE (parm));
!       if (decl && DECL_CONTEXT (decl) == fndecl)
  	{
  	  /* If we got something other than a PARM_DECL it is an error.  */
  	  if (TREE_CODE (decl) != PARM_DECL)
! 	    error ("%J\"%D\" declared as a non-parameter", decl, decl);
  	  /* If the declaration is already marked, we have a duplicate
  	     name.  Complain and ignore the duplicate.  */
  	  else if (DECL_WEAK (decl))
  	    {
! 	      error ("%Jmultiple parameters named \"%D\"", decl, decl);
  	      TREE_PURPOSE (parm) = 0;
  	      continue;
  	    }
--- 5854,5871 ----
  	  continue;
  	}
  
!       b = I_SYMBOL_BINDING (TREE_VALUE (parm));
!       if (b && b->contour == current_scope)
  	{
+ 	  decl = b->decl;
  	  /* If we got something other than a PARM_DECL it is an error.  */
  	  if (TREE_CODE (decl) != PARM_DECL)
! 	    error ("%J'%D' declared as a non-parameter", decl, decl);
  	  /* If the declaration is already marked, we have a duplicate
  	     name.  Complain and ignore the duplicate.  */
  	  else if (DECL_WEAK (decl))
  	    {
! 	      error ("%Jmultiple parameters named '%D'", decl, decl);
  	      TREE_PURPOSE (parm) = 0;
  	      continue;
  	    }
*************** store_parm_decls_oldstyle (void)
*** 5758,5764 ****
  	     an int.  */
  	  else if (VOID_TYPE_P (TREE_TYPE (decl)))
  	    {
! 	      error ("%Jparameter \"%D\" declared void", decl, decl);
  	      TREE_TYPE (decl) = integer_type_node;
  	      DECL_ARG_TYPE (decl) = integer_type_node;
  	      layout_decl (decl, 0);
--- 5873,5879 ----
  	     an int.  */
  	  else if (VOID_TYPE_P (TREE_TYPE (decl)))
  	    {
! 	      error ("%Jparameter '%D' declared with void type", decl, decl);
  	      TREE_TYPE (decl) = integer_type_node;
  	      DECL_ARG_TYPE (decl) = integer_type_node;
  	      layout_decl (decl, 0);
*************** store_parm_decls_oldstyle (void)
*** 5773,5781 ****
  	  pushdecl (decl);
  
  	  if (flag_isoc99)
! 	    pedwarn ("%Jtype of \"%D\" defaults to \"int\"", decl, decl);
  	  else if (extra_warnings)
! 	    warning ("%Jtype of \"%D\" defaults to \"int\"", decl, decl);
  	}
  
        TREE_PURPOSE (parm) = decl;
--- 5888,5896 ----
  	  pushdecl (decl);
  
  	  if (flag_isoc99)
! 	    pedwarn ("%Jtype of '%D' defaults to 'int'", decl, decl);
  	  else if (extra_warnings)
! 	    warning ("%Jtype of '%D' defaults to 'int'", decl, decl);
  	}
  
        TREE_PURPOSE (parm) = decl;
*************** store_parm_decls_oldstyle (void)
*** 5785,5801 ****
    /* Now examine the parms chain for incomplete declarations
       and declarations with no corresponding names.  */
  
!   for (parm = current_scope->parms; parm; parm = TREE_CHAIN (parm))
      {
        if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
  	{
! 	  error ("%Jparameter \"%D\" has incomplete type", parm, parm);
  	  TREE_TYPE (parm) = error_mark_node;
  	}
  
        if (! DECL_WEAK (parm))
  	{
! 	  error ("%Jdeclaration for parameter \"%D\" but no such parameter",
  		 parm, parm);
  
  	  /* Pretend the parameter was not missing.
--- 5900,5920 ----
    /* Now examine the parms chain for incomplete declarations
       and declarations with no corresponding names.  */
  
!   for (b = current_scope->bindings; b; b = b->prev)
      {
+       parm = b->decl;
+       if (TREE_CODE (parm) != PARM_DECL)
+ 	continue;
+ 
        if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
  	{
! 	  error ("%Jparameter '%D' has incomplete type", parm, parm);
  	  TREE_TYPE (parm) = error_mark_node;
  	}
  
        if (! DECL_WEAK (parm))
  	{
! 	  error ("%Jdeclaration for parameter '%D' but no such parameter",
  		 parm, parm);
  
  	  /* Pretend the parameter was not missing.
*************** store_parm_decls_oldstyle (void)
*** 5817,5823 ****
      {
        last = TREE_PURPOSE (parm);
        DECL_ARGUMENTS (fndecl) = last;
-       current_scope->parms = last;
        DECL_WEAK (last) = 0;
  
        for (parm = TREE_CHAIN (parm); parm; parm = TREE_CHAIN (parm))
--- 5936,5941 ----
*************** store_parm_decls_oldstyle (void)
*** 5827,5833 ****
  	    last = TREE_PURPOSE (parm);
  	    DECL_WEAK (last) = 0;
  	  }
-       current_scope->parms_last = last;
        TREE_CHAIN (last) = 0;
      }
  
--- 5945,5950 ----
*************** store_parm_decls_oldstyle (void)
*** 5877,5883 ****
  
  		  if (pedantic)
  		    {
! 		      pedwarn ("promoted argument \"%D\" "
  			       "doesn't match prototype", parm);
  		      pedwarn ("%Hprototype declaration",
  			       &current_function_prototype_locus);
--- 5994,6000 ----
  
  		  if (pedantic)
  		    {
! 		      pedwarn ("promoted argument '%D' "
  			       "doesn't match prototype", parm);
  		      pedwarn ("%Hprototype declaration",
  			       &current_function_prototype_locus);
*************** store_parm_decls_oldstyle (void)
*** 5885,5891 ****
  		}
  	      else
  		{
! 		  error ("argument \"%D\" doesn't match prototype", parm);
  		  error ("%Hprototype declaration",
  			 &current_function_prototype_locus);
  		}
--- 6002,6008 ----
  		}
  	      else
  		{
! 		  error ("argument '%D' doesn't match prototype", parm);
  		  error ("%Hprototype declaration",
  			 &current_function_prototype_locus);
  		}
*************** store_parm_decls (void)
*** 5963,5985 ****
    /* The function containing FNDECL, if any.  */
    tree context = decl_function_context (fndecl);
  
!   /* True if this definition is written with a prototype.  */
!   bool prototype = (current_function_parms
! 		    && TREE_CODE (current_function_parms) != TREE_LIST);
  
!   if (prototype)
!     store_parm_decls_newstyle ();
    else
!     store_parm_decls_oldstyle ();
  
!   /* The next call to pushlevel will be a function body.  */
  
    next_is_function_body = true;
  
    /* Write a record describing this function definition to the prototypes
       file (if requested).  */
  
!   gen_aux_info_record (fndecl, 1, 0, prototype);
  
    /* Initialize the RTL code for the function.  */
    allocate_struct_function (fndecl);
--- 6080,6108 ----
    /* The function containing FNDECL, if any.  */
    tree context = decl_function_context (fndecl);
  
!   /* The argument information block for FNDECL.  */
!   tree arg_info = DECL_ARGUMENTS (fndecl);
! 
!   /* True if this definition is written with a prototype.  Note:
!      despite C99 6.7.5.3p14, we can *not* treat an empty argument
!      list in a function definition as equivalent to (void) -- an
!      empty argument list specifies the function has no parameters,
!      but only (void) sets up a prototype for future calls.  */
!   bool proto = ARG_INFO_TYPES (arg_info) != 0;
  
!   if (proto)
!     store_parm_decls_newstyle (fndecl, arg_info);
    else
!     store_parm_decls_oldstyle (fndecl, arg_info);
  
!   /* The next call to push_scope will be a function body.  */
  
    next_is_function_body = true;
  
    /* Write a record describing this function definition to the prototypes
       file (if requested).  */
  
!   gen_aux_info_record (fndecl, 1, 0, proto);
  
    /* Initialize the RTL code for the function.  */
    allocate_struct_function (fndecl);
*************** finish_function (void)
*** 6060,6076 ****
    /* When a function declaration is totally empty, e.g.
          void foo(void) { }
       (the argument list is irrelevant) the compstmt rule will not
!      bother calling pushlevel/poplevel, 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 pushlevel does not actually push another
       scope - see there for details.  */
  
    if (current_scope->parm_flag && next_is_function_body)
      {
!       pushlevel (0);
!       poplevel (0, 0, 0);
      }
  
    if (TREE_CODE (fndecl) == FUNCTION_DECL
--- 6183,6199 ----
    /* 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
*************** c_expand_body_1 (tree fndecl, int nested
*** 6201,6208 ****
    if (DECL_STATIC_CONSTRUCTOR (fndecl))
      {
        if (targetm.have_ctors_dtors)
! 	(* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
! 				         DEFAULT_INIT_PRIORITY);
        else
  	static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
      }
--- 6324,6331 ----
    if (DECL_STATIC_CONSTRUCTOR (fndecl))
      {
        if (targetm.have_ctors_dtors)
! 	targetm.asm_out.constructor (XEXP (DECL_RTL (fndecl), 0),
! 				     DEFAULT_INIT_PRIORITY);
        else
  	static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
      }
*************** c_expand_body_1 (tree fndecl, int nested
*** 6210,6217 ****
    if (DECL_STATIC_DESTRUCTOR (fndecl))
      {
        if (targetm.have_ctors_dtors)
! 	(* targetm.asm_out.destructor) (XEXP (DECL_RTL (fndecl), 0),
! 				        DEFAULT_INIT_PRIORITY);
        else
  	static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
      }
--- 6333,6340 ----
    if (DECL_STATIC_DESTRUCTOR (fndecl))
      {
        if (targetm.have_ctors_dtors)
! 	targetm.asm_out.destructor (XEXP (DECL_RTL (fndecl), 0),
! 				    DEFAULT_INIT_PRIORITY);
        else
  	static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
      }
*************** c_expand_body (tree fndecl)
*** 6232,6238 ****
  void
  check_for_loop_decls (void)
  {
!   tree t;
  
    if (!flag_isoc99)
      {
--- 6355,6361 ----
  void
  check_for_loop_decls (void)
  {
!   struct c_binding *b;
  
    if (!flag_isoc99)
      {
*************** check_for_loop_decls (void)
*** 6256,6290 ****
       interpretation, to avoid creating an extension which later causes
       problems.  */
  
!   for (t = current_scope->tags; t; t = TREE_CHAIN (t))
      {
!       if (TREE_PURPOSE (t) != 0)
!         {
!           enum tree_code code = TREE_CODE (TREE_VALUE (t));
  
!           if (code == RECORD_TYPE)
!             error ("'struct %s' declared in 'for' loop initial declaration",
!                    IDENTIFIER_POINTER (TREE_PURPOSE (t)));
!           else if (code == UNION_TYPE)
!             error ("'union %s' declared in 'for' loop initial declaration",
!                    IDENTIFIER_POINTER (TREE_PURPOSE (t)));
!           else
!             error ("'enum %s' declared in 'for' loop initial declaration",
!                    IDENTIFIER_POINTER (TREE_PURPOSE (t)));
!         }
!     }
  
!   for (t = current_scope->names; t; t = TREE_CHAIN (t))
!     {
!       if (TREE_CODE (t) != VAR_DECL && DECL_NAME (t))
! 	error ("%Jdeclaration of non-variable '%D' in 'for' loop "
!                "initial declaration", t, t);
!       else if (TREE_STATIC (t))
! 	error ("%Jdeclaration of static variable '%D' in 'for' loop "
! 	       "initial declaration", t, t);
!       else if (DECL_EXTERNAL (t))
! 	error ("%Jdeclaration of 'extern' variable '%D' in 'for' loop "
!                "initial declaration", t, t);
      }
  }
  
--- 6379,6416 ----
       interpretation, to avoid creating an extension which later causes
       problems.  */
  
!   for (b = current_scope->bindings; b; b = b->prev)
      {
!       tree id = b->id;
!       tree decl = b->decl;
  
!       if (!id)
! 	continue;
  
!       switch (TREE_CODE (decl))
! 	{
! 	case VAR_DECL:
! 	  if (TREE_STATIC (decl))
! 	    error ("%Jdeclaration of static variable '%D' in 'for' loop "
! 		   "initial declaration", decl, decl);
! 	  else if (DECL_EXTERNAL (decl))
! 	    error ("%Jdeclaration of 'extern' variable '%D' in 'for' loop "
! 		   "initial declaration", decl, decl);
! 	  break;
! 
! 	case RECORD_TYPE:
! 	  error ("'struct %E' declared in 'for' loop initial declaration", id);
! 	  break;
! 	case UNION_TYPE:
! 	  error ("'union %E' declared in 'for' loop initial declaration", id);
! 	  break;
! 	case ENUMERAL_TYPE:
! 	  error ("'enum %E' declared in 'for' loop initial declaration", id);
! 	  break;
! 	default:
! 	  error ("%Jdeclaration of non-variable '%D' in 'for' loop "
! 		 "initial declaration", decl, decl);
! 	}
      }
  }
  
*************** c_expand_decl (tree decl)
*** 6450,6465 ****
  tree
  identifier_global_value	(tree t)
  {
!   tree decl = IDENTIFIER_SYMBOL_VALUE (t);
!   if (decl == 0 || DECL_FILE_SCOPE_P (decl))
!     return decl;
  
!   /* Shadowed by something else; find the true global value.  */
!   for (decl = global_scope->names; decl; decl = TREE_CHAIN (decl))
!     if (DECL_NAME (decl) == t)
!       return decl;
  
-   /* Only local values for this decl.  */
    return 0;
  }
  
--- 6576,6587 ----
  tree
  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)
!       return b->decl;
  
    return 0;
  }
  
*************** void
*** 6470,6483 ****
  record_builtin_type (enum rid rid_index, const char *name, tree type)
  {
    tree id;
-   tree tdecl;
    if (name == 0)
      id = ridpointers[(int) rid_index];
    else
      id = get_identifier (name);
!   tdecl = build_decl (TYPE_DECL, id, type);
!   pushdecl (tdecl);
!   debug_hooks->type_decl (tdecl, 0);
  }
  
  /* Build the void_list_node (void_type_node having been created).  */
--- 6592,6602 ----
  record_builtin_type (enum rid rid_index, const char *name, tree type)
  {
    tree id;
    if (name == 0)
      id = ridpointers[(int) rid_index];
    else
      id = get_identifier (name);
!   pushdecl (build_decl (TYPE_DECL, id, type));
  }
  
  /* Build the void_list_node (void_type_node having been created).  */
*************** c_static_assembler_name (tree decl)
*** 6524,6701 ****
      lhd_set_decl_assembler_name (decl);
  }
  
! /* Hash and equality functions for link_hash_table: key off
!    DECL_ASSEMBLER_NAME.  */
! 
! static hashval_t
! link_hash_hash (const void *x_p)
! {
!   tree x = (tree)x_p;
!   return (hashval_t) (long)DECL_ASSEMBLER_NAME (x);
! }
! 
! static int
! link_hash_eq (const void *x1_p, const void *x2_p)
! {
!   tree x1 = (tree)x1_p;
!   tree x2 = (tree)x2_p;
!   return DECL_ASSEMBLER_NAME (x1) == DECL_ASSEMBLER_NAME (x2);
! }
! 
! /* Propagate information between definitions and uses between multiple
!    translation units in TU_LIST based on linkage rules.  */
! 
! void
! merge_translation_unit_decls (void)
  {
!   const tree tu_list = current_file_decl;
!   tree tu;
    tree decl;
!   htab_t link_hash_table;
!   tree block;
! 
!   /* Create the BLOCK that poplevel would have created, but don't
!      actually call poplevel since that's expensive.  */
!   block = make_node (BLOCK);
!   BLOCK_VARS (block) = current_scope->names;
!   TREE_USED (block) = 1;
!   DECL_INITIAL (current_file_decl) = block;
! 
!   /* If only one translation unit seen, no copying necessary.  */
!   if (TREE_CHAIN (tu_list) == NULL_TREE)
!     return;
! 
!   link_hash_table = htab_create (1021, link_hash_hash, link_hash_eq, NULL);
! 
!   /* Enter any actual definitions into the hash table.  */
!   for (tu = tu_list; tu; tu = TREE_CHAIN (tu))
!     for (decl = BLOCK_VARS (DECL_INITIAL (tu)); decl; decl = TREE_CHAIN 
(decl))
!       if (TREE_PUBLIC (decl) && ! DECL_EXTERNAL (decl))
! 	{
! 	  PTR *slot;
! 	  slot = htab_find_slot (link_hash_table, decl, INSERT);
! 
! 	  /* If we've already got a definition, work out which one is
! 	     the real one, put it into the hash table, and make the
! 	     other one DECL_EXTERNAL.  This is important to avoid
! 	     putting out two definitions of the same symbol in the
! 	     assembly output.  */
! 	  if (*slot != NULL)
! 	    {
! 	      tree old_decl = (tree) *slot;
! 
! 	      /* If this is weak or common or whatever, suppress it
! 		 in favor of the other definition.  */
! 	      if (DECL_WEAK (decl))
! 		DECL_EXTERNAL (decl) = 1;
! 	      else if (DECL_WEAK (old_decl) && ! DECL_WEAK (decl))
! 		DECL_EXTERNAL (old_decl) = 1;
! 	      else if (DECL_COMMON (decl) || DECL_ONE_ONLY (decl))
! 		DECL_EXTERNAL (decl) = 1;
! 	      else if (DECL_COMMON (old_decl) || DECL_ONE_ONLY (old_decl))
! 		DECL_EXTERNAL (old_decl) = 1;
! 
! 	      if (DECL_EXTERNAL (decl))
! 		{
! 		  DECL_INITIAL (decl) = NULL_TREE;
! 		  DECL_COMMON (decl) = 0;
! 		  DECL_ONE_ONLY (decl) = 0;
! 		  DECL_WEAK (decl) = 0;
! 		}
! 	      else if (DECL_EXTERNAL (old_decl))
! 		{
! 		  DECL_INITIAL (old_decl) = NULL_TREE;
! 		  DECL_COMMON (old_decl) = 0;
! 		  DECL_ONE_ONLY (old_decl) = 0;
! 		  DECL_WEAK (old_decl) = 0;
! 		  *slot = decl;
! 		}
! 	      else
! 		{
! 		  error ("%Jredefinition of global '%D'", decl, decl);
! 		  error ("%J'%D' previously defined here", old_decl, old_decl);
! 		}
! 	    }
! 	  else
! 	    *slot = decl;
! 	}
! 
!   /* Now insert the desired information from all the definitions
!      into any plain declarations.  */
!   for (tu = tu_list; tu; tu = TREE_CHAIN (tu))
!     for (decl = BLOCK_VARS (DECL_INITIAL (tu)); decl; decl = TREE_CHAIN 
(decl))
!       if (TREE_PUBLIC (decl) && DECL_EXTERNAL (decl))
! 	{
! 	  tree global_decl;
! 	  global_decl = htab_find (link_hash_table, decl);
! 
! 	  if (! global_decl)
! 	    continue;
! 
! 	  /* Print any appropriate error messages, and partially merge
! 	     the decls.  */
! 	  (void) duplicate_decls (decl, global_decl);
! 	}
  
!   htab_delete (link_hash_table);
  }
  
- /* Perform final processing on file-scope data.  */
- 
  void
! c_write_global_declarations(void)
  {
!   tree link;
! 
!   for (link = current_file_decl; link; link = TREE_CHAIN (link))
!     {
!       tree globals = BLOCK_VARS (DECL_INITIAL (link));
!       int len = list_length (globals);
!       tree *vec = xmalloc (sizeof (tree) * len);
!       int 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);
! 
!       /* Clean up.  */
!       free (vec);
!     }
! }
  
! /* Reset the parser's state in preparation for a new file.  */
  
! void
! c_reset_state (void)
! {
!   tree link;
!   tree file_scope_decl;
  
!   /* Pop the global scope.  */
!   if (current_scope != global_scope)
!       current_scope = global_scope;
!   file_scope_decl = current_file_decl;
!   DECL_INITIAL (file_scope_decl) = poplevel (1, 0, 0);
!   BLOCK_SUPERCONTEXT (DECL_INITIAL (file_scope_decl)) = file_scope_decl;
!   truly_local_externals = NULL_TREE;
! 
!   /* Start a new global binding level.  */
!   pushlevel (0);
!   global_scope = current_scope;
!   current_file_decl = build_decl (TRANSLATION_UNIT_DECL, NULL, NULL);
!   TREE_CHAIN (current_file_decl) = file_scope_decl;
! 
!   /* Reintroduce the builtin declarations.  */
!   for (link = first_builtin_decl;
!        link != TREE_CHAIN (last_builtin_decl);
!        link = TREE_CHAIN (link))
!     pushdecl (copy_node (link));
  }
  
  #include "gt-c-decl.h"
--- 6643,6684 ----
      lhd_set_decl_assembler_name (decl);
  }
  
! /* Perform final processing on file-scope data.  */
! static void
! c_write_global_declarations_1 (tree globals)
  {
!   size_t len = list_length (globals);
!   tree *vec = xmalloc (sizeof (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;
  
!   /* We don't want to do this if generating a PCH.  */
!   if (pch_file)
!     return;
  
!   /* Process all file scopes in this compilation.  */
!   for (t = current_file_decl; 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));
  }
  
  #include "gt-c-decl.h"
Index: c-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lang.c,v
retrieving revision 1.94.2.21
diff -c -p -r1.94.2.21 c-lang.c
*** c-lang.c	16 Mar 2004 22:16:29 -0000	1.94.2.21
--- c-lang.c	24 Mar 2004 18:24:47 -0000
*************** enum c_language_kind c_language = clk_c;
*** 68,73 ****
--- 68,75 ----
  #define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable
  #undef LANG_HOOKS_PARSE_FILE
  #define LANG_HOOKS_PARSE_FILE c_common_parse_file
+ #undef LANG_HOOKS_CLEAR_BINDING_STACK
+ #define LANG_HOOKS_CLEAR_BINDING_STACK lhd_do_nothing
  #undef LANG_HOOKS_TRUTHVALUE_CONVERSION
  #define LANG_HOOKS_TRUTHVALUE_CONVERSION c_objc_common_truthvalue_conversion
  #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
*************** enum c_language_kind c_language = clk_c;
*** 143,148 ****
--- 145,163 ----
  #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
  #define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
  
+ /* The C front end's scoping structure is very different from
+    that expected by the language-independent code; it is best
+    to disable all of pushlevel, poplevel, set_block, and getdecls.
+    This means it must also provide its own write_globals.  */
+ 
+ #undef LANG_HOOKS_PUSHLEVEL
+ #define LANG_HOOKS_PUSHLEVEL lhd_do_nothing_i
+ #undef LANG_HOOKS_POPLEVEL
+ #define LANG_HOOKS_POPLEVEL lhd_do_nothing_iii_return_null_tree
+ #undef LANG_HOOKS_SET_BLOCK
+ #define LANG_HOOKS_SET_BLOCK lhd_do_nothing_t
+ #undef LANG_HOOKS_GETDECLS
+ #define LANG_HOOKS_GETDECLS lhd_return_null_tree_v
  #undef LANG_HOOKS_WRITE_GLOBALS
  #define LANG_HOOKS_WRITE_GLOBALS c_write_global_declarations
  
Index: c-mudflap.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/c-mudflap.c,v
retrieving revision 1.1.2.11
diff -c -p -r1.1.2.11 c-mudflap.c
*** c-mudflap.c	30 Jan 2004 21:30:34 -0000	1.1.2.11
--- c-mudflap.c	24 Mar 2004 18:24:47 -0000
*************** mflang_flush_calls (tree enqueued_call_s
*** 85,98 ****
    mf_mark (current_function_decl);
  
    body = c_begin_compound_stmt ();
!   pushlevel (0);
    clear_last_expr ();
    add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
  
    c_expand_expr_stmt (enqueued_call_stmt_chain);
  
    scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
!   block = poplevel (0, 0, 0);
    SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
    SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
    RECHAIN_STMTS (body, COMPOUND_BODY (body));
--- 85,98 ----
    mf_mark (current_function_decl);
  
    body = c_begin_compound_stmt ();
!   push_scope ();
    clear_last_expr ();
    add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
  
    c_expand_expr_stmt (enqueued_call_stmt_chain);
  
    scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
!   block = pop_scope ();
    SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
    SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
    RECHAIN_STMTS (body, COMPOUND_BODY (body));
Index: c-objc-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-objc-common.c,v
retrieving revision 1.14.2.26
diff -c -p -r1.14.2.26 c-objc-common.c
*** c-objc-common.c	2 Mar 2004 18:41:23 -0000	1.14.2.26
--- c-objc-common.c	24 Mar 2004 18:24:47 -0000
*************** start_cdtor (int method_type)
*** 204,210 ****
  
    body = c_begin_compound_stmt ();
  
!   pushlevel (0);
    clear_last_expr ();
    add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
  
--- 204,210 ----
  
    body = c_begin_compound_stmt ();
  
!   push_scope ();
    clear_last_expr ();
    add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
  
*************** finish_cdtor (tree body)
*** 218,224 ****
    tree block;
  
    scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
!   block = poplevel (0, 0, 0);
    SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
    SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
  
--- 218,224 ----
    tree block;
  
    scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
!   block = pop_scope ();
    SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
    SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
  
*************** c_objc_common_finish_file (void)
*** 234,243 ****
  {
    if (pch_file)
      c_common_write_pch ();
- 
-   /* If multiple translation units were built, copy information between
-      them based on linkage rules.  */
-   merge_translation_unit_decls ();
  
    cgraph_finalize_compilation_unit ();
    cgraph_optimize ();
--- 234,239 ----
Index: c-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.7.2.30
diff -c -p -r1.7.2.30 c-opts.c
*** c-opts.c	5 Mar 2004 23:48:04 -0000	1.7.2.30
--- c-opts.c	24 Mar 2004 18:24:49 -0000
*************** c_common_init (void)
*** 1207,1247 ****
  /* Initialize the integrated preprocessor after debug output has been
     initialized; loop over each input file.  */
  void
! c_common_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
  {
-   unsigned file_index;
-   
  #if YYDEBUG != 0
    yydebug = set_yydebug;
  #else
!   warning ("YYDEBUG not defined");
  #endif
  
!   file_index = 0;
!   
!   do
!     {
!       if (file_index > 0)
! 	{
! 	  /* Reset the state of the parser.  */
! 	  c_reset_state();
  
! 	  /* Reset cpplib's macros and start a new file.  */
! 	  cpp_undef_all (parse_in);
! 	  main_input_filename = this_input_filename
! 	    = cpp_read_main_file (parse_in, in_fnames[file_index]);
! 	  if (this_input_filename == NULL)
! 	    break;
! 	}
!       finish_options ();
!       if (file_index == 0)
! 	pch_init();
!       c_parse_file ();
! 
!       file_index++;
!     } while (file_index < num_in_fnames);
!   
    finish_file ();
  }
  
  /* Common finish hook for the C, ObjC and C++ front ends.  */
--- 1207,1230 ----
  /* Initialize the integrated preprocessor after debug output has been
     initialized; loop over each input file.  */
  void
! c_common_parse_file (int set_yydebug)
  {
  #if YYDEBUG != 0
    yydebug = set_yydebug;
  #else
!   if (set_yydebug)
!     warning ("YYDEBUG not defined");
  #endif
  
!   if (num_in_fnames > 1)
!     fatal_error ("sorry, inter-module analysis temporarily out of 
commission");
  
!   finish_options ();
!   pch_init ();
!   push_file_scope ();
!   c_parse_file ();
    finish_file ();
+   pop_file_scope ();
  }
  
  /* Common finish hook for the C, ObjC and C++ front ends.  */
Index: c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.144.2.30
diff -c -p -r1.144.2.30 c-parse.in
*** c-parse.in	2 Mar 2004 18:41:23 -0000	1.144.2.30
--- c-parse.in	24 Mar 2004 18:24:54 -0000
*************** do {									\
*** 208,214 ****
  %type <ttype> any_word
  
  %type <ttype> compstmt compstmt_start compstmt_nostart compstmt_primary_start
! %type <ttype> do_stmt_start poplevel stmt label
  
  %type <ttype> c99_block_start c99_block_end
  %type <ttype> declarator
--- 208,214 ----
  %type <ttype> any_word
  
  %type <ttype> compstmt compstmt_start compstmt_nostart compstmt_primary_start
! %type <ttype> do_stmt_start pop_scope stmt label
  
  %type <ttype> c99_block_start c99_block_end
  %type <ttype> declarator
*************** static int objc_need_raw_identifier;
*** 328,335 ****
  #define OBJC_NEED_RAW_IDENTIFIER(VAL)	/* nothing */
  @@end_ifc
  
- static bool parsing_iso_function_signature;
- 
  /* Tell yyparse how to print a token's value, if yydebug is set.  */
  
  #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
--- 328,333 ----
*************** extdefs:
*** 368,378 ****
  	;
  
  extdef:
- 	extdef_1
- 	{ parsing_iso_function_signature = false; } /* Reset after any external 
definition.  */
- 	;
- 
- extdef_1:
  	fndef
  	| datadef
  	| asmdef
--- 366,371 ----
*************** primary:
*** 742,769 ****
  	;
  
  old_style_parm_decls:
- 	old_style_parm_decls_1
- 	{
- 	  parsing_iso_function_signature = false; /* Reset after decls.  */
- 	}
- 	;
- 
- old_style_parm_decls_1:
  	/* empty */
- 	{
- 	  if (warn_traditional && !in_system_header
- 	      && parsing_iso_function_signature)
- 	    warning ("traditional C rejects ISO C style function definitions");
- 	  if (warn_old_style_definition && !in_system_header
- 	      && !parsing_iso_function_signature)
- 	    warning ("old-style parameter declaration");
- 	  parsing_iso_function_signature = false; /* Reset after warning.  */
- 	}
  	| datadecls
- 	{
- 	  if (warn_old_style_definition && !in_system_header)
- 	    warning ("old-style parameter declaration");
- 	}
  	;
  
  /* The following are analogous to lineno_decl, decls and decl
--- 735,742 ----
*************** nested_function:
*** 1556,1562 ****
  		      pop_function_context ();
  		      YYERROR1;
  		    }
- 		  parsing_iso_function_signature = false; /* Don't warn about nested 
functions.  */
  		}
  	   old_style_parm_decls save_location
  		{ tree decl = current_function_decl;
--- 1529,1534 ----
*************** notype_nested_function:
*** 1587,1593 ****
  		      pop_function_context ();
  		      YYERROR1;
  		    }
- 		  parsing_iso_function_signature = false; /* Don't warn about nested 
functions.  */
  		}
  	  old_style_parm_decls save_location
  		{ tree decl = current_function_decl;
--- 1559,1564 ----
*************** after_type_declarator:
*** 1621,1629 ****
  		{ $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; }
  	| after_type_declarator '(' parmlist_or_identifiers  %prec '.'
  		{ $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
- /*	| after_type_declarator '(' error ')'  %prec '.'
- 		{ $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
- 		  poplevel (0, 0, 0); }  */
  	| after_type_declarator array_declarator  %prec '.'
  		{ $$ = set_array_declarator_type ($2, $1, 0); }
  	| '*' maybe_type_quals_attrs after_type_declarator  %prec UNARY
--- 1592,1597 ----
*************** parm_declarator:
*** 1646,1654 ****
  parm_declarator_starttypename:
  	  parm_declarator_starttypename '(' parmlist_or_identifiers  %prec '.'
  		{ $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
- /*	| parm_declarator_starttypename '(' error ')'  %prec '.'
- 		{ $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
- 		  poplevel (0, 0, 0); }  */
  	| parm_declarator_starttypename array_declarator  %prec '.'
  		{ $$ = set_array_declarator_type ($2, $1, 0); }
  	| TYPENAME
--- 1614,1619 ----
*************** parm_declarator_starttypename:
*** 1660,1668 ****
  parm_declarator_nostarttypename:
  	  parm_declarator_nostarttypename '(' parmlist_or_identifiers  %prec '.'
  		{ $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
- /*	| parm_declarator_nostarttypename '(' error ')'  %prec '.'
- 		{ $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
- 		  poplevel (0, 0, 0); }  */
  	| parm_declarator_nostarttypename array_declarator  %prec '.'
  		{ $$ = set_array_declarator_type ($2, $1, 0); }
  	| '*' maybe_type_quals_attrs parm_declarator_starttypename  %prec UNARY
--- 1625,1630 ----
*************** parm_declarator_nostarttypename:
*** 1679,1687 ****
  notype_declarator:
  	  notype_declarator '(' parmlist_or_identifiers  %prec '.'
  		{ $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
- /*	| notype_declarator '(' error ')'  %prec '.'
- 		{ $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
- 		  poplevel (0, 0, 0); }  */
  	| '(' maybe_attribute notype_declarator ')'
  		{ $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; }
  	| '*' maybe_type_quals_attrs notype_declarator  %prec UNARY
--- 1641,1646 ----
*************** lineno_stmt_decl_or_labels:
*** 2038,2051 ****
  errstmt:  error ';'
  	;
  
! pushlevel:  /* empty */
! 		{ pushlevel (0);
  		  clear_last_expr ();
  		  add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
  		}
  	;
  
! poplevel:  /* empty */
                  {
  @@ifobjc
  		  if (c_dialect_objc ())
--- 1997,2010 ----
  errstmt:  error ';'
  	;
  
! push_scope:  /* empty */
! 		{ push_scope ();
  		  clear_last_expr ();
  		  add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
  		}
  	;
  
! pop_scope:  /* empty */
                  {
  @@ifobjc
  		  if (c_dialect_objc ())
*************** c99_block_start: /* empty */
*** 2060,2066 ****
  		{ if (flag_isoc99)
  		    {
  		      $$ = c_begin_compound_stmt ();
! 		      pushlevel (0);
  		      clear_last_expr ();
  		      add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
  		    }
--- 2019,2025 ----
  		{ if (flag_isoc99)
  		    {
  		      $$ = c_begin_compound_stmt ();
! 		      push_scope ();
  		      clear_last_expr ();
  		      add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
  		    }
*************** c99_block_end: /* empty */
*** 2076,2082 ****
                  { if (flag_isoc99)
  		    {
  		      tree scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
! 		      $$ = poplevel (KEEP_MAYBE, 0, 0);
  		      SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
  			= SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
  			= $$;
--- 2035,2041 ----
                  { if (flag_isoc99)
  		    {
  		      tree scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
! 		      $$ = pop_scope ();
  		      SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
  			= SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
  			= $$;
*************** compstmt_start: '{' { compstmt_count++;
*** 2125,2132 ****
  
  compstmt_nostart: '}'
  		{ $$ = convert (void_type_node, integer_zero_node); }
! 	| pushlevel maybe_label_decls compstmt_contents_nonempty '}' poplevel
! 		{ $$ = poplevel (KEEP_MAYBE, 0, 0);
  		  SCOPE_STMT_BLOCK (TREE_PURPOSE ($5))
  		    = SCOPE_STMT_BLOCK (TREE_VALUE ($5))
  		    = $$; }
--- 2084,2091 ----
  
  compstmt_nostart: '}'
  		{ $$ = convert (void_type_node, integer_zero_node); }
! 	| push_scope maybe_label_decls compstmt_contents_nonempty '}' pop_scope
! 		{ $$ = pop_scope ();
  		  SCOPE_STMT_BLOCK (TREE_PURPOSE ($5))
  		    = SCOPE_STMT_BLOCK (TREE_VALUE ($5))
  		    = $$; }
*************** start_string_translation:
*** 2590,2600 ****
     "void bar (int (__attribute__((__mode__(SI))) int foo));".  */
  parmlist:
  	  maybe_attribute
! 		{ pushlevel (0);
  		  declare_parm_level (); }
  	  parmlist_1
  		{ $$ = $3;
! 		  poplevel (0, 0, 0); }
  	;
  
  parmlist_1:
--- 2549,2559 ----
     "void bar (int (__attribute__((__mode__(SI))) int foo));".  */
  parmlist:
  	  maybe_attribute
! 		{ push_scope ();
  		  declare_parm_level (); }
  	  parmlist_1
  		{ $$ = $3;
! 		  pop_scope (); }
  	;
  
  parmlist_1:
*************** parmlist_1:
*** 2607,2638 ****
  	  parmlist_1
  		{ $$ = $6; }
  	| error ')'
! 		{ $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); }
  	;
  
  /* This is what appears inside the parens in a function declarator.
     Is value is represented in the format that grokdeclarator expects.  */
  parmlist_2:  /* empty */
! 		{ $$ = get_parm_info (0); }
  	| ELLIPSIS
! 		{ $$ = get_parm_info (0);
! 		  /* Gcc used to allow this as an extension.  However, it does
! 		     not work for all targets, and thus has been disabled.
! 		     Also, since func (...) and func () are indistinguishable,
! 		     it caused problems with the code in expand_builtin which
! 		     tries to verify that BUILT_IN_NEXT_ARG is being used
! 		     correctly.  */
  		  error ("ISO C requires a named argument before `...'");
- 		  parsing_iso_function_signature = true;
  		}
  	| parms
! 		{ $$ = get_parm_info (1);
! 		  parsing_iso_function_signature = true;
! 		}
  	| parms ',' ELLIPSIS
! 		{ $$ = get_parm_info (0);
! 		  parsing_iso_function_signature = true;
! 		}
  	;
  
  parms:
--- 2566,2588 ----
  	  parmlist_1
  		{ $$ = $6; }
  	| error ')'
! 		{ $$ = make_node (TREE_LIST); }
  	;
  
  /* This is what appears inside the parens in a function declarator.
     Is value is represented in the format that grokdeclarator expects.  */
  parmlist_2:  /* empty */
! 		{ $$ = make_node (TREE_LIST); }
  	| ELLIPSIS
! 		{ $$ = make_node (TREE_LIST); 
! 		  /* Suppress -Wold-style-definition for this case.  */
! 		  TREE_CHAIN ($$) = error_mark_node;
  		  error ("ISO C requires a named argument before `...'");
  		}
  	| parms
! 		{ $$ = get_parm_info (/*ellipsis=*/false); }
  	| parms ',' ELLIPSIS
! 		{ $$ = get_parm_info (/*ellipsis=*/true); }
  	;
  
  parms:
*************** setspecs_fp:
*** 2707,2717 ****
     Its value is a list of ..._TYPE nodes or a list of identifiers.  */
  parmlist_or_identifiers:
  	  maybe_attribute
! 		{ pushlevel (0);
  		  declare_parm_level (); }
  	  parmlist_or_identifiers_1
  		{ $$ = $3;
! 		  poplevel (0, 0, 0); }
  	;
  
  parmlist_or_identifiers_1:
--- 2657,2667 ----
     Its value is a list of ..._TYPE nodes or a list of identifiers.  */
  parmlist_or_identifiers:
  	  maybe_attribute
! 		{ push_scope ();
  		  declare_parm_level (); }
  	  parmlist_or_identifiers_1
  		{ $$ = $3;
! 		  pop_scope (); }
  	;
  
  parmlist_or_identifiers_1:
*************** optparmlist:
*** 3129,3141 ****
  		}
  	| ','
  		{
! 		  pushlevel (0);
  		}
  	  parmlist_2
  		{
  		  /* returns a tree list node generated by get_parm_info */
  		  $$ = $3;
! 		  poplevel (0, 0, 0);
  		}
  	;
  
--- 3079,3091 ----
  		}
  	| ','
  		{
! 		  push_scope ();
  		}
  	  parmlist_2
  		{
  		  /* returns a tree list node generated by get_parm_info */
  		  $$ = $3;
! 		  pop_scope ();
  		}
  	;
  
*************** yyprint (FILE *file, int yychar, YYSTYPE
*** 3800,3821 ****
      }
  }
  
! /* This is not the ideal place to put these, but we have to get them out
!    of c-lex.c because cp/lex.c has its own versions.  */
  
  /* Parse the file.  */
  void
  c_parse_file (void)
  {
    yyparse ();
-   /* In case there were missing closebraces, get us back to the global
-      binding level.  */
-   while (! global_bindings_p ())
-     poplevel (0, 0, 0);
-   /* __FUNCTION__ is defined at file scope ("").  This
-      call may not be necessary as my tests indicate it
-      still works without it.  */
-   finish_fname_decls ();
  
    if (malloced_yyss)
      {
--- 3750,3763 ----
      }
  }
  
! /* This is not the ideal place to put this, but we have to get it out
!    of c-lex.c because cp/lex.c has its own version.  */
  
  /* Parse the file.  */
  void
  c_parse_file (void)
  {
    yyparse ();
  
    if (malloced_yyss)
      {
Index: c-simplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/c-simplify.c,v
retrieving revision 1.1.4.94
diff -c -p -r1.1.4.94 c-simplify.c
*** c-simplify.c	25 Feb 2004 03:22:46 -0000	1.1.4.94
--- c-simplify.c	24 Mar 2004 18:24:56 -0000
*************** gimplify_compound_literal_expr (tree *ex
*** 923,928 ****
--- 923,934 ----
    tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
    tree decl = DECL_STMT_DECL (decl_s);
  
+   /* This decl isn't mentioned in the enclosing block, so add it to the
+      list of temps.  FIXME it seems a bit of a kludge to say that
+      anonymous artificial vars aren't pushed, but everything else is.  */
+   if (DECL_NAME (decl) == NULL_TREE)
+     gimple_add_tmp_var (decl);
+ 
    gimplify_decl_stmt (&decl_s);
    *expr_p = decl_s ? decl_s : decl;
    return GS_OK;
Index: c-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-tree.h,v
retrieving revision 1.99.2.33
diff -c -p -r1.99.2.33 c-tree.h
*** c-tree.h	16 Mar 2004 22:16:29 -0000	1.99.2.33
--- c-tree.h	24 Mar 2004 18:24:56 -0000
*************** Software Foundation, 59 Temple Place - S
*** 24,45 ****
  
  #include "c-common.h"
  
! /* Language-dependent contents of an identifier.  */
  
! /* The limbo_value is used for block level extern declarations, which need
!    to be type checked against subsequent extern declarations.  They can't
!    be referenced after they fall out of scope, so they can't be global.
! 
!    The rid_code field is used for keywords.  It is in all
!    lang_identifier nodes, because some keywords are only special in a
!    particular context.  */
  
  struct lang_identifier GTY(())
  {
    struct c_common_identifier common_id;
!   tree symbol_value;
!   tree tag_value;
!   tree label_value;
  };
  
  /* The resulting tree type.  */
--- 24,44 ----
  
  #include "c-common.h"
  
! /* Each C symbol points to three linked lists of c_binding structures.
!    These describe the values of the identifier in the three different
!    namespaces defined by the language.  The contents of these lists
!    are private to c-decl.c.  */
! 
! struct c_binding;
  
! /* Language-dependent contents of an identifier.  */
  
  struct lang_identifier GTY(())
  {
    struct c_common_identifier common_id;
!   struct c_binding *symbol_binding; /* vars, funcs, constants, typedefs */
!   struct c_binding *tag_binding;    /* struct/union/enum tags */
!   struct c_binding *label_binding;  /* labels */
  };
  
  /* The resulting tree type.  */
*************** struct lang_decl GTY(())
*** 71,96 ****
    tree pending_sizes;
  };
  
- /* Macros for access to language-specific slots in an identifier.  */
- /* Each of these slots contains a DECL node or null.  */
- 
- /* The value of the identifier in the namespace of "ordinary identifiers"
-    (data objects, enum constants, functions, typedefs).  */
- #define IDENTIFIER_SYMBOL_VALUE(NODE)	\
-   (((struct lang_identifier *) (NODE))->symbol_value)
- /* The value of the identifier in the namespace of struct, union,
-    and enum tags.  */
- #define IDENTIFIER_TAG_VALUE(NODE)	\
-   (((struct lang_identifier *) (NODE))->tag_value)
- /* The value of the identifier in the namespace of labels.  */
- #define IDENTIFIER_LABEL_VALUE(NODE)	\
-   (((struct lang_identifier *) (NODE))->label_value)
- 
- /* In identifiers, C uses the following fields in a special way:
-    TREE_PUBLIC        to record that there was a previous local extern decl.
-    TREE_USED          to record that such a decl was used.
-    TREE_ADDRESSABLE   to record that the address of such a decl was used.  */
- 
  /* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only.  */
  #define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1 (TYPE)
  
--- 70,75 ----
*************** struct lang_type GTY(())
*** 138,148 ****
  /* For a FUNCTION_DECL, nonzero if it was an implicit declaration.  */
  #define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP)
  
! /* Nonzero for a declaration of an external object which is not
!    currently in scope.  This is either a built-in declaration of
!    a library function, before a real declaration has been seen,
!    or a declaration that appeared in an inner scope that has ended.  */
! #define C_DECL_INVISIBLE(EXP) DECL_LANG_FLAG_3 (EXP)
  
  /* Nonzero for a decl which either doesn't exist or isn't a prototype.
     N.B. Could be simplified if all built-in decls had complete prototypes
--- 117,129 ----
  /* For a FUNCTION_DECL, nonzero if it was an implicit declaration.  */
  #define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP)
  
! /* For any decl, nonzero if it is bound in the externals scope and
!    pop_scope mustn't chain it into any higher block.  */
! #define C_DECL_IN_EXTERNAL_SCOPE(EXP) DECL_LANG_FLAG_3 (EXP)
! 
! /* For FUNCTION_DECLs, evaluates true if the decl is built-in but has
!    been declared.  */
! #define C_DECL_DECLARED_BUILTIN(EXP) DECL_LANG_FLAG_4 (EXP)
  
  /* Nonzero for a decl which either doesn't exist or isn't a prototype.
     N.B. Could be simplified if all built-in decls had complete prototypes
*************** struct lang_type GTY(())
*** 157,167 ****
     without prototypes.  */
  #define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_BINFO (NODE)
  
- /* Values for the first parameter to poplevel.  */
- #define KEEP_NO		0
- #define KEEP_YES	1
- #define KEEP_MAYBE	2
- 
  /* Save and restore the variables in this file and elsewhere
     that keep track of the progress of compilation of the current function.
     Used for nested functions.  */
--- 138,143 ----
*************** extern int c_in_case_stmt;
*** 191,199 ****
  
  extern int global_bindings_p (void);
  extern tree getdecls (void);
! extern void pushlevel (int);
  extern void insert_block (tree);
- extern void set_block (tree);
  extern tree pushdecl (tree);
  extern void c_expand_body (tree);
  
--- 167,175 ----
  
  extern int global_bindings_p (void);
  extern tree getdecls (void);
! extern void push_scope (void);
! extern tree pop_scope (void);
  extern void insert_block (tree);
  extern tree pushdecl (tree);
  extern void c_expand_body (tree);
  
*************** extern void finish_decl (tree, tree, tre
*** 213,224 ****
  extern tree finish_enum (tree, tree, tree);
  extern void finish_function (void);
  extern tree finish_struct (tree, tree, tree);
! extern tree get_parm_info (int);
  extern tree grokfield (tree, tree, tree);
  extern tree groktypename (tree);
  extern tree groktypename_in_parm_context (tree);
  extern tree implicitly_declare (tree);
- extern int  in_parm_level_p (void);
  extern void keep_next_level (void);
  extern tree lookup_name (tree);
  extern void pending_xref_error (void);
--- 189,199 ----
  extern tree finish_enum (tree, tree, tree);
  extern void finish_function (void);
  extern tree finish_struct (tree, tree, tree);
! extern tree get_parm_info (bool);
  extern tree grokfield (tree, tree, tree);
  extern tree groktypename (tree);
  extern tree groktypename_in_parm_context (tree);
  extern tree implicitly_declare (tree);
  extern void keep_next_level (void);
  extern tree lookup_name (tree);
  extern void pending_xref_error (void);
*************** extern void c_push_function_context (str
*** 226,232 ****
  extern void c_pop_function_context (struct function *);
  extern void push_parm_decl (tree);
  extern tree pushdecl_top_level (tree);
- extern void pushtag (tree, tree);
  extern tree set_array_declarator_type (tree, tree, int);
  extern void shadow_tag (tree);
  extern void shadow_tag_warned (tree, int);
--- 201,206 ----
*************** extern tree c_begin_compound_stmt (void)
*** 240,246 ****
  extern int c_expand_decl (tree);
  extern void c_static_assembler_name (tree);
  extern tree make_pointer_declarator (tree, tree);
- extern void merge_translation_unit_decls (void);
  
  /* in c-objc-common.c */
  extern int c_disregard_inline_limits (tree);
--- 214,219 ----
*************** enum {
*** 267,272 ****
--- 240,246 ----
  };
  
  extern tree require_complete_type (tree);
+ extern int same_translation_unit_p (tree, tree);
  extern int comptypes (tree, tree, int);
  extern tree c_size_in_bytes (tree);
  extern bool c_mark_addressable (tree);
*************** extern int current_function_returns_abno
*** 323,328 ****
--- 297,307 ----
  /* Nonzero means we are reading code that came from a system header file.  */
  
  extern int system_header_p;
+ 
+ /* True means global_bindings_p should return false even if the scope stack
+    says we are in file scope.  */
+ 
+ extern bool c_override_global_bindings_to_false;
  
  /* In c-decl.c */
  extern void c_finish_incomplete_decl (tree);
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.196.2.44
diff -c -p -r1.196.2.44 c-typeck.c
*** c-typeck.c	22 Mar 2004 22:55:11 -0000	1.196.2.44
--- c-typeck.c	24 Mar 2004 18:25:09 -0000
*************** Software Foundation, 59 Temple Place - S
*** 51,57 ****
  static int missing_braces_mentioned;
  
  static tree qualify_type (tree, tree);
- static int same_translation_unit_p (tree, tree);
  static int tagged_types_tu_compatible_p (tree, tree, int);
  static int comp_target_types (tree, tree, int);
  static int function_types_compatible_p (tree, tree, int);
--- 51,56 ----
*************** common_type (tree t1, tree t2)
*** 369,377 ****
  
  	/* If both args specify argument types, we must merge the two
  	   lists, argument by argument.  */
! 
! 	pushlevel (0);
! 	declare_parm_level ();
  
  	len = list_length (p1);
  	newargs = 0;
--- 368,376 ----
  
  	/* If both args specify argument types, we must merge the two
  	   lists, argument by argument.  */
! 	/* Tell global_bindings_p to return false so that variable_size
! 	   doesn't abort on VLAs in parameter types.  */
! 	c_override_global_bindings_to_false = true;
  
  	len = list_length (p1);
  	newargs = 0;
*************** common_type (tree t1, tree t2)
*** 434,441 ****
  	  parm_done: ;
  	  }
  
! 	poplevel (0, 0, 0);
! 
  	t1 = build_function_type (valtype, newargs);
  	/* ... falls through ...  */
        }
--- 433,439 ----
  	  parm_done: ;
  	  }
  
! 	c_override_global_bindings_to_false = false;
  	t1 = build_function_type (valtype, newargs);
  	/* ... falls through ...  */
        }
*************** comp_target_types (tree ttl, tree ttr, i
*** 613,623 ****
  
  /* Subroutines of `comptypes'.  */
  
! /* Determine whether two types derive from the same translation unit.
!    If the CONTEXT chain ends in a null, that type's context is still
!    being parsed, so if two types have context chains ending in null,
     they're in the same translation unit.  */
! static int
  same_translation_unit_p (tree t1, tree t2)
  {
    while (t1 && TREE_CODE (t1) != TRANSLATION_UNIT_DECL)
--- 611,621 ----
  
  /* Subroutines of `comptypes'.  */
  
! /* Determine whether two trees derive from the same translation unit.
!    If the CONTEXT chain ends in a null, that tree's context is still
!    being parsed, so if two trees have context chains ending in null,
     they're in the same translation unit.  */
! int
  same_translation_unit_p (tree t1, tree t2)
  {
    while (t1 && TREE_CODE (t1) != TRANSLATION_UNIT_DECL)
Index: coverage.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/coverage.c,v
retrieving revision 1.6.2.13
diff -c -p -r1.6.2.13 coverage.c
*** coverage.c	4 Mar 2004 15:38:41 -0000	1.6.2.13
--- coverage.c	24 Mar 2004 18:25:11 -0000
*************** create_coverage (void)
*** 939,945 ****
    DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
    DECL_UNINLINABLE (ctor) = 1;
  
-   ctor = (*lang_hooks.decls.pushdecl) (ctor);
    rest_of_decl_compilation (ctor, 0, 1, 0);
    announce_function (ctor);
    current_function_decl = ctor;
--- 939,944 ----
Index: langhooks.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks.c,v
retrieving revision 1.31.2.24
diff -c -p -r1.31.2.24 langhooks.c
*** langhooks.c	16 Mar 2004 22:16:32 -0000	1.31.2.24
--- langhooks.c	24 Mar 2004 18:25:12 -0000
*************** void
*** 217,223 ****
  lhd_clear_binding_stack (void)
  {
    while (! (*lang_hooks.decls.global_bindings_p) ())
!     poplevel (0, 0, 0);
  }
  
  /* Type promotion for variable arguments.  */
--- 217,223 ----
  lhd_clear_binding_stack (void)
  {
    while (! (*lang_hooks.decls.global_bindings_p) ())
!     lang_hooks.decls.poplevel (0, 0, 0);
  }
  
  /* Type promotion for variable arguments.  */
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.263.2.84
diff -c -p -r1.263.2.84 tree.c
*** tree.c	8 Mar 2004 18:05:42 -0000	1.263.2.84
--- tree.c	24 Mar 2004 18:25:19 -0000
*************** chain_member (tree elem, tree chain)
*** 973,983 ****
  int
  list_length (tree t)
  {
!   tree tail;
    int len = 0;
  
!   for (tail = t; tail; tail = TREE_CHAIN (tail))
!     len++;
  
    return len;
  }
--- 973,995 ----
  int
  list_length (tree t)
  {
!   tree p = t;
! #ifdef ENABLE_TREE_CHECKING
!   tree q = t;
! #endif
    int len = 0;
  
!   while (p)
!     {
!       p = TREE_CHAIN (p);
! #ifdef ENABLE_TREE_CHECKING
!       if (len % 2)
! 	q = TREE_CHAIN (q);
!       if (p == q)
! 	abort ();
! #endif
!       len++;
!     }
  
    return len;
  }
Index: cp/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ChangeLog,v
retrieving revision 1.2849.2.70
diff -c -p -r1.2849.2.70 ChangeLog
*** cp/ChangeLog	8 Mar 2004 18:06:00 -0000	1.2849.2.70
--- cp/ChangeLog	24 Mar 2004 18:25:31 -0000
***************
*** 1,3 ****
--- 1,10 ----
+ 2004-03-23  Zack Weinberg  <zack@codesourcery.com>
+                                                                              

+ 	PR 12267, 12391, 12560, 13129, 14114, 14133
+ 	* cp-lang.c (c_reset_state): Delete.
+ 	(push_file_scope, pop_file_scope): New stubs.
+ 	* parser.c (c_parse_file): Call sorry() here if called more than once.
+                                                                              

  2004-03-05  Jason Merrill  <jason@redhat.com>
  
  	* tree.c (list_hash_pieces): s/TYPE_HASH/TREE_HASH/.
Index: cp/cp-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-lang.c,v
retrieving revision 1.36.2.34
diff -c -p -r1.36.2.34 cp-lang.c
*** cp/cp-lang.c	18 Mar 2004 00:44:33 -0000	1.36.2.34
--- cp/cp-lang.c	24 Mar 2004 18:25:32 -0000
*************** static int cxx_types_compatible_p (tree 
*** 365,377 ****
    return same_type_ignoring_top_level_qualifiers_p (x, y);
  }
  
- /* Stub routine to tell people that this doesn't work yet.  */
- void
- c_reset_state (void)
- {
-   sorry ("inter-module optimisations not implemented yet");
- }
- 
  /* Construct a C++-aware pretty-printer for CONTEXT.  It is assumed
     that CONTEXT->printer is an already constructed basic pretty_printer.  */
  static void
--- 365,370 ----
*************** cxx_initialize_diagnostics (diagnostic_c
*** 385,388 ****
--- 378,392 ----
  
    /* It is safe to free this object because it was previously malloc()'d.  */
    free (base);
+ }
+ 
+ /* Stubs to keep c-opts.c happy.  */
+ void
+ push_file_scope (void)
+ {
+ }
+ 
+ void
+ pop_file_scope (void)
+ {
  }
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.32.2.23
diff -c -p -r1.32.2.23 parser.c
*** cp/parser.c	4 Mar 2004 15:39:29 -0000	1.32.2.23
--- cp/parser.c	24 Mar 2004 18:25:57 -0000
*************** cp_parser_allow_gnu_extensions_p (cp_par
*** 15319,15325 ****
  }
  
  
- 
  /* The parser.  */
  
  static GTY (()) cp_parser *the_parser;
--- 15319,15324 ----
*************** void
*** 15332,15337 ****
--- 15331,15344 ----
  c_parse_file (void)
  {
    bool error_occurred;
+   static bool already_called = false;
+ 
+   if (already_called)
+     {
+       sorry ("inter-module optimizations not implemented for C++");
+       return;
+     }
+   already_called = true;
  
    the_parser = cp_parser_new ();
    push_deferring_access_checks (flag_access_control
Index: objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.137.2.33
diff -c -p -r1.137.2.33 objc-act.c
*** objc/objc-act.c	8 Mar 2004 18:06:07 -0000	1.137.2.33
--- objc/objc-act.c	24 Mar 2004 18:26:13 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 64,71 ****
  #include "diagnostic.h"
  #include "cgraph.h"
  
- #define OBJC_VOID_AT_END	build_tree_list (NULL_TREE, void_type_node)
- 
  /* This is the default way of generating a method name.  */
  /* I am not sure it is really correct.
     Perhaps there's a danger that it will make name conflicts
--- 64,69 ----
*************** static void generate_ivar_lists (void);
*** 161,167 ****
  static void generate_dispatch_tables (void);
  static void generate_shared_structures (void);
  static tree generate_protocol_list (tree);
- static void generate_forward_declaration_to_string_table (void);
  static void build_protocol_reference (tree);
  
  static tree build_keyword_selector (tree);
--- 159,164 ----
*************** synth_module_prologue (void)
*** 1238,1244 ****
          = build_function_type (IMP_type,
                                 tree_cons (NULL_TREE, id_type,
                                            tree_cons (NULL_TREE, 
selector_type,
!                                                      OBJC_VOID_AT_END)));
        umsg_decl = builtin_function (TAG_MSGSEND,
  				    temp_type, 0, NOT_BUILT_IN,
  				    NULL, NULL_TREE);
--- 1235,1241 ----
          = build_function_type (IMP_type,
                                 tree_cons (NULL_TREE, id_type,
                                            tree_cons (NULL_TREE, 
selector_type,
!                                                      void_list_node)));
        umsg_decl = builtin_function (TAG_MSGSEND,
  				    temp_type, 0, NOT_BUILT_IN,
  				    NULL, NULL_TREE);
*************** synth_module_prologue (void)
*** 1248,1254 ****
          = build_function_type (IMP_type,
                                 tree_cons (NULL_TREE, super_type,
                                            tree_cons (NULL_TREE, 
selector_type,
!                                                      OBJC_VOID_AT_END)));
        umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
  					  temp_type, 0, NOT_BUILT_IN,
  					  NULL, NULL_TREE);
--- 1245,1251 ----
          = build_function_type (IMP_type,
                                 tree_cons (NULL_TREE, super_type,
                                            tree_cons (NULL_TREE, 
selector_type,
!                                                      void_list_node)));
        umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
  					  temp_type, 0, NOT_BUILT_IN,
  					  NULL, NULL_TREE);
*************** synth_module_prologue (void)
*** 1259,1265 ****
    temp_type = build_function_type (id_type,
  				   tree_cons (NULL_TREE,
  					      const_string_type_node,
! 					      OBJC_VOID_AT_END));
  
    objc_get_class_decl
      = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
--- 1256,1262 ----
    temp_type = build_function_type (id_type,
  				   tree_cons (NULL_TREE,
  					      const_string_type_node,
! 					      void_list_node));
  
    objc_get_class_decl
      = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
*************** synth_module_prologue (void)
*** 1305,1312 ****
        TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
      }
  
-   generate_forward_declaration_to_string_table ();
- 
    /* Forward declare constant_string_id and constant_string_type.  */
    if (!constant_string_class_name)
      constant_string_class_name = default_constant_string_class_name;
--- 1302,1307 ----
*************** build_module_descriptor (void)
*** 1877,1883 ****
  				 get_identifier (TAG_EXECCLASS),
  				 build_function_type (void_type_node,
  					tree_cons (NULL_TREE, ptr_type_node,
! 						   OBJC_VOID_AT_END)));
  						
      DECL_EXTERNAL (execclass_decl) = 1;
      DECL_ARTIFICIAL (execclass_decl) = 1;
--- 1872,1878 ----
  				 get_identifier (TAG_EXECCLASS),
  				 build_function_type (void_type_node,
  					tree_cons (NULL_TREE, ptr_type_node,
! 						   void_list_node)));
  						
      DECL_EXTERNAL (execclass_decl) = 1;
      DECL_ARTIFICIAL (execclass_decl) = 1;
*************** build_module_descriptor (void)
*** 1892,1898 ****
      start_function (void_list_node_1,
  		    build_nt (CALL_EXPR, init_function_name,
  			      tree_cons (NULL_TREE, NULL_TREE,
! 					 OBJC_VOID_AT_END),
  			      NULL_TREE),
  		    NULL_TREE);
      store_parm_decls ();
--- 1887,1893 ----
      start_function (void_list_node_1,
  		    build_nt (CALL_EXPR, init_function_name,
  			      tree_cons (NULL_TREE, NULL_TREE,
! 					 void_list_node),
  			      NULL_TREE),
  		    NULL_TREE);
      store_parm_decls ();
*************** build_module_descriptor (void)
*** 1919,1940 ****
    }
  }
  
- /* extern const char _OBJC_STRINGS[]; */
- 
- static void
- generate_forward_declaration_to_string_table (void)
- {
-   tree sc_spec, decl_specs, expr_decl;
- 
-   sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE);
-   decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
- 
-   expr_decl
-     = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE);
- 
-   UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);
- }
- 
  /* Return the DECL of the string IDENT in the SECTION.  */
  
  static tree
--- 1914,1919 ----
*************** objc_enter_block (void)
*** 2699,2705 ****
    block = begin_compound_stmt (0);
  #else
    block = c_begin_compound_stmt ();
!   pushlevel (0);
    clear_last_expr ();
    add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
  #endif
--- 2678,2684 ----
    block = begin_compound_stmt (0);
  #else
    block = c_begin_compound_stmt ();
!   push_scope ();
    clear_last_expr ();
    add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
  #endif
*************** objc_exit_block (void)
*** 2724,2730 ****
    finish_compound_stmt (0, block);
  #else
    scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
!   inner = poplevel (KEEP_MAYBE, 1, 0);
  
    SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
  	= SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
--- 2703,2709 ----
    finish_compound_stmt (0, block);
  #else
    scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
!   inner = pop_scope ();
  
    SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
  	= SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
*************** build_objc_exception_stuff (void)
*** 3331,3337 ****
      = build_function_type (id_type,
  			   tree_cons (NULL_TREE,
  				      build_pointer_type (objc_exception_data_template),
! 				      OBJC_VOID_AT_END));
    objc_exception_extract_decl
      = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
    /* void objc_exception_try_enter(struct _objc_exception_data *); */
--- 3310,3316 ----
      = build_function_type (id_type,
  			   tree_cons (NULL_TREE,
  				      build_pointer_type (objc_exception_data_template),
! 				      void_list_node));
    objc_exception_extract_decl
      = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
    /* void objc_exception_try_enter(struct _objc_exception_data *); */
*************** build_objc_exception_stuff (void)
*** 3340,3346 ****
      = build_function_type (void_type_node,
  			   tree_cons (NULL_TREE,
  				      build_pointer_type (objc_exception_data_template),
! 				      OBJC_VOID_AT_END));
    objc_exception_try_enter_decl
      = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
    objc_exception_try_exit_decl
--- 3319,3325 ----
      = build_function_type (void_type_node,
  			   tree_cons (NULL_TREE,
  				      build_pointer_type (objc_exception_data_template),
! 				      void_list_node));
    objc_exception_try_enter_decl
      = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
    objc_exception_try_exit_decl
*************** build_objc_exception_stuff (void)
*** 3350,3356 ****
    /* void objc_sync_exit(id); */
    temp_type = build_function_type (void_type_node,
  				   tree_cons (NULL_TREE, id_type,
! 					      OBJC_VOID_AT_END));
    objc_exception_throw_decl
      = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
    DECL_ATTRIBUTES (objc_exception_throw_decl)
--- 3329,3335 ----
    /* void objc_sync_exit(id); */
    temp_type = build_function_type (void_type_node,
  				   tree_cons (NULL_TREE, id_type,
! 					      void_list_node));
    objc_exception_throw_decl
      = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
    DECL_ATTRIBUTES (objc_exception_throw_decl)
*************** build_objc_exception_stuff (void)
*** 3363,3369 ****
    temp_type = build_function_type (integer_type_node,
  				   tree_cons (NULL_TREE, id_type,
  					      tree_cons (NULL_TREE, id_type,
! 							 OBJC_VOID_AT_END)));
    objc_exception_match_decl
      = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
  	
--- 3342,3348 ----
    temp_type = build_function_type (integer_type_node,
  				   tree_cons (NULL_TREE, id_type,
  					      tree_cons (NULL_TREE, id_type,
! 							 void_list_node)));
    objc_exception_match_decl
      = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
  	
*************** get_arg_type_list (tree meth, int contex
*** 5463,5469 ****
  
    if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
      /* We have a `, ...' immediately following the selector,
!        finalize the arglist...simulate get_parm_info (0).  */
      ;
    else if (METHOD_ADD_ARGS (meth))
      {
--- 5442,5448 ----
  
    if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
      /* We have a `, ...' immediately following the selector,
!        finalize the arglist...simulate get_parm_info (true).  */
      ;
    else if (METHOD_ADD_ARGS (meth))
      {
*************** get_arg_type_list (tree meth, int contex
*** 5472,5479 ****
        chainon (arglist, add_arg_list);
      }
    else
!     /* finalize the arglist...simulate get_parm_info (1) */
!     chainon (arglist, OBJC_VOID_AT_END);
  
    return arglist;
  }
--- 5451,5458 ----
        chainon (arglist, add_arg_list);
      }
    else
!     /* finalize the arglist...simulate get_parm_info (false) */
!     chainon (arglist, void_list_node);
  
    return arglist;
  }
*************** start_method_def (tree method)
*** 7541,7547 ****
    UOBJC_SUPER_decl = NULL_TREE;
  
    /* Must be called BEFORE start_function.  */
!   pushlevel (0);
  
    /* Generate prototype declarations for arguments..."new-style".  */
    synth_self_and_ucmd_args ();
--- 7520,7527 ----
    UOBJC_SUPER_decl = NULL_TREE;
  
    /* Must be called BEFORE start_function.  */
!   push_scope ();
!   declare_parm_level ();
  
    /* Generate prototype declarations for arguments..."new-style".  */
    synth_self_and_ucmd_args ();
*************** continue_method_def (void)
*** 7821,7829 ****
  
    if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
      /* We have a `, ...' immediately following the selector.  */
!     parmlist = get_parm_info (0);
    else
!     parmlist = get_parm_info (1); /* place a `void_at_end' */
  
  #ifndef OBJCPLUS
    /* Set self_decl from the first argument...this global is used by
--- 7801,7809 ----
  
    if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
      /* We have a `, ...' immediately following the selector.  */
!     parmlist = get_parm_info (/*ellipsis=*/true);
    else
!     parmlist = get_parm_info (/*ellipsis=*/false);
  
  #ifndef OBJCPLUS
    /* Set self_decl from the first argument...this global is used by
*************** continue_method_def (void)
*** 7831,7837 ****
    self_decl = TREE_PURPOSE (parmlist);
  #endif /* !OBJCPLUS */
  
!   poplevel (0, 0, 0);
    really_start_method (objc_method_context, parmlist);
    store_parm_decls ();
  }
--- 7811,7817 ----
    self_decl = TREE_PURPOSE (parmlist);
  #endif /* !OBJCPLUS */
  
!   pop_scope ();
    really_start_method (objc_method_context, parmlist);
    store_parm_decls ();
  }
*************** finish_objc (void)
*** 8802,8809 ****
        objc_ivar_chain = NULL_TREE;
        objc_implementation_context = NULL_TREE;
      }
- 
-   generate_forward_declaration_to_string_table ();
  
    /* Process the static instances here because initialization of objc_symtab
       depends on them.  */
--- 8782,8787 ----
Index: objc/objc-act.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.h,v
retrieving revision 1.10.2.9
diff -c -p -r1.10.2.9 objc-act.h
*** objc/objc-act.h	19 Oct 2003 00:00:59 -0000	1.10.2.9
--- objc/objc-act.h	24 Mar 2004 18:26:13 -0000
*************** enum objc_tree_index
*** 234,240 ****
      OCTI_MCLS_DECL,
      OCTI_SEL_TABLE_DECL,
      OCTI_MODULES_DECL,
-     OCTI_STRG_DECL,
  
      OCTI_INTF_CTX,
      OCTI_IMPL_CTX,
--- 234,239 ----
*************** extern GTY(()) tree objc_global_trees[OC
*** 360,366 ****
  #define UOBJC_METACLASS_decl		objc_global_trees[OCTI_MCLS_DECL]
  #define UOBJC_SELECTOR_TABLE_decl	objc_global_trees[OCTI_SEL_TABLE_DECL]
  #define UOBJC_MODULES_decl		objc_global_trees[OCTI_MODULES_DECL]
- #define UOBJC_STRINGS_decl		objc_global_trees[OCTI_STRG_DECL]
  
  /* The following are used when compiling a class implementation.
     implementation_template will normally be an interface, however if
--- 359,364 ----
Index: objc/objc-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-lang.c,v
retrieving revision 1.24.2.16
diff -c -p -r1.24.2.16 objc-lang.c
*** objc/objc-lang.c	13 Feb 2004 13:13:51 -0000	1.24.2.16
--- objc/objc-lang.c	24 Mar 2004 18:26:14 -0000
*************** enum c_language_kind c_language = clk_ob
*** 55,60 ****
--- 55,62 ----
  #define LANG_HOOKS_SAFE_FROM_P c_safe_from_p
  #undef LANG_HOOKS_PARSE_FILE
  #define LANG_HOOKS_PARSE_FILE c_common_parse_file
+ #undef LANG_HOOKS_CLEAR_BINDING_STACK
+ #define LANG_HOOKS_CLEAR_BINDING_STACK lhd_do_nothing
  #undef LANG_HOOKS_EXPAND_EXPR
  #define LANG_HOOKS_EXPAND_EXPR c_expand_expr
  #undef LANG_HOOKS_EXPAND_DECL
*************** enum c_language_kind c_language = clk_ob
*** 135,140 ****
--- 137,155 ----
  #undef  LANG_HOOKS_GIMPLIFY_EXPR
  #define LANG_HOOKS_GIMPLIFY_EXPR c_gimplify_expr
  
+ /* The C front end's scoping structure is very different from
+    that expected by the language-independent code; it is best
+    to disable all of pushlevel, poplevel, set_block, and getdecls.
+    This means it must also provide its own write_globals.  */
+ 
+ #undef LANG_HOOKS_PUSHLEVEL
+ #define LANG_HOOKS_PUSHLEVEL lhd_do_nothing_i
+ #undef LANG_HOOKS_POPLEVEL
+ #define LANG_HOOKS_POPLEVEL lhd_do_nothing_iii_return_null_tree
+ #undef LANG_HOOKS_SET_BLOCK
+ #define LANG_HOOKS_SET_BLOCK lhd_do_nothing_t
+ #undef LANG_HOOKS_GETDECLS
+ #define LANG_HOOKS_GETDECLS lhd_return_null_tree_v
  #undef LANG_HOOKS_WRITE_GLOBALS
  #define LANG_HOOKS_WRITE_GLOBALS c_write_global_declarations
  
Index: testsuite/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/ChangeLog,v
retrieving revision 1.1936.2.54
diff -c -p -r1.1936.2.54 ChangeLog
*** testsuite/ChangeLog	18 Mar 2004 22:52:37 -0000	1.1936.2.54
--- testsuite/ChangeLog	24 Mar 2004 18:26:47 -0000
***************
*** 1,10 ****
  2004-03-18  Mark Mitchell  <mark@codesourcery.com>
   
  	* gcc.dg/local1.c: New test.
  
  	* gcc.dg/debug/dwarf2/c99-typedef1.c: New test.
   
! 
  2004-03-07  Roger Sayle  <roger@eyesopen.com>
  
  	* gcc.c-torture/execute/20040307-1.c: New test case.
--- 1,25 ----
+ 2004-03-23  Zack Weinberg  <zack@codesourcery.com>
+  
+ 	PR 12267, 12391, 12560, 13129, 14114, 14133
+ 	* gcc.dg/Wold-style-definition-1.c, gcc.dg/builtins-30.c
+ 	* gcc.dg/unused-4.c, gcc.dg/noncompile/label-1.c
+ 	* gcc.dg/noncompile/label-lineno-1.c, objc.dg/naming-1.m:
+ 	Adjust error regexps.
+ 	* gcc.dg/Wshadow-2.c, gcc.dg/noncompile/incomplete-3.c
+ 	* gcc.dg/noncompile/undeclared-1.c: New test cases.
+ 	* gcc.dg/decl-5.c, gcc.dg/redecl-1.c: Remove XFAIL.
+ 	* gcc.dg/local1.c: Add explanatory comment.
+  
  2004-03-18  Mark Mitchell  <mark@codesourcery.com>
   
  	* gcc.dg/local1.c: New test.
  
  	* gcc.dg/debug/dwarf2/c99-typedef1.c: New test.
   
! 2004-03-09  Zack Weinberg  <zack@codesourcery.com>
!  
! 	* gcc.dg/noncompile/incomplete-2.c: Move dg-error to proper line.
!  
  2004-03-07  Roger Sayle  <roger@eyesopen.com>
  
  	* gcc.c-torture/execute/20040307-1.c: New test case.
Index: testsuite/gcc.dg/Wold-style-definition-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/Wold-style-definition-1.c,v
retrieving revision 1.1.4.1
diff -c -p -r1.1.4.1 Wold-style-definition-1.c
*** testsuite/gcc.dg/Wold-style-definition-1.c	28 Sep 2003 06:07:53 -0000	
1.1.4.1
--- testsuite/gcc.dg/Wold-style-definition-1.c	24 Mar 2004 18:27:30 -0000
***************
*** 5,23 ****
  /* { dg-options "-Wold-style-definition" } */
  
  void
! bar (a) int a; { } /* { dg-warning "old-style parameter declaration" } */
  
! void bar1 () {} /* { dg-warning "old-style parameter declaration" } */
  
  extern void bar2 (void);
  
! void bar2 () {} /* { dg-warning "old-style parameter declaration" } */
  
  extern void bar3 (int);
  
! void bar3 (a) {} /* { dg-warning "old-style parameter declaration" } */
  
! void bar4 (a) {} /* { dg-warning "old-style parameter declaration" } */
  
  void bar5 (int a) {}
  
--- 5,23 ----
  /* { dg-options "-Wold-style-definition" } */
  
  void
! bar (a) int a; { } /* { dg-warning "old-style function definition" } */
  
! void bar1 () {} /* { dg-warning "old-style function definition" } */
  
  extern void bar2 (void);
  
! void bar2 () {} /* { dg-warning "old-style function definition" } */
  
  extern void bar3 (int);
  
! void bar3 (a) {} /* { dg-warning "old-style function definition" } */
  
! void bar4 (a) {} /* { dg-warning "old-style function definition" } */
  
  void bar5 (int a) {}
  
Index: testsuite/gcc.dg/Wshadow-2.c
===================================================================
RCS file: testsuite/gcc.dg/Wshadow-2.c
diff -N testsuite/gcc.dg/Wshadow-2.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/Wshadow-2.c	24 Mar 2004 18:27:30 -0000
***************
*** 0 ****
--- 1,10 ----
+ /* Bogus warning for a double declaration of the same extern variable,
+    first at file scope, then at block scope.  PR 13129.  */
+ 
+ /* { dg-options "-Wshadow" } */
+ 
+ extern struct foo bar;
+ void dummy()
+ {
+   extern struct foo bar;  /* { dg-bogus "shadows" } */
+ }
Index: testsuite/gcc.dg/builtins-30.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/builtins-30.c,v
retrieving revision 1.2.4.1
diff -c -p -r1.2.4.1 builtins-30.c
*** testsuite/gcc.dg/builtins-30.c	30 Jan 2004 13:17:46 -0000	1.2.4.1
--- testsuite/gcc.dg/builtins-30.c	24 Mar 2004 18:27:32 -0000
*************** extern double strtod (const char *, char
*** 6,26 ****
  
  /* A built-in function may be overridden by an old-style definition
     specifying too few arguments... */
! double nan ()
! {  /* { dg-warning "shadowing built-in" } */
    return strtod ("nan", 0);
  }
  
  /* the right number, but the wrong type, arguments... */
! float nanf (foo)
!      int foo UNUSED;  /* { dg-warning "shadowing built-in" } */
  {
    return strtod ("nan", 0);
  }
  
  /* or too many arguments.  */
! long double nanl (foo, bar)
!      const char *foo UNUSED;  /* { dg-warning "shadowing built-in" } */
       int bar UNUSED;
  {
    return strtod ("nan", 0);
--- 6,26 ----
  
  /* A built-in function may be overridden by an old-style definition
     specifying too few arguments... */
! double cos ()
! {  /* { dg-warning "shadows a built-in" } */
    return strtod ("nan", 0);
  }
  
  /* the right number, but the wrong type, arguments... */
! double sin (foo)
!      int foo UNUSED;  /* { dg-warning "shadows a built-in" } */
  {
    return strtod ("nan", 0);
  }
  
  /* or too many arguments.  */
! long double cosl (foo, bar)
!      const char *foo UNUSED;  /* { dg-warning "shadows a built-in" } */
       int bar UNUSED;
  {
    return strtod ("nan", 0);
Index: testsuite/gcc.dg/decl-5.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/decl-5.c,v
retrieving revision 1.1.4.1
diff -c -p -r1.1.4.1 decl-5.c
*** testsuite/gcc.dg/decl-5.c	8 Mar 2004 18:06:12 -0000	1.1.4.1
--- testsuite/gcc.dg/decl-5.c	24 Mar 2004 18:27:32 -0000
*************** void a()
*** 10,16 ****
  {
    void c();
    c();
! } /* { dg-bogus "error" "PR c/14114" { xfail *-*-* } } */
  
  void b()
  {
--- 10,16 ----
  {
    void c();
    c();
! }
  
  void b()
  {
Index: testsuite/gcc.dg/local1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/local1.c,v
retrieving revision 1.2.2.1
diff -c -p -r1.2.2.1 local1.c
*** testsuite/gcc.dg/local1.c	18 Mar 2004 22:52:39 -0000	1.2.2.1
--- testsuite/gcc.dg/local1.c	24 Mar 2004 18:27:32 -0000
***************
*** 1,3 ****
--- 1,19 ----
+ /* This is allowed, with the effect that the 'extern' declaration at block
+    scope refers to the same object as the 'static' declaration at file scope.
+ 
+       C90 6.1.2.2 [as corrected by TC1], C99 6.2.2:
+ 
+ 	  For an identifier declared with the storage-class specifier
+ 	  extern in a scope in which a prior declaration of that
+ 	  identifier is visible, if the prior declaration specifies
+ 	  internal or external linkage, the linkage of the identifier at
+ 	  the later daclaration is the same as the linkage specified at
+ 	  the prior declaration.  If no prior declaration is visible,
+ 	  or if the prior declaration specifies no linkage, then the
+ 	  identifer has external linkage.
+ 
+    This is PR 14366.  */
+ 
  static int i;
  
  extern int i;
Index: testsuite/gcc.dg/redecl-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/redecl-1.c,v
retrieving revision 1.1.2.2
diff -c -p -r1.1.2.2 redecl-1.c
*** testsuite/gcc.dg/redecl-1.c	30 Jan 2004 13:17:46 -0000	1.1.2.2
--- testsuite/gcc.dg/redecl-1.c	24 Mar 2004 18:27:34 -0000
*************** void test4(void)
*** 64,70 ****
  
  void prime5(void)
  {
!   extern double bar5(double);	/* { dg-error "previous" "" { xfail *-*-* } } 
*/
  }
  
  void test5(void)
--- 64,70 ----
  
  void prime5(void)
  {
!   extern double bar5(double);	/* { dg-error "previous" "" } */
  }
  
  void test5(void)
Index: testsuite/gcc.dg/unused-4.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/unused-4.c,v
retrieving revision 1.1.10.1
diff -c -p -r1.1.10.1 unused-4.c
*** testsuite/gcc.dg/unused-4.c	25 Nov 2003 02:11:30 -0000	1.1.10.1
--- testsuite/gcc.dg/unused-4.c	24 Mar 2004 18:27:34 -0000
***************
*** 1,6 ****
  /* { dg-do compile } */
  /* { dg-options "-Wunused -O3" } */
  
! static const int i = 0;
  static void f() { }		/* { dg-warning "defined but not used" } */
  static inline void g() { }
--- 1,6 ----
  /* { dg-do compile } */
  /* { dg-options "-Wunused -O3" } */
  
! static const int i = 0;		/* { dg-warning "unused variable" } */
  static void f() { }		/* { dg-warning "defined but not used" } */
  static inline void g() { }
Index: testsuite/gcc.dg/noncompile/incomplete-2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/noncompile/incomplete-2.c,v
retrieving revision 1.1.8.1
diff -c -p -r1.1.8.1 incomplete-2.c
*** testsuite/gcc.dg/noncompile/incomplete-2.c	20 Aug 2003 20:45:24 -0000	
1.1.8.1
--- testsuite/gcc.dg/noncompile/incomplete-2.c	24 Mar 2004 18:27:36 -0000
***************
*** 6,12 ****
  int g95_type_for_mode (enum machine_mode);
  
  int
! g95_type_for_mode (enum machine_mode mode)
! { /* { dg-error "has incomplete type" } */
    return 0;
  }
--- 6,12 ----
  int g95_type_for_mode (enum machine_mode);
  
  int
! g95_type_for_mode (enum machine_mode mode) /* { dg-error "incomplete type" } 
*/
! {
    return 0;
  }
Index: testsuite/gcc.dg/noncompile/incomplete-3.c
===================================================================
RCS file: testsuite/gcc.dg/noncompile/incomplete-3.c
diff -N testsuite/gcc.dg/noncompile/incomplete-3.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/noncompile/incomplete-3.c	24 Mar 2004 18:27:36 -0000
***************
*** 0 ****
--- 1,9 ----
+ /* Both occurrences of "c" should get diagnostics.  PR 12391.  */
+ typedef struct { int a; } b_t;
+ 
+ int foo (void)
+ {
+   b_t d;
+   struct b_t *c = &d;	/* { dg-warning "incompatible pointer type" } */
+   c->a;			/* { dg-error "incomplete type" } */
+ }
Index: testsuite/gcc.dg/noncompile/label-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/noncompile/label-1.c,v
retrieving revision 1.1.2.1
diff -c -p -r1.1.2.1 label-1.c
*** testsuite/gcc.dg/noncompile/label-1.c	23 Jul 2003 17:02:08 -0000	1.1.2.1
--- testsuite/gcc.dg/noncompile/label-1.c	24 Mar 2004 18:27:36 -0000
*************** void c(void)
*** 28,34 ****
  /* can't have two labels with the same name in the same function */
  void d(void)
  {
!  l: dummy();  /* { dg-error "previously defined" "prev def same scope" } */
   l: dummy();  /* { dg-error "duplicate label" "dup label same scope" } */
   goto l;
  }
--- 28,34 ----
  /* can't have two labels with the same name in the same function */
  void d(void)
  {
!  l: dummy();  /* { dg-error "previous definition" "prev def same scope" } */
   l: dummy();  /* { dg-error "duplicate label" "dup label same scope" } */
   goto l;
  }
*************** void d(void)
*** 36,42 ****
  /* even at different scopes */
  void e(void)
  {
!  l: dummy();	/* { dg-error "previously defined"  "prev def diff scope" } */
    {
    l: dummy();	/* { dg-error "duplicate label" "dup label diff scope" } */
    }
--- 36,42 ----
  /* even at different scopes */
  void e(void)
  {
!  l: dummy();	/* { dg-error "previous definition"  "prev def diff scope" } */
    {
    l: dummy();	/* { dg-error "duplicate label" "dup label diff scope" } */
    }
*************** void m(void)
*** 150,156 ****
  
  void n(void)
  {
!   __label__ l; /* { dg-error "previously declared" "outer label decl" } */
    void nest(void)
      {
      l: goto l;  /* { dg-error "duplicate label" "inner label defn" } */
--- 150,156 ----
  
  void n(void)
  {
!   __label__ l; /* { dg-error "previous declaration" "outer label decl" } */
    void nest(void)
      {
      l: goto l;  /* { dg-error "duplicate label" "inner label defn" } */
Index: testsuite/gcc.dg/noncompile/label-lineno-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/noncompile/label-lineno-1.c,v
retrieving revision 1.2.6.1
diff -c -p -r1.2.6.1 label-lineno-1.c
*** testsuite/gcc.dg/noncompile/label-lineno-1.c	23 Jul 2003 17:02:08 -0000	
1.2.6.1
--- testsuite/gcc.dg/noncompile/label-lineno-1.c	24 Mar 2004 18:27:36 -0000
***************
*** 4,10 ****
  void
  foo(int i)
  {
!  my_label: /* { dg-error "previously defined" "prev label" } */
  
    i++;
  
--- 4,10 ----
  void
  foo(int i)
  {
!  my_label: /* { dg-error "previous definition" "prev label" } */
  
    i++;
  
Index: testsuite/gcc.dg/noncompile/undeclared-1.c
===================================================================
RCS file: testsuite/gcc.dg/noncompile/undeclared-1.c
diff -N testsuite/gcc.dg/noncompile/undeclared-1.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/noncompile/undeclared-1.c	24 Mar 2004 18:27:36 -0000
***************
*** 0 ****
--- 1,8 ----
+ /* Test for no ICE with an undeclared identifier in an enum in old-style
+    parameter decls.  PR 12560.  */
+ /* { dg-options "-w" } */
+ 
+ foo(c)
+      enum { a = b } c;  /* { dg-error "undeclared|for each" } */
+ {
+ }
Index: testsuite/objc.dg/naming-1.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/naming-1.m,v
retrieving revision 1.1.22.1
diff -c -p -r1.1.22.1 naming-1.m
*** testsuite/objc.dg/naming-1.m	9 Apr 2003 19:28:59 -0000	1.1.22.1
--- testsuite/objc.dg/naming-1.m	24 Mar 2004 18:27:38 -0000
*************** void foo(void)
*** 9,17 ****
  {
          int View;	/* ok */
          View = 1;	/* ok */
! 	View *view;	/* { dg-error "`view' undeclared" } */
! 	/* { dg-error "is reported only once" "" { target *-*-* } 12 } */
! 	/* { dg-error "function it appears in" "" { target *-*-* } 12 } */
  }
  
  void bar(void)
--- 9,15 ----
  {
          int View;	/* ok */
          View = 1;	/* ok */
! 	View *view;	/* { dg-error "undeclared|only once|it appears" } */
  }
  
  void bar(void)







Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]