GCC-3.4.6源代码学习笔记(135)
2010-12-25 13:55
351 查看
5.12.5.2.2.2.1.3.2.
具现基类——完成
在处理完所有的基类后(基类被串接起来),在
instantiate_class_template
的
5452
行,调用
xref_basetype
来填充其
binfo
部分,其中实参
ref
是派生类的
RECORD_TYPE
,而
base_list
包含了基类的
RECORD_TYPE
,及其访问属性。
基类的
RECORD_TYPE
是尚未完成的,因为其
type
域是空的,因此它需要首先通过在
xref_basetype
9645
行的
complete_type_or_else
来完成这个域。
4210
#define
complete_type_or_else
(T,V)
(complete_type_or_diagnostic ((T), (V), 0))
147
tree
148
complete_type_or_diagnostic
(tree type,
tree value, int diag_type)
in typeck.c
149
{
150
type = complete_type (type);
151
if (type == error_mark_node)
152
/* We already
issued an error.
*/
153
return
NULL_TREE;
154
else if (!COMPLETE_TYPE_P (type))
155
{
156
cxx_incomplete_type_diagnostic (value,
type, diag_type);
157
return
NULL_TREE;
158
}
159
else
160
return
type;
161
}
看到在函数的开头,
complete_type
被递归调用(我们从为派生类调用的
complete_type
中来到这里)。在
complete_type
中,为基类亦调用了
instantiate_class_template
来对其具现。如果基类亦是从某个模板类派生,这个过程亦为该基类重复。直到找到最底层的模板类(我们现在只看到具现模板类的前半部分,在后半部分模板类要调用
finish_struct
来完成
RECORD_TYPE
节点),或者最底层非模板类(这样的类型已经调用过
finish_struct
,其
RECORD_TYPE
节点已经完成处理)。在这里我们跳过在
complete_type
中基类处理的细节,假定之后其
RECORD_TYPE
已经完成处理。
xref_basetype
的细节可以参考前面的章节,对于我们的例子,执行深拷贝,因为基类是一个
RECORD_TYPE
节点。我们得到如下的布局。
(
点此打开
)
5.12.5.2.2.2.1.3.3.
完成派生类的
RECORD_TYPE
–
成员的替代
现在基类的具现体已经就绪,并且该派生类的
binfo
也已设置,接下来需要填入该类的成员,因为这里的
type
是一个对应具现体的空的
RECORD_TYPE
。进一步的派生类中的某些成员可能依赖于模板参数,它们也需要进行实参替换。如何产生这些类型值得了解。该处理函数虽然长,但相当明白。
instantiate_class_template (continue)
5458
/* Now that our
base classes are set up, enter the scope of the
5459
class, so that name lookups
into base classes, etc. will work
5460
correctly. This is precisely
analogous to what we do in
5461
begin_class_definition when
defining an ordinary non-template
5462
class.
*/
5463
pushclass
(type);
5464
5465
/* Now members are
processed in the order of declaration.
*/
5466
for
(member =
CLASSTYPE_DECL_LIST (pattern);
5467
member; member = TREE_CHAIN (member))
5468
{
5469
tree t = TREE_VALUE (member);
5470
5471
if (TREE_PURPOSE (member))
5472
{
5473
if (TYPE_P (t))
5474
{
5475
/* Build new CLASSTYPE_NESTED_UTDS.
*/
5476
5477
tree tag = t;
5478
tree name = TYPE_IDENTIFIER (tag);
5479
tree newtag;
5480
bool class_template_p;
5481
5482
class_template_p = (TREE_CODE (tag) !=
ENUMERAL_TYPE
5483
&&
TYPE_LANG_SPECIFIC (tag)
5484
&&
CLASSTYPE_IS_TEMPLATE (tag));
5485
/* If the
member is a class template, then -- even after
5486
substituition -- there
may be dependent types in the
5487
template argument list
for the class. We increment
5488
PROCESSING_TEMPLATE_DECL
so that dependent_type_p, as
5489
that function will
assume that no types are dependent
5490
when outside of a
template.
*/
5491
if (class_template_p)
5492
++processing_template_decl;
5493
newtag = tsubst (tag, args, tf_error,
NULL_TREE);
5494
if (class_template_p)
5495
--processing_template_decl;
5496
if (newtag == error_mark_node)
5497
continue
;
5498
5499
if (TREE_CODE (newtag) !=
ENUMERAL_TYPE)
5500
{
5501
if (class_template_p)
5502
/*
Unfortunately, lookup_template_class sets
5503
CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
5504
instantiation
(i.e., for the type of a member
5505
template class
nested within a template class.)
5506
This behavior is
required for
5507
maybe_process_partial_specialization to work
5508
correctly, but is
not accurate in this case;
5509
the TAG is not an
instantiation of anything.
5510
(The corresponding
TEMPLATE_DECL is an
5511
instantiation, but
the TYPE is not.) */
5512
CLASSTYPE_USE_TEMPLATE (newtag) =
0;
5513
5514
/* Now, we
call pushtag to put this NEWTAG into the scope of
5515
TYPE. We first set up
the IDENTIFIER_TYPE_VALUE to avoid
5516
pushtag calling
push_template_decl. We don't have to do
5517
this for enums because
it will already have been done in
5518
tsubst_enum.
*/
5519
if (name)
5520
SET_IDENTIFIER_TYPE_VALUE (name,
newtag);
5521
pushtag
(name,
newtag, /*globalize=*/
0);
5522
}
5523
}
// end if (TYPE_P (t))
5524
else if (TREE_CODE (t) == FUNCTION_DECL
5525
|| DECL_FUNCTION_TEMPLATE_P (t))
5526
{
5527
/* Build new
TYPE_METHODS.
*/
5528
tree r;
5529
5530
if (TREE_CODE (t) == TEMPLATE_DECL)
5531
++processing_template_decl;
5532
r = tsubst (t, args, tf_error,
NULL_TREE);
5533
if (TREE_CODE (t) == TEMPLATE_DECL)
5534
--processing_template_decl;
5535
set_current_access_from_decl (r);
5536
grok_special_member_properties (r);
5537
finish_member_declaration
(r);
5538
}
5539
else
5540
{
5541
/* Build new TYPE_FIELDS.
*/
5542
5543
if (TREE_CODE (t) != CONST_DECL)
5544
{
5545
tree r;
5546
5547
/* The the file and line for this declaration,
to
5548
assist in error
message reporting. Since we
5549
called
push_tinst_level above, we don't need to
5550
restore these.
*/
5551
input_location
= DECL_SOURCE_LOCATION (t);
5552
5553
if (TREE_CODE (t) == TEMPLATE_DECL)
5554
++processing_template_decl;
5555
r = tsubst (t, args, tf_error |
tf_warning, NULL_TREE);
5556
if (TREE_CODE (t) == TEMPLATE_DECL)
5557
--processing_template_decl;
5558
if (TREE_CODE (r) == VAR_DECL)
5559
{
5560
tree init;
5561
5562
if (DECL_INITIALIZED_IN_CLASS_P
(r))
5563
init = tsubst_expr (DECL_INITIAL
(t), args,
5564
tf_error |
tf_warning, NULL_TREE);
5565
else
5566
init = NULL_TREE;
5567
5568
finish_static_data_member_decl
5569
(r, init, /*asmspec_tree=*/
NULL_TREE, /*flags=*/
0);
5570
5571
if (DECL_INITIALIZED_IN_CLASS_P
(r))
5572
check_static_variable_definition
(r, TREE_TYPE (r));
5573
}
5574
else if (TREE_CODE (r) == FIELD_DECL)
5575
{
5576
/*
Determine whether R has a valid type and can be
5577
completed later. If
R is invalid, then it is
5578
replaced by
error_mark_node so that it will not be
5579
added to
TYPE_FIELDS.
*/
5580
tree rtype = TREE_TYPE (r);
5581
if
(can_complete_type_without_circularity (rtype))
5582
complete_type
(rtype);
5583
5584
if (!COMPLETE_TYPE_P (rtype))
5585
{
5586
cxx_incomplete_type_error (r,
rtype);
5587
r = error_mark_node;
5588
}
5589
}
5590
5591
/* If it is
a TYPE_DECL for a class-scoped ENUMERAL_TYPE,
5592
such a thing will
already have been added to the field
5593
list by tsubst_enum in
finish_member_declaration in the
5594
CLASSTYPE_NESTED_UTDS
case above.
*/
5595
if (!(TREE_CODE (r) == TYPE_DECL
5596
&& TREE_CODE (TREE_TYPE
(r)) == ENUMERAL_TYPE
5597
&& DECL_ARTIFICIAL (r)))
5598
{
5599
set_current_access_from_decl (r);
5600
finish_member_declaration
(r);
5601
}
5602
}
5603
}
5604
}
// if (TREE_PURPOSE (member))
5605
else
5606
{
5607
if (TYPE_P (t) || DECL_CLASS_TEMPLATE_P
(t))
5608
{
5609
/* Build new
CLASSTYPE_FRIEND_CLASSES.
*/
5610
5611
tree friend_type = t;
5612
tree new_friend_type;
5613
5614
if (TREE_CODE (friend_type) ==
TEMPLATE_DECL)
5615
new_friend_type = tsubst_friend_class
(friend_type, args);
5616
else if (uses_template_parms
(friend_type))
5617
new_friend_type = tsubst
(friend_type, args,
5618
tf_error |
tf_warning, NULL_TREE);
5619
else if (CLASSTYPE_USE_TEMPLATE
(friend_type))
5620
new_friend_type = friend_type;
5621
else
5622
{
5623
tree ns = decl_namespace_context
(TYPE_MAIN_DECL
(friend_type));
5624
5625
/* The call
to xref_tag_from_type does injection for friend
5626
classes.
*/
5627
push_nested_namespace
(ns);
5628
new_friend_type =
5629
xref_tag_from_type (friend_type,
NULL_TREE, 1);
5630
pop_nested_namespace (ns);
5631
}
5632
5633
if (TREE_CODE (friend_type) ==
TEMPLATE_DECL)
5634
/* Trick
make_friend_class into realizing that the friend
5635
we're adding is a
template, not an ordinary class. It's
5636
important that we use
make_friend_class since it will
5637
perform some
error-checking and output cross-reference
5638
information.
*/
5639
++processing_template_decl;
5640
5641
if (new_friend_type != error_mark_node)
5642
make_friend_class (type,
new_friend_type,
5643
/*complain=*/
false);
5644
5645
if (TREE_CODE (friend_type) ==
TEMPLATE_DECL)
5646
--processing_template_decl;
5647
}
5648
else
5649
{
5650
/* Build new
DECL_FRIENDLIST.
*/
5651
tree r;
5652
5653
if (TREE_CODE (t) == TEMPLATE_DECL)
5654
++processing_template_decl;
5655
r = tsubst_friend_function (t, args);
5656
if (TREE_CODE (t) == TEMPLATE_DECL)
5657
--processing_template_decl;
5658
add_friend (type, r, /*complain=*/
false);
5659
}
5660
}
5661
}
5662
5663
/* Set the file and
line number information to whatever is given for
5664
the class itself. This puts
error messages involving generated
5665
implicit functions at a
predictable point, and the same point
5666
that would be used for
non-template classes.
*/
5667
typedecl = TYPE_MAIN_DECL (type);
5668
input_location
= DECL_SOURCE_LOCATION (typedecl);
5669
5670
unreverse_member_declarations
(type);
5671
finish_struct_1
(type);
注意到在该类中声明的成员被
CLASSTYPE_DECL_LIST
域以
tree_list
节点的形式记录起来。在这些
tree_list
节点中,
TREE_PURPOSE
域记录了其所属的类(如果是友元声明则是
NULL
),而
TREE_VALUE
域保存了声明本身。
在前面的章节中看到,在模板类中声明的实体亦被视为模板声明,连同产生
TEMPLATE_DECL
。在具现的过程中,模板实参将替换模板形参。
5.12.5.2.2.2.1.3.4.
完成派生类的
RECORD_TYPE
–
修正内联方法
因为模板类的具现对应的
RECORD_TYPE
是一个普通的类,在
5671
行必须调用
finish_struct_1
来完成其定义。
4997
void
4998
finish_struct_1
(tree t)
in class.c
4999
{
5001
tree x;
5002
/* A TREE_LIST. The
TREE_VALUE of each node is a FUNCTION_DECL.
*/
5003
tree virtuals = NULL_TREE;
5004
int n_fields = 0;
5005
tree vfield;
5006
5007
if (COMPLETE_TYPE_P (t))
5008
{
5009
if (IS_AGGR_TYPE (t))
5010
error ("redefinition of `%#T'",
t);
5011
else
5012
abort ();
5013
popclass ();
5014
return
;
5015
}
5016
5017
/* If this type was
previously laid out as a forward reference,
5018
make sure we lay it out
again.
*/
5019
TYPE_SIZE (t) = NULL_TREE;
5020
CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
5021
5022
fixup_inline_methods
(t);
5023
5024
/* Make assumptions
about the class; we'll reset the flags if
5025
necessary.
*/
5026
CLASSTYPE_EMPTY_P (t) = 1;
5027
CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
5028
CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0;
5029
5030
/* Do end-of-class
semantic processing: checking the validity of the
5031
bases and members and add
implicitly generated methods.
*/
5032
check_bases_and_members
(t);
同样,记得对于内联方法,在对应的
FUNCTION_DECL
节点中,其
template_info
域填充有模板信息。上面的成员替换为成员正确地进行了实参替换,但是某些关系尚未相应地更新。
4323
static
void
4324
fixup_inline_methods
(tree type)
in class.
4325
{
4326
tree method = TYPE_METHODS (type);
4327
4328
if (method && TREE_CODE (method) ==
TREE_VEC)
4329
{
4330
if (TREE_VEC_ELT (method, 1))
4331
method = TREE_VEC_ELT (method, 1);
4332
else if (TREE_VEC_ELT (method, 0))
4333
method = TREE_VEC_ELT (method, 0);
4334
else
4335
method = TREE_VEC_ELT (method, 2);
4336
}
4337
4338
/* Do inline member
functions.
*/
4339
for
(;
method; method = TREE_CHAIN (method))
4340
fixup_pending_inline
(method);
4341
4342
/* Do friends.
*/
4343
for
(method =
CLASSTYPE_INLINE_FRIENDS (type);
4344
method;
4345
method = TREE_CHAIN (method))
4346
fixup_pending_inline (TREE_VALUE (method));
4347
CLASSTYPE_INLINE_FRIENDS (type) = NULL_TREE;
4348
}
记得内联方法的函数体被缓存在
DECL_PENDING_INLINE_INFO
中。在具现时,内联方法的实参已经被替换入其函数体,但其
context
域并未触及,在完成替换后,需要为内联方法将其更新(构建的新节点)。
4306
static
void
4307
fixup_pending_inline
(tree fn)
in class.
4308
{
4309
if (DECL_PENDING_INLINE_INFO (fn))
4310
{
4311
tree args = DECL_ARGUMENTS (fn);
4312
while
(args)
4313
{
4314
DECL_CONTEXT (args) = fn;
4315
args = TREE_CHAIN (args);
4316
}
4317
}
4318
}
5.12.5.2.2.2.1.3.5.
完成派生类的
RECORD_TYPE
–
验证基类
在这一点上,基类及成员的实参替换被恰当地完成了,不过没有对模板的具现进行类级别的语义检查。这个语义检查应尽快进行。这里就是尽早执行语义检查的点。
4145
static
void
4146
check_bases_and_members
(tree t)
in class.c
4147
{
4148
/* Nonzero if we
are not allowed to generate a default constructor
4149
for this case.
*/
4150
int cant_have_default_ctor;
4151
/* Nonzero if the
implicitly generated copy constructor should take
4152
a non-const reference argument.
*/
4153
int cant_have_const_ctor;
4154
/* Nonzero if the
the implicitly generated assignment operator
4155
should take a non-const
reference argument.
*/
4156
int no_const_asn_ref;
4157
tree access_decls;
4158
4159
/* By default, we
use const reference arguments and generate default
4160
constructors.
*/
4161
cant_have_default_ctor = 0;
4162
cant_have_const_ctor = 0;
4163
no_const_asn_ref = 0;
4164
4165
/* Check all the
base-classes.
*/
4166
check_bases
(t,
&cant_have_default_ctor, &cant_have_const_ctor,
4167
&no_const_asn_ref);
如果模板类包含(派生)基类(记得基类也可以是模板类,比如我们的“
SmallObject
”),是时候检查派生类与基类间是否有不符合的地方。
1109
static
void
1110
check_bases
(tree t,
in class.c
1111
int* cant_have_default_ctor_p,
1112
int* cant_have_const_ctor_p,
1113
int* no_const_asn_ref_p)
1114
{
1115
int n_baseclasses;
1116
int i;
1117
int seen_non_virtual_nearly_empty_base_p;
1118
tree binfos;
1119
1120
binfos = TYPE_BINFO_BASETYPES (t);
1121
n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
1122
seen_non_virtual_nearly_empty_base_p = 0;
1123
1124
/* An aggregate
cannot have baseclasses.
*/
1125
CLASSTYPE_NON_AGGREGATE (t) |= (n_baseclasses !=
0);
1126
1127
for
(i = 0; i < n_baseclasses; ++i)
1128
{
1129
tree base_binfo;
1130
tree basetype;
1131
1132
/* Figure out
what base we're looking at.
*/
1133
base_binfo = TREE_VEC_ELT (binfos, i);
1134
basetype = TREE_TYPE (base_binfo);
1135
1136
/* If the type of
basetype is incomplete, then we already
1137
complained about that fact
(and we should have fixed it up as
1138
well).
*/
1139
if (!COMPLETE_TYPE_P (basetype))
1140
{
1141
int j;
1142
/* The base
type is of incomplete type. It is
1143
probably best to pretend
that it does not
1144
exist.
*/
1145
if (i == n_baseclasses-1)
1146
TREE_VEC_ELT (binfos, i) = NULL_TREE;
1147
TREE_VEC_LENGTH (binfos) -= 1;
1148
n_baseclasses -= 1;
1149
for
(j = i; j+1 < n_baseclasses; j++)
1150
TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1);
1151
continue
;
1152
}
1153
1154
/* Effective C++
rule 14. We only need to check TYPE_POLYMORPHIC_P
1155
here because the case of
virtual functions but non-virtual
1156
dtor is handled in
finish_struct_1.
*/
1157
if (warn_ecpp
&& ! TYPE_POLYMORPHIC_P
(basetype)
1158
&& TYPE_HAS_DESTRUCTOR
(basetype))
1159
warning ("base class `%#T' has a
non-virtual destructor",
1160
basetype);
1161
1162
/* If the base
class doesn't have copy constructors or
1163
assignment operators that
take const references, then the
1164
derived class cannot have
such a member automatically
1165
generated.
*/
1166
if (! TYPE_HAS_CONST_INIT_REF (basetype))
1167
*cant_have_const_ctor_p = 1;
1168
if (TYPE_HAS_ASSIGN_REF (basetype)
1169
&& !TYPE_HAS_CONST_ASSIGN_REF
(basetype))
1170
*no_const_asn_ref_p = 1;
1171
/* Similarly, if
the base class doesn't have a default
1172
constructor, then the derived
class won't have an
1173
automatically generated
default constructor.
*/
1174
if (TYPE_HAS_CONSTRUCTOR (basetype)
1175
&& !
TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype))
1176
{
1177
*cant_have_default_ctor_p = 1;
1178
if (! TYPE_HAS_CONSTRUCTOR (t))
1179
pedwarn ("base
`%T' with only non-default constructor in class without a constructor",
1180
basetype);
1181
}
1182
1183
if (TREE_VIA_VIRTUAL (base_binfo))
1184
/* A virtual
base does not effect nearly emptiness.
*/
1185
;
1186
else if (CLASSTYPE_NEARLY_EMPTY_P
(basetype))
1187
{
1188
if (seen_non_virtual_nearly_empty_base_p)
1189
/* And if
there is more than one nearly empty base, then the
1190
derived class is not nearly empty either.
*/
1191
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
1192
else
1193
/* Remember
we've seen one.
*/
1194
seen_non_virtual_nearly_empty_base_p =
1;
1195
}
1196
else if (!is_empty_class (basetype))
1197
/* If the base
class is not empty or nearly empty, then this
1198
class cannot be nearly
empty.
*/
1199
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
1200
1201
/* A lot of
properties from the bases also apply to the derived
1202
class.
*/
1203
TYPE_NEEDS_CONSTRUCTING
(t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
1204
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
1205
|= TYPE_HAS_NONTRIVIAL_DESTRUCTOR
(basetype);
1206
TYPE_HAS_COMPLEX_ASSIGN_REF (t)
1207
|= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);
1208
TYPE_HAS_COMPLEX_INIT_REF
(t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype);
1209
TYPE_POLYMORPHIC_P (t) |=
TYPE_POLYMORPHIC_P (basetype);
1210
CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
1211
|= CLASSTYPE_CONTAINS_EMPTY_CLASS_P
(basetype);
1212
}
1213
}
在该次调用的实参中,
cant_have_default_ctor
是非
0
值,如果基类没有缺省构造函数;
cant_have_const_ctor
是非
0
值,如果基类没有使用引用常量的拷贝构造函数,而
no_const_asn_ref
是非
0
值,如果基类没有使用引用常量的赋值操作符。
具现基类——完成
在处理完所有的基类后(基类被串接起来),在
instantiate_class_template
的
5452
行,调用
xref_basetype
来填充其
binfo
部分,其中实参
ref
是派生类的
RECORD_TYPE
,而
base_list
包含了基类的
RECORD_TYPE
,及其访问属性。
基类的
RECORD_TYPE
是尚未完成的,因为其
type
域是空的,因此它需要首先通过在
xref_basetype
9645
行的
complete_type_or_else
来完成这个域。
4210
#define
complete_type_or_else
(T,V)
(complete_type_or_diagnostic ((T), (V), 0))
147
tree
148
complete_type_or_diagnostic
(tree type,
tree value, int diag_type)
in typeck.c
149
{
150
type = complete_type (type);
151
if (type == error_mark_node)
152
/* We already
issued an error.
*/
153
return
NULL_TREE;
154
else if (!COMPLETE_TYPE_P (type))
155
{
156
cxx_incomplete_type_diagnostic (value,
type, diag_type);
157
return
NULL_TREE;
158
}
159
else
160
return
type;
161
}
看到在函数的开头,
complete_type
被递归调用(我们从为派生类调用的
complete_type
中来到这里)。在
complete_type
中,为基类亦调用了
instantiate_class_template
来对其具现。如果基类亦是从某个模板类派生,这个过程亦为该基类重复。直到找到最底层的模板类(我们现在只看到具现模板类的前半部分,在后半部分模板类要调用
finish_struct
来完成
RECORD_TYPE
节点),或者最底层非模板类(这样的类型已经调用过
finish_struct
,其
RECORD_TYPE
节点已经完成处理)。在这里我们跳过在
complete_type
中基类处理的细节,假定之后其
RECORD_TYPE
已经完成处理。
xref_basetype
的细节可以参考前面的章节,对于我们的例子,执行深拷贝,因为基类是一个
RECORD_TYPE
节点。我们得到如下的布局。
(
点此打开
)
5.12.5.2.2.2.1.3.3.
完成派生类的
RECORD_TYPE
–
成员的替代
现在基类的具现体已经就绪,并且该派生类的
binfo
也已设置,接下来需要填入该类的成员,因为这里的
type
是一个对应具现体的空的
RECORD_TYPE
。进一步的派生类中的某些成员可能依赖于模板参数,它们也需要进行实参替换。如何产生这些类型值得了解。该处理函数虽然长,但相当明白。
instantiate_class_template (continue)
5458
/* Now that our
base classes are set up, enter the scope of the
5459
class, so that name lookups
into base classes, etc. will work
5460
correctly. This is precisely
analogous to what we do in
5461
begin_class_definition when
defining an ordinary non-template
5462
class.
*/
5463
pushclass
(type);
5464
5465
/* Now members are
processed in the order of declaration.
*/
5466
for
(member =
CLASSTYPE_DECL_LIST (pattern);
5467
member; member = TREE_CHAIN (member))
5468
{
5469
tree t = TREE_VALUE (member);
5470
5471
if (TREE_PURPOSE (member))
5472
{
5473
if (TYPE_P (t))
5474
{
5475
/* Build new CLASSTYPE_NESTED_UTDS.
*/
5476
5477
tree tag = t;
5478
tree name = TYPE_IDENTIFIER (tag);
5479
tree newtag;
5480
bool class_template_p;
5481
5482
class_template_p = (TREE_CODE (tag) !=
ENUMERAL_TYPE
5483
&&
TYPE_LANG_SPECIFIC (tag)
5484
&&
CLASSTYPE_IS_TEMPLATE (tag));
5485
/* If the
member is a class template, then -- even after
5486
substituition -- there
may be dependent types in the
5487
template argument list
for the class. We increment
5488
PROCESSING_TEMPLATE_DECL
so that dependent_type_p, as
5489
that function will
assume that no types are dependent
5490
when outside of a
template.
*/
5491
if (class_template_p)
5492
++processing_template_decl;
5493
newtag = tsubst (tag, args, tf_error,
NULL_TREE);
5494
if (class_template_p)
5495
--processing_template_decl;
5496
if (newtag == error_mark_node)
5497
continue
;
5498
5499
if (TREE_CODE (newtag) !=
ENUMERAL_TYPE)
5500
{
5501
if (class_template_p)
5502
/*
Unfortunately, lookup_template_class sets
5503
CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
5504
instantiation
(i.e., for the type of a member
5505
template class
nested within a template class.)
5506
This behavior is
required for
5507
maybe_process_partial_specialization to work
5508
correctly, but is
not accurate in this case;
5509
the TAG is not an
instantiation of anything.
5510
(The corresponding
TEMPLATE_DECL is an
5511
instantiation, but
the TYPE is not.) */
5512
CLASSTYPE_USE_TEMPLATE (newtag) =
0;
5513
5514
/* Now, we
call pushtag to put this NEWTAG into the scope of
5515
TYPE. We first set up
the IDENTIFIER_TYPE_VALUE to avoid
5516
pushtag calling
push_template_decl. We don't have to do
5517
this for enums because
it will already have been done in
5518
tsubst_enum.
*/
5519
if (name)
5520
SET_IDENTIFIER_TYPE_VALUE (name,
newtag);
5521
pushtag
(name,
newtag, /*globalize=*/
0);
5522
}
5523
}
// end if (TYPE_P (t))
5524
else if (TREE_CODE (t) == FUNCTION_DECL
5525
|| DECL_FUNCTION_TEMPLATE_P (t))
5526
{
5527
/* Build new
TYPE_METHODS.
*/
5528
tree r;
5529
5530
if (TREE_CODE (t) == TEMPLATE_DECL)
5531
++processing_template_decl;
5532
r = tsubst (t, args, tf_error,
NULL_TREE);
5533
if (TREE_CODE (t) == TEMPLATE_DECL)
5534
--processing_template_decl;
5535
set_current_access_from_decl (r);
5536
grok_special_member_properties (r);
5537
finish_member_declaration
(r);
5538
}
5539
else
5540
{
5541
/* Build new TYPE_FIELDS.
*/
5542
5543
if (TREE_CODE (t) != CONST_DECL)
5544
{
5545
tree r;
5546
5547
/* The the file and line for this declaration,
to
5548
assist in error
message reporting. Since we
5549
called
push_tinst_level above, we don't need to
5550
restore these.
*/
5551
input_location
= DECL_SOURCE_LOCATION (t);
5552
5553
if (TREE_CODE (t) == TEMPLATE_DECL)
5554
++processing_template_decl;
5555
r = tsubst (t, args, tf_error |
tf_warning, NULL_TREE);
5556
if (TREE_CODE (t) == TEMPLATE_DECL)
5557
--processing_template_decl;
5558
if (TREE_CODE (r) == VAR_DECL)
5559
{
5560
tree init;
5561
5562
if (DECL_INITIALIZED_IN_CLASS_P
(r))
5563
init = tsubst_expr (DECL_INITIAL
(t), args,
5564
tf_error |
tf_warning, NULL_TREE);
5565
else
5566
init = NULL_TREE;
5567
5568
finish_static_data_member_decl
5569
(r, init, /*asmspec_tree=*/
NULL_TREE, /*flags=*/
0);
5570
5571
if (DECL_INITIALIZED_IN_CLASS_P
(r))
5572
check_static_variable_definition
(r, TREE_TYPE (r));
5573
}
5574
else if (TREE_CODE (r) == FIELD_DECL)
5575
{
5576
/*
Determine whether R has a valid type and can be
5577
completed later. If
R is invalid, then it is
5578
replaced by
error_mark_node so that it will not be
5579
added to
TYPE_FIELDS.
*/
5580
tree rtype = TREE_TYPE (r);
5581
if
(can_complete_type_without_circularity (rtype))
5582
complete_type
(rtype);
5583
5584
if (!COMPLETE_TYPE_P (rtype))
5585
{
5586
cxx_incomplete_type_error (r,
rtype);
5587
r = error_mark_node;
5588
}
5589
}
5590
5591
/* If it is
a TYPE_DECL for a class-scoped ENUMERAL_TYPE,
5592
such a thing will
already have been added to the field
5593
list by tsubst_enum in
finish_member_declaration in the
5594
CLASSTYPE_NESTED_UTDS
case above.
*/
5595
if (!(TREE_CODE (r) == TYPE_DECL
5596
&& TREE_CODE (TREE_TYPE
(r)) == ENUMERAL_TYPE
5597
&& DECL_ARTIFICIAL (r)))
5598
{
5599
set_current_access_from_decl (r);
5600
finish_member_declaration
(r);
5601
}
5602
}
5603
}
5604
}
// if (TREE_PURPOSE (member))
5605
else
5606
{
5607
if (TYPE_P (t) || DECL_CLASS_TEMPLATE_P
(t))
5608
{
5609
/* Build new
CLASSTYPE_FRIEND_CLASSES.
*/
5610
5611
tree friend_type = t;
5612
tree new_friend_type;
5613
5614
if (TREE_CODE (friend_type) ==
TEMPLATE_DECL)
5615
new_friend_type = tsubst_friend_class
(friend_type, args);
5616
else if (uses_template_parms
(friend_type))
5617
new_friend_type = tsubst
(friend_type, args,
5618
tf_error |
tf_warning, NULL_TREE);
5619
else if (CLASSTYPE_USE_TEMPLATE
(friend_type))
5620
new_friend_type = friend_type;
5621
else
5622
{
5623
tree ns = decl_namespace_context
(TYPE_MAIN_DECL
(friend_type));
5624
5625
/* The call
to xref_tag_from_type does injection for friend
5626
classes.
*/
5627
push_nested_namespace
(ns);
5628
new_friend_type =
5629
xref_tag_from_type (friend_type,
NULL_TREE, 1);
5630
pop_nested_namespace (ns);
5631
}
5632
5633
if (TREE_CODE (friend_type) ==
TEMPLATE_DECL)
5634
/* Trick
make_friend_class into realizing that the friend
5635
we're adding is a
template, not an ordinary class. It's
5636
important that we use
make_friend_class since it will
5637
perform some
error-checking and output cross-reference
5638
information.
*/
5639
++processing_template_decl;
5640
5641
if (new_friend_type != error_mark_node)
5642
make_friend_class (type,
new_friend_type,
5643
/*complain=*/
false);
5644
5645
if (TREE_CODE (friend_type) ==
TEMPLATE_DECL)
5646
--processing_template_decl;
5647
}
5648
else
5649
{
5650
/* Build new
DECL_FRIENDLIST.
*/
5651
tree r;
5652
5653
if (TREE_CODE (t) == TEMPLATE_DECL)
5654
++processing_template_decl;
5655
r = tsubst_friend_function (t, args);
5656
if (TREE_CODE (t) == TEMPLATE_DECL)
5657
--processing_template_decl;
5658
add_friend (type, r, /*complain=*/
false);
5659
}
5660
}
5661
}
5662
5663
/* Set the file and
line number information to whatever is given for
5664
the class itself. This puts
error messages involving generated
5665
implicit functions at a
predictable point, and the same point
5666
that would be used for
non-template classes.
*/
5667
typedecl = TYPE_MAIN_DECL (type);
5668
input_location
= DECL_SOURCE_LOCATION (typedecl);
5669
5670
unreverse_member_declarations
(type);
5671
finish_struct_1
(type);
注意到在该类中声明的成员被
CLASSTYPE_DECL_LIST
域以
tree_list
节点的形式记录起来。在这些
tree_list
节点中,
TREE_PURPOSE
域记录了其所属的类(如果是友元声明则是
NULL
),而
TREE_VALUE
域保存了声明本身。
在前面的章节中看到,在模板类中声明的实体亦被视为模板声明,连同产生
TEMPLATE_DECL
。在具现的过程中,模板实参将替换模板形参。
5.12.5.2.2.2.1.3.4.
完成派生类的
RECORD_TYPE
–
修正内联方法
因为模板类的具现对应的
RECORD_TYPE
是一个普通的类,在
5671
行必须调用
finish_struct_1
来完成其定义。
4997
void
4998
finish_struct_1
(tree t)
in class.c
4999
{
5001
tree x;
5002
/* A TREE_LIST. The
TREE_VALUE of each node is a FUNCTION_DECL.
*/
5003
tree virtuals = NULL_TREE;
5004
int n_fields = 0;
5005
tree vfield;
5006
5007
if (COMPLETE_TYPE_P (t))
5008
{
5009
if (IS_AGGR_TYPE (t))
5010
error ("redefinition of `%#T'",
t);
5011
else
5012
abort ();
5013
popclass ();
5014
return
;
5015
}
5016
5017
/* If this type was
previously laid out as a forward reference,
5018
make sure we lay it out
again.
*/
5019
TYPE_SIZE (t) = NULL_TREE;
5020
CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
5021
5022
fixup_inline_methods
(t);
5023
5024
/* Make assumptions
about the class; we'll reset the flags if
5025
necessary.
*/
5026
CLASSTYPE_EMPTY_P (t) = 1;
5027
CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
5028
CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0;
5029
5030
/* Do end-of-class
semantic processing: checking the validity of the
5031
bases and members and add
implicitly generated methods.
*/
5032
check_bases_and_members
(t);
同样,记得对于内联方法,在对应的
FUNCTION_DECL
节点中,其
template_info
域填充有模板信息。上面的成员替换为成员正确地进行了实参替换,但是某些关系尚未相应地更新。
4323
static
void
4324
fixup_inline_methods
(tree type)
in class.
4325
{
4326
tree method = TYPE_METHODS (type);
4327
4328
if (method && TREE_CODE (method) ==
TREE_VEC)
4329
{
4330
if (TREE_VEC_ELT (method, 1))
4331
method = TREE_VEC_ELT (method, 1);
4332
else if (TREE_VEC_ELT (method, 0))
4333
method = TREE_VEC_ELT (method, 0);
4334
else
4335
method = TREE_VEC_ELT (method, 2);
4336
}
4337
4338
/* Do inline member
functions.
*/
4339
for
(;
method; method = TREE_CHAIN (method))
4340
fixup_pending_inline
(method);
4341
4342
/* Do friends.
*/
4343
for
(method =
CLASSTYPE_INLINE_FRIENDS (type);
4344
method;
4345
method = TREE_CHAIN (method))
4346
fixup_pending_inline (TREE_VALUE (method));
4347
CLASSTYPE_INLINE_FRIENDS (type) = NULL_TREE;
4348
}
记得内联方法的函数体被缓存在
DECL_PENDING_INLINE_INFO
中。在具现时,内联方法的实参已经被替换入其函数体,但其
context
域并未触及,在完成替换后,需要为内联方法将其更新(构建的新节点)。
4306
static
void
4307
fixup_pending_inline
(tree fn)
in class.
4308
{
4309
if (DECL_PENDING_INLINE_INFO (fn))
4310
{
4311
tree args = DECL_ARGUMENTS (fn);
4312
while
(args)
4313
{
4314
DECL_CONTEXT (args) = fn;
4315
args = TREE_CHAIN (args);
4316
}
4317
}
4318
}
5.12.5.2.2.2.1.3.5.
完成派生类的
RECORD_TYPE
–
验证基类
在这一点上,基类及成员的实参替换被恰当地完成了,不过没有对模板的具现进行类级别的语义检查。这个语义检查应尽快进行。这里就是尽早执行语义检查的点。
4145
static
void
4146
check_bases_and_members
(tree t)
in class.c
4147
{
4148
/* Nonzero if we
are not allowed to generate a default constructor
4149
for this case.
*/
4150
int cant_have_default_ctor;
4151
/* Nonzero if the
implicitly generated copy constructor should take
4152
a non-const reference argument.
*/
4153
int cant_have_const_ctor;
4154
/* Nonzero if the
the implicitly generated assignment operator
4155
should take a non-const
reference argument.
*/
4156
int no_const_asn_ref;
4157
tree access_decls;
4158
4159
/* By default, we
use const reference arguments and generate default
4160
constructors.
*/
4161
cant_have_default_ctor = 0;
4162
cant_have_const_ctor = 0;
4163
no_const_asn_ref = 0;
4164
4165
/* Check all the
base-classes.
*/
4166
check_bases
(t,
&cant_have_default_ctor, &cant_have_const_ctor,
4167
&no_const_asn_ref);
如果模板类包含(派生)基类(记得基类也可以是模板类,比如我们的“
SmallObject
”),是时候检查派生类与基类间是否有不符合的地方。
1109
static
void
1110
check_bases
(tree t,
in class.c
1111
int* cant_have_default_ctor_p,
1112
int* cant_have_const_ctor_p,
1113
int* no_const_asn_ref_p)
1114
{
1115
int n_baseclasses;
1116
int i;
1117
int seen_non_virtual_nearly_empty_base_p;
1118
tree binfos;
1119
1120
binfos = TYPE_BINFO_BASETYPES (t);
1121
n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
1122
seen_non_virtual_nearly_empty_base_p = 0;
1123
1124
/* An aggregate
cannot have baseclasses.
*/
1125
CLASSTYPE_NON_AGGREGATE (t) |= (n_baseclasses !=
0);
1126
1127
for
(i = 0; i < n_baseclasses; ++i)
1128
{
1129
tree base_binfo;
1130
tree basetype;
1131
1132
/* Figure out
what base we're looking at.
*/
1133
base_binfo = TREE_VEC_ELT (binfos, i);
1134
basetype = TREE_TYPE (base_binfo);
1135
1136
/* If the type of
basetype is incomplete, then we already
1137
complained about that fact
(and we should have fixed it up as
1138
well).
*/
1139
if (!COMPLETE_TYPE_P (basetype))
1140
{
1141
int j;
1142
/* The base
type is of incomplete type. It is
1143
probably best to pretend
that it does not
1144
exist.
*/
1145
if (i == n_baseclasses-1)
1146
TREE_VEC_ELT (binfos, i) = NULL_TREE;
1147
TREE_VEC_LENGTH (binfos) -= 1;
1148
n_baseclasses -= 1;
1149
for
(j = i; j+1 < n_baseclasses; j++)
1150
TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1);
1151
continue
;
1152
}
1153
1154
/* Effective C++
rule 14. We only need to check TYPE_POLYMORPHIC_P
1155
here because the case of
virtual functions but non-virtual
1156
dtor is handled in
finish_struct_1.
*/
1157
if (warn_ecpp
&& ! TYPE_POLYMORPHIC_P
(basetype)
1158
&& TYPE_HAS_DESTRUCTOR
(basetype))
1159
warning ("base class `%#T' has a
non-virtual destructor",
1160
basetype);
1161
1162
/* If the base
class doesn't have copy constructors or
1163
assignment operators that
take const references, then the
1164
derived class cannot have
such a member automatically
1165
generated.
*/
1166
if (! TYPE_HAS_CONST_INIT_REF (basetype))
1167
*cant_have_const_ctor_p = 1;
1168
if (TYPE_HAS_ASSIGN_REF (basetype)
1169
&& !TYPE_HAS_CONST_ASSIGN_REF
(basetype))
1170
*no_const_asn_ref_p = 1;
1171
/* Similarly, if
the base class doesn't have a default
1172
constructor, then the derived
class won't have an
1173
automatically generated
default constructor.
*/
1174
if (TYPE_HAS_CONSTRUCTOR (basetype)
1175
&& !
TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype))
1176
{
1177
*cant_have_default_ctor_p = 1;
1178
if (! TYPE_HAS_CONSTRUCTOR (t))
1179
pedwarn ("base
`%T' with only non-default constructor in class without a constructor",
1180
basetype);
1181
}
1182
1183
if (TREE_VIA_VIRTUAL (base_binfo))
1184
/* A virtual
base does not effect nearly emptiness.
*/
1185
;
1186
else if (CLASSTYPE_NEARLY_EMPTY_P
(basetype))
1187
{
1188
if (seen_non_virtual_nearly_empty_base_p)
1189
/* And if
there is more than one nearly empty base, then the
1190
derived class is not nearly empty either.
*/
1191
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
1192
else
1193
/* Remember
we've seen one.
*/
1194
seen_non_virtual_nearly_empty_base_p =
1;
1195
}
1196
else if (!is_empty_class (basetype))
1197
/* If the base
class is not empty or nearly empty, then this
1198
class cannot be nearly
empty.
*/
1199
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
1200
1201
/* A lot of
properties from the bases also apply to the derived
1202
class.
*/
1203
TYPE_NEEDS_CONSTRUCTING
(t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
1204
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
1205
|= TYPE_HAS_NONTRIVIAL_DESTRUCTOR
(basetype);
1206
TYPE_HAS_COMPLEX_ASSIGN_REF (t)
1207
|= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);
1208
TYPE_HAS_COMPLEX_INIT_REF
(t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype);
1209
TYPE_POLYMORPHIC_P (t) |=
TYPE_POLYMORPHIC_P (basetype);
1210
CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
1211
|= CLASSTYPE_CONTAINS_EMPTY_CLASS_P
(basetype);
1212
}
1213
}
在该次调用的实参中,
cant_have_default_ctor
是非
0
值,如果基类没有缺省构造函数;
cant_have_const_ctor
是非
0
值,如果基类没有使用引用常量的拷贝构造函数,而
no_const_asn_ref
是非
0
值,如果基类没有使用引用常量的赋值操作符。
相关文章推荐
- GCC-3.4.6源代码学习笔记(5)
- GCC-3.4.6源代码学习笔记(33)
- GCC-3.4.6源代码学习笔记(68)
- GCC-3.4.6源代码学习笔记(17)
- GCC-3.4.6源代码学习笔记(174)
- GCC-3.4.6源代码学习笔记(19)
- GCC-3.4.6源代码学习笔记(122)
- GCC-3.4.6源代码学习笔记(126)
- GCC-3.4.6源代码学习笔记(153)
- GCC-3.4.6源代码学习笔记 (106)
- GCC-3.4.6源代码学习笔记(26)
- GCC-3.4.6源代码学习笔记(57)
- GCC-3.4.6源代码学习笔记(26续2)
- GCC-3.4.6源代码学习笔记(59)
- GCC-3.4.6源代码学习笔记(10续1)
- GCC-3.4.6源代码学习笔记(168)
- GCC-3.4.6源代码学习笔记(47)
- GCC-3.4.6源代码学习笔记(142-续1)
- GCC-3.4.6源代码学习笔记(69)
- GCC-3.4.6源代码学习笔记(147-续1)