Studying note of GCC-3.4.6 source (159)
2011-02-11 08:09
369 查看
5.13.4.4.
Iterate – emitting code for deferred function
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.
相关文章推荐
- Studying note of GCC-3.4.6 source (131)
- Studying note of GCC-3.4.6 source (10 cont2)
- Studying note of GCC-3.4.6 source (144)
- Studying note of GCC-3.4.6 source (22)
- Studying note of GCC-3.4.6 source (161)
- Studying note of GCC-3.4.6 source (25 cont2)
- Studying note of GCC-3.4.6 source (171)
- Studying note of GCC-3.4.6 source (172)
- Studying note of GCC-3.4.6 source (51)
- Studying note of GCC-3.4.6 source (71)
- Studying note of GCC-3.4.6 source (111)
- Studying note of GCC-3.4.6 source (125)
- Studying note of GCC-3.4.6 source (137)
- Studying note of GCC-3.4.6 source (141)
- Studying note of GCC-3.4.6 source (10 cont3)
- Studying note of GCC-3.4.6 source (148)
- Studying note of GCC-3.4.6 source (24)
- Studying note of GCC-3.4.6 source (162 - continue)
- Studying note of GCC-3.4.6 source (59)
- Studying note of GCC-3.4.6 source (78)