OSDN Git Service

cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Mar 2002 23:09:00 +0000 (23:09 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Mar 2002 23:09:00 +0000 (23:09 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@51098 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/mangle.c

index 0a79602..96b7f46 100644 (file)
@@ -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
        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.
index a71cc00..ac24b6e 100644 (file)
@@ -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;