您的位置:首页 > 编程语言

GCC-3.4.6源代码学习笔记(126)

2010-11-05 09:54 323 查看
5.12.4.2.3.1.1.3.


生成template-id



那么作为结果,对于这个非类型实参,“
chunkSize
”的
IDENTIFIER_NODE
被返回。类似的还有下一个实参“
maxSmallObjectSize
”。因此在
lookup_template_class


4346
行退出
coerce_template_parms

时,
arglist

为下图中标记为红色的节点。


点此打开




111

:构建的
arglist

lookup_template_class (continue)

4352

if (arglist == error_mark_node)

4353

/* We were unable to bind
the arguments.
*/

4354

POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
error_mark_node);

4355

4356

/* In the scope
of a template class, explicit references to the

4357

template class refer to the type of the
template, not any

4358

instantiation of it. For example, in:

4359

4360

template <class T> class C { void
f(C<T>); }

4361

4362

the `C<T>' is just the same as `C'.
Outside of the

4363

class, however, such a reference is an
instantiation.
*/

4364

if (comp_template_args (TYPE_TI_ARGS
(template_type),

4365

arglist))

4366

{



4386

}

4387

if (found)

4388

POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
found);

4389

4390

for
(tp =
&DECL_TEMPLATE_INSTANTIATIONS (template);

4391

*tp;

4392

tp = &TREE_CHAIN (*tp))

4393

if (comp_template_args (TREE_PURPOSE
(*tp), arglist))

4394

{



4405

}

4406

4407

/* This type is a
"partial instantiation" if any of the template

4408

arguments still involve
template parameters. Note that we set

4409

IS_PARTIAL_INSTANTIATION for
partial specializations as

4410

well.
*/

4411

is_partial_instantiation = uses_template_parms
(arglist);

4412

4413

/* If the deduced
arguments are invalid, then the binding

4414

failed.
*/

4415

if (!is_partial_instantiation

4416

&& check_instantiated_args
(template,

4417

INNERMOST_TEMPLATE_ARGS
(arglist),

4418

complain))

4419

POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
error_mark_node);

4420

4421

if (!is_partial_instantiation

4422

&& !PRIMARY_TEMPLATE_P
(template)

4423

&& TREE_CODE (CP_DECL_CONTEXT
(template)) == NAMESPACE_DECL)

4424

{

4425

found = xref_tag_from_type (TREE_TYPE
(template),

4426

DECL_NAME
(template),

4427

/*globalize=*/
1);

4428

POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
found);

4429

}

4430

4431

context = tsubst (DECL_CONTEXT (template),
arglist,

4432

complain, in_decl);

4433

if (!context)

4434

context = global_namespace

;


4411
行对于标记为红色的
TREE_VEC

uses_template_parms

将依次遍历其成员,任一成员为类型依赖或值依赖都将导致该函数返回非
0
值,使得
is_partial_instantiation

成为
1

同样在
4431
行,变量
template

指向“
SmallObject
”的
TEMPLATE_DECL
,因此其上下文是
Loki

NAMESPACE_DECL
,它由
tsubst

返回不作任何处理。

lookup_template_class (continue)

4436

/* Create the
type.
*/

4437

if (TREE_CODE (template_type) ==
ENUMERAL_TYPE)

4438

{



4450

}

4451

else

4452

{

4453

t = make_aggr_type
(TREE_CODE (template_type));

4454

CLASSTYPE_DECLARED_CLASS (t)

4455

= CLASSTYPE_DECLARED_CLASS
(template_type);

4456

SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);

4457

TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA
(template_type);

4458

4459

/* A local
class. Make sure the decl gets registered properly.
*/

4460

if (context == current_function_decl

)

4461

pushtag (DECL_NAME (template), t, 0);

4462

}

4463

4464

/* If we called
start_enum or pushtag above, this information

4465

will already be set up.
*/

4466

if (!TYPE_NAME (t))

4467

{

4468

TYPE_CONTEXT (t) = FROB_CONTEXT (context);

4469

4470

type_decl = create_implicit_typedef
(DECL_NAME
(template), t);

4471

DECL_CONTEXT (type_decl) = TYPE_CONTEXT (t);

4472

TYPE_STUB_DECL (t) = type_decl;

4473

DECL_SOURCE_LOCATION (type_decl)

4474

= DECL_SOURCE_LOCATION (TYPE_STUB_DECL
(template_type));

4475

}

4476

else

4477

type_decl = TYPE_NAME (t);

4478

4479

TREE_PRIVATE (type_decl)

4480

= TREE_PRIVATE (TYPE_STUB_DECL
(template_type));

4481

TREE_PROTECTED (type_decl)

4482

= TREE_PROTECTED (TYPE_STUB_DECL
(template_type));

4483

4484

/* Set up the
template information. We have to figure out which

4485

template is the immediate
parent if this is a full

4486

instantiation.
*/

4487

if (parm_depth == 1 ||
is_partial_instantiation

4488

|| !PRIMARY_TEMPLATE_P (template))

4489

/* This case is
easy; there are no member templates involved.

*/

4490

found = template;

4491

else

4492

{



4544

}

4545

4546

SET_TYPE_TEMPLATE_INFO (t, tree_cons
(found, arglist, NULL_TREE));

4547

DECL_TEMPLATE_INSTANTIATIONS (template)

4548

= tree_cons
(arglist, t,

4549

DECL_TEMPLATE_INSTANTIATIONS
(template));

4550

4551

if (TREE_CODE (t) == ENUMERAL_TYPE

4552

&& !is_partial_instantiation)

4553

/* Now that the
type has been registered on the instantiations

4554

list, we set up the
enumerators. Because the enumeration

4555

constants may involve the
enumeration type itself, we make

4556

sure to register the type
first, and then create the

4557

constants. That way, doing
tsubst_expr for the enumeration

4558

constants won't result in
recursive calls here; we'll find

4559

the instantiation and exit
above.
*/

4560

tsubst_enum (template_type, t, arglist);

4561

4562

/* Reset the name
of the type, now that CLASSTYPE_TEMPLATE_INFO

4563

is set up.
*/

4564

if (TREE_CODE (t) != ENUMERAL_TYPE)

4565

DECL_NAME (type_decl) = classtype_mangled_name
(t);

4566

if (is_partial_instantiation)

4567

/* If the type makes use of template parameters, the

4568

code that generates
debugging information will crash.
*/

4569

DECL_IGNORED_P (TYPE_STUB_DECL (t)) = 1;

4570

4571

POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);

4572

}

4573

timevar_pop (TV_NAME_LOOKUP);

4574

}

变量
template_type

是“
SmallObject
”的
RECORD_TYPE
节点。首先在
4551
行之前,下面红色的节点被构建了。


点此打开



作为具现的实例,要求一个修饰名而不是之前看到的朴素名(
plain name
)。

4002

static
tree

4003

classtype_mangled_name

(tree t)

in pt.c

4004

{

4005

if (CLASSTYPE_TEMPLATE_INFO (t)

4006

/* Specializations have already had their
names set up in

4007

lookup_template_class.
*/

4008

&&
!CLASSTYPE_TEMPLATE_SPECIALIZATION (t))

4009

{

4010

tree tmpl = most_general_template
(CLASSTYPE_TI_TEMPLATE (t));

4011

4012

/* For
non-primary templates, the template parameters are

4013

implicit from their
surrounding context.
*/

4014

if (PRIMARY_TEMPLATE_P
(tmpl))

4015

{

4016

tree name = DECL_NAME (tmpl);

4017

char *mangled_name = mangle_class_name_for_template

4018

(IDENTIFIER_POINTER
(name),

4019

DECL_INNERMOST_TEMPLATE_PARMS (tmpl),

4020

CLASSTYPE_TI_ARGS
(t));

4021

tree id = get_identifier
(mangled_name);

4022

IDENTIFIER_TEMPLATE (id) = name;

4023

return
id;

4024

}

4025

}

4026

4027

return
TYPE_IDENTIFIER (t);

4028

}

修饰名根据主模板来构建(它通常就是最泛化的模板,通过
most_general_template

来获取),其中主模板的名字是一个标识符(作为比较,一个偏特化的模板的名字是一个
template-id
)。以下的宏用于检查指定的模板是否为主模板。

2783

#define
DECL_PRIMARY_TEMPLATE
(NODE)
/

in cp-tree.h

2784

(TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS
(NODE)))

2785

2786

/* Returns nonzero if NODE is a primary template.
*/

27873

#define
PRIMARY_TEMPLATE_P
(NODE) (DECL_PRIMARY_TEMPLATE
(NODE) == (NODE))

2661

#define
DECL_INNERMOST_TEMPLATE_PARMS
(NODE)
/

2662

INNERMOST_TEMPLATE_PARMS
(DECL_TEMPLATE_PARMS (NODE))

INNERMOST_TEMPLATE_P ARMS
只是返回节点
value

域中的内容;而
DECL_TEMPLATE_PARMS
返回
TEMPLATE_DECL

arguments

域的指针。

那么具现实例的
TYPE_DECL
被更新为如下的修饰名。


点此打开




112

:内层的
template-id

作为结果,
lookup_template_class

返回具现实例所对应的
RECORD_TYPE
节点。接下来,通过其
chain

域(在
finish_template_type

中的
TYPE_STUB_DECL
)把
TYPE_DECL
(粗红线节点)作为
template-id
返回。

5.12.4.2.3.1.2.

外层
template-id

对于外层的
template-id
,内层
template-id
——“
SmallObject<ThreadingModel,
chunkSize, maxSmallObjectSize>
”是其一个实参;而且下面的
arguments

是一个具有单个成员为该
template-id

tree_vec
。然后我们又以下面的代码进行解析。

cp_parser_template_id

7991

/* Build a representation
of the specialization.
*/

7992

if (TREE_CODE (template) == IDENTIFIER_NODE)

7993

template_id = build_min_nt
(TEMPLATE_ID_EXPR, template, arguments);

7994

else if (DECL_CLASS_TEMPLATE_P (template)

7995

||
DECL_TEMPLATE_TEMPLATE_PARM_P (template))

7996

template_id

7997

= finish_template_type
(template, arguments,

7998

cp_lexer_next_token_is
(parser->lexer,

7999

CPP_SCOPE));

不过在
lookup_template_class

中的处理有一些不同,因为“
ThreadingModel
”是模板参数。

4133

tree

4134

lookup_template_class
(tree d1,

in pt.c

4135

tree arglist,

4136

tree in_decl,

4137

tree context,

4138

int entering_scope,

4139

tsubst_flags_t complain)

4140

{

4141

tree template = NULL_TREE, parmlist;

4142

tree t;

4143

4144

timevar_push (TV_NAME_LOOKUP);

4145

4146

if (TREE_CODE (d1) == IDENTIFIER_NODE)

4147

{

4148

if (IDENTIFIER_VALUE (d1)

4149

&& DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1)))

4150

template = IDENTIFIER_VALUE (d1);

4151

else

4152

{

4153

if (context)

4154

push_decl_namespace (context);

4155

template
= lookup_name
(d1, /*prefer_type=*/
0);

4156

template = maybe_get_template_decl_from_type_decl
(template);

4157

if (context)

4158

pop_decl_namespace
();

4159

}

4160

if (template)

4161

context = DECL_CONTEXT (template);

4162

}

4163

else if (TREE_CODE (d1) == TYPE_DECL
&& IS_AGGR_TYPE (TREE_TYPE (d1)))

4164

{

4165

tree type = TREE_TYPE (d1);

4166

4167

/* If we are
declaring a constructor, say A<T>::A<T>, we will get

4168

an implicit
typename for the second A. Deal with it.

*/

4169

if (TREE_CODE (type) == TYPENAME_TYPE
&& TREE_TYPE (type))

4170

type = TREE_TYPE (type);

4171

4172

if (CLASSTYPE_TEMPLATE_INFO (type))

4173

{

4174

template = CLASSTYPE_TI_TEMPLATE (type);

4175

d1
= DECL_NAME (template);

4176

}

4177

}

4178

else if (TREE_CODE (d1) == ENUMERAL_TYPE

4179

|| (TYPE_P (d1) && IS_AGGR_TYPE
(d1)))

4180

{

4181

template = TYPE_TI_TEMPLATE (d1);

4182

d1 = DECL_NAME (template);

4183

}

4184

else if (TREE_CODE (d1) == TEMPLATE_DECL

4185

&& TREE_CODE
(DECL_TEMPLATE_RESULT (d1)) == TYPE_DECL)

4186

{

4187

template = d1;

4188

d1 = DECL_NAME (template);

4189

context = DECL_CONTEXT (template);

4190

}

4191

4192

