summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2001-02-06 19:04:01 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2001-02-06 19:04:01 +0000
commit360a08892ad83318633455e9e51fabdb40546d9f (patch)
treee24c8d0cb0ede4380a07adda9b07f477891f7c06 /gcc/config/rs6000
parentd0d6b1de2a673052ab0b5e6820b921d033249376 (diff)
downloadgcc-360a08892ad83318633455e9e51fabdb40546d9f.tar.gz
* config/rs6000/rs6000.h (ASM_OUTPUT_SYMBOL_REF): Define.
* config/rs6000/rs6000-protos.h (rs6000_output_symbol_ref): Declare. * config/rs6000/rs6000.c (VTABLE_NAME_P): New macro. (rs6000_output_symbol_ref): New function. (output_toc): Use VTABLE_NAME_P. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@39497 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c34
-rw-r--r--gcc/config/rs6000/rs6000.h5
3 files changed, 39 insertions, 1 deletions
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 846321a36ad..31e5716bcf8 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -109,6 +109,7 @@ extern void rs6000_emit_move PARAMS ((rtx, rtx, enum machine_mode));
extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
extern void rs6000_select_rtx_section PARAMS ((enum machine_mode, rtx));
extern rtx rs6000_return_addr PARAMS ((int, rtx));
+extern void rs6000_output_symbol_ref PARAMS ((FILE*, rtx));
#endif /* RTX_CODE */
#ifdef TREE_CODE
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 9d8060bea2d..40c8bbd4cc5 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -6735,6 +6735,38 @@ toc_hash_mark_table (vht)
htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
}
+/* These are the names given by the C++ front-end to vtables, and
+ vtable-like objects. Ideally, this logic should not be here;
+ instead, there should be some programmatic way of inquiring as
+ to whether or not an object is a vtable. */
+
+#define VTABLE_NAME_P(NAME) \
+ (strncmp ("_vt.", name, strlen("_vt.")) == 0 \
+ || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
+ || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
+ || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
+
+void
+rs6000_output_symbol_ref (file, x)
+ FILE *file;
+ rtx x;
+{
+ /* Currently C++ toc references to vtables can be emitted before it
+ is decided whether the vtable is public or private. If this is
+ the case, then the linker will eventually complain that there is
+ a reference to an unknown section. Thus, for vtables only,
+ we emit the TOC reference to reference the symbol and not the
+ section. */
+ const char *name = XSTR (x, 0);
+
+ if (VTABLE_NAME_P (name))
+ {
+ RS6000_OUTPUT_BASENAME (file, name);
+ }
+ else
+ assemble_name (file, name);
+}
+
/* Output a TOC entry. We derive the entry name from what is
being written. */
@@ -6942,7 +6974,7 @@ output_toc (file, x, labelno, mode)
a TOC reference to an unknown section. Thus, for vtables only,
we emit the TOC reference to reference the symbol and not the
section. */
- if (strncmp ("_vt.", name, 4) == 0)
+ if (VTABLE_NAME_P (name))
{
RS6000_OUTPUT_BASENAME (file, name);
if (offset < 0)
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index fc70c506c3a..bb59c473358 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2628,6 +2628,11 @@ do { \
( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+/* Output a reference to SYM on FILE. */
+
+#define ASM_OUTPUT_SYMBOL_REF(FILE, SYM) \
+ rs6000_output_symbol_ref (FILE, SYM)
+
/* Define the parentheses used to group arithmetic operations
in assembler code. */