Studying note of GCC-3.4.6 source (54)

4.3.1.7.3.            Build Tree Node of Type Information

Then GCC will finialize the choice of inlining functions to flag_inline_trees , and abandon others. For ptrmemfunc_vbit_in_pfn at line 2983, it is enum type ptrmemfunc_vbit_where_t .

 

2048   enum ptrmemfunc_vbit_where_t                                                                              in tree.h

2049   {

2050     ptrmemfunc_vbit_in_pfn,

2051     ptrmemfunc_vbit_in_delta

2052   };

 

It is needed because GCC needs to compile program written by various languages, so a pointer-to-function member type in the system looks like:

     struct {

       __P __pfn;

       ptrdiff_t __delta;

     };

If __pfn is NULL, it is a NULL pointer-to-member-function. (Because the vtable is always the first thing in the object, we don't need its offset.) If the function is virtual, then PFN is one plus twice the index into the vtable (the offset from the head of vtable, and lowest significant bit will be 1); otherwise, it is just a pointer to the function (normally, alignment is required on function addresses, and lowest significant bit will be 0, for that case, the lowest bit can tell if the function is virtual or not).

Unfortunately, using the lowest bit of PFN doesn't work in architectures that don't impose alignment requirements on function addresses, or that use the lowest bit to tell one ISA from another, for example. For such architectures, we use the lowest bit of DELTA instead of the lowest bit of the PFN, and DELTA will be multiplied by 2.

No doubt macro TARGET_PTRMEMFUNC_VBIT_LOCATION tells where is bit telling virtual function from common function. For x86, it’s ptrmemfunc_vbit_in_pfn . And variable force_align_functions_log keeps the forced alignment of function (log of radix 2). Of course if it’s 0, means no alignment requirement, which needs be adjusted to 1 (aligned at boundary of even byte).

 

cxx_init_decl_processing (continue)

 

2967     /* Adjust various flags based on command-line settings.  */

2968     if (!flag_permissive )

2969       flag_pedantic_errors = 1;

2970     if (!flag_no_inline )

2971     {

2972       flag_inline_trees = 1;

2973        flag_no_inline = 1;

2974     }

2975     if (flag_inline_functions )

2976     {

2977       flag_inline_trees = 2;

2978       flag_inline_functions = 0;

2979     }

2980  

2981     /* Force minimum function alignment if using the least significant

2982       bit of function pointers to store the virtual bit.  */

2983     if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn

2984         && force_align_functions_log < 1)

2985       force_align_functions_log = 1;

2986  

2987     /* Initially, C.  */

2988     current_lang_name = lang_name_c;

2989  

2990     build_common_tree_nodes (flag_signed_char );

2991  

2992     error_mark_list = build_tree_list (error_mark_node, error_mark_node);

2993     TREE_TYPE (error_mark_list ) = error_mark_node;

 

In section Create node for internal types , we have seen details about creating tree nodes for internal type below function. Here is the place where these builtin type get generated.

 

4834   void

4835   build_common_tree_nodes (int signed_char)                                                     in tree.c

4836   {

4837     error_mark_node = make_node (ERROR_MARK);

4838     TREE_TYPE (error_mark_node) = error_mark_node;

4839  

4840     initialize_sizetypes ();

4841  

4842     /* Define both `signed char' and `unsigned char'.  */

4843     signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);

4844     unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);

4845  

4846     /* Define `char', which is like either `signed char' or `unsigned char'

4847       but not the same as either.  */

4848     char_type_node

4849       = (signed_char

4850          ? make_signed_type (CHAR_TYPE_SIZE)

4851          : make_unsigned_type (CHAR_TYPE_SIZE));

4852  

4853     short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);

4854     short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);

4855     integer_type_node = make_signed_type (INT_TYPE_SIZE);

4856     unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE);

4857     long_integer_type_node = make_signed_type (LONG_TYPE_SIZE);

4858     long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE);

4859     long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE);

4860     long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE);

4861  

4862     /* Define a boolean type. This type only represents boolean values but

4863       may be larger than char depending on the value of BOOL_TYPE_SIZE.

4864       Front ends which want to override this size (i.e. Java) can redefine

4865       boolean_type_node before calling build_common_tree_nodes_2.  */

4866     boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);

4867     TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);

4868     TYPE_MAX_VALUE (boolean_type_node) = build_int_2 (1, 0);

4869     TREE_TYPE (TYPE_MAX_VALUE (boolean_type_node)) = boolean_type_node;

4870     TYPE_PRECISION (boolean_type_node) = 1;

4871  

4872     /* Fill in the rest of the sized types. Reuse existing type nodes

4873       when possible.  */

4874     intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 0);

4875     intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 0);

4876     intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 0);

4877     intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 0);

4878     intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 0);

4879  

4880     unsigned_intQI_type_node =make_or_reuse_type(GET_MODE_BITSIZE (QImode), 1);

4881     unsigned_intHI_type_node =make_or_reuse_type(GET_MODE_BITSIZE (HImode), 1);

4882     unsigned_intSI_type_node = make_or_reuse_type(GET_MODE_BITSIZE (SImode), 1);

4883     unsigned_intDI_type_node =make_or_reuse_type(GET_MODE_BITSIZE (DImode), 1);

4884     unsigned_intTI_type_node = make_or_reuse_type(GET_MODE_BITSIZE (TImode), 1);

4885  

4886     access_public_node = get_identifier ("public");

4887     access_protected_node = get_identifier ("protected");

4888     access_private_node = get_identifier ("private");

4889   }

 

In C++, builtin type short, unsighed short, int, etc., whose size depend on the platform. Then in the compiler’s implementation, it binds nodes of these builtin type with nodes of standard size. The nodes of standard size are those intQI_type_node , intHI_type_node , etc. above. The binding is done by make_or_reuse_type . It favors instant knowing the mode of builtin types (that is memory usage), for example, if short_integer_type_node is intHI_type_node , it means type short is of HI mode.

 

4809   static tree

4810   make_or_reuse_type (unsigned size, int unsignedp)                                            in tree.c

4811   {

4812     if (size == INT_TYPE_SIZE)

4813       return unsignedp ? unsigned_type_node : integer_type_node;

4814     if (size == CHAR_TYPE_SIZE)

4815       return unsignedp ? unsigned_char_type_node : signed_char_type_node;

4816     if (size == SHORT_TYPE_SIZE)

4817       return unsignedp ? short_unsigned_type_node : short_integer_type_node;

4818     if (size == LONG_TYPE_SIZE)

4819       return unsignedp ? long_unsigned_type_node : long_integer_type_node;

4820     if (size == LONG_LONG_TYPE_SIZE)

4821       return (unsignedp ? long_long_unsigned_type_node

4822               : long_long_integer_type_node);

4823  

4824     if (unsignedp)

4825       return make_unsigned_type (size);

4826     else

4827       return make_signed_type (size);

4828   }

 

What’s more, line 4886 ~ 4888, generate nodes for keywords: public, protected, and private.

 

 

你可能感兴趣的:(function,tree,Integer,Build,alignment,Pointers)