您的位置:首页 > 其它

Studying note of GCC-3.4.6 source (141 - cont 2)

2011-01-09 17:37 381 查看
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 vtbl_type_node

which is ARRAY_TYPE of vtable_entry_type

which in turn is a pointer of certain function type; of course no constructor
is defined for this ARRAY_TYPE. So condition at line 4546 is false for type

.

410

tree

411

store_init_value

(tree decl, tree init)

in

typeck2.c

412

{

413

tree value, type;

414

415

/* If variable's
type was invalidly declared, just ignore it.

*/

416

417

type = TREE_TYPE (decl);

418

if (TREE_CODE (type) == ERROR_MARK)

419

return
NULL_TREE;

420

421

if (IS_AGGR_TYPE (type))

422

{



432

}

433

else if (TREE_CODE (init) == TREE_LIST

434

&& TREE_TYPE (init) !=
unknown_type_node)

435

{



448

}

449

450

/* Digest the
specified initializer into an expression.

*/

451

value = digest_init
(type, init, (tree *) 0);

452

/* If the
initializer is not a constant, fill in DECL_INITIAL with

453

the bits that are
constant, and then return an expression that

454

will perform the
dynamic initialization.
*/

455

if (value != error_mark_node

456

&& (! TREE_CONSTANT (value)

457

|| ! initializer_constant_valid_p
(value, TREE_TYPE (value))))

458

return
split_nonconstant_init (decl, value);

459

/* If the value is
a constant, just put it in DECL_INITIAL. If DECL

460

is an automatic
variable, the middle end will turn this into a

461

dynamic
initialization later.
*/

462

DECL_INITIAL (decl) = value;

463

return
NULL_TREE;

464

}

Here argument type

is the type of the VAR_DECL. Initializers needsn’t
be the same type as corresponding member as long as appropriate convertor is
found. The purpose of digest_init

is to find the applicable convertor
and generate necessary code for this conversion, if type

and init

can’t match exactly.

476

tree

477

digest_init

(tree type, tree init, tree*
tail)

in

typeck2.c

478

