/* 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
可以看出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)