/* Part of CPP library.  (Macro and #define handling.)
   Copyright (C) 1986-2025 Free Software Foundation, Inc.
   Written by Per Bothner, 1994.
   Based on CCCP program by Paul Rubin, June 1986
   Adapted to ANSI C, Richard Stallman, Jan 1987

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, 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; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.

 In other words, you are welcome to use, share and improve this program.
 You are forbidden to forbid anyone else to use, share and improve
 what you give them.   Help stamp out software-hoarding!  */

#include "config.h"
#include "system.h"
#include "cpplib.h"
#include "internal.h"

typedef struct macro_arg macro_arg;
/* This structure represents the tokens of a macro argument.  These
   tokens can be macro themselves, in which case they can be either
   expanded or unexpanded.  When they are expanded, this data
   structure keeps both the expanded and unexpanded forms.  */
struct macro_arg
{
  const cpp_token **first;	/* First token in unexpanded argument.  */
  const cpp_token **expanded;	/* Macro-expanded argument.  */
  const cpp_token *stringified;	/* Stringified argument.  */
  unsigned int count;		/* # of tokens in argument.  */
  unsigned int expanded_count;	/* # of tokens in expanded argument.  */
  location_t *virt_locs;	/* Where virtual locations for
				   unexpanded tokens are stored.  */
  location_t *expanded_virt_locs; /* Where virtual locations for
					  expanded tokens are
					  stored.  */
};

/* The kind of macro tokens which the instance of
   macro_arg_token_iter is supposed to iterate over.  */
enum macro_arg_token_kind {
  MACRO_ARG_TOKEN_NORMAL,
  /* This is a macro argument token that got transformed into a string
     literal, e.g. #foo.  */
  MACRO_ARG_TOKEN_STRINGIFIED,
  /* This is a token resulting from the expansion of a macro
     argument that was itself a macro.  */
  MACRO_ARG_TOKEN_EXPANDED
};

/* An iterator over tokens coming from a function-like macro
   argument.  */
typedef struct macro_arg_token_iter macro_arg_token_iter;
struct macro_arg_token_iter
{
  /* Whether or not -ftrack-macro-expansion is used.  */
  bool track_macro_exp_p;
  /* The kind of token over which we are supposed to iterate.  */
  enum macro_arg_token_kind kind;
  /* A pointer to the current token pointed to by the iterator.  */
  const cpp_token **token_ptr;
  /* A pointer to the "full" location of the current token.  If
     -ftrack-macro-expansion is used this location tracks loci across
     macro expansion.  */
  const location_t *location_ptr;
#if CHECKING_P
  /* The number of times the iterator went forward. This useful only
     when checking is enabled.  */
  size_t num_forwards;
#endif
};

/* Saved data about an identifier being used as a macro argument
   name.  */
struct macro_arg_saved_data {
  /* The canonical (UTF-8) spelling of this identifier.  */
  cpp_hashnode *canonical_node;
  /* The previous value & type of this identifier.  */
  union _cpp_hashnode_value value;
  node_type type;
};

static const char *vaopt_paste_error =
  N_("'##' cannot appear at either end of __VA_OPT__");

static void expand_arg (cpp_reader *, macro_arg *);

/* A class for tracking __VA_OPT__ state while iterating over a
   sequence of tokens.  This is used during both macro definition and
   expansion.  */
class vaopt_state {

 public:

  enum update_type
  {
    ERROR,
    DROP,
    INCLUDE,
    BEGIN,
    END
  };

  /* Initialize the state tracker.  ANY_ARGS is true if variable
     arguments were provided to the macro invocation.  */
  vaopt_state (cpp_reader *pfile, bool is_variadic, macro_arg *arg)
    : m_pfile (pfile),
    m_arg (arg),
    m_variadic (is_variadic),
    m_last_was_paste (false),
    m_stringify (false),
    m_state (0),
    m_paste_location (0),
    m_location (0),
    m_update (ERROR)
  {
  }

  /* Given a token, update the state of this tracker and return a
     boolean indicating whether the token should be be included in the
     expansion.  */
  update_type update (const cpp_token *token)
  {
    /* If the macro isn't variadic, just don't bother.  */
    if (!m_variadic)
      return INCLUDE;

    if (token->type == CPP_NAME
	&& token->val.node.node == m_pfile->spec_nodes.n__VA_OPT__)
      {
	if (m_state > 0)
	  {
	    cpp_error_at (m_pfile, CPP_DL_ERROR, token->src_loc,
			  "%<__VA_OPT__%> may not appear in a %<__VA_OPT__%>");
	    return ERROR;
	  }
	++m_state;
	m_location = token->src_loc;
	m_stringify = (token->flags & STRINGIFY_ARG) != 0;
	return BEGIN;
      }
    else if (m_state == 1)
      {
	if (token->type != CPP_OPEN_PAREN)
	  {
	    cpp_error_at (m_pfile, CPP_DL_ERROR, m_location,
			  "%<__VA_OPT__%> must be followed by an "
			  "open parenthesis");
	    return ERROR;
	  }
	++m_state;
	if (m_update == ERROR)
	  {
	    if (m_arg == NULL)
	      m_update = INCLUDE;
	    else
	      {
		m_update = DROP;
		if (!m_arg->expanded)
		  expand_arg (m_pfile, m_arg);
		for (unsigned idx = 0; idx < m_arg->expanded_count; ++idx)
		  if (m_arg->expanded[idx]->type != CPP_PADDING)
		    {
		      m_update = INCLUDE;
		      break;
		    }
	      }
	  }
	return DROP;
      }
    else if (m_state >= 2)
      {
	if (m_state == 2 && token->type == CPP_PASTE)
	  {
	    cpp_error_at (m_pfile, CPP_DL_ERROR, token->src_loc,
			  vaopt_paste_error);
	    return ERROR;
	  }
	/* Advance states before further considering this token, in
	   case we see a close paren immediately after the open
	   paren.  */
	if (m_state == 2)
	  ++m_state;

	bool was_paste = m_last_was_paste;
	m_last_was_paste = false;
	if (token->type == CPP_PASTE)
	  {
	    m_last_was_paste = true;
	    m_paste_location = token->src_loc;
	  }
	else if (token->type == CPP_OPEN_PAREN)
	  ++m_state;
	else if (token->type == CPP_CLOSE_PAREN)
	  {
	    --m_state;
	    if (m_state == 2)
	      {
		/* Saw the final paren.  */
		m_state = 0;

		if (was_paste)
		  {
		    cpp_error_at (m_pfile, CPP_DL_ERROR, token->src_loc,
				  vaopt_paste_error);
		    return ERROR;
		  }

		return END;
	      }
	  }
	return m_update;
      }

    /* Nothing to do with __VA_OPT__.  */
    return INCLUDE;
  }

  /* Ensure that any __VA_OPT__ was completed.  If ok, return true.
     Otherwise, issue an error and return false.  */
  bool completed ()
  {
    if (m_variadic && m_state != 0)
      cpp_error_at (m_pfile, CPP_DL_ERROR, m_location,
		    "unterminated %<__VA_OPT__%>");
    return m_state == 0;
  }

  /* Return true for # __VA_OPT__.  */
  bool stringify () const
  {
    return m_stringify;
  }

 private:

  /* The cpp_reader.  */
  cpp_reader *m_pfile;

  /* The __VA_ARGS__ argument.  */
  macro_arg *m_arg;

  /* True if the macro is variadic.  */
  bool m_variadic;
  /* If true, the previous token was ##.  This is used to detect when
     a paste occurs at the end of the sequence.  */
  bool m_last_was_paste;
  /* True for #__VA_OPT__.  */
  bool m_stringify;

  /* The state variable:
     0 means not parsing
     1 means __VA_OPT__ seen, looking for "("
     2 means "(" seen (so the next token can't be "##")
     >= 3 means looking for ")", the number encodes the paren depth.  */
  int m_state;

  /* The location of the paste token.  */
  location_t m_paste_location;

  /* Location of the __VA_OPT__ token.  */
  location_t m_location;

  /* If __VA_ARGS__ substitutes to no preprocessing tokens,
     INCLUDE, otherwise DROP.  ERROR when unknown yet.  */
  update_type m_update;
};

/* Macro expansion.  */

static cpp_macro *get_deferred_or_lazy_macro (cpp_reader *, cpp_hashnode *,
					      location_t);
static int enter_macro_context (cpp_reader *, cpp_hashnode *,
				const cpp_token *, location_t);
static int builtin_macro (cpp_reader *, cpp_hashnode *,
			  location_t, location_t);
static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *,
				 const cpp_token **, unsigned int);
static void push_extended_tokens_context (cpp_reader *, cpp_hashnode *,
					  _cpp_buff *, location_t *,
					  const cpp_token **, unsigned int);
static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *,
				_cpp_buff **, unsigned *);
static cpp_context *next_context (cpp_reader *);
static const cpp_token *padding_token (cpp_reader *, const cpp_token *);
static const cpp_token *new_string_token (cpp_reader *, uchar *, unsigned int);
static const cpp_token *stringify_arg (cpp_reader *, const cpp_token **,
				       unsigned int);
static void paste_all_tokens (cpp_reader *, const cpp_token *);
static bool paste_tokens (cpp_reader *, location_t,
			  const cpp_token **, const cpp_token *);
static void alloc_expanded_arg_mem (cpp_reader *, macro_arg *, size_t);
static void ensure_expanded_arg_room (cpp_reader *, macro_arg *, size_t, size_t *);
static void delete_macro_args (_cpp_buff*, unsigned num_args);
static void set_arg_token (macro_arg *, const cpp_token *,
			   location_t, size_t,
			   enum macro_arg_token_kind,
			   bool);
static const location_t *get_arg_token_location (const macro_arg *,
						      enum macro_arg_token_kind);
static const cpp_token **arg_token_ptr_at (const macro_arg *,
					   size_t,
					   enum macro_arg_token_kind,
					   location_t **virt_location);

static void macro_arg_token_iter_init (macro_arg_token_iter *, bool,
				       enum macro_arg_token_kind,
				       const macro_arg *,
				       const cpp_token **);
static const cpp_token *macro_arg_token_iter_get_token
(const macro_arg_token_iter *it);
static location_t macro_arg_token_iter_get_location
(const macro_arg_token_iter *);
static void macro_arg_token_iter_forward (macro_arg_token_iter *);
static _cpp_buff *tokens_buff_new (cpp_reader *, size_t,
				   location_t **);
static size_t tokens_buff_count (_cpp_buff *);
static const cpp_token **tokens_buff_last_token_ptr (_cpp_buff *);
static inline const cpp_token **tokens_buff_put_token_to (const cpp_token **,
                                                          location_t *,
                                                          const cpp_token *,
                                                          location_t,
                                                          location_t,
                                                          const line_map_macro *,
                                                          unsigned int);

static const cpp_token **tokens_buff_add_token (_cpp_buff *,
						location_t *,
						const cpp_token *,
						location_t,
						location_t,
						const line_map_macro *,
						unsigned int);
static inline void tokens_buff_remove_last_token (_cpp_buff *);
static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *,
			  macro_arg *, location_t);
static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *,
					_cpp_buff **, unsigned *);
static cpp_macro *create_iso_definition (cpp_reader *);

/* #define directive parsing and handling.  */

static cpp_macro *lex_expansion_token (cpp_reader *, cpp_macro *);
static bool parse_params (cpp_reader *, unsigned *, bool *);
static void check_trad_stringification (cpp_reader *, const cpp_macro *,
					const cpp_string *);
static bool reached_end_of_context (cpp_context *);
static void consume_next_token_from_context (cpp_reader *pfile,
					     const cpp_token **,
					     location_t *);
static const cpp_token* cpp_get_token_1 (cpp_reader *, location_t *);

static cpp_hashnode* macro_of_context (cpp_context *context);

/* Statistical counter tracking the number of macros that got
   expanded.  */
line_map_uint_t num_expanded_macros_counter = 0;
/* Statistical counter tracking the total number tokens resulting
   from macro expansion.  */
line_map_uint_t num_macro_tokens_counter = 0;

/* Wrapper around cpp_get_token to skip CPP_PADDING tokens
   and not consume CPP_EOF.  */
const cpp_token *
_cpp_get_token_no_padding (cpp_reader *pfile)
{
  for (;;)
    {
      const cpp_token *ret = cpp_peek_token (pfile, 0);
      if (ret->type == CPP_EOF)
	return ret;
      ret = cpp_get_token (pfile);
      if (ret->type != CPP_PADDING)
	return ret;
    }
}

/* Helper function for builtin_has_include and builtin_has_embed.  */

static char *
builtin_has_include_1 (cpp_reader *pfile, const char *name, bool *paren,
		       bool *bracket, location_t *loc)
{
  if (!pfile->state.in_directive)
    cpp_error (pfile, CPP_DL_ERROR,
	       "%qs used outside of preprocessing directive", name);

  pfile->state.angled_headers = true;
  const auto sav_padding = pfile->state.directive_wants_padding;
  pfile->state.directive_wants_padding = true;
  const cpp_token *token = _cpp_get_token_no_padding (pfile);
  *paren = token->type == CPP_OPEN_PAREN;
  if (*paren)
    token = _cpp_get_token_no_padding (pfile);
  else
    cpp_error (pfile, CPP_DL_ERROR,
	       "missing %<(%> before %qs operand", name);
  pfile->state.angled_headers = false;
  pfile->state.directive_wants_padding = sav_padding;

  if (loc)
    *loc = token->src_loc;
  *bracket = token->type != CPP_STRING;
  char *fname = NULL;
  if (token->type == CPP_STRING || token->type == CPP_HEADER_NAME)
    {
      fname = XNEWVEC (char, token->val.str.len - 1);
      memcpy (fname, token->val.str.text + 1, token->val.str.len - 2);
      fname[token->val.str.len - 2] = '\0';
    }
  else if (token->type == CPP_LESS)
    fname = _cpp_bracket_include (pfile);
  else
    cpp_error (pfile, CPP_DL_ERROR,
	       "operator %qs requires a header-name", name);
  return fname;
}

/* Handle meeting "__has_include" builtin macro.  */

static int
builtin_has_include (cpp_reader *pfile, cpp_hashnode *op, bool has_next)
{
  int result = 0;
  bool paren, bracket;
  char *fname = builtin_has_include_1 (pfile, (const char *) NODE_NAME (op),
				       &paren, &bracket, NULL);

  if (fname)
    {
      /* Do not do the lookup if we're skipping, that's unnecessary
	 IO.  */
      if (!pfile->state.skip_eval
	  && _cpp_has_header (pfile, fname, bracket,
			      has_next ? IT_INCLUDE_NEXT : IT_INCLUDE))
	result = 1;

      XDELETEVEC (fname);
    }

  if (paren
      && _cpp_get_token_no_padding (pfile)->type != CPP_CLOSE_PAREN)
    cpp_error (pfile, CPP_DL_ERROR,
	       "missing %<)%> after %qs operand", NODE_NAME (op));

  return result;
}

/* Handle the "__has_embed" expression.  */

static int
builtin_has_embed (cpp_reader *pfile)
{
  int result = 0;
  bool paren, bracket;
  struct cpp_embed_params params = {};
  char *fname = builtin_has_include_1 (pfile, "__has_embed", &paren,
				       &bracket, &params.loc);

  if (fname)
    {
      params.has_embed = true;
      auto save_in_directive = pfile->state.in_directive;
      auto save_angled_headers = pfile->state.angled_headers;
      auto save_directive_wants_padding = pfile->state.directive_wants_padding;
      auto save_op_stack = pfile->op_stack;
      auto save_op_limit = pfile->op_limit;
      auto save_skip_eval = pfile->state.skip_eval;
      auto save_mi_ind_cmacro = pfile->mi_ind_cmacro;
      /* Tell the lexer this is an embed directive.  */
      pfile->state.in_directive = 3;
      pfile->state.angled_headers = false;
      pfile->state.directive_wants_padding = false;
      pfile->op_stack = NULL;
      pfile->op_limit = NULL;
      bool ok = _cpp_parse_embed_params (pfile, &params);
      free (pfile->op_stack);
      pfile->state.in_directive = save_in_directive;
      pfile->state.angled_headers = save_angled_headers;
      pfile->state.directive_wants_padding = save_directive_wants_padding;
      pfile->op_stack = save_op_stack;
      pfile->op_limit = save_op_limit;
      pfile->state.skip_eval = save_skip_eval;
      pfile->mi_ind_cmacro = save_mi_ind_cmacro;

      if (!*fname)
	{
	  cpp_error_with_line (pfile, CPP_DL_ERROR, params.loc, 0,
			       "empty filename in %qs", "__has_embed");
	  ok = false;
	}

      /* Do not do the lookup if we're skipping, that's unnecessary
	 IO.  */
      if (ok && !pfile->state.skip_eval)
	result = _cpp_stack_embed (pfile, fname, bracket, &params);

      _cpp_free_embed_params_tokens (&params.base64);

      XDELETEVEC (fname);
    }
  else if (paren)
    _cpp_get_token_no_padding (pfile);

  return result;
}

/* Emits a warning if NODE is a macro defined in the main file that
   has not been used.  */
int
_cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node,
			   void *v ATTRIBUTE_UNUSED)
{
  if (cpp_user_macro_p (node))
    {
      cpp_macro *macro = node->value.macro;

      if (!macro->used
	  && MAIN_FILE_P (linemap_check_ordinary
			    (linemap_lookup (pfile->line_table,
					     macro->line))))
	cpp_warning_with_line (pfile, CPP_W_UNUSED_MACROS, macro->line, 0,
			       "macro %qs is not used", NODE_NAME (node));
    }

  return 1;
}

/* Allocates and returns a CPP_STRING token, containing TEXT of length
   LEN, after null-terminating it.  TEXT must be in permanent storage.  */
static const cpp_token *
new_string_token (cpp_reader *pfile, unsigned char *text, unsigned int len)
{
  cpp_token *token = _cpp_temp_token (pfile);

  text[len] = '\0';
  token->type = CPP_STRING;
  token->val.str.len = len;
  token->val.str.text = text;
  token->flags = 0;
  return token;
}

static const char * const monthnames[] =
{
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

/* Helper function for builtin_macro.  Returns the text generated by
   a builtin macro. */
const uchar *
_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
			 location_t loc)
{
  const uchar *result = NULL;
  linenum_type number = 1;

  switch (node->value.builtin)
    {
    default:
      cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro %qs",
		 NODE_NAME (node));
      break;

    case BT_TIMESTAMP:
      {
	if (CPP_OPTION (pfile, warn_date_time))
	  cpp_warning (pfile, CPP_W_DATE_TIME, "macro %qs might prevent "
		       "reproducible builds", NODE_NAME (node));

	cpp_buffer *pbuffer = cpp_get_buffer (pfile);
	if (pbuffer->timestamp == NULL)
	  {
	    /* Initialize timestamp value of the assotiated file. */
            struct _cpp_file *file = cpp_get_file (pbuffer);
	    if (file)
	      {
    		/* Generate __TIMESTAMP__ string, that represents
		   the date and time of the last modification
		   of the current source file. The string constant
		   looks like "Sun Sep 16 01:03:52 1973".  */
		struct tm *tb = NULL;
		struct stat *st = _cpp_get_file_stat (file);
		if (st)
		  tb = localtime (&st->st_mtime);
		if (tb)
		  {
		    char *str = asctime (tb);
		    size_t len = strlen (str);
		    unsigned char *buf = _cpp_unaligned_alloc (pfile, len + 2);
		    buf[0] = '"';
		    strcpy ((char *) buf + 1, str);
		    buf[len] = '"';
		    pbuffer->timestamp = buf;
		  }
		else
		  {
		    cpp_errno (pfile, CPP_DL_WARNING,
			"could not determine file timestamp");
		    pbuffer->timestamp = UC"\"??? ??? ?? ??:??:?? ????\"";
		  }
	      }
	  }
	result = pbuffer->timestamp;
      }
      break;
    case BT_FILE:
    case BT_FILE_NAME:
    case BT_BASE_FILE:
      {
	unsigned int len;
	const char *name;
	uchar *buf;

	if (node->value.builtin == BT_FILE
	    || node->value.builtin == BT_FILE_NAME)
	  {
	    name = linemap_get_expansion_filename (pfile->line_table,
						   pfile->line_table->highest_line);
	    if ((node->value.builtin == BT_FILE_NAME) && name)
	      name = lbasename (name);
	  }
	else
	  {
	    name = _cpp_get_file_name (pfile->main_file);
	    if (!name)
	      abort ();
	  }
	if (pfile->cb.remap_filename && !pfile->state.in_directive)
	  name = pfile->cb.remap_filename (name);
	len = strlen (name);
	buf = _cpp_unaligned_alloc (pfile, len * 2 + 3);
	result = buf;
	*buf = '"';
	buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len);
	*buf++ = '"';
	*buf = '\0';
      }
      break;

    case BT_INCLUDE_LEVEL:
      /* The line map depth counts the primary source as level 1, but
	 historically __INCLUDE_DEPTH__ has called the primary source
	 level 0.  */
      number = pfile->line_table->depth - 1;
      break;

    case BT_SPECLINE:
      /* If __LINE__ is embedded in a macro, it must expand to the
	 line of the macro's invocation, not its definition.
	 Otherwise things like assert() will not work properly.
	 See WG14 N1911, WG21 N4220 sec 6.5, and PR 61861.  */
      if (CPP_OPTION (pfile, traditional))
	loc = pfile->line_table->highest_line;
      else
	loc = linemap_resolve_location (pfile->line_table, loc,
					LRK_MACRO_EXPANSION_POINT, NULL);
      number = linemap_get_expansion_line (pfile->line_table, loc);
      break;

      /* __STDC__ has the value 1 under normal circumstances.
	 However, if (a) we are in a system header, (b) the option
	 stdc_0_in_system_headers is true (set by target config), and
	 (c) we are not in strictly conforming mode, then it has the
	 value 0.  (b) and (c) are already checked in cpp_init_builtins.  */
    case BT_STDC:
      if (_cpp_in_system_header (pfile))
	number = 0;
      else
	number = 1;
      break;

    case BT_DATE:
    case BT_TIME:
      if (CPP_OPTION (pfile, warn_date_time))
	cpp_warning (pfile, CPP_W_DATE_TIME, "macro %qs might prevent "
		     "reproducible builds", NODE_NAME (node));
      if (pfile->date == NULL)
	{
	  /* Allocate __DATE__ and __TIME__ strings from permanent
	     storage.  We only do this once, and don't generate them
	     at init time, because time() and localtime() are very
	     slow on some systems.  */
	  time_t tt;
	  auto kind = cpp_get_date (pfile, &tt);

	  if (kind == CPP_time_kind::UNKNOWN)
	    {
	      cpp_errno (pfile, CPP_DL_WARNING,
			 "could not determine date and time");

	      pfile->date = UC"\"??? ?? ????\"";
	      pfile->time = UC"\"??:??:??\"";
	    }
	  else
	    {
	      struct tm *tb = (kind == CPP_time_kind::FIXED
			       ? gmtime : localtime) (&tt);

	      pfile->date = _cpp_unaligned_alloc (pfile,
						  sizeof ("\"Oct 11 1347\""));
	      sprintf ((char *) pfile->date, "\"%s %2d %4d\"",
		       monthnames[tb->tm_mon], tb->tm_mday,
		       tb->tm_year + 1900);

	      pfile->time = _cpp_unaligned_alloc (pfile,
						  sizeof ("\"12:34:56\""));
	      sprintf ((char *) pfile->time, "\"%02d:%02d:%02d\"",
		       tb->tm_hour, tb->tm_min, tb->tm_sec);
	    }
	}

      if (node->value.builtin == BT_DATE)
	result = pfile->date;
      else
	result = pfile->time;
      break;

    case BT_COUNTER:
      if (CPP_OPTION (pfile, directives_only) && pfile->state.in_directive)
	cpp_error (pfile, CPP_DL_ERROR,
		   "%<__COUNTER__%> expanded inside directive with "
		   "%<-fdirectives-only%>");
      number = pfile->counter++;
      break;

    case BT_HAS_ATTRIBUTE:
      number = pfile->cb.has_attribute (pfile, false);
      break;

    case BT_HAS_STD_ATTRIBUTE:
      number = pfile->cb.has_attribute (pfile, true);
      break;

    case BT_HAS_BUILTIN:
      number = pfile->cb.has_builtin (pfile);
      break;

    case BT_HAS_INCLUDE:
    case BT_HAS_INCLUDE_NEXT:
      number = builtin_has_include (pfile, node,
				    node->value.builtin == BT_HAS_INCLUDE_NEXT);
      break;

    case BT_HAS_EMBED:
      if (CPP_OPTION (pfile, traditional))
	{
	  cpp_error (pfile, CPP_DL_ERROR, /* FIXME should be DL_SORRY */
		     "%<__has_embed%> not supported in traditional C");
	  break;
	}
      number = builtin_has_embed (pfile);
      break;

    case BT_HAS_FEATURE:
    case BT_HAS_EXTENSION:
      number = pfile->cb.has_feature (pfile,
				      node->value.builtin == BT_HAS_FEATURE);
      break;
    }

  if (result == NULL)
    {
      /* 21 bytes holds all NUL-terminated unsigned 64-bit numbers.  */
      result = _cpp_unaligned_alloc (pfile, 21);
      sprintf ((char *) result, "%u", number);
    }

  return result;
}

/* Get an idempotent date.  Either the cached value, the value from
   source epoch, or failing that, the value from time(2).  Use this
   during compilation so that every time stamp is the same.  */
CPP_time_kind
cpp_get_date (cpp_reader *pfile, time_t *result)
{
  if (!pfile->time_stamp_kind)
    {
      int kind = 0;
      if (pfile->cb.get_source_date_epoch)
	{
	  /* Try reading the fixed epoch.  */
	  pfile->time_stamp = pfile->cb.get_source_date_epoch (pfile);
	  if (pfile->time_stamp != time_t (-1))
	    kind = int (CPP_time_kind::FIXED);
	}

      if (!kind)
	{
	  /* Pedantically time_t (-1) is a legitimate value for
	     "number of seconds since the Epoch".  It is a silly
	     time.   */
	  errno = 0;
	  pfile->time_stamp = time (nullptr);
	  /* Annoyingly a library could legally set errno and return a
	     valid time!  Bad library!  */
	  if (pfile->time_stamp == time_t (-1) && errno)
	    kind = errno;
	  else
	    kind = int (CPP_time_kind::DYNAMIC);
	}

      pfile->time_stamp_kind = kind;
    }

  *result = pfile->time_stamp;
  if (pfile->time_stamp_kind >= 0)
    {
      errno = pfile->time_stamp_kind;
      return CPP_time_kind::UNKNOWN;
    }

  return CPP_time_kind (pfile->time_stamp_kind);
}

/* Convert builtin macros like __FILE__ to a token and push it on the
   context stack.  Also handles _Pragma, for which a new token may not
   be created.  Returns 1 if it generates a new token context, 0 to
   return the token to the caller.  LOC is the location of the expansion
   point of the macro.  */
static int
builtin_macro (cpp_reader *pfile, cpp_hashnode *node,
	       location_t loc, location_t expand_loc)
{
  const uchar *buf;
  size_t len;
  char *nbuf;

  if (node->value.builtin == BT_PRAGMA)
    {
      /* Don't interpret _Pragma within directives.  The standard is
         not clear on this, but to me this makes most sense.
         Similarly, don't interpret _Pragma inside expand_args, we might
         need to stringize it later on.  */
      if (pfile->state.in_directive || pfile->state.ignore__Pragma)
	return 0;

      return _cpp_do__Pragma (pfile, loc);
    }

  buf = _cpp_builtin_macro_text (pfile, node, expand_loc);
  len = ustrlen (buf);
  nbuf = (char *) alloca (len + 1);
  memcpy (nbuf, buf, len);
  nbuf[len]='\n';

  cpp_push_buffer (pfile, (uchar *) nbuf, len, /* from_stage3 */ true);
  _cpp_clean_line (pfile);

  /* Set pfile->cur_token as required by _cpp_lex_direct.  */
  pfile->cur_token = _cpp_temp_token (pfile);
  cpp_token *token = _cpp_lex_direct (pfile);
  /* We should point to the expansion point of the builtin macro.  */
  token->src_loc = loc;
  if (pfile->context->tokens_kind == TOKENS_KIND_EXTENDED)
    {
      /* We are tracking tokens resulting from macro expansion.
	 Create a macro line map and generate a virtual location for
	 the token resulting from the expansion of the built-in
	 macro.  */
      location_t *virt_locs = NULL;
      _cpp_buff *token_buf = tokens_buff_new (pfile, 1, &virt_locs);
      const line_map_macro * map =
	linemap_enter_macro (pfile->line_table, node, loc, 1);
      tokens_buff_add_token (token_buf, virt_locs, token,
			     pfile->line_table->builtin_location,
			     pfile->line_table->builtin_location,
			    map, /*macro_token_index=*/0);
      push_extended_tokens_context (pfile, node, token_buf, virt_locs,
				    (const cpp_token **)token_buf->base,
				    1);
    }
  else
    _cpp_push_token_context (pfile, NULL, token, 1);
  if (pfile->buffer->cur != pfile->buffer->rlimit)
    cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro %qs",
	       NODE_NAME (node));
  _cpp_pop_buffer (pfile);

  return 1;
}

/* Copies SRC, of length LEN, to DEST, adding backslashes before all
   backslashes and double quotes. DEST must be of sufficient size.
   Returns a pointer to the end of the string.  */
uchar *
cpp_quote_string (uchar *dest, const uchar *src, unsigned int len)
{
  while (len--)
    {
      uchar c = *src++;

      switch (c)
	{
	case '\n':
	  /* Naked LF can appear in raw string literals  */
	  c = 'n';
	  /* FALLTHROUGH */

	case '\\':
	case '"':
	  *dest++ = '\\';
	  /* FALLTHROUGH */

	default:
	  *dest++ = c;
	}
    }

  return dest;
}

/* Convert a token sequence FIRST to FIRST+COUNT-1 to a single string token
   according to the rules of the ISO C #-operator.  */
static const cpp_token *
stringify_arg (cpp_reader *pfile, const cpp_token **first, unsigned int count)
{
  unsigned char *dest;
  unsigned int i, escape_it, backslash_count = 0;
  const cpp_token *source = NULL;
  size_t len;

  if (BUFF_ROOM (pfile->u_buff) < 3)
    _cpp_extend_buff (pfile, &pfile->u_buff, 3);
  dest = BUFF_FRONT (pfile->u_buff);
  *dest++ = '"';

  /* Loop, reading in the argument's tokens.  */
  for (i = 0; i < count; i++)
    {
      const cpp_token *token = first[i];

      if (token->type == CPP_PADDING)
	{
	  if (source == NULL
	      || (!(source->flags & PREV_WHITE)
		  && token->val.source == NULL))
	    source = token->val.source;
	  continue;
	}

      escape_it = (token->type == CPP_STRING || token->type == CPP_CHAR
		   || token->type == CPP_WSTRING || token->type == CPP_WCHAR
		   || token->type == CPP_STRING32 || token->type == CPP_CHAR32
		   || token->type == CPP_STRING16 || token->type == CPP_CHAR16
		   || token->type == CPP_UTF8STRING || token->type == CPP_UTF8CHAR
		   || cpp_userdef_string_p (token->type)
		   || cpp_userdef_char_p (token->type));

      /* Room for each char being written in octal, initial space and
	 final quote and NUL.  */
      len = cpp_token_len (token);
      if (escape_it)
	len *= 4;
      len += 3;

      if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len)
	{
	  size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
	  _cpp_extend_buff (pfile, &pfile->u_buff, len);
	  dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
	}

      /* Leading white space?  */
      if (dest - 1 != BUFF_FRONT (pfile->u_buff))
	{
	  if (source == NULL)
	    source = token;
	  if (source->flags & PREV_WHITE)
	    *dest++ = ' ';
	}
      source = NULL;

      if (escape_it)
	{
	  _cpp_buff *buff = _cpp_get_buff (pfile, len);
	  unsigned char *buf = BUFF_FRONT (buff);
	  len = cpp_spell_token (pfile, token, buf, true) - buf;
	  dest = cpp_quote_string (dest, buf, len);
	  _cpp_release_buff (pfile, buff);
	}
      else
	dest = cpp_spell_token (pfile, token, dest, true);

      if (token->type == CPP_OTHER && token->val.str.text[0] == '\\')
	backslash_count++;
      else
	backslash_count = 0;
    }

  /* Ignore the final \ of invalid string literals.  */
  if (backslash_count & 1)
    {
      cpp_error (pfile, CPP_DL_WARNING,
		 "invalid string literal, ignoring final %<\\%>");
      dest--;
    }

  /* Commit the memory, including NUL, and return the token.  */
  *dest++ = '"';
  len = dest - BUFF_FRONT (pfile->u_buff);
  BUFF_FRONT (pfile->u_buff) = dest + 1;
  return new_string_token (pfile, dest - len, len);
}

/* Try to paste two tokens.  On success, return nonzero.  In any
   case, PLHS is updated to point to the pasted token, which is
   guaranteed to not have the PASTE_LEFT flag set.  LOCATION is
   the virtual location used for error reporting.  */
static bool
paste_tokens (cpp_reader *pfile, location_t location,
	      const cpp_token **plhs, const cpp_token *rhs)
{
  unsigned char *buf, *end, *lhsend;
  cpp_token *lhs;
  unsigned int len;

  len = cpp_token_len (*plhs) + cpp_token_len (rhs) + 2;
  buf = (unsigned char *) alloca (len);
  end = lhsend = cpp_spell_token (pfile, *plhs, buf, true);

  /* Avoid comment headers, since they are still processed in stage 3.
     It is simpler to insert a space here, rather than modifying the
     lexer to ignore comments in some circumstances.  Simply returning
     false doesn't work, since we want to clear the PASTE_LEFT flag.  */
  if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ)
    *end++ = ' ';
  /* In one obscure case we might see padding here.  */
  if (rhs->type != CPP_PADDING)
    end = cpp_spell_token (pfile, rhs, end, true);
  *end = '\n';

  cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true);
  _cpp_clean_line (pfile);

  /* Set pfile->cur_token as required by _cpp_lex_direct.  */
  pfile->cur_token = _cpp_temp_token (pfile);
  lhs = _cpp_lex_direct (pfile);
  if (pfile->buffer->cur != pfile->buffer->rlimit)
    {
      location_t saved_loc = lhs->src_loc;

      _cpp_pop_buffer (pfile);

      unsigned char *rhsstart = lhsend;
      if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ)
	rhsstart++;

      /* We have to remove the PASTE_LEFT flag from the old lhs, but
	 we want to keep the new location.  */
      *lhs = **plhs;
      *plhs = lhs;
      lhs->src_loc = saved_loc;
      lhs->flags &= ~PASTE_LEFT;

      /* Mandatory error for all apart from assembler.  */
      if (CPP_OPTION (pfile, lang) != CLK_ASM)
	cpp_error_with_line (pfile, CPP_DL_ERROR, location, 0,
			     "pasting \"%.*s\" and \"%.*s\" does not give "
			     "a valid preprocessing token",
			     (int) (lhsend - buf), buf,
			     (int) (end - rhsstart), rhsstart);
      return false;
    }

  lhs->flags |= (*plhs)->flags & (PREV_WHITE | PREV_FALLTHROUGH);
  *plhs = lhs;
  _cpp_pop_buffer (pfile);
  return true;
}

/* Handles an arbitrarily long sequence of ## operators, with initial
   operand LHS.  This implementation is left-associative,
   non-recursive, and finishes a paste before handling succeeding
   ones.  If a paste fails, we back up to the RHS of the failing ##
   operator before pushing the context containing the result of prior
   successful pastes, with the effect that the RHS appears in the
   output stream after the pasted LHS normally.  */
static void
paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs)
{
  const cpp_token *rhs = NULL;
  cpp_context *context = pfile->context;
  location_t virt_loc = 0;

  /* We are expanding a macro and we must have been called on a token
     that appears at the left hand side of a ## operator.  */
  if (macro_of_context (pfile->context) == NULL
      || (!(lhs->flags & PASTE_LEFT)))
    abort ();

  if (context->tokens_kind == TOKENS_KIND_EXTENDED)
    /* The caller must have called consume_next_token_from_context
       right before calling us.  That has incremented the pointer to
       the current virtual location.  So it now points to the location
       of the token that comes right after *LHS.  We want the
       resulting pasted token to have the location of the current
       *LHS, though.  */
    virt_loc = context->c.mc->cur_virt_loc[-1];
  else
    /* We are not tracking macro expansion.  So the best virtual
       location we can get here is the expansion point of the macro we
       are currently expanding.  */
    virt_loc = pfile->invocation_location;

  do
    {
      /* Take the token directly from the current context.  We can do
	 this, because we are in the replacement list of either an
	 object-like macro, or a function-like macro with arguments
	 inserted.  In either case, the constraints to #define
	 guarantee we have at least one more token.  */
      if (context->tokens_kind == TOKENS_KIND_DIRECT)
	rhs = FIRST (context).token++;
      else if (context->tokens_kind == TOKENS_KIND_INDIRECT)
	rhs = *FIRST (context).ptoken++;
      else if (context->tokens_kind == TOKENS_KIND_EXTENDED)
	{
	  /* So we are in presence of an extended token context, which
	     means that each token in this context has a virtual
	     location attached to it.  So let's not forget to update
	     the pointer to the current virtual location of the
	     current token when we update the pointer to the current
	     token */

	  rhs = *FIRST (context).ptoken++;
	  /* context->c.mc must be non-null, as if we were not in a
	     macro context, context->tokens_kind could not be equal to
	     TOKENS_KIND_EXTENDED.  */
	  context->c.mc->cur_virt_loc++;
	}

      if (rhs->type == CPP_PADDING)
	{
	  if (rhs->flags & PASTE_LEFT)
	    abort ();
	}
      if (!paste_tokens (pfile, virt_loc, &lhs, rhs))
	{
	  _cpp_backup_tokens (pfile, 1);
	  break;
	}
    }
  while (rhs->flags & PASTE_LEFT);

  /* Put the resulting token in its own context.  */
  if (context->tokens_kind == TOKENS_KIND_EXTENDED)
    {
      location_t *virt_locs = NULL;
      _cpp_buff *token_buf = tokens_buff_new (pfile, 1, &virt_locs);
      tokens_buff_add_token (token_buf, virt_locs, lhs,
			     virt_loc, 0, NULL, 0);
      push_extended_tokens_context (pfile, context->c.mc->macro_node,
				    token_buf, virt_locs,
				    (const cpp_token **)token_buf->base, 1);
    }
  else
    _cpp_push_token_context (pfile, NULL, lhs, 1);
}

/* Returns TRUE if the number of arguments ARGC supplied in an
   invocation of the MACRO referenced by NODE is valid.  An empty
   invocation to a macro with no parameters should pass ARGC as zero.

   Note that MACRO cannot necessarily be deduced from NODE, in case
   NODE was redefined whilst collecting arguments.  */
bool
_cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node, unsigned int argc)
{
  if (argc == macro->paramc)
    return true;

  if (argc < macro->paramc)
    {
      /* In C++20 and C23 (here the va_opt flag is used), and also as a GNU
	 extension, variadic arguments are allowed to not appear in
	 the invocation at all.
	 e.g. #define debug(format, args...) something
	 debug("string");

	 This is exactly the same as if an empty variadic list had been
	 supplied - debug("string", ).  */

      if (argc + 1 == macro->paramc && macro->variadic)
	{
	  if (CPP_PEDANTIC (pfile) && ! macro->syshdr
	      && ! CPP_OPTION (pfile, va_opt))
	    {
	      if (CPP_OPTION (pfile, cplusplus))
		cpp_pedwarning (pfile, CPP_W_CXX20_EXTENSIONS,
				"ISO C++11 requires at least one argument "
				"for the %<...%> in a variadic macro");
	      else
		cpp_pedwarning (pfile, CPP_W_PEDANTIC,
				"ISO C99 requires at least one argument "
				"for the %<...%> in a variadic macro");
	    }
	  return true;
	}

      cpp_error (pfile, CPP_DL_ERROR,
		 "macro %qs requires %u arguments, but only %u given",
		 NODE_NAME (node), macro->paramc, argc);
    }
  else
    cpp_error (pfile, CPP_DL_ERROR,
	       "macro %qs passed %u arguments, but takes just %u",
	       NODE_NAME (node), argc, macro->paramc);

  if (macro->line > RESERVED_LOCATION_COUNT)
    cpp_error_at (pfile, CPP_DL_NOTE, macro->line, "macro %qs defined here",
		  NODE_NAME (node));

  return false;
}

/* Reads and returns the arguments to a function-like macro
   invocation.  Assumes the opening parenthesis has been processed.
   If there is an error, emits an appropriate diagnostic and returns
   NULL.  Each argument is terminated by a CPP_EOF token, for the
   future benefit of expand_arg().  If there are any deferred
   #pragma directives among macro arguments, store pointers to the
   CPP_PRAGMA ... CPP_PRAGMA_EOL tokens into *PRAGMA_BUFF buffer.

   What is returned is the buffer that contains the memory allocated
   to hold the macro arguments.  NODE is the name of the macro this
   function is dealing with.  If NUM_ARGS is non-NULL, *NUM_ARGS is
   set to the actual number of macro arguments allocated in the
   returned buffer.  */
static _cpp_buff *
collect_args (cpp_reader *pfile, const cpp_hashnode *node,
	      _cpp_buff **pragma_buff, unsigned *num_args)
{
  _cpp_buff *buff, *base_buff;
  cpp_macro *macro;
  macro_arg *args, *arg;
  const cpp_token *token;
  unsigned int argc;
  location_t virt_loc;
  bool track_macro_expansion_p = CPP_OPTION (pfile, track_macro_expansion);
  unsigned num_args_alloced = 0;

  macro = node->value.macro;
  if (macro->paramc)
    argc = macro->paramc;
  else
    argc = 1;

#define DEFAULT_NUM_TOKENS_PER_MACRO_ARG 50
#define ARG_TOKENS_EXTENT 1000

  buff = _cpp_get_buff (pfile, argc * (DEFAULT_NUM_TOKENS_PER_MACRO_ARG
				       * sizeof (cpp_token *)
				       + sizeof (macro_arg)));
  base_buff = buff;
  args = (macro_arg *) buff->base;
  memset (args, 0, argc * sizeof (macro_arg));
  buff->cur = (unsigned char *) &args[argc];
  arg = args, argc = 0;

  /* Collect the tokens making up each argument.  We don't yet know
     how many arguments have been supplied, whether too many or too
     few.  Hence the slightly bizarre usage of "argc" and "arg".  */
  do
    {
      unsigned int paren_depth = 0;
      unsigned int ntokens = 0;
      unsigned virt_locs_capacity = DEFAULT_NUM_TOKENS_PER_MACRO_ARG;
      num_args_alloced++;

      argc++;
      arg->first = (const cpp_token **) buff->cur;
      if (track_macro_expansion_p)
	{
	  virt_locs_capacity = DEFAULT_NUM_TOKENS_PER_MACRO_ARG;
	  arg->virt_locs = XNEWVEC (location_t,
				    virt_locs_capacity);
	}

      for (;;)
	{
	  /* Require space for 2 new tokens (including a CPP_EOF).  */
	  if ((unsigned char *) &arg->first[ntokens + 2] > buff->limit)
	    {
	      buff = _cpp_append_extend_buff (pfile, buff,
					      ARG_TOKENS_EXTENT
					      * sizeof (cpp_token *));
	      arg->first = (const cpp_token **) buff->cur;
	    }
	  if (track_macro_expansion_p
	      && (ntokens + 2 > virt_locs_capacity))
	    {
	      virt_locs_capacity += ARG_TOKENS_EXTENT;
	      arg->virt_locs = XRESIZEVEC (location_t,
					   arg->virt_locs,
					   virt_locs_capacity);
	    }

	  token = cpp_get_token_1 (pfile, &virt_loc);

	  if (token->type == CPP_PADDING)
	    {
	      /* Drop leading padding.  */
	      if (ntokens == 0)
		continue;
	    }
	  else if (token->type == CPP_OPEN_PAREN)
	    paren_depth++;
	  else if (token->type == CPP_CLOSE_PAREN)
	    {
	      if (paren_depth-- == 0)
		break;
	    }
	  else if (token->type == CPP_COMMA)
	    {
	      /* A comma does not terminate an argument within
		 parentheses or as part of a variable argument.  */
	      if (paren_depth == 0
		  && ! (macro->variadic && argc == macro->paramc))
		break;
	    }
	  else if (token->type == CPP_EOF
		   || (token->type == CPP_HASH && token->flags & BOL))
	    break;
	  else if (token->type == CPP_PRAGMA && !(token->flags & PRAGMA_OP))
	    {
	      cpp_token *newtok = _cpp_temp_token (pfile);

	      /* CPP_PRAGMA token lives in directive_result, which will
		 be overwritten on the next directive.  */
	      *newtok = *token;
	      token = newtok;
	      do
		{
		  if (*pragma_buff == NULL
		      || BUFF_ROOM (*pragma_buff) < sizeof (cpp_token *))
		    {
		      _cpp_buff *next;
		      if (*pragma_buff == NULL)
			*pragma_buff
			  = _cpp_get_buff (pfile, 32 * sizeof (cpp_token *));
		      else
			{
			  next = *pragma_buff;
			  *pragma_buff
			    = _cpp_get_buff (pfile,
					     (BUFF_FRONT (*pragma_buff)
					      - (*pragma_buff)->base) * 2);
			  (*pragma_buff)->next = next;
			}
		    }
		  *(const cpp_token **) BUFF_FRONT (*pragma_buff) = token;
		  BUFF_FRONT (*pragma_buff) += sizeof (cpp_token *);
		  if (token->type == CPP_PRAGMA_EOL)
		    break;
		  token = cpp_get_token_1 (pfile, &virt_loc);
		}
	      while (token->type != CPP_EOF);

	      /* In deferred pragmas parsing_args and prevent_expansion
		 had been changed, reset it.  */
	      pfile->state.parsing_args = 2;
	      pfile->state.prevent_expansion = 1;

	      if (token->type == CPP_EOF)
		break;
	      else
		continue;
	    }
	  set_arg_token (arg, token, virt_loc,
			 ntokens, MACRO_ARG_TOKEN_NORMAL,
			 CPP_OPTION (pfile, track_macro_expansion));
	  ntokens++;
	}

      /* Drop trailing padding.  */
      while (ntokens > 0 && arg->first[ntokens - 1]->type == CPP_PADDING)
	ntokens--;

      arg->count = ntokens;
      /* Append an EOF to mark end-of-argument.  */
      set_arg_token (arg, &pfile->endarg, token->src_loc,
		     ntokens, MACRO_ARG_TOKEN_NORMAL,
		     CPP_OPTION (pfile, track_macro_expansion));

      /* Terminate the argument.  Excess arguments loop back and
	 overwrite the final legitimate argument, before failing.  */
      if (argc <= macro->paramc)
	{
	  buff->cur = (unsigned char *) &arg->first[ntokens + 1];
	  if (argc != macro->paramc)
	    arg++;
	}
    }
  while (token->type != CPP_CLOSE_PAREN && token->type != CPP_EOF);

  if (token->type == CPP_EOF)
    {
      /* Unless the EOF is marking the end of an argument, it's a fake
	 one from the end of a file that _cpp_clean_line will not have
	 advanced past.  */
      if (token == &pfile->endarg)
	_cpp_backup_tokens (pfile, 1);
      cpp_error (pfile, CPP_DL_ERROR,
		 "unterminated argument list invoking macro %qs",
		 NODE_NAME (node));
    }
  else
    {
      /* A single empty argument is counted as no argument.  */
      if (argc == 1 && macro->paramc == 0 && args[0].count == 0)
	argc = 0;
      if (_cpp_arguments_ok (pfile, macro, node, argc))
	{
	  /* GCC has special semantics for , ## b where b is a varargs
	     parameter: we remove the comma if b was omitted entirely.
	     If b was merely an empty argument, the comma is retained.
	     If the macro takes just one (varargs) parameter, then we
	     retain the comma only if we are standards conforming.

	     If FIRST is NULL replace_args () swallows the comma.  */
	  if (macro->variadic && (argc < macro->paramc
				  || (argc == 1 && args[0].count == 0
				      && !CPP_OPTION (pfile, std))))
	    args[macro->paramc - 1].first = NULL;
	  if (num_args)
	    *num_args = num_args_alloced;
	  return base_buff;
	}
    }

  /* An error occurred.  */
  _cpp_release_buff (pfile, base_buff);
  return NULL;
}

/* Search for an opening parenthesis to the macro of NODE, in such a
   way that, if none is found, we don't lose the information in any
   intervening padding tokens.  If we find the parenthesis, collect
   the arguments and return the buffer containing them.  PRAGMA_BUFF
   argument is the same as in collect_args.  If NUM_ARGS is non-NULL,
   *NUM_ARGS is set to the number of arguments contained in the
   returned buffer.  */
static _cpp_buff *
funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node,
		      _cpp_buff **pragma_buff, unsigned *num_args)
{
  const cpp_token *token, *padding = NULL;

  for (;;)
    {
      token = cpp_get_token (pfile);
      if (token->type != CPP_PADDING)
	break;
      gcc_assert ((token->flags & PREV_WHITE) == 0);
      if (padding == NULL
	  || padding->val.source == NULL
	  || (!(padding->val.source->flags & PREV_WHITE)
	      && token->val.source == NULL))
	padding = token;
    }

  if (token->type == CPP_OPEN_PAREN)
    {
      pfile->state.parsing_args = 2;
      return collect_args (pfile, node, pragma_buff, num_args);
    }

  /* Back up.  A CPP_EOF is either an EOF from an argument we're
     expanding, or a fake one from lex_direct.  We want to backup the
     former, but not the latter.  We may have skipped padding, in
     which case backing up more than one token when expanding macros
     is in general too difficult.  We re-insert it in its own
     context.  */
  if (token->type != CPP_EOF || token == &pfile->endarg)
    {
      _cpp_backup_tokens (pfile, 1);
      if (padding)
	_cpp_push_token_context (pfile, NULL, padding, 1);
    }

  return NULL;
}

/* Return the real number of tokens in the expansion of MACRO.  */
static inline unsigned int
macro_real_token_count (const cpp_macro *macro)
{
  if (__builtin_expect (!macro->extra_tokens, true))
    return macro->count;

  for (unsigned i = macro->count; i--;)
    if (macro->exp.tokens[i].type != CPP_PASTE)
      return i + 1;

  return 0;
}

/* Push the context of a macro with hash entry NODE onto the context
   stack.  If we can successfully expand the macro, we push a context
   containing its yet-to-be-rescanned replacement list and return one.
   If there were additionally any unexpanded deferred #pragma
   directives among macro arguments, push another context containing
   the pragma tokens before the yet-to-be-rescanned replacement list
   and return two.  Otherwise, we don't push a context and return
   zero. LOCATION is the location of the expansion point of the
   macro.  */
static int
enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
		     const cpp_token *result, location_t location)
{
  /* The presence of a macro invalidates a file's controlling macro.  */
  pfile->mi_valid = false;

  pfile->state.angled_headers = false;

  /* From here to when we push the context for the macro later down
     this function, we need to flag the fact that we are about to
     expand a macro.  This is useful when -ftrack-macro-expansion is
     turned off.  In that case, we need to record the location of the
     expansion point of the top-most macro we are about to to expand,
     into pfile->invocation_location.  But we must not record any such
     location once the process of expanding the macro starts; that is,
     we must not do that recording between now and later down this
     function where set this flag to FALSE.  */
  pfile->about_to_expand_macro_p = true;

  if (cpp_user_macro_p (node))
    {
      cpp_macro *macro = node->value.macro;
      _cpp_buff *pragma_buff = NULL;

      if (macro->fun_like)
	{
	  _cpp_buff *buff;
	  unsigned num_args = 0;

	  pfile->state.prevent_expansion++;
	  pfile->keep_tokens++;
	  pfile->state.parsing_args = 1;
	  buff = funlike_invocation_p (pfile, node, &pragma_buff,
				       &num_args);
	  pfile->state.parsing_args = 0;
	  pfile->keep_tokens--;
	  pfile->state.prevent_expansion--;

	  if (buff == NULL)
	    {
	      if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
		cpp_warning (pfile, CPP_W_TRADITIONAL,
			     "function-like macro %qs must be used with "
			     "arguments in traditional C", NODE_NAME (node));

	      if (pragma_buff)
		_cpp_release_buff (pfile, pragma_buff);

	      pfile->about_to_expand_macro_p = false;
	      return 0;
	    }

	  if (macro->paramc > 0)
	    replace_args (pfile, node, macro,
			  (macro_arg *) buff->base,
			  location);
	  /* Free the memory used by the arguments of this
	     function-like macro.  This memory has been allocated by
	     funlike_invocation_p and by replace_args.  */
	  delete_macro_args (buff, num_args);
	}

      /* Disable the macro within its expansion.  */
      node->flags |= NODE_DISABLED;

      /* Laziness can only affect the expansion tokens of the macro,
	 not its fun-likeness or parameters.  */
      _cpp_maybe_notify_macro_use (pfile, node, location);
      if (pfile->cb.used)
	pfile->cb.used (pfile, location, node);

      macro->used = 1;

      if (macro->paramc == 0)
	{
	  unsigned tokens_count = macro_real_token_count (macro);
	  if (CPP_OPTION (pfile, track_macro_expansion))
	    {
	      unsigned int i;
	      const cpp_token *src = macro->exp.tokens;
	      const line_map_macro *map;
	      location_t *virt_locs = NULL;
	      _cpp_buff *macro_tokens
		= tokens_buff_new (pfile, tokens_count, &virt_locs);

	      /* Create a macro map to record the locations of the
		 tokens that are involved in the expansion. LOCATION
		 is the location of the macro expansion point.  */
	      map = linemap_enter_macro (pfile->line_table,
					 node, location, tokens_count);
	      for (i = 0; i < tokens_count; ++i)
		{
		  tokens_buff_add_token (macro_tokens, virt_locs,
					 src, src->src_loc,
					 src->src_loc, map, i);
		  ++src;
		}
	      push_extended_tokens_context (pfile, node,
					    macro_tokens,
					    virt_locs,
					    (const cpp_token **)
					    macro_tokens->base,
					    tokens_count);
	    }
	  else
	    _cpp_push_token_context (pfile, node, macro->exp.tokens,
				     tokens_count);
	  num_macro_tokens_counter += tokens_count;
	}

      if (pragma_buff)
	{
	  if (!pfile->state.in_directive)
	    _cpp_push_token_context (pfile, NULL,
				     padding_token (pfile, result), 1);
	  do
	    {
	      unsigned tokens_count;
	      _cpp_buff *tail = pragma_buff->next;
	      pragma_buff->next = NULL;
	      tokens_count = ((const cpp_token **) BUFF_FRONT (pragma_buff)
			      - (const cpp_token **) pragma_buff->base);
	      push_ptoken_context (pfile, NULL, pragma_buff,
				   (const cpp_token **) pragma_buff->base,
				   tokens_count);
	      pragma_buff = tail;
	      if (!CPP_OPTION (pfile, track_macro_expansion))
		num_macro_tokens_counter += tokens_count;

	    }
	  while (pragma_buff != NULL);
	  pfile->about_to_expand_macro_p = false;
	  return 2;
	}

      pfile->about_to_expand_macro_p = false;
      return 1;
    }

  pfile->about_to_expand_macro_p = false;
  /* Handle built-in macros and the _Pragma operator.  */
  {
    location_t expand_loc;

    if (/* The top-level macro invocation that triggered the expansion
	   we are looking at is with a function-like user macro ...  */
	cpp_fun_like_macro_p (pfile->top_most_macro_node)
	/* ... and we are tracking the macro expansion.  */
	&& CPP_OPTION (pfile, track_macro_expansion))
      /* Then the location of the end of the macro invocation is the
	 location of the expansion point of this macro.  */
      expand_loc = location;
    else
      /* Otherwise, the location of the end of the macro invocation is
	 the location of the expansion point of that top-level macro
	 invocation.  */
      expand_loc = pfile->invocation_location;

    return builtin_macro (pfile, node, location, expand_loc);
  }
}

/* De-allocate the memory used by BUFF which is an array of instances
   of macro_arg.  NUM_ARGS is the number of instances of macro_arg
   present in BUFF.  */
static void
delete_macro_args (_cpp_buff *buff, unsigned num_args)
{
  macro_arg *macro_args;
  unsigned i;

  if (buff == NULL)
    return;

  macro_args = (macro_arg *) buff->base;

  /* Walk instances of macro_arg to free their expanded tokens as well
     as their macro_arg::virt_locs members.  */
  for (i = 0; i < num_args; ++i)
    {
      if (macro_args[i].expanded)
	{
	  free (macro_args[i].expanded);
	  macro_args[i].expanded = NULL;
	}
      if (macro_args[i].virt_locs)
	{
	  free (macro_args[i].virt_locs);
	  macro_args[i].virt_locs = NULL;
	}
      if (macro_args[i].expanded_virt_locs)
	{
	  free (macro_args[i].expanded_virt_locs);
	  macro_args[i].expanded_virt_locs = NULL;
	}
    }
  _cpp_free_buff (buff);
}

/* Set the INDEXth token of the macro argument ARG. TOKEN is the token
   to set, LOCATION is its virtual location.  "Virtual" location means
   the location that encodes loci across macro expansion. Otherwise
   it has to be TOKEN->SRC_LOC.  KIND is the kind of tokens the
   argument ARG is supposed to contain.  Note that ARG must be
   tailored so that it has enough room to contain INDEX + 1 numbers of
   tokens, at least.  */
static void
set_arg_token (macro_arg *arg, const cpp_token *token,
	       location_t location, size_t index,
	       enum macro_arg_token_kind kind,
	       bool track_macro_exp_p)
{
  const cpp_token **token_ptr;
  location_t *loc = NULL;

  token_ptr =
    arg_token_ptr_at (arg, index, kind,
		      track_macro_exp_p ? &loc : NULL);
  *token_ptr = token;

  if (loc != NULL)
    {
      /* We can't set the location of a stringified argument
	 token and we can't set any location if we aren't tracking
	 macro expansion locations.   */
      gcc_checking_assert (kind != MACRO_ARG_TOKEN_STRINGIFIED
			   && track_macro_exp_p);
      *loc = location;
    }
}

/* Get the pointer to the location of the argument token of the
   function-like macro argument ARG.  This function must be called
   only when we -ftrack-macro-expansion is on.  */
static const location_t *
get_arg_token_location (const macro_arg *arg,
			enum macro_arg_token_kind kind)
{
  const location_t *loc = NULL;
  const cpp_token **token_ptr =
    arg_token_ptr_at (arg, 0, kind, (location_t **) &loc);

  if (token_ptr == NULL)
    return NULL;

  return loc;
}

/* Return the pointer to the INDEXth token of the macro argument ARG.
   KIND specifies the kind of token the macro argument ARG contains.
   If VIRT_LOCATION is non NULL, *VIRT_LOCATION is set to the address
   of the virtual location of the returned token if the
   -ftrack-macro-expansion flag is on; otherwise, it's set to the
   spelling location of the returned token.  */
static const cpp_token **
arg_token_ptr_at (const macro_arg *arg, size_t index,
		  enum macro_arg_token_kind kind,
		  location_t **virt_location)
{
  const cpp_token **tokens_ptr = NULL;

  switch (kind)
    {
    case MACRO_ARG_TOKEN_NORMAL:
      tokens_ptr = arg->first;
      break;
    case MACRO_ARG_TOKEN_STRINGIFIED:
      tokens_ptr = (const cpp_token **) &arg->stringified;
      break;
    case MACRO_ARG_TOKEN_EXPANDED:
	tokens_ptr = arg->expanded;
      break;
    }

  if (tokens_ptr == NULL)
    /* This can happen for e.g, an empty token argument to a
       funtion-like macro.  */
    return tokens_ptr;

  if (virt_location)
    {
      if (kind == MACRO_ARG_TOKEN_NORMAL)
	*virt_location = &arg->virt_locs[index];
      else if (kind == MACRO_ARG_TOKEN_EXPANDED)
	*virt_location = &arg->expanded_virt_locs[index];
      else if (kind == MACRO_ARG_TOKEN_STRINGIFIED)
	*virt_location =
	  (location_t *) &tokens_ptr[index]->src_loc;
    }
  return &tokens_ptr[index];
}

/* Initialize an iterator so that it iterates over the tokens of a
   function-like macro argument.  KIND is the kind of tokens we want
   ITER to iterate over. TOKEN_PTR points the first token ITER will
   iterate over.  */
static void
macro_arg_token_iter_init (macro_arg_token_iter *iter,
			   bool track_macro_exp_p,
			   enum macro_arg_token_kind kind,
			   const macro_arg *arg,
			   const cpp_token **token_ptr)
{
  iter->track_macro_exp_p = track_macro_exp_p;
  iter->kind = kind;
  iter->token_ptr = token_ptr;
  /* Unconditionally initialize this so that the compiler doesn't warn
     about iter->location_ptr being possibly uninitialized later after
     this code has been inlined somewhere.  */
  iter->location_ptr = NULL;
  if (track_macro_exp_p)
    iter->location_ptr = get_arg_token_location (arg, kind);
#if CHECKING_P
  iter->num_forwards = 0;
  if (track_macro_exp_p
      && token_ptr != NULL
      && iter->location_ptr == NULL)
    abort ();
#endif
}

/* Move the iterator one token forward. Note that if IT was
   initialized on an argument that has a stringified token, moving it
   forward doesn't make sense as a stringified token is essentially one
   string.  */
static void
macro_arg_token_iter_forward (macro_arg_token_iter *it)
{
  switch (it->kind)
    {
    case MACRO_ARG_TOKEN_NORMAL:
    case MACRO_ARG_TOKEN_EXPANDED:
      it->token_ptr++;
      if (it->track_macro_exp_p)
	it->location_ptr++;
      break;
    case MACRO_ARG_TOKEN_STRINGIFIED:
#if CHECKING_P
      if (it->num_forwards > 0)
	abort ();
#endif
      break;
    }

#if CHECKING_P
  it->num_forwards++;
#endif
}

/* Return the token pointed to by the iterator.  */
static const cpp_token *
macro_arg_token_iter_get_token (const macro_arg_token_iter *it)
{
#if CHECKING_P
  if (it->kind == MACRO_ARG_TOKEN_STRINGIFIED
      && it->num_forwards > 0)
    abort ();
#endif
  if (it->token_ptr == NULL)
    return NULL;
  return *it->token_ptr;
}

/* Return the location of the token pointed to by the iterator.*/
static location_t
macro_arg_token_iter_get_location (const macro_arg_token_iter *it)
{
#if CHECKING_P
  if (it->kind == MACRO_ARG_TOKEN_STRINGIFIED
      && it->num_forwards > 0)
    abort ();
#endif
  if (it->track_macro_exp_p)
    return *it->location_ptr;
  else
    return (*it->token_ptr)->src_loc;
}

/* Return the index of a token [resulting from macro expansion] inside
   the total list of tokens resulting from a given macro
   expansion. The index can be different depending on whether if we
   want each tokens resulting from function-like macro arguments
   expansion to have a different location or not.

   E.g, consider this function-like macro:

        #define M(x) x - 3

   Then consider us "calling" it (and thus expanding it) like:

       M(1+4)

   It will be expanded into:

       1+4-3

   Let's consider the case of the token '4'.

   Its index can be 2 (it's the third token of the set of tokens
   resulting from the expansion) or it can be 0 if we consider that
   all tokens resulting from the expansion of the argument "1+2" have
   the same index, which is 0. In this later case, the index of token
   '-' would then be 1 and the index of token '3' would be 2.

   The later case is useful to use less memory e.g, for the case of
   the user using the option -ftrack-macro-expansion=1.

   ABSOLUTE_TOKEN_INDEX is the index of the macro argument token we
   are interested in.  CUR_REPLACEMENT_TOKEN is the token of the macro
   parameter (inside the macro replacement list) that corresponds to
   the macro argument for which ABSOLUTE_TOKEN_INDEX is a token index
   of.

   If we refer to the example above, for the '4' argument token,
   ABSOLUTE_TOKEN_INDEX would be set to 2, and CUR_REPLACEMENT_TOKEN
   would be set to the token 'x', in the replacement list "x - 3" of
   macro M.

   This is a subroutine of replace_args.  */
inline static unsigned
expanded_token_index (cpp_reader *pfile, cpp_macro *macro,
		      const cpp_token *cur_replacement_token,
		      unsigned absolute_token_index)
{
  if (CPP_OPTION (pfile, track_macro_expansion) > 1)
    return absolute_token_index;
  return cur_replacement_token - macro->exp.tokens;
}

/* Copy whether PASTE_LEFT is set from SRC to *PASTE_FLAG.  */

static void
copy_paste_flag (cpp_reader *pfile, const cpp_token **paste_flag,
		 const cpp_token *src)
{
  cpp_token *token = _cpp_temp_token (pfile);
  token->type = (*paste_flag)->type;
  token->val = (*paste_flag)->val;
  if (src->flags & PASTE_LEFT)
    token->flags = (*paste_flag)->flags | PASTE_LEFT;
  else
    token->flags = (*paste_flag)->flags & ~PASTE_LEFT;
  *paste_flag = token;
}

/* True IFF the last token emitted into BUFF (if any) is PTR.  */

static bool
last_token_is (_cpp_buff *buff, const cpp_token **ptr)
{
  return (ptr && tokens_buff_last_token_ptr (buff) == ptr);
}

/* Replace the parameters in a function-like macro of NODE with the
   actual ARGS, and place the result in a newly pushed token context.
   Expand each argument before replacing, unless it is operated upon
   by the # or ## operators. EXPANSION_POINT_LOC is the location of
   the expansion point of the macro. E.g, the location of the
   function-like macro invocation.  */
