/* C preprocessor macro expansion for GDB.
   Copyright (C) 2002-2022 Free Software Foundation, Inc.
   Contributed by Red Hat, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "gdbsupport/gdb_obstack.h"
#include "macrotab.h"
#include "macroexp.h"
#include "macroscope.h"
#include "c-lang.h"




/* A string type that we can use to refer to substrings of other
   strings.  */

struct shared_macro_buffer
{
  /* An array of characters.  This buffer is a pointer into some
     larger string and thus we can't assume in that the text is
     null-terminated.  */
  const char *text;

  /* The number of characters in the string.  */
  int len;

  /* For detecting token splicing. 

     This is the index in TEXT of the first character of the token
     that abuts the end of TEXT.  If TEXT contains no tokens, then we
     set this equal to LEN.  If TEXT ends in whitespace, then there is
     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 = -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 = 0;

  shared_macro_buffer ()
    : text (NULL),
      len (0)
  {
  }

  /* Set the macro buffer to refer to the LEN bytes at ADDR, as a
     shared substring.  */
  shared_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 = addr;
    len = len_;
  }
};

/* A string type that we can resize and quickly append to.  */

struct growable_macro_buffer
{
  /* An array of characters.  The first LEN bytes are the real text,
     but there are SIZE bytes allocated to the array.  */
  char *text;

  /* The number of characters in the string.  */
  int len;

  /* The number of characters allocated to the string.  */
  int size;

  /* For detecting token splicing.

     This is the index in TEXT of the first character of the token
     that abuts the end of TEXT.  If TEXT contains no tokens, then we
     set this equal to LEN.  If TEXT ends in whitespace, then there is
     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 = -1;

  /* 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 growable_macro_buffer (int n)
    : len (0),
      size (n)
  {
    if (n > 0)
      text = (char *) xmalloc (n);
    else
      text = NULL;
  }

  DISABLE_COPY_AND_ASSIGN (growable_macro_buffer);

  ~growable_macro_buffer ()
  {
    xfree (text);
  }

  /* Release the text of the buffer to the caller.  */
  gdb::unique_xmalloc_ptr<char> release ()
  {
    gdb_assert (size);
    char *result = text;
    text = NULL;
    return gdb::unique_xmalloc_ptr<char> (result);
  }

  /* Resize the buffer to be at least N bytes long.  */
  void resize_buffer (int n)
  {
    if (size == 0)
      size = n;
    else
      while (size <= n)
	size *= 2;

    text = (char *) xrealloc (text, size);
  }

  /* Append the character C to the buffer.  */
  void appendc (int c)
  {
    int new_len = len + 1;

    if (new_len > size)
      resize_buffer (new_len);

    text[len] = c;
    len = new_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 > size)
      resize_buffer (new_len);

    memcpy (text + len, addr, count);
    len = new_len;
  }
};



/* Recognizing preprocessor tokens.  */


int
macro_is_whitespace (int c)
{
  return (c == ' '
	  || c == '\t'
	  || c == '\n'
	  || c == '\v'
	  || c == '\f');
}


int
macro_is_digit (int c)
{
  return ('0' <= c && c <= '9');
}


int
macro_is_identifier_nondigit (int c)
{
  return (c == '_'
	  || ('a' <= c && c <= 'z')
	  || ('A' <= c && c <= 'Z'));
}


static void
set_token (shared_macro_buffer *tok, const char *start, const char *end)
{
  tok->set_shared (start, end - start);
  tok->last_token = 0;

  /* Presumed; get_identifier may overwrite this.  */
  tok->is_identifier = 0;
}


static int
get_comment (shared_macro_buffer *tok, const char *p, const char *end)
{
  if (p + 2 > end)
    return 0;
  else if (p[0] == '/'
	   && p[1] == '*')
    {
      const char *tok_start = p;

      p += 2;

      for (; p < end; p++)
	if (p + 2 <= end
	    && p[0] == '*'
	    && p[1] == '/')
	  {
	    p += 2;
	    set_token (tok, tok_start, p);
	    return 1;
	  }

      error (_("Unterminated comment in macro expansion."));
    }
  else if (p[0] == '/'
	   && p[1] == '/')
    {
      const char *tok_start = p;

      p += 2;
      for (; p < end; p++)
	if (*p == '\n')
	  break;

      set_token (tok, tok_start, p);
      return 1;
    }
  else
    return 0;
}


