https://gcc.gnu.org/g:73eef7a04453d01147cbf4642fe6626350dded75

commit r15-826-g73eef7a04453d01147cbf4642fe6626350dded75
Author: Eric Botcazou <ebotca...@adacore.com>
Date:   Fri May 24 19:48:18 2024 +0200

    Small enhancement to implementation of -fdump-ada-spec
    
    This lets it recognize more preprocessing floating constants.
    
    gcc/c-family/
            * c-ada-spec.cc (is_cpp_float): New predicate.
            (dump_number): Deal with more preprocessing floating constants.
            (dump_ada_macros) <CPP_NUMBER>: Use is_cpp_float.

Diff:
---
 gcc/c-family/c-ada-spec.cc | 70 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 61 insertions(+), 9 deletions(-)

diff --git a/gcc/c-family/c-ada-spec.cc b/gcc/c-family/c-ada-spec.cc
index 8f0849bd427..0bea923220b 100644
--- a/gcc/c-family/c-ada-spec.cc
+++ b/gcc/c-family/c-ada-spec.cc
@@ -113,6 +113,26 @@ macro_length (const cpp_macro *macro, int *supported, int 
*buffer_len,
   (*buffer_len)++;
 }
 
+/* Return true if NUMBER is a preprocessing floating-point number.  */
+
+static bool
+is_cpp_float (unsigned char *number)
+{
+  /* In C, a floating constant need not have a point.  */
+  while (*number != '\0')
+    {
+      if (*number == '.')
+       return true;
+      else if ((*number == 'e' || *number == 'E')
+              && (*(number + 1) == '+' || *(number + 1) == '-'))
+       return true;
+      else
+       number++;
+    }
+
+  return false;
+}
+
 /* Dump all digits/hex chars from NUMBER to BUFFER and return a pointer
    to the character after the last character written.  If FLOAT_P is true,
    this is a floating-point number.  */
@@ -120,12 +140,45 @@ macro_length (const cpp_macro *macro, int *supported, int 
*buffer_len,
 static unsigned char *
 dump_number (unsigned char *number, unsigned char *buffer, bool float_p)
 {
-  while (*number != '\0'
-        && *number != (float_p ? 'F' : 'U')
-        && *number != (float_p ? 'f' : 'u')
-        && *number != 'l'
-        && *number != 'L')
-    *buffer++ = *number++;
+  /* In Ada, a real literal is a numeric literal that includes a point.  */
+  if (float_p)
+    {
+      bool point_seen = false;
+
+      while (*number != '\0')
+       {
+         if (ISDIGIT (*number))
+           *buffer++ = *number++;
+         else if (*number == '.')
+           {
+             *buffer++ = *number++;
+             point_seen = true;
+           }
+         else if ((*number == 'e' || *number == 'E')
+                  && (*(number + 1) == '+' || *(number + 1) == '-'))
+           {
+             if (!point_seen)
+               {
+                 *buffer++ = '.';
+                 *buffer++ = '0';
+                 point_seen = true;
+               }
+              *buffer++ = *number++;
+              *buffer++ = *number++;
+           }
+         else
+           break;
+       }
+    }
+
+  /* An integer literal is a numeric literal without a point.  */
+  else
+    while (*number != '\0'
+          && *number != 'U'
+          && *number != 'u'
+          && *number != 'l'
+          && *number != 'L')
+      *buffer++ = *number++;
 
   return buffer;
 }
@@ -450,7 +503,7 @@ dump_ada_macros (pretty_printer *pp, const char* file)
 
                              default:
                                /* Dump floating-point constant unmodified.  */
-                               if (strchr ((const char *)tmp, '.'))
+                               if (is_cpp_float (tmp))
                                  buffer = dump_number (tmp, buffer, true);
                                else
                                  {
@@ -480,8 +533,7 @@ dump_ada_macros (pretty_printer *pp, const char* file)
 
                        default:
                          buffer
-                           = dump_number (tmp, buffer,
-                                          strchr ((const char *)tmp, '.'));
+                           = dump_number (tmp, buffer, is_cpp_float (tmp));
                          break;
                      }
                    break;

Reply via email to