expr.c (interpret_float_suffix): Support hr, r, lr, llr, uhr, ur, ulr, ullr, hk,...
authorChao-ying Fu <fu@mips.com>
Thu, 30 Aug 2007 23:05:17 +0000 (23:05 +0000)
committerChao-ying Fu <chaoyingfu@gcc.gnu.org>
Thu, 30 Aug 2007 23:05:17 +0000 (23:05 +0000)
* 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

libcpp/ChangeLog
libcpp/expr.c
libcpp/include/cpplib.h

index 7e8dfd5..c24f47e 100644 (file)
@@ -1,3 +1,14 @@
+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:
index f20d50c..9df7533 100644 (file)
@@ -83,12 +83,18 @@ static unsigned int
 interpret_float_suffix (const uchar *s, size_t len)
 {
   size_t f, l, w, q, i, d;
+  size_t r, k, u, h;
 
   f = l = w = q = i = d = 0;
+  r = k = u = h = 0;
 
   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;
@@ -98,6 +104,9 @@ interpret_float_suffix (const uchar *s, size_t len)
        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)
@@ -116,7 +125,34 @@ interpret_float_suffix (const uchar *s, size_t len)
        return 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.  */
@@ -238,6 +274,26 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
        }
     }
 
+  /* 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;
 
@@ -304,6 +360,10 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
           return CPP_N_INVALID;
         }
 
+      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");
@@ -343,6 +403,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
       result |= CPP_N_INTEGER;
     }
 
+ syntax_ok:
   if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
     cpp_error (pfile, CPP_DL_PEDWARN,
               "imaginary constants are a GCC extension");
index 2dac4c2..039dfbb 100644 (file)
@@ -747,9 +747,10 @@ struct cpp_num
 #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
@@ -765,6 +766,9 @@ struct cpp_num
 #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 *);