static int
get_identifier (shared_macro_buffer *tok, const char *p, const char *end)
{
  if (p < end
      && macro_is_identifier_nondigit (*p))
    {
      const char *tok_start = p;

      while (p < end
	     && (macro_is_identifier_nondigit (*p)
		 || macro_is_digit (*p)))
	p++;

      set_token (tok, tok_start, p);
      tok->is_identifier = 1;
      return 1;
    }
  else
    return 0;
}


static int
get_pp_number (shared_macro_buffer *tok, const char *p, const char *end)
{
  if (p < end
      && (macro_is_digit (*p)
	  || (*p == '.'
	      && p + 2 <= end
	      && macro_is_digit (p[1]))))
    {
      const char *tok_start = p;

      while (p < end)
	{
	  if (p + 2 <= end
	      && strchr ("eEpP", *p)
	      && (p[1] == '+' || p[1] == '-'))
	    p += 2;
	  else if (macro_is_digit (*p)
		   || macro_is_identifier_nondigit (*p)
		   || *p == '.')
	    p++;
	  else
	    break;
	}

      set_token (tok, tok_start, p);
      return 1;
    }
  else
    return 0;
}



/* If the text starting at P going up to (but not including) END
   starts with a character constant, set *TOK to point to that
   character constant, and return 1.  Otherwise, return zero.
   Signal an error if it contains a malformed or incomplete character
   constant.  */
static int
get_character_constant (shared_macro_buffer *tok,
			const char *p, const char *end)
{
  /* ISO/IEC 9899:1999 (E)  Section 6.4.4.4  paragraph 1 
     But of course, what really matters is that we handle it the same
     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[0] == 'u' || p[0] == 'U')
	  && p[1] == '\''))
    {
      const char *tok_start = p;
      int char_count = 0;

      if (*p == '\'')
	p++;
      else if (*p == 'L' || *p == 'u' || *p == 'U')
	p += 2;
      else
	gdb_assert_not_reached ("unexpected character constant");

      for (;;)
	{
	  if (p >= end)
	    error (_("Unmatched single quote."));
	  else if (*p == '\'')
	    {
	      if (!char_count)
		error (_("A character constant must contain at least one "
		       "character."));
	      p++;
	      break;
	    }
	  else if (*p == '\\')
	    {
	      const char *s, *o;

	      s = o = ++p;
	      char_count += c_parse_escape (&s, NULL);
	      p += s - o;
	    }
	  else
	    {
	      p++;
	      char_count++;
	    }
	}

      set_token (tok, tok_start, p);
      return 1;
    }
  else
    return 0;
}


/* If the text starting at P going up to (but not including) END
   starts with a string literal, set *TOK to point to that string
   literal, and return 1.  Otherwise, return zero.  Signal an error if
   it contains a malformed or incomplete string literal.  */
static int
get_string_literal (shared_macro_buffer *tok, const char *p, const char *end)
{
  if ((p + 1 <= end
       && *p == '"')
      || (p + 2 <= end
	  && (p[0] == 'L' || p[0] == 'u' || p[0] == 'U')
	  && p[1] == '"'))
    {
      const char *tok_start = p;

      if (*p == '"')
	p++;
      else if (*p == 'L' || *p == 'u' || *p == 'U')
	p += 2;
      else
	gdb_assert_not_reached ("unexpected string literal");

      for (;;)
	{
	  if (p >= end)
	    error (_("Unterminated string in expression."));
	  else if (*p == '"')
	    {
	      p++;
	      break;
	    }
	  else if (*p == '\n')
	    error (_("Newline characters may not appear in string "
		   "constants."));
	  else if (*p == '\\')
	    {
	      const char *s, *o;

	      s = o = ++p;
	      c_parse_escape (&s, NULL);
	      p += s - o;
	    }
	  else
	    p++;
	}

      set_token (tok, tok_start, p);
      return 1;
    }
  else
    return 0;
}


static int
get_punctuator (shared_macro_buffer *tok, const char *p, const char *end)
{
  /* Here, speed is much less important than correctness and clarity.  */

  /* ISO/IEC 9899:1999 (E)  Section 6.4.6  Paragraph 1.
     Note that this table is ordered in a special way.  A punctuator
     which is a prefix of another punctuator must appear after its
     "extension".  Otherwise, the wrong token will be returned.  */
  static const char * const punctuators[] = {
    "[", "]", "(", ")", "{", "}", "?", ";", ",", "~",
    "...", ".",
    "->", "--", "-=", "-",
    "++", "+=", "+",
    "*=", "*",
    "!=", "!",
    "&&", "&=", "&",
    "/=", "/",
    "%>", "%:%:", "%:", "%=", "%",
    "^=", "^",
    "##", "#",
    ":>", ":",
    "||", "|=", "|",
    "<<=", "<<", "<=", "<:", "<%", "<",
    ">>=", ">>", ">=", ">",
    "==", "=",
    0
  };

  int i;

  if (p + 1 <= end)
    {
      for (i = 0; punctuators[i]; i++)
	{
	  const char *punctuator = punctuators[i];

	  if (p[0] == punctuator[0])
	    {
	      int len = strlen (punctuator);

	      if (p + len <= end
		  && ! memcmp (p, punctuator, len))
		{
		  set_token (tok, p, p + len);
		  return 1;
		}
	    }
	}
    }

  return 0;
}


/* Peel the next preprocessor token off of SRC, and put it in TOK.
   Mutate TOK to refer to the first token in SRC, and mutate SRC to
   refer to the text after that token.  The resulting TOK will point
   into the same string SRC does.  Initialize TOK's last_token field.
   Return non-zero if we succeed, or 0 if we didn't find any more
   tokens in SRC.  */

static int
get_token (shared_macro_buffer *tok, shared_macro_buffer *src)
{
  const char *p = src->text;
  const char *end = p + src->len;

  /* From the ISO C standard, ISO/IEC 9899:1999 (E), section 6.4:

     preprocessing-token: 
	 header-name
	 identifier
	 pp-number
	 character-constant
	 string-literal
	 punctuator
	 each non-white-space character that cannot be one of the above

     We don't have to deal with header-name tokens, since those can
     only occur after a #include, which we will never see.  */

  while (p < end)
    if (macro_is_whitespace (*p))
      p++;
    else if (get_comment (tok, p, end))
      p += tok->len;
    else if (get_pp_number (tok, p, end)
	     || get_character_constant (tok, p, end)
	     || get_string_literal (tok, p, end)
	     /* Note: the grammar in the standard seems to be
		ambiguous: L'x' can be either a wide character
		constant, or an identifier followed by a normal
		character constant.  By trying `get_identifier' after
		we try get_character_constant and get_string_literal,
		we give the wide character syntax precedence.  Now,
		since GDB doesn't handle wide character constants
		anyway, is this the right thing to do?  */
	     || get_identifier (tok, p, end)
	     || get_punctuator (tok, p, end))
      {
	/* How many characters did we consume, including whitespace?  */
	int consumed = p - src->text + tok->len;

	src->text += consumed;
	src->len -= consumed;
	return 1;
      }
    else 
      {
	/* We have found a "non-whitespace character that cannot be
	   one of the above."  Make a token out of it.  */
	int consumed;

	set_token (tok, p, p + 1);
	consumed = p - src->text + tok->len;
	src->text += consumed;
	src->len -= consumed;
	return 1;
      }

  return 0;
}



/* Appending token strings, with and without splicing  */


/* Append the macro buffer SRC to the end of DEST, and ensure that
   doing so doesn't splice the token at the end of SRC with the token
   at the beginning of DEST.  SRC and DEST must have their last_token
   fields set.  Upon return, DEST's last_token field is set correctly.

   For example:

   If DEST is "(" and SRC is "y", then we can return with
   DEST set to "(y" --- we've simply appended the two buffers.

   However, if DEST is "x" and SRC is "y", then we must not return
   with DEST set to "xy" --- that would splice the two tokens "x" and
   "y" together to make a single token "xy".  However, it would be
   fine to return with DEST set to "x y".  Similarly, "<" and "<" must
   yield "< <", not "<<", etc.  */
static void
append_tokens_without_splicing (growable_macro_buffer *dest,
                                shared_macro_buffer *src)
{
  int original_dest_len = dest->len;
  shared_macro_buffer dest_tail, new_token;

  gdb_assert (src->last_token != -1);
  gdb_assert (dest->last_token != -1);
  
  /* First, just try appending the two, and call get_token to see if
     we got a splice.  */
  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.  */
  if (dest->last_token == original_dest_len)
    {
      dest->last_token = original_dest_len + src->last_token;
      return;
    }

  /* Set DEST_TAIL to point to the last token in DEST, followed by
     all the stuff we just appended.  */
  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
     append, then we must have spliced "/" and "*" or "/" and "/" to
     make a comment start.  (Just for the record, I got this right
     the first time.  This is not a bug fix.)  */
  if (get_token (&new_token, &dest_tail)
      && (new_token.text + new_token.len
	  == dest->text + original_dest_len))
    {
      /* No splice, so we're done.  */
      dest->last_token = original_dest_len + src->last_token;
      return;
    }

  /* Okay, a simple append caused a splice.  Let's chop dest back to
     its original length and try again, but separate the texts with a
     space.  */
  dest->len = original_dest_len;
  dest->appendc (' ');
  dest->appendmem (src->text, src->len);

  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)
      && (new_token.text + new_token.len
	  == dest->text + original_dest_len))
    {
      /* No splice, so we're done.  */
      dest->last_token = original_dest_len + 1 + src->last_token;
      return;
    }

  /* As far as I know, there's no case where inserting a space isn't
     enough to prevent a splice.  */
  internal_error (__FILE__, __LINE__,
		  _("unable to avoid splicing tokens during macro expansion"));
}

