Studying note of GCC-3.4.6 source (10)

1.6. Create node for types – part 1

1.6.1. Create node for function types

First, we see what FUNCTION_TYPE is:

FUNCTION_TYPE[2]

²        Used to represent the type of non-member functions and of static member functions. The TREE_TYPE gives the return type of the function. The TYPE_ARG_TYPES are a TREE_LIST of the argument types. The TREE_VALUE of each node in this list is the type of the corresponding argument; the TREE_PURPOSE is an expression for the default argument value, if any. If the last node in the list is void_list_node (a TREE_LIST node whose TREE_VALUE is the void_type_node), then functions of this type do not take variable arguments. Otherwise, they do take a variable number of arguments.

Note that in C (but not in C++) a function declared like void f() is an unprototyped function taking a variable number of arguments; the TYPE_ARG_TYPES of such a function will be NULL.

1.6.1.1.    Create node for function type from individual parameters

Function build_function_type_list accepts discrete nodes for parameters. It is invoked majorly by back-end.

 

3876 tree

3877 build_function_type_list (tree return_type, ...)                                                    in tree.c

3878 {

3879   tree t, args, last;

3880   va_list p;

3881

3882   va_start (p, return_type);

3883

3884   t = va_arg (p, tree);

3885   for (args = NULL_TREE; t != NULL_TREE; t = va_arg (p, tree))

3886     args = tree_cons (NULL_TREE, t, args);

3887

3888   last = args;

3889   args = nreverse (args);

3890   TREE_CHAIN (last) = void_list_node;

3891   args = build_function_type (return_type, args);

3892

3893   va_end (p);

3894   return args;

3895 }

 

Note the nodes of parmaeters are passed to build_function_type_list in the order of declaration. And at line 3889, these parameters are put in reversed order (i.e, the order they get processed in assemble).

1.6.1.2.    Create node for function type from parameters list

The front-end prefers below function for creating node of function type. The parameter of the function arg_types is a tree_list, it chains all parameters in reversed order of declaration.

 

3845 tree

3846 build_function_type (tree value_type, tree arg_types)                                          in tree.c

3847 {

3848   tree t;

3849   unsigned int hashcode;

3850

3851   if (TREE_CODE (value_type) == FUNCTION_TYPE)

3852   {

3853     error ("function return type cannot be function");

3854     value_type = integer_type_node;

3855   }

3856

3857   /* Make a node of the sort we want.  */

3858   t = make_node (FUNCTION_TYPE);

3859   TREE_TYPE (t) = value_type;

3860   TYPE_ARG_TYPES (t) = arg_types;

3861

3862   /* If we already have such a type, use the old one and free this one.  */

3863   hashcode = TYPE_HASH (value_type) + type_hash_list (arg_types);

3864   t = type_hash_canon (hashcode, t);

3865

3866   if (!COMPLETE_TYPE_P (t))

3867     layout_type (t);

3868   return t;

3869 }

 

The type of function is determined by its returned type and type of parameters. For example, int f (int, int) and int g (int, int) have the same type. To ensure one correspondence between the node and the type definition, all nodes of type definition are saved within the hashtable - type_hash_table.

1.6.1.3.    Lay out the function type

In object file, the function definition is placed within text section. Out of consideration of accessing efficiency, the starting address of the function definition has alignment requirement. So function type needs be laid out here.

 

1528 void

1529 layout_type (tree type)                                                                       in stor-layout.c

1530 {

1531   if (type == 0)

1532     abort ();

1533

1534   /* Do nothing if type has been laid out before.  */

1535   if (TYPE_SIZE (type))

1536     return;

1537

1538   switch (TREE_CODE (type))

1539   {

        

1595     case FUNCTION_TYPE:

1596     case METHOD_TYPE:

1597       TYPE_MODE (type) = mode_for_size (2 * POINTER_SIZE, MODE_INT, 0);

1598       TYPE_SIZE (type) = bitsize_int (2 * POINTER_SIZE);

1599       TYPE_SIZE_UNIT (type) = size_int ((2 * POINTER_SIZE) / BITS_PER_UNIT);

1600       break;

         

1796  }

      

1801   if (TREE_CODE (type) != RECORD_TYPE

1802       && TREE_CODE (type) != UNION_TYPE

1803       && TREE_CODE (type) != QUAL_UNION_TYPE)

1804     finalize_type_size (type);

      

1818 }

 

Find that for FUNCTION_TYPE and METHOD_TYPE are defined as integer mode in size of 2*POINTER_SIZE. This data of mode will effect the alignment of the type in finalize_type_size.

1.6.2. Create node for index

Below function creates a type of integers to be the TYPE_DOMAIN of an ARRAY_TYPE. Parameter maxval should be the maximum value in the domain (one less than the length of the array).

 

3724 tree

3725 build_index_type (tree maxval)                                                                          in tree.c

3726 {

3727   tree itype = make_node (INTEGER_TYPE);

3728

3729   TREE_TYPE (itype) = sizetype;

3730   TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);

3731   TYPE_MIN_VALUE (itype) = size_zero_node;

3732   TYPE_MAX_VALUE (itype) = convert (sizetype, maxval);

3733   TYPE_MODE (itype) = TYPE_MODE (sizetype);

3734   TYPE_SIZE (itype) = TYPE_SIZE (sizetype);

3735   TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (sizetype);

3736   TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);

3737   TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (sizetype);

3738

3739   if (host_integerp (maxval, 1))

3740     return type_hash_canon (tree_low_cst (maxval, 1), itype);

3741   else

3742     return itype;

3743 }

 

Notice that the type of index is size_t.

你可能感兴趣的:(function,list,tree,Parameters,alignment,Types)