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

GCC-3.4.6源代码学习笔记(156)

2013年01月16日 ⁄ 综合 ⁄ 共 10479字 ⁄ 字号 评论关闭

5.13.3.     


为基本类型产生tinfo

操持完
PCH
文件,回到
finish_file


中继续为汇编代码的生成而奋斗。接下来编译器将为基本类型准备
tinfo

 

finish_file (continue)

 

2546  


 
/* Otherwise, GDB
can get confused, because in only knows

2547  


   
about source for LINENO-1
lines. 
*/

2548  


 
input_line -= 1;

2549  

2550  


 
interface_unknown

= 1;

2551  


 
interface_only

= 0;

2552  

2553  


 
/* We now have to
write out all the stuff we put off writing out.

2554  


   
These include:

2555  

2556  


   
o Template specializations
that we have not yet instantiated,

2557  


     
but which are needed.

2558  


   
o Initialization and
destruction for non-local objects with

2559  


     
static storage duration.
(Local objects with static storage

2560  


     
duration are initialized
when their scope is first entered,

2561  


     
and are cleaned up via
atexit.)

2562  


   
o Virtual function
tables. 

2563  

2564  


   
All of these may cause others
to be needed. For example,

2565  


   
instantiating one function may
cause another to be needed, and

2566  


   
generating the initializer for
an object may cause templates to be

2567  


   
instantiated, etc., etc. 
*/

2568  

2569  


 
timevar_push (TV_VARCONST);

2570  

2571  


 
emit_support_tinfos
();

 

所有这样的
tinfo
将可以在名字空间
abi_node

中找到。在
get_tinfo_decl


中,这些
tinfo
将被串入
unemitted_tinfo_decls

。注意到数组
fundamentals

的内容是基本类型的节点,它们是在建立编译器环境时构建的。

 

1353  


void

1354  


emit_support_tinfos
(void)                                                                                    

in rtti.c

1355  


{

1356  


 
static
tree *const
fundamentals[] =

1357  


 
{

1358  


  
 
&void_type_node,

1359  


   
&boolean_type_node,

1360  


   
&wchar_type_node,

1361  


   
&char_type_node,
&signed_char_type_node, &unsigned_char_type_node,

1362  


   
&short_integer_type_node,
&short_unsigned_type_node,

1363  


   
&integer_type_node, &unsigned_type_node,

1364  


   
&long_integer_type_node,
&long_unsigned_type_node,

1365  


   
&long_long_integer_type_node,
&long_long_unsigned_type_node,

1366  


   
&float_type_node,
&double_type_node, &long_double_type_node,

1367  


   
0

1368  


 
};

1369  


 
int ix;

1370  


 
tree bltn_type, dtor;

1371  


 

1372  


 
push_nested_namespace
(abi_node

);

1373  


 
bltn_type = xref_tag
(class_type,

1374  


                   
get_identifier
("__fundamental_type_info"),

1375  


  
                 
true, false);

1376  


 
pop_nested_namespace (abi_node

);

1377  


 
if (!COMPLETE_TYPE_P (bltn_type))

1378  


   
return
;

1379  


 
dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC
(bltn_type), 1);

1380  


 
if (DECL_EXTERNAL (dtor))

1381  


   
return
;

1382  


 
doing_runtime

= 1;

1383  


 
for
(ix = 0;
fundamentals[ix]; ix++)

1384  


 
{

1385  


   
tree bltn = *fundamentals[ix];

1386  


   
tree bltn_ptr = build_pointer_type
(bltn);

1387  


   
tree bltn_const_ptr = build_pointer_type

1388  


                            
(build_qualified_type
(bltn, TYPE_QUAL_CONST));

1389  


   
tree tinfo;

1390  


     

1391  


   
tinfo = get_tinfo_decl
(bltn);

1392  


   
TREE_USED (tinfo) = 1;

1393  


   
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME
(tinfo)) = 1;

1394  


     

1395  


   
tinfo = get_tinfo_decl
(bltn_ptr);

1396  


   
TREE_USED (tinfo) = 1;

1397  


   
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME
(tinfo)) = 1;

1398  


     

1399  


   
tinfo = get_tinfo_decl
(bltn_const_ptr);

1400  


   
TREE_USED (tinfo) = 1;

1401  


   
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME
(tinfo)) = 1;

1402  


 
}

1403  


}

 

看到对于每个基本类型,需要产生
3

tinfo

一个对应朴素(
plain
)类型,一个对应指针,还有一个对应常量指针。

5.13.4.     


稳定中间树

下面的庞大的
DO WHILE

循环不断重复,直到没有任何相关的东西发生改变。在
2582
行,
instantiate_pending_templates


具现仍未了结的模板。在前端内部,一个全局的
tree_list
链表
pending_tempaltes

保存了所有具现被延迟的模板,它们要么定义还未知,要么我们推迟了这个具现。每个节点的
tree_purose
或者是一个
DECL
(对于一个函数或者静态数据成员),或一个
TYPE
(对于一个类),它代表我们所期望的具现形式。而
tree_value
不被使用。

 

finish_file (continue)

 

2573  


 
do

2574  


 
{

2575  


   
tree t;

2576  


   
size_t n_old, n_new;

2577  

2578  


   
reconsider = false;

2579  

2580  


   
/* If there are
templates that we've put off instantiating, do

2581  


     
them now. 
*/

2582  


   
instantiate_pending_templates ();

2583  


   
ggc_collect ();

2584  

2585  


   
/* Write out
virtual tables as required. Note that writing out

2586  


    
 
the virtual table for a template class may
cause the

2587  


     
instantiation of members of
that class. If we write out

2588  


    
 
vtables then we remove the class from our list
so we don't

2589  


    
 
have to look at it again. 
*/

2590  

2591  


   
while
(keyed_classes

!= NULL_TREE

2592  


          
&& maybe_emit_vtables
(TREE_VALUE (keyed_classes

)))

2593  


   
{

2594  


     
reconsider = true;

2595  


     
keyed_classes

= TREE_CHAIN (keyed_classes

);

2596  


   
}

2597  


2598  


   
t = keyed_classes

;

2599  


   
if (t != NULL_TREE)

2600  


 
  
{

2601  


     
tree next = TREE_CHAIN (t);

2602  


2603  


     
while
(next)

2604  


  
    
{

2605  


  
      
if (maybe_emit_vtables
(TREE_VALUE (next)))

2606  


        
{

2607  


          
reconsider = true;

2608  


          
TREE_CHAIN (t) = TREE_CHAIN (next);

2609  


        
}

2610  


        
else

2611  


          
t = next;

2612  


2613  


        
next = TREE_CHAIN (t);

2614  


     
}

2615  


   
}

2616  

2617  


  
/* Write out
needed type info variables. We have to be careful

2618  


   
 
looping through unemitted decls, because
emit_tinfo_decl may

2619  


   
 
cause other variables to be needed. We stick
new elements

2620  


   
 
(and old elements that we may need to
reconsider) at the end

2621  


    
of the array, then shift them
back to the beginning once we're

2622  


   
 
done. 

*/

2623  


 

2624  


   
n_old = VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls

);

2625  


   
for
(i = 0;
i < n_old; ++i)

2626  


   
{

2627  


     
tree tinfo_decl = VARRAY_TREE (unemitted_tinfo_decls

,
i);

2628  


     
if (emit_tinfo_decl
(tinfo_decl))

2629  


       
reconsider = true;

2630  


     
else

2631  


       
VARRAY_PUSH_TREE (unemitted_tinfo_decls

, tinfo_decl);

2632  


   
}

2633  


 

2634  


  
 
/* The only elements we want to keep are the
new ones. Copy

2635  


     
them to the beginning of the
array, then get rid of the

2636  


     
leftovers. 
*/

2637  


   
n_new = VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls

)
- n_old;

2638  


   
if (n_new)

2639  


     
memmove (&VARRAY_TREE (unemitted_tinfo_decls

,
0),

2640  


               
&VARRAY_TREE (unemitted_tinfo_decls

,
n_old),

2641  


               
n_new * sizeof
(tree));

2642  


   
memset (&VARRAY_TREE (unemitted_tinfo_decls

,
n_new),

2643  


           
0, n_old * sizeof
(tree));

2644  


   
VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls

) = n_new;

2645  

2646  


   
/* The list of
objects with static storage duration is built up

2647  


    
 
i

n reverse order. We clear STATIC_AGGREGATES so that any new

2648  


    
 
aggregates added during the initialization of
these will be

2649  


    
 
initialized in the correct order when we next
come around the

2650  


    
 
loop. 

*/

2651  


   
vars = prune_vars_needing_no_initialization
(&static_aggregates

);

2652  

2653  


   
if (vars)

2654  


   
{

2655  


     
tree v;

2656  

2657  


    
 
/* We need to start a new initialization
function each time

2658  


       
through the loop. That's
because we need to know which

2659  


  
     
vtables have been referenced, and
TREE_SYMBOL_REFERENCED

2660  


  
     
isn't computed until a function is finished,
and written

2661  


  
     
out. That's a deficiency in the back-end.
When this is

2662  


  
     
fixed, these initialization functions
could all become

2663  


  
     
inline, with resulting performance
improvements. 
*/

2664  


     
tree ssdf_body;

2665  

2666  


    
 
/* Set the line and file, so that it is
obviously not from

2667  


  
     
the source file. 
*/

2668  


     
input_location

= locus;

2669  


     
ssdf_body = start_static_storage_duration_function
(ssdf_count);

2670  

2671  


     
/* Make sure
the back end knows about all the variables. 

*/

2672  


     
write_out_vars
(vars);

2673  

2674  


     
/* First
generate code to do all the initializations. 

*/

2675  


     
for
(v =
vars; v; v = TREE_CHAIN (v))

2676  


       
do_static_initialization
(TREE_VALUE (v),

2677  


                           
TREE_PURPOSE (v));

2678  

2679  


     
/* Then,
generate code to do all the destructions. Do these

2680  


  
     
i

n reverse order so that the most recently constructed

2681  


   
    
variable is the first destroyed. If we're
using

2682  


  
     
__cxa_atexit, then we don't need to do
this; functions

2683  


  
     
were registered at initialization time to
destroy the

2684  


  
     
local statics. 
*/

2685  


     
if (!flag_use_cxa_atexit

)

2686  


     
{

2687  


       
vars = nreverse (vars);

2688  


       
for
(v
= vars; v; v = TREE_CHAIN (v))

2689  


         
do_static_destruction (TREE_VALUE
(v));

2690  


     
}

2691  


     
else

2692  


       
vars = NULL_TREE;

2693  

2694  


    
 
/* Finish up the static storage duration
function for this

2695  


  
     
round. 

*/

2696  


     
input_location

= locus;

2697  


     
finish_static_storage_duration_function
(ssdf_body);

2698  

2699  


     
/* All those
initializations and finalizations might cause

2700  


  
     
us to need more inline functions, more
template

2701  


  
     
instantiations, etc. 
*/

2702  


     
reconsider = true;

2703  


     
ssdf_count++;

2704  


     
locus.line++;

2705  


   
}

2706  


     

2707  


   
for
(i = 0;
i < deferred_fns_used

;
++i)

2708  


   
{

2709  


     
tree decl = VARRAY_TREE (deferred_fns

,
i);

2710  

2711  


     
/* Does it need
synthesizing? 
*/

2712  


     
if (DECL_ARTIFICIAL (decl) && !
DECL_INITIAL (decl)

2713  


        
&& TREE_USED (decl)

2714  


        
&& (! DECL_REALLY_EXTERN
(decl) || DECL_INLINE (decl)))

2715  


     
{

2716  


       
/* Even
though we're already at the top-level, we push

2717  


        
 
there again. That way, when we pop back a few
lines

2718  


        
 
hence, all of our state is restored.
Otherwise,

2719  


        
 
finish_function doesn't clean things up, and
we end

2720  


        
 
up with CURRENT_FUNCTION_DECL set. 
*/

2721  


       
push_to_top_level
();

2722  


       
synthesize_method (decl);

2723  


       
pop_from_top_level ();

2724  


       
reconsider = true;

2725  


     
}

2726  

2727  


     
/* If the
function has no body, avoid calling

2728  


  
     
import_export_decl. On a system without
weak symbols,

2729  


  
     
calling import_export_decl will make an
inline template

2730  


  
     
instantiation "static", which
will result in errors about

2731  


  
     
the use of undefined functions if there is
no body for

2732  


  
     
the function. 
*/

2733  


     
if (!DECL_SAVED_TREE (decl))

2734  


       
continue
;

2735  

2736  


     
import_export_decl (decl);

2737  

2738  


     
/* We lie to
the back-end, pretending that some functions

2739  


  
     
are not defined when they really are. This
keeps these

2740  


  
     
functions from being put out
unnecessarily. But, we must

2741  


  
     
stop lying when the functions are
referenced, or if they

2742  


  
     
are not comdat since they need to be put
out now. This

2743  


  
     
is done in a separate for cycle, because
if some deferred

2744  


  
     
function is contained in another deferred
function later

2745  


  
     
i

n deferred_fns varray, rest_of_compilation would skip

2746  


  
     
this function and we really cannot expand
the same

2747  


  
     
function twice. 
*/

2748  


     
if (DECL_NOT_REALLY_EXTERN (decl)

2749  


        
&& DECL_INITIAL (decl)

2750  


        
&& DECL_NEEDED_P (decl))

2751  


       
DECL_EXTERNAL (decl) = 0;

2752  

2753  


     
/* If we're
going to need to write this function out, and

2754  


  
  
   
there's already a body for it, create RTL
for it now.

2755  


  
     
(There might be no body if this is a
method we haven't

2756  


  
     
gotten around to synthesizing yet.) 
*/

2757  


     
if (!DECL_EXTERNAL (decl)

2758  


        
&& DECL_NEEDED_P (decl)

2759  


        
&& DECL_SAVED_TREE (decl)

2760  


        
&& !TREE_ASM_WRITTEN (decl)

2761  


        
&& (!flag_unit_at_a_time

2762  


            
|| !cgraph_node
(decl)->local.finalized))

2763  


     
{

2764  


       
/* We will
output the function; no longer consider it in this

2765  


        
 
loop. 

*/

2766  


       
DECL_DEFER_OUTPUT (decl) = 0;

2767  


       
/* Generate
RTL for this function now that we know we

2768  

抱歉!评论已关闭.