diff options
author | Jason Merrill <merrill@gnu.org> | 1996-09-18 11:07:42 +0000 |
---|---|---|
committer | Jason Merrill <merrill@gnu.org> | 1996-09-18 11:07:42 +0000 |
commit | f796d997137a498b881ea786e9517bda7a2b4bea (patch) | |
tree | 598c02da5e00d23238635a9741dc5128d224569e /gcc/varasm.c | |
parent | 855609f33465ff7d4925d1e81f433b324b2793ac (diff) | |
download | gcc-f796d997137a498b881ea786e9517bda7a2b4bea.tar.gz |
(assemble_variable): Fix setting of first_global_object_name.
(assemble_variable): Fix setting of
first_global_object_name.
(assemble_start_function): Likewise.
(supports_one_only): New function.
(make_decl_one_only): Likewise.
From-SVN: r12734
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r-- | gcc/varasm.c | 76 |
1 files changed, 66 insertions, 10 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c index a2a17a989c1..d6a42507412 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -976,7 +976,8 @@ assemble_start_function (decl, fnname) if (TREE_PUBLIC (decl)) { - if (!first_global_object_name) + if (!first_global_object_name && ! DECL_WEAK (decl) + && ! DECL_ONE_ONLY (decl)) { char *p; @@ -1259,6 +1260,20 @@ assemble_variable (decl, top_level, at_end, dont_output_data) name = XSTR (XEXP (DECL_RTL (decl), 0), 0); + if (TREE_PUBLIC (decl) && DECL_NAME (decl) + && ! first_global_object_name + && ! (DECL_COMMON (decl) && (DECL_INITIAL (decl) == 0 + || DECL_INITIAL (decl) == error_mark_node)) + && ! DECL_WEAK (decl) + && ! DECL_ONE_ONLY (decl)) + { + char *p; + + STRIP_NAME_ENCODING (p, name); + first_global_object_name = permalloc (strlen (p) + 1); + strcpy (first_global_object_name, p); + } + /* Handle uninitialized definitions. */ if ((DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node) @@ -1387,15 +1402,6 @@ assemble_variable (decl, top_level, at_end, dont_output_data) /* First make the assembler name(s) global if appropriate. */ if (TREE_PUBLIC (decl) && DECL_NAME (decl)) { - if (!first_global_object_name) - { - char *p; - - STRIP_NAME_ENCODING (p, name); - first_global_object_name = permalloc (strlen (p) + 1); - strcpy (first_global_object_name, p); - } - #ifdef ASM_WEAKEN_LABEL if (DECL_WEAK (decl)) ASM_WEAKEN_LABEL (asm_out_file, name); @@ -4237,3 +4243,53 @@ assemble_alias (decl, target) warning ("alias definitions not supported in this configuration"); #endif } + +/* This determines whether or not we support link-once semantics. */ +#ifndef SUPPORTS_ONE_ONLY +#ifdef MAKE_DECL_ONE_ONLY +#define SUPPORTS_ONE_ONLY 1 +#else +#define SUPPORTS_ONE_ONLY 0 +#endif +#endif + +/* Returns 1 if the target configuration supports defining public symbols + so that one of them will be chosen at link time instead of generating a + multiply-defined symbol error, whether through the use of weak symbols or + a target-specific mechanism for having duplicates discarded. */ + +int +supports_one_only () +{ + if (SUPPORTS_ONE_ONLY) + return 1; + return SUPPORTS_WEAK; +} + +/* Set up DECL as a public symbol that can be defined in multiple + translation units without generating a linker error. */ + +void +make_decl_one_only (decl) + tree decl; +{ + if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) + abort (); + + TREE_PUBLIC (decl) = 1; + + if (TREE_CODE (decl) == VAR_DECL + && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node)) + DECL_COMMON (decl) = 1; + else if (SUPPORTS_ONE_ONLY) + { +#ifdef MAKE_DECL_ONE_ONLY + MAKE_DECL_ONE_ONLY (decl); +#endif + DECL_ONE_ONLY (decl) = 1; + } + else if (SUPPORTS_WEAK) + DECL_WEAK (decl) = 1; + else + abort (); +} |