From 8c152bad172993de682af91636b5ae70eb83149d Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 20 Mar 2002 23:09:00 +0000 Subject: [PATCH] re PR c++/4361 (bogus ambiguity taking the address of a member template) cp: PR c++/4361 * mangle.c (struct globals) Add internal_mangling_p member. (write_template_param): Do internal mangling, if needed. (mangle_conv_op_name_for_type): Request internal mangling. From-SVN: r51098 --- gcc/cp/ChangeLog | 12 ++++++++---- gcc/cp/mangle.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0a796024ffe..96b7f46cbaa 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2002-03-20 Nathan Sidwell + + PR c++/4361 + * mangle.c (struct globals) Add internal_mangling_p member. + (write_template_param): Do internal mangling, if needed. + (mangle_conv_op_name_for_type): Request internal mangling. + 2002-03-20 Jason Merrill PR c++/2136 @@ -79,14 +86,11 @@ all end up on slot 2. * lex.c (do_identifier): A conversion operator token might be satisfied by a templated conversion operator. - * mangle.c (struct globals) Add internal_mangling_p member. - (write_template_param): Do internal mangling, if needed. - (mangle_conv_op_name_for_type): Request internal mangling. * pt.c (check_explicit_specialization): Use CLASSTYPE_FIRST_CONVERSION_SLOT. (template_parm_this_level_p): New function. (push_template_decl_real): Determine DECL_TEMPLATE_CONV_FN_P. - * search.c (lookup_fn_fields_1): Template conversions will be on + * search.c (lookup_fnfields_1): Template conversions will be on the first slot. * typeck.c (build_component_ref): Preserve the type of an conversion operator name on the overload type. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index a71cc006525..ac24b6eb8c6 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -93,6 +93,11 @@ static struct globals /* An array of the current substitution candidates, in the order we've seen them. */ varray_type substitutions; + + /* 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; } G; /* Indices into subst_identifiers. These are identifiers used in @@ -2049,13 +2054,22 @@ write_pointer_to_member_type (type) TEMPLATE_TEMPLATE_PARM, BOUND_TEMPLATE_TEMPLATE_PARM or a TEMPLATE_PARM_INDEX. - ::= T _ */ + ::= T _ + + If we are internally mangling then we distinguish level and, for + non-type parms, type too. The mangling appends + + _ _ + + This is used by mangle_conv_op_name_for_type. */ static void write_template_param (parm) tree parm; { int parm_index; + int parm_level; + tree parm_type = NULL_TREE; MANGLE_TRACE_TREE ("template-parm", parm); @@ -2065,10 +2079,13 @@ write_template_param (parm) case TEMPLATE_TEMPLATE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM: parm_index = TEMPLATE_TYPE_IDX (parm); + parm_level = TEMPLATE_TYPE_LEVEL (parm); break; case TEMPLATE_PARM_INDEX: parm_index = TEMPLATE_PARM_IDX (parm); + parm_level = TEMPLATE_PARM_LEVEL (parm); + parm_type = TREE_TYPE (TEMPLATE_PARM_DECL (parm)); break; default: @@ -2081,6 +2098,15 @@ write_template_param (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 ('_'); + } } /* @@ -2407,15 +2433,26 @@ mangle_conv_op_name_for_type (type) tree type; { tree identifier; + const char *mangled_type; + char *op_name; - /* Build the mangling for TYPE. */ - const char *mangled_type = mangle_type_string (type); + /* 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. */ - char *op_name = concat ("operator ", mangled_type, NULL); + 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. */ + my_friendly_assert (!IDENTIFIER_TYPENAME_P (identifier) + || same_type_p (type, TREE_TYPE (identifier)), + 20011230); + /* Set bits on the identifier so we know later it's a conversion. */ IDENTIFIER_OPNAME_P (identifier) = 1; IDENTIFIER_TYPENAME_P (identifier) = 1;