In the file c-typeck.c
C-PARSE.TAB.Y file in this place called!
Primary
| Primary ' (' exprlist ') '%prec '. '
{$$ = Build_function_call ($, $ $);}
/* 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 of not a 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 to 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 the 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);
Passing the above statement produces the following tree.
<addr_expr 84090
Type <pointer_type 98f48
Type <function_type 956e8 type <integer_type 824d0* int>
Permanent EP
Size <INTEGER_CST 82DD8 literal permanent 8
Align 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 Size_unit 8 sep_unit 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 source code analysis, Build_function_call () function analysis