c-ada-spec.c (dump_number): New function.
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 15 Aug 2016 13:05:37 +0000 (13:05 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 15 Aug 2016 13:05:37 +0000 (13:05 +0000)
* c-ada-spec.c (dump_number): New function.
(handle_escape_character): Likewise.
(print_ada_macros): Add handling of constant integers and strings.

Co-Authored-By: Arnaud Charlet <charlet@adacore.com>
From-SVN: r239481

gcc/c-family/ChangeLog
gcc/c-family/c-ada-spec.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/dump-ada-spec-5.c [new file with mode: 0644]

index 14db7087321a140dc06c688ff39009558c8f6f4e..84f8007bd91d50cc2ff5a702b94f6977c2fee7ec 100644 (file)
@@ -1,3 +1,10 @@
+2016-08-16  Eric Botcazou  <ebotcazou@adacore.com>
+            Arnaud Charlet  <charlet@adacore.com>
+
+       * c-ada-spec.c (dump_number): New function.
+       (handle_escape_character): Likewise.
+       (print_ada_macros): Add handling of constant integers and strings.
+
 2016-08-12  Marek Polacek  <polacek@redhat.com>
 
        PR c/7652
index 17b86103fec7e65a0002ddd4ed3dea10cd73bc49..a4e0c38cef9f0a52beea23bdb981d933dacbfc5d 100644 (file)
@@ -116,6 +116,58 @@ macro_length (const cpp_macro *macro, int *supported, int *buffer_len,
   (*buffer_len)++;
 }
 
+/* Dump all digits/hex chars from NUMBER to BUFFER and return a pointer
+   to the character after the last character written.  */
+
+static unsigned char *
+dump_number (unsigned char *number, unsigned char *buffer)
+{
+  while (*number != '\0'
+        && *number != 'U'
+        && *number != 'u'
+        && *number != 'l'
+        && *number != 'L')
+    *buffer++ = *number++;
+
+  return buffer;
+}
+
+/* Handle escape character C and convert to an Ada character into BUFFER.
+   Return a pointer to the character after the last character written, or
+   NULL if the escape character is not supported.  */
+
+static unsigned char *
+handle_escape_character (unsigned char *buffer, char c)
+{
+  switch (c)
+    {
+      case '"':
+       *buffer++ = '"';
+       *buffer++ = '"';
+       break;
+
+      case 'n':
+       strcpy ((char *) buffer, "\" & ASCII.LF & \"");
+       buffer += 16;
+       break;
+
+      case 'r':
+       strcpy ((char *) buffer, "\" & ASCII.CR & \"");
+       buffer += 16;
+       break;
+
+      case 't':
+       strcpy ((char *) buffer, "\" & ASCII.HT & \"");
+       buffer += 16;
+       break;
+
+      default:
+       return NULL;
+    }
+
+  return buffer;
+}
+
 /* Dump into PP a set of MAX_ADA_MACROS MACROS (C/C++) as Ada constants when
    possible.  */
 
@@ -132,7 +184,7 @@ print_ada_macros (pretty_printer *pp, cpp_hashnode **macros, int max_ada_macros)
       int supported = 1, prev_is_one = 0, buffer_len, param_len;
       int is_string = 0, is_char = 0;
       char *ada_name;
-      unsigned char *s, *params, *buffer, *buf_param, *char_one = NULL;
+      unsigned char *s, *params, *buffer, *buf_param, *char_one = NULL, *tmp;
 
       macro_length (macro, &supported, &buffer_len, &param_len);
       s = buffer = XALLOCAVEC (unsigned char, buffer_len);
@@ -246,14 +298,33 @@ print_ada_macros (pretty_printer *pp, cpp_hashnode **macros, int max_ada_macros)
                  case CPP_CHAR32:
                  case CPP_UTF8CHAR:
                  case CPP_NAME:
-                 case CPP_STRING:
-                 case CPP_NUMBER:
                    if (!macro->fun_like)
                      supported = 0;
                    else
                      buffer = cpp_spell_token (parse_in, token, buffer, false);
                    break;
 
+                 case CPP_STRING:
+                   is_string = 1;
+                   {
+                     const unsigned char *s = token->val.str.text;
+
+                     for (; *s; s++)
+                       if (*s == '\\')
+                         {
+                           s++;
+                           buffer = handle_escape_character (buffer, *s);
+                           if (buffer == NULL)
+                             {
+                               supported = 0;
+                               break;
+                             }
+                         }
+                       else
+                         *buffer++ = *s;
+                   }
+                   break;
+
                  case CPP_CHAR:
                    is_char = 1;
                    {
@@ -278,6 +349,72 @@ print_ada_macros (pretty_printer *pp, cpp_hashnode **macros, int max_ada_macros)
                    }
                    break;
 
+                 case CPP_NUMBER:
+                   tmp = cpp_token_as_text (parse_in, token);
+
+                   switch (*tmp)
+                     {
+                       case '0':
+                         switch (tmp[1])
+                           {
+                             case '\0':
+                             case 'l':
+                             case 'L':
+                             case 'u':
+                             case 'U':
+                               *buffer++ = '0';
+                               break;
+
+                             case 'x':
+                             case 'X':
+                               *buffer++ = '1';
+                               *buffer++ = '6';
+                               *buffer++ = '#';
+                               buffer = dump_number (tmp + 2, buffer);
+                               *buffer++ = '#';
+                               break;
+
+                             case 'b':
+                             case 'B':
+                               *buffer++ = '2';
+                               *buffer++ = '#';
+                               buffer = dump_number (tmp + 2, buffer);
+                               *buffer++ = '#';
+                               break;
+
+                             default:
+                               /* Dump floating constants unmodified.  */
+                               if (strchr ((const char *)tmp, '.'))
+                                 buffer = dump_number (tmp, buffer);
+                               else
+                                 {
+                                   *buffer++ = '8';
+                                   *buffer++ = '#';
+                                   buffer = dump_number (tmp + 1, buffer);
+                                   *buffer++ = '#';
+                                 }
+                               break;
+                           }
+                         break;
+
+                       case '1':
+                         if (tmp[1] == '\0' || tmp[1] == 'l' || tmp[1] == 'u'
+                             || tmp[1] == 'L' || tmp[1] == 'U')
+                           {
+                             is_one = 1;
+                             char_one = buffer;
+                             *buffer++ = '1';
+                           }
+                         else
+                           buffer = dump_number (tmp, buffer);
+                         break;
+
+                       default:
+                         buffer = dump_number (tmp, buffer);
+                         break;
+                     }
+                   break;
+
                  case CPP_LSHIFT:
                    if (prev_is_one)
                      {
index fc25482e1bb735a2ed3b9be0d4b2984d90cae792..eeaa5d5bc2c74fb37b414cb14c55ffa1edfa2a3e 100644 (file)
@@ -1,3 +1,7 @@
+2016-08-16  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * c-c++-common/dump-ada-spec-5.c: New test.
+
 2016-08-15  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/73434
diff --git a/gcc/testsuite/c-c++-common/dump-ada-spec-5.c b/gcc/testsuite/c-c++-common/dump-ada-spec-5.c
new file mode 100644 (file)
index 0000000..7221109
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-ada-spec" } */
+
+#define not_octal_constant 0.627
+
+extern double foo (double);
+
+/* { dg-final { scan-ada-spec-not "unsupported macro" } } */
+/* { dg-final { cleanup-ada-spec } } */