[PATCH] Macro body is trailing array
authorNathan Sidwell <nathan@acm.org>
Fri, 17 Aug 2018 16:07:19 +0000 (16:07 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Fri, 17 Aug 2018 16:07:19 +0000 (16:07 +0000)
https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01037.html
* include/cpplib.h (enum cpp_macro_kind): New.
(struct cpp_macro): Make body trailing array.  Add kind field,
delete traditional flag.
* internal.h (_cpp_new_macro): Declare.
(_cpp_reserve_room): New inline.
(_cpp_commit_buf): Declare.
(_cpp_create_trad_definition): Return new macro.
* lex.c (_cpp_commit_buff): New.
* macro.c (macro_real_token_count): Count backwards.
(replace_args): Pointer equality not orderedness.
(_cpp_save_parameter): Use _cpp_reserve_room.
(alloc_expansion_token): Delete.
(lex_expansion_token): Return macro pointer.  Use _cpp_reserve_room.
(create_iso_definition): Allocate macro itself.  Adjust for
different allocation ordering.
(_cpp_new_macro): New.
(_cpp_create_definition): Adjust for API changes.
* traditional.c (push_replacement_text): Don't set traditional
flag.
(save_replacement_text): Likewise.
(_cpp_create_trad_definition): Allocate macro itself, Adjust for
different allocation ordering.

From-SVN: r263622

gcc/c-family/ChangeLog
gcc/c-family/c-ada-spec.c
libcpp/ChangeLog
libcpp/include/cpplib.h
libcpp/internal.h
libcpp/lex.c
libcpp/macro.c
libcpp/traditional.c

index 93b1ba1478d47883b39e6e023c501291d725fbde..6ad2fe0122d3a125e059156e68b69d2a385de183 100644 (file)
@@ -1,5 +1,7 @@
 2018-08-17  Nathan Sidwell  <nathan@acm.org>
 
+       * c-ada-spec.c (macro_length, dump_ada_macros): Constify.
+
        * c-ada-spec.c: Don't #include "cpp-id-data.h"
        * c-cppbuiltin.c: Likewise.
 
index 0352932c03973e5916e1772362f6aa10be017700..4b21d71345af1f21d303fd447804cca91fae913b 100644 (file)
@@ -88,7 +88,7 @@ macro_length (const cpp_macro *macro, int *supported, int *buffer_len,
 
   for (j = 0; j < macro->count; j++)
     {
-      cpp_token *token = &macro->exp.tokens[j];
+      const cpp_token *token = &macro->exp.tokens[j];
 
       if (token->flags & PREV_WHITE)
        (*buffer_len)++;
@@ -274,7 +274,7 @@ dump_ada_macros (pretty_printer *pp, const char* file)
 
          for (i = 0; supported && i < macro->count; i++)
            {
-             cpp_token *token = &macro->exp.tokens[i];
+             const cpp_token *token = &macro->exp.tokens[i];
              int is_one = 0;
 
              if (token->flags & PREV_WHITE)
index 978b32e37c627c296cf387dfb6c5774026523760..c79866f502a0dbbe029c763fd520dc81a2ef342d 100644 (file)
@@ -1,5 +1,28 @@
 2018-08-17  Nathan Sidwell  <nathan@acm.org>
 
+       * include/cpplib.h (enum cpp_macro_kind): New.
+       (struct cpp_macro): Make body trailing array.  Add kind field,
+       delete traditional flag.
+       * internal.h (_cpp_new_macro): Declare.
+       (_cpp_reserve_room): New inline.
+       (_cpp_commit_buf): Declare.
+       (_cpp_create_trad_definition): Return new macro.
+       * lex.c (_cpp_commit_buff): New.
+       * macro.c (macro_real_token_count): Count backwards.
+       (replace_args): Pointer equality not orderedness.
+       (_cpp_save_parameter): Use _cpp_reserve_room.
+       (alloc_expansion_token): Delete.
+       (lex_expansion_token): Return macro pointer.  Use _cpp_reserve_room.
+       (create_iso_definition): Allocate macro itself.  Adjust for
+       different allocation ordering.
+       (_cpp_new_macro): New.
+       (_cpp_create_definition): Adjust for API changes.
+       * traditional.c (push_replacement_text): Don't set traditional
+       flag.
+       (save_replacement_text): Likewise.
+       (_cpp_create_trad_definition): Allocate macro itself, Adjust for
+       different allocation ordering.
+
        * cpp-id-data.h (uchar, UC): Move to internal.h
        (struct cpp_macro): Move to cpplib.h.
        * internal.h (uchar, UC): From cpp-id-data.h.
index 2b3440d251d80af842baadb1890386a3317ec716..a0d0c53c0902a1dc3cb3afa224900a3c6592af1e 100644 (file)
@@ -671,6 +671,12 @@ struct cpp_dir
   dev_t dev;
 };
 
+/* The kind of the cpp_macro.  */
+enum cpp_macro_kind {
+  cmk_macro,   /* An ISO macro (token expansion).  */
+  cmk_traditional,     /* A traditional macro (text expansion).  */
+};
+
 /* Each macro definition is recorded in a cpp_macro structure.
    Variadic macros cannot occur with traditional cpp.  */
 struct GTY(()) cpp_macro {
@@ -683,15 +689,6 @@ struct GTY(()) cpp_macro {
                        length ("%h.paramc")))
     params;
 
-  /* Replacement tokens (ISO) or replacement text (traditional).  See
-     comment at top of cpptrad.c for how traditional function-like
-     macros are encoded.  */
-  union cpp_macro_u
-  {
-    cpp_token * GTY ((tag ("0"), length ("%0.count"))) tokens;
-    const unsigned char * GTY ((tag ("1"))) text;
-  } GTY ((desc ("%1.traditional"))) exp;
-
   /* Definition line number.  */
   source_location line;
 
@@ -701,6 +698,9 @@ struct GTY(()) cpp_macro {
   /* Number of parameters.  */
   unsigned short paramc;
 
+  /* The kind of this macro (ISO, trad or assert) */
+  unsigned kind : 2;
+
   /* If a function-like macro.  */
   unsigned int fun_like : 1;
 
@@ -713,13 +713,23 @@ struct GTY(()) cpp_macro {
   /* Nonzero if it has been expanded or had its existence tested.  */
   unsigned int used     : 1;
 
-  /* Indicate which field of 'exp' is in use.  */
-  unsigned int traditional : 1;
-
   /* Indicate whether the tokens include extra CPP_PASTE tokens at the
      end to track invalid redefinitions with consecutive CPP_PASTE
      tokens.  */
   unsigned int extra_tokens : 1;
+
+  /* 1 bits spare (32-bit). 33 on 64-bit target.  */
+
+  union cpp_exp_u
+  {
+    /* Trailing array of replacement tokens (ISO), or assertion body value.  */
+    cpp_token GTY ((tag ("false"), length ("%1.count"))) tokens[1];
+
+    /* Pointer to replacement text (traditional).  See comment at top
+       of cpptrad.c for how traditional function-like macros are
+       encoded.  */
+    const unsigned char *GTY ((tag ("true"))) text;
+  } GTY ((desc ("%1.kind == cmk_traditional"))) exp;
 };
 
 /* The structure of a node in the hash table.  The hash table has
index 0c2395a2dcd1a7c03daac2ac3d4e4bd6e6de859f..e40b20f267ce74944844205aa4d633dfc3ebec37 100644 (file)
@@ -633,6 +633,7 @@ inline void _cpp_maybe_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node)
   if (!(node->flags & NODE_USED))
     _cpp_notify_macro_use (pfile, node);
 }
+extern cpp_macro *_cpp_new_macro (cpp_reader *, cpp_macro_kind, void *);
 extern void _cpp_free_definition (cpp_hashnode *);
 extern bool _cpp_create_definition (cpp_reader *, cpp_hashnode *);
 extern void _cpp_pop_context (cpp_reader *);
@@ -697,6 +698,14 @@ extern void _cpp_init_tokenrun (tokenrun *, unsigned int);
 extern cpp_hashnode *_cpp_lex_identifier (cpp_reader *, const char *);
 extern int _cpp_remaining_tokens_num_in_context (cpp_context *);
 extern void _cpp_init_lexer (void);
+static inline void *_cpp_reserve_room (cpp_reader *pfile, size_t have,
+                                      size_t extra)
+{
+  if (BUFF_ROOM (pfile->a_buff) < (have + extra))
+    _cpp_extend_buff (pfile, &pfile->a_buff, extra);
+  return BUFF_FRONT (pfile->a_buff);
+}
+extern void *_cpp_commit_buff (cpp_reader *pfile, size_t size);
 
 /* In init.c.  */
 extern void _cpp_maybe_push_include_file (cpp_reader *);
@@ -733,7 +742,7 @@ extern bool _cpp_read_logical_line_trad (cpp_reader *);
 extern void _cpp_overlay_buffer (cpp_reader *pfile, const unsigned char *,
                                 size_t);
 extern void _cpp_remove_overlay (cpp_reader *);
-extern bool _cpp_create_trad_definition (cpp_reader *, cpp_macro *);
+extern cpp_macro *_cpp_create_trad_definition (cpp_reader *);
 extern bool _cpp_expansions_different_trad (const cpp_macro *,
                                            const cpp_macro *);
 extern unsigned char *_cpp_copy_replacement_text (const cpp_macro *,
index fa465beadb025e58492bbf9947f4cf8411fceb95..892cfc4494de592df4e1ade5d0cf4c02ee345b01 100644 (file)
@@ -3725,6 +3725,25 @@ _cpp_aligned_alloc (cpp_reader *pfile, size_t len)
   return result;
 }
 
+/* Commit or allocate storage from a buffer.  */
+
+void *
+_cpp_commit_buff (cpp_reader *pfile, size_t size)
+{
+  void *ptr = BUFF_FRONT (pfile->a_buff);
+
+  if (pfile->hash_table->alloc_subobject)
+    {
+      void *copy = pfile->hash_table->alloc_subobject (size);
+      memcpy (copy, ptr, size);
+      ptr = copy;
+    }
+  else
+    BUFF_FRONT (pfile->a_buff) += size;
+
+  return ptr;
+}
+
 /* Say which field of TOK is in use.  */
 
 enum cpp_token_fld_kind
index 52098efe63cf2655cd7a8e7023a00412ccd3f1de..25f4a361189d13b55f0bd2e31b48758b973dc2c7 100644 (file)
@@ -308,12 +308,11 @@ static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *,
                          macro_arg *, source_location);
 static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *,
                                        _cpp_buff **, unsigned *);
-static bool create_iso_definition (cpp_reader *, cpp_macro *);
+static cpp_macro *create_iso_definition (cpp_reader *);
 
 /* #define directive parsing and handling.  */
 
-static cpp_token *alloc_expansion_token (cpp_reader *, cpp_macro *);
-static cpp_token *lex_expansion_token (cpp_reader *, cpp_macro *);
+static cpp_macro *lex_expansion_token (cpp_reader *, cpp_macro *);
 static bool warn_of_redefinition (cpp_reader *, cpp_hashnode *,
                                  const cpp_macro *);
 static bool parse_params (cpp_reader *, unsigned *, bool *);
@@ -1235,13 +1234,14 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node,
 static inline unsigned int
 macro_real_token_count (const cpp_macro *macro)
 {
-  unsigned int i;
   if (__builtin_expect (!macro->extra_tokens, true))
     return macro->count;
-  for (i = 0; i < macro->count; i++)
-    if (macro->exp.tokens[i].type == CPP_PASTE)
-      return i;
-  abort ();
+
+  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
@@ -1773,7 +1773,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro,
              arg->stringified = stringify_arg (pfile, arg);
          }
        else if ((src->flags & PASTE_LEFT)
-                || (src > macro->exp.tokens && (src[-1].flags & PASTE_LEFT)))
+                || (src != macro->exp.tokens && (src[-1].flags & PASTE_LEFT)))
          total += arg->count - 1;
        else
          {
@@ -3078,10 +3078,9 @@ _cpp_save_parameter (cpp_reader *pfile, unsigned n, cpp_hashnode *node,
   saved[n].canonical_node = node;
   saved[n].value = node->value;
 
-  if (BUFF_ROOM (pfile->a_buff) < (n + 1) * sizeof (cpp_hashnode *))
-    _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_hashnode *));
-
-  ((cpp_hashnode **) BUFF_FRONT (pfile->a_buff))[n] = spelling;
+  void *base = _cpp_reserve_room (pfile, n * sizeof (cpp_hashnode *),
+                                 sizeof (cpp_hashnode *));
+  ((cpp_hashnode **)base)[n] = spelling;
 
   /* Morph into a macro arg.  */
   node->flags |= NODE_MACRO_ARG;
@@ -3226,26 +3225,18 @@ parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *varadic_ptr)
   return ok;
 }
 