/* Stringify an argument, and insert it into DEST.  ARG is the text to
   stringify; it is LEN bytes long.  */

static void
stringify (growable_macro_buffer *dest, const char *arg, int len)
{
  /* Trim initial whitespace from ARG.  */
  while (len > 0 && macro_is_whitespace (*arg))
    {
      ++arg;
      --len;
    }

  /* Trim trailing whitespace from ARG.  */
  while (len > 0 && macro_is_whitespace (arg[len - 1]))
    --len;

  /* Insert the string.  */
  dest->appendc ('"');
  while (len > 0)
    {
      /* We could try to handle strange cases here, like control
	 characters, but there doesn't seem to be much point.  */
      if (macro_is_whitespace (*arg))
	{
	  /* Replace a sequence of whitespace with a single space.  */
	  dest->appendc (' ');
	  while (len > 1 && macro_is_whitespace (arg[1]))
	    {
	      ++arg;
	      --len;
	    }
	}
      else if (*arg == '\\' || *arg == '"')
	{
	  dest->appendc ('\\');
	  dest->appendc (*arg);
	}
      else
	dest->appendc (*arg);
      ++arg;
      --len;
    }
  dest->appendc ('"');
  dest->last_token = dest->len;
}

/* See macroexp.h.  */

gdb::unique_xmalloc_ptr<char>
macro_stringify (const char *str)
{
  int len = strlen (str);
  growable_macro_buffer buffer (len);

  stringify (&buffer, str, len);
  buffer.appendc ('\0');

  return buffer.release ();
}


/* Expanding macros!  */


/* A singly-linked list of the names of the macros we are currently 
   expanding --- for detecting expansion loops.  */
struct macro_name_list {
  const char *name;
  struct macro_name_list *next;
};


/* Return non-zero if we are currently expanding the macro named NAME,
   according to LIST; otherwise, return zero.

   You know, it would be possible to get rid of all the NO_LOOP
   arguments to these functions by simply generating a new lookup
   function and baton which refuses to find the definition for a
   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.  :(  */
static int
currently_rescanning (struct macro_name_list *list, const char *name)
{
  for (; list; list = list->next)
    if (strcmp (name, list->name) == 0)
      return 1;

  return 0;
}


/* Gather the arguments to a macro expansion.

   NAME is the name of the macro being invoked.  (It's only used for
   printing error messages.)

   Assume that SRC is the text of the macro invocation immediately
   following the macro name.  For example, if we're processing the
   text foo(bar, baz), then NAME would be foo and SRC will be (bar,
   baz).

   If SRC doesn't start with an open paren ( token at all, return
   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 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
   like "foo()"), we treat that as one argument, which happens to be
   the empty list of tokens.  The caller should keep in mind that such
   a sequence of tokens is a valid way to invoke one-parameter
   function-like macros, but also a valid way to invoke zero-parameter
   function-like macros.  Eeew.

   Consume the tokens from SRC; after this call, SRC contains the text
   following the invocation.  */

