gcc源代码分析,finish_decl ()函数和rest_of_decl_compilation ()函数分析

int    printf            (const char *     , ... ) ;

本文探讨函数声明到tree到rtx的生成过程。

c-parse.y文件中有下面的一条规则,会调用start_decl ()函数和finish_decl ()函数。

initdcl:
      declarator maybeasm maybe_attribute '='
        { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
      init
/* Note how the declaration of the variable is in effect while its init is parsed! */
        { finish_decl ($<ttype>5, $6, $2); }
    | declarator maybeasm maybe_attribute
        { tree d = start_decl ($1, current_declspecs, 0);
          finish_decl (d, NULL_TREE, $2); }



printf
 <identifier_node 95540 printf permanent
in build_pointer_type
 <integer_type 91130 char readonly permanent QI
    size <integer_cst 82638 type <integer_type 82848* unsigned int> literal permanent 1
    align 8 size_unit 8 sep_unit 8 symtab 0
    sep <integer_cst 82608 type <integer_type 825bc* char> literal permanent -128 precision 8 min <integer_cst 82608 -128>
    max <integer_cst 82620 type <integer_type 825bc* char> literal permanent 127
    pointer_to_this <pointer_type 9117c>
in finish_decl
in start_decl
 <call_expr 956c8 permanent
    arg 0 <identifier_node 95540 printf permanent
    arg 1 <tree_list 956b0 permanent
        purpose <parm_decl 941c0 type <pointer_type 9117c>
            unsigned SI file /usr/include/stdio.h line 214
            size <integer_cst 8254c literal permanent 4
            align 32 size_unit 8 offset 0 arguments <pointer_type 9117c>
        chain <tree_list 95698 permanent value <pointer_type 9117c> chain <tree_list 95698>(nil)

 <tree_list 95608 permanent
    value <identifier_node 82008 int permanent
        global <type_decl 82564 int type <integer_type 824d0* int>
            permanent VOID file (null) line 0
            align 1 size_unit 1 offset 0
in finish_decl
finish_decl 2
rest_of_decl_compilation
 <function_decl 95740 printf
    type <function_type 956e8
        type <integer_type 824d0 int permanent SI
            size <integer_cst 8254c literal permanent 4
            align 32 size_unit 8 sep_unit 32 symtab 0
            sep <integer_cst 8251c literal permanent -2147483648 precision 32 min <integer_cst 8251c -2147483648>
            max <integer_cst 82534 literal permanent 2147483647
            pointer_to_this <pointer_type 88b4c> chain <integer_type 825bc* char>
        permanent EP
        size <integer_cst 82dd8 literal permanent 8
        align 32 size_unit 8 sep_unit 0 symtab 0
        arg-types <tree_list 95698 permanent value <pointer_type 9117c>
    external public permanent QI file /usr/include/stdio.h line 214
    align 1 size_unit 1 offset 0 chain <function_decl 954d8 ungetc>

(symbol_ref:SI ("printf"))

(mem:QI (symbol_ref:SI ("printf")))
rest of decl 1
the end of rest_of_decl
finish_decl 3



/* Finish processing of a declaration;
   install its line number and initial value.
   If the length of an array type is not known before,
   it must be determined now, from the initial value, or it is an error.  */

void
finish_decl (decl, init, asmspec_tree)
     tree decl, init;
     tree asmspec_tree;
{


  if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
    {
      if (flag_traditional && allocation_temporary_p ())
    {
      end_temporary_allocation ();
      rest_of_decl_compilation (decl, asmspec,
                    current_binding_level == global_binding_level,
                    0);
      resume_temporary_allocation ();
    }
      else
    rest_of_decl_compilation (decl, asmspec,
                  current_binding_level == global_binding_level,
                  0);
...
    }

...
}


/* This is called from finish_decl (within yyparse)
   for each declaration of a function or variable.
   This does nothing for automatic variables.
   Otherwise, it sets up the RTL and outputs any assembler code
   (label definition, storage allocation and initialization).

   DECL is the declaration.  If ASMSPEC is nonzero, it specifies
   the assembler symbol name to be used.  TOP_LEVEL is nonzero
   if this declaration is not within a function.  */

void
rest_of_decl_compilation (decl, asmspec, top_level, at_end)
     tree decl;
     char *asmspec;
     int top_level;
     int at_end;
{
  /* Declarations of variables, and of functions defined elsewhere.  */

  if (TREE_STATIC (decl) || TREE_EXTERNAL (decl))
    TIMEVAR (varconst_time,
         {
           make_decl_rtl (decl, asmspec, top_level);
           /* Don't output anything
          when a tentative file-scope definition is seen.
          But at end of compilation, do output code for them.  */
           if (! (! at_end && top_level
              && (DECL_INITIAL (decl) == 0
              || DECL_INITIAL (decl) == error_mark_node)))
         assemble_variable (decl, top_level, write_symbols, at_end);
         });


/* Create the DECL_RTL for a declaration for a static or external variable
   or static or external function.
   ASMSPEC, if not 0, is the string which the user specified
   as the assembler symbol name.
   TOP_LEVEL is nonzero if this is a file-scope variable.

   This is never called for PARM_DECL nodes.  */

void
make_decl_rtl (decl, asmspec, top_level)
     tree decl;
     char *asmspec;
     int top_level;
{

...
      DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl),
                     gen_rtx (SYMBOL_REF, Pmode, name));


<function_decl 95740 printf 已经生成。

在main函数里么再调用的时候就直接使用了。

你可能感兴趣的:(gcc,源代码,分析)