-/* Allocate room for a token from a macro's replacement list.  */
-static cpp_token *
-alloc_expansion_token (cpp_reader *pfile, cpp_macro *macro)
-{
-  if (BUFF_ROOM (pfile->a_buff) < (macro->count + 1) * sizeof (cpp_token))
-    _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_token));
-
-  return &((cpp_token *) BUFF_FRONT (pfile->a_buff))[macro->count++];
-}
-
 /* Lex a token from the expansion of MACRO, but mark parameters as we
    find them and warn of traditional stringification.  */
-static cpp_token *
+static cpp_macro *
 lex_expansion_token (cpp_reader *pfile, cpp_macro *macro)
 {
-  cpp_token *token, *saved_cur_token;
-
-  saved_cur_token = pfile->cur_token;
-  pfile->cur_token = alloc_expansion_token (pfile, macro);
-  token = _cpp_lex_direct (pfile);
+  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?  */
@@ -3261,52 +3252,45 @@ lex_expansion_token (cpp_reader *pfile, cpp_macro *macro)
           && (token->type == CPP_STRING || token->type == CPP_CHAR))
     check_trad_stringification (pfile, macro, &token->val.str);
 
-  return token;
+  return macro;
 }
 
-static bool
-create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
+static cpp_macro *
+create_iso_definition (cpp_reader *pfile)
 {
-  cpp_token *token;
-  const cpp_token *ctoken;
   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 varadic = false;
   bool ok = false;
+  cpp_macro *macro = NULL;
 
-  /* Get the first token of the expansion (or the '(' of a
-     function-like macro).  */
-  ctoken = _cpp_lex_token (pfile);
+  /* 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 (ctoken->flags & PREV_WHITE)
+  if (token->flags & PREV_WHITE)
     /* Preceeded by space, must be part of expansion.  */;
-  else if (ctoken->type == CPP_OPEN_PAREN)
+  else if (token->type == CPP_OPEN_PAREN)
     {
       /* An open-paren, get a parameter list.  */
       if (!parse_params (pfile, &nparms, &varadic))
        goto out;
-      macro->variadic = varadic;
-      macro->paramc = nparms;
-      macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
 
-      /* Success.  Commit or allocate the parameter array.  */
-      if (pfile->hash_table->alloc_subobject)
-       {
-         cpp_hashnode **params =
-            (cpp_hashnode **) pfile->hash_table->alloc_subobject
-            (sizeof (cpp_hashnode *) * macro->paramc);
-         memcpy (params, macro->params,
-                 sizeof (cpp_hashnode *) * macro->paramc);
-         macro->params = params;
-       }
-      else
-       BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
-      macro->fun_like = 1;
+      params = (cpp_hashnode **)_cpp_commit_buff
+       (pfile, sizeof (cpp_hashnode *) * nparms);
+      token = NULL;
     }
-  else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE))
+  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
@@ -3319,7 +3303,7 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
       else
        {
          int warntype = CPP_DL_WARNING;
-         switch (ctoken->type)
+         switch (token->type)
            {
            case CPP_ATSIGN:
            case CPP_AT_NAME:
@@ -3330,7 +3314,7 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
            case CPP_OTHER:
              /* Basic character set sans letters, digits and _.  */
              if (strchr ("!\"#%&'()*+,-./:;<=>?[\\]^{|}~",
-                         ctoken->val.str.text[0]) == NULL)
+                         token->val.str.text[0]) == NULL)
                warntype = CPP_DL_PEDWARN;
              break;
            default:
