首页 > 代码库 > 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 98f48
        type <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 ()函数分析