Studying note of GCC-3.4.6 source (111)
来源:互联网 发布:js中国地图插件 编辑:程序博客网 时间:2024/06/08 12:46
5.12.3.2.1.2.1.3. Finishfunction handling
Then finish_function will finish filling-up ofnode of FUNCTION_DECL for the function. We will go back to this function lateragain 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 returnerror_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 Thiscaused &foo to be of type ptr-to-const-function
10842 whichthen 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 thestatements. As there may be more than one assignments kept in saved_function_name_decls(correspond to “__FUNCTION__”, “__func__”, “__PRETTY_FUNCTION__”), so below atline 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 theDECL_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 thefunction-body. As these statements are saved by fname_vars[ix].decl before, nowthey got handled, and at exitting the function, they no longer valid; FOR loopat line 1044 cleans fname_vars[ix]. And FOR loop at line 1052 in factrestores fname_vars[ix].decl’sinitial 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 thefunction. */
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 aboveaddress of it is needed for inserting the statements. Now as statements are alllinked 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 havedeclarations (from inline functions) that need to go into
10882 thisfunction's blocks. */
10883
10884 /*If the current binding level isn't the outermost binding level
10885 forthis function, either there is a bug, or we have experienced
10886 syntaxerrors 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 ofcurly 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 forthe nrv. genrtl_start_function and declare_return_variable
10914 handlemaking 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 theFUNCTION_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 anyexception can throw exception of any kind; to declare a function throw noexception, you should use nothrow at the end of the declaration. Thisinformation is useful for optimization, needs record it within theFUNCTION_DECL node. And IF blockbeginning at line 10915 is for named return value optimization purpose, we willcome to this topic later.
10614 static void
10615 save_function_data (tree decl) in decl.c
10616 {
10617 structlanguage_function *f;
10618
10619 /*Save the language-specific per-function data so that we can
10620 get itback 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 (structlanguage_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 mustremember 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 realfunction declaration. For the real function declaration, it needs remember thisassociated language_function and release cfun as we get out of the function declarationand 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 localvariables 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 thisfunction 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 compiledseparately. */
10980 && (DECL_INLINE(fndecl) || processing_template_decl))
10981 warning ("no returnstatement 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 returnfndecl;
11009 }
Being a method of class, it is either defined outside the classbody, or defined as inclass-inline, no matter what kind, ctype at line 10996points to the class node which forms the context for the method. When finishhandling the method, it also steps out of the class (remember forinclass-inline definition, its handling is deferred to the finish of classbody). 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 (111)
- Studying note of GCC-3.4.6 source (6)
- Studying note of GCC-3.4.6 source (1)
- Studying note of GCC-3.4.6 source (2)
- Studying note of GCC-3.4.6 source (3)
- Studying note of GCC-3.4.6 source (4)
- Studying note of GCC-3.4.6 source (5)
- Studying note of GCC-3.4.6 source (7)
- Studying note of GCC-3.4.6 source (8)
- Studying note of GCC-3.4.6 source (9)
- Studying note of GCC-3.4.6 source (10)
- Studying note of GCC-3.4.6 source (10 cont1)
- Studying note of GCC-3.4.6 source (10 cont2)
- Studying note of GCC-3.4.6 source (10 cont3)
- Studying note of GCC-3.4.6 source (10 cont4)
- Studying note of GCC-3.4.6 source (11)
- Studying note of GCC-3.4.6 source (12)
- Studying note of GCC-3.4.6 source (13)
- C++中extern “C”含义深层探索
- GCC-3.4.6源代码学习笔记(111)
- FZU 网赛最后K题 Three kingdoms(有点卡常数的)
- Android JNI
- 转一个支付宝接口的ASP代码 支付宝接口(应用实例)2008-08-22 16:33支付宝接口的ASP代码
- Studying note of GCC-3.4.6 source (111)
- 支付宝接口(asp-支持UTF8、GB2312)
- GCC-3.4.6源代码学习笔记(112)
- KNN分类算法
- C# where用法
- arm-linux-gcc 安装和使用(交叉编译环境搭建)
- Studying note of GCC-3.4.6 source (112)
- c#中的interface abstract与virtual
- 将文本文件插入Oracle表中