gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / macroexp.c
index 86689c3362168035ea93ee7a12a3fbbffe064ffd..9015bc1c9d404fdb5e33b798c54140ef1a6377e7 100644 (file)
@@ -1,5 +1,5 @@
 /* C preprocessor macro expansion for GDB.
-   Copyright (C) 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2002-2020 Free Software Foundation, Inc.
    Contributed by Red Hat, Inc.
 
    This file is part of GDB.
 
 #include "defs.h"
 #include "gdb_obstack.h"
-#include "bcache.h"
 #include "macrotab.h"
 #include "macroexp.h"
-#include "gdb_assert.h"
 #include "c-lang.h"
 
 
@@ -54,8 +52,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. 
 
@@ -65,107 +64,120 @@ struct macro_buffer
      no token abutting the end of TEXT (it's just whitespace), and
      again, we set this equal to LEN.  We set this to -1 if we don't
      know the nature of TEXT.  */
-  int last_token;
+  int last_token = -1;
 
   /* If this buffer is holding the result from get_token, then this 
      is non-zero if it is an identifier token, zero otherwise.  */
-  int is_identifier;
-};
-
-
-/* Set the macro buffer *B to the empty string, guessing that its
-   final contents will fit in N bytes.  (It'll get resized if it
-   doesn't, so the guess doesn't have to be right.)  Allocate the
-   initial storage with xmalloc.  */
-static void
-init_buffer (struct macro_buffer *b, int n)
-{
-  b->size = n;
-  if (n > 0)
-    b->text = (char *) xmalloc (n);
-  else
-    b->text = NULL;
-  b->len = 0;
-  b->shared = 0;
-  b->last_token = -1;
-}
+  int is_identifier = 0;
 
 
-/* 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)
-{
-  buf->text = addr;
-  buf->len = len;
-  buf->shared = 1;
-  buf->size = 0;
-  buf->last_token = -1;
-}
+  macro_buffer ()
+    : text (NULL),
+      len (0),
+      size (0),
+      shared (false)
+  {
+  }
 
+  /* Set the macro buffer to the empty string, guessing that its
+     final contents will fit in N bytes.  (It'll get resized if it
+     doesn't, so the guess doesn't have to be right.)  Allocate the
+     initial storage with xmalloc.  */
+  explicit macro_buffer (int n)
+    : len (0),
+      size (n),
+      shared (false)
+  {
+    if (n > 0)
+      text = (char *) xmalloc (n);
+    else
+      text = NULL;
+  }
 
-/* Free the text of the buffer B.  Raise an error if B is shared.  */
-static void
-free_buffer (struct macro_buffer *b)
-{
-  gdb_assert (! b->shared);
-  if (b->size)
-    xfree (b->text);
-}
+  /* Set the macro buffer to refer to the LEN bytes at ADDR, as a
+     shared substring.  */
+  macro_buffer (const char *addr, int len)
+  {
+    set_shared (addr, len);
+  }
 
+  /* Set the macro buffer to refer to the LEN bytes at ADDR, as a
+     shared substring.  */
+  void set_shared (const char *addr, int len_)
+  {
+    text = (char *) addr;
+    len = len_;
+    size = 0;
+    shared = true;
+  }
 
-/* A cleanup function for macro buffers.  */
-static void
-cleanup_macro_buffer (void *untyped_buf)
-{
-  free_buffer ((struct macro_buffer *) untyped_buf);
-}
+  macro_buffer& operator= (const macro_buffer &src)
+  {
+    gdb_assert (src.shared);
+    gdb_assert (shared);
+    set_shared (src.text, src.len);
+    last_token = src.last_token;
+    is_identifier = src.is_identifier;
+    return *this;
+  }
 
+  ~macro_buffer ()
+  {
+    if (! shared && size)
+      xfree (text);
+  }
 
-/* Resize the buffer B to be at least N bytes long.  Raise an error if
-   B shouldn't be resized.  */
-static void
-resize_buffer (struct macro_buffer *b, int n)
-{
-  /* We shouldn't be trying to resize shared strings.  */
-  gdb_assert (! b->shared);
-  
-  if (b->size == 0)
-    b->size = n;
-  else
-    while (b->size <= n)
-      b->size *= 2;
+  /* Release the text of the buffer to the caller, which is now
+     responsible for freeing it.  */
+  ATTRIBUTE_UNUSED_RESULT char *release ()
+  {
+    gdb_assert (! shared);
+    gdb_assert (size);
+    char *result = text;
+    text = NULL;
+    return result;
+  }
 
-  b->text = xrealloc (b->text, b->size);
-}
+  /* Resize the buffer to be at least N bytes long.  Raise an error if
+     the buffer shouldn't be resized.  */
+  void resize_buffer (int n)
+  {
+    /* We shouldn't be trying to resize shared strings.  */
+    gdb_assert (! shared);
 
+    if (size == 0)
+      size = n;
+    else
+      while (size <= n)
+       size *= 2;
 
-/* Append the character C to the buffer B.  */
-static void
-appendc (struct macro_buffer *b, int c)
-{
-  int new_len = b->len + 1;
+    text = (char *) xrealloc (text, size);
+  }
 
-  if (new_len > b->size)
-    resize_buffer (b, new_len);
+  /* Append the character C to the buffer.  */
+  void appendc (int c)
+  {
+    int new_len = len + 1;
 
-  b->text[b->len] = c;
-  b->len = new_len;
-}
+    if (new_len > size)
+      resize_buffer (new_len);
 
+    text[len] = c;
+    len = new_len;
+  }
 
-/* Append the LEN bytes at ADDR to the buffer B.  */
-static void
-appendmem (struct macro_buffer *b, char *addr, int len)
-{
-  int new_len = b->len + len;
+  /* Append the COUNT bytes at ADDR to the buffer.  */
+  void appendmem (const char *addr, int count)
+  {
+    int new_len = len + count;
 
-  if (new_len > b->size)
-    resize_buffer (b, new_len);
+    if (new_len > size)
+      resize_buffer (new_len);
 
-  memcpy (b->text + b->len, addr, len);
-  b->len = new_len;
-}
+    memcpy (text + len, addr, count);
+    len = new_len;
+  }
+};
 
 
 \f
@@ -202,10 +214,10 @@ macro_is_identifier_nondigit (int c)
 static void
 set_token (struct macro_buffer *tok, char *start, char *end)
 {
-  init_shared_buffer (tok, start, end - start);
+  tok->set_shared (start, end - start);
   tok->last_token = 0;
 
-  /* Presumed; get_identifier may overwrite this. */
+  /* Presumed; get_identifier may overwrite this.  */
   tok->is_identifier = 0;
 }
 
@@ -326,7 +338,6 @@ get_character_constant (struct macro_buffer *tok, char *p, char *end)
          && p[1] == '\''))
     {
       char *tok_start = p;
-      char *body_start;
       int char_count = 0;
 
       if (*p == '\'')
@@ -336,7 +347,6 @@ get_character_constant (struct macro_buffer *tok, char *p, char *end)
       else
         gdb_assert_not_reached ("unexpected character constant");
 
-      body_start = p;
       for (;;)
         {
           if (p >= end)
@@ -351,8 +361,11 @@ get_character_constant (struct macro_buffer *tok, char *p, char *end)
             }
           else if (*p == '\\')
             {
-              p++;
-             char_count += c_parse_escape (&p, NULL);
+             const char *s, *o;
+
+             s = o = ++p;
+             char_count += c_parse_escape (&s, NULL);
+             p += s - o;
             }
           else
            {
@@ -405,8 +418,11 @@ get_string_literal (struct macro_buffer *tok, char *p, char *end)
                    "constants."));
           else if (*p == '\\')
             {
-              p++;
-              c_parse_escape (&p, NULL);
+             const char *s, *o;
+
+             s = o = ++p;
+             c_parse_escape (&s, NULL);
+             p += s - o;
             }
           else
             p++;
