Revised c-decl.c patch - ObjC still not quite right
Ziemowit Laski
zlaski@apple.com
Sat Mar 20 22:07:00 GMT 2004
Zack,
I'll make you a deal. :-) Why don't you review and approve
http://gcc.gnu.org/ml/gcc-patches/2004-03/msg00222.html
and I'll give you temporary absolution for breaking comp-types-1.m and
fix the issue once your patch is in. You game? :-)
--Zem
On 20 Mar 2004, at 0.42, Zack Weinberg wrote:
>
> Here's my revisions to date. libobjc now builds, but I still see a
> few regressions in the objc testsuite:
>
> FAIL: objc.dg/comp-types-1.m (test for warnings, line 37)
> FAIL: objc.dg/comp-types-1.m (test for warnings, line 53)
> FAIL: objc.dg/comp-types-1.m (test for warnings, line 71)
> FAIL: objc.dg/comp-types-1.m (test for warnings, line 72)
> FAIL: objc.dg/comp-types-1.m (test for warnings, line 82)
> FAIL: objc.dg/comp-types-1.m (test for warnings, line 83)
>
> I can't see any obvious reason why these would have been caused by my
> patch, but neither can I see any obvious other cause for them.
>
> Java works now, I think. I got the dreaded segfault-that-disappears-
> on-retry building libjava. *Might* have been an out-of-memory
> condition.
>
> C, C++, F77 are in good shape. Haven't yet incorporated the
> suggestions for better commentary.
>
> All testing is on i686-linux btw.
>
> zw
>
> ===================================================================
> Index: c-common.h
> --- c-common.h 17 Feb 2004 18:32:32 -0000 1.222
> +++ c-common.h 20 Mar 2004 08:40:29 -0000
> @@ -329,6 +329,8 @@ extern void (*lang_expand_function_end)
> 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);
> @@ -950,9 +952,6 @@ extern int self_promoting_args_p (tree);
> 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. */
> ===================================================================
> Index: c-decl.c
> --- c-decl.c 18 Mar 2004 18:58:01 -0000 1.485
> +++ c-decl.c 20 Mar 2004 08:40:29 -0000
> @@ -108,19 +108,13 @@ static GTY(()) tree c_scope_stmt_stack;
> 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;
> -
> /* A DECL for the current file-scope context. */
>
> static GTY(()) tree current_file_decl;
>
> +/* 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. */
>
> @@ -144,10 +138,56 @@ static int warn_about_return_type;
> /* 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_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.
> +/* 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.
>
> @@ -157,18 +197,37 @@ static int current_extern_inline;
> 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
> + 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
> - global scope even though that isn't the current scope.
> + 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 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 bindings list is strictly in reverse order of declarations;
> + pop_scope relies on this. */
>
> - The order of the tags, shadowed, and shadowed_tags
> - lists does not matter, so we just prepend to these lists. */
>
> struct c_scope GTY(())
> {
> @@ -178,35 +237,18 @@ struct c_scope GTY(())
> /* 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;
> + /* 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;
> @@ -230,20 +272,28 @@ struct c_scope GTY(())
>
> 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. */
> +/* 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;
>
> -static GTY(()) struct c_scope *global_scope;
> +/* 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 { \
> @@ -271,7 +321,7 @@ static GTY(()) struct c_scope *global_sc
>
> static bool keep_next_level_flag;
>
> -/* True means the next call to pushlevel will be the outermost scope
> +/* 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. */
>
> @@ -282,27 +332,11 @@ static bool next_is_function_body;
> 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 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);
> -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
> @@ -319,9 +353,9 @@ static enum deprecated_states deprecated
> 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);
> + 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)];
> @@ -330,6 +364,80 @@ c_print_identifier (FILE *file, tree nod
> (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.
> */
> @@ -354,40 +462,6 @@ c_finish_incomplete_decl (tree decl)
> }
> }
>
> -/* 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 *
> @@ -403,30 +477,34 @@ void
> 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)
> {
> - tree decl;
> -
> - for (decl = scope->names; decl; decl = TREE_CHAIN (decl))
> + for (b = scope->bindings; b; b = b->prev)
> {
> - DECL_REGISTER (decl) = 0;
> - TREE_THIS_VOLATILE (decl) = 1;
> + 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 the global scope. */
> +/* Nonzero if we are currently in file scope. */
>
> int
> global_bindings_p (void)
> {
> - return current_scope == global_scope;
> + return current_scope == file_scope &&
> !c_override_global_bindings_to_false;
> }
>
> void
> @@ -443,19 +521,8 @@ declare_parm_level (void)
> 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)
> +push_scope (void)
> {
> if (next_is_function_body)
> {
> @@ -480,49 +547,46 @@ pushlevel (int dummy ATTRIBUTE_UNUSED)
> }
> else
> {
> - struct c_scope *scope = make_scope ();
> + 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.
> -
> - 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. */
> + 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
> -poplevel (int keep, int dummy ATTRIBUTE_UNUSED, int functionbody)
> +pop_scope (void)
> {
> 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);
> + tree block, context, p;
> + struct c_binding *b;
>
> - keep |= scope->keep;
> - keep |= scope->function_body;
> + 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. */
> @@ -530,28 +594,44 @@ poplevel (int keep, int dummy ATTRIBUTE_
> 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;
> + /* 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.
> + BLOCK_VARS (block) = 0;
> + }
>
> - Propagate TREE_ADDRESSABLE from nested functions to their
> - containing functions.
> + /* 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.
>
> - Issue warnings for unused variables and labels, and errors for
> - undefined labels, if there are any. */
> + 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;
>
> - for (p = scope->names; p; p = TREE_CHAIN (p))
> + /* 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);
> @@ -564,94 +644,101 @@ poplevel (int keep, int dummy ATTRIBUTE_
> 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;
>
> - IDENTIFIER_LABEL_VALUE (DECL_NAME (p)) = 0;
> - 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 normal;
> + goto common_symbol;
>
> 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
> + /* 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))
> + && !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;
> + }
>
> - default:
> - normal:
> - if (DECL_NAME (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)
> {
> - 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;
> +#ifdef ENABLE_CHECKING
> + if (I_SYMBOL_BINDING (b->id) != b) abort ();
> +#endif
> + I_SYMBOL_BINDING (b->id) = b->shadowed;
> }
> break;
> +
> + default:
> + abort ();
> }
> }
>
> - /* 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))
> +
> + /* Dispose of the block that we just made inside some higher level.
> */
> + if ((scope->function_body || scope == file_scope) && context)
> {
> - if (TREE_PURPOSE (p))
> - IDENTIFIER_TAG_VALUE (TREE_PURPOSE (p)) = 0;
> - if (decl)
> - TYPE_CONTEXT (TREE_VALUE (p)) = decl;
> + DECL_INITIAL (context) = block;
> + BLOCK_SUPERCONTEXT (block) = context;
> }
> -
> - /* 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)
> @@ -664,11 +751,60 @@ poplevel (int keep, int dummy ATTRIBUTE_
> }
>
> /* Pop the current scope, and free the structure for reuse. */
> - pop_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;
>
> 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. */
> @@ -679,15 +815,6 @@ insert_block (tree block)
> 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.
> @@ -696,24 +823,13 @@ set_block (tree block ATTRIBUTE_UNUSED)
> Note that the definition may really be just a forward reference.
> In that case, the TYPE_SIZE will be zero. */
>
> -void
> +static 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);
> + 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
> @@ -725,7 +841,7 @@ pushtag (tree name, tree type)
> 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. */
> + This will be updated in pop_scope. */
> TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_STUB_DECL (type));
> }
>
> @@ -916,8 +1032,9 @@ diagnose_mismatched_decls (tree newdecl,
> 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))
> + 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);
> @@ -927,7 +1044,7 @@ diagnose_mismatched_decls (tree newdecl,
> warning ("%Jbuilt-in function '%D' declared as non-function",
> newdecl, newdecl);
> else if (warn_shadow)
> - warning ("%Jshadowing built-in function '%D'",
> + warning ("%Jdeclaration of '%D' shadows a built-in function",
> newdecl, newdecl);
> return false;
> }
> @@ -935,7 +1052,7 @@ diagnose_mismatched_decls (tree newdecl,
> if (!comptypes (oldtype, newtype, COMPARE_STRICT))
> {
> if (TREE_CODE (olddecl) == FUNCTION_DECL
> - && DECL_BUILT_IN (olddecl) && C_DECL_INVISIBLE (olddecl))
> + && DECL_BUILT_IN (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl))
> {
> /* Accept harmless mismatch in function types.
> This is for the ffs and fprintf builtins. */
> @@ -1013,13 +1130,14 @@ diagnose_mismatched_decls (tree newdecl,
> 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)
> + && !C_DECL_DECLARED_BUILTIN (olddecl)
> && (!TREE_PUBLIC (newdecl)
> || (DECL_INITIAL (newdecl)
> && !TYPE_ARG_TYPES (TREE_TYPE (newdecl)))))
> {
> if (warn_shadow)
> - warning ("%Jshadowing built-in function '%D'", newdecl, newdecl);
> + warning ("%Jdeclaration of '%D' shadows a built-in function",
> + newdecl, newdecl);
> /* Discard the old built-in function. */
> return false;
> }
> @@ -1190,8 +1308,15 @@ diagnose_mismatched_decls (tree newdecl,
> }
> 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). */
> + /* 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)))
> {
> @@ -1258,13 +1383,26 @@ merge_decls (tree newdecl, tree olddecl,
> 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. */
> + /* 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 = ¤t_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;
> - return;
> }
>
> DECL_ATTRIBUTES (newdecl)
> @@ -1421,9 +1559,11 @@ merge_decls (tree newdecl, tree olddecl,
>
> if (DECL_BUILT_IN (olddecl))
> {
> - /* If redeclaring a builtin function, it stays built in. */
> + /* 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. */
> @@ -1454,6 +1594,9 @@ merge_decls (tree newdecl, tree olddecl,
> }
> }
>
> + /* 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. */
> {
> @@ -1495,69 +1638,49 @@ duplicate_decls (tree newdecl, tree oldd
> }
>
>
> -/* 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. */
> +/* Check whether decl-node NEW shadows an existing declaration. */
> static void
> -record_external_decl (tree decl)
> +warn_if_shadowing (tree new)
> {
> - tree name = DECL_NAME (decl);
> - if (!IDENTIFIER_SYMBOL_VALUE (name))
> - return;
> -
> - truly_local_externals = tree_cons (name, decl,
> truly_local_externals);
> -}
> + struct c_binding *b;
>
> -/* 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
> + /* Shadow warnings wanted? */
> + if (!warn_shadow
> /* No shadow warnings for internally generated vars. */
> - || DECL_SOURCE_LINE (x) == 0
> + || DECL_SOURCE_LINE (new) == 0
> /* No shadow warnings for vars made for inlining. */
> - || DECL_FROM_INLINE (x)
> + || 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. */
> - || (TREE_CODE (x) == PARM_DECL &&
> current_scope->outer->parm_flag))
> + 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;
>
> - 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);
> + /* 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;
>
> - warning ("%Jshadowed declaration is here", old);
> + 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;
> + }
> }
>
>
> @@ -1638,12 +1761,7 @@ pushdecl (tree x)
> {
> tree name = DECL_NAME (x);
> struct c_scope *scope = current_scope;
> -
> -#ifdef ENABLE_CHECKING
> - if (error_mark_node == 0)
> - /* Called too early. */
> - abort ();
> -#endif
> + struct c_binding *b;
>
> /* Functions need the lang_decl data. */
> if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x))
> @@ -1659,130 +1777,110 @@ pushdecl (tree x)
> else
> DECL_CONTEXT (x) = current_function_decl;
>
> - if (name)
> + /* Anonymous decls are just inserted in the scope. */
> + if (!name)
> {
> - tree old;
> + 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 != global_scope
> - && DECL_EXTERNAL (x)
> + && scope != file_scope
> && !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))
> - {
> - /* XXX This copy_node call violates the basic
> - assumption that there is only one DECL for any
> - given object. This causes all sorts of problems
> - elsewhere. To correct it we must stop chaining
> - DECLs directly within the scope structure (work
> - in progress). -zw 2004-03-05 */
> - x = copy_node (ext);
> -
> - /* Kludge around one of the worst consequences of
> - the above copy_node call, viz. that the arg_info
> - block created by get_parm_info can survive in a
> - copied FUNCTION_DECL after store_parm_decls is
> - done with it, and confuse the debug info
> - generators. */
> - if (TREE_CODE (ext) == FUNCTION_DECL
> - && DECL_ARGUMENTS (ext)
> - && TREE_CODE (DECL_ARGUMENTS (ext)) == TREE_LIST)
> - DECL_ARGUMENTS (ext) = 0;
> - }
> - }
> - 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);
> + while (b && b->contour != external_scope)
> + b = b->shadowed;
>
> - 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));
> + /* 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);
> }
> }
>
> - if (TREE_CODE (x) == PARM_DECL)
> - SCOPE_LIST_APPEND (scope, parms, x);
> - else
> - SCOPE_LIST_APPEND (scope, names, x);
> -
> + 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 the global scope (C99 "file scope").
> +/* 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. */
> @@ -1797,44 +1895,72 @@ pushdecl_top_level (tree x)
>
> name = DECL_NAME (x);
>
> - if (IDENTIFIER_SYMBOL_VALUE (name))
> + if (I_SYMBOL_BINDING (name))
> abort ();
>
> DECL_CONTEXT (x) = current_file_decl;
> - IDENTIFIER_SYMBOL_VALUE (name) = x;
> + 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);
>
> - SCOPE_LIST_APPEND (global_scope, names, x);
> 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 = any_external_decl (functionid);
> + tree decl = lookup_name_in_scope (functionid, external_scope);
>
> 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));
> + /* 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. */
> @@ -1842,7 +1968,7 @@ implicitly_declare (tree functionid)
> DECL_EXTERNAL (decl) = 1;
> TREE_PUBLIC (decl) = 1;
> C_DECL_IMPLICIT (decl) = 1;
> - implicit_decl_warning (functionid);
> + implicit_decl_warning (functionid, 0);
>
> /* C89 says implicit declarations are in the innermost block.
> So we record the decl in the standard fashion. */
> @@ -1861,16 +1987,6 @@ implicitly_declare (tree functionid)
> 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
> @@ -1884,14 +2000,12 @@ undeclared_variable (tree id)
>
> if (current_function_decl == 0)
> {
> - error ("`%s' undeclared here (not in a function)",
> - IDENTIFIER_POINTER (id));
> + error ("'%E' undeclared here (not in a function)", id);
> scope = current_scope;
> }
> else
> {
> - error ("`%s' undeclared (first use in this function)",
> - IDENTIFIER_POINTER (id));
> + error ("'%E' undeclared (first use in this function)", id);
>
> if (! already)
> {
> @@ -1900,12 +2014,11 @@ undeclared_variable (tree id)
> already = true;
> }
>
> - scope = current_function_scope;
> + /* 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;
> }
> -
> - scope->shadowed = tree_cons (id, IDENTIFIER_SYMBOL_VALUE (id),
> - scope->shadowed);
> - IDENTIFIER_SYMBOL_VALUE (id) = error_mark_node;
> + bind (id, error_mark_node, scope);
> }
>
> /* Subroutine of lookup_label, declare_label, define_label: construct
> a
> @@ -1923,20 +2036,6 @@ make_label (tree name, location_t locati
> 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
> @@ -1957,7 +2056,7 @@ lookup_label (tree name)
> /* 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);
> + label = I_LABEL_DECL (name);
> if (label && (DECL_CONTEXT (label) == current_function_decl
> || C_DECLARED_LABEL_FLAG (label)))
> {
> @@ -1973,7 +2072,7 @@ lookup_label (tree name)
> label = make_label (name, input_location);
>
> /* Ordinary labels go in the current function scope. */
> - bind_label (name, label, current_function_scope);
> + bind (name, label, current_function_scope);
> return label;
> }
>
> @@ -1988,26 +2087,25 @@ lookup_label (tree name)
> tree
> declare_label (tree name)
> {
> - tree label = IDENTIFIER_LABEL_VALUE (name);
> - tree dup;
> + 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 */
> - 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);
> + 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 dup;
> - }
> + /* 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_label (name, label, current_scope);
> + bind (name, label, current_scope);
> return label;
> }
>
> @@ -2018,13 +2116,11 @@ declare_label (tree name)
> 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);
> + tree label = I_LABEL_DECL (name);
>
> if (label
> && ((DECL_CONTEXT (label) == current_function_decl
> @@ -2033,10 +2129,7 @@ define_label (location_t location, tree
> && 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);
> + locate_old_decl (label, error);
> return 0;
> }
> else if (label && DECL_CONTEXT (label) == current_function_decl)
> @@ -2052,7 +2145,7 @@ define_label (location_t location, tree
> label = make_label (name, location);
>
> /* Ordinary labels go in the current function scope. */
> - bind_label (name, label, current_function_scope);
> + bind (name, label, current_function_scope);
> }
>
> if (warn_traditional && !in_system_header && lookup_name (name))
> @@ -2065,16 +2158,6 @@ define_label (location_t location, tree
> return label;
> }
>
> -/* Return the list of declarations of the current scope.
> - This hook is optional and not implemented for C. */
> -
> -tree
> -getdecls (void)
> -{
> - return 0;
> -}
> -
> -
> /* Given NAME, an IDENTIFIER_NODE,
> return the structure (or union or enum) definition for that name.
> If THISLEVEL_ONLY is nonzero, searches only the current_scope.
> @@ -2085,25 +2168,29 @@ getdecls (void)
> static tree
> lookup_tag (enum tree_code code, tree name, int thislevel_only)
> {
> - tree tag = IDENTIFIER_TAG_VALUE (name);
> + struct c_binding *b = I_TAG_BINDING (name);
> int thislevel = 0;
>
> - if (!tag)
> + 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 (tag) != code)
> + if (thislevel_only || TREE_CODE (b->decl) != code)
> {
> - if (current_scope == global_scope
> - || purpose_member (name, current_scope->tags))
> + /* 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 (tag) != code)
> + if (TREE_CODE (b->decl) != code)
> {
> /* Definition isn't the kind we were looking for. */
> pending_invalid_xref = name;
> @@ -2116,7 +2203,7 @@ lookup_tag (enum tree_code code, tree na
> if (thislevel)
> pending_xref_error ();
> }
> - return tag;
> + return b->decl;
> }
>
> /* Print an error message now
> @@ -2143,36 +2230,22 @@ pending_xref_error (void)
> 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;
> + 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 current scope. */
> +/* Similar to `lookup_name' but look only at the indicated scope. */
>
> static tree
> -lookup_name_current_level (tree name)
> +lookup_name_in_scope (tree name, struct c_scope *scope)
> {
> - 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;
> + struct c_binding *b;
>
> + for (b = I_SYMBOL_BINDING (name); b; b = b->shadowed)
> + if (b->contour == scope)
> + return b->decl;
> return 0;
> }
>
> @@ -2193,9 +2266,9 @@ c_init_decl_processing (void)
>
> current_function_decl = 0;
>
> - /* Make the c_scope structure for global names. */
> - pushlevel (0);
> - global_scope = current_scope;
> + /* 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
> @@ -2203,9 +2276,6 @@ c_init_decl_processing (void)
> 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 ();
> @@ -2231,9 +2301,6 @@ c_init_decl_processing (void)
>
> 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
> @@ -2269,8 +2336,7 @@ c_make_fname_decl (tree id, int type_dep
> if (current_function_decl)
> {
> DECL_CONTEXT (decl) = current_function_decl;
> - IDENTIFIER_SYMBOL_VALUE (id) = decl;
> - SCOPE_LIST_APPEND (current_function_scope, names, decl);
> + bind (id, decl, current_function_scope);
> }
>
> finish_decl (decl, init, NULL_TREE);
> @@ -2292,20 +2358,31 @@ builtin_function (const char *name, tree
> 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 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);
> - 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;
> + /* 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)
> @@ -2519,34 +2596,31 @@ start_decl (tree declarator, tree declsp
> 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. */
> + 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)));
> + error ("typedef '%D' is initialized (use __typeof__ instead)", decl);
> initialized = 0;
> break;
>
> case FUNCTION_DECL:
> - error ("function `%s' is initialized like a variable",
> - IDENTIFIER_POINTER (DECL_NAME (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 `%s' is initialized",
> - IDENTIFIER_POINTER (DECL_NAME (decl)));
> + 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.
> */
> + /* 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. */
> + /* 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)))
> @@ -2562,14 +2636,12 @@ start_decl (tree declarator, tree declsp
> }
> else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
> {
> - error ("variable `%s' has initializer but incomplete type",
> - IDENTIFIER_POINTER (DECL_NAME (decl)));
> + 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 `%s' have incomplete type",
> - IDENTIFIER_POINTER (DECL_NAME (decl)));
> + error ("elements of array '%D' have incomplete type", decl);
> initialized = 0;
> }
> }
> @@ -2577,12 +2649,12 @@ start_decl (tree declarator, tree declsp
> if (initialized)
> {
> DECL_EXTERNAL (decl) = 0;
> - if (current_scope == global_scope)
> + if (current_scope == file_scope)
> TREE_STATIC (decl) = 1;
>
> - /* Tell `pushdecl' this is an initialized decl
> + /* 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. */
> + Also tell 'finish_decl' it may store the real initializer. */
> DECL_INITIAL (decl) = error_mark_node;
> }
>
> @@ -2643,21 +2715,6 @@ start_decl (tree declarator, tree declsp
> 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;
> }
>
> @@ -2674,7 +2731,7 @@ finish_decl (tree decl, tree init, tree
> const char *asmspec = 0;
>
> /* If a name was specified, get the string. */
> - if (current_scope == global_scope)
> + if (current_scope == file_scope)
> asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
> if (asmspec_tree)
> asmspec = TREE_STRING_POINTER (asmspec_tree);
> @@ -2812,7 +2869,7 @@ finish_decl (tree decl, tree init, tree
> }
>
> /* If #pragma weak was used, mark the decl weak now. */
> - if (current_scope == global_scope)
> + if (current_scope == file_scope)
> maybe_apply_pragma_weak (decl);
>
> /* Output the assembler code and/or RTL code for variables and
> functions,
> @@ -2891,7 +2948,7 @@ finish_decl (tree decl, tree init, tree
> /* 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)
> + if (current_scope == file_scope)
> get_pending_sizes ();
>
> /* Install a cleanup (aka destructor) if one was given. */
> @@ -2955,14 +3012,13 @@ push_parm_decl (tree parm)
> 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.
> +/* Mark all the parameter declarations to date as forward decls.
> Also diagnose use of this extension. */
>
> void
> mark_forward_parm_decls (void)
> {
> - tree parm;
> + struct c_binding *b;
>
> if (pedantic && !current_scope->warned_forward_parm_decls)
> {
> @@ -2970,12 +3026,9 @@ mark_forward_parm_decls (void)
> 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;
> + 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;
> @@ -2996,7 +3049,7 @@ build_compound_literal (tree type, tree
> tree stmt;
> DECL_EXTERNAL (decl) = 0;
> TREE_PUBLIC (decl) = 0;
> - TREE_STATIC (decl) = (current_scope == global_scope);
> + TREE_STATIC (decl) = (current_scope == file_scope);
> DECL_CONTEXT (decl) = current_function_decl;
> TREE_USED (decl) = 1;
> TREE_TYPE (decl) = type;
> @@ -3316,8 +3369,7 @@ grokdeclarator (tree declarator, tree de
> /* 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)
> + if (decl_context == NORMAL && !funcdef_flag &&
> current_scope->parm_flag)
> decl_context = PARM;
>
> /* Look through the decl specs and record which ones appear.
> @@ -3413,11 +3465,11 @@ grokdeclarator (tree declarator, tree de
> 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)
> + 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);
> @@ -3674,7 +3726,7 @@ grokdeclarator (tree declarator, tree de
> | (1 << (int) RID_THREAD))))
> {
> if (specbits & 1 << (int) RID_AUTO
> - && (pedantic || current_scope == global_scope))
> + && (pedantic || current_scope == file_scope))
> pedwarn ("function definition declared `auto'");
> if (specbits & 1 << (int) RID_REGISTER)
> error ("function definition declared `register'");
> @@ -3712,12 +3764,12 @@ grokdeclarator (tree declarator, tree de
> 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)
> + 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 == global_scope)
> + else if (current_scope == file_scope)
> {
> if (specbits & 1 << (int) RID_AUTO)
> error ("file-scope declaration of `%s' specifies `auto'", name);
> @@ -3970,14 +4022,15 @@ grokdeclarator (tree declarator, tree de
> }
> else if (TREE_CODE (declarator) == CALL_EXPR)
> {
> - /* Declaring a function type. Say it's a definition only
> - for the CALL_EXPR closest to the identifier. */
> + /* 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;
>
> - /* Make sure we have a valid type for the function to return. */
> + /* Declaring a function type.
> + Make sure we have a valid type for the function to return. */
> if (type == error_mark_node)
> continue;
>
> @@ -4186,7 +4239,7 @@ grokdeclarator (tree declarator, tree de
> 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
> + || (current_scope == file_scope
> && !(specbits
> & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)))))))
> {
> @@ -4321,10 +4374,10 @@ grokdeclarator (tree declarator, tree de
> 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);
> + || current_scope == file_scope);
>
> if (specbits & (1 << (int) RID_AUTO)
> - && (pedantic || current_scope == global_scope))
> + && (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);
> @@ -4333,7 +4386,7 @@ grokdeclarator (tree declarator, tree de
> /* Function declaration not at file scope.
> Storage classes other than `extern' are not allowed
> and `extern' makes no difference. */
> - if (current_scope != global_scope
> + if (current_scope != file_scope
> && (specbits & ((1 << (int) RID_STATIC) | (1 << (int)
> RID_INLINE)))
> && pedantic)
> pedwarn ("invalid storage class for function `%s'", name);
> @@ -4414,20 +4467,23 @@ grokdeclarator (tree declarator, tree de
> else if (type_quals)
> type = c_build_qualified_type (type, type_quals);
>
> - /* It is invalid to create an `extern' declaration for a
> + /* 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 (extern_ref && current_scope != global_scope)
> + '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;
> + tree global_decl = identifier_global_value (declarator);
> + tree visible_decl = lookup_name (declarator);
>
> - global_decl = identifier_global_value (declarator);
> if (global_decl
> + && global_decl != visible_decl
> && TREE_CODE (global_decl) == VAR_DECL
> - && lookup_name (declarator) != global_decl
> && !TREE_PUBLIC (global_decl))
> - error ("variable previously declared `static' redeclared "
> - "`extern'");
> + error ("variable previously declared 'static' redeclared "
> + "'extern'");
> }
>
> decl = build_decl (VAR_DECL, declarator, type);
> @@ -4443,7 +4499,7 @@ grokdeclarator (tree declarator, tree de
> 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)
> + if (current_scope == file_scope)
> {
> TREE_PUBLIC (decl) = !(specbits & ((1 << (int) RID_STATIC)
> | (1 << (int) RID_REGISTER)));
> @@ -4518,7 +4574,10 @@ grokparms (tree arg_info, int funcdef_fl
> && !in_system_header)
> warning ("function declaration isn't a prototype");
>
> - if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) ==
> IDENTIFIER_NODE)
> + 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");
> @@ -4574,141 +4633,193 @@ grokparms (tree arg_info, int funcdef_fl
> }
> }
>
> -/* 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:
> +/* 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.
> + constants) defined with the parameters.
>
> This tree_list node is later fed to 'grokparms' and
> 'store_parm_decls'.
>
> - 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'. */
> + 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 (int void_at_end)
> +get_parm_info (bool ellipsis)
> {
> - 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;
> + 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;
>
> - /* 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");
> -
> - list = make_node (TREE_LIST);
> - ARG_INFO_TYPES (list) = build_tree_list (0, void_type_node);
> - return list;
> - }
> + /* 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;
>
> - /* Sanity check all of the parameter declarations. */
> - for (decl = parms; decl; decl = TREE_CHAIN (decl))
> - {
> + /* This function is only called if there was *something* on the
> + parameter list. */
> #ifdef ENABLE_CHECKING
> - if (TREE_CODE (decl) != PARM_DECL)
> - abort ();
> - if (TREE_ASM_WRITTEN (decl))
> - abort ();
> + if (b == 0)
> + abort ();
> #endif
>
> - /* 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;
> + /* 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");
>
> - /* 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;
> - }
> + /* There cannot be an ellipsis. */
> + if (ellipsis)
> + error ("'void' must be the only parameter");
>
> - type = build_tree_list (0, type);
> - *last_type = type;
> - last_type = &TREE_CHAIN (type);
> + ARG_INFO_TYPES (arg_info) = void_list_node;
> + return arg_info;
> }
>
> - /* 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);
> - }
> + if (!ellipsis)
> + types = void_list_node;
>
> - /* 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))
> + /* Break up the bindings list into parms, tags, types, and others;
> + apply sanity checks; purge the name-to-decl bindings. */
> + while (b)
> {
> - enum tree_code code = TREE_CODE (TREE_VALUE (decl));
> + tree decl = b->decl;
> + tree type = TREE_TYPE (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)
> + switch (TREE_CODE (decl))
> {
> - case RECORD_TYPE: keyword = "struct"; break;
> - case UNION_TYPE: keyword = "union"; break;
> - case ENUMERAL_TYPE: keyword = "enum"; break;
> - default: abort ();
> - }
> + 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;
> + }
>
> - if (TREE_PURPOSE (decl))
> - /* The %s will be one of 'struct', 'union', or 'enum'. */
> - warning ("'%s %E' declared inside parameter list",
> - keyword, TREE_PURPOSE (decl));
> - else
> - /* The %s will be one of 'struct', 'union', or 'enum'. */
> - warning ("anonymous %s declared inside parameter list", keyword);
> + /* 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;
>
> - if (! explained_incomplete_types)
> - {
> - warning ("its scope is only this definition or declaration,"
> - " which is probably not what you want");
> - explained_incomplete_types = true;
> - }
> - }
> + 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;
> + }
> + }
>
> - if (void_at_end)
> - {
> - type = build_tree_list (0, void_type_node);
> - *last_type = type;
> + 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);
> }
>
> - list = make_node (TREE_LIST);
> - ARG_INFO_PARMS (list) = parms;
> - ARG_INFO_TAGS (list) = tags;
> - ARG_INFO_TYPES (list) = types;
> - ARG_INFO_OTHERS (list) = others;
> - return list;
> + 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.
> @@ -4927,7 +5038,7 @@ tree
> finish_struct (tree t, tree fieldlist, tree attributes)
> {
> tree x;
> - int toplevel = global_scope == current_scope;
> + bool toplevel = file_scope == current_scope;
> int saw_named_field;
>
> /* If this type was previously laid out as a forward reference,
> @@ -4937,19 +5048,6 @@ finish_struct (tree t, tree fieldlist, t
>
> 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))
> @@ -5219,10 +5317,7 @@ finish_enum (tree enumtype, tree values,
> tree pair, tem;
> tree minnode = 0, maxnode = 0, enum_value_type;
> int precision, unsign;
> - int toplevel = (global_scope == current_scope);
> -
> - if (in_parm_level_p ())
> - warning ("enum defined inside parms");
> + bool toplevel = (file_scope == current_scope);
>
> decl_attributes (&enumtype, attributes, (int)
> ATTR_FLAG_TYPE_IN_PLACE);
>
> @@ -5351,16 +5446,19 @@ build_enumerator (tree name, tree value)
>
> if (value != 0)
> {
> - if (TREE_CODE (value) == INTEGER_CST)
> + /* 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)
> {
> - value = default_conversion (value);
> - constant_expression_warning (value);
> + error ("enumerator value for '%E' is not an integer constant",
> name);
> + value = 0;
> }
> else
> {
> - error ("enumerator value for `%s' not integer constant",
> - IDENTIFIER_POINTER (name));
> - value = 0;
> + value = default_conversion (value);
> + constant_expression_warning (value);
> }
> }
>
> @@ -5377,6 +5475,8 @@ build_enumerator (tree name, tree value)
> 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);
> }
>
> @@ -5463,13 +5563,13 @@ start_function (tree declspecs, tree dec
> 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 poplevel) with the BLOCK.
> */
> + 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_current_level (DECL_NAME (decl1));
> + 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)))
> @@ -5534,7 +5634,7 @@ start_function (tree declspecs, tree dec
> #endif
>
> /* If #pragma weak was used, mark the decl weak now. */
> - if (current_scope == global_scope)
> + if (current_scope == file_scope)
> maybe_apply_pragma_weak (decl1);
>
> /* Warn for unlikely, improbable, or stupid declarations of `main'.
> */
> @@ -5600,7 +5700,7 @@ start_function (tree declspecs, tree dec
>
> current_function_decl = pushdecl (decl1);
>
> - pushlevel (0);
> + push_scope ();
> declare_parm_level ();
>
> make_decl_rtl (current_function_decl, NULL);
> @@ -5639,75 +5739,56 @@ start_function (tree declspecs, tree dec
> static void
> store_parm_decls_newstyle (tree fndecl, tree arg_info)
> {
> - tree decl, last;
> -
> - tree parms = ARG_INFO_PARMS (arg_info);
> - tree tags = ARG_INFO_TAGS (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->parms || current_scope->names ||
> current_scope->tags)
> + if (current_scope->bindings)
> {
> error ("%Jold-style parameter declarations in prototyped "
> "function definition", fndecl);
>
> /* Get rid of the old-style declarations. */
> - poplevel (0, 0, 0);
> - pushlevel (0);
> + 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 (last = 0, decl = parms; decl; last = decl, decl = TREE_CHAIN
> (decl))
> + for (decl = parms; decl; decl = TREE_CHAIN (decl))
> {
> DECL_CONTEXT (decl) = current_function_decl;
> - if (DECL_NAME (decl) == 0)
> - error ("%Jparameter name omitted", decl);
> + if (DECL_NAME (decl))
> + bind (DECL_NAME (decl), decl, current_scope);
> 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;
> - }
> + error ("%Jparameter name omitted", 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))
> + for (decl = others; 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;
> - }
> + if (DECL_NAME (decl))
> + bind (DECL_NAME (decl), decl, current_scope);
> }
> - 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;
> + bind (TREE_PURPOSE (decl), TREE_VALUE (decl), current_scope);
> }
>
> /* Subroutine of store_parm_decls which handles old-style function
> @@ -5716,19 +5797,21 @@ store_parm_decls_newstyle (tree fndecl,
> static void
> store_parm_decls_oldstyle (tree fndecl, tree arg_info)
> {
> + struct c_binding *b;
> tree parm, decl, last;
> -
> - /* This is the identifier list from the function declarator. */
> 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 (parm = current_scope->parms; parm; parm = TREE_CHAIN (parm))
> - if (DECL_WEAK (parm))
> + 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))
> @@ -5740,17 +5823,18 @@ store_parm_decls_oldstyle (tree fndecl,
> continue;
> }
>
> - decl = IDENTIFIER_SYMBOL_VALUE (TREE_VALUE (parm));
> - if (decl && DECL_CONTEXT (decl) == fndecl)
> + 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);
> + 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);
> + error ("%Jmultiple parameters named '%D'", decl, decl);
> TREE_PURPOSE (parm) = 0;
> continue;
> }
> @@ -5758,7 +5842,7 @@ store_parm_decls_oldstyle (tree fndecl,
> an int. */
> else if (VOID_TYPE_P (TREE_TYPE (decl)))
> {
> - error ("%Jparameter \"%D\" declared void", decl, 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);
> @@ -5773,9 +5857,9 @@ store_parm_decls_oldstyle (tree fndecl,
> pushdecl (decl);
>
> if (flag_isoc99)
> - pedwarn ("%Jtype of \"%D\" defaults to \"int\"", decl, decl);
> + pedwarn ("%Jtype of '%D' defaults to 'int'", decl, decl);
> else if (extra_warnings)
> - warning ("%Jtype of \"%D\" defaults to \"int\"", decl, decl);
> + warning ("%Jtype of '%D' defaults to 'int'", decl, decl);
> }
>
> TREE_PURPOSE (parm) = decl;
> @@ -5785,17 +5869,21 @@ store_parm_decls_oldstyle (tree fndecl,
> /* Now examine the parms chain for incomplete declarations
> and declarations with no corresponding names. */
>
> - for (parm = current_scope->parms; parm; parm = TREE_CHAIN (parm))
> + 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);
> + 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",
> + error ("%Jdeclaration for parameter '%D' but no such parameter",
> parm, parm);
>
> /* Pretend the parameter was not missing.
> @@ -5817,7 +5905,6 @@ store_parm_decls_oldstyle (tree fndecl,
> {
> 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))
> @@ -5827,7 +5914,6 @@ store_parm_decls_oldstyle (tree fndecl,
> last = TREE_PURPOSE (parm);
> DECL_WEAK (last) = 0;
> }
> - current_scope->parms_last = last;
> TREE_CHAIN (last) = 0;
> }
>
> @@ -5877,7 +5963,7 @@ store_parm_decls_oldstyle (tree fndecl,
>
> if (pedantic)
> {
> - pedwarn ("promoted argument \"%D\" "
> + pedwarn ("promoted argument '%D' "
> "doesn't match prototype", parm);
> pedwarn ("%Hprototype declaration",
> ¤t_function_prototype_locus);
> @@ -5885,7 +5971,7 @@ store_parm_decls_oldstyle (tree fndecl,
> }
> else
> {
> - error ("argument \"%D\" doesn't match prototype", parm);
> + error ("argument '%D' doesn't match prototype", parm);
> error ("%Hprototype declaration",
> ¤t_function_prototype_locus);
> }
> @@ -5947,26 +6033,26 @@ store_parm_decls (void)
> /* The argument information block for FNDECL. */
> tree arg_info = DECL_ARGUMENTS (fndecl);
>
> - /* True if this definition is written with a prototype. Since this
> - is a function definition, we can treat a null parameter list
> - (i.e. "foo()") as prototyped (C99 6.7.5.3p14) - this reduces
> - overhead. */
> - bool prototype = (!ARG_INFO_PARMS (arg_info)
> - || TREE_CODE (ARG_INFO_PARMS (arg_info)) != TREE_LIST);
> + /* 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 (prototype)
> + if (proto)
> store_parm_decls_newstyle (fndecl, arg_info);
> else
> store_parm_decls_oldstyle (fndecl, arg_info);
>
> - /* The next call to pushlevel will be a function body. */
> + /* 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, prototype);
> + gen_aux_info_record (fndecl, 1, 0, proto);
>
> /* Initialize the RTL code for the function. */
> allocate_struct_function (fndecl);
> @@ -6014,17 +6100,17 @@ finish_function (void)
> /* 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
> + 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 pushlevel does not actually push another
> + 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)
> {
> - pushlevel (0);
> - poplevel (0, 0, 0);
> + push_scope ();
> + pop_scope ();
> }
>
> if (TREE_CODE (fndecl) == FUNCTION_DECL
> @@ -6168,7 +6254,7 @@ c_expand_body (tree fndecl)
> void
> check_for_loop_decls (void)
> {
> - tree t;
> + struct c_binding *b;
>
> if (!flag_isoc99)
> {
> @@ -6192,35 +6278,38 @@ check_for_loop_decls (void)
> interpretation, to avoid creating an extension which later causes
> problems. */
>
> - for (t = current_scope->tags; t; t = TREE_CHAIN (t))
> + for (b = current_scope->bindings; b; b = b->prev)
> {
> - if (TREE_PURPOSE (t) != 0)
> - {
> - enum tree_code code = TREE_CODE (TREE_VALUE (t));
> + tree id = b->id;
> + tree decl = b->decl;
>
> - 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)));
> - }
> - }
> + if (!id)
> + continue;
>
> - 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);
> + 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);
> + }
> }
> }
>
> @@ -6373,16 +6462,12 @@ c_expand_decl_stmt (tree t)
> tree
> identifier_global_value (tree t)
> {
> - tree decl = IDENTIFIER_SYMBOL_VALUE (t);
> - if (decl == 0 || DECL_FILE_SCOPE_P (decl))
> - return decl;
> + struct c_binding *b;
>
> - /* 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;
> + for (b = I_SYMBOL_BINDING (t); b; b = b->shadowed)
> + if (b->contour == file_scope || b->contour == external_scope)
> + return b->decl;
>
> - /* Only local values for this decl. */
> return 0;
> }
>
> @@ -6393,14 +6478,11 @@ void
> 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);
> + pushdecl (build_decl (TYPE_DECL, id, type));
> }
>
> /* Build the void_list_node (void_type_node having been created). */
> @@ -6447,178 +6529,42 @@ c_static_assembler_name (tree decl)
> 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)
> +/* Perform final processing on file-scope data. */
> +static void
> +c_write_global_declarations_1 (tree globals)
> {
> - const tree tu_list = current_file_decl;
> - tree tu;
> + size_t len = list_length (globals);
> + tree *vec = xmalloc (sizeof (tree) * len);
> + size_t i;
> 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);
> - }
> +
> + /* Process the decls in the order they were written. */
> + for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
> + vec[i] = decl;
>
> - htab_delete (link_hash_table);
> + wrapup_global_declarations (vec, len);
> + check_global_declarations (vec, len);
> +
> + free (vec);
> }
>
> -/* Perform final processing on file-scope data. */
> -
> void
> -c_write_global_declarations(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);
> - }
> -}
> + tree t;
>
> -/* Reset the parser's state in preparation for a new file. */
> + /* We don't want to do this if generating a PCH. */
> + if (pch_file)
> + return;
>
> -void
> -c_reset_state (void)
> -{
> - tree link;
> - tree file_scope_decl;
> + /* 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)));
>
> - /* 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));
> + /* 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
> --- c-lang.c 4 Feb 2004 19:15:16 -0000 1.121
> +++ c-lang.c 20 Mar 2004 08:40:29 -0000
> @@ -65,6 +65,8 @@ enum c_language_kind c_language = clk_c;
> #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
> @@ -136,6 +138,19 @@ enum c_language_kind c_language = clk_c;
> #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-objc-common.c
> --- c-objc-common.c 14 Mar 2004 22:26:00 -0000 1.41
> +++ c-objc-common.c 20 Mar 2004 08:40:29 -0000
> @@ -206,7 +206,7 @@ start_cdtor (int method_type)
>
> body = c_begin_compound_stmt ();
>
> - pushlevel (0);
> + push_scope ();
> clear_last_expr ();
> add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
>
> @@ -220,7 +220,7 @@ finish_cdtor (tree body)
> tree block;
>
> scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
> - block = poplevel (0, 0, 0);
> + block = pop_scope ();
> SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
> SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
>
> @@ -236,10 +236,6 @@ c_objc_common_finish_file (void)
> {
> 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 ();
> ===================================================================
> Index: c-opts.c
> --- c-opts.c 4 Mar 2004 02:39:37 -0000 1.107
> +++ c-opts.c 20 Mar 2004 08:40:29 -0000
> @@ -1216,41 +1216,24 @@ c_common_init (void)
> /* 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)
> +c_common_parse_file (int set_yydebug)
> {
> - unsigned file_index;
> -
> #if YYDEBUG != 0
> yydebug = set_yydebug;
> #else
> - warning ("YYDEBUG not defined");
> + if (set_yydebug)
> + warning ("YYDEBUG not defined");
> #endif
>
> - file_index = 0;
> -
> - do
> - {
> - if (file_index > 0)
> - {
> - /* Reset the state of the parser. */
> - c_reset_state();
> + if (num_in_fnames > 1)
> + fatal_error ("sorry, inter-module analysis temporarily out of
> commission");
>
> - /* 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_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
> --- c-parse.in 27 Feb 2004 02:01:06 -0000 1.202
> +++ c-parse.in 20 Mar 2004 08:40:29 -0000
> @@ -208,7 +208,7 @@ do { \
> %type <ttype> any_word
>
> %type <ttype> compstmt compstmt_start compstmt_nostart
> compstmt_primary_start
> -%type <ttype> do_stmt_start poplevel stmt label
> +%type <ttype> do_stmt_start pop_scope stmt label
>
> %type <ttype> c99_block_start c99_block_end
> %type <ttype> declarator
> @@ -328,8 +328,6 @@ static int objc_need_raw_identifier;
> #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)
> @@ -368,11 +366,6 @@ extdefs:
> ;
>
> extdef:
> - extdef_1
> - { parsing_iso_function_signature = false; } /* Reset after any
> external definition. */
> - ;
> -
> -extdef_1:
> fndef
> | datadef
> | asmdef
> @@ -741,28 +734,8 @@ primary:
> ;
>
> 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
> @@ -1555,7 +1528,6 @@ nested_function:
> 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;
> @@ -1586,7 +1558,6 @@ notype_nested_function:
> 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;
> @@ -1620,9 +1591,6 @@ after_type_declarator:
> { $$ = $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
> @@ -1645,9 +1613,6 @@ parm_declarator:
> 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
> @@ -1659,9 +1624,6 @@ parm_declarator_starttypename:
> 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
> @@ -1678,9 +1640,6 @@ parm_declarator_nostarttypename:
> 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
> @@ -2037,14 +1996,14 @@ lineno_stmt_decl_or_labels:
> errstmt: error ';'
> ;
>
> -pushlevel: /* empty */
> - { pushlevel (0);
> +push_scope: /* empty */
> + { push_scope ();
> clear_last_expr ();
> add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
> }
> ;
>
> -poplevel: /* empty */
> +pop_scope: /* empty */
> {
> @@ifobjc
> if (c_dialect_objc ())
> @@ -2059,7 +2018,7 @@ c99_block_start: /* empty */
> { if (flag_isoc99)
> {
> $$ = c_begin_compound_stmt ();
> - pushlevel (0);
> + push_scope ();
> clear_last_expr ();
> add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
> }
> @@ -2075,7 +2034,7 @@ c99_block_end: /* empty */
> { if (flag_isoc99)
> {
> tree scope_stmt = add_scope_stmt (/*begin_p=*/0,
> /*partial_p=*/0);
> - $$ = poplevel (KEEP_MAYBE, 0, 0);
> + $$ = pop_scope ();
> SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
> = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
> = $$;
> @@ -2124,8 +2083,8 @@ compstmt_start: '{' { compstmt_count++;
>
> compstmt_nostart: '}'
> { $$ = convert (void_type_node, integer_zero_node); }
> - | pushlevel maybe_label_decls compstmt_contents_nonempty '}' poplevel
> - { $$ = poplevel (KEEP_MAYBE, 0, 0);
> + | push_scope maybe_label_decls compstmt_contents_nonempty '}'
> pop_scope
> + { $$ = pop_scope ();
> SCOPE_STMT_BLOCK (TREE_PURPOSE ($5))
> = SCOPE_STMT_BLOCK (TREE_VALUE ($5))
> = $$; }
> @@ -2589,11 +2548,11 @@ start_string_translation:
> "void bar (int (__attribute__((__mode__(SI))) int foo));". */
> parmlist:
> maybe_attribute
> - { pushlevel (0);
> + { push_scope ();
> declare_parm_level (); }
> parmlist_1
> { $$ = $3;
> - poplevel (0, 0, 0); }
> + pop_scope (); }
> ;
>
> parmlist_1:
> @@ -2606,32 +2565,23 @@ parmlist_1:
> parmlist_1
> { $$ = $6; }
> | error ')'
> - { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); }
> + { $$ = 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 */
> - { $$ = get_parm_info (0); }
> + { $$ = make_node (TREE_LIST); }
> | 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. */
> + { $$ = make_node (TREE_LIST);
> + /* Suppress -Wold-style-definition for this case. */
> + TREE_CHAIN ($$) = error_mark_node;
> error ("ISO C requires a named argument before `...'");
> - parsing_iso_function_signature = true;
> }
> | parms
> - { $$ = get_parm_info (1);
> - parsing_iso_function_signature = true;
> - }
> + { $$ = get_parm_info (/*ellipsis=*/false); }
> | parms ',' ELLIPSIS
> - { $$ = get_parm_info (0);
> - parsing_iso_function_signature = true;
> - }
> + { $$ = get_parm_info (/*ellipsis=*/true); }
> ;
>
> parms:
> @@ -2706,11 +2656,11 @@ setspecs_fp:
> Its value is a list of ..._TYPE nodes or a list of identifiers. */
> parmlist_or_identifiers:
> maybe_attribute
> - { pushlevel (0);
> + { push_scope ();
> declare_parm_level (); }
> parmlist_or_identifiers_1
> { $$ = $3;
> - poplevel (0, 0, 0); }
> + pop_scope (); }
> ;
>
> parmlist_or_identifiers_1:
> @@ -3128,13 +3078,13 @@ optparmlist:
> }
> | ','
> {
> - pushlevel (0);
> + push_scope ();
> }
> parmlist_2
> {
> /* returns a tree list node generated by get_parm_info */
> $$ = $3;
> - poplevel (0, 0, 0);
> + pop_scope ();
> }
> ;
>
> @@ -3799,22 +3749,14 @@ yyprint (FILE *file, int yychar, YYSTYPE
> }
> }
>
> -/* 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. */
> +/* 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 ();
> - /* 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)
> {
> ===================================================================
> Index: c-tree.h
> --- c-tree.h 29 Feb 2004 23:43:20 -0000 1.141
> +++ c-tree.h 20 Mar 2004 08:40:29 -0000
> @@ -24,22 +24,21 @@ Software Foundation, 59 Temple Place - S
>
> #include "c-common.h"
>
> -/* Language-dependent contents of an identifier. */
> +/* 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;
>
> -/* 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. */
> +/* Language-dependent contents of an identifier. */
>
> struct lang_identifier GTY(())
> {
> struct c_common_identifier common_id;
> - tree symbol_value;
> - tree tag_value;
> - tree label_value;
> + 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. */
> @@ -64,26 +63,6 @@ struct lang_decl GTY(())
> 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)
>
> @@ -128,11 +107,13 @@ struct lang_type GTY(())
> /* 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)
> +/* 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
> @@ -147,11 +128,6 @@ struct lang_type GTY(())
> 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. */
> @@ -181,9 +157,9 @@ extern int c_in_case_stmt;
>
> extern int global_bindings_p (void);
> extern tree getdecls (void);
> -extern void pushlevel (int);
> +extern void push_scope (void);
> +extern tree pop_scope (void);
> extern void insert_block (tree);
> -extern void set_block (tree);
> extern tree pushdecl (tree);
> extern void c_expand_body (tree);
>
> @@ -203,12 +179,11 @@ extern void finish_decl (tree, tree, tre
> 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 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 int in_parm_level_p (void);
> extern void keep_next_level (void);
> extern tree lookup_name (tree);
> extern void pending_xref_error (void);
> @@ -216,7 +191,6 @@ extern void c_push_function_context (str
> 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);
> @@ -230,7 +204,6 @@ extern tree c_begin_compound_stmt (void)
> extern void c_expand_decl_stmt (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);
> @@ -257,6 +230,7 @@ enum {
> };
>
> 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);
> @@ -312,6 +286,11 @@ extern int current_function_returns_abno
> /* 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
> --- c-typeck.c 18 Mar 2004 20:58:34 -0000 1.289
> +++ c-typeck.c 20 Mar 2004 08:40:30 -0000
> @@ -51,7 +51,6 @@ Software Foundation, 59 Temple Place - S
> 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);
> @@ -369,9 +368,9 @@ common_type (tree t1, tree t2)
>
> /* If both args specify argument types, we must merge the two
> lists, argument by argument. */
> -
> - pushlevel (0);
> - declare_parm_level ();
> + /* 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;
> @@ -434,8 +433,7 @@ common_type (tree t1, tree t2)
> parm_done: ;
> }
>
> - poplevel (0, 0, 0);
> -
> + c_override_global_bindings_to_false = false;
> t1 = build_function_type (valtype, newargs);
> /* ... falls through ... */
> }
> @@ -614,11 +612,11 @@ comp_target_types (tree ttl, tree ttr, i
>
> /* 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,
> +/* 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. */
> -static int
> +int
> same_translation_unit_p (tree t1, tree t2)
> {
> while (t1 && TREE_CODE (t1) != TRANSLATION_UNIT_DECL)
> @@ -633,7 +631,7 @@ same_translation_unit_p (tree t1, tree t
> while (t2 && TREE_CODE (t2) != TRANSLATION_UNIT_DECL)
> switch (TREE_CODE_CLASS (TREE_CODE (t2)))
> {
> - case 'd': t2 = DECL_CONTEXT (t1); break;
> + case 'd': t2 = DECL_CONTEXT (t2); break;
> case 't': t2 = TYPE_CONTEXT (t2); break;
> case 'b': t2 = BLOCK_SUPERCONTEXT (t2); break;
> default: abort ();
> ===================================================================
> Index: coverage.c
> --- coverage.c 14 Mar 2004 22:26:01 -0000 1.31
> +++ coverage.c 20 Mar 2004 08:40:30 -0000
> @@ -902,7 +902,6 @@ create_coverage (void)
> 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;
> ===================================================================
> Index: langhooks.c
> --- langhooks.c 14 Mar 2004 22:26:06 -0000 1.60
> +++ langhooks.c 20 Mar 2004 08:40:30 -0000
> @@ -216,7 +216,7 @@ void
> lhd_clear_binding_stack (void)
> {
> while (! lang_hooks.decls.global_bindings_p ())
> - poplevel (0, 0, 0);
> + lang_hooks.decls.poplevel (0, 0, 0);
> }
>
> /* Type promotion for variable arguments. */
> ===================================================================
> Index: tree.c
> --- tree.c 19 Mar 2004 19:36:52 -0000 1.358
> +++ tree.c 20 Mar 2004 08:40:30 -0000
> @@ -941,11 +941,23 @@ chain_member (tree elem, tree chain)
> int
> list_length (tree t)
> {
> - tree tail;
> + tree p = t;
> +#ifdef ENABLE_TREE_CHECKING
> + tree q = t;
> +#endif
> int len = 0;
>
> - for (tail = t; tail; tail = TREE_CHAIN (tail))
> - len++;
> + 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/cp-lang.c
> --- cp/cp-lang.c 15 Mar 2004 18:20:51 -0000 1.74
> +++ cp/cp-lang.c 20 Mar 2004 08:40:32 -0000
> @@ -388,13 +388,6 @@ cp_var_mod_type_p (tree type)
> return false;
> }
>
> -/* 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
> @@ -408,4 +401,15 @@ cxx_initialize_diagnostics (diagnostic_c
>
> /* 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
> --- cp/parser.c 19 Mar 2004 09:58:41 -0000 1.186
> +++ cp/parser.c 20 Mar 2004 08:40:32 -0000
> @@ -15347,7 +15347,6 @@ cp_parser_allow_gnu_extensions_p (cp_par
> }
>
>
> -
> /* The parser. */
>
> static GTY (()) cp_parser *the_parser;
> @@ -15360,6 +15359,14 @@ void
> 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
> --- objc/objc-act.c 6 Mar 2004 00:26:42 -0000 1.207
> +++ objc/objc-act.c 20 Mar 2004 08:40:34 -0000
> @@ -64,8 +64,6 @@ Boston, MA 02111-1307, USA. */
> #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
> @@ -161,7 +159,6 @@ static void generate_ivar_lists (void);
> 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);
> @@ -1238,7 +1235,7 @@ synth_module_prologue (void)
> = build_function_type (IMP_type,
> tree_cons (NULL_TREE, id_type,
> tree_cons (NULL_TREE,
> selector_type,
> -
> OBJC_VOID_AT_END)));
> +
> void_list_node)));
> umsg_decl = builtin_function (TAG_MSGSEND,
> temp_type, 0, NOT_BUILT_IN,
> NULL, NULL_TREE);
> @@ -1248,7 +1245,7 @@ synth_module_prologue (void)
> = build_function_type (IMP_type,
> tree_cons (NULL_TREE, super_type,
> tree_cons (NULL_TREE,
> selector_type,
> -
> OBJC_VOID_AT_END)));
> +
> void_list_node)));
> umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
> temp_type, 0, NOT_BUILT_IN,
> NULL, NULL_TREE);
> @@ -1259,7 +1256,7 @@ synth_module_prologue (void)
> temp_type = build_function_type (id_type,
> tree_cons (NULL_TREE,
> const_string_type_node,
> - OBJC_VOID_AT_END));
> + void_list_node));
>
> objc_get_class_decl
> = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
> @@ -1305,8 +1302,6 @@ synth_module_prologue (void)
> 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;
> @@ -1877,7 +1872,7 @@ build_module_descriptor (void)
> get_identifier (TAG_EXECCLASS),
> build_function_type (void_type_node,
> tree_cons (NULL_TREE, ptr_type_node,
> - OBJC_VOID_AT_END)));
> + void_list_node)));
>
> DECL_EXTERNAL (execclass_decl) = 1;
> DECL_ARTIFICIAL (execclass_decl) = 1;
> @@ -1892,7 +1887,7 @@ build_module_descriptor (void)
> start_function (void_list_node_1,
> build_nt (CALL_EXPR, init_function_name,
> tree_cons (NULL_TREE, NULL_TREE,
> - OBJC_VOID_AT_END),
> + void_list_node),
> NULL_TREE),
> NULL_TREE);
> store_parm_decls ();
> @@ -1919,22 +1914,6 @@ build_module_descriptor (void)
> }
> }
>
> -/* 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
> @@ -2699,7 +2678,7 @@ objc_enter_block (void)
> block = begin_compound_stmt (0);
> #else
> block = c_begin_compound_stmt ();
> - pushlevel (0);
> + push_scope ();
> clear_last_expr ();
> add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
> #endif
> @@ -2724,7 +2703,7 @@ objc_exit_block (void)
> finish_compound_stmt (0, block);
> #else
> scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
> - inner = poplevel (KEEP_MAYBE, 1, 0);
> + inner = pop_scope ();
>
> SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
> = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
> @@ -3331,7 +3310,7 @@ build_objc_exception_stuff (void)
> = build_function_type (id_type,
> tree_cons (NULL_TREE,
> build_pointer_type (objc_exception_data_template),
> - OBJC_VOID_AT_END));
> + 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 *); */
> @@ -3340,7 +3319,7 @@ build_objc_exception_stuff (void)
> = build_function_type (void_type_node,
> tree_cons (NULL_TREE,
> build_pointer_type (objc_exception_data_template),
> - OBJC_VOID_AT_END));
> + 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
> @@ -3350,7 +3329,7 @@ build_objc_exception_stuff (void)
> /* void objc_sync_exit(id); */
> temp_type = build_function_type (void_type_node,
> tree_cons (NULL_TREE, id_type,
> - OBJC_VOID_AT_END));
> + 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)
> @@ -3363,7 +3342,7 @@ build_objc_exception_stuff (void)
> temp_type = build_function_type (integer_type_node,
> tree_cons (NULL_TREE, id_type,
> tree_cons (NULL_TREE, id_type,
> - OBJC_VOID_AT_END)));
> + void_list_node)));
> objc_exception_match_decl
> = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0,
> NOT_BUILT_IN, NULL, NULL_TREE);
>
> @@ -5463,7 +5442,7 @@ get_arg_type_list (tree meth, int contex
>
> if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
> /* We have a `, ...' immediately following the selector,
> - finalize the arglist...simulate get_parm_info (0). */
> + finalize the arglist...simulate get_parm_info (true). */
> ;
> else if (METHOD_ADD_ARGS (meth))
> {
> @@ -5472,8 +5451,8 @@ get_arg_type_list (tree meth, int contex
> chainon (arglist, add_arg_list);
> }
> else
> - /* finalize the arglist...simulate get_parm_info (1) */
> - chainon (arglist, OBJC_VOID_AT_END);
> + /* finalize the arglist...simulate get_parm_info (false) */
> + chainon (arglist, void_list_node);
>
> return arglist;
> }
> @@ -7539,7 +7518,8 @@ start_method_def (tree method)
> UOBJC_SUPER_decl = NULL_TREE;
>
> /* Must be called BEFORE start_function. */
> - pushlevel (0);
> + push_scope ();
> + declare_parm_level ();
>
> /* Generate prototype declarations for arguments..."new-style". */
> synth_self_and_ucmd_args ();
> @@ -7819,9 +7799,9 @@ continue_method_def (void)
>
> if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
> /* We have a `, ...' immediately following the selector. */
> - parmlist = get_parm_info (0);
> + parmlist = get_parm_info (/*ellipsis=*/true);
> else
> - parmlist = get_parm_info (1); /* place a `void_at_end' */
> + parmlist = get_parm_info (/*ellipsis=*/false);
>
> #ifndef OBJCPLUS
> /* Set self_decl from the first argument...this global is used by
> @@ -7829,7 +7809,7 @@ continue_method_def (void)
> self_decl = TREE_PURPOSE (parmlist);
> #endif /* !OBJCPLUS */
>
> - poplevel (0, 0, 0);
> + pop_scope ();
> really_start_method (objc_method_context, parmlist);
> store_parm_decls ();
> }
> @@ -8800,8 +8780,6 @@ finish_objc (void)
> 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. */
> ===================================================================
> Index: objc/objc-act.h
> --- objc/objc-act.h 15 Oct 2003 00:10:27 -0000 1.20
> +++ objc/objc-act.h 20 Mar 2004 08:40:34 -0000
> @@ -234,7 +234,6 @@ enum objc_tree_index
> OCTI_MCLS_DECL,
> OCTI_SEL_TABLE_DECL,
> OCTI_MODULES_DECL,
> - OCTI_STRG_DECL,
>
> OCTI_INTF_CTX,
> OCTI_IMPL_CTX,
> @@ -360,7 +359,6 @@ extern GTY(()) tree objc_global_trees[OC
> #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
> ===================================================================
> Index: objc/objc-lang.c
> --- objc/objc-lang.c 3 Feb 2004 11:22:41 -0000 1.40
> +++ objc/objc-lang.c 20 Mar 2004 08:40:34 -0000
> @@ -55,6 +55,8 @@ enum c_language_kind c_language = clk_ob
> #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_MARK_ADDRESSABLE
> @@ -130,6 +132,19 @@ enum c_language_kind c_language = clk_ob
> #undef LANG_HOOKS_TYPE_PROMOTES_TO
> #define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to
>
> +/* 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/gcc.dg/Wold-style-definition-1.c
> --- testsuite/gcc.dg/Wold-style-definition-1.c 15 Sep 2003 09:31:16
> -0000 1.1
> +++ testsuite/gcc.dg/Wold-style-definition-1.c 20 Mar 2004 08:40:41
> -0000
> @@ -5,19 +5,19 @@
> /* { dg-options "-Wold-style-definition" } */
>
> void
> -bar (a) int a; { } /* { dg-warning "old-style parameter declaration"
> } */
> +bar (a) int a; { } /* { dg-warning "old-style function definition" }
> */
>
> -void bar1 () {} /* { dg-warning "old-style parameter declaration" } */
> +void bar1 () {} /* { dg-warning "old-style function definition" } */
>
> extern void bar2 (void);
>
> -void bar2 () {} /* { dg-warning "old-style parameter declaration" } */
> +void bar2 () {} /* { dg-warning "old-style function definition" } */
>
> extern void bar3 (int);
>
> -void bar3 (a) {} /* { dg-warning "old-style parameter declaration" }
> */
> +void bar3 (a) {} /* { dg-warning "old-style function definition" } */
>
> -void bar4 (a) {} /* { dg-warning "old-style parameter declaration" }
> */
> +void bar4 (a) {} /* { dg-warning "old-style function definition" } */
>
> void bar5 (int a) {}
>
> ===================================================================
> Index: testsuite/gcc.dg/Wshadow-2.c
> --- testsuite/gcc.dg/Wshadow-2.c 1 Jan 1970 00:00:00 -0000
> +++ testsuite/gcc.dg/Wshadow-2.c 20 Mar 2004 08:40:41 -0000
> @@ -0,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
> --- testsuite/gcc.dg/builtins-30.c 24 Jan 2004 05:27:45 -0000 1.2
> +++ testsuite/gcc.dg/builtins-30.c 20 Mar 2004 08:40:41 -0000
> @@ -7,20 +7,20 @@ extern double strtod (const char *, char
> /* A built-in function may be overridden by an old-style definition
> specifying too few arguments... */
> double nan ()
> -{ /* { dg-warning "shadowing built-in" } */
> +{ /* { dg-warning "shadows a 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" } */
> + int foo UNUSED; /* { dg-warning "shadows a built-in" } */
> {
> return strtod ("nan", 0);
> }
>
> /* or too many arguments. */
> long double nanl (foo, bar)
> - const char *foo UNUSED; /* { dg-warning "shadowing built-in" }
> */
> + const char *foo UNUSED; /* { dg-warning "shadows a built-in" }
> */
> int bar UNUSED;
> {
> return strtod ("nan", 0);
> ===================================================================
> Index: testsuite/gcc.dg/decl-5.c
> --- testsuite/gcc.dg/decl-5.c 6 Mar 2004 09:28:51 -0000 1.1
> +++ testsuite/gcc.dg/decl-5.c 20 Mar 2004 08:40:41 -0000
> @@ -10,7 +10,7 @@ void a()
> {
> void c();
> c();
> -} /* { dg-bogus "error" "PR c/14114" { xfail *-*-* } } */
> +}
>
> void b()
> {
> ===================================================================
> Index: testsuite/gcc.dg/local1.c
> --- testsuite/gcc.dg/local1.c 18 Mar 2004 18:58:07 -0000 1.2
> +++ testsuite/gcc.dg/local1.c 20 Mar 2004 08:40:41 -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
> --- testsuite/gcc.dg/redecl-1.c 11 Jan 2004 01:18:58 -0000 1.2
> +++ testsuite/gcc.dg/redecl-1.c 20 Mar 2004 08:40:41 -0000
> @@ -64,7 +64,7 @@ void test4(void)
>
> void prime5(void)
> {
> - extern double bar5(double); /* { dg-error "previous" "" { xfail
> *-*-* } } */
> + extern double bar5(double); /* { dg-error "previous" "" } */
> }
>
> void test5(void)
> ===================================================================
> Index: testsuite/gcc.dg/unused-4.c
> --- testsuite/gcc.dg/unused-4.c 13 Nov 2003 19:40:19 -0000 1.2
> +++ testsuite/gcc.dg/unused-4.c 20 Mar 2004 08:40:41 -0000
> @@ -1,6 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-Wunused -O3" } */
>
> -static const int i = 0;
> +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-3.c
> --- testsuite/gcc.dg/noncompile/incomplete-3.c 1 Jan 1970 00:00:00
> -0000
> +++ testsuite/gcc.dg/noncompile/incomplete-3.c 20 Mar 2004 08:40:41
> -0000
> @@ -0,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
> --- testsuite/gcc.dg/noncompile/label-1.c 19 Jul 2003 23:32:55
> -0000 1.1
> +++ testsuite/gcc.dg/noncompile/label-1.c 20 Mar 2004 08:40:41 -0000
> @@ -28,7 +28,7 @@ void c(void)
> /* 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 "previous definition" "prev def same
> scope" } */
> l: dummy(); /* { dg-error "duplicate label" "dup label same scope"
> } */
> goto l;
> }
> @@ -36,7 +36,7 @@ void d(void)
> /* even at different scopes */
> void e(void)
> {
> - l: dummy(); /* { dg-error "previously defined" "prev def diff
> scope" } */
> + l: dummy(); /* { dg-error "previous definition" "prev def diff
> scope" } */
> {
> l: dummy(); /* { dg-error "duplicate label" "dup label diff scope"
> } */
> }
> @@ -150,7 +150,7 @@ void m(void)
>
> void n(void)
> {
> - __label__ l; /* { dg-error "previously declared" "outer label decl"
> } */
> + __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
> --- testsuite/gcc.dg/noncompile/label-lineno-1.c 19 Jul 2003 23:32:55
> -0000 1.3
> +++ testsuite/gcc.dg/noncompile/label-lineno-1.c 20 Mar 2004 08:40:41
> -0000
> @@ -4,7 +4,7 @@
> void
> foo(int i)
> {
> - my_label: /* { dg-error "previously defined" "prev label" } */
> + my_label: /* { dg-error "previous definition" "prev label" } */
>
> i++;
>
> ===================================================================
> Index: testsuite/gcc.dg/noncompile/undeclared-1.c
> --- testsuite/gcc.dg/noncompile/undeclared-1.c 1 Jan 1970 00:00:00
> -0000
> +++ testsuite/gcc.dg/noncompile/undeclared-1.c 20 Mar 2004 08:40:41
> -0000
> @@ -0,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
> --- testsuite/objc.dg/naming-1.m 17 Mar 2003 20:58:44 -0000 1.2
> +++ testsuite/objc.dg/naming-1.m 20 Mar 2004 08:40:42 -0000
> @@ -9,9 +9,7 @@ void foo(void)
> {
> 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 } */
> + View *view; /* { dg-error "undeclared|only once|it appears" } */
> }
>
> void bar(void)
More information about the Gcc-patches
mailing list