您的位置:首页 > 其它

Studying note of GCC-3.4.6 source (135)

2010-12-25 13:59 435 查看
5.12.5.2.2.2.1.3.2.


Instantiate
base class – finish


After processing the bases (they are chained tegother), in instantiate_class_template

at line 5452, xref_basetype

is called to fill the binfo part, in which parameter ref

is the RECORD_TYPE of the
derived, and base_list

contains the RECORD_TYPE of the bases and their accessbility.

The RECORD_TYPE of base is incomplete as the type

field is empty, so it needs be
completed first by complete_type_or_else

at line 9645 in xref_basetype

.

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

}

See complete_type

is recursed at the beginning the function
(we come here inside the complete_type

called
for the derived), in which also calls instantiate_class_template

to instantiate the
base. If the base also derives from certain template class, this procedure
would be repeated till arrives at the bottom template class (we just see the
first part of the instantiating, in the rear part the template will invoke finish_struct

to complete its RECORD_TYPE), or the bottom non-template class (such type has
invoked finsih_struct

,
its RECORD_TYPE is complete). Here we just skip the detail of the handling of
the base class in complete_type

and assume this node of
RECORD_TYPE is completed after that.

The detail of xref_basetype

can be seen in previous section, for our case, real deep copy is executed as
base class is a node of RECORD_TYPE. And it gets following layout.

(Click
here for open
)

5.12.5.2.2.2.1.3.3.


Finish the derived
RECORD_TYPE –members subsititution


Now the instantiation of base class is ready, and the binfo of the
derived is setup, following it needs fill in the member of the class as type

here is an empty RECORD_TYPE for the instantiation. Further the member of the
derived class as some of them may depend on the template parameters, so they
need be subsitituted by the arguments too. It’s worth our attention to see how
to generate these types. The function though is lengthy but quite straight
forward.

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);

Notice that members declared within the class are recorded by node
of tree_list and chained in field of CLASSTYPE_DECL_LIST. In the tree_list
node, TREE_PURPOSE field records the class it belongs to (and NULL if it is the
friend declaration), and TREE_VALUE field holds the declaration itself.

Also see in previous sections, entities declared within the class
template are considered as template declarations too, with TEMPLATE_DECL
generated. During instantiation, the real template arguments should substitute
the template parameters.

5.12.5.2.2.2.1.3.4.


Finish the derived
RECORD_TYPE – fixup inline methods


As RECORD_TYPE for the class template instantiation is a normal
class, at line 5671 finish_struct_1

must be invoked to finish the
definition.

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);

Also, remember that for inline method, the associated FUNCTION_DECL
node has its template_info

field filled with the template information. The member subsititution above
subsititues the arguments for methods appropriately, but some relations are
still not updated accordingly.

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

}

Remember the body of inline method is cached within
DECL_PENDING_INLINE_INFO. For arguments of the inline method, they have been
subsititued with those at instantiating, but the context

field remains untouched, it
needs updated for the inline method after subsititution (the new nodes
created).

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.


Finish the derived
RECORD_TYPE – verify base classes


At this point, the base class, and the members are subsitituted with
argument appropriately, but no semantic checking at the class level is
performed for the template instantiation. This semantic checking should be
taken as soon as possible. Here is the most early point the semantic checking
can be performed.

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);

If the class template contains (derives) base classes (remember the
base classes may be class template too, see our example of “SmallObject”), it
is time to see there is any flaw between the class and the base classes.

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

}

Among the arguments in the invocation, cant_have_default_ctor

is nonzero if
base classes have no default constructor, cant_have_const_ctor

is nonzero if base classes
have no copy constructor that takes constant reference, and no_const_asn_ref

is nonzero if base classes have no assignment operator that takes constant
reference.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: