diff options
author | Richard Henderson <rth@redhat.com> | 2002-03-14 23:11:14 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2002-03-14 23:11:14 -0800 |
commit | ecb0eecefbd769b20dc9842fb0881db7492ec225 (patch) | |
tree | a4832f691fe7468c7db7811469b930a129616f84 /gcc/varasm.c | |
parent | 98d2b17e0c941e8e60055d10b36e2ceef522be92 (diff) | |
download | gcc-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.c | 145 |
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 (); } |