static void
replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro,
	      macro_arg *args, location_t expansion_point_loc)
{
  unsigned int i, total;
  const cpp_token *src, *limit;
  const cpp_token **first = NULL;
  macro_arg *arg;
  _cpp_buff *buff = NULL;
  location_t *virt_locs = NULL;
  unsigned int exp_count;
  const line_map_macro *map = NULL;
  int track_macro_exp;

  /* First, fully macro-expand arguments, calculating the number of
     tokens in the final expansion as we go.  The ordering of the if
     statements below is subtle; we must handle stringification before
     pasting.  */

  /* EXP_COUNT is the number of tokens in the macro replacement
     list.  TOTAL is the number of tokens /after/ macro parameters
     have been replaced by their arguments.   */
  exp_count = macro_real_token_count (macro);
  total = exp_count;
  limit = macro->exp.tokens + exp_count;

  for (src = macro->exp.tokens; src < limit; src++)
    if (src->type == CPP_MACRO_ARG)
      {
	/* Leading and trailing padding tokens.  */
	total += 2;
	/* Account for leading and padding tokens in exp_count too.
	   This is going to be important later down this function,
	   when we want to handle the case of (track_macro_exp <
	   2).  */
	exp_count += 2;

	/* We have an argument.  If it is not being stringified or
	   pasted it is macro-replaced before insertion.  */
	arg = &args[src->val.macro_arg.arg_no - 1];

	if (src->flags & STRINGIFY_ARG)
	  {
	    if (!arg->stringified)
	      arg->stringified = stringify_arg (pfile, arg->first, arg->count);
	  }
	else if ((src->flags & PASTE_LEFT)
		 || (src != macro->exp.tokens && (src[-1].flags & PASTE_LEFT)))
	  total += arg->count - 1;
	else
	  {
	    if (!arg->expanded)
	      expand_arg (pfile, arg);
	    total += arg->expanded_count - 1;
	  }
      }

  /* When the compiler is called with the -ftrack-macro-expansion
     flag, we need to keep track of the location of each token that
     results from macro expansion.

     A token resulting from macro expansion is not a new token. It is
     simply the same token as the token coming from the macro
     definition.  The new things that are allocated are the buffer
     that holds the tokens resulting from macro expansion and a new
     location that records many things like the locus of the expansion
     point as well as the original locus inside the definition of the
     macro.  This location is called a virtual location.

     So the buffer BUFF holds a set of cpp_token*, and the buffer
     VIRT_LOCS holds the virtual locations of the tokens held by BUFF.

     Both of these two buffers are going to be hung off of the macro
     context, when the latter is pushed.  The memory allocated to
     store the tokens and their locations is going to be freed once
     the context of macro expansion is popped.

     As far as tokens are concerned, the memory overhead of
     -ftrack-macro-expansion is proportional to the number of
     macros that get expanded multiplied by sizeof (location_t).
     The good news is that extra memory gets freed when the macro
     context is freed, i.e shortly after the macro got expanded.  */

  /* Is the -ftrack-macro-expansion flag in effect?  */
  track_macro_exp = CPP_OPTION (pfile, track_macro_expansion);

  /* Now allocate memory space for tokens and locations resulting from
     the macro expansion, copy the tokens and replace the arguments.
     This memory must be freed when the context of the macro MACRO is
     popped.  */
  buff = tokens_buff_new (pfile, total, track_macro_exp ? &virt_locs : NULL);

  first = (const cpp_token **) buff->base;

  /* Create a macro map to record the locations of the tokens that are
     involved in the expansion.  Note that the expansion point is set
     to the location of the closing parenthesis.  Otherwise, the
     subsequent map created for the first token that comes after the
     macro map might have a wrong line number.  That would lead to
     tokens with wrong line numbers after the macro expansion.  This
     adds up to the memory overhead of the -ftrack-macro-expansion
     flag; for every macro that is expanded, a "macro map" is
     created.  */
  if (track_macro_exp)
    {
      int num_macro_tokens = total;
      if (track_macro_exp < 2)
	/* Then the number of macro tokens won't take in account the
	   fact that function-like macro arguments can expand to
	   multiple tokens. This is to save memory at the expense of
	   accuracy.

	   Suppose we have #define SQUARE(A) A * A

	   And then we do SQUARE(2+3)

	   Then the tokens 2, +, 3, will have the same location,
	   saying they come from the expansion of the argument A.  */
	num_macro_tokens = exp_count;
      map = linemap_enter_macro (pfile->line_table, node,
				 expansion_point_loc,
				 num_macro_tokens);
    }
  i = 0;
  vaopt_state vaopt_tracker (pfile, macro->variadic, &args[macro->paramc - 1]);
  const cpp_token **vaopt_start = NULL;
  for (src = macro->exp.tokens; src < limit; src++)
    {
      unsigned int arg_tokens_count;
      macro_arg_token_iter from;
      const cpp_token **paste_flag = NULL;
      const cpp_token **tmp_token_ptr;

      /* __VA_OPT__ handling.  */
      vaopt_state::update_type vostate = vaopt_tracker.update (src);
      if (__builtin_expect (vostate != vaopt_state::INCLUDE, false))
	{
	  if (vostate == vaopt_state::BEGIN)
	    {
	      /* Padding on the left of __VA_OPT__ (unless RHS of ##).  */
	      if (src != macro->exp.tokens && !(src[-1].flags & PASTE_LEFT))
		{
		  const cpp_token *t = padding_token (pfile, src);
		  unsigned index = expanded_token_index (pfile, macro, src, i);
		  /* Allocate a virtual location for the padding token and
		     append the token and its location to BUFF and
		     VIRT_LOCS.   */
		  tokens_buff_add_token (buff, virt_locs, t,
					 t->src_loc, t->src_loc,
					 map, index);
		}
	      vaopt_start = tokens_buff_last_token_ptr (buff);
	    }
	  else if (vostate == vaopt_state::END)
	    {
	      const cpp_token **start = vaopt_start;
	      vaopt_start = NULL;

	      paste_flag = tokens_buff_last_token_ptr (buff);

	      if (vaopt_tracker.stringify ())
		{
		  unsigned int count
		    = start ? paste_flag - start : tokens_buff_count (buff);
		  const cpp_token **first
		    = start ? start + 1
			    : (const cpp_token **) (buff->base);
		  unsigned int i, j;

		  /* Paste any tokens that need to be pasted before calling
		     stringify_arg, because stringify_arg uses pfile->u_buff
		     which paste_tokens can use as well.  */
		  for (i = 0, j = 0; i < count; i++, j++)
		    {
		      const cpp_token *token = first[i];

		      if (token->flags & PASTE_LEFT)
			{
			  location_t virt_loc = pfile->invocation_location;
			  const cpp_token *rhs;
			  do
			    {
			      if (i == count)
				abort ();
			      rhs = first[++i];
			      if (!paste_tokens (pfile, virt_loc, &token, rhs))
				{
				  --i;
				  break;
				}
			    }
			  while (rhs->flags & PASTE_LEFT);
			}

		      first[j] = token;
		    }
		  if (j != i)
		    {
		      while (i-- != j)
			tokens_buff_remove_last_token (buff);
		      count = j;
		    }

		  const cpp_token *t = stringify_arg (pfile, first, count);
		  while (count--)
		    tokens_buff_remove_last_token (buff);
		  if (src->flags & PASTE_LEFT)
		    copy_paste_flag (pfile, &t, src);
		  tokens_buff_add_token (buff, virt_locs,
					 t, t->src_loc, t->src_loc,
					 NULL, 0);
		  continue;
		}
	      if (start && paste_flag == start && (*start)->flags & PASTE_LEFT)
		/* If __VA_OPT__ expands to nothing (either because __VA_ARGS__
		   is empty or because it is __VA_OPT__() ), drop PASTE_LEFT
		   flag from previous token.  */
		copy_paste_flag (pfile, start, &pfile->avoid_paste);
	      if (src->flags & PASTE_LEFT)
		{
		  /* Don't avoid paste after all.  */
		  while (paste_flag && paste_flag != start
			 && *paste_flag == &pfile->avoid_paste)
		    {
		      tokens_buff_remove_last_token (buff);
		      paste_flag = tokens_buff_last_token_ptr (buff);
		    }

		  /* With a non-empty __VA_OPT__ on the LHS of ##, the last
		     token should be flagged PASTE_LEFT.  */
		  if (paste_flag && (*paste_flag)->type != CPP_PADDING)
		    copy_paste_flag (pfile, paste_flag, src);
		}
	      else
		{
		  /* Otherwise, avoid paste on RHS, __VA_OPT__(c)d or
		     __VA_OPT__(c)__VA_OPT__(d).  */
		  const cpp_token *t = &pfile->avoid_paste;
		  tokens_buff_add_token (buff, virt_locs,
					 t, t->src_loc, t->src_loc,
					 NULL, 0);
		}
	    }
	  continue;
	}

      if (src->type != CPP_MACRO_ARG)
	{
	  /* Allocate a virtual location for token SRC, and add that
	     token and its virtual location into the buffers BUFF and
	     VIRT_LOCS.  */
	  unsigned index = expanded_token_index (pfile, macro, src, i);
	  tokens_buff_add_token (buff, virt_locs, src,
				 src->src_loc, src->src_loc,
				 map, index);
	  i += 1;
	  continue;
	}

      paste_flag = 0;
      arg = &args[src->val.macro_arg.arg_no - 1];
      /* SRC is a macro parameter that we need to replace with its
	 corresponding argument.  So at some point we'll need to
	 iterate over the tokens of the macro argument and copy them
	 into the "place" now holding the correspondig macro
	 parameter.  We are going to use the iterator type
	 macro_argo_token_iter to handle that iterating.  The 'if'
	 below is to initialize the iterator depending on the type of
	 tokens the macro argument has.  It also does some adjustment
	 related to padding tokens and some pasting corner cases.  */
      if (src->flags & STRINGIFY_ARG)
	{
	  arg_tokens_count = 1;
	  macro_arg_token_iter_init (&from,
				     CPP_OPTION (pfile,
						 track_macro_expansion),
				     MACRO_ARG_TOKEN_STRINGIFIED,
				     arg, &arg->stringified);
	}
      else if (src->flags & PASTE_LEFT)
	{
	  arg_tokens_count = arg->count;
	  macro_arg_token_iter_init (&from,
				     CPP_OPTION (pfile,
						 track_macro_expansion),
				     MACRO_ARG_TOKEN_NORMAL,
				     arg, arg->first);
	}
      else if (src != macro->exp.tokens && (src[-1].flags & PASTE_LEFT))
	{
	  int num_toks;
	  arg_tokens_count = arg->count;
	  macro_arg_token_iter_init (&from,
				     CPP_OPTION (pfile,
						 track_macro_expansion),
				     MACRO_ARG_TOKEN_NORMAL,
				     arg, arg->first);

	  num_toks = tokens_buff_count (buff);

	  if (num_toks != 0)
	    {
	      /* So the current parameter token is pasted to the previous
		 token in the replacement list.  Let's look at what
		 we have as previous and current arguments.  */

	      /* This is the previous argument's token ...  */
	      tmp_token_ptr = tokens_buff_last_token_ptr (buff);

	      if ((*tmp_token_ptr)->type == CPP_COMMA
		  && macro->variadic
		  && src->val.macro_arg.arg_no == macro->paramc)
		{
		  /* ... which is a comma; and the current parameter
		     is the last parameter of a variadic function-like
		     macro.  If the argument to the current last
		     parameter is NULL, then swallow the comma,
		     otherwise drop the paste flag.  */
		  if (macro_arg_token_iter_get_token (&from) == NULL)
		    tokens_buff_remove_last_token (buff);
		  else
		    paste_flag = tmp_token_ptr;
		}
	      /* Remove the paste flag if the RHS is a placemarker.  */
	      else if (arg_tokens_count == 0)
		paste_flag = tmp_token_ptr;
	    }
	}
      else
	{
	  arg_tokens_count = arg->expanded_count;
	  macro_arg_token_iter_init (&from,
				     CPP_OPTION (pfile,
						 track_macro_expansion),
				     MACRO_ARG_TOKEN_EXPANDED,
				     arg, arg->expanded);

	  if (last_token_is (buff, vaopt_start))
	    {
	      /* We're expanding an arg at the beginning of __VA_OPT__.
		 Skip padding. */
	      while (arg_tokens_count)
		{
		  const cpp_token *t = macro_arg_token_iter_get_token (&from);
		  if (t->type != CPP_PADDING)
		    break;
		  macro_arg_token_iter_forward (&from);
		  --arg_tokens_count;
		}
	    }
	}

      /* Padding on the left of an argument (unless RHS of ##).  */
      if ((!pfile->state.in_directive || pfile->state.directive_wants_padding)
	  && src != macro->exp.tokens
	  && !(src[-1].flags & PASTE_LEFT)
	  && !last_token_is (buff, vaopt_start))
	{
	  const cpp_token *t = padding_token (pfile, src);
	  unsigned index = expanded_token_index (pfile, macro, src, i);
	  /* Allocate a virtual location for the padding token and
	     append the token and its location to BUFF and
	     VIRT_LOCS.   */
	  tokens_buff_add_token (buff, virt_locs, t,
				 t->src_loc, t->src_loc,
				 map, index);
	}

      if (arg_tokens_count)
	{
	  /* So now we've got the number of tokens that make up the
	     argument that is going to replace the current parameter
	     in the macro's replacement list.  */
	  unsigned int j;
	  for (j = 0; j < arg_tokens_count; ++j)
	    {
	      /* So if track_macro_exp is < 2, the user wants to
		 save extra memory while tracking macro expansion
		 locations.  So in that case here is what we do:

		 Suppose we have #define SQUARE(A) A * A

		 And then we do SQUARE(2+3)

		 Then the tokens 2, +, 3, will have the same location,
		 saying they come from the expansion of the argument
		 A.

	      So that means we are going to ignore the COUNT tokens
	      resulting from the expansion of the current macro
	      argument. In other words all the ARG_TOKENS_COUNT tokens
	      resulting from the expansion of the macro argument will
	      have the index I.  Normally, each of those tokens should
	      have index I+J.  */
	      unsigned token_index = i;
	      unsigned index;
	      if (track_macro_exp > 1)
		token_index += j;

	      index = expanded_token_index (pfile, macro, src, token_index);
	      const cpp_token *tok = macro_arg_token_iter_get_token (&from);
	      tokens_buff_add_token (buff, virt_locs, tok,
				     macro_arg_token_iter_get_location (&from),
				     src->src_loc, map, index);
	      macro_arg_token_iter_forward (&from);
	    }

	  /* With a non-empty argument on the LHS of ##, the last
	     token should be flagged PASTE_LEFT.  */
	  if (src->flags & PASTE_LEFT)
	    paste_flag
	      = (const cpp_token **) tokens_buff_last_token_ptr (buff);
	}
      else if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, c99)
	       && ! macro->syshdr && ! _cpp_in_system_header (pfile))
	{
	  if (CPP_OPTION (pfile, cplusplus))
	    cpp_pedwarning (pfile, CPP_W_VARIADIC_MACROS,
			    "invoking macro %s argument %d: "
			    "empty macro arguments are undefined"
			    " in ISO C++98",
			    NODE_NAME (node), src->val.macro_arg.arg_no);
	  else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat))
	    cpp_pedwarning (pfile,
			    CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0
			    ? CPP_W_C90_C99_COMPAT : CPP_W_PEDANTIC,
			    "invoking macro %s argument %d: "
			    "empty macro arguments are undefined"
			    " in ISO C90",
			    NODE_NAME (node), src->val.macro_arg.arg_no);
	}
      else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0
	       && ! CPP_OPTION (pfile, cplusplus)
	       && ! macro->syshdr && ! _cpp_in_system_header (pfile))
	cpp_warning (pfile, CPP_W_C90_C99_COMPAT,
		     "invoking macro %s argument %d: "
		     "empty macro arguments are undefined"
		     " in ISO C90",
		     NODE_NAME (node), src->val.macro_arg.arg_no);

      /* Avoid paste on RHS (even case count == 0).  */
      if (!pfile->state.in_directive && !(src->flags & PASTE_LEFT))
	{
	  const cpp_token *t = &pfile->avoid_paste;
	  tokens_buff_add_token (buff, virt_locs,
				 t, t->src_loc, t->src_loc,
				 NULL, 0);
	}

      /* Add a new paste flag, or remove an unwanted one.  */
      if (paste_flag)
	copy_paste_flag (pfile, paste_flag, src);

      i += arg_tokens_count;
    }

  if (track_macro_exp)
    push_extended_tokens_context (pfile, node, buff, virt_locs, first,
				  tokens_buff_count (buff));
  else
    push_ptoken_context (pfile, node, buff, first,
			 tokens_buff_count (buff));

  num_macro_tokens_counter += tokens_buff_count (buff);
}

/* Return a special padding token, with padding inherited from SOURCE.  */
static const cpp_token *
padding_token (cpp_reader *pfile, const cpp_token *source)
{
  cpp_token *result = _cpp_temp_token (pfile);

  result->type = CPP_PADDING;

  /* Data in GCed data structures cannot be made const so far, so we
     need a cast here.  */
  result->val.source = (cpp_token *) source;
  result->flags = 0;
  return result;
}

/* Get a new uninitialized context.  Create a new one if we cannot
   re-use an old one.  */
static cpp_context *
next_context (cpp_reader *pfile)
{
  cpp_context *result = pfile->context->next;

  if (result == 0)
    {
      result = XNEW (cpp_context);
      memset (result, 0, sizeof (cpp_context));
      result->prev = pfile->context;
      result->next = 0;
      pfile->context->next = result;
    }

  pfile->context = result;
  return result;
}

/* Push a list of pointers to tokens.  */
static void
push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff,
		     const cpp_token **first, unsigned int count)
{
  cpp_context *context = next_context (pfile);

  context->tokens_kind = TOKENS_KIND_INDIRECT;
  context->c.macro = macro;
  context->buff = buff;
  FIRST (context).ptoken = first;
  LAST (context).ptoken = first + count;
}

/* Push a list of tokens.

   A NULL macro means that we should continue the current macro
   expansion, in essence.  That means that if we are currently in a
   macro expansion context, we'll make the new pfile->context refer to
   the current macro.  */
void
_cpp_push_token_context (cpp_reader *pfile, cpp_hashnode *macro,
			 const cpp_token *first, unsigned int count)
{
  cpp_context *context;

   if (macro == NULL)
     macro = macro_of_context (pfile->context);

   context = next_context (pfile);
   context->tokens_kind = TOKENS_KIND_DIRECT;
   context->c.macro = macro;
   context->buff = NULL;
   FIRST (context).token = first;
   LAST (context).token = first + count;
}

/* Build a context containing a list of tokens as well as their
   virtual locations and push it.  TOKENS_BUFF is the buffer that
   contains the tokens pointed to by FIRST.  If TOKENS_BUFF is
   non-NULL, it means that the context owns it, meaning that
   _cpp_pop_context will free it as well as VIRT_LOCS_BUFF that
   contains the virtual locations.

   A NULL macro means that we should continue the current macro
   expansion, in essence.  That means that if we are currently in a
   macro expansion context, we'll make the new pfile->context refer to
   the current macro.  */
static void
push_extended_tokens_context (cpp_reader *pfile,
			      cpp_hashnode *macro,
			      _cpp_buff *token_buff,
			      location_t *virt_locs,
			      const cpp_token **first,
			      unsigned int count)
{
  cpp_context *context;
  macro_context *m;

  if (macro == NULL)
    macro = macro_of_context (pfile->context);

  context = next_context (pfile);
  context->tokens_kind = TOKENS_KIND_EXTENDED;
  context->buff = token_buff;

  m = XNEW (macro_context);
  m->macro_node = macro;
  m->virt_locs = virt_locs;
  m->cur_virt_loc = virt_locs;
  context->c.mc = m;
  FIRST (context).ptoken = first;
  LAST (context).ptoken = first + count;
}

/* Push a traditional macro's replacement text.  */
void
_cpp_push_text_context (cpp_reader *pfile, cpp_hashnode *macro,
			const uchar *start, size_t len)
{
  cpp_context *context = next_context (pfile);

  context->tokens_kind = TOKENS_KIND_DIRECT;
  context->c.macro = macro;
  context->buff = NULL;
  CUR (context) = start;
  RLIMIT (context) = start + len;
  macro->flags |= NODE_DISABLED;
}

/* Creates a buffer that holds tokens a.k.a "token buffer", usually
   for the purpose of storing them on a cpp_context. If VIRT_LOCS is
   non-null (which means that -ftrack-macro-expansion is on),
   *VIRT_LOCS is set to a newly allocated buffer that is supposed to
   hold the virtual locations of the tokens resulting from macro
   expansion.  */
static _cpp_buff*
tokens_buff_new (cpp_reader *pfile, size_t len,
		 location_t **virt_locs)
{
  size_t tokens_size = len * sizeof (cpp_token *);
  if (virt_locs != NULL)
    *virt_locs = XNEWVEC (location_t, len);
  return _cpp_get_buff (pfile, tokens_size);
}

/* Returns the number of tokens contained in a token buffer.  The
   buffer holds a set of cpp_token*.  */
static size_t
tokens_buff_count (_cpp_buff *buff)
{
  return (BUFF_FRONT (buff) - buff->base) / sizeof (cpp_token *);
}

/* Return a pointer to the last token contained in the token buffer
   BUFF.  */
static const cpp_token **
tokens_buff_last_token_ptr (_cpp_buff *buff)
{
  if (BUFF_FRONT (buff) == buff->base)
    return NULL;
  return &((const cpp_token **) BUFF_FRONT (buff))[-1];
}

/* Remove the last token contained in the token buffer TOKENS_BUFF.
   If VIRT_LOCS_BUFF is non-NULL,  it should point at the buffer
   containing the virtual locations of the tokens in TOKENS_BUFF; in
   which case the function updates that buffer as well.   */
