Hi!

I'm trying to implement the wbN suffix as per the extension proposed in
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119058>.

I think I've got most of it, but need to know how I can parse an integer
that is in the middle of a token.  That is, I have a token that could be
0x1234wb567u, and need to have a subtoken that starts right after the
wb (or WB), so '567u', which I can pass to cpp_interpret_integer().  Is
there any function to generate such a subtoken, or do I need to do it
manually?

Below is the draft with which I'm working.


Have a lovely night!
Alex

---
diff --git i/gcc/c-family/c-lex.cc w/gcc/c-family/c-lex.cc
index 8e182938938..32cf253df8d 100644
--- i/gcc/c-family/c-lex.cc
+++ w/gcc/c-family/c-lex.cc
@@ -930,7 +930,7 @@ interpret_integer (const cpp_token *token, unsigned int 
flags,
 
   *overflow = OT_NONE;
 
-  if (UNLIKELY (flags & CPP_N_BITINT))
+  if (UNLIKELY (flags & (CPP_N_BITINT | CPP_N_BITINT_N)))
     {
       unsigned int suffix_len = 2 + ((flags & CPP_N_UNSIGNED) ? 1 : 0);
       int max_bits_per_digit = 4; // ceil (log2 (10))
@@ -1070,11 +1070,29 @@ interpret_integer (const cpp_token *token, unsigned int 
flags,
          while (1);
        }
 
-      prec = wi::min_precision (wval, UNSIGNED);
-      if (prec == 0)
-       prec = 1;
-      if ((flags & CPP_N_UNSIGNED) == 0)
-       ++prec;
+      if (flags & CPP_N_BITINT)
+       {
+         prec = wi::min_precision (wval, UNSIGNED);
+         if (prec == 0)
+           prec = 1;
+         if ((flags & CPP_N_UNSIGNED) == 0)
+           ++prec;
+       }
+      else
+       {
+         /* (flags & CPP_N_BITINT_N) */
+         /* TODO: Parse decimal digits after wb/WB.  */
+         /* Need a subtoken that starts right after wb/WB. */
+         cpp_token subtok;
+         subtok = subtoken(token, "wb") ?: subtoken(token, "WB");
+         integer = cpp_interpret_integer (parse_in, subtoken,
+                                          CPP_N_DECIMAL | CPP_N_UNSIGNED);
+         ival[0] = integer.low;
+         ival[1] = integer.high;
+         ival[2] = 0;
+         prec = widest_int::from_array (ival, 3);
+       }
+
       if (prec > bitint_maxwidth)
        {
        bitint_overflow:
diff --git i/libcpp/expr.cc w/libcpp/expr.cc
index 685233797c8..a8a715b1364 100644
--- i/libcpp/expr.cc
+++ w/libcpp/expr.cc
@@ -338,7 +338,8 @@ static unsigned int
 interpret_int_suffix (cpp_reader *pfile, const uchar *s, size_t len)
 {
   size_t orig_len = len;
-  size_t u, l, i, z, wb;
+  size_t u, l, i, z, wb, wbN;
+  size_t wbN_bits;
 
   u = l = i = z = wb = 0;
 
@@ -366,11 +367,40 @@ interpret_int_suffix (cpp_reader *pfile, const uchar *s, 
size_t len)
        wb++;
        len--;
        break;
+      case 0:
+      case 1:
+      case 2:
+      case 3:
+      case 4:
+      case 5:
+      case 6:
+      case 7:
+      case 8:
+      case 9:
+       {
+         size_t dd;
+
+         for (dd = 1; dd < len && ISDIGIT(s[len - dd]); dd++)
+           continue;
+         /* Octals and 0 not allowed.  */
+         if (s[len - dd + 1] == '0')
+           return 0;
+         len -= dd;
+         if (len == 0)
+           return 0;
+         len--;
+         wbN++;
+         if (s[len] == 'w' && s[len + 1] == 'b')
+           break;
+         if (s[len] == 'W' && s[len + 1] == 'B')
+           break;
+         return 0;
+       }
       default:
        return 0;
       }
 
-  if (l > 2 || u > 1 || i > 1 || z > 1 || wb > 1)
+  if (l > 2 || u > 1 || i > 1 || z > 1 || wb > 1 || wbN > 1)
     return 0;
 
   if (z)
@@ -389,6 +419,14 @@ interpret_int_suffix (cpp_reader *pfile, const uchar *s, 
size_t len)
        return 0;
     }
 
+  if (wbN)
+    {
+      if (CPP_OPTION (pfile, cplusplus))
+       return 0;
+      if (l > 0 || i > 0 || z > 0 || wb > 0)
+       return 0;
+    }
+
   if (i)
     {
       if (!CPP_OPTION (pfile, ext_numeric_literals))
@@ -408,7 +446,8 @@ interpret_int_suffix (cpp_reader *pfile, const uchar *s, 
size_t len)
          | ((l == 0) ? CPP_N_SMALL
             : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE)
          | (z ? CPP_N_SIZE_T : 0)
-         | (wb ? CPP_N_BITINT : 0));
+         | (wb ? CPP_N_BITINT : 0)
+         | (wbN ? CPP_N_BITINT_N : 0));
 }
 
 /* Return the classification flags for an int suffix.  */
diff --git i/libcpp/include/cpplib.h w/libcpp/include/cpplib.h
index e73f77e67d8..d76aeec77f4 100644
--- i/libcpp/include/cpplib.h
+++ w/libcpp/include/cpplib.h
@@ -1363,6 +1363,7 @@ struct cpp_num
 #define CPP_N_SIZE_T   0x2000000 /* C++23 size_t literal.  */
 #define CPP_N_BFLOAT16 0x4000000 /* std::bfloat16_t type.  */
 #define CPP_N_BITINT   0x8000000 /* C23 _BitInt literal.  */
+#define CPP_N_BITINT_N 0x10000000 /* C2y _BitInt(N) literal.  */
 
 #define CPP_N_WIDTH_FLOATN_NX  0xF0000000 /* _FloatN / _FloatNx value
                                              of N, divided by 16.  */


-- 
<https://www.alejandro-colomar.es/>

Attachment: signature.asc
Description: PGP signature

Reply via email to