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

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

2010-12-18 16:23 369 查看
5.12.5.2.2.2.1.3.


为具现构建

RECORD_TYPE


最后,在
cp_parser_init_declarator


10181
行,
cp_finish_decl

完成这个声明。因为它是在一个函数中的声明,在下面
4957
行,一个新的
DECL_STMT
被插入到对应的
stmt-tree
,之后我们得到如下的中间树。


点此打开



4786

void

4787

cp_finish_decl

(tree decl, tree init,
tree asmspec_tree, int flags)

in decl.c

4788

{

4789

tree type;

4790

tree ttype = NULL_TREE;

4791

tree cleanup;

4792

const
char
*asmspec = NULL;

4793

int was_readonly = 0;

4794

bool var_definition_p = false;

4795

4796

if (decl == error_mark_node)

4797

return
;

4798

else if (! decl)

4799

{

4800

if (init)

4801

error ("assignment (not
initialization) in declaration");

4802

return
;

4803

}

4804

4805

my_friendly_assert (TREE_CODE (decl) !=
RESULT_DECL, 20030619);



4821

type = TREE_TYPE (decl);



4844

/* Parameters are
handled by store_parm_decls, not cp_finish_decl.
*/

4845

my_friendly_assert (TREE_CODE (decl) !=
PARM_DECL, 19990828);



4953

/* Add this
declaration to the statement-tree. This needs to happen

4954

after the call to
check_initializer so that the DECL_STMT for a

4955

reference temp is added before
the DECL_STMT for the reference itself.

*/

4956

if (at_function_scope_p ())

4957

add_decl_stmt (decl);

4958

4959

if (TREE_CODE (decl) == VAR_DECL)

4960

layout_var_decl
(decl);

接下来需要由下面的
layout_var_decl

来完成该类型的定义。

4043

static
void

4044

layout_var_decl

(tree decl)

in decl.c

4045

{

4046

tree type = TREE_TYPE (decl);

4047

#if
0

4048

tree ttype = target_type (type);

4049

#endif

4050

4051

/* If we haven't
already layed out this declaration, do so now.

4052

Note that we must not call
complete type for an external object

4053

because it's type might
involve templates that we are not

4054

supposed to instantiate
yet.
(And it's perfectly valid to say

4055

`extern X x' for some
incomplete type `X'.)
*/

4056

if (!DECL_EXTERNAL (decl))

4057

complete_type
(type);

4058

if (!DECL_SIZE (decl)

4059

&& TREE_TYPE (decl) !=
error_mark_node

4060

&& (COMPLETE_TYPE_P (type)

4061

|| (TREE_CODE (type) == ARRAY_TYPE

4062

&& !TYPE_DOMAIN (type)

4063

&& COMPLETE_TYPE_P
(TREE_TYPE (type)))))

4064

layout_decl
(decl, 0);

4065

4066

if (!DECL_EXTERNAL (decl) &&
DECL_SIZE (decl) == NULL_TREE)

4067

{

4068

/* An automatic
variable with an incomplete type: that is an error.

4069

Don't talk about array types
here, since we took care of that

4070

message in
grokdeclarator.
*/

4071

error ("storage size of `%D' isn't
known", decl);

4072

TREE_TYPE (decl) = error_mark_node;

4073

}

4074

#if
0



4084

#endif

4085

4086

if ((DECL_EXTERNAL (decl) || TREE_STATIC
(decl))

4087

&& DECL_SIZE (decl) != NULL_TREE

4088

&& ! TREE_CONSTANT (DECL_SIZE
(decl)))

4089

{

4090

if (TREE_CODE (DECL_SIZE (decl)) ==
INTEGER_CST)

4091

constant_expression_warning (DECL_SIZE
(decl));

4092

else

4093

error ("storage size of `%D' isn't
constant", decl);

4094

}

4095

4096

if (TREE_STATIC (decl)

4097

&& !DECL_ARTIFICIAL (decl)

4098

&& current_function_decl

4099

&& DECL_CONTEXT (decl) == current_function_decl

)

4100

push_local_name
(decl);

4101

}

在这里,
type

是刚创建的
RECORD_TYPE
,而
decl

是一个非外部声明(
non-external declaration
)。因此
type

应该已经在这个编译单元中定义,现在可以完成其定义了。

116

tree

117

complete_type

(tree type)

in typeck.c

118

{

119

if (type == NULL_TREE)

120

/* Rather than
crash, we return something sure to cause an error

121

at some
point.
*/

122

return
error_mark_node;

123

124

if (type == error_mark_node ||
COMPLETE_TYPE_P (type))

125

;

126

else if (TREE_CODE (type) == ARRAY_TYPE
&& TYPE_DOMAIN (type))

127

{

128

tree t = complete_type (TREE_TYPE (type));

129

if (COMPLETE_TYPE_P (t) &&
!dependent_type_p (type))

130

layout_type (type);

131

TYPE_NEEDS_CONSTRUCTING (type)

132

= TYPE_NEEDS_CONSTRUCTING
(TYPE_MAIN_VARIANT (t));

133

TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)

134

= TYPE_HAS_NONTRIVIAL_DESTRUCTOR
(TYPE_MAIN_VARIANT (t));

135

}

136

else if (CLASS_TYPE_P (type)
&& CLASSTYPE_TEMPLATE_INSTANTIATION (type))

137

instantiate_class_template
(TYPE_MAIN_VARIANT (type));

138

139

return
type;

140

}

对于模板定义,在具现点生成一个新类型。该新类型的定义也在该点完毕(因为其
TREE_SIZE
域是
NULL
,这是一个不完整的类型)。

5274

tree

5275

instantiate_class_template

(tree type)

in pt.c

5276

{

5277

tree template, args, pattern, t, member;

5278

tree typedecl;

5279

tree pbinfo;

5280

5281

if (type == error_mark_node)

5282

return
error_mark_node;

5283

5284

if (TYPE_BEING_DEFINED (type)

5285

|| COMPLETE_TYPE_P (type)

5286

|| dependent_type_p (type))

5287

return
type;

5288

5289

/* Figure out which
template is being instantiated.
*/

5290

template = most_general_template
(CLASSTYPE_TI_TEMPLATE (type));

5291

my_friendly_assert (TREE_CODE (template) ==
TEMPLATE_DECL, 279);

5292

5293

/* Figure out which
arguments are being used to do the

5294

instantiation.
*/

5295

args = CLASSTYPE_TI_ARGS (type);

5296

5297

/* Determine what
specialization of the original template to

5298

instantiate.
*/

5299

t = most_specialized_class (template, args);

5300

if (t == error_mark_node)

5301

{



5315

}

5316

5317

if (t)

5318

pattern = TREE_TYPE (t);

5319

else

5320

pattern = TREE_TYPE (template);

5321

5322

/* If the template
we're instantiating is incomplete, then clearly

5323

there's nothing we can
do.
*/

5324

if (!COMPLETE_TYPE_P (pattern))

5325

return
type;

5326

5327

/* If we've
recursively instantiated too many templates, stop.
*/

5328

if (! push_tinst_level
(type))

5329

return
type;

5330

5331

/* Now we're really
doing the instantiation. Mark the type as in

5332

the process of being
defined.
*/

5333

TYPE_BEING_DEFINED (type) = 1;

注意到在上面的
5320
行,
pattern

指向最泛化模板所对应的
RECORD_TYPE
(也即模板定义中出现的“
SmallObject
”),其
TYPE_SIZE
域在
finish_struct

中被初始化为
bitsize_zero_node

size_zero_node

5299
行的
most_specialized_class

返回匹配的特化程度最高的定义,找不到或没有特化的定义则返回
NULL


虽然在理论上具现的层数是没有限制的,但是在实现中必须防止由于编程或者实现的失误而导致的无限模板具现。这样具现的层数必须是有限制的。在
GCC
,版本
3.4.6
中,全局变量
max_tinst_depth

保存这个限制。其值现在是
500


4850

int

4851

push_tinst_level

(tree d)

in pt.c

4852

{

4853

tree new;

4854

4855

if (tinst_depth

>= max_tinst_depth

)

4856

{

4857

/* If the
instantiation in question still has unbound template parms,

4858

we don't really care if we
can't instantiate it, so just return.

4859

This happens with base
instantiation for implicit `typename'.

*/

4860

if (uses_template_parms
(d))

4861

return
0;

4862

4863

last_template_error_tick

= tinst_level_tick

;

4864

error ("template instantiation depth
exceeds maximum of %d (use -ftemplate-depth-NN to increase the maximum)
instantiating `%D'",

4865

max_tinst_depth

, d);

4866

4867

print_instantiation_context ();

4868

4869

return
0;

4870

}

4871

4872

new = build_expr_wfl (d, input_filename,
input_line, 0);

4873

TREE_CHAIN (new) = current_tinst_level

;

4874

current_tinst_level

= new;

4875

4876

++tinst_depth

;

4877

#ifdef
GATHER_STATISTICS

4878

if (tinst_depth

> depth_reached

)

4879

depth_reached

= tinst_depth

;

4880

#endif

4881

4882

++tinst_level_tick

;

4883

return
1;

4884

}

上面在
4872
行,节点
EXPR_WITH_FILE_LOCATION
被构建来记录具现所在的文件及行数。并且这个节点被串接入全局链表
current_tinst_level

用于诊断的目的。

instantiate_class_template (continue)

5335

/* We may be in the
middle of deferred access check. Disable

5336

it now.
*/

5337

push_deferring_access_checks
(dk_no_deferred);

5338

5339

push_to_top_level
();

5340

5341

if (t)

5342

{



5367

}

5368

5369

SET_CLASSTYPE_INTERFACE_UNKNOWN (type);

5370

5371

/* Set the input
location to the template definition. This is needed

5372

if tsubsting causes an
error.
*/

5373

input_location = DECL_SOURCE_LOCATION
(TYPE_NAME (pattern));

5374

5375

TYPE_HAS_CONSTRUCTOR (type) =
TYPE_HAS_CONSTRUCTOR (pattern);

5376

TYPE_HAS_DESTRUCTOR (type) =
TYPE_HAS_DESTRUCTOR (pattern);

5377

TYPE_HAS_NEW_OPERATOR (type) =
TYPE_HAS_NEW_OPERATOR (pattern);

5378

TYPE_HAS_ARRAY_NEW_OPERATOR
(type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern);

5379

TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE
(pattern);

5380

TYPE_HAS_ASSIGN_REF (type) =
TYPE_HAS_ASSIGN_REF (pattern);

5381

TYPE_HAS_CONST_ASSIGN_REF
(type) = TYPE_HAS_CONST_ASSIGN_REF (pattern);

5382

TYPE_HAS_ABSTRACT_ASSIGN_REF
(type) = TYPE_HAS_ABSTRACT_ASSIGN_REF (pattern);

5383

TYPE_HAS_INIT_REF (type) = TYPE_HAS_INIT_REF
(pattern);

5384

TYPE_HAS_CONST_INIT_REF (type) =
TYPE_HAS_CONST_INIT_REF (pattern);

5385

TYPE_HAS_DEFAULT_CONSTRUCTOR
(type) = TYPE_HAS_DEFAULT_CONSTRUCTOR (pattern);

5386

TYPE_HAS_CONVERSION (type) =
TYPE_HAS_CONVERSION (pattern);

5387

TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)

5388

= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P
(pattern);

5389

TYPE_USES_MULTIPLE_INHERITANCE (type)

5390

= TYPE_USES_MULTIPLE_INHERITANCE (pattern);

5391

TYPE_USES_VIRTUAL_BASECLASSES (type)

5392

= TYPE_USES_VIRTUAL_BASECLASSES (pattern);

5393

TYPE_PACKED (type) = TYPE_PACKED (pattern);

5394

TYPE_ALIGN (type) = TYPE_ALIGN (pattern);

5395

TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN
(pattern);

5396

TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA
(pattern); /* For libjava's JArray<T> */

5397

if (ANON_AGGR_TYPE_P (pattern))

5398

SET_ANON_AGGR_TYPE_P (type);

注意上面的
pattern

对应着模板定义中的
RECORD_TYPE
,而
type

对应具现时刻产生的
RECORD_TYPE
。在具现的过程中,我们需要进入具现类型及其子类(如果有子类的话)的作用域,这将改变当前的作用域。因此在第一步,我们需要跑到绑定域的顶层——全局名字空间(
5339
行的
push_to_top_level

),并缓存当前的作用域层次,由下面的
push_scope


pushclass

为我们构建合适的上下文(注意这里的
type


pattern


context
都是“
Loki
”的
NAMESPACE_DECL
——具现的类型被视为在同一作用域下不同的变种)。

instantiate_class_template (continue)

5400

pbinfo = TYPE_BINFO (pattern);

5401

5402

#ifdef
ENABLE_CHECKING

5403

if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL
(pattern))

5404

&& ! COMPLETE_TYPE_P
(TYPE_CONTEXT (type))

5405

&& ! TYPE_BEING_DEFINED (TYPE_CONTEXT
(type)))

5406

/* We should
never instantiate a nested class before its enclosing

5407

class; we need to look up
the nested class by name before we can

5408

instantiate it, and that
lookup should instantiate the enclosing

5409

class.
*/

5410

abort ();

5411

#endif

5412

5413

if (BINFO_BASETYPES (pbinfo))

5414

{

5415

tree base_list = NULL_TREE;

5416

tree pbases = BINFO_BASETYPES (pbinfo);

5417

tree paccesses = BINFO_BASEACCESSES
(pbinfo);

5418

tree context = TYPE_CONTEXT (type);

5419

bool pop_p;

5420

int i;

5421

5422

/* We must enter
the scope containing the type, as that is where

5423

the accessibility of types
named in dependent bases are

5424

looked up from.
*/

5425

pop_p = push_scope (context ? context : global_namespace

);

5426

5427

/* Substitute
into each of the bases to determine the actual

5428

basetypes.
*/

5429

for
(i = 0;
i < TREE_VEC_LENGTH (pbases); ++i)

5430

{

5431

tree base;

5432

tree access;

5433

tree pbase;

5434

5435

pbase = TREE_VEC_ELT (pbases, i);

5436

access = TREE_VEC_ELT (paccesses, i);

5437

5438

/* Substitute
to figure out the base class.
*/

5439

base = tsubst (BINFO_TYPE (pbase), args,
tf_error, NULL_TREE);

5440

if (base == error_mark_node)

5441

continue
;

5442

5443

base_list = tree_cons (access, base,
base_list);

5444

TREE_VIA_VIRTUAL (base_list) =
TREE_VIA_VIRTUAL (pbase);

5445

}

5446

5447

/* The list is
now in reverse order; correct that.
*/

5448

base_list = nreverse (base_list);

5449

5450

/* Now call
xref_basetypes to set up all the base-class

5451

information.
*/

5452

xref_basetypes

(type, base_list);

5453

5454

if (pop_p)

5455

pop_scope (context ? context : global_namespace

);

5456

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