static inline void
tokens_buff_remove_last_token (_cpp_buff *tokens_buff)

{
  if (BUFF_FRONT (tokens_buff) > tokens_buff->base)
    BUFF_FRONT (tokens_buff) =
      (unsigned char *) &((cpp_token **) BUFF_FRONT (tokens_buff))[-1];
}

/* Insert a token into the token buffer at the position pointed to by
   DEST.  Note that the buffer is not enlarged so the previous token
   that was at *DEST is overwritten.  VIRT_LOC_DEST, if non-null,
   means -ftrack-macro-expansion is effect; it then points to where to
   insert the virtual location of TOKEN.  TOKEN is the token to
   insert.  VIRT_LOC is the virtual location of the token, i.e, the
   location possibly encoding its locus across macro expansion.  If
   TOKEN is an argument of a function-like macro (inside a macro
   replacement list), PARM_DEF_LOC is the spelling location of the
   macro parameter that TOKEN is replacing, in the replacement list of
   the macro.  If TOKEN is not an argument of a function-like macro or
   if it doesn't come from a macro expansion, then VIRT_LOC can just
   be set to the same value as PARM_DEF_LOC.  If MAP is non null, it
   means TOKEN comes from a macro expansion and MAP is the macro map
   associated to the macro.  MACRO_TOKEN_INDEX points to the index of
   the token in the macro map; it is not considered if MAP is NULL.

   Upon successful completion this function returns the a pointer to
   the position of the token coming right after the insertion
   point.  */
static inline const cpp_token **
tokens_buff_put_token_to (const cpp_token **dest,
			  location_t *virt_loc_dest,
			  const cpp_token *token,
			  location_t virt_loc,
			  location_t parm_def_loc,
			  const line_map_macro *map,
			  unsigned int macro_token_index)
{
  location_t macro_loc = virt_loc;
  const cpp_token **result;

  if (virt_loc_dest)
    {
      /* -ftrack-macro-expansion is on.  */
      if (map)
	macro_loc = linemap_add_macro_token (map, macro_token_index,
					     virt_loc, parm_def_loc);
      *virt_loc_dest = macro_loc;
    }
  *dest = token;
  result = &dest[1];

  return result;
}

/* Adds a token at the end of the tokens contained in BUFFER.  Note
   that this function doesn't enlarge BUFFER when the number of tokens
   reaches BUFFER's size; it aborts in that situation.

   TOKEN is the token to append. VIRT_LOC is the virtual location of
   the token, i.e, the location possibly encoding its locus across
   macro expansion. If TOKEN is an argument of a function-like macro
   (inside a macro replacement list), PARM_DEF_LOC is the location of
   the macro parameter that TOKEN is replacing.  If TOKEN doesn't come
   from a macro expansion, then VIRT_LOC can just be set to the same
   value as PARM_DEF_LOC.  If MAP is non null, it means TOKEN comes
   from a macro expansion and MAP is the macro map associated to the
   macro.  MACRO_TOKEN_INDEX points to the index of the token in the
   macro map; It is not considered if MAP is NULL.  If VIRT_LOCS is
   non-null, it means -ftrack-macro-expansion is on; in which case
   this function adds the virtual location DEF_LOC to the VIRT_LOCS
   array, at the same index as the one of TOKEN in BUFFER.  Upon
   successful completion this function returns the a pointer to the
   position of the token coming right after the insertion point.  */
static const cpp_token **
tokens_buff_add_token (_cpp_buff *buffer,
		       location_t *virt_locs,
		       const cpp_token *token,
		       location_t virt_loc,
		       location_t parm_def_loc,
		       const line_map_macro *map,
		       unsigned int macro_token_index)
{
  const cpp_token **result;
  location_t *virt_loc_dest = NULL;
  unsigned token_index =
    (BUFF_FRONT (buffer) - buffer->base) / sizeof (cpp_token *);

  /* Abort if we pass the end the buffer.  */
  if (BUFF_FRONT (buffer) > BUFF_LIMIT (buffer))
    abort ();

  if (virt_locs != NULL)
    virt_loc_dest = &virt_locs[token_index];

  result =
    tokens_buff_put_token_to ((const cpp_token **) BUFF_FRONT (buffer),
			      virt_loc_dest, token, virt_loc, parm_def_loc,
			      map, macro_token_index);

  BUFF_FRONT (buffer) = (unsigned char *) result;
  return result;
}

/* Allocate space for the function-like macro argument ARG to store
   the tokens resulting from the macro-expansion of the tokens that
   make up ARG itself. That space is allocated in ARG->expanded and
   needs to be freed using free.  */
static void
alloc_expanded_arg_mem (cpp_reader *pfile, macro_arg *arg, size_t capacity)
{
  gcc_checking_assert (arg->expanded == NULL
		       && arg->expanded_virt_locs == NULL);

  arg->expanded = XNEWVEC (const cpp_token *, capacity);
  if (CPP_OPTION (pfile, track_macro_expansion))
    arg->expanded_virt_locs = XNEWVEC (location_t, capacity);

}

/* If necessary, enlarge ARG->expanded to so that it can contain SIZE
   tokens.  */
static void
ensure_expanded_arg_room (cpp_reader *pfile, macro_arg *arg,
			  size_t size, size_t *expanded_capacity)
{
  if (size <= *expanded_capacity)
    return;

  size *= 2;

  arg->expanded =
    XRESIZEVEC (const cpp_token *, arg->expanded, size);
  *expanded_capacity = size;

  if (CPP_OPTION (pfile, track_macro_expansion))
    {
      if (arg->expanded_virt_locs == NULL)
	arg->expanded_virt_locs = XNEWVEC (location_t, size);
      else
	arg->expanded_virt_locs = XRESIZEVEC (location_t,
					      arg->expanded_virt_locs,
					      size);
    }
}

/* Expand an argument ARG before replacing parameters in a
   function-like macro.  This works by pushing a context with the
   argument's tokens, and then expanding that into a temporary buffer
   as if it were a normal part of the token stream.  collect_args()
   has terminated the argument's tokens with a CPP_EOF so that we know
   when we have fully expanded the argument.  */
static void
expand_arg (cpp_reader *pfile, macro_arg *arg)
{
  size_t capacity;
  bool saved_warn_trad;
  bool track_macro_exp_p = CPP_OPTION (pfile, track_macro_expansion);
  bool saved_ignore__Pragma;

  if (arg->count == 0
      || arg->expanded != NULL)
    return;

  /* Don't warn about funlike macros when pre-expanding.  */
  saved_warn_trad = CPP_WTRADITIONAL (pfile);
  CPP_WTRADITIONAL (pfile) = 0;

  /* Loop, reading in the tokens of the argument.  */
  capacity = 256;
  alloc_expanded_arg_mem (pfile, arg, capacity);

  if (track_macro_exp_p)
    push_extended_tokens_context (pfile, NULL, NULL,
				  arg->virt_locs,
				  arg->first,
				  arg->count + 1);
  else
    push_ptoken_context (pfile, NULL, NULL,
			 arg->first, arg->count + 1);

  saved_ignore__Pragma = pfile->state.ignore__Pragma;
  pfile->state.ignore__Pragma = 1;

  for (;;)
    {
      const cpp_token *token;
      location_t location;

      ensure_expanded_arg_room (pfile, arg, arg->expanded_count + 1,
				&capacity);

      token = cpp_get_token_1 (pfile, &location);

      if (token->type == CPP_EOF)
	break;

      set_arg_token (arg, token, location,
		     arg->expanded_count, MACRO_ARG_TOKEN_EXPANDED,
		     CPP_OPTION (pfile, track_macro_expansion));
      arg->expanded_count++;
    }

  _cpp_pop_context (pfile);

  CPP_WTRADITIONAL (pfile) = saved_warn_trad;
  pfile->state.ignore__Pragma = saved_ignore__Pragma;
}

/* Returns the macro associated to the current context if we are in
   the context a macro expansion, NULL otherwise.  */
static cpp_hashnode*
macro_of_context (cpp_context *context)
{
  if (context == NULL)
    return NULL;

  return (context->tokens_kind == TOKENS_KIND_EXTENDED)
    ? context->c.mc->macro_node
    : context->c.macro;
}

/* Return TRUE iff we are expanding a macro or are about to start
   expanding one.  If we are effectively expanding a macro, the
   function macro_of_context returns a pointer to the macro being
   expanded.  */
static bool
in_macro_expansion_p (cpp_reader *pfile)
{
  if (pfile == NULL)
    return false;

  return (pfile->about_to_expand_macro_p
	  || macro_of_context (pfile->context));
}

/* Pop the current context off the stack, re-enabling the macro if the
   context represented a macro's replacement list.  Initially the
   context structure was not freed so that we can re-use it later, but
   now we do free it to reduce peak memory consumption.  */
void
_cpp_pop_context (cpp_reader *pfile)
{
  cpp_context *context = pfile->context;

  /* We should not be popping the base context.  */
  gcc_assert (context != &pfile->base_context);

  if (context->c.macro)
    {
      cpp_hashnode *macro;
      if (context->tokens_kind == TOKENS_KIND_EXTENDED)
	{
	  macro_context *mc = context->c.mc;
	  macro = mc->macro_node;
	  /* If context->buff is set, it means the life time of tokens
	     is bound to the life time of this context; so we must
	     free the tokens; that means we must free the virtual
	     locations of these tokens too.  */
	  if (context->buff && mc->virt_locs)
	    {
	      free (mc->virt_locs);
	      mc->virt_locs = NULL;
	    }
	  free (mc);
	  context->c.mc = NULL;
	}
      else
	macro = context->c.macro;

      /* Beware that MACRO can be NULL in cases like when we are
	 called from expand_arg.  In those cases, a dummy context with
	 tokens is pushed just for the purpose of walking them using
	 cpp_get_token_1.  In that case, no 'macro' field is set into
	 the dummy context.  */
      if (macro != NULL
	  /* Several contiguous macro expansion contexts can be
	     associated to the same macro; that means it's the same
	     macro expansion that spans across all these (sub)
	     contexts.  So we should re-enable an expansion-disabled
	     macro only when we are sure we are really out of that
	     macro expansion.  */
	  && macro_of_context (context->prev) != macro)
	macro->flags &= ~NODE_DISABLED;

      if (macro == pfile->top_most_macro_node && context->prev == NULL)
	/* We are popping the context of the top-most macro node.  */
	pfile->top_most_macro_node = NULL;
    }

  if (context->buff)
    {
      /* Decrease memory peak consumption by freeing the memory used
	 by the context.  */
      _cpp_free_buff (context->buff);
    }

  pfile->context = context->prev;
  /* Decrease peak memory consumption by freeing the context.  */
  pfile->context->next = NULL;
  free (context);
}

/* Return TRUE if we reached the end of the set of tokens stored in
   CONTEXT, FALSE otherwise.  */
static inline bool
reached_end_of_context (cpp_context *context)
{
  if (context->tokens_kind == TOKENS_KIND_DIRECT)
      return FIRST (context).token == LAST (context).token;
  else if (context->tokens_kind == TOKENS_KIND_INDIRECT
	   || context->tokens_kind == TOKENS_KIND_EXTENDED)
    return FIRST (context).ptoken == LAST (context).ptoken;
  else
    abort ();
}

/* Consume the next token contained in the current context of PFILE,
   and return it in *TOKEN. It's "full location" is returned in
   *LOCATION. If -ftrack-macro-location is in effeect, fFull location"
   means the location encoding the locus of the token across macro
   expansion; otherwise it's just is the "normal" location of the
   token which (*TOKEN)->src_loc.  */
static inline void
consume_next_token_from_context (cpp_reader *pfile,
				 const cpp_token ** token,
				 location_t *location)
{
  cpp_context *c = pfile->context;

  if ((c)->tokens_kind == TOKENS_KIND_DIRECT)
    {
      *token = FIRST (c).token;
      *location = (*token)->src_loc;
      FIRST (c).token++;
    }
  else if ((c)->tokens_kind == TOKENS_KIND_INDIRECT)
    {
      *token = *FIRST (c).ptoken;
      *location = (*token)->src_loc;
      FIRST (c).ptoken++;
    }
  else if ((c)->tokens_kind == TOKENS_KIND_EXTENDED)
    {
      macro_context *m = c->c.mc;
      *token = *FIRST (c).ptoken;
      if (m->virt_locs)
	{
	  *location = *m->cur_virt_loc;
	  m->cur_virt_loc++;
	}
      else
	*location = (*token)->src_loc;
      FIRST (c).ptoken++;
    }
  else
    abort ();
}

/* In the traditional mode of the preprocessor, if we are currently in
   a directive, the location of a token must be the location of the
   start of the directive line.  This function returns the proper
   location if we are in the traditional mode, and just returns
   LOCATION otherwise.  */

static inline location_t
maybe_adjust_loc_for_trad_cpp (cpp_reader *pfile, location_t location)
{
  if (CPP_OPTION (pfile, traditional))
    {
      if (pfile->state.in_directive)
	return pfile->directive_line;
    }
  return location;
}

/* Routine to get a token as well as its location.

   Macro expansions and directives are transparently handled,
   including entering included files.  Thus tokens are post-macro
   expansion, and after any intervening directives.  External callers
   see CPP_EOF only at EOF.  Internal callers also see it when meeting
   a directive inside a macro call, when at the end of a directive and
   state.in_directive is still 1, and at the end of argument
   pre-expansion.

   LOC is an out parameter; *LOC is set to the location "as expected
   by the user".  Please read the comment of
   cpp_get_token_with_location to learn more about the meaning of this
   location.  */
static const cpp_token*
cpp_get_token_1 (cpp_reader *pfile, location_t *location)
{
  const cpp_token *result;
  /* This token is a virtual token that either encodes a location
     related to macro expansion or a spelling location.  */
  location_t virt_loc = 0;
  /* pfile->about_to_expand_macro_p can be overriden by indirect calls
     to functions that push macro contexts.  So let's save it so that
     we can restore it when we are about to leave this routine.  */
  bool saved_about_to_expand_macro = pfile->about_to_expand_macro_p;

  for (;;)
    {
      cpp_hashnode *node;
      cpp_context *context = pfile->context;

      /* Context->prev == 0 <=> base context.  */
      if (!context->prev)
	{
	  result = _cpp_lex_token (pfile);
	  virt_loc = result->src_loc;
	}
      else if (!reached_end_of_context (context))
	{
	  consume_next_token_from_context (pfile, &result,
					   &virt_loc);
	  if (result->flags & PASTE_LEFT)
	    {
	      paste_all_tokens (pfile, result);
	      if (pfile->state.in_directive)
		continue;
	      result = padding_token (pfile, result);
	      goto out;
	    }
	}
      else
	{
	  if (pfile->context->c.macro)
	    ++num_expanded_macros_counter;
	  _cpp_pop_context (pfile);
	  if (pfile->state.in_directive)
	    continue;
	  result = &pfile->avoid_paste;
	  goto out;
	}

      if (pfile->state.in_directive && result->type == CPP_COMMENT)
	continue;

      if (result->type != CPP_NAME)
	break;

      node = result->val.node.node;

      if (node->type == NT_VOID || (result->flags & NO_EXPAND))
	break;

      if (!(node->flags & NODE_USED)
	  && node->type == NT_USER_MACRO
	  && !node->value.macro
	  && !cpp_get_deferred_macro (pfile, node, result->src_loc))
	break;

      if (!(node->flags & NODE_DISABLED))
	{
	  int ret = 0;
	  /* If not in a macro context, and we're going to start an
	     expansion, record the location and the top level macro
	     about to be expanded.  */
	  if (!in_macro_expansion_p (pfile))
	    {
	      pfile->invocation_location = result->src_loc;
	      pfile->top_most_macro_node = node;
	    }
	  if (pfile->state.prevent_expansion)
	    break;

	  if ((result->flags & NO_DOT_COLON) != 0)
	    pfile->diagnose_dot_colon_from_macro_p = true;

	  /* Conditional macros require that a predicate be evaluated
	     first.  */
	  if ((node->flags & NODE_CONDITIONAL) != 0)
	    {
	      if (pfile->cb.macro_to_expand)
		{
		  bool whitespace_after;
		  const cpp_token *peek_tok = cpp_peek_token (pfile, 0);

		  whitespace_after = (peek_tok->type == CPP_PADDING
				      || (peek_tok->flags & PREV_WHITE));
		  node = pfile->cb.macro_to_expand (pfile, result);
		  if (node)
		    ret = enter_macro_context (pfile, node, result, virt_loc);
		  else if (whitespace_after)
		    {
		      /* If macro_to_expand hook returned NULL and it
			 ate some tokens, see if we don't need to add
			 a padding token in between this and the
			 next token.  */
		      peek_tok = cpp_peek_token (pfile, 0);
		      if (peek_tok->type != CPP_PADDING
			  && (peek_tok->flags & PREV_WHITE) == 0)
			_cpp_push_token_context (pfile, NULL,
						 padding_token (pfile,
								peek_tok), 1);
		    }
		}
	    }
	  else
	    ret = enter_macro_context (pfile, node, result, virt_loc);
	  if (ret)
 	    {
	      if (pfile->state.in_directive || ret == 2)
		continue;
	      result = padding_token (pfile, result);
	      goto out;
	    }
	}
      else
	{
	  /* Flag this token as always unexpandable.  FIXME: move this
	     to collect_args()?.  */
	  cpp_token *t = _cpp_temp_token (pfile);
	  t->type = result->type;
	  t->flags = result->flags | NO_EXPAND;
	  t->val = result->val;
	  result = t;
	}

      break;
    }

 out:
  if (location != NULL)
    {
      if (virt_loc == 0)
	virt_loc = result->src_loc;
      *location = virt_loc;

      if (!CPP_OPTION (pfile, track_macro_expansion)
	  && macro_of_context (pfile->context) != NULL)
	/* We are in a macro expansion context, are not tracking
	   virtual location, but were asked to report the location
	   of the expansion point of the macro being expanded.  */
	*location = pfile->invocation_location;

      *location = maybe_adjust_loc_for_trad_cpp (pfile, *location);
    }

  pfile->about_to_expand_macro_p = saved_about_to_expand_macro;

  if (pfile->state.directive_file_token
      && !pfile->state.parsing_args
      && !(result->type == CPP_PADDING || result->type == CPP_COMMENT)
      && !(15 & --pfile->state.directive_file_token))
    {
      /* Do header-name frobbery.  Concatenate < ... > as approprate.
	 Do header search if needed, and finally drop the outer <> or
	 "".  */
      pfile->state.angled_headers = false;

      /* Do angle-header reconstitution.  Then do include searching.
	 We'll always end up with a ""-quoted header-name in that
	 case.  If searching finds nothing, we emit a diagnostic and
	 an empty string.  */
      size_t len = 0;
      char *fname = NULL;

      cpp_token *tmp = _cpp_temp_token (pfile);
      *tmp = *result;

      tmp->type = CPP_HEADER_NAME;
      bool need_search = !pfile->state.directive_file_token;
      pfile->state.directive_file_token = 0;

      bool angle = result->type != CPP_STRING;
      if (result->type == CPP_HEADER_NAME
	  || (result->type == CPP_STRING && result->val.str.text[0] != 'R'))
	{
	  len = result->val.str.len - 2;
	  fname = XNEWVEC (char, len + 1);
	  memcpy (fname, result->val.str.text + 1, len);
	  fname[len] = 0;
	}
      else if (result->type == CPP_LESS)
	fname = _cpp_bracket_include (pfile);

      if (fname)
	{
	  /* We have a header-name.  Look it up.  This will emit an
	     unfound diagnostic.  Canonicalize the found name.  */
	  const char *found = fname;

	  if (need_search)
	    {
	      found = _cpp_find_header_unit (pfile, fname, angle, tmp->src_loc);
	      if (!found)
		found = "";
	      len = strlen (found);
	    }
	  /* Force a leading './' if it's not absolute.  */
	  bool dotme = (found[0] == '.' ? !IS_DIR_SEPARATOR (found[1])
			: found[0] && !IS_ABSOLUTE_PATH (found));

	  if (BUFF_ROOM (pfile->u_buff) < len + 1 + dotme * 2)
	    _cpp_extend_buff (pfile, &pfile->u_buff, len + 1 + dotme * 2);
	  unsigned char *buf = BUFF_FRONT (pfile->u_buff);
	  size_t pos = 0;

	  if (dotme)
	    {
	      buf[pos++] = '.';
	      /* Apparently '/' is unconditional.  */
	      buf[pos++] = '/';
	    }
	  memcpy (&buf[pos], found, len);
	  pos += len;
	  buf[pos] = 0;

	  tmp->val.str.len = pos;
	  tmp->val.str.text = buf;

	  tmp->type = CPP_HEADER_NAME;
	  XDELETEVEC (fname);

	  result = tmp;
	}
    }

  if (pfile->diagnose_dot_colon_from_macro_p
      && !pfile->about_to_expand_macro_p
      && result->type != CPP_PADDING
      && result->type != CPP_COMMENT)
    {
      if (result->type == CPP_DOT || result->type == CPP_COLON)
	cpp_error_with_line (pfile, CPP_DL_ERROR,
			     result->src_loc, 0,
			     "%qc in module name or partition "
			     "comes from or after macro expansion",
			     result->type == CPP_DOT ? '.' : ':');
      pfile->diagnose_dot_colon_from_macro_p = false;
    }

  return result;
}