{

479

enum
tree_code code = TREE_CODE (type);

480

tree element = NULL_TREE;

481

tree old_tail_contents = NULL_TREE;

482

/* Nonzero if INIT
is a braced grouping.
*/

483

int raw_constructor;

484

485

/* By default,
assume we use one element from a list.

486

We correct this
later in the sole case where it is not true.

*/

487

488

if (tail)

489

{

490

old_tail_contents = *tail;

491

*tail = TREE_CHAIN (*tail);

492

}

493

494

if (init == error_mark_node || (TREE_CODE
(init) == TREE_LIST

495

&&
TREE_VALUE (init) == error_mark_node))

496

return
error_mark_node;

497

498

if (TREE_CODE (init) == ERROR_MARK)

499

/*
__PRETTY_FUNCTION__'s initializer is a bogus expression inside

500

a template function. This gets substituted
during instantiation.
*/

501

return
init;

502

503

/* We must strip
the outermost array type when completing the type,

504

because the its
bounds might be incomplete at the moment.

*/

505

if (!complete_type_or_else (TREE_CODE (type)
== ARRAY_TYPE

506

? TREE_TYPE (type) :
type, NULL_TREE))

507

return
error_mark_node;

508

509

/* Strip
NON_LVALUE_EXPRs since we aren't using as an lvalue.
*/

510

if (TREE_CODE (init) == NON_LVALUE_EXPR)

511

init = TREE_OPERAND (init, 0);

512

513

raw_constructor = (TREE_CODE (init) ==
CONSTRUCTOR

514

&& TREE_HAS_CONSTRUCTOR (init));

515

516

if (raw_constructor

517

&& CONSTRUCTOR_ELTS (init) != 0

518

&& TREE_CHAIN (CONSTRUCTOR_ELTS
(init)) == 0)

519

{

520

element = TREE_VALUE (CONSTRUCTOR_ELTS
(init));

521

/* Strip NON_LVALUE_EXPRs since we aren't
using as an lvalue.
*/

522

if (element && TREE_CODE (element)
== NON_LVALUE_EXPR)

523

element = TREE_OPERAND (element, 0);

524

if (element == error_mark_node)

525

return
element;

526

}

527

528

/* Initialization
of an array of chars from a string constant

529

optionally
enclosed in braces.
*/

530

531

if (code == ARRAY_TYPE)

532

{

533

tree typ1;

534

535

if (TREE_CODE (init) == TREE_LIST)

536

{

537

error ("initializing array with parameter
list");

538

return
error_mark_node;

539

}

540

541

typ1 = TYPE_MAIN_VARIANT (TREE_TYPE
(type));

542

if (char_type_p (typ1)

543

&& ((init && TREE_CODE
(init) == STRING_CST)

544

|| (element && TREE_CODE
(element) == STRING_CST)))

545

{



577

}

578

}

579

580

/* Handle scalar
types, including conversions,

581

and signature
pointers and references.
*/

582

583

if (code == INTEGER_TYPE || code == REAL_TYPE
|| code == POINTER_TYPE

584

||
code == ENUMERAL_TYPE || code == REFERENCE_TYPE

585

|| code == BOOLEAN_TYPE || code ==
COMPLEX_TYPE

586

|| TYPE_PTR_TO_MEMBER_P (type))

587

{

588

if (raw_constructor)

589

{

590

if (element == 0)

591

{

592

error ("initializer for scalar
variable requires one element");

593

return
error_mark_node;

594

}

595

init = element;

596

}

597

while
(TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))

598

{

599

pedwarn ("braces around scalar
initializer for `%T'", type);

600

init = CONSTRUCTOR_ELTS (init);

601

if (TREE_CHAIN (init))

602

pedwarn ("ignoring extra
initializers for `%T'", type);

603

init = TREE_VALUE (init);

604

}

605

606

return
convert_for_initialization (0, type, init, LOOKUP_NORMAL,

607

"initialization", NULL_TREE, 0);

608

}

609

610

/* Come here only
for records and arrays (and unions with constructors).
*/

611

612

if (COMPLETE_TYPE_P (type) && !
TREE_CONSTANT (TYPE_SIZE (type)))

613

{

614

error ("variable-sized object of type
`%T' may not be initialized",

615

type);

616

return
error_mark_node;

617

}

618

619

if (code == ARRAY_TYPE ||
code == VECTOR_TYPE || IS_AGGR_TYPE_CODE (code))

620

{

621

if (raw_constructor &&
TYPE_NON_AGGREGATE_CLASS (type)

622

&& TREE_HAS_CONSTRUCTOR (init))

623

{

624

error ("subobject of type `%T' must
be initialized by constructor, not by `%E'",

625

type, init);

626

return
error_mark_node;

627

}

628

else if (raw_constructor)

629

return
process_init_constructor
(type, init,
(tree *)0);



649

}

650

651

error ("invalid initializer");

652

return
error_mark_node;

653

}

For the initializers of our example, at line 513, raw_constructor

is nonzero; and code

is ARRAY_TYPE. Then argument init

is passed to process_init_constructor

for
handling.

670

static
tree

671

process_init_constructor

(tree type,
tree init, tree* elts)

in
typeck2.c

672

{

673

tree tail;

674

/* List of the
elements of the result constructor,

675

i
n reverse order.

*/

676

tree members = NULL;

677

tree next1;

678

tree result;

679

int allconstant = 1;

680

int allsimple = 1;

681

int erroneous = 0;

682

683

/* Make TAIL be the
list of elements to use for the initialization,

684

no matter how the
data was given to us.
*/

685

686

if (elts)

687

{

688

if (warn_missing_braces

)

689

warning ("aggregate has a partly
bracketed initializer");

690

tail = *elts;

691

}

692

else

693

tail = CONSTRUCTOR_ELTS (init);

694

695

/* Gobble as many
elements as needed, and make a constructor or initial value

696

for each element
of this aggregate. Chain them together in result.

697

If there are too
few, use 0 for each scalar ultimate component.

*/

698

699

if (TREE_CODE (type) == ARRAY_TYPE ||
TREE_CODE (type) == VECTOR_TYPE)

700

{

701

long len;

702

int i;

703

704

if (TREE_CODE (type) == ARRAY_TYPE)

705

{

706

tree domain = TYPE_DOMAIN (type);

707

if (domain)

708

len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE
(domain))

709

- TREE_INT_CST_LOW
(TYPE_MIN_VALUE (domain))

710

+ 1);

711

else

712

len = -1;
/* Take as many as
there are.
*/

713

}

714

else

715

{

716

/* Vectors are
like simple fixed-size arrays.
*/

717

len = TYPE_VECTOR_SUBPARTS (type);

718

}

719

720

for
(i = 0; len < 0 || i < len; i++)

721

{

722

if (tail)

723

{

724

if (TREE_PURPOSE (tail)

725

&& (TREE_CODE (TREE_PURPOSE
(tail)) != INTEGER_CST

726

|| compare_tree_int (TREE_PURPOSE
(tail), i) != 0))

727

sorry ("non-trivial labeled
initializers");

728

729

if (TREE_VALUE (tail) != 0)

730

{

731

tree tail1 = tail;

732

next1 = digest_init
(TREE_TYPE (type),

733

TREE_VALUE (tail),
&tail1);

734

if (next1 == error_mark_node)

735

return
next1;

736

my_friendly_assert

737

(same_type_ignoring_top_level_qualifiers_p

738

(TREE_TYPE (type),
TREE_TYPE (next1)),

739

981123);

740

my_friendly_assert (tail1 == 0

741

|| TREE_CODE (tail1)
== TREE_LIST, 319);

742

if (tail == tail1 && len <
0)

743

{

744

error ("non-empty initializer
for array of empty elements");

745

/* Just
ignore what we were supposed to use.
*/

746

tail1 = NULL_TREE;

747

}

748

tail = tail1;

749

}

750

else

751

{

752

next1 = error_mark_node;

753

tail = TREE_CHAIN (tail);

754

}

755

}

756

else if (len < 0)

757

/* We're
done.
*/

758

break
;

759

else if (TYPE_NEEDS_CONSTRUCTING
(TREE_TYPE (type)))

760

{



771

}

772

else if (! zero_init_p (TREE_TYPE (type)))

773

next1 = build_zero_init (TREE_TYPE
(type),

774

/*nelts=*/
NULL_TREE,

775

/*static_storage_p=*/
false);

776

else

777

/* The
default zero-initialization is fine for us; don't

778

add
anything to the CONSTRUCTOR.
*/

779

break
;

780

781

if (next1 == error_mark_node)

782

erroneous = 1;

783

else if (!TREE_CONSTANT (next1))

784

allconstant = 0;

785

else if (! initializer_constant_valid_p
(next1, TREE_TYPE (next1)))

786

allsimple = 0;

787

members = tree_cons (size_int (i), next1,
members);

788

}

789

}

790

else if (TREE_CODE (type) == RECORD_TYPE)

791

{



908

}

909

else if (TREE_CODE (type) == UNION_TYPE

910

/* If the initializer was empty, use default zero
initialization.
*/

911

&& tail)

912

{



977

}

978

979

/* If arguments
were specified as a list, just remove the ones we used.
*/

980

if (elts)

981

*elts = tail;

982

/* If arguments
were specified as a constructor,

983

complain unless
we used all the elements of the constructor.

*/

984

else if (tail)

985

pedwarn ("excess elements in aggregate
initializer");

986

987

if (erroneous)

988

return
error_mark_node;

989

990

result = build_constructor
(type, nreverse (members));

991

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

992

complete_array_type (type, result, /*do_default=*/
0);

993

if (init)

994

TREE_HAS_CONSTRUCTOR (result) =
TREE_HAS_CONSTRUCTOR (init);

995

if (allconstant) TREE_CONSTANT (result) = 1;

996

if (allconstant && allsimple)
TREE_STATIC (result) = 1;

997

return
result;

998

}

Not surprising, for each element of ARRAY_TYPE, digest_init

is recursed. Note
that in this invocation, argument tail

is the initializers. If digest_init

can process part
of initializers successfully. This part will be removed from the list of initializers.
At line 606, convert_for_initialization

is invoked to do the possible conversion. Here in our example, no conversion is
expected as we prepare init

of type vtable_entry_type

before hand. As a result, the
function returns init

as returned value.

Exitting convert_for_initialization

gets out of digest_init

immediately, which means this (part) initializer
is verified. At line 787, this returned value is chained into members

.
Next at line 990, new version CONSTRUCTOR is created. See that all elements of
vtable should be constant. And this CONSTRUCTOR allocates static storage (i.e,
initializes static member). Then at line 4902 in cp_finish_decl

, store_init_value

returns
NULL

cp_finish_decl (continue)

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

4961

4962

/* Output the
assembler code and/or RTL code for variables and functions,

4963

unless the type is an
undefined structure or union.

4964

If not, it will get done when
the type is completed.
*/

4965

if (TREE_CODE (decl) == VAR_DECL || TREE_CODE
(decl) == FUNCTION_DECL)

4966

{

4967

if (TREE_CODE (decl) == VAR_DECL)

4968

maybe_commonize_var (decl);

4969

4970

make_rtl_for_nonlocal_decl (decl, init,
asmspec);

4971

4972

if (TREE_CODE (type) == FUNCTION_TYPE

4973

||
TREE_CODE (type) == METHOD_TYPE)

4974

abstract_virtuals_error
(decl,

4975

strip_array_types (TREE_TYPE (type)));

4976

else if (POINTER_TYPE_P (type) || TREE_CODE
(type) == ARRAY_TYPE)

4977

{

4978

/* If it's
either a pointer or an array type, strip through all

4979

of them but the last one. If the last is an
array type, issue

4980

an error if the element type is
abstract.
*/

4981

while
(POINTER_TYPE_P (TREE_TYPE (type))

4982

|| TREE_CODE (TREE_TYPE (type)) ==
ARRAY_TYPE)

4983

type = TREE_TYPE (type);

4984

if (TREE_CODE (type) == ARRAY_TYPE)

4985

abstract_virtuals_error
(decl, TREE_TYPE
(type));

4986

}

4987

else

4988

abstract_virtuals_error
(decl, type);

4989

4990

if (TREE_CODE (decl) == FUNCTION_DECL

4991

||
TREE_TYPE (decl) == error_mark_node)

4992

/* No
initialization required.
*/

4993

;

4994

else if (DECL_EXTERNAL (decl)

4995

&& ! (DECL_LANG_SPECIFIC (decl)

4996

&& DECL_NOT_REALLY_EXTERN (decl)))

4997

{

4998

if
(init)

4999

DECL_INITIAL (decl) = init;

5000

}

5001

else

5002

{

5003

/*
A variable definition.
*/

5004

if (DECL_FUNCTION_SCOPE_P
(decl))

5005

{

5006

/*
This is a local declaration.
*/

5007

maybe_inject_for_scope_var (decl);

5008

/*
Initialize the local variable.
*/

5009

if (processing_template_decl

)

5010

{

5011

if
(init || DECL_INITIAL (decl) == error_mark_node)

5012

DECL_INITIAL (decl) = init;

5013

}

5014

else if (!TREE_STATIC
(decl))

5015

initialize_local_var (decl, init);

5016

}

5017

5018

/*
If a variable is defined, and then a subsequent

5019

definintion with
external linkage is encountered, we will

5020

get here twice
for the same variable. We want to avoid

5021

calling
expand_static_init more than once. For variables

5022

that are not
static data members, we can call

5023

expand_static_init only when we actually
process the

5024

initializer. It
is not legal to redeclare a static data

5025

member, so this
issue does not arise in that case.
*/

5026

if (var_definition_p
&& TREE_STATIC (decl))

5027

expand_static_init (decl,
init);

5028

}

5029

finish_end0:

5030

5031

/* Undo call to `pushclass' that was done in `start_decl'

5032

due to initialization of qualified member
variable.

5033

I.e., Foo::x = 10;
*/

5034

{

5035

tree context = CP_DECL_CONTEXT (decl);

5036

if (context

5037

&& TYPE_P (context)

5038

&& (TREE_CODE (decl) == VAR_DECL

5039

/* We
also have a pushclass done that we need to undo here

5040

if we're at top level and declare a
method.
*/

5041

|| TREE_CODE (decl) ==
FUNCTION_DECL)

5042

/* If size hasn't been set, we're still defining it,

5043

and therefore inside the class body;
don't pop

5044

the
binding level..
*/

5045

&& COMPLETE_TYPE_P (context)

5046

&& context == current_class_type

)

5047

pop_nested_class ();

5048

}

5049

}

5050

5051

/* If a CLEANUP_STMT
was created to destroy a temporary bound to a

5052

reference, insert it in the
statement-tree now.
*/

5053

if (cleanup)

5054

add_stmt (cleanup);

5055

5056

finish_end:

5057

5058

if (was_readonly)

5059

TREE_READONLY (decl) = 1;

5060

5061

/* If this was
marked 'used', be sure it will be output.

*/

5062

if (lookup_attribute
("used", DECL_ATTRIBUTES (decl)))

5063

mark_referenced (DECL_ASSEMBLER_NAME
(decl));

5064

}

As in initialize_array

at line 6809, context of decl

is
temperarily cleaned, at_function_scope_p

at line 4956 returns
false. Then maybe_commonize_var

at line 4968 handles the situation in which a local static variable is declared
in an inline function, or we have a weak definition, for which the compile must
endeavor to create only one instance of the variable at link-time.

Then back cp_finish_decl

, at line 4970, within make_rtl_for_nonlocal_decl

,
the local variable defer_p

is set as true at line 4658 as this
VAR_DECL has flag DECL_VIRTUAL_P set; further at invocation, asmspec

is NULL. So nothing non-trivial is done in this function.

Next, as var_definition_p

is true at line 5026, expand_static_init

is invoked, however, as the ARRAY_TYPE of the vtable hasn’t flag TYPE_NEEDS_CONSTRUCTING
set, the function exits immediately.

At last, cleanup

at line 5053 may be not NULL if we are
handling referecne (here it is NULL). Exitting from cp_finish_decl

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