aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2002-03-20 23:09:00 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2002-03-20 23:09:00 +0000
commit8c152bad172993de682af91636b5ae70eb83149d (patch)
treec52d88a300a436b981cc3d6059ec85d568e3a82f
parent852b81bbe00b28c8a472c148c8fc84f6ecee9c3b (diff)
downloadgcc-8c152bad172993de682af91636b5ae70eb83149d.zip
gcc-8c152bad172993de682af91636b5ae70eb83149d.tar.gz
gcc-8c152bad172993de682af91636b5ae70eb83149d.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/mangle.c45
2 files changed, 49 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0a79602..96b7f46 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2002-03-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ 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 <jason@redhat.com>
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 a71cc00..ac24b6e 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.
- <template-param> ::= T </parameter/ number> _ */
+ <template-param> ::= T </parameter/ number> _
+
+ If we are internally mangling then we distinguish level and, for
+ non-type parms, type too. The mangling appends
+
+ </level/ number> _ </non-type type/ type> _
+
+ 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 ('_');
+ }
}
/* <template-template-param>
@@ -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;