aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/mangle.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-06-17 16:58:19 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-06-17 16:58:19 +0000
commitca90f3e1c758d9efb6c8ba658a66675c3c36c6d4 (patch)
tree9158221fab15fe3ae9e6c048a33b2f599faa86c7 /gcc/cp/mangle.c
parent8207b189e50ec5350d3ab72b397ee139282b4e9d (diff)
downloadgcc-ca90f3e1c758d9efb6c8ba658a66675c3c36c6d4.zip
gcc-ca90f3e1c758d9efb6c8ba658a66675c3c36c6d4.tar.gz
gcc-ca90f3e1c758d9efb6c8ba658a66675c3c36c6d4.tar.bz2
re PR c++/11105 ([3.3/3.4 regression of sorts] ICE in mangle_conv_op_name_for_type)
PR c++/11105 * cp-tree.h (DECL_CONV_FN_TYPE): New method. * mangle.c (struct globals): Remove internal_mangling_p. (write_unqualified_name): Use DECL_CONV_FN_TYPE. (write_template_parm): Don't write out the level number. (conv_type_names): New variable. (hash_type): New function. (compare_type): Likewise. (mangle_conv_op_name_for_type): Don't try to mangle conversion operator names. * search.c (lookup_conversion_operator): New function. (lookup_fnfields_1): Use it. PR c++/11105 * g++.dg/abi/conv1.C: Remove it. * g++.dg/template/conv7.C: New test. * g++.dg/template/conv8.C: Likewise. * g++.old-deja/g++.ext/pretty2.C: Do not test __FUNCTION__ for a conversion operator. From-SVN: r68095
Diffstat (limited to 'gcc/cp/mangle.c')
-rw-r--r--gcc/cp/mangle.c77
1 files changed, 37 insertions, 40 deletions
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index c0d31ba..4c53662 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -102,11 +102,6 @@ static struct globals
/* The entity that is being mangled. */
tree entity;
- /* We are mangling an internal symbol. It is important to keep those
- involving template parmeters distinct by distinguishing their level
- and, for non-type parms, their type. */
- bool internal_mangling_p;
-
/* True if the mangling will be different in a future version of the
ABI. */
bool need_abi_warning;
@@ -1006,7 +1001,7 @@ write_unqualified_name (const tree decl)
type = TREE_TYPE (fn_type);
}
else
- type = TREE_TYPE (DECL_NAME (decl));
+ type = DECL_CONV_FN_TYPE (decl);
write_conversion_operator_name (type);
}
else if (DECL_OVERLOADED_OPERATOR_P (decl))
@@ -2250,15 +2245,6 @@ write_template_param (const tree parm)
if (parm_index > 0)
write_unsigned_number (parm_index - 1);
write_char ('_');
- if (G.internal_mangling_p)
- {
- if (parm_level > 0)
- write_unsigned_number (parm_level - 1);
- write_char ('_');
- if (parm_type)
- write_type (parm_type);
- write_char ('_');
- }
}
/* <template-template-param>
@@ -2600,6 +2586,28 @@ mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset,
return get_identifier (result);
}
+/* This hash table maps TYPEs to the IDENTIFIER for a conversion
+ operator to TYPE. The nodes are TREE_LISTs whose TREE_PURPOSE is
+ the TYPE and whose TREE_VALUE is the IDENTIFIER. */
+
+static GTY ((param_is (union tree_node))) htab_t conv_type_names;
+
+/* Hash a node (VAL1) in the table. */
+
+static hashval_t
+hash_type (const void *val)
+{
+ return htab_hash_pointer (TREE_PURPOSE (*((tree *) val)));
+}
+
+/* Compare VAL1 (a node in the table) with VAL2 (a TYPE). */
+
+static int
+compare_type (const void *val1, const void *val2)
+{
+ return TREE_PURPOSE ((tree) val1) == (tree) val2;
+}
+
/* Return an identifier for the mangled unqualified name for a
conversion operator to TYPE. This mangling is not specified by the
ABI spec; it is only used internally. */
@@ -2607,33 +2615,22 @@ mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset,
tree
mangle_conv_op_name_for_type (const tree type)
{
+ void **slot;
tree identifier;
- const char *mangled_type;
- char *op_name;
+ char buffer[64];
- /* Build the internal mangling for TYPE. */
- G.internal_mangling_p = true;
- mangled_type = mangle_type_string (type);
- G.internal_mangling_p = false;
-
- /* Allocate a temporary buffer for the complete name. */
- op_name = concat ("operator ", mangled_type, NULL);
- /* Find or create an identifier. */
- identifier = get_identifier (op_name);
- /* Done with the temporary buffer. */
- free (op_name);
-
- /* It had better be a unique mangling for the type. */
- if (IDENTIFIER_TYPENAME_P (identifier)
- && !same_type_p (type, TREE_TYPE (identifier)))
- {
- /* In G++ 3.2, the name mangling scheme was ambiguous. In later
- versions of the ABI, this problem has been fixed. */
- if (abi_version_at_least (2))
- abort ();
- error ("due to a defect in the G++ 3.2 ABI, G++ has assigned the "
- "same mangled name to two different types");
- }
+ if (conv_type_names == NULL)
+ conv_type_names = htab_create_ggc (31, &hash_type, &compare_type, NULL);
+
+ slot = htab_find_slot_with_hash (conv_type_names, type,
+ htab_hash_pointer (type), INSERT);
+ if (*slot)
+ return TREE_VALUE ((tree) *slot);
+
+ /* Create a unique name corresponding to TYPE. */
+ sprintf (buffer, "operator %d\n", htab_elements (conv_type_names));
+ identifier = get_identifier (buffer);
+ *slot = build_tree_list (type, identifier);
/* Set bits on the identifier so we know later it's a conversion. */
IDENTIFIER_OPNAME_P (identifier) = 1;