This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
c++ 2.96 patch lookup_template_class push_decl_namespace
- To: gcc-patches at gcc dot gnu dot org
- Subject: c++ 2.96 patch lookup_template_class push_decl_namespace
- From: Larry Evans <jcampbell3 at prodigy dot net>
- Date: Mon, 26 Jun 2000 07:54:38 -0500
Included below is a patch to the g++ 2.96 compiler that avoids an
error in the following test case:
----------<begin test case>---------------
// Build don't link
//Purpose:
// Test nested template as template template arg.
//Result:
// Before the patch, got:
// `C' is not a template
template
< template<typename S>class T
>
struct
A
{ T<int> m_t;
};
struct
B
{
template
< typename V
>
struct
C
{ V m_v;
};
};
A
<B
::C
>
z
;
----------<end test case>---------------
The reason the previous pt.c failed was because of the following
statements in function lookup_template_class:
push_decl_namespace (context);
template = lookup_name (d1, /*prefer_type=*/0);
...
pop_decl_namespace ();
This failed because context was not a namespace in the above test
case. The solution simply involves checking this condition and
calling lookup_field(context,d1,0,0) instead.
----------<ChangeLog>---------------
2000-06-26 Larry Evans <jcampbell3@prodigy.net>
* pt.c (lookup_template_class): dispatch on TREE_CODE(context)
instead of assuming it's a NAMESPACE_DECL
----------<cvs diffs>---------------
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.446
diff -c -3 -p -r1.446 pt.c
*** pt.c 2000/06/23 06:49:44 1.446
--- pt.c 2000/06/25 12:16:24
*************** maybe_get_template_decl_from_type_decl (
*** 3713,3719 ****
the class we are looking up.
If the template class is really a local class in a template
! function, then the FUNCTION_CONTEXT is the function in which it is
being instantiated. */
tree
--- 3713,3719 ----
the class we are looking up.
If the template class is really a local class in a template
! function, then the CONTEXT is the function in which it is
being instantiated. */
tree
*************** lookup_template_class (d1, arglist, in_d
*** 3729,3765 ****
if (TREE_CODE (d1) == IDENTIFIER_NODE)
{
if (IDENTIFIER_VALUE (d1)
! && DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1)))
template = IDENTIFIER_VALUE (d1);
else
! {
! if (context)
! push_decl_namespace (context);
! template = lookup_name (d1, /*prefer_type=*/0);
template = maybe_get_template_decl_from_type_decl (template);
! if (context)
! pop_decl_namespace ();
! }
if (template)
context = DECL_CONTEXT (template);
}
else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE
(d1)))
{
tree type = TREE_TYPE (d1);
!
/* If we are declaring a constructor, say A<T>::A<T>, we will
get
! an implicit typename for the second A. Deal with it. */
if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type))
type = TREE_TYPE (type);
!
if (CLASSTYPE_TEMPLATE_INFO (type))
{
! template = CLASSTYPE_TI_TEMPLATE (type);
! d1 = DECL_NAME (template);
}
}
else if (TREE_CODE (d1) == ENUMERAL_TYPE
! || (TYPE_P (d1) && IS_AGGR_TYPE (d1)))
{
template = TYPE_TI_TEMPLATE (d1);
d1 = DECL_NAME (template);
--- 3729,3780 ----
if (TREE_CODE (d1) == IDENTIFIER_NODE)
{
if (IDENTIFIER_VALUE (d1)
! && DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1)))
template = IDENTIFIER_VALUE (d1);
else
! {
! int is_namespace=0;
! if (context)
! {
! is_namespace=TREE_CODE(context) == NAMESPACE_DECL;
! if(is_namespace)
! {
! push_decl_namespace(context);
! template = lookup_name (d1, /*prefer_type=*/0);
! }
! else
! {
! template = lookup_field(context,d1,0,0);
! }
! }
! else
! {
! template = lookup_name (d1, /*prefer_type=*/0);
! }
template = maybe_get_template_decl_from_type_decl (template);
! if(is_namespace)
! pop_decl_namespace ();
! }
if (template)
context = DECL_CONTEXT (template);
}
else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE
(d1)))
{
tree type = TREE_TYPE (d1);
!
/* If we are declaring a constructor, say A<T>::A<T>, we will
get
! an implicit typename for the second A. Deal with it. */
if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type))
type = TREE_TYPE (type);
!
if (CLASSTYPE_TEMPLATE_INFO (type))
{
! template = CLASSTYPE_TI_TEMPLATE (type);
! d1 = DECL_NAME (template);
}
}
else if (TREE_CODE (d1) == ENUMERAL_TYPE
! || (TYPE_P (d1) && IS_AGGR_TYPE (d1)))
{
template = TYPE_TI_TEMPLATE (d1);
d1 = DECL_NAME (template);
----------<g++ tests>---------------
runtest --tool g++
WARNING: Couldn't find the global config file.
Test Run By evansl on Sun Jun 25 12:33:28 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
/home/evansl/prog_dev/gcc_all/gcc-2.96/snap/gcc/gcc/testsuite/config/default.exp
as tool-and-target-specific interface file.
Running
/home/evansl/prog_dev/gcc_all/gcc-2.96/snap/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
/home/evansl/prog_dev/gcc_all/gcc-2.96/snap/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)
XPASS: g++.oliva/template7.C - conversion from int to non-scalar - (test
for bogus messages, line 12)
FAIL: g++.other/crash18.C (test for excess errors)
FAIL: g++.other/initstring.C (test for excess errors)
FAIL: g++.other/type.C caused compiler crash
=== g++ Summary ===
# of expected passes 5907
# of unexpected failures 10
# of unexpected successes 1
# of expected failures 98
# of untested testcases 8
/home/evansl/prog_dev/gcc_all/gcc-2.96/snap/objdir/gcc/testsuite/../g++
version 2.96 20000625 (experimental)