Call cooked_read in ppu2spu_prev_register
[binutils-gdb.git] / gdb / macroexp.c
index dda3592db317db70ecf368cd4d9008d305b3de61..8a2df1edff30246a438d3cd53eeb47b84fb73b44 100644 (file)
@@ -1,5 +1,5 @@
 /* C preprocessor macro expansion for GDB.
-   Copyright (C) 2002, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2002-2018 Free Software Foundation, Inc.
    Contributed by Red Hat, Inc.
 
    This file is part of GDB.
@@ -22,7 +22,7 @@
 #include "bcache.h"
 #include "macrotab.h"
 #include "macroexp.h"
-#include "gdb_assert.h"
+#include "c-lang.h"
 
 
 \f
@@ -53,8 +53,9 @@ struct macro_buffer
 
   /* Zero if TEXT can be safely realloc'ed (i.e., it's its own malloc
      block).  Non-zero if TEXT is actually pointing into the middle of
-     some other block, and we shouldn't reallocate it.  */
-  int shared;
+     some other block, or to a string literal, and we shouldn't
+     reallocate it.  */
+  bool shared;
 
   /* For detecting token splicing. 
 
@@ -85,19 +86,22 @@ init_buffer (struct macro_buffer *b, int n)
   else
     b->text = NULL;
   b->len = 0;
-  b->shared = 0;
+  b->shared = false;
   b->last_token = -1;
 }
 
 
 /* Set the macro buffer *BUF to refer to the LEN bytes at ADDR, as a
    shared substring.  */
+
 static void
-init_shared_buffer (struct macro_buffer *buf, char *addr, int len)
+init_shared_buffer (struct macro_buffer *buf, const char *addr, int len)
 {
-  buf->text = addr;
+  /* The function accept a "const char *" addr so that clients can
+     pass in string literals without casts.  */
+  buf->text = (char *) addr;
   buf->len = len;
-  buf->shared = 1;
+  buf->shared = true;
   buf->size = 0;
   buf->last_token = -1;
 }
@@ -112,6 +116,17 @@ free_buffer (struct macro_buffer *b)
     xfree (b->text);
 }
 
+/* Like free_buffer, but return the text as an xstrdup()d string.
+   This only exists to try to make the API relatively clean.  */
+
+static char *
+free_buffer_return_text (struct macro_buffer *b)
+{
+  gdb_assert (! b->shared);
+  gdb_assert (b->size);
+  /* Nothing to do.  */
+  return b->text;
+}
 
 /* A cleanup function for macro buffers.  */
 static void
@@ -135,7 +150,7 @@ resize_buffer (struct macro_buffer *b, int n)
     while (b->size <= n)
       b->size *= 2;
 
-  b->text = xrealloc (b->text, b->size);
+  b->text = (char *) xrealloc (b->text, b->size);
 }
 
 
@@ -155,7 +170,7 @@ appendc (struct macro_buffer *b, int c)
 
 /* Append the LEN bytes at ADDR to the buffer B.  */
 static void
-appendmem (struct macro_buffer *b, char *addr, int len)
+appendmem (struct macro_buffer *b, const char *addr, int len)
 {
   int new_len = b->len + len;
 
@@ -204,7 +219,7 @@ set_token (struct macro_buffer *tok, char *start, char *end)
   init_shared_buffer (tok, start, end - start);
   tok->last_token = 0;
 
-  /* Presumed; get_identifier may overwrite this. */
+  /* Presumed; get_identifier may overwrite this.  */
   tok->is_identifier = 0;
 }
 
@@ -320,26 +335,27 @@ get_character_constant (struct macro_buffer *tok, char *p, char *end)
      way GDB's C/C++ lexer does.  So we call parse_escape in utils.c
      to handle escape sequences.  */
   if ((p + 1 <= end && *p == '\'')
-      || (p + 2 <= end && p[0] == 'L' && p[1] == '\''))
+      || (p + 2 <= end
+         && (p[0] == 'L' || p[0] == 'u' || p[0] == 'U')
+         && p[1] == '\''))
     {
       char *tok_start = p;
-      char *body_start;
+      int char_count = 0;
 
       if (*p == '\'')
         p++;
-      else if (*p == 'L')
+      else if (*p == 'L' || *p == 'u' || *p == 'U')
         p += 2;
       else
-        gdb_assert (0);
+        gdb_assert_not_reached ("unexpected character constant");
 
-      body_start = p;
       for (;;)
         {
           if (p >= end)
             error (_("Unmatched single quote."));
           else if (*p == '\'')
             {
-              if (p == body_start)
+              if (!char_count)
                 error (_("A character constant must contain at least one "
                        "character."));
               p++;
@@ -347,11 +363,17 @@ get_character_constant (struct macro_buffer *tok, char *p, char *end)
             }
           else if (*p == '\\')
             {
-              p++;
-              parse_escape (&p);
+             const char *s, *o;
+
+             s = o = ++p;
+             char_count += c_parse_escape (&s, NULL);
+             p += s - o;
             }
           else
-            p++;
+           {
+             p++;
+             char_count++;
+           }
         }
 
       set_token (tok, tok_start, p);
@@ -370,25 +392,25 @@ static int
 get_string_literal (struct macro_buffer *tok, char *p, char *end)
 {
   if ((p + 1 <= end
-       && *p == '\"')
+       && *p == '"')
       || (p + 2 <= end
-          && p[0] == 'L'
-          && p[1] == '\"'))
+          && (p[0] == 'L' || p[0] == 'u' || p[0] == 'U')
+          && p[1] == '"'))
     {
       char *tok_start = p;
 
-      if (*p == '\"')
+      if (*p == '"')
         p++;
-      else if (*p == 'L')
+      else if (*p == 'L' || *p == 'u' || *p == 'U')
         p += 2;
       else
-        gdb_assert (0);
+        gdb_assert_not_reached ("unexpected string literal");
 
       for (;;)
         {
           if (p >= end)
             error (_("Unterminated string in expression."));
-          else if (*p == '\"')
+          else if (*p == '"')
             {
               p++;
               break;
@@ -398,8 +420,11 @@ get_string_literal (struct macro_buffer *tok, char *p, char *end)
                    "constants."));
           else if (*p == '\\')
             {
-              p++;
-              parse_escape (&p);
+             const char *s, *o;
+
+             s = o = ++p;
+             c_parse_escape (&s, NULL);
+             p += s - o;
             }
           else
             p++;
@@ -518,6 +543,7 @@ get_token (struct macro_buffer *tok,
       {
         /* How many characters did we consume, including whitespace?  */
         int consumed = p - src->text + tok->len;
+
         src->text += consumed;
         src->len -= consumed;
         return 1;
@@ -631,7 +657,7 @@ append_tokens_without_splicing (struct macro_buffer *dest,
    stringify; it is LEN bytes long.  */
 
 static void
-stringify (struct macro_buffer *dest, char *arg, int len)
+stringify (struct macro_buffer *dest, const char *arg, int len)
 {
   /* Trim initial whitespace from ARG.  */
   while (len > 0 && macro_is_whitespace (*arg))
@@ -674,6 +700,21 @@ stringify (struct macro_buffer *dest, char *arg, int len)
   dest->last_token = dest->len;
 }
 
+/* See macroexp.h.  */
+
+char *
+macro_stringify (const char *str)
+{
+  struct macro_buffer buffer;
+  int len = strlen (str);
+
+  init_buffer (&buffer, len);
+  stringify (&buffer, str, len);
+  appendc (&buffer, '\0');
+
+  return free_buffer_return_text (&buffer);
+}
+
 \f
 /* Expanding macros!  */
 
@@ -695,7 +736,7 @@ struct macro_name_list {
    particular macro, and otherwise delegates the decision to another
    function/baton pair.  But that makes the linked list of excluded
    macros chained through untyped baton pointers, which will make it
-   harder to debug.  :( */
+   harder to debug.  :(  */
 static int
 currently_rescanning (struct macro_name_list *list, const char *name)
 {
@@ -760,6 +801,7 @@ gather_arguments (const char *name, struct macro_buffer *src,
      paren.  */
   {
     struct macro_buffer temp;
+
     init_shared_buffer (&temp, src->text, src->len);
 
     if (! get_token (&tok, &temp)
@@ -776,7 +818,7 @@ gather_arguments (const char *name, struct macro_buffer *src,
 
   args_len = 0;
   args_size = 6;
-  args = (struct macro_buffer *) xmalloc (sizeof (*args) * args_size);
+  args = XNEWVEC (struct macro_buffer, args_size);
 
   for (;;)
     {
@@ -787,7 +829,7 @@ gather_arguments (const char *name, struct macro_buffer *src,
       if (args_len >= args_size)
         {
           args_size *= 2;
-          args = xrealloc (args, sizeof (*args) * args_size);
+          args = XRESIZEVEC (struct macro_buffer, args, args_size);
         }
 
       /* Initialize the next argument.  */
@@ -798,8 +840,6 @@ gather_arguments (const char *name, struct macro_buffer *src,
       depth = 0;
       for (;;)
         {
-          char *start = src->text;
-
           if (! get_token (&tok, src))
             error (_("Malformed argument list for macro `%s'."), name);
       
@@ -822,7 +862,8 @@ gather_arguments (const char *name, struct macro_buffer *src,
                      if (args_len >= args_size)
                        {
                          args_size++;
-                         args = xrealloc (args, sizeof (*args) * args_size);
+                         args = XRESIZEVEC (struct macro_buffer, args,
+                                            args_size);
                        }
                      arg = &args[args_len++];
                      set_token (arg, src->text, src->text);
@@ -894,7 +935,8 @@ find_parameter (const struct macro_buffer *tok,
     return -1;
 
   for (i = 0; i < argc; ++i)
-    if (tok->len == strlen (argv[i]) && ! memcmp (tok->text, argv[i], tok->len))
+    if (tok->len == strlen (argv[i]) 
+       && !memcmp (tok->text, argv[i], tok->len))
       return i;
 
   if (is_varargs && tok->len == va_arg_name->len
@@ -904,6 +946,30 @@ find_parameter (const struct macro_buffer *tok,
   return -1;
 }
  
+/* Helper function for substitute_args that gets the next token and
+   updates the passed-in state variables.  */
+
+static void
+get_next_token_for_substitution (struct macro_buffer *replacement_list,
+                                struct macro_buffer *token,
+                                char **start,
+                                struct macro_buffer *lookahead,
+                                char **lookahead_start,
+                                int *lookahead_valid,
+                                bool *keep_going)
+{
+  if (!*lookahead_valid)
+    *keep_going = false;
+  else
+    {
+      *keep_going = true;
+      *token = *lookahead;
+      *start = *lookahead_start;
+      *lookahead_start = replacement_list->text;
+      *lookahead_valid = get_token (lookahead, replacement_list);
+    }
+}
+
 /* Given the macro definition DEF, being invoked with the actual
    arguments given by ARGC and ARGV, substitute the arguments into the
    replacement list, and store the result in DEST.
@@ -942,7 +1008,7 @@ substitute_args (struct macro_buffer *dest,
      lexed.  */
   char *lookahead_rl_start;
 
-  init_shared_buffer (&replacement_list, (char *) def->replacement,
+  init_shared_buffer (&replacement_list, def->replacement,
                       strlen (def->replacement));
 
   gdb_assert (dest->len == 0);
@@ -954,8 +1020,64 @@ substitute_args (struct macro_buffer *dest,
   lookahead_rl_start = replacement_list.text;
   lookahead_valid = get_token (&lookahead, &replacement_list);
 
-  for (;;)
+  /* __VA_OPT__ state variable.  The states are:
+     0 - nothing happening
+     1 - saw __VA_OPT__
+     >= 2 in __VA_OPT__, the value encodes the parenthesis depth.  */
+  unsigned vaopt_state = 0;
+
+  for (bool keep_going = true;
+       keep_going;
+       get_next_token_for_substitution (&replacement_list,
+                                       &tok,
+                                       &original_rl_start,
+                                       &lookahead,
+                                       &lookahead_rl_start,
+                                       &lookahead_valid,
+                                       &keep_going))
     {
+      bool token_is_vaopt = (tok.len == 10
+                            && strncmp (tok.text, "__VA_OPT__", 10) == 0);
+
+      if (vaopt_state > 0)
+       {
+         if (token_is_vaopt)
+           error (_("__VA_OPT__ cannot appear inside __VA_OPT__"));
+         else if (tok.len == 1 && tok.text[0] == '(')
+           {
+             ++vaopt_state;
+             /* We just entered __VA_OPT__, so don't emit this
+                token.  */
+             continue;
+           }
+         else if (vaopt_state == 1)
+           error (_("__VA_OPT__ must be followed by an open parenthesis"));
+         else if (tok.len == 1 && tok.text[0] == ')')
+           {
+             --vaopt_state;
+             if (vaopt_state == 1)
+               {
+                 /* Done with __VA_OPT__.  */
+                 vaopt_state = 0;
+                 /* Don't emit.  */
+                 continue;
+               }
+           }
+
+         /* If __VA_ARGS__ is empty, then drop the contents of
+            __VA_OPT__.  */
+         if (argv[argc - 1].len == 0)
+           continue;
+       }
+      else if (token_is_vaopt)
+       {
+         if (!is_varargs)
+           error (_("__VA_OPT__ is only valid in a variadic macro"));
+         vaopt_state = 1;
+         /* Don't emit this token.  */
+         continue;
+       }
+
       /* Just for aesthetics.  If we skipped some whitespace, copy
          that to DEST.  */
       if (tok.text > original_rl_start)
@@ -997,7 +1119,7 @@ substitute_args (struct macro_buffer *dest,
               && lookahead.text[0] == '#'
               && lookahead.text[1] == '#')
        {
-         int arg, finished = 0;
+         int finished = 0;
          int prev_was_comma = 0;
 
          /* Note that GCC warns if the result of splicing is not a
@@ -1011,6 +1133,7 @@ substitute_args (struct macro_buffer *dest,
            {
              int arg = find_parameter (&tok, is_varargs, va_arg_name,
                                        def->argc, def->argv);
+
              if (arg != -1)
                appendmem (dest, argv[arg].text, argv[arg].len);
              else
@@ -1050,6 +1173,7 @@ substitute_args (struct macro_buffer *dest,
                {
                  int arg = find_parameter (&tok, is_varargs, va_arg_name,
                                            def->argc, def->argv);
+
                  if (arg != -1)
                    appendmem (dest, argv[arg].text, argv[arg].len);
                  else
@@ -1113,16 +1237,10 @@ substitute_args (struct macro_buffer *dest,
          if (! substituted)
            append_tokens_without_splicing (dest, &tok);
        }
-
-      if (! lookahead_valid)
-       break;
-
-      tok = lookahead;
-      original_rl_start = lookahead_rl_start;
-
-      lookahead_rl_start = replacement_list.text;
-      lookahead_valid = get_token (&lookahead, &replacement_list);
     }
+
+  if (vaopt_state > 0)
+    error (_("Unterminated __VA_OPT__"));
 }
 
 
@@ -1130,7 +1248,7 @@ substitute_args (struct macro_buffer *dest,
    its expansion to DEST.  SRC is the input text following the ID
    token.  We are currently rescanning the expansions of the macros
    named in NO_LOOP; don't re-expand them.  Use LOOKUP_FUNC and
-   LOOKUP_BATON to find definitions for any nested macro references.  
+   LOOKUP_BATON to find definitions for any nested macro references.
 
    Return 1 if we decided to expand it, zero otherwise.  (If it's a
    function-like macro name that isn't followed by an argument list,
@@ -1159,7 +1277,7 @@ expand (const char *id,
     {
       struct macro_buffer replacement_list;
 
-      init_shared_buffer (&replacement_list, (char *) def->replacement,
+      init_shared_buffer (&replacement_list, def->replacement,
                           strlen (def->replacement));
 
       scan (dest, &replacement_list, &new_no_loop, lookup_func, lookup_baton);
@@ -1172,7 +1290,7 @@ expand (const char *id,
       struct macro_buffer *argv = NULL;
       struct macro_buffer substituted;
       struct macro_buffer substituted_src;
-      struct macro_buffer va_arg_name;
+      struct macro_buffer va_arg_name = {0};
       int is_varargs = 0;
 
       if (def->argc >= 1)
@@ -1188,6 +1306,7 @@ expand (const char *id,
          else
            {
              int len = strlen (def->argv[def->argc - 1]);
+
              if (len > 3
                  && strcmp (def->argv[def->argc - 1] + len - 3, "...") == 0)
                {
@@ -1195,7 +1314,7 @@ expand (const char *id,
                     substitution parameter is the name of the formal
                     argument without the "...".  */
                  init_shared_buffer (&va_arg_name,
-                                     (char *) def->argv[def->argc - 1],
+                                     def->argv[def->argc - 1],
                                      len - 3);
                  is_varargs = 1;
                }
@@ -1290,8 +1409,9 @@ maybe_expand (struct macro_buffer *dest,
     {
       /* Make a null-terminated copy of it, since that's what our
          lookup function expects.  */
-      char *id = xmalloc (src_first->len + 1);
+      char *id = (char *) xmalloc (src_first->len + 1);
       struct cleanup *back_to = make_cleanup (xfree, id);
+
       memcpy (id, src_first->text, src_first->len);
       id[src_first->len] = 0;
           
@@ -1373,7 +1493,7 @@ macro_expand (const char *source,
   struct macro_buffer src, dest;
   struct cleanup *back_to;
 
-  init_shared_buffer (&src, (char *) source, strlen (source));
+  init_shared_buffer (&src, source, strlen (source));
 
   init_buffer (&dest, 0);
   dest.last_token = 0;
@@ -1398,7 +1518,7 @@ macro_expand_once (const char *source,
 
 
 char *
-macro_expand_next (char **lexptr,
+macro_expand_next (const char **lexptr,
                    macro_lookup_ftype *lookup_func,
                    void *lookup_baton)
 {