Studying note of GCC-3.4.6 source (54)

来源:互联网 发布:淘宝刷单赚钱是真的吗 编辑:程序博客网 时间:2024/04/29 11:52

4.3.1.7.3.           BuildTree Node of Type Information

Then GCC will finialize the choiceof inlining functions to flag_inline_trees, and abandon others. For ptrmemfunc_vbit_in_pfnat 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 compileprogram written by various languages, so a pointer-to-function member type inthe system looks like:

    struct {

       __P __pfn;

       ptrdiff_t __delta;

    };

If __pfn is NULL, it is a NULL pointer-to-member-function. (Because thevtable is always the first thing in the object, we don't need its offset.) Ifthe 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 isrequired on function addresses, and lowest significant bit will be 0, for thatcase, the lowest bit can tell if the function is virtual or not).

Unfortunately, using the lowest bitof PFN doesn't work in architectures that don't impose alignment requirementson 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 ofthe lowest bit of the PFN, and DELTA will be multiplied by 2.

No doubt macro TARGET_PTRMEMFUNC_VBIT_LOCATIONtells where is bit telling virtual function from common function. For x86, it’sptrmemfunc_vbit_in_pfn.And variable force_align_functions_logkeeps 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 atboundary of even byte).

 

cxx_init_decl_processing(continue)

 

2967    /* Adjust various flags based on command-linesettings.  */

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 usingthe least significant

2982       bit of function pointers to store thevirtual 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 seendetails about creating tree nodes for internal type below function. Here is theplace 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 `signedchar' 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 onlyrepresents boolean values but

4863       may be larger than char depending on thevalue of BOOL_TYPE_SIZE.

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

4865       boolean_type_node before callingbuild_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. Reuseexisting 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, unsighedshort, int, etc., whose size depend on the platform. Then in the compiler’simplementation, it binds nodes of these builtin type with nodes of standardsize. The nodes of standard size are those intQI_type_node, intHI_type_node, etc. above. Thebinding is done by make_or_reuse_type. It favors instant knowingthe mode of builtin types (that is memory usage), for example, if short_integer_type_nodeis 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.

 

 

原创粉丝点击