/* With something
like `template <class T> class X class X { ... };'

4193

we could end up with D1 having
nothing but an IDENTIFIER_VALUE.

4194

We don't want to do that, but
we have to deal with the situation,

4195

so let's give them some syntax
errors to chew on instead of a

4196

crash. Alternatively D1 might
not be a template type at all.
*/

4197

if (! template)

4198

{

4199

if (complain & tf_error)

4200

error ("`%T' is not a
template", d1);

4201

POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
error_mark_node);

4202

}

4203

4204

if (TREE_CODE (template) != TEMPLATE_DECL

4205

/* Make sure
it's a user visible template, if it was named by

4206

the user.
*/

4207

|| ((complain & tf_user) &&
!DECL_TEMPLATE_PARM_P (template)

4208

&& !PRIMARY_TEMPLATE_P
(template)))

4209

{

4210

if (complain & tf_error)

4211

{

4212

error ("non-template type `%T' used as
a template", d1);

4213

if (in_decl)

4214

cp_error_at ("for template
declaration `%D'", in_decl);

4215

}

4216

POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
error_mark_node);

4217

}

4218

4219

complain &= ~tf_user;

4220

4221

if (DECL_TEMPLATE_TEMPLATE_PARM_P (template))

4222

{

4223

/*
Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store

4224

template arguments */

4225

4226

tree parm;

4227

tree arglist2;

4228

4229

parmlist = DECL_INNERMOST_TEMPLATE_PARMS
(template);

4230

4231

/* Consider an
example where a template template parameter declared as

4232

4233

template <class T, class
U = std::allocator<T> > class TT

4234

4235

The template parameter level
of T and U are one level larger than

4236

of TT. To proper process the
default argument of U, say when an

4237

instantiation
`TT<int>' is seen, we need to build the full

4238

arguments containing {int}
as the innermost level. Outer levels,

4239

available when not appearing
as default template argument, can be

4240

obtained from
`current_template_args ()'.

4241

4242

Suppose that TT is later
substituted with std::vector. The above

4243

instantiation is `TT<int,
std::allocator<T> >' with TT at

4244

level 1, and T at level 2,
while the template arguments at level 1

4245

becomes {std::vector} and
the inner level 2 is {int}.
*/

4246

4247

if (current_template_parms
)

4248

arglist = add_to_template_args
(current_template_args
(), arglist);

4249

4250

arglist2 = coerce_template_parms (parmlist,
arglist, template,

4251

complain, /*require_all_args=*/
1);

4252

if (arglist2 == error_mark_node

4253

|| (!uses_template_parms (arglist2)

4254

&& check_instantiated_args
(template, arglist2, complain)))

4255

POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
error_mark_node);

4256

4257

parm = bind_template_template_parm
(TREE_TYPE
(template), arglist2);

4258

POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
parm);

4259

}



4574

}

上面的
d1

指向下图的
TEMPLATE_DECL
。而
arglist

指向代表内层
template-id
的子树。


点此打开



还有注意
current_template_parms

指向的节点,它是“
SmallObject
”的实参。它还应该是“
ThreadingModel
”的实参,因为“
ThreadingModel
”被包括在“
SmallObject
”的参数列表中。因此在
4248
行,函数
current_template_args

拷贝出这个向量,不过拷贝节点的
type

域是空的。

511

static
tree

512

add_to_template_args

(tree args, tree
extra_args)

in pt.c

513

{

514

tree new_args;

515

int extra_depth;

516

int i;

517

int j;

518

519

extra_depth = TMPL_ARGS_DEPTH (extra_args);

520

new_args = make_tree_vec (TMPL_ARGS_DEPTH
(args) + extra_depth);

521

522

for
(i = 1; i <= TMPL_ARGS_DEPTH (args); ++i)

523

SET_TMPL_ARGS_LEVEL (new_args, i,
TMPL_ARGS_LEVEL (args, i));

524

525

for
(j = 1; j
<= extra_depth; ++j, ++i)

526

SET_TMPL_ARGS_LEVEL (new_args, i, TMPL_ARGS_LEVEL
(extra_args, j));

527

528

return
new_args;

529

}

接着在
4248
行,构建了
TREE_VEC
类型的
arglists

,其第一个成员指向上图中红色的
TREE_VEC
,而第二个成员指向内层
template-id
(在下面传递给
args

)的
TREE_VEC
。那么在
4250
行的
parmlist