static bool
gather_arguments (const char *name, shared_macro_buffer *src, int nargs,
		  std::vector<shared_macro_buffer> *args_ptr)
{
  shared_macro_buffer tok;
  std::vector<shared_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.  */
  {
    shared_macro_buffer temp (src->text, src->len);

    if (! get_token (&tok, &temp)
	|| tok.len != 1
	|| tok.text[0] != '(')
      return false;
  }

  /* Consume SRC's opening paren.  */
  get_token (&tok, src);

  for (;;)
    {
      shared_macro_buffer *arg;
      int depth;

      /* Initialize the next argument.  */
      args.emplace_back ();
      arg = &args.back ();
      set_token (arg, src->text, src->text);

      /* Gather the argument's tokens.  */
      depth = 0;
      for (;;)
	{
	  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++;

	  /* Is tok is a closing paren?  */
	  else if (tok.len == 1 && tok.text[0] == ')')
	    {
	      /* If it's a closing paren at the top level, then that's
		 the end of the argument list.  */
	      if (depth == 0)
		{
		  /* In the varargs case, the last argument may be
		     missing.  Add an empty argument in this case.  */
		  if (nargs != -1 && args.size () == nargs - 1)
		    {
		      args.emplace_back ();
		      arg = &args.back ();
		      set_token (arg, src->text, src->text);
		    }

		  *args_ptr = std::move (args);
		  return true;
		}

	      depth--;
	    }

	  /* If tok is a comma at top level, then that's the end of
	     the current argument.  However, if we are handling a
	     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.size () < nargs))
	    break;

	  /* Extend the current argument to enclose this token.  If
	     this is the current argument's first token, leave out any
	     leading whitespace, just for aesthetics.  */
	  if (arg->len == 0)
	    {
	      arg->text = tok.text;
	      arg->len = tok.len;
	      arg->last_token = 0;
	    }
	  else
	    {
	      arg->len = (tok.text + tok.len) - arg->text;
	      arg->last_token = tok.text - arg->text;
	    }
	}
    }
}


/* The `expand' and `substitute_args' functions both invoke `scan'
   recursively, so we need a forward declaration somewhere.  */
static void scan (growable_macro_buffer *dest,
		  shared_macro_buffer *src,
		  struct macro_name_list *no_loop,
		  const macro_scope &scope);

/* A helper function for substitute_args.
   
   ARGV is a vector of all the arguments; ARGC is the number of
   arguments.  IS_VARARGS is true if the macro being substituted is a
   varargs macro; in this case VA_ARG_NAME is the name of the
   "variable" argument.  VA_ARG_NAME is ignored if IS_VARARGS is
   false.

   If the token TOK is the name of a parameter, return the parameter's
   index.  If TOK is not an argument, return -1.  */

