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
;