(在下面传递给
parms

)指向图
112
中的其他
TREE_VEC
,这个节点代表“
ThreadingModel
”的实参。

3805

static
tree

3806

coerce_template_parms
(tree parms,

in pt.c

3807

tree args,

3808

tree in_decl,

3809

tsubst_flags_t complain,

3810

int require_all_arguments)

3811

{

3812

int nparms, nargs, i, lost = 0;

3813

tree inner_args;

3814

tree new_args;

3815

tree new_inner_args;

3816

3817

inner_args = INNERMOST_TEMPLATE_ARGS (args);

3818

nargs = inner_args ? NUM_TMPL_ARGS
(inner_args) : 0;

3819

nparms = TREE_VEC_LENGTH (parms);

3820

3821

if (nargs > nparms

3822

|| (nargs < nparms

3823

&& require_all_arguments

3824

&& TREE_PURPOSE (TREE_VEC_ELT
(parms, nargs)) == NULL_TREE))

3825

{

3826

if (complain & tf_error)

3827

{

3828

error ("wrong number of template
arguments (%d, should be %d)",

3829

nargs, nparms);

3830

3831

if (in_decl)

3832

cp_error_at ("provided for
`%D'", in_decl);

3833

}

3834

3835

return
error_mark_node;

3836

}

3837

3838

new_inner_args = make_tree_vec (nparms);

3839

new_args = add_outermost_template_args
(args,
new_inner_args);


3817
行,
INNERMOST_TEMPLATE_ARGS
返回先前所构建的
arglists

的最后一个成员,这是代表内层
template-id
的节点。作为结果,我们得到
nparms


1
),
nargs


1
)。

538

static
tree

539

add_outermost_template_args
(tree args, tree extra_args)

in pt.c

540

{

541

tree new_args;

542

543

/* If there are
more levels of EXTRA_ARGS than there are ARGS,

544

something very
fishy is going on.
*/

545

my_friendly_assert
(TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (extra_args),

546

0);

547

548

/* If *all* the new
arguments will be the EXTRA_ARGS, just return

549

them.
*/

550

if (TMPL_ARGS_DEPTH (args) == TMPL_ARGS_DEPTH
(extra_args))

551

return
extra_args;

552

553

/* For the moment,
we make ARGS look like it contains fewer levels.
*/

554

TREE_VEC_LENGTH (args) -= TMPL_ARGS_DEPTH
(extra_args);

555

556

new_args = add_to_template_args
(args, extra_args);

557

558

/* Now, we restore
ARGS to its full dimensions.
*/

559

TREE_VEC_LENGTH (args) += TMPL_ARGS_DEPTH
(extra_args);

560

561

return
new_args;

562

}

因为
args

是包含
TREE_VEC

TREE_VEC

TMPL_ARGS_DEPTH
返回的外层向量的长度(它是
2
),
extra_args

是长度是
1

TREE_VEC
,因为不是包含
TREE_VEC

TREE_VEC

TMPL_ARGS_DEPTH
对其总是返回
1
。因此
add_outermost_template_args

的总体效果是使用
extra_args

来替代
args

的最后的成员。

coerce_template_parms (continue)

3840

for
(i = 0; i < nparms; i++)

3841

{

3842

tree arg;

3843

tree parm;

3844

3845

/* Get the Ith
template parameter.
*/

3846

parm = TREE_VEC_ELT (parms, i);

3847

3848

/*
Calculate the Ith argument.
*/

3849

if (i < nargs)

3850

arg = TREE_VEC_ELT (inner_args, i);

3851

else if (require_all_arguments)

3852

/* There must
be a default arg in this case.
*/

3853

arg = tsubst_template_arg (TREE_PURPOSE
(parm), new_args,

3854

complain, in_decl);

3855

else

3856

break
;

3857

3858

my_friendly_assert (arg, 20030727);

3859

if (arg == error_mark_node)

3860

error ("template argument %d is
invalid", i + 1);

3861

else

3862

arg = convert_template_argument
(TREE_VALUE (parm),

3863

arg, new_args,
complain, i,

3864

i
n_decl);

3865

3866

if (arg == error_mark_node)

3867

lost++;

3868

TREE_VEC_ELT (new_inner_args, i) = arg;

3869

}

3870

3871

if (lost)

3872

return
error_mark_node;

3873

3874

return
new_inner_args;

3875

}

在这个函数的调用中,参数
parm

是上图(不是图
112
)中的
TYPE_DECL

arg

是内层
template-id
(它是
TYPE_DECL
节点);
args

是由
add_outermost_template_args

构建的包含
TREE_VEC

TREE_VEC


3636

static
tree

3637

convert_template_argument
(tree parm,

in pt.c

3638

tree arg,

3639

tree args,

3640

tsubst_flags_t
complain,

3641

int i,

3642

tree in_decl)

3643

{

3644

tree val;

3645

tree inner_args;

3646

int is_type, requires_type, is_tmpl_type,
requires_tmpl_type;

3647

3648

inner_args = INNERMOST_TEMPLATE_ARGS (args);

3649

3650

if (TREE_CODE (arg) == TREE_LIST

3651

&& TREE_CODE (TREE_VALUE (arg))
== OFFSET_REF)

3652

{



3660

}

3661

3662

requires_tmpl_type = TREE_CODE (parm) ==
TEMPLATE_DECL;

3663

requires_type = (TREE_CODE (parm) ==
TYPE_DECL

3664

|| requires_tmpl_type);

3665

3666

is_tmpl_type = ((TREE_CODE (arg) ==
TEMPLATE_DECL

3667

&&
TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)

3668

|| TREE_CODE (arg) ==
TEMPLATE_TEMPLATE_PARM

3669

|| TREE_CODE (arg) ==
UNBOUND_CLASS_TEMPLATE);

3670

3671

if (is_tmpl_type

3672

&& (TREE_CODE (arg) ==
TEMPLATE_TEMPLATE_PARM

3673

|| TREE_CODE (arg) ==
UNBOUND_CLASS_TEMPLATE))

3674

arg
= TYPE_STUB_DECL (arg);

3675

3676

is_type = TYPE_P (arg) || is_tmpl_type;



3722

if (is_type)

3723

{

3724

if (requires_tmpl_type)

3725

{



3759

}

3760

else

3761

val =
groktypename

(arg);

3762

}

3763

else

3764

{



3790

}

3791

3792

return
val;

3793

}

因为
arg

是一个
TYPE_DECL
节点,在
3761
行,
groktypename

不对它做任何事,只是返回它。然后在
3868
行,在
coerce_template_parms

中该节点被填入
new_inner_args

。记得当构建
new_inner_args

时,这个节点被刻意忽略了,但现在我们开始照顾到它了。因此从
4250
行返回到
lookup_template_class

时,
arglist2


arglist

相同。

记住在
4257
行的
template

指向代表“
ThreadingModel
”的
TEMPLATE_DECL
。接下来,将构建
BOUND_TEMPLATE_TEMPLATE_PARM
节点,正如其名字所暗示,它代表模板模板参数的一个绑定。

995

tree

996

bind_template_template_parm

(tree t,
tree newargs)

in tree.c

997

{

998

tree decl = TYPE_NAME (t);

999

tree t2;

1000

1001

t2 = make_aggr_type
(BOUND_TEMPLATE_TEMPLATE_PARM);

1002

decl = build_decl
(TYPE_DECL, DECL_NAME (decl), NULL_TREE);

1003

1004

/* These nodes have
to be created to reflect new TYPE_DECL and template

1005

arguments.
*/

1006

TEMPLATE_TYPE_PARM_INDEX (t2) = copy_node
(TEMPLATE_TYPE_PARM_INDEX (t));

1007

TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (t2)) = decl;

1008

TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2)

1009

=
tree_cons

(TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t),

1010

newargs, NULL_TREE);

1011

1012

TREE_TYPE (decl) = t2;

1013

TYPE_NAME (t2) = decl;

1014

TYPE_STUB_DECL (t2) = decl;

1015

TYPE_SIZE (t2) = 0;

1016

1017

return
t2;

1018

}

最终,所构建的
BOUND_TEMPLATE_TEMPLATE_PARM
节点如下图所示。并且它被
lookup_template_class

返回。


点此打开




113


BOUND_TEMPLATE_TEMPLATE_PARM
节点

那么在
finish_template_type


cp_parser_template_id

中,通过该节点的
chain

域得到的
TYPE_DECL
被返回作为该
template-id
的代表。

接着该节点为
cp_parser_class_name

返回给
cp_parser_base_specifier

。相关代码参照章节
完成类名查找

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: