首页 > 代码库 > gcc源代码分析,build_function_call ()函数分析
gcc源代码分析,build_function_call ()函数分析
在文件c-typeck.c中
c-parse.tab.y文件中这个地方调用!
primary:
| primary ‘(‘ exprlist ‘)‘ %prec ‘.‘
{ $$ = build_function_call ($1, $3); }
/* Build a function call to function FUNCTION with parameters PARAMS.
PARAMS is a list--a chain of TREE_LIST nodes--in which the
TREE_VALUE of each node is a parameter-expression.
FUNCTION‘s data type may be a function type or a pointer-to-function. */
tree
build_function_call (function, params)
tree function, params;
{
register tree fntype;
register tree value_type;
register tree coerced_params;
tree name = NULL_TREE;
tree actualparameterlist ();
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context. */
if (TREE_CODE (function) == NOP_EXPR
&& TREE_TYPE (function) == TREE_TYPE (TREE_OPERAND (function, 0)))
function = TREE_OPERAND (function, 0);
/* Convert anything with function type to a pointer-to-function. */
if (TREE_CODE (function) == FUNCTION_DECL)
{
name = DECL_NAME (function);
/* Differs from default_conversion by not setting TREE_ADDRESSABLE
(because calling an inline function does not mean the function
needs to be separately compiled). */
function = build (ADDR_EXPR, build_pointer_type (TREE_TYPE (function)),
function);
}
else
function = default_conversion (function);
fntype = TREE_TYPE (function);
if (TREE_CODE (fntype) == ERROR_MARK)
return error_mark_node;
if (!(TREE_CODE (fntype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE))
{
error ("called object is not a function");
return error_mark_node;
}
/* fntype now gets the type of function pointed to. */
fntype = TREE_TYPE (fntype);
/* Convert the parameters to the types declared in the
function prototype, or apply default promotions. */
coerced_params = actualparameterlist (TYPE_ARG_TYPES (fntype), params, name);
/* Recognize certain built-in functions so we can make tree-codes
other than CALL_EXPR. We do this when it enables fold-const.c
to do something useful. */
if (TREE_CODE (function) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
switch (DECL_FUNCTION_CODE (TREE_OPERAND (function, 0)))
{
case BUILT_IN_ABS:
case BUILT_IN_LABS:
case BUILT_IN_FABS:
if (coerced_params == 0)
return integer_zero_node;
return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0);
}
value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node;
{
register tree result =
build (CALL_EXPR, value_type, function, coerced_params, NULL_TREE);
TREE_VOLATILE (result) = 1;
if (value_type == void_type_node)
return result;
return require_complete_type (result);
}
}
function = build (ADDR_EXPR, build_pointer_type (TREE_TYPE (function)),
function);
经过上面的语句会产生下面的tree。
<addr_expr 84090
type <pointer_type 98f48type <function_type 956e8 type <integer_type 824d0* int>
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>
pointer_to_this <pointer_type 98f48> chain <function_type 959b0>
permanent unsigned SI
size <integer_cst 8254c literal permanent 4
align 32 size_unit 8 sep_unit 32 symtab 0
arg 0 <function_decl 95740 printf type <function_type 956e8>
external public permanent used QI file /usr/include/stdio.h line 214
align 1 size_unit 1 offset 0
chain <function_decl 954d8 ungetc type <function_type 8f4f0>
external public permanent QI file /usr/include/stdio.h line 212
align 1 size_unit 1 offset 0 chain <function_decl 95280 fputs>
gcc源代码分析,build_function_call ()函数分析