Studying note of GCC-3.4.6 source (111)
2010-10-11 11:52
369 查看
5.12.3.2.1.2.1.3.
Finish
function handling
Then finish_function
will finish filling-up of
node of FUNCTION_DECL for the function. We will go back to this function later
again for other example.
10815
tree
10816
finish_function
(int flags)
in decl.c
10817
{
10818
tree fndecl = current_function_decl
;
10819
tree fntype, ctype =
NULL_TREE;
10820
int inclass_inline = (flags
& 2) != 0;
10821
int nested;
10822
10823
/*
When we get some parse errors, we can end up without a
10824
current_function_decl, so cope.
*/
10825
if (fndecl == NULL_TREE)
10826
return
error_mark_node;
10827
10828
if
(DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
10829
&& DECL_VIRTUAL_P
(fndecl)
10830
&& ! processing_template_decl
)
10831
{
10832
tree fnclass =
DECL_CONTEXT (fndecl);
10833
if (fndecl ==
CLASSTYPE_KEY_METHOD (fnclass))
10834
keyed_classes =
tree_cons (NULL_TREE, fnclass, keyed_classes);
10835
}
10836
10837
nested = function_depth
> 1;
10838
fntype = TREE_TYPE (fndecl);
10839
10840
/*
TREE_READONLY (fndecl) = 1;
10841
This
caused &foo to be of type ptr-to-const-function
10842
which
then got a warning when stored in a ptr-to-function variable.
*/
10843
10844
my_friendly_assert
(building_stmt_tree (), 20000911);
10845
10846
/*
For a cloned function, we've already got all the code we need;
10847
there's no need to add any extra bits.
*/
10848
if (!DECL_CLONED_FUNCTION_P
(fndecl))
10849
{
10850
if (DECL_MAIN_P (current_function_decl
))
10851
{
10852
/*
Make it so that `main' always returns 0 by default.
*/
10853
#if
VMS_TARGET
10854
finish_return_stmt
(integer_one_node);
10855
#else
10856
finish_return_stmt
(integer_zero_node);
10857
#endif
10858
}
10859
10860
/*
Finish dealing with exception specifiers.
*/
10861
if (flag_exceptions
&& ! processing_template_decl
10862
&& flag_enforce_eh_specs
10863
&&
TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl
)))
10864
finish_eh_spec_block
(TYPE_RAISES_EXCEPTIONS
10865
(TREE_TYPE (current_function_decl
)),
10866
current_eh_spec_block);
10867
}
10868
10869
finish_fname_decls
();
10870
10871
/*
If we're saving up tree structure, tie off the function now.
*/
10872
finish_stmt_tree
(&DECL_SAVED_TREE (fndecl));
If assignment statements are generated for “__FUNCTION__” and like,
field TREE_VALUE of the associated item in saved_function_name_decls
will record the
statements. As there may be more than one assignments kept in saved_function_name_decls
(correspond to “__FUNCTION__”, “__func__”, “__PRETTY_FUNCTION__”), so below at
line 1019, FOR loop integrates these statements.
1012
void
1013
finish_fname_decls
(void)
in c-common.c
1014
{
1015
unsigned ix;
1016
tree body = NULL_TREE;
1017
tree stack =
saved_function_name_decls;
1018
1019
for
(; stack && TREE_VALUE (stack); stack = TREE_CHAIN (stack))
1020
body = chainon (TREE_VALUE
(stack), body);
1021
1022
if (body)
1023
{
1024
/*
They were called into existence, so add to statement tree. Add
1025
the
DECL_STMTs inside the outermost scope.
*/
1026
tree *p =
&DECL_SAVED_TREE (current_function_decl
);
1027
/*
Skip the dummy EXPR_STMT and any EH_SPEC_BLOCK.
*/
1028
while
(TREE_CODE (*p) != COMPOUND_STMT)
1029
{
1030
if (TREE_CODE (*p) ==
EXPR_STMT)
1031
p = &TREE_CHAIN
(*p);
1032
else
1033
p =
&TREE_OPERAND(*p, 0);
1034
}
1035
1036
p = &COMPOUND_BODY
(*p);
1037
if (TREE_CODE (*p) ==
SCOPE_STMT)
1038
p = &TREE_CHAIN
(*p);
1039
1040
body = chainon (body, *p);
1041
*p = body;
1042
}
1043
1044
for
(ix = 0; fname_vars
[ix].decl;
ix++)
1045
*fname_vars
[ix].decl = NULL_TREE;
1046
1047
if (stack)
1048
{
1049
/*
We had saved values, restore them.
*/
1050
tree saved;
1051
1052
for
(saved = TREE_PURPOSE (stack); saved; saved = TREE_CHAIN (saved))
1053
{
1054
tree decl = TREE_PURPOSE
(saved);
1055
unsigned ix =
TREE_INT_CST_LOW (TREE_VALUE (saved));
1056
1057
*fname_vars
[ix].decl = decl;
1058
}
1059
stack = TREE_CHAIN
(stack);
1060
}
1061
saved_function_name_decls =
stack;
1062
}
IF block At line 1012 puts these statements at head of the
function-body. As these statements are saved by fname_vars
[ix].decl before, now
they got handled, and at exitting the function, they no longer valid; FOR loop
at line 1044 cleans fname_vars
[ix]. And FOR loop at line 1052 in fact
restores fname_vars
[ix].decl’s
initial value.
165
void
166
finish_stmt_tree
(tree *t)
in c-semantics.c
167
{
168
tree stmt;
169
170
/*
Remove the fake extra statement added in begin_stmt_tree.
*/
171
stmt = TREE_CHAIN (*t);
172
*t = stmt;
173
last_tree = NULL_TREE;
174
175
if (cfun
&& stmt)
176
{
177
/*
The line-number recorded in the outermost statement in a function
178
is the line number of the end of the
function.
*/
179
STMT_LINENO (stmt) =
input_line;
180
STMT_LINENO_FOR_FN_P
(stmt) = 1;
181
}
182
}
In begin_stmt_tree
,
a fake statement of void_zero_node
is created because seeing in above
address of it is needed for inserting the statements. Now as statements are all
linked in, this fake node can be removed.
finish_function (continue)
10874
/*
If this function can't throw any exceptions, remember that.
*/
10875
if (!processing_template_decl
10876
&&
!cp_function_chain->can_throw
10877
&& !flag_non_call_exceptions
)
10878
TREE_NOTHROW (fndecl) = 1;
10879
10880
/*
This must come after expand_function_end because cleanups might
10881
have
declarations (from inline functions) that need to go into
10882
this
function's blocks.
*/
10883
10884
/*
If the current binding level isn't the outermost binding level
10885
for
this function, either there is a bug, or we have experienced
10886
syntax
errors and the statement tree is malformed.
*/
10887
if (
current_binding_level
->kind != sk_function_parms)
10888
{
…
10904
}
10905
poplevel
(1, 0, 1);
10906
10907
/*
Statements should always be full-expressions at the outermost set
10908
of
curly braces for a function.
*/
10909
my_friendly_assert (stmts_are_full_exprs_p
(), 19990831);
10910
10911
/*
Set up the named return value optimization, if we can. Here, we
10912
eliminate the copy from the nrv into the RESULT_DECL and any cleanup
10913
for
the nrv. genrtl_start_function and declare_return_variable
10914
handle
making the nrv and RESULT_DECL share space.
*/
10915
if (current_function_return_value
)
10916
{
…
10941
}
10942
10943
/*
Remember that we were in class scope.
*/
10944
if (current_class_name)
10945
ctype = current_class_type
;
10946
10947
/*
Must mark the RESULT_DECL as being in this function.
*/
10948
DECL_CONTEXT (DECL_RESULT
(fndecl)) = fndecl;
10949
10950
/*
Set the BLOCK_SUPERCONTEXT of the outermost function scope to point
10951
to the
FUNCTION_DECL node itself.
*/
10952
BLOCK_SUPERCONTEXT (DECL_INITIAL
(fndecl)) = fndecl;
10953
10954
/*
Save away current state, if appropriate.
*/
10955
if (!processing_template_decl
)
10956
save_function_data
(fndecl);
By the language grammar, function without declaring throws any
exception can throw exception of any kind; to declare a function throw no
exception, you should use nothrow at the end of the declaration. This
information is useful for optimization, needs record it within the
FUNCTION_DECL node. And IF
block
beginning at line 10915 is for named return value optimization purpose, we will
come to this topic later.
10614
static
void
10615
save_function_data
(tree decl)
in decl.c
10616
{
10617
struct
language_function *f;
10618
10619
/*
Save the language-specific per-function data so that we can
10620
get it
back when we really expand this function.
*/
10621
my_friendly_assert
(!DECL_PENDING_INLINE_P (decl),
10622
19990908);
10623
10624
/*
Make a copy.
*/
10625
f = ggc_alloc (sizeof
(struct
language_function));
10626
memcpy (f,
cp_function_chain, sizeof
(struct
language_function));
10627
DECL_SAVED_FUNCTION_DATA
(decl) = f;
10628
10629
/*
Clear out the bits we don't need.
*/
10630
f->base.x_stmt_tree.x_last_stmt = NULL_TREE;
10631
f->base.x_stmt_tree.x_last_expr_type = NULL_TREE;
10632
f->x_named_label_uses =
NULL;
10633
f->bindings = NULL;
10634
f->x_local_names = NULL;
10635
10636
/*
If we've already decided that we cannot inline this function, we
10637
must
remember that fact when we actually go to expand the
10638
function.
*/
10639
if
(current_function_cannot_inline)
10640
{
10641
f->cannot_inline =
current_function_cannot_inline;
10642
DECL_INLINE (decl) = 0;
10643
}
10644
}
If it is method of class-template, the method is not the real
function declaration. For the real function declaration, it needs remember this
associated language_function and release cfun
as we get out of the function declaration
and scope now. It is done by save_function_data
.
finish_function (continue)
10958
/*
If this function calls `setjmp' it cannot be inlined. When
10959
`longjmp' is called it is not guaranteed to restore the value of
10960
local
variables that have been modified since the call to
10961
`setjmp'. So, if were to inline this function into some caller
10962
`c',
then when we `longjmp', we might not restore all variables
10963
in
`c'. (It might seem, at first blush, that there's no way for
10964
this
function to modify local variables in `c', but their
10965
addresses may have been stored somewhere accessible to this
10966
function.)
*/
10967
if (!processing_template_decl
&&
calls_setjmp_p (fndecl))
10968
DECL_UNINLINABLE (fndecl)
= 1;
10969
10970
/*
Complain if there's just no return statement.
*/
10971
if (warn_return_type
10972
&& TREE_CODE
(TREE_TYPE (fntype)) != VOID_TYPE
10973
&& !dependent_type_p (TREE_TYPE
(fntype))
10974
&& !current_function_returns_value
&& !current_function_returns_null
10975
/* Don't complain if we abort or throw.
*/
10976
&& !current_function_returns_abnormally
10977
&& !DECL_NAME
(DECL_RESULT (fndecl))
10978
/*
Normally, with -Wreturn-type, flow will complain. Unless we're an
10979
inline function, as we might never be compiled
separately.
*/
10980
&& (DECL_INLINE
(fndecl) || processing_template_decl
))
10981
warning ("no return
statement in function returning non-void");
10982
10983
/*
We're leaving the context of this function, so zap cfun. It's still in
10984
DECL_SAVED_INSNS, and we'll restore it in tree_rest_of_compilation.
*/
10985
cfun
= NULL;
10986
current_function_decl
= NULL;
10987
10988
/*
If this is an in-class inline definition, we may have to pop the
10989
bindings for the template parameters that we added in
10990
maybe_begin_member_template_processing when start_function was
10991
called.
*/
10992
if (inclass_inline)
10993
maybe_end_member_template_processing ();
10994
10995
/*
Leave the scope of the class.
*/
10996
if (ctype)
10997
pop_nested_class
();
10998
10999
--function_depth
;
11000
11001
/*
Clean up.
*/
11002
if (! nested)
11003
/*
Let the error reporting routines know that we're outside a
11004
function. For a nested function, this value is used in
11005
cxx_pop_function_context and then reset via pop_function_context.
*/
11006
current_function_decl
= NULL_TREE;
11007
11008
return
fndecl;
11009
}
Being a method of class, it is either defined outside the class
body, or defined as inclass-inline, no matter what kind, ctype at line 10996
points to the class node which forms the context for the method. When finish
handling the method, it also steps out of the class (remember for
inclass-inline definition, its handling is deferred to the finish of class
body). Exitting from the class scope is done by pop_nested_class
.
5650
void
5651
pop_nested_class
(void)
in class.c
5652
{
5653
tree context = DECL_CONTEXT
(TYPE_MAIN_DECL (current_class_type
));
5654
5655
popclass
();
5656
if (context &&
CLASS_TYPE_P (context))
5657
pop_nested_class ();
5658
}
Finish
function handling
Then finish_function
will finish filling-up of
node of FUNCTION_DECL for the function. We will go back to this function later
again for other example.
10815
tree
10816
finish_function
(int flags)
in decl.c
10817
{
10818
tree fndecl = current_function_decl
;
10819
tree fntype, ctype =
NULL_TREE;
10820
int inclass_inline = (flags
& 2) != 0;
10821
int nested;
10822
10823
/*
When we get some parse errors, we can end up without a
10824
current_function_decl, so cope.
*/
10825
if (fndecl == NULL_TREE)
10826
return
error_mark_node;
10827
10828
if
(DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
10829
&& DECL_VIRTUAL_P
(fndecl)
10830
&& ! processing_template_decl
)
10831
{
10832
tree fnclass =
DECL_CONTEXT (fndecl);
10833
if (fndecl ==
CLASSTYPE_KEY_METHOD (fnclass))
10834
keyed_classes =
tree_cons (NULL_TREE, fnclass, keyed_classes);
10835
}
10836
10837
nested = function_depth
> 1;
10838
fntype = TREE_TYPE (fndecl);
10839
10840
/*
TREE_READONLY (fndecl) = 1;
10841
This
caused &foo to be of type ptr-to-const-function
10842
which
then got a warning when stored in a ptr-to-function variable.
*/
10843
10844
my_friendly_assert
(building_stmt_tree (), 20000911);
10845
10846
/*
For a cloned function, we've already got all the code we need;
10847
there's no need to add any extra bits.
*/
10848
if (!DECL_CLONED_FUNCTION_P
(fndecl))
10849
{
10850
if (DECL_MAIN_P (current_function_decl
))
10851
{
10852
/*
Make it so that `main' always returns 0 by default.
*/
10853
#if
VMS_TARGET
10854
finish_return_stmt
(integer_one_node);
10855
#else
10856
finish_return_stmt
(integer_zero_node);
10857
#endif
10858
}
10859
10860
/*
Finish dealing with exception specifiers.
*/
10861
if (flag_exceptions
&& ! processing_template_decl
10862
&& flag_enforce_eh_specs
10863
&&
TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl
)))
10864
finish_eh_spec_block
(TYPE_RAISES_EXCEPTIONS
10865
(TREE_TYPE (current_function_decl
)),
10866
current_eh_spec_block);
10867
}
10868
10869
finish_fname_decls
();
10870
10871
/*
If we're saving up tree structure, tie off the function now.
*/
10872
finish_stmt_tree
(&DECL_SAVED_TREE (fndecl));
If assignment statements are generated for “__FUNCTION__” and like,
field TREE_VALUE of the associated item in saved_function_name_decls
will record the
statements. As there may be more than one assignments kept in saved_function_name_decls
(correspond to “__FUNCTION__”, “__func__”, “__PRETTY_FUNCTION__”), so below at
line 1019, FOR loop integrates these statements.
1012
void
1013
finish_fname_decls
(void)
in c-common.c
1014
{
1015
unsigned ix;
1016
tree body = NULL_TREE;
1017
tree stack =
saved_function_name_decls;
1018
1019
for
(; stack && TREE_VALUE (stack); stack = TREE_CHAIN (stack))
1020
body = chainon (TREE_VALUE
(stack), body);
1021
1022
if (body)
1023
{
1024
/*
They were called into existence, so add to statement tree. Add
1025
the
DECL_STMTs inside the outermost scope.
*/
1026
tree *p =
&DECL_SAVED_TREE (current_function_decl
);
1027
/*
Skip the dummy EXPR_STMT and any EH_SPEC_BLOCK.
*/
1028
while
(TREE_CODE (*p) != COMPOUND_STMT)
1029
{
1030
if (TREE_CODE (*p) ==
EXPR_STMT)
1031
p = &TREE_CHAIN
(*p);
1032
else
1033
p =
&TREE_OPERAND(*p, 0);
1034
}
1035
1036
p = &COMPOUND_BODY
(*p);
1037
if (TREE_CODE (*p) ==
SCOPE_STMT)
1038
p = &TREE_CHAIN
(*p);
1039
1040
body = chainon (body, *p);
1041
*p = body;
1042
}
1043
1044
for
(ix = 0; fname_vars
[ix].decl;
ix++)
1045
*fname_vars
[ix].decl = NULL_TREE;
1046
1047
if (stack)
1048
{
1049
/*
We had saved values, restore them.
*/
1050
tree saved;
1051
1052
for
(saved = TREE_PURPOSE (stack); saved; saved = TREE_CHAIN (saved))
1053
{
1054
tree decl = TREE_PURPOSE
(saved);
1055
unsigned ix =
TREE_INT_CST_LOW (TREE_VALUE (saved));
1056
1057
*fname_vars
[ix].decl = decl;
1058
}
1059
stack = TREE_CHAIN
(stack);
1060
}
1061
saved_function_name_decls =
stack;
1062
}
IF block At line 1012 puts these statements at head of the
function-body. As these statements are saved by fname_vars
[ix].decl before, now
they got handled, and at exitting the function, they no longer valid; FOR loop
at line 1044 cleans fname_vars
[ix]. And FOR loop at line 1052 in fact
restores fname_vars
[ix].decl’s
initial value.
165
void
166
finish_stmt_tree
(tree *t)
in c-semantics.c
167
{
168
tree stmt;
169
170
/*
Remove the fake extra statement added in begin_stmt_tree.
*/
171
stmt = TREE_CHAIN (*t);
172
*t = stmt;
173
last_tree = NULL_TREE;
174
175
if (cfun
&& stmt)
176
{
177
/*
The line-number recorded in the outermost statement in a function
178
is the line number of the end of the
function.
*/
179
STMT_LINENO (stmt) =
input_line;
180
STMT_LINENO_FOR_FN_P
(stmt) = 1;
181
}
182
}
In begin_stmt_tree
,
a fake statement of void_zero_node
is created because seeing in above
address of it is needed for inserting the statements. Now as statements are all
linked in, this fake node can be removed.
finish_function (continue)
10874
/*
If this function can't throw any exceptions, remember that.
*/
10875
if (!processing_template_decl
10876
&&
!cp_function_chain->can_throw
10877
&& !flag_non_call_exceptions
)
10878
TREE_NOTHROW (fndecl) = 1;
10879
10880
/*
This must come after expand_function_end because cleanups might
10881
have
declarations (from inline functions) that need to go into
10882
this
function's blocks.
*/
10883
10884
/*
If the current binding level isn't the outermost binding level
10885
for
this function, either there is a bug, or we have experienced
10886
syntax
errors and the statement tree is malformed.
*/
10887
if (
current_binding_level
->kind != sk_function_parms)
10888
{
…
10904
}
10905
poplevel
(1, 0, 1);
10906
10907
/*
Statements should always be full-expressions at the outermost set
10908
of
curly braces for a function.
*/
10909
my_friendly_assert (stmts_are_full_exprs_p
(), 19990831);
10910
10911
/*
Set up the named return value optimization, if we can. Here, we
10912
eliminate the copy from the nrv into the RESULT_DECL and any cleanup
10913
for
the nrv. genrtl_start_function and declare_return_variable
10914
handle
making the nrv and RESULT_DECL share space.
*/
10915
if (current_function_return_value
)
10916
{
…
10941
}
10942
10943
/*
Remember that we were in class scope.
*/
10944
if (current_class_name)
10945
ctype = current_class_type
;
10946
10947
/*
Must mark the RESULT_DECL as being in this function.
*/
10948
DECL_CONTEXT (DECL_RESULT
(fndecl)) = fndecl;
10949
10950
/*
Set the BLOCK_SUPERCONTEXT of the outermost function scope to point
10951
to the
FUNCTION_DECL node itself.
*/
10952
BLOCK_SUPERCONTEXT (DECL_INITIAL
(fndecl)) = fndecl;
10953
10954
/*
Save away current state, if appropriate.
*/
10955
if (!processing_template_decl
)
10956
save_function_data
(fndecl);
By the language grammar, function without declaring throws any
exception can throw exception of any kind; to declare a function throw no
exception, you should use nothrow at the end of the declaration. This
information is useful for optimization, needs record it within the
FUNCTION_DECL node. And IF
block
beginning at line 10915 is for named return value optimization purpose, we will
come to this topic later.
10614
static
void
10615
save_function_data
(tree decl)
in decl.c
10616
{
10617
struct
language_function *f;
10618
10619
/*
Save the language-specific per-function data so that we can
10620
get it
back when we really expand this function.
*/
10621
my_friendly_assert
(!DECL_PENDING_INLINE_P (decl),
10622
19990908);
10623
10624
/*
Make a copy.
*/
10625
f = ggc_alloc (sizeof
(struct
language_function));
10626
memcpy (f,
cp_function_chain, sizeof
(struct
language_function));
10627
DECL_SAVED_FUNCTION_DATA
(decl) = f;
10628
10629
/*
Clear out the bits we don't need.
*/
10630
f->base.x_stmt_tree.x_last_stmt = NULL_TREE;
10631
f->base.x_stmt_tree.x_last_expr_type = NULL_TREE;
10632
f->x_named_label_uses =
NULL;
10633
f->bindings = NULL;
10634
f->x_local_names = NULL;
10635
10636
/*
If we've already decided that we cannot inline this function, we
10637
must
remember that fact when we actually go to expand the
10638
function.
*/
10639
if
(current_function_cannot_inline)
10640
{
10641
f->cannot_inline =
current_function_cannot_inline;
10642
DECL_INLINE (decl) = 0;
10643
}
10644
}
If it is method of class-template, the method is not the real
function declaration. For the real function declaration, it needs remember this
associated language_function and release cfun
as we get out of the function declaration
and scope now. It is done by save_function_data
.
finish_function (continue)
10958
/*
If this function calls `setjmp' it cannot be inlined. When
10959
`longjmp' is called it is not guaranteed to restore the value of
10960
local
variables that have been modified since the call to
10961
`setjmp'. So, if were to inline this function into some caller
10962
`c',
then when we `longjmp', we might not restore all variables
10963
in
`c'. (It might seem, at first blush, that there's no way for
10964
this
function to modify local variables in `c', but their
10965
addresses may have been stored somewhere accessible to this
10966
function.)
*/
10967
if (!processing_template_decl
&&
calls_setjmp_p (fndecl))
10968
DECL_UNINLINABLE (fndecl)
= 1;
10969
10970
/*
Complain if there's just no return statement.
*/
10971
if (warn_return_type
10972
&& TREE_CODE
(TREE_TYPE (fntype)) != VOID_TYPE
10973
&& !dependent_type_p (TREE_TYPE
(fntype))
10974
&& !current_function_returns_value
&& !current_function_returns_null
10975
/* Don't complain if we abort or throw.
*/
10976
&& !current_function_returns_abnormally
10977
&& !DECL_NAME
(DECL_RESULT (fndecl))
10978
/*
Normally, with -Wreturn-type, flow will complain. Unless we're an
10979
inline function, as we might never be compiled
separately.
*/
10980
&& (DECL_INLINE
(fndecl) || processing_template_decl
))
10981
warning ("no return
statement in function returning non-void");
10982
10983
/*
We're leaving the context of this function, so zap cfun. It's still in
10984
DECL_SAVED_INSNS, and we'll restore it in tree_rest_of_compilation.
*/
10985
cfun
= NULL;
10986
current_function_decl
= NULL;
10987
10988
/*
If this is an in-class inline definition, we may have to pop the
10989
bindings for the template parameters that we added in
10990
maybe_begin_member_template_processing when start_function was
10991
called.
*/
10992
if (inclass_inline)
10993
maybe_end_member_template_processing ();
10994
10995
/*
Leave the scope of the class.
*/
10996
if (ctype)
10997
pop_nested_class
();
10998
10999
--function_depth
;
11000
11001
/*
Clean up.
*/
11002
if (! nested)
11003
/*
Let the error reporting routines know that we're outside a
11004
function. For a nested function, this value is used in
11005
cxx_pop_function_context and then reset via pop_function_context.
*/
11006
current_function_decl
= NULL_TREE;
11007
11008
return
fndecl;
11009
}
Being a method of class, it is either defined outside the class
body, or defined as inclass-inline, no matter what kind, ctype at line 10996
points to the class node which forms the context for the method. When finish
handling the method, it also steps out of the class (remember for
inclass-inline definition, its handling is deferred to the finish of class
body). Exitting from the class scope is done by pop_nested_class
.
5650
void
5651
pop_nested_class
(void)
in class.c
5652
{
5653
tree context = DECL_CONTEXT
(TYPE_MAIN_DECL (current_class_type
));
5654
5655
popclass
();
5656
if (context &&
CLASS_TYPE_P (context))
5657
pop_nested_class ();
5658
}
相关文章推荐
- Studying note of GCC-3.4.6 source (59)
- Studying note of GCC-3.4.6 source (68)
- Studying note of GCC-3.4.6 source (98)
- Studying note of GCC-3.4.6 source (108)
- Studying note of GCC-3.4.6 source (114)
- Studying note of GCC-3.4.6 source (137)
- Studying note of GCC-3.4.6 source (12)
- Studying note of GCC-3.4.6 source (144)
- Studying note of GCC-3.4.6 source (15)
- Studying note of GCC-3.4.6 source (23)
- Studying note of GCC-3.4.6 source (25)
- Studying note of GCC-3.4.6 source (178)
- Studying note of GCC-3.4.6 source (60)
- Studying note of GCC-3.4.6 source (69)
- Studying note of GCC-3.4.6 source (101)
- Studying note of GCC-3.4.6 source (102)
- Studying note of GCC-3.4.6 source (122)
- Studying note of GCC-3.4.6 source (129)
- Studying note of GCC-3.4.6 source (10 cont2)
- Studying note of GCC-3.4.6 source (141)