@@ -3343,16 +3327,32 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
        }
     }
 
-  if (macro->fun_like)
-    token = lex_expansion_token (pfile, macro);
+  macro = _cpp_new_macro (pfile, cmk_macro,
+                         _cpp_reserve_room (pfile, 0, sizeof (cpp_macro)));
+
+  if (!token)
+    {
+      macro->variadic = varadic;
+      macro->paramc = nparms;
+      macro->params = params;
+      macro->fun_like = true;
+    }
   else
     {
-      token = alloc_expansion_token (pfile, macro);
-      *token = *ctoken;
+      /* 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, true);;)
+  for (vaopt_state vaopt_tracker (pfile, macro->variadic, true);; 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)
@@ -3404,14 +3404,16 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
              goto out;
            }
 
-         if (token[-1].flags & PASTE_LEFT)
+         if (following_paste_op)
            {
-             macro->extra_tokens = 1;
+             /* 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)
@@ -3419,79 +3421,64 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
              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;
-
-      following_paste_op = (token->type == CPP_PASTE);
-      token = lex_expansion_token (pfile, macro);
     }
 
   /* We're committed to winning now.  */
   ok = true;
 
-  macro->exp.tokens = (cpp_token *) BUFF_FRONT (pfile->a_buff);
-  macro->traditional = 0;
-
   /* 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 for warn_of_redefinition().  */
   if (macro->count)
     macro->exp.tokens[0].flags &= ~PREV_WHITE;
 
-  /* Commit or allocate the memory.  */
-  if (pfile->hash_table->alloc_subobject)
+  if (num_extra_tokens)
     {
-      cpp_token *tokns =
-        (cpp_token *) pfile->hash_table->alloc_subobject (sizeof (cpp_token)
-                                                          * macro->count);
-      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.  */
-         cpp_token *normal_dest = tokns;
-         cpp_token *extra_dest = tokns + macro->count - num_extra_tokens;
-         unsigned int i;
-         for (i = 0; i < macro->count; i++)
-           {
-             if (macro->exp.tokens[i].type == CPP_PASTE)
-               *extra_dest++ = macro->exp.tokens[i];
-             else
-               *normal_dest++ = macro->exp.tokens[i];
-           }
-       }
-      else
-       memcpy (tokns, macro->exp.tokens, sizeof (cpp_token) * macro->count);
-      macro->exp.tokens = tokns;
+      /* 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;
     }
-  else
-    BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->exp.tokens[macro->count];
 
  out:
   pfile->state.va_args_ok = 0;
   _cpp_unsave_parameters (pfile, nparms);
 
-  return ok;
+  return ok ? macro : NULL;
 }
 
-/* Parse a macro and save its expansion.  Returns nonzero on success.  */
-bool
-_cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
+cpp_macro *
+_cpp_new_macro (cpp_reader *pfile, cpp_macro_kind kind, void *placement)
 {
-  cpp_macro *macro;
-  bool ok;
+  cpp_macro *macro = (cpp_macro *) placement;
 
-  if (pfile->hash_table->alloc_subobject)
-    macro = (cpp_macro *) pfile->hash_table->alloc_subobject
-      (sizeof (cpp_macro));
-  else
-    macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
   macro->line = pfile->directive_line;
   macro->params = 0;
   macro->paramc = 0;
@@ -3503,15 +3490,26 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
   /* 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)
+{
+  cpp_macro *macro;
+
   if (CPP_OPTION (pfile, traditional))
-    ok = _cpp_create_trad_definition (pfile, macro);
+    macro = _cpp_create_trad_definition (pfile);
   else
-    ok = create_iso_definition (pfile, macro);
+    macro = create_iso_definition (pfile);
 
-  if (!ok)
-    return ok;
+  if (!macro)
+    return false;
 
-  if (node->type == NT_MACRO)
+  if (cpp_macro_p (node))
     {
       if (CPP_OPTION (pfile, warn_unused_macros))
        _cpp_warn_if_unused_macro (pfile, node, NULL);
@@ -3552,7 +3550,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
      conditional flag */
   node->flags &= ~NODE_CONDITIONAL;
 
-  return ok;
+  return true;
 }
 
 /* Notify the use of NODE in a macro-aware context (i.e. expanding it,
@@ -3678,7 +3676,7 @@ cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
       unsigned int count = macro_real_token_count (macro);
       for (i = 0; i < count; i++)
        {
-         cpp_token *token = &macro->exp.tokens[i];
+         const cpp_token *token = &macro->exp.tokens[i];
 
          if (token->type == CPP_MACRO_ARG)
            len += NODE_LEN (token->val.macro_arg.spelling);
@@ -3742,7 +3740,7 @@ cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
       unsigned int count = macro_real_token_count (macro);
       for (i = 0; i < count; i++)
        {
-         cpp_token *token = &macro->exp.tokens[i];
+         const cpp_token *token = &macro->exp.tokens[i];
 
          if (token->flags & PREV_WHITE)
            *buffer++ = ' ';
index f4842369c3a168393760c15e194de830a4df88f2..3c3b8ac3f1a7a665c58c7a722b0d988c2aff44e6 100644 (file)
@@ -853,7 +853,6 @@ push_replacement_text (cpp_reader *pfile, cpp_hashnode *node)
       cpp_macro *macro = node->value.macro;
       macro->used = 1;
       text = macro->exp.text;
-      macro->traditional = 1;
       len = macro->count;
     }
 
@@ -1143,7 +1142,6 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
       memcpy (exp, pfile->out.base, len);
       exp[len] = '\n';
       macro->exp.text = exp;
-      macro->traditional = 1;
       macro->count = len;
     }
   else
@@ -1159,7 +1157,6 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
       exp = BUFF_FRONT (pfile->a_buff);
       block = (struct block *) (exp + macro->count);
       macro->exp.text = exp;
-      macro->traditional = 1;
 
       /* Write out the block information.  */
       block->text_len = len;
@@ -1179,13 +1176,15 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
 
 /* Analyze and save the replacement text of a macro.  Returns true on
    success.  */
-bool
-_cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro)
+cpp_macro *
+_cpp_create_trad_definition (cpp_reader *pfile)
 {
   const uchar *cur;
   uchar *limit;
   cpp_context *context = pfile->context;
   unsigned nparms = 0;
+  int fun_like = 0;
+  cpp_hashnode **params = NULL;
 
   /* The context has not been set up for command line defines, and CUR
      has not been updated for the macro name for in-file defines.  */
@@ -1197,21 +1196,23 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro)
   /* Is this a function-like macro?  */
   if (* CUR (context) == '(')
     {
-      bool ok = scan_parameters (pfile, &nparms);
-      macro->paramc = nparms;
+      fun_like = +1;
+      if (scan_parameters (pfile, &nparms))
+       params = (cpp_hashnode **)_cpp_commit_buff
+         (pfile, sizeof (cpp_hashnode *) * nparms);
+      else
+       fun_like = -1;
+    }
 