static int
find_parameter (const shared_macro_buffer *tok,
		int is_varargs, const shared_macro_buffer *va_arg_name,
		int argc, const char * const *argv)
{
  int i;

  if (! tok->is_identifier)
    return -1;

  for (i = 0; i < argc; ++i)
    if (tok->len == strlen (argv[i]) 
	&& !memcmp (tok->text, argv[i], tok->len))
      return i;

  if (is_varargs && tok->len == va_arg_name->len
      && ! memcmp (tok->text, va_arg_name->text, tok->len))
    return argc - 1;

  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 (shared_macro_buffer *replacement_list,
				 shared_macro_buffer *token,
				 const char **start,
				 shared_macro_buffer *lookahead,
				 const 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 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,
   VA_ARG_NAME should be the name of the "variable" argument -- either
   __VA_ARGS__ for c99-style varargs, or the final argument name, for
   GNU-style varargs.  If IS_VARARGS is false, this parameter is
   ignored.

   If it is necessary to expand macro invocations in one of the
   arguments, use LOOKUP_FUNC and LOOKUP_BATON to find the macro
   definitions, and don't expand invocations of the macros listed in
   NO_LOOP.  */

static void
substitute_args (growable_macro_buffer *dest,
		 struct macro_definition *def,
		 int is_varargs, const shared_macro_buffer *va_arg_name,
		 const std::vector<shared_macro_buffer> &argv,
		 struct macro_name_list *no_loop,
		 const macro_scope &scope)
{
  /* The token we are currently considering.  */
  shared_macro_buffer tok;
  /* The replacement list's pointer from just before TOK was lexed.  */
  const char *original_rl_start;
  /* We have a single lookahead token to handle token splicing.  */
  shared_macro_buffer lookahead;
  /* The lookahead token might not be valid.  */
  int lookahead_valid;
  /* The replacement list's pointer from just before LOOKAHEAD was
     lexed.  */
  const char *lookahead_rl_start;

  /* A macro buffer for the macro's replacement list.  */
  shared_macro_buffer replacement_list (def->replacement,
					strlen (def->replacement));

  gdb_assert (dest->len == 0);
  dest->last_token = 0;

  original_rl_start = replacement_list.text;
  if (! get_token (&tok, &replacement_list))
    return;
  lookahead_rl_start = replacement_list.text;
  lookahead_valid = get_token (&lookahead, &replacement_list);

  /* __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
			     && startswith (tok.text, "__VA_OPT__"));

      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)
	{
	  dest->appendmem (original_rl_start, tok.text - original_rl_start);
	  dest->last_token = dest->len;
	}

      /* Is this token the stringification operator?  */
      if (tok.len == 1
	  && tok.text[0] == '#')
	{
	  int arg;

	  if (!lookahead_valid)
	    error (_("Stringification operator requires an argument."));

	  arg = find_parameter (&lookahead, is_varargs, va_arg_name,
				def->argc, def->argv);
	  if (arg == -1)
	    error (_("Argument to stringification operator must name "
		     "a macro parameter."));

	  stringify (dest, argv[arg].text, argv[arg].len);

	  /* Read one token and let the loop iteration code handle the
	     rest.  */
	  lookahead_rl_start = replacement_list.text;
	  lookahead_valid = get_token (&lookahead, &replacement_list);
	}
      /* Is this token the splicing operator?  */
      else if (tok.len == 2
	       && tok.text[0] == '#'
	       && tok.text[1] == '#')
	error (_("Stray splicing operator"));
      /* Is the next token the splicing operator?  */
      else if (lookahead_valid
	       && lookahead.len == 2
	       && lookahead.text[0] == '#'
	       && lookahead.text[1] == '#')
	{
	  int finished = 0;
	  int prev_was_comma = 0;

	  /* Note that GCC warns if the result of splicing is not a
	     token.  In the debugger there doesn't seem to be much
	     benefit from doing this.  */

	  /* Insert the first token.  */
	  if (tok.len == 1 && tok.text[0] == ',')
	    prev_was_comma = 1;
	  else
	    {
	      int arg = find_parameter (&tok, is_varargs, va_arg_name,
					def->argc, def->argv);

	      if (arg != -1)
		dest->appendmem (argv[arg].text, argv[arg].len);
	      else
		dest->appendmem (tok.text, tok.len);
	    }

	  /* Apply a possible sequence of ## operators.  */
	  for (;;)
	    {
	      if (! get_token (&tok, &replacement_list))
		error (_("Splicing operator at end of macro"));

	      /* Handle a comma before a ##.  If we are handling
		 varargs, and the token on the right hand side is the
		 varargs marker, and the final argument is empty or
		 missing, then drop the comma.  This is a GNU
		 extension.  There is one ambiguous case here,
		 involving pedantic behavior with an empty argument,
		 but we settle that in favor of GNU-style (GCC uses an
		 option).  If we aren't dealing with varargs, we
		 simply insert the comma.  */
	      if (prev_was_comma)
		{
		  if (! (is_varargs
			 && tok.len == va_arg_name->len
			 && !memcmp (tok.text, va_arg_name->text, tok.len)
			 && argv.back ().len == 0))
		    dest->appendmem (",", 1);
		  prev_was_comma = 0;
		}

	      /* Insert the token.  If it is a parameter, insert the
		 argument.  If it is a comma, treat it specially.  */
	      if (tok.len == 1 && tok.text[0] == ',')
		prev_was_comma = 1;
	      else
		{
		  int arg = find_parameter (&tok, is_varargs, va_arg_name,
					    def->argc, def->argv);

		  if (arg != -1)
		    dest->appendmem (argv[arg].text, argv[arg].len);
		  else
		    dest->appendmem (tok.text, tok.len);
		}

	      /* Now read another token.  If it is another splice, we
		 loop.  */
	      original_rl_start = replacement_list.text;
	      if (! get_token (&tok, &replacement_list))
		{
		  finished = 1;
		  break;
		}

	      if (! (tok.len == 2
		     && tok.text[0] == '#'
		     && tok.text[1] == '#'))
		break;
	    }

	  if (prev_was_comma)
	    {
	      /* We saw a comma.  Insert it now.  */
	      dest->appendmem (",", 1);
	    }

	  dest->last_token = dest->len;
	  if (finished)
	    lookahead_valid = 0;
	  else
	    {
	      /* Set up for the loop iterator.  */
	      lookahead = tok;
	      lookahead_rl_start = original_rl_start;
	      lookahead_valid = 1;
	    }
	}
      else
	{
	  /* Is this token an identifier?  */
	  int substituted = 0;
	  int arg = find_parameter (&tok, is_varargs, va_arg_name,
				    def->argc, def->argv);

	  if (arg != -1)
	    {
	      /* 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.  */
	      shared_macro_buffer arg_src (argv[arg].text, argv[arg].len);
	      scan (dest, &arg_src, no_loop, scope);
	      substituted = 1;
	    }

	  /* If it wasn't a parameter, then just copy it across.  */
	  if (! substituted)
	    append_tokens_without_splicing (dest, &tok);
	}
    }

  if (vaopt_state > 0)
    error (_("Unterminated __VA_OPT__"));
}


/* Expand a call to a macro named ID, whose definition is DEF.  Append
   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.

   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,
   we don't expand it.)  If we return zero, leave SRC unchanged.  */
static int
expand (const char *id,
	struct macro_definition *def,
	growable_macro_buffer *dest,
	shared_macro_buffer *src,
	struct macro_name_list *no_loop,
	const macro_scope &scope)
{
  struct macro_name_list new_no_loop;

  /* Create a new node to be added to the front of the no-expand list.
     This list is appropriate for re-scanning replacement lists, but
     it is *not* appropriate for scanning macro arguments; invocations
     of the macro whose arguments we are gathering *do* get expanded
     there.  */
  new_no_loop.name = id;
  new_no_loop.next = no_loop;

  /* What kind of macro are we expanding?  */
  if (def->kind == macro_object_like)
    {
      shared_macro_buffer replacement_list (def->replacement,
					    strlen (def->replacement));

      scan (dest, &replacement_list, &new_no_loop, scope);
      return 1;
    }
  else if (def->kind == macro_function_like)
    {
      shared_macro_buffer va_arg_name;
      int is_varargs = 0;

      if (def->argc >= 1)
	{
	  if (strcmp (def->argv[def->argc - 1], "...") == 0)
	    {
	      /* In C99-style varargs, substitution is done using
		 __VA_ARGS__.  */
	      va_arg_name.set_shared ("__VA_ARGS__", strlen ("__VA_ARGS__"));
	      is_varargs = 1;
	    }
	  else
	    {
	      int len = strlen (def->argv[def->argc - 1]);

	      if (len > 3
		  && strcmp (def->argv[def->argc - 1] + len - 3, "...") == 0)
		{
		  /* In GNU-style varargs, the name of the
		     substitution parameter is the name of the formal
		     argument without the "...".  */
		  va_arg_name.set_shared (def->argv[def->argc - 1], len - 3);
		  is_varargs = 1;
		}
	    }
	}

      std::vector<shared_macro_buffer> argv;
      /* If we couldn't find any argument list, then we don't expand
	 this macro.  */
      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 (argv.size () != def->argc)
	{
	  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 (! (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, int (argv.size ()));
	}

      /* Note that we don't expand macro invocations in the arguments
	 yet --- we let subst_args take care of that.  Parameters that
	 appear as operands of the stringifying operator "#" or the
	 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.  */
      growable_macro_buffer substituted (0);
      substitute_args (&substituted, def, is_varargs, &va_arg_name,
		       argv, no_loop, scope);

      /* Now `substituted' is the macro's replacement list, with all
	 argument values substituted into it properly.	Re-scan it for
	 macro references, but don't expand invocations of this macro.

	 We create a new buffer, `substituted_src', which points into
	 `substituted', and scan that.	We can't scan `substituted'
	 itself, since the tokenization process moves the buffer's
	 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.  */
      shared_macro_buffer substituted_src (substituted.text, substituted.len);
      scan (dest, &substituted_src, &new_no_loop, scope);

      return 1;
    }
  else
    internal_error (__FILE__, __LINE__, _("bad macro definition kind"));
}


/* If the single token in SRC_FIRST followed by the tokens in SRC_REST
   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.

   SRC_FIRST must be a string built by get_token.  */
static int
maybe_expand (growable_macro_buffer *dest,
	      shared_macro_buffer *src_first,
	      shared_macro_buffer *src_rest,
	      struct macro_name_list *no_loop,
	      const macro_scope &scope)
{
  /* Is this token an identifier?  */
  if (src_first->is_identifier)
    {
      /* Make a null-terminated copy of it, since that's what our
	 lookup function expects.  */
      std::string id (src_first->text, src_first->len);

      /* If we're currently re-scanning the result of expanding
	 this macro, don't expand it again.  */
      if (! currently_rescanning (no_loop, id.c_str ()))
	{
	  /* Does this identifier have a macro definition in scope?  */
	  macro_definition *def = standard_macro_lookup (id.c_str (), scope);

	  if (def && expand (id.c_str (), def, dest, src_rest, no_loop, scope))
	    return 1;
	}
    }

  return 0;
}


/* Expand macro references in SRC, appending the results to DEST.
   Assume we are re-scanning the result of expanding the macros named
   in NO_LOOP, and don't try to re-expand references to them.  */

static void
scan (growable_macro_buffer *dest,
      shared_macro_buffer *src,
      struct macro_name_list *no_loop,
      const macro_scope &scope)
{

  for (;;)
    {
      shared_macro_buffer tok;
      const char *original_src_start = src->text;

      /* Find the next token in SRC.  */
      if (! get_token (&tok, src))
	break;

      /* Just for aesthetics.  If we skipped some whitespace, copy
	 that to DEST.  */
      if (tok.text > original_src_start)
	{
	  dest->appendmem (original_src_start, tok.text - original_src_start);
	  dest->last_token = dest->len;
	}

      if (! maybe_expand (dest, &tok, src, no_loop, scope))
	/* We didn't end up expanding tok as a macro reference, so
	   simply append it to dest.  */
	append_tokens_without_splicing (dest, &tok);
    }

  /* Just for aesthetics.  If there was any trailing whitespace in
     src, copy it to dest.  */
  if (src->len)
    {
      dest->appendmem (src->text, src->len);
      dest->last_token = dest->len;
    }
}


gdb::unique_xmalloc_ptr<char>
macro_expand (const char *source, const macro_scope &scope)
{
  shared_macro_buffer src (source, strlen (source));

  growable_macro_buffer dest (0);
  dest.last_token = 0;

  scan (&dest, &src, 0, scope);

  dest.appendc ('\0');

  return dest.release ();
}


gdb::unique_xmalloc_ptr<char>
macro_expand_once (const char *source, const macro_scope &scope)
{
  error (_("Expand-once not implemented yet."));
}

gdb::unique_xmalloc_ptr<char>
macro_expand_next (const char **lexptr, const macro_scope &scope)
{
  shared_macro_buffer tok;

  /* Set up SRC to refer to the input text, pointed to by *lexptr.  */
  shared_macro_buffer src (*lexptr, strlen (*lexptr));

  /* Set up DEST to receive the expansion, if there is one.  */
  growable_macro_buffer dest (0);
  dest.last_token = 0;

  /* Get the text's first preprocessing token.  */
  if (! get_token (&tok, &src))
    return nullptr;

  /* If it's a macro invocation, expand it.  */
  if (maybe_expand (&dest, &tok, &src, 0, scope))
    {
      /* 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.  */
      dest.appendc ('\0');
      *lexptr = src.text;
      return dest.release ();
    }
  else
    {
      /* It wasn't a macro invocation.  */
      return nullptr;
    }
}