/* External routine to get a token.  Also used nearly everywhere
   internally, except for places where we know we can safely call
   _cpp_lex_token directly, such as lexing a directive name.

   Macro expansions and directives are transparently handled,
   including entering included files.  Thus tokens are post-macro
   expansion, and after any intervening directives.  External callers
   see CPP_EOF only at EOF.  Internal callers also see it when meeting
   a directive inside a macro call, when at the end of a directive and
   state.in_directive is still 1, and at the end of argument
   pre-expansion.  */
const cpp_token *
cpp_get_token (cpp_reader *pfile)
{
  return cpp_get_token_1 (pfile, NULL);
}

/* Like cpp_get_token, but also returns a virtual token location
   separate from the spelling location carried by the returned token.

   LOC is an out parameter; *LOC is set to the location "as expected
   by the user".  This matters when a token results from macro
   expansion; in that case the token's spelling location indicates the
   locus of the token in the definition of the macro but *LOC
   virtually encodes all the other meaningful locuses associated to
   the token.

   What? virtual location? Yes, virtual location.

   If the token results from macro expansion and if macro expansion
   location tracking is enabled its virtual location encodes (at the
   same time):

   - the spelling location of the token

   - the locus of the macro expansion point

   - the locus of the point where the token got instantiated as part
     of the macro expansion process.

   You have to use the linemap API to get the locus you are interested
   in from a given virtual location.

   Note however that virtual locations are not necessarily ordered for
   relations '<' and '>'.  One must use the function
   linemap_location_before_p instead of using the relational operator
   '<'.

   If macro expansion tracking is off and if the token results from
   macro expansion the virtual location is the expansion point of the
   macro that got expanded.

   When the token doesn't result from macro expansion, the virtual
   location is just the same thing as its spelling location.  */

const cpp_token *
cpp_get_token_with_location (cpp_reader *pfile, location_t *loc)
{
  return cpp_get_token_1 (pfile, loc);
}

/* Returns true if we're expanding an object-like macro that was
   defined in a system header.  Just checks the macro at the top of
   the stack.  Used for diagnostic suppression.
   Also return true for builtin macros.  */
int
cpp_sys_macro_p (cpp_reader *pfile)
{
  cpp_hashnode *node = NULL;

  if (pfile->context->tokens_kind == TOKENS_KIND_EXTENDED)
    node = pfile->context->c.mc->macro_node;
  else
    node = pfile->context->c.macro;

  if (!node)
    return false;
  if (cpp_builtin_macro_p (node))
    return true;
  return node->value.macro && node->value.macro->syshdr;
}

/* Read each token in, until end of the current file.  Directives are
   transparently processed.  */
void
cpp_scan_nooutput (cpp_reader *pfile)
{
  /* Request a CPP_EOF token at the end of this file, rather than
     transparently continuing with the including file.  */
  pfile->buffer->return_at_eof = true;

  pfile->state.discarding_output++;
  pfile->state.prevent_expansion++;

  if (CPP_OPTION (pfile, traditional))
    while (_cpp_read_logical_line_trad (pfile))
      ;
  else
    while (cpp_get_token (pfile)->type != CPP_EOF)
      ;

  pfile->state.discarding_output--;
  pfile->state.prevent_expansion--;
}

/* Step back one or more tokens obtained from the lexer.  */
void
_cpp_backup_tokens_direct (cpp_reader *pfile, unsigned int count)
{
  pfile->lookaheads += count;
  while (count--)
    {
      pfile->cur_token--;
      if (pfile->cur_token == pfile->cur_run->base
          /* Possible with -fpreprocessed and no leading #line.  */
          && pfile->cur_run->prev != NULL)
        {
          pfile->cur_run = pfile->cur_run->prev;
          pfile->cur_token = pfile->cur_run->limit;
        }
    }
}

/* Step back one (or more) tokens.  Can only step back more than 1 if
   they are from the lexer, and not from macro expansion.  */
void
_cpp_backup_tokens (cpp_reader *pfile, unsigned int count)
{
  if (pfile->context->prev == NULL)
    _cpp_backup_tokens_direct (pfile, count);
  else
    {
      if (count != 1)
	abort ();
      if (pfile->context->tokens_kind == TOKENS_KIND_DIRECT)
	FIRST (pfile->context).token--;
      else if (pfile->context->tokens_kind == TOKENS_KIND_INDIRECT)
	FIRST (pfile->context).ptoken--;
      else if (pfile->context->tokens_kind == TOKENS_KIND_EXTENDED)
	{
	  FIRST (pfile->context).ptoken--;
	  if (pfile->context->c.macro)
	    {
	      macro_context *m = pfile->context->c.mc;
	      m->cur_virt_loc--;
	      gcc_checking_assert (m->cur_virt_loc >= m->virt_locs);
	    }
	  else
	    abort ();
	}
      else
	abort ();
    }
}

/* #define directive parsing and handling.  */

/* Returns true if a macro redefinition warning is required.  */
static bool
warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node,
		      const cpp_macro *macro2)
{
  /* Some redefinitions need to be warned about regardless.  */
  if (node->flags & NODE_WARN)
    return true;

  /* Suppress warnings for builtins that lack the NODE_WARN flag,
     unless Wbuiltin-macro-redefined.  */
  if (cpp_builtin_macro_p (node))
    return CPP_OPTION (pfile, warn_builtin_macro_redefined);

  /* Redefinitions of conditional (context-sensitive) macros, on
     the other hand, must be allowed silently.  */
  if (node->flags & NODE_CONDITIONAL)
    return false;

  if (cpp_macro *macro1 = get_deferred_or_lazy_macro (pfile, node, macro2->line))
    return cpp_compare_macros (macro1, macro2);
  return false;
}

/* Return TRUE if MACRO1 and MACRO2 differ.  */

bool
cpp_compare_macros (const cpp_macro *macro1, const cpp_macro *macro2)
{
  /* Redefinition of a macro is allowed if and only if the old and new
     definitions are the same.  (6.10.3 paragraph 2).  */

  /* Don't check count here as it can be different in valid
     traditional redefinitions with just whitespace differences.  */
  if (macro1->paramc != macro2->paramc
      || macro1->fun_like != macro2->fun_like
      || macro1->variadic != macro2->variadic)
    return true;

  /* Check parameter spellings.  */
  for (unsigned i = macro1->paramc; i--; )
    if (macro1->parm.params[i] != macro2->parm.params[i])
      return true;

  /* Check the replacement text or tokens.  */
  if (macro1->kind == cmk_traditional)
    return _cpp_expansions_different_trad (macro1, macro2);

  if (macro1->count != macro2->count)
    return true;

  for (unsigned i= macro1->count; i--; )
    if (!_cpp_equiv_tokens (&macro1->exp.tokens[i], &macro2->exp.tokens[i]))
      return true;

  return false;
}

/* Free the definition of hashnode H.  */
void
_cpp_free_definition (cpp_hashnode *h)
{
  /* Macros and assertions no longer have anything to free.  */
  h->type = NT_VOID;
  h->value.answers = NULL;
  h->flags &= ~(NODE_DISABLED | NODE_USED);
}

/* Save parameter NODE (spelling SPELLING) to the parameter list of
   macro MACRO.  Returns true on success, false on failure.   */
bool
_cpp_save_parameter (cpp_reader *pfile, unsigned n, cpp_hashnode *node,
		     cpp_hashnode *spelling)
{
  /* Constraint 6.10.3.6 - duplicate parameter names.  */
  if (node->type == NT_MACRO_ARG)
    {
      cpp_error (pfile, CPP_DL_ERROR, "duplicate macro parameter %qs",
		 NODE_NAME (node));
      return false;
    }

  unsigned len = (n + 1) * sizeof (struct macro_arg_saved_data);
  if (len > pfile->macro_buffer_len)
    {
      pfile->macro_buffer
	= XRESIZEVEC (unsigned char, pfile->macro_buffer, len);
      pfile->macro_buffer_len = len;
    }

  macro_arg_saved_data *saved = (macro_arg_saved_data *)pfile->macro_buffer;
  saved[n].canonical_node = node;
  saved[n].value = node->value;
  saved[n].type = node->type;

  void *base = _cpp_reserve_room (pfile, n * sizeof (cpp_hashnode *),
				  sizeof (cpp_hashnode *));
  ((cpp_hashnode **)base)[n] = spelling;

  /* Morph into a macro arg.  */
  node->type = NT_MACRO_ARG;
  /* Index is 1 based.  */
  node->value.arg_index = n + 1;

  return true;
}

/* Restore the parameters to their previous state.  */
void
_cpp_unsave_parameters (cpp_reader *pfile, unsigned n)
{
  /* Clear the fast argument lookup indices.  */
  while (n--)
    {
      struct macro_arg_saved_data *save =
	&((struct macro_arg_saved_data *) pfile->macro_buffer)[n];

      struct cpp_hashnode *node = save->canonical_node;
      node->type = save->type;
      node->value = save->value;
    }
}

/* Check the syntax of the parameters in a MACRO definition.  Return
   false on failure.  Set *N_PTR and *VARADIC_PTR as appropriate.
   '(' ')'
   '(' parm-list ',' last-parm ')'
   '(' last-parm ')'
   parm-list: name
            | parm-list, name
   last-parm: name
   	    | name '...'
            | '...'
*/

static bool
parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *variadic_ptr)
{
  unsigned nparms = 0;
  bool ok = false;

  for (bool prev_ident = false;;)
    {
      const cpp_token *token = _cpp_lex_token (pfile);

      switch (token->type)
	{
	case CPP_COMMENT:
	  /* Allow/ignore comments in parameter lists if we are
	     preserving comments in macro expansions.  */
	  if (!CPP_OPTION (pfile, discard_comments_in_macro_exp))
	    break;

	  /* FALLTHRU  */
	default:
	bad:
	  {
	    const char *const msgs[5] =
	      {
	       N_("expected parameter name, found %qs"),
	       N_("expected %<,%> or %<)%>, found %qs"),
	       N_("expected parameter name before end of line"),
	       N_("expected %<)%> before end of line"),
	       N_("expected %<)%> after %<...%>")
	      };
	    unsigned ix = prev_ident;
	    const unsigned char *as_text = NULL;
	    if (*variadic_ptr)
	      ix = 4;
	    else if (token->type == CPP_EOF)
	      ix += 2;
	    else
	      as_text = cpp_token_as_text (pfile, token);
	    cpp_error (pfile, CPP_DL_ERROR, msgs[ix], as_text);
	  }
	  goto out;

	case CPP_NAME:
	  if (prev_ident || *variadic_ptr)
	    goto bad;
	  prev_ident = true;

	  if (!_cpp_save_parameter (pfile, nparms, token->val.node.node,
				    token->val.node.spelling))
	    goto out;
	  nparms++;
	  break;

	case CPP_CLOSE_PAREN:
	  if (prev_ident || !nparms || *variadic_ptr)
	    {
	      ok = true;
	      goto out;
	    }

	  /* FALLTHRU */
	case CPP_COMMA:
	  if (!prev_ident || *variadic_ptr)
	    goto bad;
	  prev_ident = false;
	  break;

	case CPP_ELLIPSIS:
	  if (*variadic_ptr)
	    goto bad;
	  *variadic_ptr = true;
	  if (!prev_ident)
	    {
	      /* An ISO bare ellipsis.  */
	      if (!_cpp_save_parameter (pfile, nparms,
					pfile->spec_nodes.n__VA_ARGS__,
					pfile->spec_nodes.n__VA_ARGS__))
		goto out;
	      nparms++;
	      pfile->state.va_args_ok = 1;
	      if (! CPP_OPTION (pfile, c99)
		  && CPP_OPTION (pfile, cpp_pedantic)
		  && CPP_OPTION (pfile, warn_variadic_macros))
		cpp_pedwarning
		  (pfile, CPP_W_VARIADIC_MACROS,
		   CPP_OPTION (pfile, cplusplus)
		   ? N_("anonymous variadic macros were introduced in C++11")
		   : N_("anonymous variadic macros were introduced in C99"));
	      else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0
		       && ! CPP_OPTION (pfile, cplusplus))
		cpp_error (pfile, CPP_DL_WARNING,
			   "anonymous variadic macros were introduced in C99");
	    }
	  else if (CPP_OPTION (pfile, cpp_pedantic)
		   && CPP_OPTION (pfile, warn_variadic_macros))
	    cpp_pedwarning (pfile, CPP_W_VARIADIC_MACROS,
			    CPP_OPTION (pfile, cplusplus)
			    ? N_("ISO C++ does not permit named variadic macros")
			    : N_("ISO C does not permit named variadic macros"));
	  break;
	}
    }

 out:
  *n_ptr = nparms;

  return ok;
}

/* Lex a token from the expansion of MACRO, but mark parameters as we
   find them and warn of traditional stringification.  */
static cpp_macro *
lex_expansion_token (cpp_reader *pfile, cpp_macro *macro)
{
  macro = (cpp_macro *)_cpp_reserve_room (pfile,
					  sizeof (cpp_macro) - sizeof (cpp_token)
					  + macro->count * sizeof (cpp_token),
					  sizeof (cpp_token));
  cpp_token *saved_cur_token = pfile->cur_token;
  pfile->cur_token = &macro->exp.tokens[macro->count];
  cpp_token *token = _cpp_lex_direct (pfile);
  pfile->cur_token = saved_cur_token;

  /* Is this a parameter?  */
  if (token->type == CPP_NAME && token->val.node.node->type == NT_MACRO_ARG)
    {
      /* Morph into a parameter reference.  */
      cpp_hashnode *spelling = token->val.node.spelling;
      token->type = CPP_MACRO_ARG;
      token->val.macro_arg.arg_no = token->val.node.node->value.arg_index;
      token->val.macro_arg.spelling = spelling;
    }
  else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0
	   && (token->type == CPP_STRING || token->type == CPP_CHAR))
    check_trad_stringification (pfile, macro, &token->val.str);

  return macro;
}