-      /* Remember the params so we can clear NODE_MACRO_ARG flags.  */
-      macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
+  cpp_macro *macro = NULL;
 
-      /* Setting macro to NULL indicates an error occurred, and
-        prevents unnecessary work in _cpp_scan_out_logical_line.  */
-      if (!ok)
-       macro = NULL;
-      else
-       {
-         BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
-         macro->fun_like = 1;
-       }
+  if (fun_like >= 0)
+    {
+      macro = _cpp_new_macro (pfile, cmk_traditional,
+                             _cpp_aligned_alloc (pfile, sizeof (cpp_macro)));
+      macro->params = params;
+      macro->paramc = nparms;
+      macro->fun_like = fun_like != 0;
     }
 
   /* Skip leading whitespace in the replacement text.  */
@@ -1225,18 +1226,18 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro)
 
   _cpp_unsave_parameters (pfile, nparms);
 
-  if (!macro)
-    return false;
-
-  /* Skip trailing white space.  */
-  cur = pfile->out.base;
-  limit = pfile->out.cur;
-  while (limit > cur && is_space (limit[-1]))
-    limit--;
-  pfile->out.cur = limit;
-  save_replacement_text (pfile, macro, 0);
+  if (macro)
+    {
+      /* Skip trailing white space.  */
+      cur = pfile->out.base;
+      limit = pfile->out.cur;
+      while (limit > cur && is_space (limit[-1]))
+       limit--;
+      pfile->out.cur = limit;
+      save_replacement_text (pfile, macro, 0);
+    }
 
-  return true;
+  return macro;
 }
 
 /* Copy SRC of length LEN to DEST, but convert all contiguous