This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ patch for 417:"curried template inaccurate names"
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Subject: C++ patch for 417:"curried template inaccurate names"
- From: Larry Evans <jcampbell3 at prodigy dot net>
- Date: Thu, 09 Nov 2000 07:33:55 -0600
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){};