gcc源代码分析,get_parm_info ()函数分析

来源:互联网 发布:openwrt nginx l2tp 编辑:程序博客网 时间:2024/06/07 04:11

/* Return a tree_list node with info on a parameter list just parsed.
   The TREE_PURPOSE is a chain of decls of those parms.
   The TREE_VALUE is a list of structure, union and enum tags defined.
   The TREE_CHAIN is a list of argument types to go in the FUNCTION_TYPE.
   This tree_list node is later fed to `grokparms'.

   VOID_AT_END nonzero means append `void' to the end of the type-list.
   Zero means the parmlist ended with an ellipsis so don't append `void'.  */

tree
get_parm_info (void_at_end)
     int void_at_end;
{
  register tree decl;
  register tree types = 0;
  int erred = 0;
  tree tags = gettags ();
  tree parms = nreverse (getdecls ());

fprintf(stderr,"in get_parm_info \n");

debug_tree (parms);
  /* Just `void' (and no ellipsis) is special.  There are really no parms.  */
  if (void_at_end && parms != 0
      && TREE_CHAIN (parms) == 0
      && TREE_TYPE (parms) == void_type_node
      && DECL_NAME (parms) == 0)
    {
      parms = NULL_TREE;
      storedecls (NULL_TREE);
      return saveable_tree_cons (NULL_TREE, NULL_TREE,
                 saveable_tree_cons (NULL_TREE, void_type_node, NULL_TREE));
    }

  storedecls (parms);

  for (decl = parms; decl; decl = TREE_CHAIN (decl))
    /* There may also be declarations for enumerators if an enumeration
       type is declared among the parms.  Ignore them here.  */
    if (TREE_CODE (decl) == PARM_DECL)
      {
    /* Since there is a prototype,
       args are passed in their declared types.  */
    tree type = TREE_TYPE (decl);
    DECL_ARG_TYPE (decl) = type;
#ifdef PROMOTE_PROTOTYPES
    if (TREE_CODE (type) == INTEGER_TYPE
        && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
      DECL_ARG_TYPE (decl) = integer_type_node;
#endif

    types = saveable_tree_cons (NULL_TREE, TREE_TYPE (decl), types);
    if (TREE_VALUE (types) == void_type_node && ! erred
        && DECL_NAME (decl) == 0)
      {
        error ("`void' in parameter list must be the entire list");
        erred = 1;
      }
      }

  if (void_at_end)
    return saveable_tree_cons (parms, tags,
                   nreverse (saveable_tree_cons (NULL_TREE, void_type_node, types)));

  return saveable_tree_cons (parms, tags, nreverse (types));
}


in push_parm_decl

 <tree_list 95680 permanent
    purpose <tree_list 95650 permanent
        value <identifier_node 82038 char permanent global <type_decl 82650 char>
        chain <tree_list 95638 permanent
            value <identifier_node 82210 const permanent chain <tree_list 95638>
    value <indirect_ref 95668 permanent
in build_pointer_type
 <parm_decl 941c0
    type <pointer_type 9117c
        type <integer_type 91130 char readonly permanent QI
            size <integer_cst 82638 literal permanent 1
            align 8 size_unit 8 sep_unit 8 symtab 0
            sep <integer_cst 82608 literal permanent -128 precision 8 min <integer_cst 82608 -128>
            max <integer_cst 82620 literal permanent 127
            pointer_to_this <pointer_type 9117c>
        permanent unsigned SI
        size <integer_cst 8254c literal permanent 4
        align 32 size_unit 8 sep_unit 32 symtab 0
        chain <function_type 912c0>
    unsigned SI file /usr/include/stdio.h line 214 size <integer_cst 8254c 4>
    align 32 size_unit 8 offset 0 arguments <pointer_type 9117c>
in finish_decl
in get_parm_info
 <parm_decl 941c0
    type <pointer_type 9117c
        type <integer_type 91130 char readonly permanent QI
            size <integer_cst 82638 literal permanent 1
            align 8 size_unit 8 sep_unit 8 symtab 0
            sep <integer_cst 82608 literal permanent -128 precision 8 min <integer_cst 82608 -128>
            max <integer_cst 82620 literal permanent 127
            pointer_to_this <pointer_type 9117c>
        permanent unsigned SI
        size <integer_cst 8254c literal permanent 4
        align 32 size_unit 8 sep_unit 32 symtab 0
        chain <function_type 912c0>
    unsigned SI file /usr/include/stdio.h line 214 size <integer_cst 8254c 4>
    align 32 size_unit 8 offset 0 arguments <pointer_type 9117c>
saveable_tree_cons
 <tree_list 95698 permanent
    value <pointer_type 9117c
        type <integer_type 91130 char readonly permanent QI
            size <integer_cst 82638 literal permanent 1
            align 8 size_unit 8 sep_unit 8 symtab 0
            sep <integer_cst 82608 literal permanent -128 precision 8 min <integer_cst 82608 -128>
            max <integer_cst 82620 literal permanent 127
            pointer_to_this <pointer_type 9117c>
        permanent unsigned SI
        size <integer_cst 8254c literal permanent 4
        align 32 size_unit 8 sep_unit 32 symtab 0
        chain <function_type 912c0>
saveable_tree_cons
 <tree_list 956b0 permanent
    purpose <parm_decl 941c0
        type <pointer_type 9117c type <integer_type 91130* char>
            permanent unsigned SI
            size <integer_cst 8254c literal permanent 4
            align 32 size_unit 8 sep_unit 32 symtab 0
            chain <function_type 912c0>
        unsigned SI file /usr/include/stdio.h line 214 size <integer_cst 8254c 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>


可以看出get_parm_info ()函数最终生成了一个<tree_list 956b0,既是参数列表。

在前面的start_decl ()函数中调用表达式<call_expr 956c8中,

第一个参数就是printf第二个参数就是(const char *     , ... )

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

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)


0 0