@@ -578,7 +594,7 @@ append_tokens_without_splicing (struct macro_buffer *dest,
   
   /* First, just try appending the two, and call get_token to see if
      we got a splice.  */
-  appendmem (dest, src->text, src->len);
+  dest->appendmem (src->text, src->len);
 
   /* If DEST originally had no token abutting its end, then we can't
      have spliced anything, so we're done.  */
@@ -590,9 +606,8 @@ append_tokens_without_splicing (struct macro_buffer *dest,
 
   /* Set DEST_TAIL to point to the last token in DEST, followed by
      all the stuff we just appended.  */
-  init_shared_buffer (&dest_tail,
-                      dest->text + dest->last_token,
-                      dest->len - dest->last_token);
+  dest_tail.set_shared (dest->text + dest->last_token,
+                       dest->len - dest->last_token);
 
   /* Re-parse DEST's last token.  We know that DEST used to contain
      at least one token, so if it doesn't contain any after the
@@ -612,12 +627,11 @@ append_tokens_without_splicing (struct macro_buffer *dest,
      its original length and try again, but separate the texts with a
      space.  */
   dest->len = original_dest_len;
-  appendc (dest, ' ');
-  appendmem (dest, src->text, src->len);
+  dest->appendc (' ');
+  dest->appendmem (src->text, src->len);
 
-  init_shared_buffer (&dest_tail,
-                      dest->text + dest->last_token,
-                      dest->len - dest->last_token);
+  dest_tail.set_shared (dest->text + dest->last_token,
+                       dest->len - dest->last_token);
 
   /* Try to re-parse DEST's last token, as above.  */
   if (get_token (&new_token, &dest_tail)
@@ -639,7 +653,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))
@@ -653,7 +667,7 @@ stringify (struct macro_buffer *dest, char *arg, int len)
     --len;
 
   /* Insert the string.  */
-  appendc (dest, '"');
+  dest->appendc ('"');
   while (len > 0)
     {
       /* We could try to handle strange cases here, like control
@@ -661,7 +675,7 @@ stringify (struct macro_buffer *dest, char *arg, int len)
       if (macro_is_whitespace (*arg))
        {
          /* Replace a sequence of whitespace with a single space.  */
-         appendc (dest, ' ');
+         dest->appendc (' ');
          while (len > 1 && macro_is_whitespace (arg[1]))
            {
              ++arg;
@@ -670,18 +684,32 @@ stringify (struct macro_buffer *dest, char *arg, int len)
        }
       else if (*arg == '\\' || *arg == '"')
        {
-         appendc (dest, '\\');
-         appendc (dest, *arg);
+         dest->appendc ('\\');
+         dest->appendc (*arg);
        }
       else
-       appendc (dest, *arg);
+       dest->appendc (*arg);
       ++arg;
       --len;
     }
-  appendc (dest, '"');
+  dest->appendc ('"');
   dest->last_token = dest->len;
 }
 
+/* See macroexp.h.  */
+
+char *
+macro_stringify (const char *str)
+{
+  int len = strlen (str);
+  struct macro_buffer buffer (len);
+
+  stringify (&buffer, str, len);
+  buffer.appendc ('\0');
+
+  return buffer.release ();
+}
+
 \f
 /* Expanding macros!  */
 
@@ -703,7 +731,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)
 {
@@ -726,22 +754,19 @@ currently_rescanning (struct macro_name_list *list, const char *name)
    baz).
 
    If SRC doesn't start with an open paren ( token at all, return
-   zero, leave SRC unchanged, and don't set *ARGC_P to anything.
+   false, leave SRC unchanged, and don't set *ARGS_PTR to anything.
 
    If SRC doesn't contain a properly terminated argument list, then
    raise an error.
-   
+
    For a variadic macro, NARGS holds the number of formal arguments to
    the macro.  For a GNU-style variadic macro, this should be the
    number of named arguments.  For a non-variadic macro, NARGS should
    be -1.
 
