Then check_initializer
is invoked to verify the
initializers. Here argument flags
is 0.
4463
static
tree
4464
check_initializer
(tree decl, tree init,
int flags, tree *cleanup)
in
decl.c
4465
{
4466
tree type = TREE_TYPE (decl);
4467
tree init_code = NULL;
4468
4469
/* If `start_decl'
didn't like having an initialization, ignore it now.
*/
4470
if (init != NULL_TREE && DECL_INITIAL
(decl) == NULL_TREE)
4471
init = NULL_TREE;
4472
4473
/* If an
initializer is present, DECL_INITIAL has been
4474
error_mark_node, to indicate
that an as-of-yet unevaluated
4475
initialization will occur.
From now on, DECL_INITIAL reflects
4476
the static initialization --
if any -- of DECL.
*/
4477
DECL_INITIAL (decl) = NULL_TREE;
4478
4479
/* Things that are
going to be initialized need to have complete
4480
type.
*/
4481
TREE_TYPE (decl) = type = complete_type
(TREE_TYPE (decl));
4482
4483
if (type == error_mark_node)
4484
/* We will have
already complained.
*/
4485
init = NULL_TREE;
4486
else if (init && COMPLETE_TYPE_P
(type)
4487
&& !TREE_CONSTANT (TYPE_SIZE
(type)))
4488
{
4489
error ("variable-sized object `%D' may
not be initialized", decl);
4490
init = NULL_TREE;
4491
}
4492
else if (TREE_CODE (type) == ARRAY_TYPE
4493
&& !COMPLETE_TYPE_P (complete_type
(TREE_TYPE (type))))
4494
{
4495
error ("elements of array `%#D' have
incomplete type", decl);
4496
init = NULL_TREE;
4497
}
4498
else if (TREE_CODE (type) != ARRAY_TYPE
&& !COMPLETE_TYPE_P (type))
4499
{
4500
error ("`%D' has incomplete
type", decl);
4501
TREE_TYPE (decl) = error_mark_node;
4502
init = NULL_TREE;
4503
}
4504
4505
if (TREE_CODE (decl) == CONST_DECL)
4506
{
4507
my_friendly_assert (TREE_CODE (decl) !=
REFERENCE_TYPE, 148);
4508
4509
DECL_INITIAL (decl) = init;
4510
4511
my_friendly_assert (init != NULL_TREE,
149);
4512
init = NULL_TREE;
4513
}
4514
else if (!DECL_EXTERNAL (decl) &&
TREE_CODE (type) == REFERENCE_TYPE)
4515
init = grok_reference_init (decl, type,
init, cleanup);
4516
else if (init)
4517
{
4518
if (TREE_CODE (init) ==
CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
4519
{
4520
/* [dcl.init]
paragraph 13,
4521
If T is a scalar type, then a declaration
of the form
4522
T x = { a };
4523
is equivalent to
4524
T x = a;
4525
4526
reshape_init will complain about the extra
braces,
4527
and doesn't do anything useful in the case
where TYPE is
4528
scalar, so just don't call it.
*/
4529
if
(CP_AGGREGATE_TYPE_P (type))
4530
init = reshape_init
(type, &init);
4531
4532
if
((*targetm
.vector_opaque_p)
(type))
4533
{
4534
error ("opaque vector types cannot
be initialized");
4535
init = error_mark_node;
4536
}
4537
}
One of clause of [dcl.init.aggr] of C++ standard specifies that:
All implicit type conversions (clause 4) are considered when
initializing the aggregate member with an initializer from an initializer-list.
If the initializer can initialize a member, the member is initialized.
Otherwise, if the member is itself a non-empty subaggregate, brace elision is
assumed and the initializer is considered for the initialization of the first
member of the subaggregate. For example:
struct
A {
int i;
operator
int();
};
struct
B {
A a1, a2;
int z;
};
A a;
B b = { 4, a, a };
Braces are elided around the initializer for b.a1.i. b.a1.i is
initialized with 4, b.a2 is initialized with a, b.z is initialized with
whatever a.operator int() returns.
Routine reshape_init
is invoked to transform the
initializers list in form of {4, a, a } into the form of { {4, a}, a}. The rear
one is what expected by the front-end.
Here for our example, the VAR_DECL is the array of vtable_entry_type
and initp
refers to the CONSTRUCTOR node for the initializers, which is deliberately
created with empty type. So code in block at line 4289 is executed.
CONSTRUCTOR_ELTS returns the inits
generated in above. These initializers are
treated as if enclosed by braces.
4267
static
tree
4268
reshape_init
(tree type, tree *initp)
in
decl.c
4269
{
4270
tree inits;
4271
tree old_init;
4272
tree old_init_value;
4273
tree new_init;
4274
bool brace_enclosed_p;
4275
bool string_init_p;
4276
4277
old_init = *initp;
4278
old_init_value = (TREE_CODE (*initp) ==
TREE_LIST
4279
? TREE_VALUE (*initp) : old_init);
4280
4281
my_friendly_assert (old_init_value,
20030723);
4282
4283
/* If the
initializer is brace-enclosed, pull initializers from the
4284
enclosed elements. Advance
past the brace-enclosed initializer
4285
now.
*/
4286
if (TREE_CODE (old_init_value) == CONSTRUCTOR
4287
&& TREE_TYPE (old_init_value) ==
NULL_TREE
4288
&& TREE_HAS_CONSTRUCTOR
(old_init_value))
4289
{
4290
*initp = TREE_CHAIN (old_init);
4291
TREE_CHAIN (old_init) = NULL_TREE;
4292
inits = CONSTRUCTOR_ELTS (old_init_value);
4293
initp = &inits;
4294
brace_enclosed_p = true;
4295
}
4296
else
4297
{
4298
inits = NULL_TREE;
4299
brace_enclosed_p = false;
4300
}
4301
4302
/* A non-aggregate
type is always initialized with a single
4303
initializer.
*/
4304
if (!CP_AGGREGATE_TYPE_P (type))
4305
{
4306
*initp = TREE_CHAIN (old_init);
4307
TREE_CHAIN (old_init) = NULL_TREE;
4308
/* It is invalid
to initialize a non-aggregate type with a
4309
brace-enclosed
initializer.
*/
4310
if (brace_enclosed_p)
4311
{
4312
error ("brace-enclosed initializer
used to initialize `%T'",
4313
type);
4314
if (TREE_CODE (old_init) == TREE_LIST)
4315
TREE_VALUE (old_init) = error_mark_node;
4316
else
4317
old_init = error_mark_node;
4318
}
4319
4320
return
old_init;
4321
}
4322
4323
/* [dcl.init.aggr]
4324
4325
All implicit type conversions
(clause _conv_) are considered when
4326
initializing the aggregate
member with an initializer from an
4327
initializer-list. If the
initializer can initialize a member,
4328
the member is initialized.
Otherwise, if the member is itself a
4329
non-empty subaggregate, brace
elision is assumed and the
4330
initializer is considered for
the initialization of the first
4331
member of the
subaggregate.
*/
4332
if (!brace_enclosed_p
4333
&& can_convert_arg (type,
TREE_TYPE (old_init_value), old_init_value))
4334
{
4335
*initp = TREE_CHAIN (old_init);
4336
TREE_CHAIN (old_init) = NULL_TREE;
4337
return
old_init;
4338
}
4339
4340
string_init_p = false;
4341
if (TREE_CODE (old_init_value) == STRING_CST
4342
&& TREE_CODE (type) == ARRAY_TYPE
4343
&& char_type_p (TYPE_MAIN_VARIANT
(TREE_TYPE (type))))
4344
{
…
4356
}
4357
else
4358
{
4359
/* Build a
CONSTRUCTOR to hold the contents of the aggregate.
*/
4360
new_init = build_constructor
(type, NULL_TREE);
4361
TREE_HAS_CONSTRUCTOR (new_init) = 1;
4362
4363
if (CLASS_TYPE_P (type))
4364
{
…
4419
}
4420
else if ((TREE_CODE (type)
== ARRAY_TYPE)|| (TREE_CODE (type) == VECTOR_TYPE))
4421
{
4422
tree max_index;
4423
4424
/* If the bound of the array is known, take no more
initializers
4425
than are allowed.
*/
4426
max_index = ((TYPE_DOMAIN (type) &&
(TREE_CODE (type) == ARRAY_TYPE))
4427
? array_type_nelts (type) : NULL_TREE);
4428
if
(!reshape_init_array
(TREE_TYPE (type),
max_index,
4429
initp, new_init))
4430
return
error_mark_node;
4431
}
4432
else
4433
abort ();
4434
4435
/* The
initializers were placed in reverse order in the
4436
CONSTRUCTOR.
*/
4437
CONSTRUCTOR_ELTS (new_init) = nreverse
(CONSTRUCTOR_ELTS (new_init));
4438
4439
if (TREE_CODE (old_init) == TREE_LIST)
4440
new_init = build_tree_list (TREE_PURPOSE
(old_init), new_init);
4441
}
4442
4443
/* If there are
more initializers than necessary, issue a
4444
diagnostic.
*/
4445
if (*initp)
4446
{
4447
if (brace_enclosed_p)
4448
error ("too many initializers for
`%T'", type);
4449
else if (warn_missing_braces
&&
!string_init_p)
4450
warning ("missing braces around
initializer");
4451
}
4452
4453
return
new_init;
4454
}
See for aggregate member, line 4333 verifies that type of the
initializer can be converted to that of member. For array, below reshape_init_array
iterates every element by reshape_init
to verify and reshape the
initializer. For non-aggregate member, the initializer is just returned.
4203
static
bool
4204
reshape_init_array
(tree elt_type, tree
max_index,
in
decl.c
4205
tree *initp, tree new_init)
4206
{
4207
bool sized_array_p = (max_index !=
NULL_TREE);
4208
unsigned HOST_WIDE_INT max_index_cst = 0;
4209
unsigned HOST_WIDE_INT index;
4210
4211
if (sized_array_p)
4212
{
4213
if (host_integerp (max_index, 1))
4214
max_index_cst = tree_low_cst (max_index,
1);
4215
/* sizetype is sign extended, not zero
extended.
*/
4216
else
4217
max_index_cst = tree_low_cst (convert
(size_type_node, max_index), 1);
4218
}
4219
4220
/* Loop until there
are no more initializers.
*/
4221
for
(index =
0;
4222
*initp && (!sized_array_p ||
index <= max_index_cst);
4223
++index)
4224
{
4225
tree element_init;
4226
tree designated_index;
4227
4228
element_init = reshape_init
(elt_type, initp);
4229
if (element_init == error_mark_node)
4230
return
false;
4231
TREE_CHAIN (element_init) =
CONSTRUCTOR_ELTS (new_init);
4232
CONSTRUCTOR_ELTS (new_init) = element_init;
4233
designated_index = TREE_PURPOSE
(element_init);
4234
if (designated_index)
4235
{
4236
/* Handle array designated initializers (GNU
extension).
*/
4237
if (TREE_CODE (designated_index) ==
IDENTIFIER_NODE)
4238
{
4239
error ("name `%D' used in a
GNU-style designated "
4240
"initializer for an
array", designated_index);
4241
TREE_PURPOSE (element_init) =
NULL_TREE;
4242
}
4243
else
4244
abort ();
4245
}
4246
}
4247
4248
return
true;
4259
}
Here TREE_PURPOSE of every initializer of our example is empty (TREE_PURPOSE
is used for designated initializer, IBM’s XL C supports this feature, detail
see here
.
See that the new CONSTRUCTOR generated has type assigned when compared with
former one.
Then in check_initializer
at line 4532, under x86
machine, vector_opaque_p
hook in targetm
always returns false. And below maybe_deduce_size_from_array_init
sets the
size field in the node of array, for example: int a[] = { 1, 2, 3}; the
function should set the size of 3 into the node.
check_initializer (continue)
4539
/* If DECL has an
array type without a specific bound, deduce the
4540
array size from the initializer.
*/
4541
maybe_deduce_size_from_array_init (decl,
init);
4542
type = TREE_TYPE (decl);
4543
if (TREE_CODE (init) ==
CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
4544
TREE_TYPE (init) = type;
4545
4546
if (TYPE_HAS_CONSTRUCTOR
(type) || TYPE_NEEDS_CONSTRUCTING (type))
4547
{
…
4579
}
4580
else
4581
{
4582
dont_use_constructor:
4583
if
(TREE_CODE (init) != TREE_VEC)
4584
{
4585
init_code = store_init_value
(decl, init);
4586
init = NULL;
4587
}
4588
}
4589
}
4590
else if (DECL_EXTERNAL (decl))
4591
;
4592
else if (TYPE_P (type) &&
TYPE_NEEDS_CONSTRUCTING (type))
4593
goto
initialize_aggr;
4594
else if (IS_AGGR_TYPE (type))
4595
{
4596
tree core_type = strip_array_types (type);
4597
4598
if (CLASSTYPE_READONLY_FIELDS_NEED_INIT
(core_type))
4599
error ("structure `%D' with
uninitialized const members", decl);
4600
if (CLASSTYPE_REF_FIELDS_NEED_INIT
(core_type))
4601
error ("structure `%D' with
uninitialized reference members",
4602
decl);
4603
4604
check_for_uninitialized_const_var (decl);
4605
}
4606
else
4607
check_for_uninitialized_const_var (decl);
4608
4609
if (init && init != error_mark_node)
4610
init_code = build
(INIT_EXPR, type,
decl, init);
4611
4612
return
init_code;
4613
}
Type of decl
is