Function generated by the compiler (via implicitly_declare_fn , mark_decl_instantiated , or build_clone ) or inline method is cached in deferred_fns . Arriving here, we have parsed the whole source file, information needed in handling these deferred functions should be available.
First, for “artificial” method generated by the compiler itself, it has flag DECL_ARTIFICIAL set; In FUNCTION_DECL, its DECL_INITIAL field, after the front-end doing its job, should be trees of entities bound in this function scope (i.e., BLOCK nodes), otherwise it would be NULL. For “artificial” methods having empty DECL_INITIAL, the compiler just makes the declarations so far, now it needs to synthesize the definitions.
742 void
743 synthesize_method (tree fndecl) in method.c
744 {
745 bool nested = (current_function_decl != NULL_TREE);
746 tree context = decl_function_context (fndecl);
747 bool need_body = true;
748 tree stmt;
749
750 if (at_eof )
751 import_export_decl (fndecl);
752
753 /* If we've been asked to synthesize a clone, just synthesize the
754 cloned function instead. Doing so will automatically fill in the
755 body for the clone. */
756 if (DECL_CLONED_FUNCTION_P (fndecl))
757 {
758 synthesize_method (DECL_CLONED_FUNCTION (fndecl));
759 return ;
760 }
761
762 /* We may be in the middle of deferred access check. Disable
763 it now. */
764 push_deferring_access_checks (dk_no_deferred);
765
766 if (! context)
767 push_to_top_level ();
768 else if (nested)
769 push_function_context_to (context);
770
771 /* Put the function definition at the position where it is needed,
772 rather than within the body of the class. That way, an error
773 during the generation of the implicit body points at the place
774 where the attempt to generate the function occurs, giving the
775 user a hint as to why we are attempting to generate the
776 function. */
777 DECL_SOURCE_LOCATION (fndecl) = input_location ;
778
779 interface_unknown = 1;
780 start_function (NULL_TREE, fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
781 clear_last_expr ();
782 stmt = begin_function_body ();
783
784 if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR)
785 {
786 do_build_assign_ref (fndecl);
787 need_body = false;
788 }
789 else if (DECL_CONSTRUCTOR_P (fndecl))
790 {
791 tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
792 if (arg_chain != void_list_node)
793 do_build_copy_constructor (fndecl);
794 else if (TYPE_NEEDS_CONSTRUCTING (current_class_type ))
795 finish_mem_initializers (NULL_TREE);
796 }
797
798 /* If we haven't yet generated the body of the function, just
799 generate an empty compound statement. */
800 if (need_body)
801 {
802 tree compound_stmt;
803 compound_stmt = begin_compound_stmt (/*has_no_scope=*/ false);
804 finish_compound_stmt (compound_stmt);
805 }
806
807 finish_function_body (stmt);
808 expand_or_defer_fn (finish_function (0));
809
810 extract_interface_info ();
811 if (! context)
812 pop_from_top_level ();
813 else if (nested)
814 pop_function_context_from (context);
815
816 pop_deferring_access_checks ();
817 }
See the definition of synthesize_method will be done in global namespace. But never mind, as node of the function declarations already contain correct context information. Besides, context information only is used for name-lookup, all code should be emitted within global namespace with mangled name instead.
Note expand_or_defer_fn at line 808, which is also called at line 2769 in finish_file . However, as long as invoking this function here, in finish_file , condition at line 2762 is not satisfied, so no call any more. Before, one of major operation of expand_or_defer_fn is traversing the given function tree, and calling simplify_aggr_init_exprs_r to processing AGGR_INIT_EXPR nodes found. Gccint [2] gives below description:
AGGR_INIT_EXPR
An AGGR_INIT_EXPR represents the initialization as the return value of a function call, or as the result of a constructor. An AGGR_INIT_EXPR will only appear as the second operand of a TARGET_EXPR. The first operand to the AGGR_INIT_EXPR is the address of a function to call, just as in a CALL_EXPR. The second operand are the arguments to pass that function, as a TREE_LIST, again in a manner similar to that of a CALL_EXPR. The value of the expression is that returned by the function.
If AGGR_INIT_VIA_CTOR_P holds of the AGGR_INIT_EXPR, then the initialization is via a constructor call. The address of the third operand of the AGGR_INIT_EXPR, which is always a VAR_DECL, is taken, and this value replaces the first argument in the argument list. In this case, the value of the expression is the VAR_DECL given by the third operand to the AGGR_INIT_EXPR; constructors do not return a value.
It is the structure used in named return value optimization, the caller passes the address of a block of memory in which the value should be stored. This address is called the "structure value address". simplify_aggr_init_exprs_r combines the CALL_EXPR with its arguments and the temperary local variable (which is added as extra argument, as we try to return aggregate type); and inserts these nodes within the chain of DECL_SAVED_TREE (fn) .
2769 static tree
2770 simplify_aggr_init_exprs_r (tree* tp, in semantics.c
2771 int* walk_subtrees,
2772 void* data ATTRIBUTE_UNUSED)
2773 {
2774 /* We don't need to walk into types; there's nothing in a type that
2775 needs simplification. (And, furthermore, there are places we
2776 actively don't want to go. For example, we don't want to wander
2777 into the default arguments for a FUNCTION_DECL that appears in a
2778 CALL_EXPR.) */
2779 if (TYPE_P (*tp))
2780 {
2781 *walk_subtrees = 0;
2782 return NULL_TREE;
2783 }
2784 /* Only AGGR_INIT_EXPRs are interesting. */
2785 else if (TREE_CODE (*tp) != AGGR_INIT_EXPR)
2786 return NULL_TREE;
2787
2788 simplify_aggr_init_expr (tp);
2789
2790 /* Keep iterating. */
2791 return NULL_TREE;
2792 }
It see that simplify_aggr_init_exprs_r always returns NULL, which forces walk_tree to visit the whole tree. As in a function definition it may contain more than 1 node of AGGR_INIT_EXPR. For example:
class A {…};
class B {
public :
B (const A&);
…
};
A func1 () {…}
B func2 () {
B b = func1 (); // 1st AGGR_INIT_EXPR
return b; // 2nd AGGR_INIT_EXPR
}
AGGR_INIT_EXPR is handled by below function. Note that fn gotten at line 2804 is the address of the function (i.e., node of ADDR_EXPR).
2798 void
2799 simplify_aggr_init_expr (tree *tp) in semantics.c
2800 {
2801 tree aggr_init_expr = *tp;
2802
2803 /* Form an appropriate CALL_EXPR. */
2804 tree fn = TREE_OPERAND (aggr_init_expr, 0);
2805 tree args = TREE_OPERAND (aggr_init_expr, 1);
2806 tree slot = TREE_OPERAND (aggr_init_expr, 2);
2807 tree type = TREE_TYPE (aggr_init_expr);
2808
2809 tree call_expr;
2810 enum style_t { ctor, arg, pcc } style;
2811
2812 if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr))
2813 style = ctor;
2814 #ifdef PCC_STATIC_STRUCT_RETURN
2815 else if (1)
2816 style = pcc;
2817 #endif
2818 else if (TREE_ADDRESSABLE (type))
2819 style = arg;
2820 else
2821 /* We shouldn't build an AGGR_INIT_EXPR if we don't need any special
2822 handling. See build_cplus_new. */
2823 abort ();
2824
2825 if (style == ctor || style == arg)
2826 {
2827 /* Pass the address of the slot. If this is a constructor, we
2828 replace the first argument; otherwise, we tack on a new one. */
2829 tree addr;
2830
2831 if (style == ctor)
2832 args = TREE_CHAIN (args);
2833
2834 cxx_mark_addressable (slot);
2835 addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (slot)), slot);
2836 if (style == arg)
2837 {
2838 /* The return type might have different cv-quals from the slot. */
2839 tree fntype = TREE_TYPE (TREE_TYPE (fn));
2840 #ifdef ENABLE_CHECKING
2841 if (TREE_CODE (fntype) != FUNCTION_TYPE
2842 && TREE_CODE (fntype) != METHOD_TYPE)
2843 abort ();
2844 #endif
2845 addr = convert (build_pointer_type (TREE_TYPE (fntype)), addr);
2846 }
2847
2848 args = tree_cons (NULL_TREE, addr, args);
2849 }
2850
2851 call_expr = build (CALL_EXPR,
2852 TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
2853 fn, args, NULL_TREE);
2854
2855 if (style == arg)
2856 /* Tell the backend that we've added our return slot to the argument
2857 list. */
2858 CALL_EXPR_HAS_RETURN_SLOT_ADDR (call_expr) = 1;
2859 else if (style == pcc)
2860 {
2861 /* If we're using the non-reentrant PCC calling convention, then we
2862 need to copy the returned value out of the static buffer into the
2863 SLOT. */
2864 push_deferring_access_checks (dk_no_check);
2865 call_expr = build_aggr_init (slot, call_expr,
2866 DIRECT_BIND | LOOKUP_ONLYCONVERTING);
2867 pop_deferring_access_checks ();
2868 }
2869
2870 /* We want to use the value of the initialized location as the
2871 result. */
2872 call_expr = build (COMPOUND_EXPR, type,
2873 call_expr, slot);
2874
2875 /* Replace the AGGR_INIT_EXPR with the CALL_EXPR. */
2876 TREE_CHAIN (call_expr) = TREE_CHAIN (aggr_init_expr);
2877 *tp = call_expr;
2878 }
As named return value optimization will strip the return statement from the function, at line 2872, the original call expression needs be replaced by a compound statement to make the return value can be acquired correctly. Next see line 2834, the variable holding the return value is marked as addressable, it will affect the RTL generation deeply. And PCC_STATIC_STRUCT_RETURN at line 2814 is defined if the usual system convention on the target machine for returning structures and unions is for the called function to return the address of a static variable containing the value. It is not defined for x86 machine.