-   Otherwise, return a pointer to the first element of an array of
-   macro buffers referring to the argument texts, and set *ARGC_P to
-   the number of arguments we found --- the number of elements in the
-   array.  The macro buffers share their text with SRC, and their
-   last_token fields are initialized.  The array is allocated with
-   xmalloc, and the caller is responsible for freeing it.
+   Otherwise, return true and set *ARGS_PTR to a vector of macro
+   buffers referring to the argument texts.  The macro buffers share
+   their text with SRC, and their last_token fields are initialized.
 
    NOTE WELL: if SRC starts with a open paren ( token followed
    immediately by a close paren ) token (e.g., the invocation looks
@@ -754,53 +779,36 @@ currently_rescanning (struct macro_name_list *list, const char *name)
    Consume the tokens from SRC; after this call, SRC contains the text
    following the invocation.  */
 
-static struct macro_buffer *
-gather_arguments (const char *name, struct macro_buffer *src,
-                 int nargs, int *argc_p)
+static bool
+gather_arguments (const char *name, struct macro_buffer *src, int nargs,
+                 std::vector<struct macro_buffer> *args_ptr)
 {
   struct macro_buffer tok;
-  int args_len, args_size;
-  struct macro_buffer *args = NULL;
-  struct cleanup *back_to = make_cleanup (free_current_contents, &args);
+  std::vector<struct macro_buffer> args;
 
   /* Does SRC start with an opening paren token?  Read from a copy of
      SRC, so SRC itself is unaffected if we don't find an opening
      paren.  */
   {
-    struct macro_buffer temp;
-
-    init_shared_buffer (&temp, src->text, src->len);
+    struct macro_buffer temp (src->text, src->len);
 
     if (! get_token (&tok, &temp)
         || tok.len != 1
         || tok.text[0] != '(')
-      {
-        discard_cleanups (back_to);
-        return 0;
-      }
+      return false;
   }
 
   /* Consume SRC's opening paren.  */
   get_token (&tok, src);
 
-  args_len = 0;
-  args_size = 6;
-  args = (struct macro_buffer *) xmalloc (sizeof (*args) * args_size);
-
   for (;;)
     {
       struct macro_buffer *arg;
       int depth;
 
-      /* Make sure we have room for the next argument.  */
-      if (args_len >= args_size)
-        {
-          args_size *= 2;
-          args = xrealloc (args, sizeof (*args) * args_size);
-        }
-
       /* Initialize the next argument.  */
-      arg = &args[args_len++];
+      args.emplace_back ();
+      arg = &args.back ();
       set_token (arg, src->text, src->text);
 
       /* Gather the argument's tokens.  */
@@ -809,7 +817,7 @@ gather_arguments (const char *name, struct macro_buffer *src,
         {
           if (! get_token (&tok, src))
             error (_("Malformed argument list for macro `%s'."), name);
-      
+
           /* Is tok an opening paren?  */
           if (tok.len == 1 && tok.text[0] == '(')
             depth++;
@@ -823,21 +831,15 @@ gather_arguments (const char *name, struct macro_buffer *src,
                 {
                  /* In the varargs case, the last argument may be
                     missing.  Add an empty argument in this case.  */
-                 if (nargs != -1 && args_len == nargs - 1)
+                 if (nargs != -1 && args.size () == nargs - 1)
                    {
-                     /* Make sure we have room for the argument.  */
-                     if (args_len >= args_size)
-                       {
-                         args_size++;
-                         args = xrealloc (args, sizeof (*args) * args_size);
-                       }
-                     arg = &args[args_len++];
+                     args.emplace_back ();
+                     arg = &args.back ();
                      set_token (arg, src->text, src->text);
                    }
 
-                  discard_cleanups (back_to);
-                  *argc_p = args_len;
-                  return args;
+                 *args_ptr = std::move (args);
+                 return true;
                 }
 
               depth--;
@@ -848,7 +850,7 @@ gather_arguments (const char *name, struct macro_buffer *src,
              variadic macro and we are computing the last argument, we
              want to include the comma and remaining tokens.  */
           else if (tok.len == 1 && tok.text[0] == ',' && depth == 0
-                  && (nargs == -1 || args_len < nargs))
+                  && (nargs == -1 || args.size () < nargs))
             break;
 
           /* Extend the current argument to enclose this token.  If
@@ -901,7 +903,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
@@ -911,8 +914,32 @@ 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
+   arguments given by ARGV, substitute the arguments into the
    replacement list, and store the result in DEST.
 
    IS_VARARGS should be true if DEF is a varargs macro.  In this case,
@@ -927,16 +954,14 @@ find_parameter (const struct macro_buffer *tok,
    NO_LOOP.  */
 
 static void
-substitute_args (struct macro_buffer *dest, 
+substitute_args (struct macro_buffer *dest,
                  struct macro_definition *def,
                 int is_varargs, const struct macro_buffer *va_arg_name,
-                 int argc, struct macro_buffer *argv,
+                const std::vector<struct macro_buffer> &argv,
                  struct macro_name_list *no_loop,
                  macro_lookup_ftype *lookup_func,
                  void *lookup_baton)
 {
-  /* A macro buffer for the macro's replacement list.  */
-  struct macro_buffer replacement_list;
   /* The token we are currently considering.  */
   struct macro_buffer tok;
   /* The replacement list's pointer from just before TOK was lexed.  */
@@ -949,8 +974,9 @@ substitute_args (struct macro_buffer *dest,
      lexed.  */
   char *lookahead_rl_start;
 
-  init_shared_buffer (&replacement_list, (char *) def->replacement,
-                      strlen (def->replacement));
+  /* A macro buffer for the macro's replacement list.  */
+  struct macro_buffer replacement_list (def->replacement,
+                                       strlen (def->replacement));
 
   gdb_assert (dest->len == 0);
   dest->last_token = 0;
@@ -961,13 +987,69 @@ 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.back ().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)
         {
-          appendmem (dest, original_rl_start, tok.text - original_rl_start);
+          dest->appendmem (original_rl_start, tok.text - original_rl_start);
           dest->last_token = dest->len;
         }
 
@@ -1020,9 +1102,9 @@ substitute_args (struct macro_buffer *dest,
                                        def->argc, def->argv);
 
              if (arg != -1)
-               appendmem (dest, argv[arg].text, argv[arg].len);
+               dest->appendmem (argv[arg].text, argv[arg].len);
              else
-               appendmem (dest, tok.text, tok.len);
+               dest->appendmem (tok.text, tok.len);
            }
 
          /* Apply a possible sequence of ## operators.  */
@@ -1045,8 +1127,8 @@ substitute_args (struct macro_buffer *dest,
                  if (! (is_varargs
                         && tok.len == va_arg_name->len
                         && !memcmp (tok.text, va_arg_name->text, tok.len)
-                        && argv[argc - 1].len == 0))
-                   appendmem (dest, ",", 1);
+                        && argv.back ().len == 0))
+                   dest->appendmem (",", 1);
                  prev_was_comma = 0;
                }
 
@@ -1060,9 +1142,9 @@ substitute_args (struct macro_buffer *dest,
                                            def->argc, def->argv);
 
                  if (arg != -1)
-                   appendmem (dest, argv[arg].text, argv[arg].len);
+                   dest->appendmem (argv[arg].text, argv[arg].len);
                  else
-                   appendmem (dest, tok.text, tok.len);
+                   dest->appendmem (tok.text, tok.len);
                }
 
              /* Now read another token.  If it is another splice, we
@@ -1083,7 +1165,7 @@ substitute_args (struct macro_buffer *dest,
          if (prev_was_comma)
            {
              /* We saw a comma.  Insert it now.  */
-             appendmem (dest, ",", 1);
+             dest->appendmem (",", 1);
            }
 
           dest->last_token = dest->len;
@@ -1106,14 +1188,12 @@ substitute_args (struct macro_buffer *dest,
 
          if (arg != -1)
            {
-             struct macro_buffer arg_src;
-
              /* Expand any macro invocations in the argument text,
                 and append the result to dest.  Remember that scan
                 mutates its source, so we need to scan a new buffer
                 referring to the argument's text, not the argument
                 itself.  */
-             init_shared_buffer (&arg_src, argv[arg].text, argv[arg].len);
+             struct macro_buffer arg_src (argv[arg].text, argv[arg].len);
              scan (dest, &arg_src, no_loop, lookup_func, lookup_baton);
              substituted = 1;
            }
@@ -1122,16 +1202,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__"));
 }
 
 
@@ -1139,7 +1213,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,
@@ -1166,21 +1240,14 @@ expand (const char *id,
   /* What kind of macro are we expanding?  */
   if (def->kind == macro_object_like)
     {
-      struct macro_buffer replacement_list;
-
-      init_shared_buffer (&replacement_list, (char *) def->replacement,
-                          strlen (def->replacement));
+      struct macro_buffer replacement_list (def->replacement,
+                                           strlen (def->replacement));
 
       scan (dest, &replacement_list, &new_no_loop, lookup_func, lookup_baton);
       return 1;
     }
   else if (def->kind == macro_function_like)
     {
-      struct cleanup *back_to = make_cleanup (null_cleanup, 0);
-      int argc = 0;
-      struct macro_buffer *argv = NULL;
-      struct macro_buffer substituted;
-      struct macro_buffer substituted_src;
       struct macro_buffer va_arg_name;
       int is_varargs = 0;
 
@@ -1190,8 +1257,7 @@ expand (const char *id,
            {
              /* In C99-style varargs, substitution is done using
                 __VA_ARGS__.  */
-             init_shared_buffer (&va_arg_name, "__VA_ARGS__",
-                                 strlen ("__VA_ARGS__"));
+             va_arg_name.set_shared ("__VA_ARGS__", strlen ("__VA_ARGS__"));
              is_varargs = 1;
            }
          else
@@ -1204,43 +1270,36 @@ expand (const char *id,
                  /* In GNU-style varargs, the name of the
                     substitution parameter is the name of the formal
                     argument without the "...".  */
-                 init_shared_buffer (&va_arg_name,
-                                     (char *) def->argv[def->argc - 1],
-                                     len - 3);
+                 va_arg_name.set_shared (def->argv[def->argc - 1], len - 3);
                  is_varargs = 1;
                }
            }
        }
 
-      make_cleanup (free_current_contents, &argv);
-      argv = gather_arguments (id, src, is_varargs ? def->argc : -1,
-                              &argc);
-
+      std::vector<struct macro_buffer> argv;
       /* If we couldn't find any argument list, then we don't expand
          this macro.  */
-      if (! argv)
-        {
-          do_cleanups (back_to);
-          return 0;
-        }
+      if (!gather_arguments (id, src, is_varargs ? def->argc : -1,
+                            &argv))
+       return 0;
 
       /* Check that we're passing an acceptable number of arguments for
          this macro.  */
-      if (argc != def->argc)
+      if (argv.size () != def->argc)
         {
-         if (is_varargs && argc >= def->argc - 1)
+         if (is_varargs && argv.size () >= def->argc - 1)
            {
              /* Ok.  */
            }
           /* Remember that a sequence of tokens like "foo()" is a
              valid invocation of a macro expecting either zero or one
              arguments.  */
-          else if (! (argc == 1
+          else if (! (argv.size () == 1
                      && argv[0].len == 0
                      && def->argc == 0))
             error (_("Wrong number of arguments to macro `%s' "
                    "(expected %d, got %d)."),
-                   id, def->argc, argc);
+                   id, def->argc, int (argv.size ()));
         }
 
       /* Note that we don't expand macro invocations in the arguments
@@ -1249,10 +1308,9 @@ expand (const char *id,
          splicing operator "##" don't get macro references expanded,
          so we can't really tell whether it's appropriate to macro-
          expand an argument until we see how it's being used.  */
-      init_buffer (&substituted, 0);
-      make_cleanup (cleanup_macro_buffer, &substituted);
+      struct macro_buffer substituted (0);
       substitute_args (&substituted, def, is_varargs, &va_arg_name,
-                      argc, argv, no_loop, lookup_func, lookup_baton);
+                      argv, no_loop, lookup_func, lookup_baton);
 
       /* Now `substituted' is the macro's replacement list, with all
          argument values substituted into it properly.  Re-scan it for
@@ -1264,11 +1322,9 @@ expand (const char *id,
          text pointer around, and we still need to be able to find
          `substituted's original text buffer after scanning it so we
          can free it.  */
-      init_shared_buffer (&substituted_src, substituted.text, substituted.len);
+      struct macro_buffer substituted_src (substituted.text, substituted.len);
       scan (dest, &substituted_src, &new_no_loop, lookup_func, lookup_baton);
 
-      do_cleanups (back_to);
-
       return 1;
     }
   else
@@ -1277,7 +1333,7 @@ expand (const char *id,
 
 
 /* If the single token in SRC_FIRST followed by the tokens in SRC_REST
-   constitute a macro invokation not forbidden in NO_LOOP, append its
+   constitute a macro invocation not forbidden in NO_LOOP, append its
    expansion to DEST and return non-zero.  Otherwise, return zero, and
    leave DEST unchanged.
 
@@ -1300,28 +1356,20 @@ 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);
-      struct cleanup *back_to = make_cleanup (xfree, id);
+      std::string id (src_first->text, src_first->len);
 
-      memcpy (id, src_first->text, src_first->len);
-      id[src_first->len] = 0;
-          
       /* If we're currently re-scanning the result of expanding
          this macro, don't expand it again.  */
-      if (! currently_rescanning (no_loop, id))
+      if (! currently_rescanning (no_loop, id.c_str ()))
         {
           /* Does this identifier have a macro definition in scope?  */
-          struct macro_definition *def = lookup_func (id, lookup_baton);
+          struct macro_definition *def = lookup_func (id.c_str (),
+                                                     lookup_baton);
 
-          if (def && expand (id, def, dest, src_rest, no_loop,
+          if (def && expand (id.c_str (), def, dest, src_rest, no_loop,
                              lookup_func, lookup_baton))
-            {
-              do_cleanups (back_to);
-              return 1;
-            }
+           return 1;
         }
-
-      do_cleanups (back_to);
     }
 
   return 0;
@@ -1356,7 +1404,7 @@ scan (struct macro_buffer *dest,
          that to DEST.  */
       if (tok.text > original_src_start)
         {
-          appendmem (dest, original_src_start, tok.text - original_src_start);
+          dest->appendmem (original_src_start, tok.text - original_src_start);
           dest->last_token = dest->len;
         }
 
@@ -1370,36 +1418,31 @@ scan (struct macro_buffer *dest,
      src, copy it to dest.  */
   if (src->len)
     {
-      appendmem (dest, src->text, src->len);
+      dest->appendmem (src->text, src->len);
       dest->last_token = dest->len;
     }
 }
 
 
-char *
+gdb::unique_xmalloc_ptr<char>
 macro_expand (const char *source,
               macro_lookup_ftype *lookup_func,
               void *lookup_func_baton)
 {
-  struct macro_buffer src, dest;
-  struct cleanup *back_to;
+  struct macro_buffer src (source, strlen (source));
 
-  init_shared_buffer (&src, (char *) source, strlen (source));
-
-  init_buffer (&dest, 0);
+  struct macro_buffer dest (0);
   dest.last_token = 0;
-  back_to = make_cleanup (cleanup_macro_buffer, &dest);
 
   scan (&dest, &src, 0, lookup_func, lookup_func_baton);
 
-  appendc (&dest, '\0');
+  dest.appendc ('\0');
 
-  discard_cleanups (back_to);
-  return dest.text;
+  return gdb::unique_xmalloc_ptr<char> (dest.release ());
 }
 
 
-char *
+gdb::unique_xmalloc_ptr<char>
 macro_expand_once (const char *source,
                    macro_lookup_ftype *lookup_func,
                    void *lookup_func_baton)
@@ -1409,27 +1452,22 @@ 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)
 {
-  struct macro_buffer src, dest, tok;
-  struct cleanup *back_to;
+  struct macro_buffer tok;
 
   /* Set up SRC to refer to the input text, pointed to by *lexptr.  */
-  init_shared_buffer (&src, *lexptr, strlen (*lexptr));
+  struct macro_buffer src (*lexptr, strlen (*lexptr));
 
   /* Set up DEST to receive the expansion, if there is one.  */
-  init_buffer (&dest, 0);
+  struct macro_buffer dest (0);
   dest.last_token = 0;
-  back_to = make_cleanup (cleanup_macro_buffer, &dest);
 
   /* Get the text's first preprocessing token.  */
   if (! get_token (&tok, &src))
-    {
-      do_cleanups (back_to);
-      return 0;
-    }
+    return 0;
 
   /* If it's a macro invocation, expand it.  */
   if (maybe_expand (&dest, &tok, &src, 0, lookup_func, lookup_baton))
@@ -1437,15 +1475,13 @@ macro_expand_next (char **lexptr,
       /* It was a macro invocation!  Package up the expansion as a
          null-terminated string and return it.  Set *lexptr to the
          start of the next token in the input.  */
-      appendc (&dest, '\0');
-      discard_cleanups (back_to);
+      dest.appendc ('\0');
       *lexptr = src.text;
-      return dest.text;
+      return dest.release ();
     }
   else
     {
       /* It wasn't a macro invocation.  */
-      do_cleanups (back_to);
       return 0;
     }
 }
This page took 0.038083 seconds and 4 git commands to generate.