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


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

Re: f build dies with: undefined reference to `lookup_name'


On Thu, Mar 07, 2002 at 09:48:29AM +1030, Alan Modra wrote:
> How about looking through the weak_decls list from pushdecl?

This seems to work.  Tested by building c,c++,f powerpc64-linux, and
using the following testcase.

cat >weakf.c <<EOF
extern int foo (void) __attribute__ ((weak));

#pragma weak bar
extern int bar (void);

extern int var1 __attribute__ ((weak));

#pragma weak var2
extern int var2;

extern int def (void) __attribute__ ((weak));
int def (void) { return var1; }

#pragma weak zzz = def
#pragma weak xxx = def2

#pragma weak def2
int def2 (void) { return var2; }

#pragma weak oops
static int oops (void) { return zzz () + xxx (); }

int main (void)
{
  if (foo)
    return (*foo) ();
  if (bar)
    return (*bar) ();
  if (&var1)
    return var1;
  if (&var2)
    return var2;
  return def ();
}
EOF

powerpc-linux and i686-linux bootstrap in progress.

BTW, how should we treat "#pragma weak foo = foo" ?  My c-pragma.c patch
makes it the same as "#pragma weak foo", but maybe an error is more
appropriate.  This change (or doing something slightly different in
decl_pending_weak) is necessary as decl_pending_weak needs to look
through the weak list twice to handle:

#pragma weak fun
#pragma weak fun2 = fun
int fun (void);

gcc/ChangeLog
	* c-decl.c (pushdecl): Call decl_pending_weak.
	* output.h (decl_pending_weak): Declare.
	* varasm.c (weak_decls_tail): New.
	(add_weak): Manipulate weak_decls_tail.
	(decl_pending_weak): New.
	(weak_finish): Don't lookup_name here.
	(remove_from_pending_weak_list): Fix up weak_decls_tail.  Don't
	strcmp identifiers.
	* c-pragma.c (handle_pragma_weak): Try to find a decl for value.
	Check value != name.

gcc/cp/ChangeLog
	* decl.c (pushdecl): Call decl_pending_weak.

Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.305
diff -u -p -r1.305 c-decl.c
--- c-decl.c	2002/03/05 02:34:05	1.305
+++ c-decl.c	2002/03/07 02:44:37
@@ -2242,6 +2242,14 @@ pushdecl (x)
 
 	  IDENTIFIER_GLOBAL_VALUE (name) = x;
 
+	  /* Check for a function or var decl weakened by "#pragma weak".  */
+	  if ((TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
+	      && decl_pending_weak (x))
+	    {
+	      TREE_PUBLIC (name) = 1;
+	      DECL_WEAK (x) = 1;
+	    }
+
 	  /* We no longer care about any previous block level declarations.  */
 	  IDENTIFIER_LIMBO_VALUE (name) = 0;
 
Index: c-pragma.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.c,v
retrieving revision 1.47
diff -u -p -r1.47 c-pragma.c
--- c-pragma.c	2002/03/01 06:00:32	1.47
+++ c-pragma.c	2002/03/07 02:44:37
@@ -26,6 +26,7 @@ Software Foundation, 59 Temple Place - S
 #include "function.h"
 #include "cpplib.h"
 #include "c-pragma.h"
+#include "c-tree.h"
 #include "flags.h"
 #include "toplev.h"
 #include "ggc.h"
@@ -281,8 +282,9 @@ static void
 handle_pragma_weak (dummy)
      cpp_reader *dummy ATTRIBUTE_UNUSED;
 {
-  tree name, value, x;
+  tree name, value, x, decl;
   enum cpp_ttype t;
+  const char *valstr;
 
   value = 0;
 
@@ -298,8 +300,14 @@ handle_pragma_weak (dummy)
   if (t != CPP_EOF)
     warning ("junk at end of #pragma weak");
 
-  add_weak (NULL_TREE, IDENTIFIER_POINTER (name),
-	    value ? IDENTIFIER_POINTER (value) : NULL);
+  decl = NULL_TREE;
+  valstr = NULL;
+  if (value && value != name)
+    {
+      decl = lookup_name (value);
+      valstr = IDENTIFIER_POINTER (value);
+    }
+  add_weak (decl, IDENTIFIER_POINTER (name), valstr);
 }
 #endif
 
Index: output.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/output.h,v
retrieving revision 1.96
diff -u -p -r1.96 output.h
--- output.h	2002/03/01 06:00:33	1.96
+++ output.h	2002/03/07 02:44:37
@@ -231,6 +231,10 @@ extern void mergeable_constant_section	P
 
 /* Declare DECL to be a weak symbol.  */
 extern void declare_weak		PARAMS ((tree));
+
+/* Look for DECL on "#pragma weak" list.  If found return 1 and tie
+   decl to list, otherwise return 0.  */
+extern int decl_pending_weak		PARAMS ((tree));
 #endif /* TREE_CODE */
 
 /* Emit any pending weak declarations.  */
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.255
diff -u -p -r1.255 varasm.c
--- varasm.c	2002/03/03 04:50:53	1.255
+++ varasm.c	2002/03/07 02:44:43
@@ -42,7 +42,6 @@ Software Foundation, 59 Temple Place - S
 #include "obstack.h"
 #include "hashtab.h"
 #include "c-pragma.h"
-#include "c-tree.h"
 #include "ggc.h"
 #include "langhooks.h"
 #include "tm_p.h"
@@ -5036,6 +5035,7 @@ struct weak_syms
 };
 
 static struct weak_syms * weak_decls;
+static struct weak_syms ** weak_decls_tail = &weak_decls;
 
 /* Mark weak_decls for garbage collection.  */
 
@@ -5050,7 +5050,8 @@ mark_weak_decls (arg)
 }
 
 /* Add function NAME to the weak symbols list.  VALUE is a weak alias
-   associated with NAME.  */
+   associated with NAME.  IF DECL is 0, we are being called from
+   #pragma weak handler.  *WEAK_DECLS_TAIL points to such entries.  */
 
 int
 add_weak (decl, name, value)
@@ -5065,15 +5066,53 @@ add_weak (decl, name, value)
   if (weak == NULL)
     return 0;
 
-  weak->next = weak_decls;
   weak->decl = decl;
   weak->name = name;
   weak->value = value;
-  weak_decls = weak;
+  weak->next = *weak_decls_tail;
+  *weak_decls_tail = weak;
+  if (decl)
+    weak_decls_tail = &weak->next;
 
   return 1;
 }
 
+/* Look for DECL on "#pragma weak" list.  If found return 1 and tie
+   decl to list, otherwise return 0.  */
+
+int
+decl_pending_weak (decl)
+     tree decl;
+{
+  const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
+  struct weak_syms **p;
+  struct weak_syms *weak;
+
+  for (p = weak_decls_tail; (weak = *p) != NULL; p = &weak->next)
+    if (weak->value == name)
+      {
+	weak->decl = decl;
+	*p = weak->next;
+	weak->next = *weak_decls_tail;
+	*weak_decls_tail = weak;
+	weak_decls_tail = &weak->next;
+	break;
+      }
+
+  for (p = weak_decls_tail; (weak = *p) != NULL; p = &weak->next)
+    if (weak->name == name)
+      {
+	weak->decl = decl;
+	*p = weak->next;
+	weak->next = *weak_decls_tail;
+	*weak_decls_tail = weak;
+	weak_decls_tail = &weak->next;
+	return 1;
+      }
+
+  return 0;
+}
+
 /* Declare DECL to be a weak symbol.  */
 
 void
@@ -5103,14 +5142,7 @@ weak_finish ()
       for (t = weak_decls; t != NULL; t = t->next)
 	{
 #ifdef ASM_WEAKEN_DECL
-	  tree decl = t->decl;
-	  if (decl == NULL_TREE)
-	    {
-	      tree name = get_identifier (t->name);
-	      if (name)
-		decl = lookup_name (name);
-	    }
-	  ASM_WEAKEN_DECL (asm_out_file, decl, t->name, t->value);
+	  ASM_WEAKEN_DECL (asm_out_file, t->decl, t->name, t->value);
 #else
 #ifdef ASM_OUTPUT_WEAK_ALIAS
 	  ASM_OUTPUT_WEAK_ALIAS (asm_out_file, t->name, t->value);
@@ -5140,9 +5172,11 @@ remove_from_pending_weak_list (name)
   for (p = &weak_decls; *p; )
     {
       t = *p;
-      if (strcmp (name, t->name) == 0)
+      if (name == t->name)
         {
           *p = t->next;
+	  if (weak_decls_tail == &t->next)
+	    weak_decls_tail = p;
           free (t);
         }
       else
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.869
diff -u -p -r1.869 decl.c
--- decl.c	2002/03/03 14:07:29	1.869
+++ decl.c	2002/03/07 02:44:58
@@ -4087,6 +4087,14 @@ pushdecl (x)
  		  || TREE_CODE (x) == TEMPLATE_DECL))
  	    SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
 
+	  /* Check for a function or var decl weakened by "#pragma weak".  */
+	  if ((TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
+	      && decl_pending_weak (x))
+	    {
+	      TREE_PUBLIC (name) = 1;
+	      DECL_WEAK (x) = 1;
+	    }
+
 	  /* Don't forget if the function was used via an implicit decl.  */
 	  if (IDENTIFIER_IMPLICIT_DECL (name)
 	      && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name)))


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