parent
822e3422fb
commit
4b8af8d984
|
@ -30,7 +30,7 @@ extern struct obstack permanent_obstack;
|
|||
|
||||
enum attrs {A_PACKED, A_NOCOMMON, A_NORETURN, A_CONST, A_T_UNION,
|
||||
A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
|
||||
A_FORMAT};
|
||||
A_FORMAT, A_WEAK, A_ALIAS};
|
||||
|
||||
static void declare_hidden_char_array PROTO((char *, char *));
|
||||
static void add_attribute PROTO((enum attrs, char *,
|
||||
|
@ -258,6 +258,8 @@ init_attributes ()
|
|||
add_attribute (A_SECTION, "section", 1, 1, 1);
|
||||
add_attribute (A_ALIGNED, "aligned", 0, 1, 0);
|
||||
add_attribute (A_FORMAT, "format", 3, 3, 1);
|
||||
add_attribute (A_WEAK, "weak", 0, 0, 1);
|
||||
add_attribute (A_ALIAS, "alias", 1, 1, 1);
|
||||
}
|
||||
|
||||
/* Process the attributes listed in ATTRIBUTES and PREFIX_ATTRIBUTES
|
||||
|
@ -606,6 +608,29 @@ decl_attributes (node, attributes, prefix_attributes)
|
|||
is_scan, format_num, first_arg_num);
|
||||
break;
|
||||
}
|
||||
|
||||
case A_WEAK:
|
||||
declare_weak (decl);
|
||||
break;
|
||||
|
||||
case A_ALIAS:
|
||||
if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
|
||||
|| TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl))
|
||||
error_with_decl (decl,
|
||||
"`%s' defined both normally and as an alias");
|
||||
else if (decl_function_context (decl) == 0)
|
||||
{
|
||||
tree id = get_identifier (TREE_STRING_POINTER
|
||||
(TREE_VALUE (args)));
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
DECL_INITIAL (decl) = error_mark_node;
|
||||
else
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
assemble_alias (decl, id);
|
||||
}
|
||||
else
|
||||
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,3 +85,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
fputc ('\n', FILE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* If we're using GNU as and ld, we support weak symbols. */
|
||||
|
||||
#define HANDLE_PRAGMA_WEAK flag_gnu_linker
|
||||
#define WEAK_ASM_OP ".weak"
|
||||
#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
|
||||
do { if (flag_gnu_linker) \
|
||||
{ \
|
||||
fprintf ((FILE), "\t%s\t", ".set"); \
|
||||
assemble_name (FILE, LABEL1); \
|
||||
fprintf (FILE, ","); \
|
||||
assemble_name (FILE, LABEL2); \
|
||||
fprintf (FILE, "\n"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
|
|
@ -20,3 +20,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
#define SUNOS4_SHARED_LIBRARIES 1
|
||||
|
||||
#include "sparc/sparc.h"
|
||||
|
||||
/* If we're using GNU as and ld, we support weak symbols. */
|
||||
|
||||
#define HANDLE_PRAGMA_WEAK flag_gnu_linker
|
||||
#define WEAK_ASM_OP ".weak"
|
||||
#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
|
||||
do { if (flag_gnu_linker) \
|
||||
{ \
|
||||
fprintf ((FILE), "\t%s\t", ".set"); \
|
||||
assemble_name (FILE, LABEL1); \
|
||||
fprintf (FILE, ","); \
|
||||
assemble_name (FILE, LABEL2); \
|
||||
fprintf (FILE, "\n"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
|
|
@ -2574,6 +2574,10 @@ compile_file (name)
|
|||
}
|
||||
}
|
||||
|
||||
/* Write out any pending weak symbol declarations. */
|
||||
|
||||
weak_finish ();
|
||||
|
||||
/* Do dbx symbols */
|
||||
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
|
||||
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
|
||||
|
|
94
gcc/varasm.c
94
gcc/varasm.c
|
@ -97,8 +97,13 @@ int size_directive_output;
|
|||
tree last_assemble_variable_decl;
|
||||
|
||||
/* Nonzero if at least one function definition has been seen. */
|
||||
|
||||
static int function_defined;
|
||||
|
||||
/* Any weak symbol declarations waiting to be emitted. */
|
||||
|
||||
static tree weak_decls;
|
||||
|
||||
struct addr_const;
|
||||
struct constant_descriptor;
|
||||
struct rtx_const;
|
||||
|
@ -3911,12 +3916,13 @@ output_constructor (exp, size)
|
|||
assemble_zeros (size - total_bytes);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HANDLE_SYSV_PRAGMA
|
||||
|
||||
/* Support #pragma weak by default if WEAK_ASM_OP and ASM_OUTPUT_DEF
|
||||
are defined. */
|
||||
#if defined (WEAK_ASM_OP) && defined (ASM_OUTPUT_DEF)
|
||||
#if !defined (HANDLE_PRAGMA_WEAK) && defined (WEAK_ASM_OP) && defined (ASM_OUTPUT_DEF)
|
||||
#define HANDLE_PRAGMA_WEAK 1
|
||||
#endif
|
||||
|
||||
#if defined (HANDLE_SYSV_PRAGMA) && defined (HANDLE_PRAGMA_WEAK)
|
||||
|
||||
/* See c-pragma.c for an identical definition. */
|
||||
enum pragma_state
|
||||
|
@ -3943,21 +3949,77 @@ handle_pragma_weak (what, asm_out_file, name, value)
|
|||
{
|
||||
if (what == ps_name || what == ps_value)
|
||||
{
|
||||
fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
|
||||
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_LABELREF (asm_out_file, name);
|
||||
else
|
||||
ASM_OUTPUT_LABELREF (asm_out_file, name);
|
||||
|
||||
fputc ('\n', asm_out_file);
|
||||
if (what == ps_value)
|
||||
ASM_OUTPUT_DEF (asm_out_file, name, value);
|
||||
weak_decls = perm_tree_cons (what == ps_value ? value : NULL_TREE,
|
||||
name, weak_decls);
|
||||
}
|
||||
else if (! (what == ps_done || what == ps_start))
|
||||
warning ("malformed `#pragma weak'");
|
||||
}
|
||||
|
||||
#endif /* HANDLE_PRAGMA_WEAK or (WEAK_ASM_OP and SET_ASM_OP) */
|
||||
#endif /* HANDLE_SYSV_PRAGMA && HANDLE_PRAGMA_WEAK */
|
||||
|
||||
#endif /* WEAK_ASM_OP && ASM_OUTPUT_DEF */
|
||||
/* Declare DECL to be a weak symbol. */
|
||||
|
||||
void
|
||||
declare_weak (decl)
|
||||
tree decl;
|
||||
{
|
||||
if (! TREE_PUBLIC (decl))
|
||||
error_with_decl (decl, "weak declaration of `%s' must be public");
|
||||
else
|
||||
weak_decls = perm_tree_cons (NULL_TREE, DECL_ASSEMBLER_NAME (decl),
|
||||
weak_decls);
|
||||
}
|
||||
|
||||
/* Emit any pending weak declarations. */
|
||||
|
||||
void
|
||||
weak_finish ()
|
||||
{
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
if (HANDLE_PRAGMA_WEAK)
|
||||
{
|
||||
tree t;
|
||||
for (t = weak_decls; t; t = TREE_CHAIN (t))
|
||||
{
|
||||
tree decl = TREE_VALUE (t);
|
||||
char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
|
||||
|
||||
fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
|
||||
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_LABELREF (asm_out_file, name);
|
||||
else
|
||||
ASM_OUTPUT_LABELREF (asm_out_file, name);
|
||||
|
||||
fputc ('\n', asm_out_file);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
assemble_alias (decl, target)
|
||||
tree decl, target;
|
||||
{
|
||||
#ifdef ASM_OUTPUT_DEF
|
||||
char *name;
|
||||
|
||||
make_decl_rtl (decl, (char*)0, 1);
|
||||
name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
|
||||
|
||||
/* Make name accessible from other files, if appropriate. */
|
||||
|
||||
if (TREE_PUBLIC (decl))
|
||||
{
|
||||
if (output_bytecode)
|
||||
BC_GLOBALIZE_LABEL (asm_out_file, name);
|
||||
else
|
||||
ASM_GLOBALIZE_LABEL (asm_out_file, name);
|
||||
}
|
||||
|
||||
ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
|
||||
#else
|
||||
warning ("alias definitions not supported in this configuration");
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue