This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

C++ patch for 417:"curried template inaccurate names"


Attached is a patch to the g++ 2.96 compiler that exterminates
bug 417: "curried template inaccurate names".
----------<reason for changes>---------------
The reason the previous method.c failed was because
method.c(build_template_parm_names) did not take into account nested
template template parameters.  This is corrected by calling the new
function, build_qualified_nested_name, just before the unqualified
template name is output.

This change also required a corresponding change in cplus-dem.c.  The
change here involved moving the code which appended the template name to

the <arguments> to the end of demangle_template_template_parm and, in
addition, testing to see whether 'Q' started the template name, and if
so, call demangle_qualified instead of just exiting without appending
anything.
----------<change logs>---------------
The change log entries are also attached.
Attachment
    ChangeLog.curryTemplate.libiberty
is for the <srcdir>/libiberty directory.
Attachment
    ChangeLog.curryTemplate.cp
is for the <srcdir>/gcc/cp directory.
----------<test case>---------------
The test case is in attachment mangle2.C
----------<test results>---------------
`make check-g++` was run in <objdir>/gcc with the following result
(which was no different than without the patch):


WARNING: Couldn't find the global config file.
Test Run By evansl on Thu Nov  9 05:33:05 2000
Native configuration is i586-pc-linux-gnu

  === g++ tests ===

Schedule of variations:
    unix

Running target unix
Using /usr/local/share/dejagnu/baseboards/unix.exp as board description
file for target.
Using /usr/local/share/dejagnu/config/unix.exp as generic interface file
for target.
Using
/mnt/scratch/gcc-2.96/latest-cvs/gcc/gcc/testsuite/config/default.exp as
tool-and-target-specific interface file.
Running
/mnt/scratch/gcc-2.96/latest-cvs/gcc/gcc/testsuite/g++.dg/special/ecos.exp
...
FAIL: g++.dg/special/conpr-1.C execution test
FAIL: g++.dg/special/conpr-2.C execution test
FAIL: g++.dg/special/conpr-3.C execution test
FAIL: g++.dg/special/conpr-3.C execution test
Running
/mnt/scratch/gcc-2.96/latest-cvs/gcc/gcc/testsuite/g++.old-deja/old-deja.exp
...
FAIL: g++.ext/initp1.C  Execution test
FAIL: g++.ext/instantiate1.C not instantiated (test for errors, line 18)

FAIL: g++.ext/instantiate1.C not instantiated (test for errors, line 20)

FAIL: g++.other/crash18.C (test for excess errors)
FAIL: g++.other/loop2.C caused compiler crash

  === g++ Summary ===

# of expected passes  6072
# of unexpected failures 9
# of expected failures  105
# of untested testcases  9
/mnt/scratch/gcc-2.96/latest-cvs/obj/gcc/testsuite/../g++ version 2.97
20001108 (experimental)

----------<feedback>---------------
Please let me know what else needs to be done.
----------<end>---------------

Index: libiberty/cplus-dem.c
===================================================================
RCS file: /cvs/gcc/egcs/libiberty/cplus-dem.c,v
retrieving revision 1.63
diff -c -p -r1.63 cplus-dem.c
*** cplus-dem.c	2000/09/13 23:09:29	1.63
--- cplus-dem.c	2000/11/09 12:57:58
*************** internal_cplus_demangle PARAMS ((struct 
*** 343,349 ****
  
  static int
  demangle_template_template_parm PARAMS ((struct work_stuff *work,
! 					 const char **, string *));
  
  static int
  demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
--- 343,350 ----
  
  static int
  demangle_template_template_parm PARAMS ((struct work_stuff *work,
!                                          const char **, string *, 
!                                          int ndx_argvec));
  
  static int
  demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
*************** demangle_method_args (work, mangled, dec
*** 1485,1496 ****
  }
  
  #endif
  
  static int
! demangle_template_template_parm (work, mangled, tname)
       struct work_stuff *work;
       const char **mangled;
       string *tname;
  {
    int i;
    int r;
--- 1486,1515 ----
  }
  
  #endif
+ /*
+ 
+ LOCAL FUNCTION
+ 
+ 	demangle_template_template_parm 
+         -- demangle template template parameter.
+ 
+ DESCRIPTION
  
+ 	ARGS:
+           work: work area
+           mangled: the mangled name
+           tname: the demangled name
+           ndx_argvec: if >= 0, then index into work->tmpl_argvec.  
+             This indicates that the call was made from demangle_template
+             with is_type nonzero.
+    
+  */
  static int
! demangle_template_template_parm (work, mangled, tname, ndx_argvec)
       struct work_stuff *work;
       const char **mangled;
       string *tname;
+      int ndx_argvec;
  {
    int i;
    int r;
*************** demangle_template_template_parm (work, m
*** 1520,1526 ****
  	      {
  		(*mangled)++;
  		success =
! 		  demangle_template_template_parm (work, mangled, tname);
  		if (!success)
  		  {
  		    break;
--- 1539,1546 ----
  	      {
  		(*mangled)++;
  		success =
! 		  demangle_template_template_parm (work, mangled, 
! 						   tname, -1);
  		if (!success)
  		  {
  		    break;
*************** demangle_template_template_parm (work, m
*** 1534,1540 ****
  		  {
  		    string_appends (tname, &temp);
  		  }
! 		string_delete(&temp);
  		if (!success)
  		  {
  		    break;
--- 1554,1560 ----
  		  {
  		    string_appends (tname, &temp);
  		  }
! 		string_delete (&temp);
  		if (!success)
  		  {
  		    break;
*************** demangle_template_template_parm (work, m
*** 1547,1552 ****
--- 1567,1599 ----
    if (tname->p[-1] == '>')
      string_append (tname, " ");
    string_append (tname, "> class");
+   if (success)
+     /* append the demangled template name */
+     { int r2 = consume_count (mangled);
+       if ( (r2 > 0)
+ 	&& ( (int) strlen (*mangled) >= r2) )
+         {
+           string_append (tname, " ");
+           string_appendn (tname, *mangled, r2);
+           if (-1<ndx_argvec)
+             {
+               /* Save the template argument. */
+               int i = ndx_argvec;
+               int len = r2;
+               work->tmpl_argvec[i] = xmalloc (len + 1);
+               memcpy (work->tmpl_argvec[i], *mangled, len);
+               work->tmpl_argvec[i][len] = '\0';
+             }
+           *mangled += r2;
+         }
+       else if ( **mangled=='Q' )
+         {
+           string_append (tname, " ");
+ 	  success = demangle_qualified (work, mangled, tname,
+ 				      /*isfuncname=*/0, 
+ 				      /*append=*/1);
+         }
+     }
    return (success);
  }
  
*************** demangle_template (work, mangled, tname,
*** 1966,1991 ****
        /* z for template parameters */
        else if (**mangled == 'z')
  	{
! 	  int r2;
  	  (*mangled)++;
! 	  success = demangle_template_template_parm (work, mangled, tname);
  
- 	  if (success
- 	      && (r2 = consume_count (mangled)) > 0
- 	      && (int) strlen (*mangled) >= r2)
- 	    {
- 	      string_append (tname, " ");
- 	      string_appendn (tname, *mangled, r2);
- 	      if (!is_type)
- 		{
- 		  /* Save the template argument. */
- 		  int len = r2;
- 		  work->tmpl_argvec[i] = xmalloc (len + 1);
- 		  memcpy (work->tmpl_argvec[i], *mangled, len);
- 		  work->tmpl_argvec[i][len] = '\0';
- 		}
- 	      *mangled += r2;
- 	    }
  	  if (!success)
  	    {
  	      break;
--- 2013,2023 ----
        /* z for template parameters */
        else if (**mangled == 'z')
  	{
!           int ndx_argvec = is_type?-1:i;
  	  (*mangled)++;
! 	  success = demangle_template_template_parm (work, mangled, 
!                                                      tname, ndx_argvec);
  
  	  if (!success)
  	    {
  	      break;
Index: gcc/cp/method.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/method.c,v
retrieving revision 1.179
diff -c -p -r1.179 method.c
*** method.c	2000/11/02 19:03:58	1.179
--- method.c	2000/11/09 12:58:07
*************** static int is_back_referenceable_type PA
*** 98,103 ****
--- 98,105 ----
  static int check_btype PARAMS ((tree));
  static void build_mangled_name_for_type PARAMS ((tree));
  static void build_mangled_name_for_type_with_Gcode PARAMS ((tree, int));
+ static int scope_depth PARAMS ((tree));
+ static void build_qualified_nested_name PARAMS ((tree, int));
  
  # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
  # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
*************** build_template_parm_names (parmlist, arg
*** 981,986 ****
--- 983,997 ----
  	      OB_PUTC ('z');
  	      build_template_template_parm_names
  		(DECL_INNERMOST_TEMPLATE_PARMS (parm));
+               { tree context = DECL_CONTEXT (arg);
+                 if (context)
+                   {
+                     if (TYPE_P (context) )
+                       { context = TYPE_NAME (context);
+                       }
+                     build_qualified_nested_name (context, 1);
+                   }
+               }
  	      icat (IDENTIFIER_LENGTH (DECL_NAME (arg)));
  	      OB_PUTID (DECL_NAME (arg));
  	    }
*************** static void
*** 1045,1052 ****
  build_qualified_name (decl)
       tree decl;
  {
-   tree context;
-   int i = 1;
  
    if (TYPE_P (decl))
      decl = TYPE_NAME (decl);
--- 1056,1061 ----
*************** build_qualified_name (decl)
*** 1061,1093 ****
  	numeric_output_need_bar = 1;
        return;
      }
! 
!   context = decl;
!   /* If we can't find a Ktype, do it the hard way.  */
!   if (check_ktype (context, FALSE) == -1)
!     {
!       /* Count type and namespace scopes.  */
!       while (1)
! 	{
! 	  context = CP_DECL_CONTEXT (context);
! 	  if (context == global_namespace)
! 	    break;
! 	  i += 1;
! 	  if (check_ktype (context, FALSE) != -1)
! 	    /* Found one!  */
! 	    break;
! 	  if (TYPE_P (context))
! 	    context = TYPE_NAME (context);
! 	}
!     }
! 
!   if (i > 1)
!     {
!       OB_PUTC ('Q');
!       build_underscore_int (i);
!       numeric_output_need_bar = 0;
!     }
!   build_overload_nested_name (decl);
  }
  
  /* Output the mangled representation for TYPE.  If EXTRA_GCODE is
--- 1070,1076 ----
  	numeric_output_need_bar = 1;
        return;
      }
!   build_qualified_nested_name (decl, 0);
  }
  
  /* Output the mangled representation for TYPE.  If EXTRA_GCODE is
*************** implicitly_declare_fn (kind, type, const
*** 2648,2651 ****
--- 2631,2681 ----
    defer_fn (fn);
    
    return fn;
+ }
+ 
+ /* Given CONTEXT, either a TYPE_DECL or FUNCTION_DECL, produce
+    depth of scope. */
+ 
+ static int
+ scope_depth (context)
+      tree context;
+ {
+   int i = 1;
+   /* If we can't find a Ktype, do it the hard way.  */
+   if (check_ktype (context, FALSE) == -1)
+     {
+       /* Count type and namespace scopes.  */
+       while (1)
+ 	{
+ 	  context = CP_DECL_CONTEXT (context);
+ 	  if (context == global_namespace)
+ 	    break;
+ 	  i += 1;
+ 	  if (check_ktype (context, FALSE) != -1)
+ 	    /* Found one!  */
+ 	    break;
+ 	  if (TYPE_P (context))
+ 	    context = TYPE_NAME (context);
+ 	}
+     }
+   return i;
+ }
+ 
+ /* Given DECL, either a  TYPE_DECL or FUNCTION_DECL, produce
+    the mangling for it.  */
+ 
+ static void
+ build_qualified_nested_name (decl, inc)
+      tree decl;
+      int inc;
+ {
+   int i = scope_depth (decl)+inc;
+ 
+   if (i > 1)
+     {
+       OB_PUTC ('Q');
+       build_underscore_int (i);
+       numeric_output_need_bar = 0;
+     }
+   build_overload_nested_name (decl);
  }
Index: libiberty/testsuite/demangle-expected
===================================================================
RCS file: /cvs/gcc/egcs/libiberty/testsuite/demangle-expected,v
retrieving revision 1.7
diff -c -p -r1.7 demangle-expected
*** demangle-expected	2000/09/13 23:09:30	1.7
--- demangle-expected	2000/11/09 12:58:15
*************** _27_GLOBAL_.N.__12burst_app_ct.app_insta
*** 2566,2568 ****
--- 2566,2579 ----
  --format=gnu
  _26_GLOBAL_\$N\$_tmp_n.iilg4Gya\$app_instance
  {anonymous}::app_instance
+ # begin patch submitted by Larry Evans around 2000-11-05.
+ # demangle mangled name produced by test case for 
+ # bug 417:curried template inaccurate names
+ --format=gnu
+ __Q2t1B1z1ZQ2t1B1z1ZQ2t1B1z1Z1A1C1Ct1C1Zi
+ B<template <class> class B<template <class> class B<template <class> class A>::C>::C>::C<int>::C(void)
+ # the following tests recursive call of demangle_template_template_parm
+ --format=gnu
+ __t1B1z2Zz2ZZ1CG1D
+ B<template <class, template <class, class> class> class C>::B(D)
+ # end   patch submitted by Larry Evans around 2000-11-05.
2000-11-09  Larry Evans  <jcampbell3@prodigy.net>

  * cplus-dem.c(demangle_template_template_parm): appended the
    function with what followed it in previous call from
    demangle_template.  This was done so that the class name could be
    added after the "> class" output, which was output at the end of
    previous version of function.  This was needed for mangled names
    such as __t1B1z2Zz2ZZ1A1C1D and
    __Q2t1B1z1ZQ2t1B1z1ZQ2t1B1z1Z1A1C1Ct1C1Zi. 
    
  * cplus-dem.c(demangle_template): moved the code following call to
    demangle_template_template_parm to within that function.  See
    above for reason.
2000-11-09  Larry Evans  <jcampbell3@prodigy.net>

  * method.c (scope_depth): New local function
  * method.c (build_qualified_nested_name): New local function
  * method.c (build_template_parm_names): Used the new functions to
    handle nested template template parameters.
// Build don't link:
// Origin: Larry Evans <jcampbell3@prodigy.net>
// Purpose:
//   Tests for solution to bug 417 reported by originator to
//   gcc-bugs@gcc.gnu.org on 16 Jul 2000:
//   <http://gcc.gnu.org/ml/gcc-bugs/2000-07/msg00415.html>
template
  < typename S
  >
  struct
A
  {
  };
template
  < template<typename S>class T
  >
  struct
B
  {
    template
      < typename U
      >
      struct
    C
      {
        C(void);
      };
  };
typedef B<A> B1;
typedef B<B1::C> B2;
typedef B<B2::C> B3;
template<>B2::C<int>::C(void){};
template<>B3::C<int>::C(void){};


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]