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

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

2010-10-22 09:55 393 查看
5.12.4.1.1.2.

处理模板模板参数

同样地,在解析完模板模板参数后,模板模板参数的子树也需要额外的节点。这是函数
process_template_parm

的任务。注意该函数的参数
next

指向上图中的
parameter



2161

tree

2162

process_template_parm
(tree list, tree next)

in pt.c

2163

{

2164

tree parm;

2165

tree decl = 0;

2166

tree defval;

2167

int is_type, idx;

2168

2169

parm = next;

2170

my_friendly_assert (TREE_CODE (parm) ==
TREE_LIST, 259);

2171

defval = TREE_PURPOSE (parm);

2172

parm = TREE_VALUE (parm);

2173

is_type = TREE_PURPOSE (parm) == class_type_node;

2174

2175

if (list)

2176

{

2177

tree p = TREE_VALUE (tree_last (list));

2178

2179

if (TREE_CODE (p) == TYPE_DECL || TREE_CODE
(p) == TEMPLATE_DECL)

2180

idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p));

2181

else

2182

idx = TEMPLATE_PARM_IDX (DECL_INITIAL
(p));

2183

++idx;

2184

}

2185

else

2186

idx = 0;

2187

2188

if (!is_type)

2189

{



2212

}

2213

else

2214

{

2215

tree t;

2216

parm = TREE_VALUE (parm);

2217

2218

if (parm && TREE_CODE (parm) ==
TEMPLATE_DECL)

2219

{

2220

t =
make_aggr_type

(TEMPLATE_TEMPLATE_PARM);

2221

/* This is for
distinguishing between real templates and template

2222

template parameters */

2223

TREE_TYPE (parm) = t;

2224

TREE_TYPE (DECL_TEMPLATE_RESULT (parm)) =
t;

2225

decl = parm;

2226

}

2227

else

2228

{



2232

}

2233

2234

TYPE_NAME (t) = decl;

2235

TYPE_STUB_DECL (t) = decl;

2236

parm = decl;

2237

TEMPLATE_TYPE_PARM_INDEX (t)

2238

= build_template_parm_index
(idx, processing_template_decl,

2239

processing_template_decl,

2240

decl, TREE_TYPE
(parm));

2241

}

2242

DECL_ARTIFICIAL (decl) = 1;

2243

SET_DECL_TEMPLATE_PARM_P (decl);

2244

pushdecl (decl);

2245

parm = build_tree_list (defval, parm);

2246

return
chainon (list, parm);

2247

}

注意到
idx


0
;而
processing_template_decl

现在是
1
,它表示这是最顶层的第一个参数。树节点
TEMPLATE_TYPE_PARM_INDEX
记录了这个信息。然后通过
pushdecl

将把这个子树插入到中间树中。

566

tree

567

pushdecl (tree
x)

in name-lookup.c

568

{

569

tree t;

570

tree name;

571

int need_new_binding;

572

573

timevar_push (TV_NAME_LOOKUP);

574

575

need_new_binding = 1;

576

577

if (DECL_TEMPLATE_PARM_P (x))

578

/* Template
parameters have no context; they are not X::T even

579

when declared
within a class or namespace.
*/

580

;

581

else

582

{



602

}

603

604

name = DECL_NAME (x);

605

if (name)

606

{

607

int different_binding_level = 0;



615

/* In case this
decl was explicitly namespace-qualified, look it

616

up in its
namespace context.
*/

617

if (DECL_NAMESPACE_SCOPE_P (x) &&
namespace_bindings_p ())

618

t = namespace_binding (name, DECL_CONTEXT
(x));

619

else

620

t = lookup_name_current_level (name);



743

check_template_shadow (x);



828

/* This name is new in its binding level.

829

Install the new
declaration and return it.
*/

830

if (namespace_bindings_p ())

831

{



872

}

873

else

874

{

875

/* Here to
install a non-global value.
*/

876

tree oldlocal = IDENTIFIER_VALUE (name);

877

tree oldglobal =
IDENTIFIER_NAMESPACE_VALUE (name);

878

879

if (need_new_binding)

880

{

881

push_local_binding
(name, x, 0);

882

/* Because
push_local_binding will hook X on to the

883

current_binding_level's name list, we don't want to

884

do that
again below.
*/

885

need_new_binding = 0;

886

}



1003

}

1004

1005

if (TREE_CODE (x) == VAR_DECL)

1006

maybe_register_incomplete_var (x);

1007

}

1008

1009

if (need_new_binding)

1010

add_decl_to_level
(x,

1011

DECL_NAMESPACE_SCOPE_P (x)

1012

? NAMESPACE_LEVEL (CP_DECL_CONTEXT
(x))

1013

: current_binding_level);

1014

1015

POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);

1016

}

在执行
pushdecl

后,中间树的相关部分将具有如下的结构。


点此打开




103

:加入模板模板参数


pushdecl

返回,
process_template_parm

余下的部分重新安排
parm

,并剔除无用的节点。如下图所示。


点此打开




104

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