+2002-03-01 Alan Modra <amodra@bigpond.net.au>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * doc/tm.texi (ASM_WEAKEN_DECL): Document.
+ (ASM_WEAKEN_LABEL): Mention ASM_WEAKEN_DECL.
+ (SUPPORTS_WEAK): Likewise.
+ * output.h (add_weak): Add tree param.
+ * varasm.c (add_weak): Likewise. Save decl.
+ (struct weak_syms): Add decl field.
+ (mark_weak_decls): New function.
+ (init_varasm_once): ggc_add_root mark_weak_decls.
+ (assemble_start_function): Use ASM_WEAKEN_DECL.
+ (assemble_variable): Likewise.
+ (assemble_alias): Likewise.
+ (declare_weak): Pass decl to add_weak.
+ (weak_finish): Use ASM_WEAKEN_DECL. Try to find decl.
+ (remove_from_pending_weak_list): Declare and define for
+ ASM_WEAKEN_DECL.
+ * c-pragma.c (handle_pragma_weak): Adjust add_weak call.
+ * c-pragma.h (HANDLE_PRAGMA_WEAK): Define if ASM_WEAKEN_DECL too.
+ * defaults.h (SUPPORTS_WEAK): Likewise.
+ * config/rs6000/linux64.h (ASM_DECLARE_FUNCTION_NAME): Don't emit
+ .weak for code sym. Do emit .size for descriptor sym.
+ (ASM_DECLARE_FUNCTION_SIZE): Define.
+ * config/rs6000/rs6000.h (ASM_WEAKEN_DECL): Define.
+ (ASM_OUTPUT_DEF_FROM_DECLS): Don't emit .weak here. Don't output
+ .lglobl unless TARGET_XCOFF. Formatting fixes.
+ * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Don't emit
+ .weak for code sym.
+ (HANDLE_PRAGMA_WEAK): Remove.
+ (ASM_WEAKEN_LABEL): Remove.
+ * config/rs6000/aix.h (HANDLE_SYSV_PRAGMA): Define.
+
2002-03-01 Jason Merrill <jason@redhat.com>
* tree.h (TARGET_EXPR_SLOT, TARGET_EXPR_INITIAL): New macros.
/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
- Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
This file is part of GCC.
if (t != CPP_EOF)
warning ("junk at end of #pragma weak");
- add_weak (IDENTIFIER_POINTER (name), value ? IDENTIFIER_POINTER (value) : 0);
+ add_weak (NULL_TREE, IDENTIFIER_POINTER (name),
+ value ? IDENTIFIER_POINTER (value) : NULL);
}
#endif
#define GCC_C_PRAGMA_H
#ifdef HANDLE_SYSV_PRAGMA
-/* Support #pragma weak iff ASM_WEAKEN_LABEL and ASM_OUTPUT_WEAK_ALIAS are
- defined. */
-#if defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_WEAK_ALIAS)
+#if ((defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_WEAK_ALIAS)) \
+ || defined (ASM_WEAKEN_DECL))
#define HANDLE_PRAGMA_WEAK SUPPORTS_WEAK
#endif
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU CC.
collect has a chance to see them, so scan the object files directly. */
#define COLLECT_EXPORT_LIST
+/* Handle #pragma weak and #pragma pack. */
+#define HANDLE_SYSV_PRAGMA
+
/* This is the only version of nm that collect2 can work with. */
#define REAL_NM_FILE_NAME "/usr/ucb/nm"
/* Definitions of target machine for GNU compiler,
for 64 bit powerpc linux.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU CC.
fputs (DOUBLE_INT_ASM_OP, (FILE)); \
putc ('.', (FILE)); \
assemble_name ((FILE), (NAME)); \
- putc ('\n', (FILE)); \
- fputs (DOUBLE_INT_ASM_OP, (FILE)); \
- fputs (".TOC.@tocbase, 0\n\t.previous\n", (FILE)); \
- \
- if (TREE_PUBLIC (DECL)) \
+ fputs (",.TOC.@tocbase,0\n\t.previous\n\t.size\t", (FILE)); \
+ assemble_name ((FILE), (NAME)); \
+ fputs (",24\n\t.type\t.", (FILE)); \
+ assemble_name ((FILE), (NAME)); \
+ fputs (",@function\n", (FILE)); \
+ if (TREE_PUBLIC (DECL) && ! DECL_WEAK (DECL)) \
{ \
- if (DECL_WEAK (DECL)) \
- fputs ("\t.weak\t", (FILE)); \
- else \
- fputs ("\t.globl\t", (FILE)); \
- putc ('.', (FILE)); \
+ fputs ("\t.globl\t.", (FILE)); \
assemble_name ((FILE), (NAME)); \
putc ('\n', (FILE)); \
} \
- fputs (TYPE_ASM_OP, (FILE)); \
- putc ('.', (FILE)); \
- assemble_name ((FILE), (NAME)); \
- putc (',', (FILE)); \
- fprintf ((FILE), TYPE_OPERAND_FMT, "function"); \
- putc ('\n', (FILE)); \
ASM_DECLARE_RESULT ((FILE), DECL_RESULT (DECL)); \
putc ('.', (FILE)); \
ASM_OUTPUT_LABEL ((FILE), (NAME)); \
} \
while (0)
+/* This is how to declare the size of a function. */
+#undef ASM_DECLARE_FUNCTION_SIZE
+#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
+ do \
+ { \
+ if (!flag_inhibit_size_directive) \
+ { \
+ fputs ("\t.size\t.", (FILE)); \
+ assemble_name ((FILE), (FNAME)); \
+ fputs (",.-.", (FILE)); \
+ assemble_name ((FILE), (FNAME)); \
+ putc ('\n', (FILE)); \
+ } \
+ } \
+ while (0)
+
/* Return non-zero if this entry is to be written into the constant
pool in a special way. We do so if this is a SYMBOL_REF, LABEL_REF
or a CONST containing one of them. If -mfp-in-toc (the default),
#define RS6000_WEAK 0
#endif
-/* This implementes the `alias' attribute. */
-#define ASM_OUTPUT_DEF_FROM_DECLS(FILE,decl,target) \
-do { \
- const char * alias = XSTR (XEXP (DECL_RTL (decl), 0), 0); \
- const char * name = IDENTIFIER_POINTER (target); \
- if (TREE_CODE (decl) == FUNCTION_DECL \
- && DEFAULT_ABI == ABI_AIX) \
- { \
- if (TREE_PUBLIC (decl)) \
- { \
- if (RS6000_WEAK && DECL_WEAK (decl)) \
- { \
- fputs ("\t.weak .", FILE); \
- assemble_name (FILE, alias); \
- putc ('\n', FILE); \
- } \
- else \
- { \
- fputs ("\t.globl .", FILE); \
- assemble_name (FILE, alias); \
- putc ('\n', FILE); \
- } \
- } \
- else \
- { \
- fputs ("\t.lglobl .", FILE); \
- assemble_name (FILE, alias); \
- putc ('\n', FILE); \
- } \
- fputs ("\t.set .", FILE); \
- assemble_name (FILE, alias); \
- fputs (",.", FILE); \
- assemble_name (FILE, name); \
- fputc ('\n', FILE); \
- } \
- ASM_OUTPUT_DEF (FILE, alias, name); \
-} while (0)
+#if RS6000_WEAK
+/* Used in lieu of ASM_WEAKEN_LABEL. */
+#define ASM_WEAKEN_DECL(FILE, DECL, NAME, VAL) \
+ do \
+ { \
+ fputs ("\t.weak\t", (FILE)); \
+ assemble_name ((FILE), (NAME)); \
+ if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \
+ && DEFAULT_ABI == ABI_AIX) \
+ { \
+ fputs (",.", (FILE)); \
+ assemble_name ((FILE), (NAME)); \
+ } \
+ fputc ('\n', (FILE)); \
+ if (VAL) \
+ { \
+ ASM_OUTPUT_DEF ((FILE), (NAME), (VAL)); \
+ if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \
+ && DEFAULT_ABI == ABI_AIX) \
+ { \
+ fputs ("\t.set\t.", (FILE)); \
+ assemble_name ((FILE), (NAME)); \
+ fputs (",.", (FILE)); \
+ assemble_name ((FILE), (VAL)); \
+ fputc ('\n', (FILE)); \
+ } \
+ } \
+ } \
+ while (0)
+#endif
+
+/* This implements the `alias' attribute. */
+#undef ASM_OUTPUT_DEF_FROM_DECLS
+#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET) \
+ do \
+ { \
+ const char *alias = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
+ const char *name = IDENTIFIER_POINTER (TARGET); \
+ if (TREE_CODE (DECL) == FUNCTION_DECL \
+ && DEFAULT_ABI == ABI_AIX) \
+ { \
+ if (TREE_PUBLIC (DECL)) \
+ { \
+ if (!RS6000_WEAK || !DECL_WEAK (DECL)) \
+ { \
+ fputs ("\t.globl\t.", FILE); \
+ assemble_name (FILE, alias); \
+ putc ('\n', FILE); \
+ } \
+ } \
+ else if (TARGET_XCOFF) \
+ { \
+ fputs ("\t.lglobl\t.", FILE); \
+ assemble_name (FILE, alias); \
+ putc ('\n', FILE); \
+ } \
+ fputs ("\t.set\t.", FILE); \
+ assemble_name (FILE, alias); \
+ fputs (",.", FILE); \
+ assemble_name (FILE, name); \
+ fputc ('\n', FILE); \
+ } \
+ ASM_OUTPUT_DEF (FILE, alias, name); \
+ } \
+ while (0)
/* Output to assembler file text saying following lines
may contain character constants, extra white space, comments, etc. */
/* Definitions of target machine for GNU compiler,
for some generic XCOFF file format
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU CC.
SYMBOL_REF_FLAG (sym_ref) = 1; \
if (TREE_PUBLIC (DECL)) \
{ \
- if (RS6000_WEAK && DECL_WEAK (decl)) \
- { \
- fputs ("\t.weak .", FILE); \
- RS6000_OUTPUT_BASENAME (FILE, NAME); \
- putc ('\n', FILE); \
- } \
- else \
+ if (!RS6000_WEAK || !DECL_WEAK (decl)) \
{ \
fputs ("\t.globl .", FILE); \
RS6000_OUTPUT_BASENAME (FILE, NAME); \
xcoff_bss_section_name); \
} while (0)
-/* Output a weak symbol, if weak support present. */
-#ifdef HAVE_GAS_WEAK
-#define HANDLE_PRAGMA_WEAK 1
-
-#define ASM_WEAKEN_LABEL(FILE, NAME) \
- do \
- { \
- fputs ("\t.weak ", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputc ('\n', (FILE)); \
- } \
- while (0)
-#endif /* HAVE_GAS_WEAK */
-
/* This is how we tell the assembler that two symbols have the same value. */
#define SET_ASM_OP "\t.set "
/* Definitions of various defaults for tm.h macros.
- Copyright (C) 1992, 1996, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1992, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com)
/* This determines whether or not we support weak symbols. */
#ifndef SUPPORTS_WEAK
-#ifdef ASM_WEAKEN_LABEL
+#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
#define SUPPORTS_WEAK 1
#else
#define SUPPORTS_WEAK 0
for making that name global, and a newline.
@findex ASM_WEAKEN_LABEL
-@item ASM_WEAKEN_LABEL
+@item ASM_WEAKEN_LABEL (@var{stream}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} some commands that will make the label @var{name} weak;
that is, available for reference from other files but only used if
itself; before and after that, output the additional assembler syntax
for making that name weak, and a newline.
-If you don't define this macro, GCC will not support weak
-symbols and you should not define the @code{SUPPORTS_WEAK} macro.
+If you don't define this macro or @code{ASM_WEAKEN_DECL}, GCC will not
+support weak symbols and you should not define the @code{SUPPORTS_WEAK}
+macro.
+
+@findex ASM_WEAKEN_DECL
+@item ASM_WEAKEN_DECL (@var{stream}, @var{decl}, @var{name}, @var{value})
+Combines (and replaces) the function of @code{ASM_WEAKEN_LABEL} and
+@code{ASM_OUTPUT_WEAK_ALIAS}, allowing access to the associated function
+or variable decl. If @var{value} is not @code{NULL}, this C statement
+should output to the stdio stream @var{stream} assembler code which
+defines (equates) the weak symbol @var{name} to have the value
+@var{value}. If @var{value} is @code{NULL}, it should output commands
+to make @var{name} weak.
@findex SUPPORTS_WEAK
@item SUPPORTS_WEAK
A C expression which evaluates to true if the target supports weak symbols.
If you don't define this macro, @file{defaults.h} provides a default
-definition. If @code{ASM_WEAKEN_LABEL} is defined, the default
-definition is @samp{1}; otherwise, it is @samp{0}. Define this macro if
-you want to control weak symbol support with a compiler flag such as
-@option{-melf}.
+definition. If either @code{ASM_WEAKEN_LABEL} or @code{ASM_WEAKEN_DECL}
+is defined, the default definition is @samp{1}; otherwise, it is
+@samp{0}. Define this macro if you want to control weak symbol support
+with a compiler flag such as @option{-melf}.
@findex MAKE_DECL_ONE_ONLY (@var{decl})
@item MAKE_DECL_ONE_ONLY
/* Add function NAME to the weak symbols list. VALUE is a weak alias
associated with NAME. */
-extern int add_weak PARAMS ((const char *, const char *));
+extern int add_weak PARAMS ((tree, const char *, const char *));
/* Functions in flow.c */
extern void allocate_for_life_analysis PARAMS ((void));
#include "obstack.h"
#include "hashtab.h"
#include "c-pragma.h"
+#include "c-tree.h"
#include "ggc.h"
#include "langhooks.h"
#include "tm_p.h"
static unsigned min_align PARAMS ((unsigned, unsigned));
static void output_constructor PARAMS ((tree, HOST_WIDE_INT,
unsigned int));
-#ifdef ASM_WEAKEN_LABEL
+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 int in_named_entry_eq PARAMS ((const PTR, const PTR));
weak_global_object_name = name;
}
-#ifdef ASM_WEAKEN_LABEL
+#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
if (DECL_WEAK (decl))
{
+#ifdef ASM_WEAKEN_DECL
+ ASM_WEAKEN_DECL (asm_out_file, decl, fnname, 0);
+#else
ASM_WEAKEN_LABEL (asm_out_file, fnname);
+#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
/* First make the assembler name(s) global if appropriate. */
if (TREE_PUBLIC (decl) && DECL_NAME (decl))
{
-#ifdef ASM_WEAKEN_LABEL
+#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
if (DECL_WEAK (decl))
{
+#ifdef ASM_WEAKEN_DECL
+ ASM_WEAKEN_DECL (asm_out_file, decl, name, 0);
+#else
ASM_WEAKEN_LABEL (asm_out_file, name);
+#endif
/* Remove this variable from the pending weak list so that
we do not emit multiple .weak directives for it. */
remove_from_pending_weak_list
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 (name, value)
+add_weak (decl, name, value)
+ tree decl;
const char *name;
const char *value;
{
return 0;
weak->next = weak_decls;
+ weak->decl = decl;
weak->name = name;
weak->value = value;
weak_decls = weak;
else if (TREE_ASM_WRITTEN (decl))
error_with_decl (decl, "weak declaration of `%s' must precede definition");
else if (SUPPORTS_WEAK)
- add_weak (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), NULL);
+ add_weak (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), NULL);
else
warning_with_decl (decl, "weak declaration of `%s' not supported");
if (SUPPORTS_WEAK)
{
struct weak_syms *t;
- for (t = weak_decls; t; t = t->next)
+ for (t = weak_decls; t != NULL; t = t->next)
{
+#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);
#else
ASM_WEAKEN_LABEL (asm_out_file, t->name);
#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. */
-#ifdef ASM_WEAKEN_LABEL
+#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
static void
remove_from_pending_weak_list (name)
const char *name;
p = &(t->next);
}
}
-#endif /* ASM_WEAKEN_LABEL */
+#endif /* defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) */
/* Emit an assembler directive to make the symbol for DECL an alias to
the symbol for TARGET. */
if (TREE_PUBLIC (decl))
{
-#ifdef ASM_WEAKEN_LABEL
+#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
if (DECL_WEAK (decl))
- {
+ {
+#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
ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
#endif
TREE_ASM_WRITTEN (decl) = 1;
-#else
-#ifdef ASM_OUTPUT_WEAK_ALIAS
+#else /* !ASM_OUTPUT_DEF */
+#if defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL)
if (! DECL_WEAK (decl))
warning ("only weak aliases are supported in this configuration");
+#ifdef ASM_WEAKEN_DECL
+ ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target));
+#else
ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
+#endif
TREE_ASM_WRITTEN (decl) = 1;
#else
warning ("alias definitions not supported in this configuration; ignored");
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);
const_alias_set = new_alias_set ();
}