From 4124ea8b95fc038dd73c353e2350df0f134e27f4 Mon Sep 17 00:00:00 2001
From: zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon, 17 Mar 2003 21:16:07 +0000
Subject: [PATCH] 	* 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.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@64504 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog  | 24 +++++++++++++++++++-----
 gcc/c-decl.c   | 33 ++++++++++++++++++++++++++-------
 gcc/c-tree.h   |  6 +-----
 gcc/c-typeck.c | 32 +++++++++++++++++++-------------
 4 files changed, 65 insertions(+), 30 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7859221582de..e9702e5dca70 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
 
 	* 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
 	first argument, delay the function's result RTL setup code until
 	after the emission of parameter conversions.
-	
+
 2003-03-17  Dave Love  <fx@gnu.org>
 	    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>
 
-        * simplify-rtx (simplify_binary_operation): Don't abort for
-        SS_PLUS, US_PLUS, SS_MINUS, US_MINUS.
+	* simplify-rtx (simplify_binary_operation): Don't abort for
+	SS_PLUS, US_PLUS, SS_MINUS, US_MINUS.
 
 2003-03-16  Richard Henderson  <rth@redhat.com>
 
-        * config/i386/i386.md (movstrictqi, movstrictqi_1): Check
-        optimize_size as well.
+	* config/i386/i386.md (movstrictqi, movstrictqi_1): Check
+	optimize_size as well.
 
 2003-03-16  Stephane Carrez  <stcarrez@nerim.fr>
 
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 2aa0ee77f67f..a4b435e82917 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -268,7 +268,8 @@ tree static_ctors, static_dtors;
 
 /* 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 clear_limbo_values		PARAMS ((tree));
 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, "label", IDENTIFIER_LABEL_VALUE (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);
   if (C_IS_RESERVED_WORD (node))
     {
@@ -360,6 +360,17 @@ make_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.  */
 
 static void
@@ -2016,6 +2027,17 @@ pushdecl (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.  */
 
 tree
@@ -2557,11 +2579,8 @@ c_make_fname_decl (id, type_dep)
   if (current_function_decl)
     {
       /* Add the decls to the outermost block.  */
-      struct binding_level *b = current_binding_level;
-      struct binding_level *old = b;
-      while (b->level_chain->parm_flag == 0)
-	b = b->level_chain;
-      current_binding_level = b;
+      struct binding_level *old = current_binding_level;
+      current_binding_level = get_function_binding_level ();
       pushdecl (decl);
       current_binding_level = old;
     }	
diff --git a/gcc/c-tree.h b/gcc/c-tree.h
index 22d1ee2f5fa5..29352f5dd433 100644
--- a/gcc/c-tree.h
+++ b/gcc/c-tree.h
@@ -41,7 +41,6 @@ struct lang_identifier GTY(())
   tree local_value;
   tree label_value;
   tree implicit_decl;
-  tree error_locus;
   tree limbo_value;
 };
 
@@ -91,10 +90,6 @@ struct lang_decl GTY(())
    has had one at any point in this compilation.  */
 #define IDENTIFIER_IMPLICIT_DECL(NODE)	\
   (((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:
    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 tree pushdecl_top_level                  PARAMS ((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 shadow_label                        PARAMS ((tree));
 extern void shadow_tag                          PARAMS ((tree));
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index bb696e8cfefd..dc5b9d5ba0e8 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -1412,6 +1412,11 @@ build_external_ref (id, fun)
 	}
       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
 	     builtin outside of function-call context.  */
 	  if (current_function_decl == 0)
@@ -1419,21 +1424,22 @@ build_external_ref (id, fun)
 		   IDENTIFIER_POINTER (id));
 	  else
 	    {
-	      if (IDENTIFIER_GLOBAL_VALUE (id) != error_mark_node
-		  || IDENTIFIER_ERROR_LOCUS (id) != current_function_decl)
-		{
-		  error ("`%s' undeclared (first use in this function)",
-			 IDENTIFIER_POINTER (id));
+	      error ("`%s' undeclared (first use in this function)",
+		     IDENTIFIER_POINTER (id));
 
-		  if (! undeclared_variable_notice)
-		    {
-		      error ("(Each undeclared identifier is reported only once");
-		      error ("for each function it appears in.)");
-		      undeclared_variable_notice = 1;
-		    }
+	      if (! undeclared_variable_notice)
+		{
+		  error ("(Each undeclared identifier is reported only once");
+		  error ("for each function it appears in.)");
+		  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;
 	}
-- 
GitLab