c-tree.h (struct lang_identifier): Remove error_locus field.

* c-tree.h (struct lang_identifier): Remove error_locus field.
	(IDENTIFIER_ERROR_LOCUS): Kill.
	(record_function_scope_shadow): New prototype.
	* c-typeck.c (build_external_ref): Don't complain if
	decl is error_mark_node.  When not at file scope, bind the
	decl's local value to error_mark_node to suppress further
	warnings, instead of setting IDENTIFIER_ERROR_LOCUS.

	* c-decl.c (get_function_binding_level): New static function.
	(record_function_scope_shadow): New exported function.
	(c_make_fname_decl): Use get_function_binding_level.

From-SVN: r64504
This commit is contained in:
Zack Weinberg 2003-03-17 21:16:07 +00:00
parent 0fef2ffc6f
commit 6970c06a4e
4 changed files with 65 additions and 30 deletions

View file

@ -1,3 +1,17 @@
2003-03-17 Zack Weinberg <zack@codesourcery.com>
* c-tree.h (struct lang_identifier): Remove error_locus field.
(IDENTIFIER_ERROR_LOCUS): Kill.
(record_function_scope_shadow): New prototype.
* c-typeck.c (build_external_ref): Don't complain if
decl is error_mark_node. When not at file scope, bind the
decl's local value to error_mark_node to suppress further
warnings, instead of setting IDENTIFIER_ERROR_LOCUS.
* c-decl.c (get_function_binding_level): New static function.
(record_function_scope_shadow): New exported function.
(c_make_fname_decl): Use get_function_binding_level.
2003-03-17 Steve Ellcey <sje@cup.hp.com> 2003-03-17 Steve Ellcey <sje@cup.hp.com>
* stmt.c (tail_recursion_args): Call promote_mode to set * stmt.c (tail_recursion_args): Call promote_mode to set
@ -19,7 +33,7 @@ Mon Mar 17 18:57:01 CET 2003 Jan Hubicka <jh@suse.cz>
* function.c (assign_parms): For a struct value address passed as * function.c (assign_parms): For a struct value address passed as
first argument, delay the function's result RTL setup code until first argument, delay the function's result RTL setup code until
after the emission of parameter conversions. after the emission of parameter conversions.
2003-03-17 Dave Love <fx@gnu.org> 2003-03-17 Dave Love <fx@gnu.org>
Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
@ -63,13 +77,13 @@ Mon Mar 17 18:57:01 CET 2003 Jan Hubicka <jh@suse.cz>
2003-03-16 Richard Henderson <rth@redhat.com> 2003-03-16 Richard Henderson <rth@redhat.com>
* simplify-rtx (simplify_binary_operation): Don't abort for * simplify-rtx (simplify_binary_operation): Don't abort for
SS_PLUS, US_PLUS, SS_MINUS, US_MINUS. SS_PLUS, US_PLUS, SS_MINUS, US_MINUS.
2003-03-16 Richard Henderson <rth@redhat.com> 2003-03-16 Richard Henderson <rth@redhat.com>
* config/i386/i386.md (movstrictqi, movstrictqi_1): Check * config/i386/i386.md (movstrictqi, movstrictqi_1): Check
optimize_size as well. optimize_size as well.
2003-03-16 Stephane Carrez <stcarrez@nerim.fr> 2003-03-16 Stephane Carrez <stcarrez@nerim.fr>

View file

@ -268,7 +268,8 @@ tree static_ctors, static_dtors;
/* Forward declarations. */ /* Forward declarations. */
static struct binding_level * make_binding_level PARAMS ((void)); static struct binding_level *make_binding_level PARAMS ((void));
static struct binding_level *get_function_binding_level PARAMS ((void));
static void pop_binding_level PARAMS ((struct binding_level **)); static void pop_binding_level PARAMS ((struct binding_level **));
static void clear_limbo_values PARAMS ((tree)); static void clear_limbo_values PARAMS ((tree));
static int duplicate_decls PARAMS ((tree, tree, int)); static int duplicate_decls PARAMS ((tree, tree, int));
@ -309,7 +310,6 @@ c_print_identifier (file, node, indent)
print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4); print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4); print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4); print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4);
print_node (file, "limbo value", IDENTIFIER_LIMBO_VALUE (node), indent + 4); print_node (file, "limbo value", IDENTIFIER_LIMBO_VALUE (node), indent + 4);
if (C_IS_RESERVED_WORD (node)) if (C_IS_RESERVED_WORD (node))
{ {
@ -360,6 +360,17 @@ make_binding_level ()
return (struct binding_level *) ggc_alloc (sizeof (struct binding_level)); return (struct binding_level *) ggc_alloc (sizeof (struct binding_level));
} }
/* Return the outermost binding level for the current function. */
static struct binding_level *
get_function_binding_level ()
{
struct binding_level *b = current_binding_level;
while (b->level_chain->parm_flag == 0)
b = b->level_chain;
return b;
}
/* Remove a binding level from a list and add it to the level chain. */ /* Remove a binding level from a list and add it to the level chain. */
static void static void
@ -2016,6 +2027,17 @@ pushdecl (x)
return x; return x;
} }
/* Record that the local value of NAME is shadowed at function scope.
This is used by build_external_ref in c-typeck.c. */
void
record_function_scope_shadow (name)
tree name;
{
struct binding_level *b = get_function_binding_level ();
b->shadowed = tree_cons (name, IDENTIFIER_LOCAL_VALUE (name),
b->shadowed);
}
/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */ /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
tree tree
@ -2557,11 +2579,8 @@ c_make_fname_decl (id, type_dep)
if (current_function_decl) if (current_function_decl)
{ {
/* Add the decls to the outermost block. */ /* Add the decls to the outermost block. */
struct binding_level *b = current_binding_level; struct binding_level *old = current_binding_level;
struct binding_level *old = b; current_binding_level = get_function_binding_level ();
while (b->level_chain->parm_flag == 0)
b = b->level_chain;
current_binding_level = b;
pushdecl (decl); pushdecl (decl);
current_binding_level = old; current_binding_level = old;
} }

View file

@ -41,7 +41,6 @@ struct lang_identifier GTY(())
tree local_value; tree local_value;
tree label_value; tree label_value;
tree implicit_decl; tree implicit_decl;
tree error_locus;
tree limbo_value; tree limbo_value;
}; };
@ -91,10 +90,6 @@ struct lang_decl GTY(())
has had one at any point in this compilation. */ has had one at any point in this compilation. */
#define IDENTIFIER_IMPLICIT_DECL(NODE) \ #define IDENTIFIER_IMPLICIT_DECL(NODE) \
(((struct lang_identifier *) (NODE))->implicit_decl) (((struct lang_identifier *) (NODE))->implicit_decl)
/* This is the last function in which we printed an "undefined variable"
message for this identifier. Value is a FUNCTION_DECL or null. */
#define IDENTIFIER_ERROR_LOCUS(NODE) \
(((struct lang_identifier *) (NODE))->error_locus)
/* In identifiers, C uses the following fields in a special way: /* In identifiers, C uses the following fields in a special way:
TREE_PUBLIC to record that there was a previous local extern decl. TREE_PUBLIC to record that there was a previous local extern decl.
@ -226,6 +221,7 @@ extern void push_label_level PARAMS ((void));
extern void push_parm_decl PARAMS ((tree)); extern void push_parm_decl PARAMS ((tree));
extern tree pushdecl_top_level PARAMS ((tree)); extern tree pushdecl_top_level PARAMS ((tree));
extern void pushtag PARAMS ((tree, tree)); extern void pushtag PARAMS ((tree, tree));
extern void record_function_scope_shadow PARAMS ((tree));
extern tree set_array_declarator_type PARAMS ((tree, tree, int)); extern tree set_array_declarator_type PARAMS ((tree, tree, int));
extern tree shadow_label PARAMS ((tree)); extern tree shadow_label PARAMS ((tree));
extern void shadow_tag PARAMS ((tree)); extern void shadow_tag PARAMS ((tree));

View file

@ -1412,6 +1412,11 @@ build_external_ref (id, fun)
} }
else else
{ {
/* Don't complain about something that's already been
complained about. */
if (decl == error_mark_node)
return error_mark_node;
/* Reference to undeclared variable, including reference to /* Reference to undeclared variable, including reference to
builtin outside of function-call context. */ builtin outside of function-call context. */
if (current_function_decl == 0) if (current_function_decl == 0)
@ -1419,21 +1424,22 @@ build_external_ref (id, fun)
IDENTIFIER_POINTER (id)); IDENTIFIER_POINTER (id));
else else
{ {
if (IDENTIFIER_GLOBAL_VALUE (id) != error_mark_node error ("`%s' undeclared (first use in this function)",
|| IDENTIFIER_ERROR_LOCUS (id) != current_function_decl) IDENTIFIER_POINTER (id));
{
error ("`%s' undeclared (first use in this function)",
IDENTIFIER_POINTER (id));
if (! undeclared_variable_notice) if (! undeclared_variable_notice)
{ {
error ("(Each undeclared identifier is reported only once"); error ("(Each undeclared identifier is reported only once");
error ("for each function it appears in.)"); error ("for each function it appears in.)");
undeclared_variable_notice = 1; undeclared_variable_notice = 1;
}
} }
IDENTIFIER_GLOBAL_VALUE (id) = error_mark_node;
IDENTIFIER_ERROR_LOCUS (id) = current_function_decl; /* Set IDENTIFIER_LOCAL_VALUE (id) to error_mark_node and
add a function-scope shadow entry which will undo that.
This suppresses further warnings about this undeclared
identifier in this function. */
record_function_scope_shadow (id);
IDENTIFIER_LOCAL_VALUE (id) = error_mark_node;
} }
return error_mark_node; return error_mark_node;
} }