现在的位置: 首页 > 综合 > 正文

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

2013年01月10日 ⁄ 综合 ⁄ 共 11149字 ⁄ 字号 评论关闭

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

抱歉!评论已关闭.