Studying note of GCC-3.4.6 source (111)

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   }

 

你可能感兴趣的:(function,tree,null,processing,nested,optimization)