The following code around trunk/gcc/cp/pt.c:15514:
15513 partial_spec_args = INNERMOST_TEMPLATE_ARGS (partial_spec_args);
15514 partial_spec_args = tsubst_template_args
15515 (partial_spec_args, outer_args, tf_none, NULL_TREE);
as shown here:
http://gcc.gnu.org/viewcvs/trunk/gcc/cp/pt.c?view=markup&pathrev=153822
appears to substitute outer_args in the place where inner parameters
are located. Am I reading the code wrong? I ask because gdb seems to
show this happening with the following code:
--{-- test code --
struct
outer_arg0
;
struct
inner_arg0
;
struct
inner_arg1
;
//#define CLASS_SCOPE_SPECIALIZATION
template
< class OuterArg0
>
struct
outer_tmpl
{
template
< typename InnerArg0
, typename InnerArg1
>
struct
inner_tmpl
#ifndef CLASS_SCOPE_SPECIALIZATION
;
#else
{};
template
< typename InnerArg0
>
struct
inner_tmpl
< InnerArg0
, inner_arg1
>
{
typedef
InnerArg0
inner_typdef
;
};
#endif
};
#ifndef CLASS_SCOPE_SPECIALIZATION
template
< //class OuterArg0
>
template
< typename InnerArg0
>
struct
outer_tmpl
< outer_arg0
>::
inner_tmpl
< InnerArg0
, inner_arg1
>
{
typedef
InnerArg0
inner_typdef
;
};
#endif
typedef
outer_tmpl<outer_arg0>
::inner_tmpl
< inner_arg0
, inner_arg1
>
::inner_typdef //error here.
outer_inner_type
;
--}-- test code --
To be more specific, the following is part of a gdb session:
--{-- gdb session --
Breakpoint 5, tsubst_template_args (t=0x7f89a3765d80,
args=0x7f89a3788750, complain=0, in_decl=0x0) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/pt.c:8136
[@@]tsubst_template_args:.TREE_VEC_LENGTH(t)[@@]
[***]len=
$6 = 2
[***]inp t=
<tree_vec 0x7f89a3765d80
elt 0 <template_type_parm 0x7f89a3786a80 InnerArg0 type_0 type_6 VOID
align 8 symtab 0 alias set -1 canonical type 0x7f89a3786000
index 0 level 1 orig_level 1
chain <type_decl 0x7f89a3786b40 InnerArg0>>
elt 1 <record_type 0x7f89a3775e40 inner_arg1 type_5 type_6 VOID
align 8 symtab 0 alias set -1 canonical type 0x7f89a3775e40
full-name "struct inner_arg1"
no-binfo use_template=0 interface-unknown
chain <type_decl 0x7f89a3775f00 inner_arg1>>>
[***]inp args=
<tree_vec 0x7f89a3788750
elt 0 <record_type 0x7f89a3775b40 outer_arg0 type_5 type_6 VOID
align 8 symtab 0 alias set -1 canonical type 0x7f89a3775b40
full-name "struct outer_arg0"
no-binfo use_template=0 interface-unknown
chain <type_decl 0x7f89a3775c00 outer_arg0>>>
[***]bt:
#0 tsubst_template_args (t=0x7f89a3765d80, args=0x7f89a3788750,
complain=0, in_decl=0x0) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/pt.c:8136
#1 0x0000000000586ed4 in most_specialized_class (type=0x7f89a3789e40,
tmpl=0x7f89a37869c0) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/pt.c:15439
#2 0x000000000053fa43 in instantiate_class_template
(type=0x7f89a3789e40) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/pt.c:7324
#3 0x0000000000644002 in complete_type (type=0x7f89a3789e40) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/typeck.c:130
#4 0x000000000061507d in cp_parser_nested_name_specifier_opt
(parser=0x7f89a42cca50, typename_keyword_p=0 '\0', check_dependency_p=1
'\001', type_p=0 '\0', is_declaration=0 '\0') at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:4255
#5 0x0000000000621ba0 in cp_parser_simple_type_specifier
(parser=0x7f89a42cca50, decl_specs=0x7fffac4025b0, flags=1) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:11947
#6 0x0000000000621795 in cp_parser_type_specifier
(parser=0x7f89a42cca50, flags=1, decl_specs=0x7fffac4025b0,
is_declaration=1 '\001', declares_class_or_enum=0x7fffac402534,
is_cv_qualifier=0x7fffac402533 "") at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:11749
#7 0x000000000061d3ff in cp_parser_decl_specifier_seq
(parser=0x7f89a42cca50, flags=1, decl_specs=0x7fffac4025b0,
declares_class_or_enum=0x7fffac4025ac) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:9130
#8 0x000000000061ce17 in cp_parser_simple_declaration
(parser=0x7f89a42cca50, function_definition_allowed_p=1 '\001') at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:8792
#9 0x000000000061cdcb in cp_parser_block_declaration
(parser=0x7f89a42cca50, statement_p=0 '\0') at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:8753
#10 0x000000000061cbb5 in cp_parser_declaration (parser=0x7f89a42cca50)
at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:8658
#11 0x000000000061c827 in cp_parser_declaration_seq_opt
(parser=0x7f89a42cca50) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:8549
#12 0x0000000000612cd7 in cp_parser_translation_unit
(parser=0x7f89a42cca50) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:3058
#13 0x0000000000639680 in c_parse_file () at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:22960
#14 0x00000000007a4773 in c_common_parse_file (set_yydebug=0) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/c-opts.c:1302
#15 0x0000000000bc2112 in compile_file () at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/toplev.c:1049
#16 0x0000000000bc434f in do_compile () at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/toplev.c:2408
#17 0x0000000000bc4425 in toplev_main (argc=2, argv=0x7fffac402948) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/toplev.c:2450
#18 0x00000000007b2cb0 in main (argc=2, argv=0x7fffac402948) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/main.c:35
--}-- gdb session --
I guessing that this misplaced substitution causes the compile to fail
with error message:
--{-- compilation --
make
/home/evansl/download/gcc/svn/patch.none/install/bin/g++ -c
bug.scope_specialization.cpp
bug.scope_specialization.cpp:84:3: error: 'inner_typdef' in class
'outer_tmpl<outer_arg0>::inner_tmpl<inner_arg0, inner_arg1>' does not
name a type
make: *** [bug.scope_specialization.o] Error 1
--}-- compilation --
Any clues about what's going wrong would be appreciated.
I would be happy to send anyone the gdb command file used
to set the breakpoints and create the above gdb session.
-regards,
Larry
(PS. I'm obviously using an earlier version of the code rather than
that cited above. The svn info command produces:
~/download/gcc/svn/patch.none.gdb/src $ svn info
Path: .
URL: svn://gcc.gnu.org/svn/gcc/trunk
Repository Root: svn://gcc.gnu.org/svn/gcc
Repository UUID: 138bc75d-0d04-0410-961f-82ee72b054a4
Revision: 152768
Node Kind: directory
Schedule: normal
Last Changed Author: rguenth
Last Changed Rev: 152768
Last Changed Date: 2009-10-14 09:14:44 -0500 (Wed, 14 Oct 2009)
)