aboutsummaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-03-14 23:11:14 -0800
committerRichard Henderson <rth@gcc.gnu.org>2002-03-14 23:11:14 -0800
commitecb0eecefbd769b20dc9842fb0881db7492ec225 (patch)
treea4832f691fe7468c7db7811469b930a129616f84 /gcc/varasm.c
parent98d2b17e0c941e8e60055d10b36e2ceef522be92 (diff)
downloadgcc-ecb0eecefbd769b20dc9842fb0881db7492ec225.zip
gcc-ecb0eecefbd769b20dc9842fb0881db7492ec225.tar.gz
gcc-ecb0eecefbd769b20dc9842fb0881db7492ec225.tar.bz2
c-decl.c: Include c-pragma.h.
* c-decl.c: Include c-pragma.h. (start_decl, start_function): Invoke maybe_apply_pragma_weak. (finish_function): Tidy. * c-pragma.c: Include c-common.h. (pending_weaks, apply_pragma_weak, maybe_apply_pragma_weak): New. (handle_pragma_weak): Use them. (init_pragma): Register pending_weaks. * c-pragma.h (maybe_apply_pragma_weak): Declare. * print-tree.c (print_node): Print DECL_WEAK. * varasm.c (mark_weak_decls): Remove. (remove_from_pending_weak_list): Remove. (add_weak): Remove. (asm_emit_uninitialised): Call globalize_decl for weak commons. (weak_decls): Make a tree_list. (declare_weak): Cons weak_decls directly. (globalize_decl): Remove weak_decls elements directly. (weak_finish): Simplify weak_decls walk. Don't weaken unused symbols. Don't pretend to handle aliases. (init_varasm_once): Update weak_decls registry. * Makefile.in: Update dependencies. * cp/decl.c: Include c-pragma.h. (start_decl, start_function): Invoke maybe_apply_pragma_weak. * cp/Make-lang.in: Update dependencies. * gcc.dg/weak-1.c: New. From-SVN: r50797
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r--gcc/varasm.c145
1 files changed, 43 insertions, 102 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 5d41f63..06ee8b8 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -167,10 +167,6 @@ static unsigned HOST_WIDE_INT array_size_for_constructor PARAMS ((tree));
static unsigned min_align PARAMS ((unsigned, unsigned));
static void output_constructor PARAMS ((tree, HOST_WIDE_INT,
unsigned int));
-static void mark_weak_decls PARAMS ((void *));
-#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
-static void remove_from_pending_weak_list PARAMS ((const char *));
-#endif
static void globalize_decl PARAMS ((tree));
static void maybe_assemble_visibility PARAMS ((tree));
static int in_named_entry_eq PARAMS ((const PTR, const PTR));
@@ -1399,6 +1395,17 @@ asm_emit_uninitialised (decl, name, size, rounded)
destination = asm_dest_common;
}
+ switch (destination)
+ {
+ case asm_dest_common:
+ if (! DECL_WEAK (decl))
+ break;
+ case asm_dest_bss:
+ globalize_decl (decl);
+ default:
+ break;
+ }
+
if (flag_shared_data)
{
switch (destination)
@@ -1429,7 +1436,6 @@ asm_emit_uninitialised (decl, name, size, rounded)
{
#ifdef ASM_EMIT_BSS
case asm_dest_bss:
- globalize_decl (decl);
ASM_EMIT_BSS (decl, name, size, rounded);
break;
#endif
@@ -4994,55 +5000,9 @@ output_constructor (exp, size, align)
assemble_zeros (size - total_bytes);
}
-
-/* This structure contains any weak symbol declarations waiting
+/* This TREE_LIST contains any weak symbol declarations waiting
to be emitted. */
-struct weak_syms
-{
- struct weak_syms * next;
- tree decl;
- const char * name;
- const char * value;
-};
-
-static struct weak_syms * weak_decls;
-
-/* Mark weak_decls for garbage collection. */
-
-static void
-mark_weak_decls (arg)
- void *arg;
-{
- struct weak_syms *t;
-
- for (t = *(struct weak_syms **) arg; t != NULL; t = t->next)
- ggc_mark_tree (t->decl);
-}
-
-/* Add function NAME to the weak symbols list. VALUE is a weak alias
- associated with NAME. */
-
-int
-add_weak (decl, name, value)
- tree decl;
- const char *name;
- const char *value;
-{
- struct weak_syms *weak;
-
- weak = (struct weak_syms *) xmalloc (sizeof (struct weak_syms));
-
- if (weak == NULL)
- return 0;
-
- weak->next = weak_decls;
- weak->decl = decl;
- weak->name = name;
- weak->value = value;
- weak_decls = weak;
-
- return 1;
-}
+static tree weak_decls;
/* Declare DECL to be a weak symbol. */
@@ -5055,7 +5015,10 @@ declare_weak (decl)
else if (TREE_ASM_WRITTEN (decl))
error_with_decl (decl, "weak declaration of `%s' must precede definition");
else if (SUPPORTS_WEAK)
- add_weak (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), NULL);
+ {
+ if (! DECL_WEAK (decl))
+ weak_decls = tree_cons (NULL, decl, weak_decls);
+ }
else
warning_with_decl (decl, "weak declaration of `%s' not supported");
@@ -5067,59 +5030,30 @@ declare_weak (decl)
void
weak_finish ()
{
- if (SUPPORTS_WEAK)
+ tree t;
+
+ for (t = weak_decls; t ; t = TREE_CHAIN (t))
{
- struct weak_syms *t;
- for (t = weak_decls; t != NULL; t = t->next)
- {
+ tree decl = TREE_VALUE (t);
+ const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+ if (! TREE_USED (decl))
+ continue;
+
#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);
-#else
-#ifdef ASM_OUTPUT_WEAK_ALIAS
- ASM_OUTPUT_WEAK_ALIAS (asm_out_file, t->name, t->value);
+ ASM_WEAKEN_DECL (asm_out_file, decl, name, NULL);
#else
#ifdef ASM_WEAKEN_LABEL
- if (t->value)
- abort ();
- ASM_WEAKEN_LABEL (asm_out_file, t->name);
+ ASM_WEAKEN_LABEL (asm_out_file, name);
+#else
+#ifdef ASM_OUTPUT_WEAK_ALIAS
+ warning ("only weak aliases are supported in this configuration");
+ return;
#endif
#endif
#endif
- }
- }
-}
-
-/* Remove NAME from the pending list of weak symbols. This prevents
- the compiler from emitting multiple .weak directives which confuses
- some assemblers. */
-#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
-static void
-remove_from_pending_weak_list (name)
- const char *name;
-{
- struct weak_syms *t;
- struct weak_syms **p;
-
- for (p = &weak_decls; *p; )
- {
- t = *p;
- if (strcmp (name, t->name) == 0)
- {
- *p = t->next;
- free (t);
- }
- else
- p = &(t->next);
}
}
-#endif /* defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) */
/* Emit the assembly bits to indicate that DECL is globally visible. */
@@ -5132,18 +5066,26 @@ globalize_decl (decl)
#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
if (DECL_WEAK (decl))
{
+ tree *p, t;
+
#ifdef ASM_WEAKEN_DECL
ASM_WEAKEN_DECL (asm_out_file, decl, name, 0);
#else
ASM_WEAKEN_LABEL (asm_out_file, name);
#endif
+
/* Remove this function from the pending weak list so that
we do not emit multiple .weak directives for it. */
- remove_from_pending_weak_list (name);
+ for (p = &weak_decls; (t = *p) ; p = &TREE_CHAIN (t))
+ if (TREE_VALUE (t) == decl)
+ {
+ *p = TREE_CHAIN (t);
+ break;
+ }
return;
}
- /* else */
#endif
+
ASM_GLOBALIZE_LABEL (asm_out_file, name);
}
@@ -5168,7 +5110,6 @@ assemble_alias (decl, target)
if (TREE_PUBLIC (decl))
{
globalize_decl (decl);
-
maybe_assemble_visibility (decl);
}
@@ -5282,7 +5223,7 @@ init_varasm_once ()
mark_const_hash_entry);
ggc_add_root (&const_str_htab, 1, sizeof const_str_htab,
mark_const_str_htab);
- ggc_add_root (&weak_decls, 1, sizeof weak_decls, mark_weak_decls);
+ ggc_add_tree_root (&weak_decls, 1);
const_alias_set = new_alias_set ();
}