For internal types of the language, for example, int, unsigned short in C/C++, the compiler will create nodes for these types first when it starts up.
To create nodes for internal types, temprary nodes for size_t (one for size_t, the other for bitsize_t. size_t is the returned type of sizeof, and bitsize_t is only used by internal) should be first created, as they will be used in layout internal types. Normally, the invocation sequence is like:
build_common_tree_nodes
4840 initialize_sizetypes (); in tree.c
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);
Above signed_char_type_node and unsigned_char_type_node are alias for certain elements of a global array which described in below section.
Integer types are very important and basic part of the language. They are used so heavily (appear in every program in fact), to make the accession as efficient as possible, GCC instead of placing them into hash-table as other types, uses global array to hold them.
2001 extern GTY(()) tree integer_types[itk_none]; in tree.h
2002
2003 #define char_type_node integer_types[itk_char]
2004 #define signed_char_type_node integer_types[itk_signed_char]
2005 #define unsigned_char_type_node integer_types[itk_unsigned_char]
2006 #define short_integer_type_node integer_types[itk_short]
2007 #define short_unsigned_type_node integer_types[itk_unsigned_short]
2008 #define integer_type_node integer_types[itk_int]
2009 #define unsigned_type_node integer_types[itk_unsigned_int]
2010 #define long_integer_type_node integer_types[itk_long]
2011 #define long_unsigned_type_node integer_types[itk_unsigned_long]
2012 #define long_long_integer_type_node integer_types[itk_long_long]
2013 #define long_long_unsigned_type_node integer_types[itk_unsigned_long_long]
The sizes of internal types are another extensively used data in the compiler. So GCC also saves them into a global array.
2427 extern GTY(()) tree sizetype_tab[(int) TYPE_KIND_LAST]; n tree.h
2428
2429 #define sizetype sizetype_tab[(int) SIZETYPE]
2430 #define bitsizetype sizetype_tab[(int) BITSIZETYPE]
2431 #define ssizetype sizetype_tab[(int) SSIZETYPE]
2432 #define usizetype sizetype_tab[(int) USIZETYPE]
2433 #define sbitsizetype sizetype_tab[(int) SBITSIZETYPE]
2434 #define ubitsizetype sizetype_tab[(int) UBITSIZETYPE]
Above nodes mean, normal representation of sizes in bytes; normal representation of sizes in bits; signed representation of sizes in bytes; unsigned representation of sizes in bytes; signed representation of sizes in bits; unsigned representation of sizes in bits; in turn (these 3 groups data aim to satisfy different requirement from different target machine).
Originally, only temperary sizetype and bitsizetype are created. The procedure is quite simple.
1849 void
1850 initialize_sizetypes (void) in stor-layout.c
1851 {
1852 tree t = make_node (INTEGER_TYPE);
1853
1854 /* Set this so we do something reasonable for the build_int_2 calls
1855 below. */
1856 integer_type_node = t;
1857
1858 TYPE_MODE (t) = SImode;
1859 TYPE_ALIGN (t) = GET_MODE_ALIGNMENT (SImode);
1860 TYPE_USER_ALIGN (t) = 0;
1861 TYPE_SIZE (t) = build_int_2 (GET_MODE_BITSIZE (SImode), 0);
1862 TYPE_SIZE_UNIT (t) = build_int_2 (GET_MODE_SIZE (SImode), 0);
1863 TREE_UNSIGNED (t) = 1;
1864 TYPE_PRECISION (t) = GET_MODE_BITSIZE (SImode);
1865 TYPE_MIN_VALUE (t) = build_int_2 (0, 0);
1866 TYPE_IS_SIZETYPE (t) = 1;
1867
1868 /* 1000 avoids problems with possible overflow and is certainly
1869 larger than any size value we'd want to be storing. */
1870 TYPE_MAX_VALUE (t) = build_int_2 (1000, 0);
1871
1872 /* These two must be different nodes because of the caching done in
1873 size_int_wide. */
1874 sizetype = t;
1875 bitsizetype = copy_node (t);
1876 integer_type_node = 0;
1877 }
First at line 1852 a temperary nteger_type_node created. From line 1858 to 1864, data relate to mode is generated by back-end tool genmodes from machmode.def, which is used to fill toye node here. Following, build_int_2 will build node for integer constant of 0 and 1000 as the range of the value these temparory size_t can get. And the temparory integer_type_node is used as type of these constants. Note at line 1874, integer_type_node is also used as the type of sizetype and bitsizetype. However, this sizetype will be abandoned after internal integer type created.
We just take signed integer type as example. For unsigned type, the procedure is very similar with that we see here.
1822 tree
1823 make_signed_type (int precision) in stor-layout.c
1824 {
1825 tree type = make_node (INTEGER_TYPE);
1826
1827 TYPE_PRECISION (type) = precision;
1828
1829 fixup_signed_type (type);
1830 return type;
1831 }
The `TYPE_PRECISION' is the number of bits used in the representation, represented as an `unsigned int'. (Note that in the general case this is not the same value as `TYPE_SIZE'; suppose that there were a 24-bit integer type, but that alignment requirements for the ABI required 32-bit alignment. Then, `TYPE_SIZE' would be an `INTEGER_CST' for 32, while `TYPE_PRECISION' would be 24.)
2014 void
2015 fixup_signed_type (tree type) in stor-layout.c
2016 {
2017 int precision = TYPE_PRECISION (type);
2018
2019 /* We can not represent properly constants greater then
2020 2 * HOST_BITS_PER_WIDE_INT, still we need the types
2021 as they are used by i386 vector extensions and friends. */
2022 if (precision > HOST_BITS_PER_WIDE_INT * 2)
2023 precision = HOST_BITS_PER_WIDE_INT * 2;
2024
2025 set_min_and_max_values_for_integral_type (type, precision,
2026 /*is_unsigned=*/false);
2027
2028 /* Lay out the type: set its alignment, size, etc. */
2029 layout_type (type);
2030 }
Every integer type has its own ability to present certain range of values. For the tree_type nodes created for the types, fields TYPE_MIN_VALUE and TYPE_MAX_VALUE save the low and up boundary of the range. As integer constant, these two fields are tree_int_cst.
682 struct tree_int_cst GTY(()) in tree.h
683 {
684 struct tree_common common;
685 /* A sub-struct is necessary here because the function `const_hash'
686 wants to scan both words as a unit and taking the address of the
687 sub-struct yields the properly inclusive bounded pointer. */
688 struct tree_int_cst_lowhi {
689 unsigned HOST_WIDE_INT low;
690 HOST_WIDE_INT high;
691 } int_cst;
692 };
And above at line 688, in tree_int_cst_lowhi, the low part and the high part construct an intact value presented (note that the value represented can be up to 128 bits long). The range is determined according to the precision of the type by set_min_and_max_values_for_integral_type below.
1965 void
1966 set_min_and_max_values_for_integral_type (tree type, in stor-layout.c
1967 int precision,
1968 bool is_unsigned)
1969 {
1970 tree min_value;
1971 tree max_value;
1972
1973 if (is_unsigned)
1974 {
1975 min_value = build_int_2 (0, 0);
1976 max_value
1977 = build_int_2 (precision - HOST_BITS_PER_WIDE_INT >= 0
1978 ? -1 : ((HOST_WIDE_INT) 1 << precision) - 1,
1979 precision - HOST_BITS_PER_WIDE_INT > 0
1980 ? ((unsigned HOST_WIDE_INT) ~0
1981 >> (HOST_BITS_PER_WIDE_INT
1982 - (precision - HOST_BITS_PER_WIDE_INT)))
1983 : 0);
1984 }
1985 else
1986 {
1987 min_value
1988 = build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
1989 ? 0 : (HOST_WIDE_INT) (-1) << (precision - 1)),
1990 (((HOST_WIDE_INT) (-1)
1991 << (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
1992 ? precision - HOST_BITS_PER_WIDE_INT - 1
1993 : 0))));
1994 max_value
1995 = build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
1996 ? -1 : ((HOST_WIDE_INT) 1 << (precision - 1)) - 1),
1997 (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
1998 ? (((HOST_WIDE_INT) 1
1999 << (precision - HOST_BITS_PER_WIDE_INT - 1))) - 1
2000 : 0));
2001 }
2002
2003 TREE_TYPE (min_value) = type;
2004 TREE_TYPE (max_value) = type;
2005 TYPE_MIN_VALUE (type) = min_value;
2006 TYPE_MAX_VALUE (type) = max_value;
2007 }
Above build_int_2 will create node of INTEGER_CST (detail in T.3 Creates Node of Intege Constant - build_int_2). Notice that min_value and max_value of the type should also contain the same type information.
After creating the node, it should make sure it is correctly filled up. It is the work of layout_type. This function is always invoked as last step in creating node for types. Before the nodes handled by this funciton, TYPE_SIZE field will always be NULL, and this field will be set in layout_type. To avoid duplicate layout, so if TYPE_SIZE is not NULL, the function will exit at line 1524.
1516 void
1517 layout_type (tree type) in stor_layout.c
1518 {
1519 if (type == 0)
1520 abort ();
1521
1522 /* Do nothing if type has been laid out before. */
1523 if (TYPE_SIZE (type))
1524 return;
1525
1526 switch (TREE_CODE (type))
1527 {
1528 case LANG_TYPE:
1529 /* This kind of type is the responsibility
1530 of the language-specific code. */
1531 abort ();
1532
1533 case BOOLEAN_TYPE: /* Used for Java, Pascal, and Chill. */
1534 if (TYPE_PRECISION (type) == 0)
1535 TYPE_PRECISION (type) = 1; /* default to one byte/boolean. */
1536
1537 /* ... fall through ... */
1538
1539 case INTEGER_TYPE:
1540 case ENUMERAL_TYPE:
1541 case CHAR_TYPE:
1542 if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
1543 && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0)
1544 TREE_UNSIGNED (type) = 1;
1545
1546 TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type),
1547 MODE_INT);
1548 TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
1549 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
1550 break;
1.2.2.1.5.1. Information of integer type
Above, macros having name beginning with TYPE just access the corresponding field of tree_type as indicated by the rest part of the name. And those beginning with TREE just access that of tree_common.
1.2.2.1.5.1.1. Determine the sign of type
Sign of the type is the key information. In tree_common node, field TREE_UNSIGNED is used to indicate the type’s sign if appropriate. Find out the sign for integer is very simple as following.
3337 int
3338 tree_int_cst_sgn (tree t) in tree.c
3339 {
3340 if (TREE_INT_CST_LOW (t) == 0 && TREE_INT_CST_HIGH (t) == 0)
3341 return 0;
3342 else if (TREE_UNSIGNED (TREE_TYPE (t)))
3343 return 1;
3344 else if (TREE_INT_CST_HIGH (t) < 0)
3345 return -1;
3346 else
3347 return 1;
3348 }
1.2.2.1.5.1.2. Determine the machine mode
In GCC source code, mode just serves as an index. To describe the type groups (for example, integer type of different size), there is mode_class array, and to describe the size, there are mode_size, mode_nunits, mode_precision arrays. And to describe the relation between modes belonging to the same group, there are mode_wider array. Also there are arrays for other purpose for mode. For current version, the information about available modes for the target platform are generated by tool genmodes (Back-end 7. Tool of genmodes).
At line 1547 above, as we know the group, we can find out the fittest mode with the precision in hand.
247 enum machine_mode
248 smallest_mode_for_size (unsigned int size, enum mode_class class) in stor-layout.c
249 {
250 enum machine_mode mode;
251
252 /* Get the first mode which has at least this size, in the
253 specified class. */
254 for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
255 mode = GET_MODE_WIDER_MODE (mode))
256 if (GET_MODE_PRECISION (mode) >= size)
257 return mode;
258
259 abort ();
260 }
GET_CLASS_NARROWEST_MODE returns the narrowest mode of the class, for example, INT class here. class_narrowest_mode is also generated by genmodes and records narrowest mode for the class.
150 #define GET_CLASS_NARROWEST_MODE(CLASS) class_narrowest_mode[CLASS]
Again, mode_wider is generated by genmodes which is indexed by MODE (which is enum value) and contains next wider mode in the position.
116 #define GET_MODE_WIDER_MODE(MODE) mode_wider[MODE]
mode_precision, generated by genmodes too, records the number of significant bits of the mode.
87 #define GET_MODE_PRECISION(MODE) mode_precision[MODE]
So smallest_mode_for_size just finds out the narrowest mode belonging to the class and capable to hold size bits data. With that information we can find out the exact size for the type as following.
#define GET_MODE_SIZE(MODE) ((unsigned short) mode_size[MODE]) in machmode.h
#define GET_MODE_BITSIZE(MODE) ((unsigned short) (GET_MODE_SIZE (MODE) * BITS_PER_UNIT))
These information are important when a field of the type is laid out without aggregate type.
1.2.2.1.5.1.3. Determine the size of type
At line 1548 and 1549 in layout_type, bitsize_int and size_int create nodes record size information for the type. These functions will need sizetype and bitsizetype as type information for the nodes created. That is why temperary sizetype and bitsizetype must be created first.
Besides bitsize_int and size_int, there are series macros defined.
2441 #define size_int_type(L, T) size_int_type_wide ((HOST_WIDE_INT) (L), T)
2442 #define size_int(L) size_int_wide ((HOST_WIDE_INT) (L), SIZETYPE)
2443 #define ssize_int(L) size_int_wide ((HOST_WIDE_INT) (L), SSIZETYPE)
2444 #define bitsize_int(L) size_int_wide ((HOST_WIDE_INT) (L), BITSIZETYPE)
2445 #define sbitsize_int(L) size_int_wide ((HOST_WIDE_INT) (L), SBITSIZETYPE)
Parameter L stands for the length of the type.
1544 tree
1545 size_int_wide (HOST_WIDE_INT number, enum size_type_kind kind) in fold-const.c
1546 {
1547 return size_int_type_wide (number, sizetype_tab[(int) kind]);
1548 }
Notice that parameter tree of size_int_type_wide is the temperary sizetype.
1552 static GTY (()) tree new_const;
1553 static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node))) in fold-const.c
1554 htab_t size_htab;
1555
1556 tree
1557 size_int_type_wide (HOST_WIDE_INT number, tree type)
1558 {
1559 void **slot;
1560
1561 if (size_htab == 0)
1562 {
1563 size_htab = htab_create_ggc (1024, size_htab_hash, size_htab_eq, NULL);
1564 new_const = make_node (INTEGER_CST);
1565 }
1566
1567 /* Adjust NEW_CONST to be the constant we want. If it's already in the
1568 hash table, we return the value from the hash table. Otherwise, we
1569 place that in the hash table and make a new node for the next time. */
1570 TREE_INT_CST_LOW (new_const) = number;
1571 TREE_INT_CST_HIGH (new_const) = number < 0 ? -1 : 0;
1572 TREE_TYPE (new_const) = type;
1573 TREE_OVERFLOW (new_const) = TREE_CONSTANT_OVERFLOW (new_const)
1574 = force_fit_type (new_const, 0);
1575
1576 slot = htab_find_slot (size_htab, new_const, INSERT);
1577 if (*slot == 0)
1578 {
1579 tree t = new_const;
1580
1581 *slot = new_const;
1582 new_const = make_node (INTEGER_CST);
1583 return t;
1584 }
1585 else
1586 return (tree) *slot;
1587 }
size_int_type_wide will also be invoked to create nodes for size of other integer type, these sizes information are also system wide unique, and will be accessed frequently, so they are worth to be put into hashtable. Notice that size nodes of internal integer types are also saved in another hashtable. As we have seen, in tree_int_cst, field int_cst is in fact 128 bits in size. It is obviously in most cases the constant will not occupy the whole bits. So the constant needs be extended to all bits (just regards it as type cast to the version of 128 bits).
181 int
182 force_fit_type (tree t, int overflow) in fold-const.c
183 {
184 unsigned HOST_WIDE_INT low;
185 HOST_WIDE_INT high;
186 unsigned int prec;
187
188 if (TREE_CODE (t) == REAL_CST)
189 {
190 /* ??? Used to check for overflow here via CHECK_FLOAT_TYPE.
191 Consider doing it via real_convert now. */
192 return overflow;
193 }
194
195 else if (TREE_CODE (t) != INTEGER_CST)
196 return overflow;
197
198 low = TREE_INT_CST_LOW (t);
199 high = TREE_INT_CST_HIGH (t);
200
201 if (POINTER_TYPE_P (TREE_TYPE (t))
202 || TREE_CODE (TREE_TYPE (t)) == OFFSET_TYPE)
203 prec = POINTER_SIZE;
204 else
205 prec = TYPE_PRECISION (TREE_TYPE (t));
206
207 /* First clear all bits that are beyond the type's precision. */
208
209 if (prec == 2 * HOST_BITS_PER_WIDE_INT)
210 ;
211 else if (prec > HOST_BITS_PER_WIDE_INT)
212 TREE_INT_CST_HIGH (t)
213 &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
214 else
215 {
216 TREE_INT_CST_HIGH (t) = 0;
217 if (prec < HOST_BITS_PER_WIDE_INT)
218 TREE_INT_CST_LOW (t) &= ~((unsigned HOST_WIDE_INT) (-1) << prec);
219 }
220
221 /* Unsigned types do not suffer sign extension or overflow unless they
222 are a sizetype. */
223 if (TREE_UNSIGNED (TREE_TYPE (t))
224 && ! (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
225 && TYPE_IS_SIZETYPE (TREE_TYPE (t))))
226 return overflow;
227
228 /* If the value's sign bit is set, extend the sign. */
229 if (prec != 2 * HOST_BITS_PER_WIDE_INT
230 && (prec > HOST_BITS_PER_WIDE_INT
231 ? 0 != (TREE_INT_CST_HIGH (t)
232 & ((HOST_WIDE_INT) 1
233 << (prec - HOST_BITS_PER_WIDE_INT - 1)))
234 : 0 != (TREE_INT_CST_LOW (t)
235 & ((unsigned HOST_WIDE_INT) 1 << (prec - 1)))))
236 {
237 /* Value is negative:
238 set to 1 all the bits that are outside this type's precision. */
239 if (prec > HOST_BITS_PER_WIDE_INT)
240 TREE_INT_CST_HIGH (t)
241 |= ((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
242 else
243 {
244 TREE_INT_CST_HIGH (t) = -1;
245 if (prec < HOST_BITS_PER_WIDE_INT)
246 TREE_INT_CST_LOW (t) |= ((unsigned HOST_WIDE_INT) (-1) << prec);
247 }
248 }
249
250 /* Return nonzero if signed overflow occurred. */
251 return
252 ((overflow | (low ^ TREE_INT_CST_LOW (t)) | (high ^ TREE_INT_CST_HIGH (t)))
253 != 0);
254 }
Notice that negative number is represented by 2 complement presentation. And force_fit_type also is used to check if certain integer constant is overflowed during constant folding (a kind of optimization – for example, sums the values of constants in the same expression).
Just see the way to check overflow. For signed integer type, if overflow, the signed field changes. Assuming 127+1 for char type, the value changes from 0…01111111B to 0…1000000B, force_fit_type saves this value into high and low, then cleans the extra bits and extend these bits according to the signed bit again, and we get 1…10000000B, low ^ TREE_INT_CST_LOW (t) will return nonzero. And if no overflow occurs, it will be zero for high and low parts at line 252.
1.2.2.1.5.4. Finish layout
Layout_t (continued)
1798 /* Compute the final TYPE_SIZE, TYPE_ALIGN, etc. for TYPE. For
1799 records and unions, finish_record_layout already called this
1800 function. */
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);
1805
1806 /* If this type is created before sizetype has been permanently set,
1807 record it so set_sizetype can fix it up. */
1808 if (! sizetype_set)
1809 early_type_list = tree_cons (NULL_TREE, type, early_type_list);
1810
1811 /* If an alias set has been set for this aggregate when it was incomplete,
1812 force it into alias set 0.
1813 This is too conservative, but we cannot call record_component_aliases
1814 here because some frontends still change the aggregates after
1815 layout_type. */
1816 if (AGGREGATE_TYPE_P (type) && TYPE_ALIAS_SET_KNOWN_P (type))
1817 TYPE_ALIAS_SET (type) = 0;
1818 }
finalize_type_size at line 1804 above, computes size and alignment for the type again after is is laid out. Notice that at line 1808, now at this stage, flag sizetype_size is still not set which means nodes for size_t is not ready yet (still temperary ones). Then we save these nodes before real node of size_t is ready into early_type_list. Since they use size_t, when real node of size_t is ready, we need use it to replace with that temparory one.
After the compiler has nodes for internal integer types created with aid of node of temperary size_t, it can settle down the real size_t. In current GCC, it lies in following code snippet.
c_common_nodes_and_builtins
3172 size_type_node = in c-common.c
3173 TREE_TYPE (identifier_global_value (get_identifier (SIZE_TYPE)));
3174 signed_size_type_node = c_common_signed_type (size_type_node);
3175 set_sizetype (size_type_node);
Above size_type_node is the node present size_t in C/C++. SIZE_TYPE indicates the type of size_t, in x86 Linux, it is unsigned int.
1882 void
1883 set_sizetype (tree type) in stor-layout.c
1884 {
1885 int oprecision = TYPE_PRECISION (type);
1886 /* The *bitsizetype types use a precision that avoids overflows when
1887 calculating signed sizes / offsets in bits. However, when
1888 cross-compiling from a 32 bit to a 64 bit host, we are limited to 64 bit
1889 precision. */
1890 int precision = MIN (oprecision + BITS_PER_UNIT_LOG + 1,
1891 2 * HOST_BITS_PER_WIDE_INT);
1892 unsigned int i;
1893 tree t;
1894
1895 if (sizetype_set)
1896 abort ();
1897
1898 /* Make copies of nodes since we'll be setting TYPE_IS_SIZETYPE. */
1899 sizetype = copy_node (type);
1900 TYPE_DOMAIN (sizetype) = type;
1901 TYPE_IS_SIZETYPE (sizetype) = 1;
1902 bitsizetype = make_node (INTEGER_TYPE);
1903 TYPE_NAME (bitsizetype) = TYPE_NAME (type);
1904 TYPE_PRECISION (bitsizetype) = precision;
1905 TYPE_IS_SIZETYPE (bitsizetype) = 1;
1906
1907 if (TREE_UNSIGNED (type))
1908 fixup_unsigned_type (bitsizetype);
1909 else
1910 fixup_signed_type (bitsizetype);
1911
1912 layout_type (bitsizetype);
1913
1914 if (TREE_UNSIGNED (type))
1915 {
1916 usizetype = sizetype;
1917 ubitsizetype = bitsizetype;
1918 ssizetype = copy_node (make_signed_type (oprecision));
1919 sbitsizetype = copy_node (make_signed_type (precision));
1920 }
1921 else
1922 {
1923 ssizetype = sizetype;
1924 sbitsizetype = bitsizetype;
1925 usizetype = copy_node (make_unsigned_type (oprecision));
1926 ubitsizetype = copy_node (make_unsigned_type (precision));
1927 }
1928
1929 TYPE_NAME (bitsizetype) = get_identifier ("bit_size_type");
1930
1931 /* Show is a sizetype, is a main type, and has no pointers to it. */
1932 for (i = 0; i < ARRAY_SIZE (sizetype_tab); i++)
1933 {
1934 TYPE_IS_SIZETYPE (sizetype_tab[i]) = 1;
1935 TYPE_MAIN_VARIANT (sizetype_tab[i]) = sizetype_tab[i];
1936 TYPE_NEXT_VARIANT (sizetype_tab[i]) = 0;
1937 TYPE_POINTER_TO (sizetype_tab[i]) = 0;
1938 TYPE_REFERENCE_TO (sizetype_tab[i]) = 0;
1939 }
1940
1941 /* Go down each of the types we already made and set the proper type
1942 for the sizes in them. */
1943 for (t = early_type_list; t != 0; t = TREE_CHAIN (t))
1944 {
1945 if (TREE_CODE (TREE_VALUE (t)) != INTEGER_TYPE
1946 && TREE_CODE (TREE_VALUE (t)) != BOOLEAN_TYPE)
1947 abort ();
1948
1949 TREE_TYPE (TYPE_SIZE (TREE_VALUE (t))) = bitsizetype;
1950 TREE_TYPE (TYPE_SIZE_UNIT (TREE_VALUE (t))) = sizetype;
1951 }
1952
1953 early_type_list = 0;
1954 sizetype_set = 1;
1955 }
Notice that at line 1890, oprecision is 32 for x86/Linux. And BITS_PER_UNIT_LOG is defined as following.
2456 #define BITS_PER_UNIT_LOG / in tree.h
2457 ((BITS_PER_UNIT > 1) + (BITS_PER_UNIT > 2) + (BITS_PER_UNIT > 4) /
2458 + (BITS_PER_UNIT > 8) + (BITS_PER_UNIT > 16) + (BITS_PER_UNIT > 32) /
2459 + (BITS_PER_UNIT > 64) + (BITS_PER_UNIT > 128) + (BITS_PER_UNIT > 256))
In x86/Linux, BITS_PER_UNIT is 8 (size of byte), so BITS_PER_UNIT_LOG returns 3.
Remember that, when using temperary sizetype and bitsizetype to create nodes for internal integer types, all these nodes are chained tegother with early_type_list. Now as regular nodes for size_t are ready, the temperary size_t nodes can be replaced.
As we have seen, in GCC, integer constant is presented by nodes of tree_int_cst. To create nodes of this kind, GCC uses build_int_2, which is a macro invoking build_int_2_wide inside.
2107 #define build_int_2(LO, HI) / in tree.h
2108 build_int_2_wide ((unsigned HOST_WIDE_INT) (LO), (HOST_WIDE_INT) (HI))
build_int_2_wide constructs INTEGER_CST node from its parameters low and hi.
403 tree
404 build_int_2_wide (unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi) in tree.c
405 {
406 tree t = make_node (INTEGER_CST);
407
408 TREE_INT_CST_LOW (t) = low;
409 TREE_INT_CST_HIGH (t) = hi;
410 TREE_TYPE (t) = integer_type_node;
411 return t;
412 }