您的位置:首页 > 其它

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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: