Commit ecb0eece by Richard Henderson Committed by Richard Henderson

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
parent 98d2b17e
2002-03-14 Richard Henderson <rth@redhat.com> 2002-03-14 Richard Henderson <rth@redhat.com>
* 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.
2002-03-14 Richard Henderson <rth@redhat.com>
PR target/5312 PR target/5312
* config/ia64/ia64.c: Include tm_p.h last. * config/ia64/ia64.c: Include tm_p.h last.
(gen_nop_type): Remove duplicate definition. (gen_nop_type): Remove duplicate definition.
......
...@@ -1148,7 +1148,7 @@ $(srcdir)/c-parse.y: c-parse.in ...@@ -1148,7 +1148,7 @@ $(srcdir)/c-parse.y: c-parse.in
c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) $(C_TREE_H) \ c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) $(C_TREE_H) \
$(GGC_H) $(TARGET_H) c-lex.h flags.h function.h output.h $(EXPR_H) \ $(GGC_H) $(TARGET_H) c-lex.h flags.h function.h output.h $(EXPR_H) \
debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H) debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H) c-pragma.h
c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \ c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
$(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H) $(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H)
c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \ c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
...@@ -1165,7 +1165,7 @@ c-aux-info.o : c-aux-info.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \ ...@@ -1165,7 +1165,7 @@ c-aux-info.o : c-aux-info.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
flags.h toplev.h flags.h toplev.h
c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h toplev.h c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h toplev.h
c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) function.h \ c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) function.h \
c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) $(C_COMMON_H)
mbchar.o: mbchar.c $(CONFIG_H) $(SYSTEM_H) mbchar.h mbchar.o: mbchar.c $(CONFIG_H) $(SYSTEM_H) mbchar.h
graph.o: graph.c $(CONFIG_H) $(SYSTEM_H) toplev.h flags.h output.h $(RTL_H) \ graph.o: graph.c $(CONFIG_H) $(SYSTEM_H) toplev.h flags.h output.h $(RTL_H) \
function.h hard-reg-set.h $(BASIC_BLOCK_H) graph.h function.h hard-reg-set.h $(BASIC_BLOCK_H) graph.h
......
...@@ -46,6 +46,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -46,6 +46,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "debug.h" #include "debug.h"
#include "timevar.h" #include "timevar.h"
#include "c-common.h" #include "c-common.h"
#include "c-pragma.h"
/* In grokdeclarator, distinguish syntactic contexts of declarators. */ /* In grokdeclarator, distinguish syntactic contexts of declarators. */
enum decl_context enum decl_context
...@@ -3403,6 +3404,10 @@ start_decl (declarator, declspecs, initialized, attributes) ...@@ -3403,6 +3404,10 @@ start_decl (declarator, declspecs, initialized, attributes)
/* Set attributes here so if duplicate decl, will have proper attributes. */ /* Set attributes here so if duplicate decl, will have proper attributes. */
decl_attributes (&decl, attributes, 0); decl_attributes (&decl, attributes, 0);
/* If #pragma weak was used, mark the decl weak now. */
if (current_binding_level == global_binding_level)
maybe_apply_pragma_weak (decl);
if (TREE_CODE (decl) == FUNCTION_DECL if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl) && DECL_DECLARED_INLINE_P (decl)
&& DECL_UNINLINABLE (decl) && DECL_UNINLINABLE (decl)
...@@ -6042,6 +6047,10 @@ start_function (declspecs, declarator, attributes) ...@@ -6042,6 +6047,10 @@ start_function (declspecs, declarator, attributes)
decl_attributes (&decl1, attributes, 0); decl_attributes (&decl1, attributes, 0);
/* If #pragma weak was used, mark the decl weak now. */
if (current_binding_level == global_binding_level)
maybe_apply_pragma_weak (decl1);
if (DECL_DECLARED_INLINE_P (decl1) if (DECL_DECLARED_INLINE_P (decl1)
&& DECL_UNINLINABLE (decl1) && DECL_UNINLINABLE (decl1)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1))) && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
...@@ -6691,9 +6700,11 @@ finish_function (nested) ...@@ -6691,9 +6700,11 @@ finish_function (nested)
{ {
tree fndecl = current_function_decl; tree fndecl = current_function_decl;
/* TREE_READONLY (fndecl) = 1; #if 0
This caused &foo to be of type ptr-to-const-function /* This caused &foo to be of type ptr-to-const-function which then
which then got a warning when stored in a ptr-to-function variable. */ got a warning when stored in a ptr-to-function variable. */
TREE_READONLY (fndecl) = 1;
#endif
poplevel (1, 0, 1); poplevel (1, 0, 1);
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
...@@ -6755,6 +6766,7 @@ finish_function (nested) ...@@ -6755,6 +6766,7 @@ finish_function (nested)
{ {
/* Generate RTL for the body of this function. */ /* Generate RTL for the body of this function. */
c_expand_body (fndecl, nested, 1); c_expand_body (fndecl, nested, 1);
/* Let the error reporting routines know that we're outside a /* Let the error reporting routines know that we're outside a
function. For a nested function, this value is used in function. For a nested function, this value is used in
pop_c_function_context and then reset via pop_function_context. */ pop_c_function_context and then reset via pop_function_context. */
......
...@@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h" #include "toplev.h"
#include "ggc.h" #include "ggc.h"
#include "c-lex.h" #include "c-lex.h"
#include "c-common.h"
#include "output.h" #include "output.h"
#include "tm_p.h" #include "tm_p.h"
...@@ -55,9 +56,9 @@ static struct align_stack * alignment_stack = NULL; ...@@ -55,9 +56,9 @@ static struct align_stack * alignment_stack = NULL;
maximum_field_alignment in effect. When the final pop_alignment() maximum_field_alignment in effect. When the final pop_alignment()
happens, we restore the value to this, not to a value of 0 for happens, we restore the value to this, not to a value of 0 for
maximum_field_alignment. Value is in bits. */ maximum_field_alignment. Value is in bits. */
static int default_alignment; static int default_alignment;
#define SET_GLOBAL_ALIGNMENT(ALIGN) \ #define SET_GLOBAL_ALIGNMENT(ALIGN) \
(default_alignment = maximum_field_alignment = (ALIGN)) (default_alignment = maximum_field_alignment = (ALIGN))
static void push_alignment PARAMS ((int, tree)); static void push_alignment PARAMS ((int, tree));
static void pop_alignment PARAMS ((tree)); static void pop_alignment PARAMS ((tree));
...@@ -69,7 +70,6 @@ push_alignment (alignment, id) ...@@ -69,7 +70,6 @@ push_alignment (alignment, id)
int alignment; int alignment;
tree id; tree id;
{ {
if (alignment_stack == NULL if (alignment_stack == NULL
|| alignment_stack->alignment != alignment || alignment_stack->alignment != alignment
|| id != NULL_TREE) || id != NULL_TREE)
...@@ -274,14 +274,53 @@ handle_pragma_pack (dummy) ...@@ -274,14 +274,53 @@ handle_pragma_pack (dummy)
#endif /* HANDLE_PRAGMA_PACK */ #endif /* HANDLE_PRAGMA_PACK */
#ifdef HANDLE_PRAGMA_WEAK #ifdef HANDLE_PRAGMA_WEAK
static void apply_pragma_weak PARAMS ((tree, tree));
static void handle_pragma_weak PARAMS ((cpp_reader *)); static void handle_pragma_weak PARAMS ((cpp_reader *));
static tree pending_weaks;
static void
apply_pragma_weak (decl, value)
tree decl, value;
{
if (value)
decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
build_tree_list (NULL, value)),
0);
declare_weak (decl);
}
void
maybe_apply_pragma_weak (decl)
tree decl;
{
tree *p, t, id;
/* Copied from the check in set_decl_assembler_name. */
if (TREE_CODE (decl) == FUNCTION_DECL
|| (TREE_CODE (decl) == VAR_DECL
&& (TREE_STATIC (decl)
|| DECL_EXTERNAL (decl)
|| TREE_PUBLIC (decl))))
id = DECL_ASSEMBLER_NAME (decl);
else
return;
for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t))
if (id == TREE_PURPOSE (t))
{
apply_pragma_weak (decl, TREE_VALUE (t));
*p = TREE_CHAIN (t);
break;
}
}
/* #pragma weak name [= value] */ /* #pragma weak name [= value] */
static void static void
handle_pragma_weak (dummy) handle_pragma_weak (dummy)
cpp_reader *dummy ATTRIBUTE_UNUSED; cpp_reader *dummy ATTRIBUTE_UNUSED;
{ {
tree name, value, x; tree name, value, x, decl;
enum cpp_ttype t; enum cpp_ttype t;
value = 0; value = 0;
...@@ -298,10 +337,19 @@ handle_pragma_weak (dummy) ...@@ -298,10 +337,19 @@ handle_pragma_weak (dummy)
if (t != CPP_EOF) if (t != CPP_EOF)
warning ("junk at end of #pragma weak"); warning ("junk at end of #pragma weak");
add_weak (NULL_TREE, IDENTIFIER_POINTER (name), decl = identifier_global_value (name);
value ? IDENTIFIER_POINTER (value) : NULL); if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
apply_pragma_weak (decl, value);
else
pending_weaks = tree_cons (name, value, pending_weaks);
} }
#endif #else
void
maybe_apply_pragma_weak (decl)
tree decl ATTRIBUTE_UNUSED;
{
}
#endif /* HANDLE_PRAGMA_WEAK */
void void
init_pragma () init_pragma ()
...@@ -311,6 +359,7 @@ init_pragma () ...@@ -311,6 +359,7 @@ init_pragma ()
#endif #endif
#ifdef HANDLE_PRAGMA_WEAK #ifdef HANDLE_PRAGMA_WEAK
cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak); cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
ggc_add_tree_root (&pending_weaks, 1);
#endif #endif
#ifdef REGISTER_TARGET_PRAGMAS #ifdef REGISTER_TARGET_PRAGMAS
REGISTER_TARGET_PRAGMAS (parse_in); REGISTER_TARGET_PRAGMAS (parse_in);
......
...@@ -53,4 +53,6 @@ extern void cpp_register_pragma PARAMS ((cpp_reader *, ...@@ -53,4 +53,6 @@ extern void cpp_register_pragma PARAMS ((cpp_reader *,
void (*) PARAMS ((cpp_reader *)))); void (*) PARAMS ((cpp_reader *))));
#endif #endif
extern void maybe_apply_pragma_weak PARAMS ((tree));
#endif /* GCC_C_PRAGMA_H */ #endif /* GCC_C_PRAGMA_H */
2002-03-14 Richard Henderson <rth@redhat.com>
* decl.c: Include c-pragma.h.
(start_decl, start_function): Invoke maybe_apply_pragma_weak.
* Make-lang.in: Update dependencies.
2002-03-14 Jakub Jelinek <jakub@redhat.com> 2002-03-14 Jakub Jelinek <jakub@redhat.com>
PR c++/5908 PR c++/5908
......
...@@ -255,7 +255,7 @@ cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h langhooks-def.h \ ...@@ -255,7 +255,7 @@ cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h langhooks-def.h \
c-common.h c-common.h
cp/decl.o: cp/decl.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h stack.h \ cp/decl.o: cp/decl.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h stack.h \
output.h $(EXPR_H) except.h toplev.h hash.h $(GGC_H) $(RTL_H) \ output.h $(EXPR_H) except.h toplev.h hash.h $(GGC_H) $(RTL_H) \
cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h
cp/decl2.o: cp/decl2.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \ cp/decl2.o: cp/decl2.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \
output.h except.h toplev.h $(GGC_H) $(RTL_H) output.h except.h toplev.h $(GGC_H) $(RTL_H)
cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) flags.h toplev.h output.h $(TM_P_H) \ cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) flags.h toplev.h output.h $(TM_P_H) \
......
...@@ -46,6 +46,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -46,6 +46,7 @@ Boston, MA 02111-1307, USA. */
#include "tm_p.h" #include "tm_p.h"
#include "target.h" #include "target.h"
#include "c-common.h" #include "c-common.h"
#include "c-pragma.h"
#include "diagnostic.h" #include "diagnostic.h"
extern const struct attribute_spec *lang_attribute_table; extern const struct attribute_spec *lang_attribute_table;
...@@ -7256,6 +7257,10 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) ...@@ -7256,6 +7257,10 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
/* Set attributes here so if duplicate decl, will have proper attributes. */ /* Set attributes here so if duplicate decl, will have proper attributes. */
cplus_decl_attributes (&decl, attributes, 0); cplus_decl_attributes (&decl, attributes, 0);
/* If #pragma weak was used, mark the decl weak now. */
if (current_binding_level == global_binding_level)
maybe_apply_pragma_weak (decl);
if (TREE_CODE (decl) == FUNCTION_DECL if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl) && DECL_DECLARED_INLINE_P (decl)
&& DECL_UNINLINABLE (decl) && DECL_UNINLINABLE (decl)
...@@ -13476,6 +13481,10 @@ start_function (declspecs, declarator, attrs, flags) ...@@ -13476,6 +13481,10 @@ start_function (declspecs, declarator, attrs, flags)
cplus_decl_attributes (&decl1, attrs, 0); cplus_decl_attributes (&decl1, attrs, 0);
/* If #pragma weak was used, mark the decl weak now. */
if (current_binding_level == global_binding_level)
maybe_apply_pragma_weak (decl1);
fntype = TREE_TYPE (decl1); fntype = TREE_TYPE (decl1);
restype = TREE_TYPE (fntype); restype = TREE_TYPE (fntype);
......
...@@ -317,6 +317,8 @@ print_node (file, prefix, node, indent) ...@@ -317,6 +317,8 @@ print_node (file, prefix, node, indent)
fputs (" common", file); fputs (" common", file);
if (DECL_EXTERNAL (node)) if (DECL_EXTERNAL (node))
fputs (" external", file); fputs (" external", file);
if (DECL_WEAK (node))
fputs (" weak", file);
if (DECL_REGISTER (node) && TREE_CODE (node) != FIELD_DECL if (DECL_REGISTER (node) && TREE_CODE (node) != FIELD_DECL
&& TREE_CODE (node) != FUNCTION_DECL && TREE_CODE (node) != FUNCTION_DECL
&& TREE_CODE (node) != LABEL_DECL) && TREE_CODE (node) != LABEL_DECL)
......
/* { dg-do compile } */
/* COFF does not support weak, and dg doesn't support UNSUPPORTED. */
/* { dg-do compile { xfail *-*-coff i?86-pc-cygwin } } */
/* { dg-final { scan-assembler "weak[^ ]*[ ]_?a" } } */
/* { dg-final { scan-assembler "weak[^ ]*[ ]_?b" } } */
/* { dg-final { scan-assembler "weak[^ ]*[ ]_?c" } } */
/* { dg-final { scan-assembler "weak[^ ]*[ ]_?d" } } */
/* { dg-final { scan-assembler "weak[^ ]*[ ]_?e" } } */
/* { dg-final { scan-assembler "weak[^ ]*[ ]_?g" } } */
/* { dg-final { scan-assembler-not "weak[^ ]*[ ]_?i" } } */
/* { dg-final { scan-assembler "weak[^ ]*[ ]_?j" } } */
#pragma weak a
int a;
int b;
#pragma weak b
#pragma weak c
extern int c;
int c;
extern int d;
#pragma weak d
int d;
#pragma weak e
void e(void) { }
#if 0
/* This permutation is illegal. */
void f(void) { }
#pragma weak f
#endif
#pragma weak g
int g = 1;
#if 0
/* This permutation is illegal. */
int h = 1;
#pragma weak h
#endif
#pragma weak i
extern int i;
#pragma weak j
extern int j;
int use_j() { return j; }
...@@ -167,10 +167,6 @@ static unsigned HOST_WIDE_INT array_size_for_constructor PARAMS ((tree)); ...@@ -167,10 +167,6 @@ static unsigned HOST_WIDE_INT array_size_for_constructor PARAMS ((tree));
static unsigned min_align PARAMS ((unsigned, unsigned)); static unsigned min_align PARAMS ((unsigned, unsigned));
static void output_constructor PARAMS ((tree, HOST_WIDE_INT, static void output_constructor PARAMS ((tree, HOST_WIDE_INT,
unsigned 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 globalize_decl PARAMS ((tree));
static void maybe_assemble_visibility PARAMS ((tree)); static void maybe_assemble_visibility PARAMS ((tree));
static int in_named_entry_eq PARAMS ((const PTR, const PTR)); static int in_named_entry_eq PARAMS ((const PTR, const PTR));
...@@ -1399,6 +1395,17 @@ asm_emit_uninitialised (decl, name, size, rounded) ...@@ -1399,6 +1395,17 @@ asm_emit_uninitialised (decl, name, size, rounded)
destination = asm_dest_common; 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) if (flag_shared_data)
{ {
switch (destination) switch (destination)
...@@ -1429,7 +1436,6 @@ asm_emit_uninitialised (decl, name, size, rounded) ...@@ -1429,7 +1436,6 @@ asm_emit_uninitialised (decl, name, size, rounded)
{ {
#ifdef ASM_EMIT_BSS #ifdef ASM_EMIT_BSS
case asm_dest_bss: case asm_dest_bss:
globalize_decl (decl);
ASM_EMIT_BSS (decl, name, size, rounded); ASM_EMIT_BSS (decl, name, size, rounded);
break; break;
#endif #endif
...@@ -4994,55 +5000,9 @@ output_constructor (exp, size, align) ...@@ -4994,55 +5000,9 @@ output_constructor (exp, size, align)
assemble_zeros (size - total_bytes); assemble_zeros (size - total_bytes);
} }
/* This TREE_LIST contains any weak symbol declarations waiting
/* This structure contains any weak symbol declarations waiting
to be emitted. */ to be emitted. */
struct weak_syms static tree weak_decls;
{
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;
}
/* Declare DECL to be a weak symbol. */ /* Declare DECL to be a weak symbol. */
...@@ -5055,7 +5015,10 @@ declare_weak (decl) ...@@ -5055,7 +5015,10 @@ declare_weak (decl)
else if (TREE_ASM_WRITTEN (decl)) else if (TREE_ASM_WRITTEN (decl))
error_with_decl (decl, "weak declaration of `%s' must precede definition"); error_with_decl (decl, "weak declaration of `%s' must precede definition");
else if (SUPPORTS_WEAK) 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 else
warning_with_decl (decl, "weak declaration of `%s' not supported"); warning_with_decl (decl, "weak declaration of `%s' not supported");
...@@ -5067,59 +5030,30 @@ declare_weak (decl) ...@@ -5067,59 +5030,30 @@ declare_weak (decl)
void void
weak_finish () weak_finish ()
{ {
if (SUPPORTS_WEAK) tree t;
for (t = weak_decls; t ; t = TREE_CHAIN (t))
{ {
struct weak_syms *t; tree decl = TREE_VALUE (t);
for (t = weak_decls; t != NULL; t = t->next) const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
{
if (! TREE_USED (decl))
continue;
#ifdef ASM_WEAKEN_DECL #ifdef ASM_WEAKEN_DECL
tree decl = t->decl; ASM_WEAKEN_DECL (asm_out_file, decl, name, NULL);
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);
#else #else
#ifdef ASM_WEAKEN_LABEL #ifdef ASM_WEAKEN_LABEL
if (t->value) ASM_WEAKEN_LABEL (asm_out_file, name);
abort (); #else
ASM_WEAKEN_LABEL (asm_out_file, t->name); #ifdef ASM_OUTPUT_WEAK_ALIAS
warning ("only weak aliases are supported in this configuration");
return;
#endif #endif
#endif #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. */ /* Emit the assembly bits to indicate that DECL is globally visible. */
...@@ -5132,18 +5066,26 @@ globalize_decl (decl) ...@@ -5132,18 +5066,26 @@ globalize_decl (decl)
#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) #if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
if (DECL_WEAK (decl)) if (DECL_WEAK (decl))
{ {
tree *p, t;
#ifdef ASM_WEAKEN_DECL #ifdef ASM_WEAKEN_DECL
ASM_WEAKEN_DECL (asm_out_file, decl, name, 0); ASM_WEAKEN_DECL (asm_out_file, decl, name, 0);
#else #else
ASM_WEAKEN_LABEL (asm_out_file, name); ASM_WEAKEN_LABEL (asm_out_file, name);
#endif #endif
/* Remove this function from the pending weak list so that /* Remove this function from the pending weak list so that
we do not emit multiple .weak directives for it. */ 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; return;
} }
/* else */
#endif #endif
ASM_GLOBALIZE_LABEL (asm_out_file, name); ASM_GLOBALIZE_LABEL (asm_out_file, name);
} }
...@@ -5168,7 +5110,6 @@ assemble_alias (decl, target) ...@@ -5168,7 +5110,6 @@ assemble_alias (decl, target)
if (TREE_PUBLIC (decl)) if (TREE_PUBLIC (decl))
{ {
globalize_decl (decl); globalize_decl (decl);
maybe_assemble_visibility (decl); maybe_assemble_visibility (decl);
} }
...@@ -5282,7 +5223,7 @@ init_varasm_once () ...@@ -5282,7 +5223,7 @@ init_varasm_once ()
mark_const_hash_entry); mark_const_hash_entry);
ggc_add_root (&const_str_htab, 1, sizeof const_str_htab, ggc_add_root (&const_str_htab, 1, sizeof const_str_htab,
mark_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 (); const_alias_set = new_alias_set ();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment