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