* expr.c (interpret_float_suffix): Support hr, r, lr, llr, uhr, ur,
ulr, ullr, hk, k, lk, llk, uhk, uk, ulk, ullk.
(cpp_classify_number): Support decimal fixed-point constants without
exponents.
Warn about fixed-point constants when -pedantic.
* include/cpplib.h (CPP_N_SMALL, CPP_N_MEDIUM, CPP_N_LARGE): Change
comments to support fixed-point values.
(CPP_N_FRACT, CPP_N_ACCUM): Define.
From-SVN: r127940
+2007-08-30 Chao-ying Fu <fu@mips.com>
+
+ * expr.c (interpret_float_suffix): Support hr, r, lr, llr, uhr, ur,
+ ulr, ullr, hk, k, lk, llk, uhk, uk, ulk, ullk.
+ (cpp_classify_number): Support decimal fixed-point constants without
+ exponents.
+ Warn about fixed-point constants when -pedantic.
+ * include/cpplib.h (CPP_N_SMALL, CPP_N_MEDIUM, CPP_N_LARGE): Change
+ comments to support fixed-point values.
+ (CPP_N_FRACT, CPP_N_ACCUM): Define.
+
2007-08-18 Tom Tromey <tromey@redhat.com>
PR preprocessor/32974:
2007-08-18 Tom Tromey <tromey@redhat.com>
PR preprocessor/32974:
interpret_float_suffix (const uchar *s, size_t len)
{
size_t f, l, w, q, i, d;
interpret_float_suffix (const uchar *s, size_t len)
{
size_t f, l, w, q, i, d;
f = l = w = q = i = d = 0;
f = l = w = q = i = d = 0;
while (len--)
switch (s[len])
{
while (len--)
switch (s[len])
{
+ case 'r': case 'R': r++; break;
+ case 'k': case 'K': k++; break;
+ case 'u': case 'U': u++; break;
+ case 'h': case 'H': h++; break;
case 'f': case 'F':
if (d > 0)
return 0;
case 'f': case 'F':
if (d > 0)
return 0;
if (d > 0)
return 0;
l++;
if (d > 0)
return 0;
l++;
+ /* If there are two Ls, they must be adjacent and the same case. */
+ if (l == 2 && s[len] != s[len + 1])
+ return 0;
break;
case 'w': case 'W':
if (d > 0)
break;
case 'w': case 'W':
if (d > 0)
- if (f + l + w + q > 1 || i > 1)
+ if (r + k > 1 || h > 1 || l > 2 || u > 1)
+ return 0;
+
+ if (r == 1)
+ {
+ if (f || i || d || w || q)
+ return 0;
+
+ return (CPP_N_FRACT
+ | (u ? CPP_N_UNSIGNED : 0)
+ | (h ? CPP_N_SMALL :
+ l == 2 ? CPP_N_LARGE :
+ l == 1 ? CPP_N_MEDIUM : 0));
+ }
+
+ if (k == 1)
+ {
+ if (f || i || d || w || q)
+ return 0;
+
+ return (CPP_N_ACCUM
+ | (u ? CPP_N_UNSIGNED : 0)
+ | (h ? CPP_N_SMALL :
+ l == 2 ? CPP_N_LARGE :
+ l == 1 ? CPP_N_MEDIUM : 0));
+ }
+
+ if (f + l + w + q > 1 || i > 1 || h + u > 0)
return 0;
/* Allow dd, df, dl suffixes for decimal float constants. */
return 0;
/* Allow dd, df, dl suffixes for decimal float constants. */
+ /* The suffix may be for decimal fixed-point constants without exponent. */
+ if (radix != 16 && float_flag == NOT_FLOAT)
+ {
+ result = interpret_float_suffix (str, limit - str);
+ if ((result & CPP_N_FRACT) || (result & CPP_N_ACCUM))
+ {
+ result |= CPP_N_FLOATING;
+ /* We need to restore the radix to 10, if the radix is 8. */
+ if (radix == 8)
+ radix = 10;
+
+ if (CPP_PEDANTIC (pfile))
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "fixed-point constants are a GCC extension");
+ goto syntax_ok;
+ }
+ else
+ result = 0;
+ }
+
if (float_flag != NOT_FLOAT && radix == 8)
radix = 10;
if (float_flag != NOT_FLOAT && radix == 8)
radix = 10;
+ if ((result & (CPP_N_FRACT | CPP_N_ACCUM)) && CPP_PEDANTIC (pfile))
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "fixed-point constants are a GCC extension");
+
if ((result & CPP_N_DFLOAT) && CPP_PEDANTIC (pfile))
cpp_error (pfile, CPP_DL_PEDWARN,
"decimal float constants are a GCC extension");
if ((result & CPP_N_DFLOAT) && CPP_PEDANTIC (pfile))
cpp_error (pfile, CPP_DL_PEDWARN,
"decimal float constants are a GCC extension");
result |= CPP_N_INTEGER;
}
result |= CPP_N_INTEGER;
}
if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
cpp_error (pfile, CPP_DL_PEDWARN,
"imaginary constants are a GCC extension");
if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
cpp_error (pfile, CPP_DL_PEDWARN,
"imaginary constants are a GCC extension");
#define CPP_N_FLOATING 0x0002
#define CPP_N_WIDTH 0x00F0
#define CPP_N_FLOATING 0x0002
#define CPP_N_WIDTH 0x00F0
-#define CPP_N_SMALL 0x0010 /* int, float. */
-#define CPP_N_MEDIUM 0x0020 /* long, double. */
-#define CPP_N_LARGE 0x0040 /* long long, long double. */
+#define CPP_N_SMALL 0x0010 /* int, float, shrot _Fract/Accum */
+#define CPP_N_MEDIUM 0x0020 /* long, double, long _Fract/_Accum. */
+#define CPP_N_LARGE 0x0040 /* long long, long double,
+ long long _Fract/Accum. */
#define CPP_N_WIDTH_MD 0xF0000 /* machine defined. */
#define CPP_N_MD_W 0x10000
#define CPP_N_WIDTH_MD 0xF0000 /* machine defined. */
#define CPP_N_MD_W 0x10000
#define CPP_N_IMAGINARY 0x2000
#define CPP_N_DFLOAT 0x4000
#define CPP_N_IMAGINARY 0x2000
#define CPP_N_DFLOAT 0x4000
+#define CPP_N_FRACT 0x100000 /* Fract types. */
+#define CPP_N_ACCUM 0x200000 /* Accum types. */
+
/* Classify a CPP_NUMBER token. The return value is a combination of
the flags from the above sets. */
extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *);
/* Classify a CPP_NUMBER token. The return value is a combination of
the flags from the above sets. */
extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *);