After outputting PCH file if required, back in finish_file to continue the struggle of assemble emitting. Next, the compiler should prepare tinfo for the fundamental types.
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 ();
All such tinfos would be found within namespace abi_node . In get_tinfo_decl , these generated tinfos will be chained in unemitted_tinfo_decls . Note that the content of array fundamentals is the nodes of fundamental types which are built during setting up the compiling environment.
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 }
See that for every fundamental type, three tinfos need generated, one for plain, one for pointer, one for constant pointer.
Following big DO WHILE loop repeats until nothing related can be changed. At line 2582, instantiate_pending_templates instantiates the pending template. Internal, global chain pending_tempaltes is a tree_list holding templates whose instantiations have been deferred, either because their definitions were not yet available, or because we were putting off doing the work. The tree_purose of each node is either a DECL (for a function or static data member), or a TYPE (for a class) indicating what we are hoping to instantiate. The tree_value is not used.
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 need it. */
2769 expand_or_defer_fn (decl);
2770 /* If we're compiling -fsyntax-only pretend that this
2771 function has been written out so that we don't try to
2772 expand it again. */
2773 if (flag_syntax_only )
2774 TREE_ASM_WRITTEN (decl) = 1;
2775 reconsider = true;
2776 }
2777 }
2778
2779 if (walk_namespaces (wrapup_globals_for_namespace , /*data=*/ 0))
2780 reconsider = true;
2781
2782 /* Static data members are just like namespace-scope globals. */
2783 for (i = 0; i < pending_statics_used ; ++i)
2784 {
2785 tree decl = VARRAY_TREE (pending_statics , i);
2786 if (var_finalized_p (decl))
2787 continue ;
2788 import_export_decl (decl);
2789 if (DECL_NOT_REALLY_EXTERN (decl) && ! DECL_IN_AGGR_P (decl))
2790 DECL_EXTERNAL (decl) = 0;
2791 }
2792 if (pending_statics
2793 && wrapup_global_declarations (&VARRAY_TREE (pending_statics , 0),
2794 pending_statics_used ))
2795 reconsider = true;
2796
2797 if (cgraph_assemble_pending_functions ())
2798 reconsider = true;
2799 }
2800 while (reconsider);
At first, vtable in used should be marked so as to compiler will emit code for it. In previous section, we have seen that for a class, its CLASSTYPE_VTABLES maybe contain a list of vtables. It depends on the base classes and its definition. And if a class contains vtable, it is also recorded in list of keyed_classes . At line 1565, primary_vtbl refers to the list of vtable of ctype .
1556 static bool
1557 maybe_emit_vtables (tree ctype) in decl2.c
1558 {
1559 tree vtbl;
1560 tree primary_vtbl;
1561 bool needed = false;
1562
1563 /* If the vtables for this class have already been emitted there is
1564 nothing more to do. */
1565 primary_vtbl = CLASSTYPE_VTABLES (ctype);
1566 if (var_finalized_p (primary_vtbl))
1567 return false;
1568 /* Ignore dummy vtables made by get_vtable_decl. */
1569 if (TREE_TYPE (primary_vtbl) == void_type_node)
1570 return false;
1571
1572 import_export_class (ctype);
1573
1574 /* See if any of the vtables are needed. */
1575 for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl))
1576 {
1577 import_export_vtable (vtbl, ctype, 1);
1578 if (!DECL_EXTERNAL (vtbl) && DECL_NEEDED_P (vtbl))
1579 break ;
1580 }
1581 if (!vtbl)
1582 {
1583 /* If the references to this class' vtables are optimized away,
1584 still emit the appropriate debugging information. See
1585 dfs_debug_mark. */
1586 if (DECL_COMDAT (primary_vtbl)
1587 && CLASSTYPE_DEBUG_REQUESTED (ctype))
1588 note_debug_info_needed (ctype);
1589 return false;
1590 }
1591 else if (TREE_PUBLIC (vtbl) && !DECL_COMDAT (vtbl))
1592 needed = true;
All vtables are declared as public VAR_DECL by compiler, and such nodes are associated by cgraph_varpool_node , in which if flag finalized is set means the node has code output.
1544 static bool
1545 var_finalized_p (tree var) in decl2.c
1546 {
1547 if (flag_unit_at_a_time )
1548 return cgraph_varpool_node (var)->finalized;
1549 else
1550 return TREE_ASM_WRITTEN (var);
1551 }
If flag_unit_at_a_time is nonzero, a cgraph_varpool_node is created for this VAR_DECL. Below, hashtable cgraph_varpool_hash is the queue of cgraph_varpool_node, which is managed by GC.
441 struct cgraph_varpool_node *
442 cgraph_varpool_node (tree decl) in cgraph.c
443 {
444 struct cgraph_varpool_node *node;
445 struct cgraph_varpool_node **slot;
446
447 if (!DECL_P (decl) || TREE_CODE (decl) == FUNCTION_DECL)
448 abort ();
449
450 if (!cgraph_varpool_hash)
451 cgraph_varpool_hash = htab_create_ggc (10, cgraph_varpool_hash_node,
452 eq_cgraph_varpool_node, NULL);
453 slot = (struct cgraph_varpool_node **)
454 htab_find_slot_with_hash (cgraph_varpool_hash , DECL_ASSEMBLER_NAME (decl),
455 IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (decl)),
456 INSERT);
457 if (*slot)
458 return *slot;
459 node = ggc_alloc_cleared (sizeof (*node));
460 node->decl = decl;
461 cgraph_varpool_n_nodes ++;
462 cgraph_varpool_nodes = node;
463 *slot = node;
464 return node;
465 }
Then structure cgraph_varpool_node has following definition.
134 struct cgraph_varpool_node GTY(()) in cgraph.h
135 {
136 tree decl;
137 /* Pointer to the next function in cgraph_varpool_nodes_queue. */
138 struct cgraph_varpool_node *next_needed;
139
140 /* Set when function must be output - it is externally visible
141 or it's address is taken. */
142 bool needed;
143 /* Set once it has been finalized so we consider it to be output. */
144 bool finalized;
145 /* Set when function is scheduled to be assembled. */
146 bool output;
147 };
Above at line 1572, import_export_class determines if it needs output the whole set of the class in this translation-unit or just signiture but references will be solved at link time.
Remember that option -fno-implicit-templates means never emit code for non-inline templates which are instantiated implictly. For the case we suppress the emission by setting import_export to -1.
Next it needs decide whether the specified vtable is external or not (even if the class is external, but if any of its base is defined in this translation-unit and output its vtable here, the vtable of the class also needs be output here).
1442 void
1443 import_export_vtable (tree decl, tree type, int final) in decl2.c
1444 {
1445 if (DECL_INTERFACE_KNOWN (decl))
1446 return ;
1447
1448 if (TYPE_FOR_JAVA (type))
1449 {
1450 TREE_PUBLIC (decl) = 1;
1451 DECL_EXTERNAL (decl) = 1;
1452 DECL_INTERFACE_KNOWN (decl) = 1;
1453 }
1454 else if (CLASSTYPE_INTERFACE_KNOWN (type))
1455 {
1456 TREE_PUBLIC (decl) = 1;
1457 DECL_EXTERNAL (decl) = CLASSTYPE_INTERFACE_ONLY (type);
1458 DECL_INTERFACE_KNOWN (decl) = 1;
1459 }
1460 else
1461 {
1462 /* We can only wait to decide if we have real non-inline virtual
1463 functions in our class, or if we come from a template. */
1464
1465 int found = (CLASSTYPE_TEMPLATE_INSTANTIATION (type)
1466 || CLASSTYPE_KEY_METHOD (type) != NULL_TREE);
1467
1468 if (final || ! found)
1469 {
1470 comdat_linkage (decl);
1471 DECL_EXTERNAL (decl) = 0;
1472 }
1473 else
1474 {
1475 TREE_PUBLIC (decl) = 1;
1476 DECL_EXTERNAL (decl) = 1;
1477 }
1478 }
1479 }
After import_export_vtable sets flags for VAL_DECL of the vtable, DECL_NEEDED_P tells if the vtable needs be emitted. Predicate DECL_COMDAT if holds, indicates that, even if it TREE_PUBLIC, it needs not be put out unless it is needed in this translation unit. Entities like this are shared across translation units (like weak entities), but are guaranteed to be generated by any translation unit that needs them, and therefore need not be put out anywhere where they are not needed. DECL_COMDAT is just a hint to the back-end; it is up to front-ends which set this flag to ensure that there will never be any harm, other than bloat, in putting out something which is DECL_COMDAT.
1730 #define DECL_NEEDED_P (DECL) / in cp-tree.h
1731 ((at_eof && TREE_PUBLIC (DECL) && !DECL_COMDAT (DECL)) /
1732 || (DECL_ASSEMBLER_NAME_SET_P (DECL) /
1733 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL)))/
1734 || (((flag_syntax_only || flag_unit_at_a_time ) && TREE_USED (DECL))))
If any vtable in the vtable chain needs code emitted, the compiler will emit code for all vtables within. Mark them here.
maybe_emit_vtables (continue)
1595 /* The ABI requires that we emit all of the vtables if we emit any
1596 of them. */
1597 for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl))
1598 {
1599 /* Write it out. */
1600 import_export_vtable (vtbl, ctype, 1);
1601 mark_vtable_entries (vtbl);
1602
1603 /* If we know that DECL is needed, mark it as such for the varpool. */
1604 if (needed)
1605 cgraph_varpool_mark_needed_node (cgraph_varpool_node (vtbl));
1606
1607 if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
1608 {
1609 /* It had better be all done at compile-time. */
1610 if (store_init_value (vtbl, DECL_INITIAL (vtbl)))
1611 abort ();
1612 }
1613
1614 if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG)
1615 {
1616 /* Mark the VAR_DECL node representing the vtable itself as a
1617 "gratuitous" one, thereby forcing dwarfout.c to ignore it.
1618 It is rather important that such things be ignored because
1619 any effort to actually generate DWARF for them will run
1620 into trouble when/if we encounter code like:
1621
1622 #pragma interface
1623 struct S { virtual void member (); };
1624
1625 because the artificial declaration of the vtable itself (as
1626 manufactured by the g++ front end) will say that the vtable
1627 is a static member of `S' but only *after* the debug output
1628 for the definition of `S' has already been output. This causes
1629 grief because the DWARF entry for the definition of the vtable
1630 will try to refer back to an earlier *declaration* of the
1631 vtable as a static member of `S' and there won't be one.
1632 We might be able to arrange to have the "vtable static member"
1633 attached to the member list for `S' before the debug info for
1634 `S' get written (which would solve the problem) but that would
1635 require more intrusive changes to the g++ front end. */
1636
1637 DECL_IGNORED_P (vtbl) = 1;
1638 }
1639
1640 /* Always make vtables weak. */
1641 if (flag_weak )
1642 comdat_linkage (vtbl);
1643
1644 rest_of_decl_compilation (vtbl, NULL, 1, 1);
1645
1646 /* Because we're only doing syntax-checking, we'll never end up
1647 actually marking the variable as written. */
1648 if (flag_syntax_only )
1649 TREE_ASM_WRITTEN (vtbl) = 1;
1650 }
1651
1652 /* Since we're writing out the vtable here, also write the debug
1653 info. */
1654 note_debug_info_needed (ctype);
1655
1656 return true;
1657 }
Below function just tags the virtual function as addressable and sets in-used flag to indicate the compiler to emit code later. Remember CONSTRUCTOR is always created for initializers of vtable, CONSTRUCTOR_ELTS in debug mode can do extra checking to ensure it’s indeed entity of CONSTRUCTOR and extract the initializers for the vtables (refers to initialize_array in initialize_vtable or build_vtt . Also refers section Finish the RECORD_TYPE – generate vtable for examples of initialziers).
1323 static void
1324 mark_vtable_entries (tree decl) in decl2.c
1325 {
1326 tree entries = CONSTRUCTOR_ELTS (DECL_INITIAL (decl));
1327
1328 for (; entries; entries = TREE_CHAIN (entries))
1329 {
1330 tree fnaddr = TREE_VALUE (entries);
1331 tree fn;
1332
1333 STRIP_NOPS (fnaddr);
1334
1335 if (TREE_CODE (fnaddr) != ADDR_EXPR
1336 && TREE_CODE (fnaddr) != FDESC_EXPR)
1337 /* This entry is an offset: a virtual base class offset, a
1338 virtual call offset, an RTTI offset, etc. */
1339 continue ;
1340
1341 fn = TREE_OPERAND (fnaddr, 0);
1342 TREE_ADDRESSABLE (fn) = 1;
1343 /* When we don't have vcall offsets, we output thunks whenever
1344 we output the vtables that contain them. With vcall offsets,
1345 we know all the thunks we'll need when we emit a virtual
1346 function, so we emit the thunks there instead. */
1347 if (DECL_THUNK_P (fn))
1348 use_thunk (fn, /*emit_p=*/ 0);
1349 mark_used (fn);
1350 }
1351 }
Marks decl as in-used can help compiler to remove useless code in later optimization. The flag is set at line 2982 below. Then for unemitted inline method (generally, except in-charge constructor and destructor, inline method isn’t emitted yet. Considering inline method is defined in header file, which may be included by several files within the translation-unit, deferring its handling till the last moment is necessary. Though here the caller of mark_used is within the last step of the process in front-end, however mark_used is called in many places in the front-end), caches it by deferred_fns . At line 2991, assemble_external is trivial for Linux on x86 machine. In previous section, we have seen that comipler may generate method artificially (for exmaple, cloned ctor and dctor in class), such method shouldn’t run itself but triggered by user defined method instead (referred by current_function_decl ). If DECL_INITIAL is empty at line 2998, it means the function has still not been proccessed by call sequence: start_function , begin_function_body , begin_compound_stmt || finish_compound_stmt , finish_function_body , finish_function – that is not STMT node built for it and linked into STMT list of its trigger yet. Below synthesize_method invokes above mentioned call sequence to generate necessary STMT nodes for the function, as if it comes from user declaration. Further, skip_evaluation at line 2983 was set by parser. In C++, there is case that no evalutaion of the declaration or expression is required, for example, within operator of sizeof or typeof .
2967 void
2968 mark_used (tree decl) in decl2.c
2969 {
2970 /* If DECL is a BASELINK for a single function, then treat it just
2971 like the DECL for the function. Otherwise, if the BASELINK is
2972 for an overloaded function, we don't know which function was
2973 actually used until after overload resolution. */
2974 if (TREE_CODE (decl) == BASELINK)
2975 {
2976 decl = BASELINK_FUNCTIONS (decl);
2977 if (really_overloaded_fn (decl))
2978 return ;
2979 decl = OVL_CURRENT (decl);
2980 }
2981
2982 TREE_USED (decl) = 1;
2983 if (processing_template_decl || skip_evaluation )
2984 return ;
2985
2986 if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)
2987 && !TREE_ASM_WRITTEN (decl))
2988 /* Remember it, so we can check it was defined. */
2989 defer_fn (decl);
2990
2991 assemble_external (decl);
2992
2993 /* Is it a synthesized method that needs to be synthesized? */
2994 if (TREE_CODE (decl) == FUNCTION_DECL
2995 && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
2996 && DECL_ARTIFICIAL (decl)
2997 && !DECL_THUNK_P (decl)
2998 && ! DECL_INITIAL (decl)
2999 /* Kludge: don't synthesize for default args. */
3000 && current_function_decl )
3001 {
3002 synthesize_method (decl);
3003 /* If we've already synthesized the method we don't need to
3004 instantiate it, so we can return right away. */
3005 return ;
3006 }
3007
3008 /* If this is a function or variable that is an instance of some
3009 template, we now know that we will need to actually do the
3010 instantiation. We check that DECL is not an explicit
3011 instantiation because that is not checked in instantiate_decl. */
3012 if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL)
3013 && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
3014 && (!DECL_EXPLICIT_INSTANTIATION (decl)
3015 || (TREE_CODE (decl) == FUNCTION_DECL
3016 && DECL_INLINE (DECL_TEMPLATE_RESULT
3017 (template_for_substitution (decl))))))
3018 {
3019 bool defer;
3020
3021 /* Normally, we put off instantiating functions in order to
3022 improve compile times. Maintaining a stack of active
3023 functions is expensive, and the inliner knows to
3024 instantiate any functions it might need.
3025
3026 However, if instantiating this function might help us mark
3027 the current function TREE_NOTHROW, we go ahead and
3028 instantiate it now.
3029
3030 This is not needed for unit-at-a-time since we reorder the functions
3031 i n topological order anyway.
3032 */
3033 defer = (!flag_exceptions
3034 || flag_unit_at_a_time
3035 || !optimize
3036 || TREE_CODE (decl) != FUNCTION_DECL
3037 /* If the called function can't throw, we don't need to
3038 generate its body to find that out. */
3039 || TREE_NOTHROW (decl)
3040 || !cfun
3041 || !current_function_decl
3042 /* If we already know the current function can't throw,
3043 then we don't need to work hard to prove it. */
3044 || TREE_NOTHROW (current_function_decl )
3045 /* If we already know that the current function *can*
3046 throw, there's no point in gathering more
3047 information. */
3048 || cp_function_chain ->can_throw);
3049
3050 instantiate_decl (decl, defer);
3051 }
3052 }
We have seen that thunk is a compiler generating function, it should also be done with code emitted. However at this invocation, argument emit_p is false, as result, the function only marks the thunk as in-used and returns without really emitting code for it.
336 void
337 use_thunk (tree thunk_fndecl, bool emit_p) in method.c
338 {
339 tree function, alias;
340 tree virtual_offset;
341 HOST_WIDE_INT fixed_offset, virtual_value;
342 bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
343
344 /* We should have called finish_thunk to give it a name. */
345 my_friendly_assert (DECL_NAME (thunk_fndecl), 20021127);
346
347 /* We should never be using an alias, always refer to the
348 aliased thunk. */
349 my_friendly_assert (!THUNK_ALIAS (thunk_fndecl), 20031023);
350
351 if (TREE_ASM_WRITTEN (thunk_fndecl))
352 return ;
353
354 function = THUNK_TARGET (thunk_fndecl);
355 if (DECL_RESULT (thunk_fndecl))
356 /* We already turned this thunk into an ordinary function.
357 There's no need to process this thunk again. */
358 return ;
359
360 if (DECL_THUNK_P (function))
361 /* The target is itself a thunk, process it now. */
362 use_thunk (function, emit_p);
363
364 /* Thunks are always addressable; they only appear in vtables. */
365 TREE_ADDRESSABLE (thunk_fndecl) = 1;
366
367 /* Figure out what function is being thunked to. It's referenced in
368 this translation unit. */
369 TREE_ADDRESSABLE (function) = 1;
370 mark_used (function);
371 if (!emit_p)
372 return ;
…
524 }
If the vtable is public and not shared across translation-units, needed is set at line 1592 in maybe_emit_vtables , then at line 1605, below function is invoked to set the needed flag of associated cgraph_varpool_node.
568 void
569 cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node) in cgraph.c
570 {
571 if (!node->needed && node->finalized)
572 {
573 node->next_needed = cgraph_varpool_nodes_queue ;
574 cgraph_varpool_nodes_queue = node;
575 notice_global_symbol (node->decl);
576 }
577 node->needed = 1;
578 }
Next at line 1644 in maybe_emit_vtables , rest_of_decl_compilation is invoked to try to build the RTL node according to the intermediate node and outputs any assembler code (label definition, storage allocation and initialization) if required. Here, argument top_level and at_end are both 1, and asmspec is NULL. Note that at line 1957 ASM_FINISH_DECLARE_OBJECT is not defined for x86/Linux.
1910 void
1911 rest_of_decl_compilation (tree decl, in toplev.c
1912 const char *asmspec,
1913 int top_level,
1914 int at_end)
1915 {
1916 /* We deferred calling assemble_alias so that we could collect
1917 other attributes such as visibility. Emit the alias now. */
1918 {
1919 tree alias;
1920 alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
1921 if (alias)
1922 {
1923 alias = TREE_VALUE (TREE_VALUE (alias));
1924 alias = get_identifier (TREE_STRING_POINTER (alias));
1925 assemble_alias (decl, alias);
1926 }
1927 }
1928
1929 /* Forward declarations for nested functions are not "external",
1930 but we need to treat them as if they were. */
1931 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
1932 || TREE_CODE (decl) == FUNCTION_DECL)
1933 {
1934 timevar_push (TV_VARCONST);
1935
1936 if (asmspec)
1937 make_decl_rtl (decl, asmspec);
1938
1939 /* Don't output anything when a tentative file-scope definition
1940 is seen. But at end of compilation, do output code for them.
1941
1942 We do output all variables when unit-at-a-time is active and rely on
1943 callgraph code to defer them except for forward declarations
1944 (see gcc.c-torture/compile/920624-1.c) */
1945 if ((at_end
1946 || !DECL_DEFER_OUTPUT (decl)
1947 || (flag_unit_at_a_time && DECL_INITIAL (decl)))
1948 && !DECL_EXTERNAL (decl))
1949 {
1950 if (flag_unit_at_a_time && !cgraph_global_info_ready
1951 && TREE_CODE (decl) != FUNCTION_DECL && top_level)
1952 cgraph_varpool_finalize_decl (decl);
1953 else
1954 assemble_variable (decl, top_level, at_end, 0);
1955 }
1956
1957 #ifdef ASM_FINISH_DECLARE_OBJECT
…
1963 #endif
1964
1965 timevar_pop (TV_VARCONST);
1966 }
1967 else if (DECL_REGISTER (decl) && asmspec != 0)
1968 {
1969 if (decode_reg_name (asmspec) >= 0)
1970 {
1971 SET_DECL_RTL (decl, NULL_RTX);
1972 make_decl_rtl (decl, asmspec);
1973 }
1974 else
1975 {
1976 error ("invalid register name `%s' for register variable", asmspec);
1977 DECL_REGISTER (decl) = 0;
1978 if (!top_level)
1979 expand_decl (decl);
1980 }
1981 }
…
2011 }
At line 1950 cgraph_global_info_ready is nonzero when whole unit has been analyzed, so we can access global information (it is still false under current situation). Also predicate DECL_DEFER_OUTPUT at line 1946, if nonzero tells that the linkage status of this decl is not yet known, so it should not be output now.
As vtable is a VAR_DECL, we invoke following function to set finialized flag of associated cgraph_varpool_node to indicate code to be output.
580 void
581 cgraph_varpool_finalize_decl (tree decl) in cgraph.c
582 {
583 struct cgraph_varpool_node *node = cgraph_varpool_node (decl);
584
585 /* The first declaration of a variable that comes through this function
586 decides whether it is global (in C, has external linkage)
587 or local (in C, has internal linkage). So do nothing more
588 if this function has already run. */
589 if (node->finalized)
590 return ;
591 if (node->needed)
592 {
593 node->next_needed = cgraph_varpool_nodes_queue ;
594 cgraph_varpool_nodes_queue = node;
595 notice_global_symbol (decl);
596 }
597 node->finalized = true;
598
599 if (/* Externally visible variables must be output. The exception are
600 COMDAT functions that must be output only when they are needed. */
601 (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
602 /* Function whose name is output to the assembler file must be produced.
603 It is possible to assemble the name later after finalizing the function
604 and the fact is noticed in assemble_name then. */
605 || (DECL_ASSEMBLER_NAME_SET_P (decl)
606 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
607 {
608 cgraph_varpool_mark_needed_node (node);
609 }
610 }
As at line 1605 in maybe_emit_vtables , cgraph_varpool_mark_needed_node has been invoked for vtable that needs be output; for such vtable, needed flag of its cgraph node is true, and this node is linked into cgraph_varpool_nodes_queue again here (see in cgraph_varpool_mark_needed_node at line 571, the condition for linking is “(!node->needed && node->finalized)”, if not added at that time, it is linked here); at line 608 the vtable is processed by cgraph_varpool_mark_needed_node again, which is a measure to ensure the cgraph node to be linked into cgraph_varpool_nodes_queue .
Note that if maybe_emit_vtables processes the class successfully, the class would be removed from keyed_classes , and forces next iteration.