static cpp_macro *
create_iso_definition (cpp_reader *pfile)
{
  bool following_paste_op = false;
  const char *paste_op_error_msg =
    N_("%<##%> cannot appear at either end of a macro expansion");
  unsigned int num_extra_tokens = 0;
  unsigned nparms = 0;
  cpp_hashnode **params = NULL;
  bool variadic = false;
  bool ok = false;
  cpp_macro *macro = NULL;

  /* Look at the first token, to see if this is a function-like
     macro.   */
  cpp_token first;
  cpp_token *saved_cur_token = pfile->cur_token;
  pfile->cur_token = &first;
  cpp_token *token = _cpp_lex_direct (pfile);
  pfile->cur_token = saved_cur_token;

  if (token->flags & PREV_WHITE)
    /* Preceeded by space, must be part of expansion.  */;
  else if (token->type == CPP_OPEN_PAREN)
    {
      /* An open-paren, get a parameter list.  */
      if (!parse_params (pfile, &nparms, &variadic))
	goto out;

      params = (cpp_hashnode **)_cpp_commit_buff
	(pfile, sizeof (cpp_hashnode *) * nparms);
      token = NULL;
    }
  else if (token->type != CPP_EOF
	   && !(token->type == CPP_COMMENT
		&& ! CPP_OPTION (pfile, discard_comments_in_macro_exp)))
    {
      /* While ISO C99 requires whitespace before replacement text
	 in a macro definition, ISO C90 with TC1 allows characters
	 from the basic source character set there.  */
      if (CPP_OPTION (pfile, c99))
	cpp_error (pfile, CPP_DL_PEDWARN,
		   CPP_OPTION (pfile, cplusplus)
		   ? N_("ISO C++11 requires whitespace after the macro name")
		   : N_("ISO C99 requires whitespace after the macro name"));
      else
	{
	  enum cpp_diagnostic_level warntype = CPP_DL_WARNING;
	  switch (token->type)
	    {
	    case CPP_ATSIGN:
	    case CPP_AT_NAME:
	    case CPP_OBJC_STRING:
	      /* '@' is not in basic character set.  */
	      warntype = CPP_DL_PEDWARN;
	      break;
	    case CPP_OTHER:
	      /* Basic character set sans letters, digits and _.  */
	      if (strchr ("!\"#%&'()*+,-./:;<=>?[\\]^{|}~",
			  token->val.str.text[0]) == NULL)
		warntype = CPP_DL_PEDWARN;
	      break;
	    default:
	      /* All other tokens start with a character from basic
		 character set.  */
	      break;
	    }
	  cpp_error (pfile, warntype,
		     "missing whitespace after the macro name");
	}
    }

  macro = _cpp_new_macro (pfile, cmk_macro,
			  _cpp_reserve_room (pfile, 0, sizeof (cpp_macro)));

  if (!token)
    {
      macro->variadic = variadic;
      macro->paramc = nparms;
      macro->parm.params = params;
      macro->fun_like = true;
    }
  else
    {
      /* Preserve the token we peeked, there is already a single slot for it.  */
      macro->exp.tokens[0] = *token;
      token = &macro->exp.tokens[0];
      macro->count = 1;
    }

  for (vaopt_state vaopt_tracker (pfile, macro->variadic, NULL);; token = NULL)
    {
      if (!token)
	{
	  macro = lex_expansion_token (pfile, macro);
	  token = &macro->exp.tokens[macro->count++];
	}

      /* Check the stringifying # constraint 6.10.3.2.1 of
	 function-like macros when lexing the subsequent token.  */
      if (macro->count > 1 && token[-1].type == CPP_HASH && macro->fun_like)
	{
	  if (token->type == CPP_MACRO_ARG
	      || (macro->variadic
		  && token->type == CPP_NAME
		  && token->val.node.node == pfile->spec_nodes.n__VA_OPT__))
	    {
	      if (token->flags & PREV_WHITE)
		token->flags |= SP_PREV_WHITE;
	      if (token[-1].flags & DIGRAPH)
		token->flags |= SP_DIGRAPH;
	      token->flags &= ~PREV_WHITE;
	      token->flags |= STRINGIFY_ARG;
	      token->flags |= token[-1].flags & PREV_WHITE;
	      token[-1] = token[0];
	      macro->count--;
	    }
	  /* Let assembler get away with murder.  */
	  else if (CPP_OPTION (pfile, lang) != CLK_ASM)
	    {
	      cpp_error (pfile, CPP_DL_ERROR,
			 "%<#%> is not followed by a macro parameter");
	      goto out;
	    }
	}

      if (token->type == CPP_EOF)
	{
	  /* Paste operator constraint 6.10.3.3.1:
	     Token-paste ##, can appear in both object-like and
	     function-like macros, but not at the end.  */
	  if (following_paste_op)
	    {
	      cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg);
	      goto out;
	    }
	  if (!vaopt_tracker.completed ())
	    goto out;
	  break;
	}

      /* Paste operator constraint 6.10.3.3.1.  */
      if (token->type == CPP_PASTE)
	{
	  /* Token-paste ##, can appear in both object-like and
	     function-like macros, but not at the beginning.  */
	  if (macro->count == 1)
	    {
	      cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg);
	      goto out;
	    }

	  if (following_paste_op)
	    {
	      /* Consecutive paste operators.  This one will be moved
		 to the end.  */
	      num_extra_tokens++;
	      token->val.token_no = macro->count - 1;
	    }
	  else
	    {
	      /* Drop the paste operator.  */
	      --macro->count;
	      token[-1].flags |= PASTE_LEFT;
	      if (token->flags & DIGRAPH)
		token[-1].flags |= SP_DIGRAPH;
	      if (token->flags & PREV_WHITE)
		token[-1].flags |= SP_PREV_WHITE;
	    }
	  following_paste_op = true;
	}
      else
	following_paste_op = false;

      if (vaopt_tracker.update (token) == vaopt_state::ERROR)
	goto out;
    }

  /* We're committed to winning now.  */
  ok = true;

  /* Don't count the CPP_EOF.  */
  macro->count--;

  macro = (cpp_macro *)_cpp_commit_buff
    (pfile, sizeof (cpp_macro) - sizeof (cpp_token)
     + sizeof (cpp_token) * macro->count);

  /* Clear whitespace on first token.  */
  if (macro->count)
    macro->exp.tokens[0].flags &= ~PREV_WHITE;

  if (num_extra_tokens)
    {
      /* Place second and subsequent ## or %:%: tokens in sequences of
	 consecutive such tokens at the end of the list to preserve
	 information about where they appear, how they are spelt and
	 whether they are preceded by whitespace without otherwise
	 interfering with macro expansion.   Remember, this is
	 extremely rare, so efficiency is not a priority.  */
      cpp_token *temp = (cpp_token *)_cpp_reserve_room
	(pfile, 0, num_extra_tokens * sizeof (cpp_token));
      unsigned extra_ix = 0, norm_ix = 0;
      cpp_token *exp = macro->exp.tokens;
      for (unsigned ix = 0; ix != macro->count; ix++)
	if (exp[ix].type == CPP_PASTE)
	  temp[extra_ix++] = exp[ix];
	else
	  exp[norm_ix++] = exp[ix];
      memcpy (&exp[norm_ix], temp, num_extra_tokens * sizeof (cpp_token));

      /* Record there are extra tokens.  */
      macro->extra_tokens = 1;
    }

 out:
  pfile->state.va_args_ok = 0;
  _cpp_unsave_parameters (pfile, nparms);

  return ok ? macro : NULL;
}

cpp_macro *
_cpp_new_macro (cpp_reader *pfile, cpp_macro_kind kind, void *placement)
{
  cpp_macro *macro = (cpp_macro *) placement;

  /* Zero init all the fields.  This'll tell the compiler know all the
     following inits are writing a virgin object.  */
  memset (macro, 0, offsetof (cpp_macro, exp));

  macro->line = pfile->directive_line;
  macro->parm.params = 0;
  macro->lazy = 0;
  macro->paramc = 0;
  macro->variadic = 0;
  macro->used = !CPP_OPTION (pfile, warn_unused_macros);
  macro->count = 0;
  macro->fun_like = 0;
  macro->imported_p = false;
  macro->extra_tokens = 0;
  /* To suppress some diagnostics.  */
  macro->syshdr = pfile->buffer && pfile->buffer->sysp != 0;

  macro->kind = kind;

  return macro;
}

/* Parse a macro and save its expansion.  Returns nonzero on success.  */
bool
_cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node,
			location_t name_loc)
{
  cpp_macro *macro;

  if (CPP_OPTION (pfile, traditional))
    macro = _cpp_create_trad_definition (pfile);
  else
    macro = create_iso_definition (pfile);

  if (!macro)
    return false;

  /* _cpp_new_macro () has set macro->line to pfile->directive_line, which
     denotes the line containing the #define with no column information.  If
     provided, change to name_loc, which will be the token src_loc for the
     macro name, including the location and range information.  */
  if (name_loc)
    macro->line = name_loc;

  if (cpp_macro_p (node))
    {
      if (CPP_OPTION (pfile, warn_unused_macros))
	_cpp_warn_if_unused_macro (pfile, node, NULL);

      if (warn_of_redefinition (pfile, node, macro))
	{
          const enum cpp_warning_reason reason
	    = (cpp_builtin_macro_p (node) && !(node->flags & NODE_WARN))
	    ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE;

	  bool warned
	    =  cpp_pedwarning_with_line (pfile, reason, macro->line, 0,
					 "%qs redefined", NODE_NAME (node));

	  if (warned && cpp_user_macro_p (node))
	    cpp_error_with_line (pfile, CPP_DL_NOTE, node->value.macro->line,
				 0, "this is the location of the previous "
				    "definition");
	}
      _cpp_free_definition (node);
    }

  /* Enter definition in hash table.  */
  node->type = NT_USER_MACRO;
  node->value.macro = macro;
  if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_"))
      && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_FORMAT_MACROS")
      /* __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS are mentioned
	 in the C standard, as something that one must use in C++.
	 However DR#593 and C++11 indicate that they play no role in C++.
	 We special-case them anyway.  */
      && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_LIMIT_MACROS")
      && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_CONSTANT_MACROS"))
    node->flags |= NODE_WARN;

  /* If user defines one of the conditional macros, remove the
     conditional flag */
  node->flags &= ~NODE_CONDITIONAL;

  return true;
}

extern void
cpp_define_lazily (cpp_reader *pfile, cpp_hashnode *node, unsigned num)
{
  cpp_macro *macro = node->value.macro;

  gcc_checking_assert (pfile->cb.user_lazy_macro && macro && num < UCHAR_MAX);

  macro->lazy = num + 1;
}

/* NODE is a deferred macro, resolve it, returning the definition
   (which may be NULL).  */
cpp_macro *
cpp_get_deferred_macro (cpp_reader *pfile, cpp_hashnode *node,
			location_t loc)
{
  gcc_checking_assert (node->type == NT_USER_MACRO);

  node->value.macro = pfile->cb.user_deferred_macro (pfile, loc, node);

  if (!node->value.macro)
    node->type = NT_VOID;

  return node->value.macro;
}

static cpp_macro *
get_deferred_or_lazy_macro (cpp_reader *pfile, cpp_hashnode *node,
			    location_t loc)
{
  cpp_macro *macro = node->value.macro;
  if (!macro)
    {
      macro = cpp_get_deferred_macro (pfile, node, loc);
      gcc_checking_assert (!macro || !macro->lazy);
    }
  else if (macro->lazy)
    {
      pfile->cb.user_lazy_macro (pfile, macro, macro->lazy - 1);
      macro->lazy = 0;
    }

  return macro;
}

/* Notify the use of NODE in a macro-aware context (i.e. expanding it,
   or testing its existance).  Also applies any lazy definition.
   Return FALSE if the macro isn't really there.  */

extern bool
_cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node,
		       location_t loc)
{
  node->flags |= NODE_USED;
  switch (node->type)
    {
    case NT_USER_MACRO:
      if (!get_deferred_or_lazy_macro (pfile, node, loc))
	return false;
      /* FALLTHROUGH.  */

    case NT_BUILTIN_MACRO:
      if (pfile->cb.used_define)
	pfile->cb.used_define (pfile, loc, node);
      break;

    case NT_VOID:
      if (pfile->cb.used_undef)
	pfile->cb.used_undef (pfile, loc, node);
      break;

    default:
      abort ();
    }

  return true;
}

/* Warn if a token in STRING matches one of a function-like MACRO's
   parameters.  */
static void
check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro,
			    const cpp_string *string)
{
  unsigned int i, len;
  const uchar *p, *q, *limit;

  /* Loop over the string.  */
  limit = string->text + string->len - 1;
  for (p = string->text + 1; p < limit; p = q)
    {
      /* Find the start of an identifier.  */
      while (p < limit && !is_idstart (*p))
	p++;

      /* Find the end of the identifier.  */
      q = p;
      while (q < limit && is_idchar (*q))
	q++;

      len = q - p;

      /* Loop over the function macro arguments to see if the
	 identifier inside the string matches one of them.  */
      for (i = 0; i < macro->paramc; i++)
	{
	  const cpp_hashnode *node = macro->parm.params[i];

	  if (NODE_LEN (node) == len
	      && !memcmp (p, NODE_NAME (node), len))
	    {
	      cpp_warning (pfile, CPP_W_TRADITIONAL,
			   "macro argument %qs would be stringified in "
			   "traditional C", NODE_NAME (node));
	      break;
	    }
	}
    }
}

/* Returns the name, arguments and expansion of a macro, in a format
   suitable to be read back in again, and therefore also for DWARF 2
   debugging info.  e.g. "PASTE(X, Y) X ## Y", or "MACNAME EXPANSION".
   Caller is expected to generate the "#define" bit if needed.  The
   returned text is temporary, and automatically freed later.  */
const unsigned char *
cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
{
  gcc_checking_assert (cpp_user_macro_p (node));

  if (const cpp_macro *macro = get_deferred_or_lazy_macro (pfile, node, 0))
    return cpp_macro_definition (pfile, node, macro);
  return NULL;
}

const unsigned char *
cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node,
		      const cpp_macro *macro)
{
  unsigned int i, len;
  unsigned char *buffer;

  /* Calculate length.  */
  len = NODE_LEN (node) * 10 + 2;		/* ' ' and NUL.  */
  if (macro->fun_like)
    {
      len += 4;		/* "()" plus possible final ".." of named
			   varargs (we have + 1 below).  */
      for (i = 0; i < macro->paramc; i++)
	len += NODE_LEN (macro->parm.params[i]) + 1; /* "," */
    }

  /* This should match below where we fill in the buffer.  */
  if (CPP_OPTION (pfile, traditional))
    len += _cpp_replacement_text_len (macro);
  else
    {
      unsigned int count = macro_real_token_count (macro);
      for (i = 0; i < count; i++)
	{
	  const cpp_token *token = &macro->exp.tokens[i];

	  if (token->type == CPP_MACRO_ARG)
	    len += NODE_LEN (token->val.macro_arg.spelling);
	  else
	    len += cpp_token_len (token);

	  if (token->flags & STRINGIFY_ARG)
	    len++;			/* "#" */
	  if (token->flags & PASTE_LEFT)
	    len += 3;		/* " ##" */
	  if (token->flags & PREV_WHITE)
	    len++;              /* " " */
	}
    }

  if (len > pfile->macro_buffer_len)
    {
      pfile->macro_buffer = XRESIZEVEC (unsigned char,
                                        pfile->macro_buffer, len);
      pfile->macro_buffer_len = len;
    }

  /* Fill in the buffer.  Start with the macro name.  */
  buffer = pfile->macro_buffer;
  buffer = _cpp_spell_ident_ucns (buffer, node);

  /* Parameter names.  */
  if (macro->fun_like)
    {
      *buffer++ = '(';
      for (i = 0; i < macro->paramc; i++)
	{
	  cpp_hashnode *param = macro->parm.params[i];

	  if (param != pfile->spec_nodes.n__VA_ARGS__)
	    {
	      memcpy (buffer, NODE_NAME (param), NODE_LEN (param));
	      buffer += NODE_LEN (param);
	    }

	  if (i + 1 < macro->paramc)
	    /* Don't emit a space after the comma here; we're trying
	       to emit a Dwarf-friendly definition, and the Dwarf spec
	       forbids spaces in the argument list.  */
	    *buffer++ = ',';
	  else if (macro->variadic)
	    *buffer++ = '.', *buffer++ = '.', *buffer++ = '.';
	}
      *buffer++ = ')';
    }

  /* The Dwarf spec requires a space after the macro name, even if the
     definition is the empty string.  */
  *buffer++ = ' ';

  if (CPP_OPTION (pfile, traditional))
    buffer = _cpp_copy_replacement_text (macro, buffer);
  else if (macro->count)
  /* Expansion tokens.  */
    {
      unsigned int count = macro_real_token_count (macro);
      for (i = 0; i < count; i++)
	{
	  const cpp_token *token = &macro->exp.tokens[i];

	  if (token->flags & PREV_WHITE)
	    *buffer++ = ' ';
	  if (token->flags & STRINGIFY_ARG)
	    *buffer++ = '#';

	  if (token->type == CPP_MACRO_ARG)
	    {
	      memcpy (buffer,
		      NODE_NAME (token->val.macro_arg.spelling),
		      NODE_LEN (token->val.macro_arg.spelling));
	      buffer += NODE_LEN (token->val.macro_arg.spelling);
	    }
	  else
	    buffer = cpp_spell_token (pfile, token, buffer, true);

	  if (token->flags & PASTE_LEFT)
	    {
	      *buffer++ = ' ';
	      *buffer++ = '#';
	      *buffer++ = '#';
	      /* Next has PREV_WHITE; see _cpp_create_definition.  */
	    }
	}
    }

  *buffer = '\0';
  return pfile->macro_buffer;
}
