6 /* order is important. */
9 unsigned long long max;
11 { TS_INT, P_INT_MAX },
12 { TS_UNSIGNED, P_UINT_MAX },
13 { TS_LONG, P_LONG_MAX },
14 { TS_UNSIGNED|TS_LONG, P_ULONG_MAX },
15 { TS_LONGLONG, P_LLONG_MAX },
16 { TS_UNSIGNED|TS_LONGLONG, P_ULLONG_MAX },
17 /* XXX other built-in integral types should maybe go here too */
20 #define N_INT_INFO (sizeof int_info / sizeof *int_info)
22 /* Throw away the bottom few bits of a floating point number.
23 * Makes rather free assumptions about representation!
24 * XXX only tested on i386 linux
26 * Why on earth do we need this ridiculous thing?
28 * gcc's FLT_MAX is defined as 3.40282347e+38F
29 * which its strtold converts to xxxx407effffff048ff9eb4e
30 * but gcc converts it to xxxx407effffff0000000000
31 * ----EEEEMMMMMMMMMMMMMMMM
32 * so we end up with 3.40282347e+38 > FLT_MAX being true and getting
35 * Really gcc should have written it as e.g. 3.4028234663852885982e+38
36 * which strtold converts to the exact answer.
38 * At least potentially the same problem might exist for DBL_MAX (I've
41 static void massage_float(long double *ld,
43 unsigned char *ptr = (unsigned char *)ld;
47 #if BYTE_ORDER == BIG_ENDIAN
48 memset(ptr + sizeof (long double) - bits / 8, 0, bits / 8);
49 n = sizeof (long double) - bits / 8 - 1;
51 memset(ptr, 0, bits / 8);
55 ptr[n] &= 0xFFFFFFFF << left;
58 struct declarator *numbertype(const struct expression *e) {
61 int hex, f_l = 0, f_u = 0, f_f = 0;
67 /* . always means a floating constant
68 * E/e but no 0x means a floating constant
69 * 0x and P/p means a floating constant
70 * anything else is some kind of integer
72 hex = !strncmp(e->u.constant, "0x", 2);
73 if(strchr(e->u.constant, '.')
74 || (hex ? strchr(e->u.constant, 'p') || strchr(e->u.constant, 'P')
75 : strchr(e->u.constant, 'e') || strchr(e->u.constant, 'E'))) {
76 /* long double had better be as big as the target's long double */
78 ld = strtold(e->u.constant, &rest);
80 inputerror(&e->where, "floating constant '%s' out of range",
86 case 'f': case 'F': f_f++; break;
87 case 'l': case 'L': f_l++; break;
89 inputerror(&e->where, "invalid suffix on floating constant '%s'",
95 inputerror(&e->where, "too many suffixes on floating constant '%s'",
100 massage_float(&ld, LDBL_MANT_DIG - P_FLT_MANT_DIG);
102 inputerror(&e->where, "float constant '%s' out of range",
108 massage_float(&ld, LDBL_MANT_DIG - P_DBL_MANT_DIG);
110 inputerror(&e->where, "double constant '%s' out of range",
116 massage_float(&ld, LDBL_MANT_DIG - P_LDBL_MANT_DIG);
117 if(ld > P_LDBL_MAX) {
118 inputerror(&e->where, "double constant '%s' out of range",
122 ts = TS_LONG|TS_DOUBLE;
125 NEW(d->declaration_specifiers);
126 d->declaration_specifiers->type_specifiers = ts;
130 u = strtoull(e->u.constant, &rest, 0);
132 inputerror(&e->where, "integral constant '%s' out of range",
138 case 'u': case 'U': f_u++; break;
139 case 'l': case 'L': f_l++; break;
141 inputerror(&e->where, "invalid suffix on integral constant '%s'",
146 if(f_u > 1 || f_l > 2) {
147 inputerror(&e->where, "too many suffixes on integral constant '%s'",
151 if(hex || e->u.constant[0] == '0') {
152 /* hex or octal - first type that fits */
153 for(n = 2 * f_l; n < N_INT_INFO; ++n)
154 if(u <= int_info[n].max)
157 /* decimal - unsigned only allowed if u/U specified */
158 for(n = 2 * f_l; n < N_INT_INFO; ++n)
159 if(u <= int_info[n].max)
160 if(f_u || !(int_info[n].type & TS_UNSIGNED))
163 if(n >= N_INT_INFO) {
164 inputerror(&e->where, "integral constant '%s' out of range",
169 NEW(d->declaration_specifiers);
170 d->declaration_specifiers->type_specifiers = int_info[n].type;