This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

More do_define tidy up


This patch implements Zack's "nits" in the previous patch.  It does
indeed simplify things further.

Neil.

	* cpphash.c (struct macro_info): Add new members.
	(_cpp_free_definition): Delete the macro directly.
	(count_params): Return void, with first token of
	expansion in struct macro_info on success.
	(parse_define): Return int.  Hoist syntax checking from
	save_macro_expansion.  Leave call to save_expansion to
	_cpp_create_definition.
	(alloc_macro): Needs just 2 arguments.
	(free_macro): Delete.
	(save_expansion): Don't perform syntax check.
	(_cpp_create_definition): Call save_expansion.

Index: cpphash.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cpphash.c,v
retrieving revision 1.100
diff -u -p -r1.100 cpphash.c
--- cpphash.c	2000/07/12 19:41:30	1.100
+++ cpphash.c	2000/07/12 22:16:29
@@ -44,8 +44,12 @@ struct hashdummy
 /* Stores basic information about a macro, before it is allocated.  */
 struct macro_info
 {
-  unsigned int paramlen;
-  signed short paramc;
+  const cpp_token *first_param;	/* First parameter token.  */
+  const cpp_token *first;	/* First expansion token.  */
+  unsigned int paramlen;	/* Length of parameter names. */
+  unsigned int len;		/* Length of token strings.  */
+  unsigned int ntokens;		/* Number of tokens in expansion.  */
+  signed short paramc;		/* Number of parameters.  */
   unsigned char flags;
 };
 
@@ -55,26 +59,17 @@ struct macro_info
 static unsigned int hash_HASHNODE PARAMS ((const void *));
 static int eq_HASHNODE		  PARAMS ((const void *, const void *));
 static int dump_hash_helper	  PARAMS ((void **, void *));
-
 static void dump_funlike_macro	PARAMS ((cpp_reader *, cpp_hashnode *));
-
-static const cpp_token *count_params PARAMS ((cpp_reader *,
-					      const cpp_token *,
-					      struct macro_info *));
+static void count_params PARAMS ((cpp_reader *, struct macro_info *));
 static int is__va_args__ PARAMS ((cpp_reader *, const cpp_token *));
-static const cpp_toklist * parse_define PARAMS((cpp_reader *));
+static int parse_define PARAMS((cpp_reader *, struct macro_info *));
 static int check_macro_redefinition PARAMS((cpp_reader *, cpp_hashnode *hp,
 					     const cpp_toklist *));
 static const cpp_toklist * save_expansion PARAMS((cpp_reader *,
-						  const cpp_token *,
-						  const cpp_token *,
 						  struct macro_info *));
 static unsigned int find_param PARAMS ((const cpp_token *,
 					const cpp_token *));
-static cpp_toklist * alloc_macro PARAMS ((cpp_reader *,
-					  struct macro_info *,
-					  unsigned int, unsigned int));
-static void free_macro PARAMS((const cpp_toklist *));
+static cpp_toklist * alloc_macro PARAMS ((cpp_reader *, struct macro_info *));
 
 /* Calculate hash of a string of length LEN.  */
 unsigned int
@@ -186,7 +181,7 @@ _cpp_free_definition (h)
      cpp_hashnode *h;
 {
   if (h->type == T_MACRO)
-    free_macro (h->value.expansion);
+    free ((PTR) h->value.expansion);
   h->value.expansion = NULL;
 }
 
@@ -231,29 +226,38 @@ is__va_args__ (pfile, token)
 /* Counts the parameters to a function-like macro, the length of their
    null-terminated names, and whether the macro is a variable-argument
    one.  FIRST is the token immediately after the open parenthesis,
-   INFO stores the data, and should have paramlen and flags zero.
+   INFO stores the data.
 
-   Returns the token that we stopped scanning at; if it's type isn't
-   CPP_CLOSE_PAREN there was an error, which has been reported.  */
-static const cpp_token *
-count_params (pfile, first, info)
+   On success, info->first is updated to the token after the closing
+   parenthesis, i.e. the first token of the expansion.  Otherwise
+   there was an error, which has been reported.  */
+static void
+count_params (pfile, info)
      cpp_reader *pfile;
-     const cpp_token *first;
      struct macro_info *info;
 {
   unsigned int prev_ident = 0;
   const cpp_token *token;
 
   info->paramc = 0;
-  for (token = first;; token++)
+  info->paramlen = 0;
+  info->flags = 0;
+  info->first = info->first_param; /* Not a ')' indicating success.  */
+
+  for (token = info->first_param;; token++)
     {
       switch (token->type)
 	{
+	default:
+	  cpp_error_with_line (pfile, token->line, token->col,
+			       "illegal token in macro parameter list");
+	  return;
+
 	case CPP_EOF:
 	missing_paren:
 	  cpp_error_with_line (pfile, token->line, token->col,
 			       "missing ')' in macro parameter list");
-	  goto out;
+	  return;
 
 	case CPP_COMMENT:
 	  continue;		/* Ignore -C comments.  */
@@ -263,36 +267,30 @@ count_params (pfile, first, info)
 	    {
 	      cpp_error_with_line (pfile, token->line, token->col,
 			   "macro parameters must be comma-separated");
-	      goto out;
+	      return;
 	    }
 
 	  /* Constraint 6.10.3.5  */
 	  if (is__va_args__ (pfile, token))
-	    goto out;
+	    return;
 
 	  /* Constraint 6.10.3.6 - duplicate parameter names.  */
-	  if (find_param (first, token))
+	  if (find_param (info->first, token))
 	    {
 	      cpp_error_with_line (pfile, token->line, token->col,
 				   "duplicate macro parameter \"%s\"",
 				   token->val.node->name);
-	      goto out;
+	      return;
 	    }
 
 	  prev_ident = 1;
 	  info->paramc++;
-	  if (pfile->save_parameter_spellings)
-	    info->paramlen += token->val.node->length + 1;
-	  break;
-
-	default:
-	  cpp_error_with_line (pfile, token->line, token->col,
-			       "illegal token in macro parameter list");
-	  goto out;
+	  info->paramlen += token->val.node->length + 1;
+	  continue;
 
 	case CPP_CLOSE_PAREN:
 	  if (prev_ident || info->paramc == 0)
-	    goto out;
+	    break;
 
 	  /* Fall through to pick up the error.  */
 	case CPP_COMMA:
@@ -300,12 +298,10 @@ count_params (pfile, first, info)
 	    {
 	      cpp_error_with_line (pfile, token->line, token->col,
 				   "parameter name expected");
-	      if (token->type == CPP_CLOSE_PAREN)
-		token--;		/* Return the ',' not ')'.  */
-	      goto out;
+	      return;
 	    }
 	  prev_ident = 0;
-	  break;
+	  continue;
 
 	case CPP_ELLIPSIS:
 	  /* Convert ISO-style var_args to named varargs by changing
@@ -319,8 +315,7 @@ count_params (pfile, first, info)
 	      tok->val.node = pfile->spec_nodes->n__VA_ARGS__;
 
 	      info->paramc++;
-	      if (pfile->save_parameter_spellings)
-		info->paramlen += tok->val.node->length + 1;
+	      info->paramlen += tok->val.node->length + 1;
 
 	      if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, c99))
 		cpp_pedwarn (pfile,
@@ -337,22 +332,26 @@ count_params (pfile, first, info)
 	  info->flags |= VAR_ARGS;
 	  token++;
 	  if (token->type == CPP_CLOSE_PAREN)
-	    goto out;
+	    break;
 	  goto missing_paren;
 	}
-    }
 
- out:
-  return token;
+      /* Success.  */
+      info->first = token + 1;
+      if (!pfile->save_parameter_spellings)
+	info->paramlen = 0;
+      return;
+    }
 }
 
-/* Parses a #define directive.  Returns null pointer on error.  */
-static const cpp_toklist *
-parse_define (pfile)
+/* Parses a #define directive.  On success, returns zero, and INFO is
+   filled in appropriately.  */
+static int
+parse_define (pfile, info)
      cpp_reader *pfile;
+     struct macro_info *info;
 {
-  const cpp_token *token, *first_param;
-  struct macro_info info;
+  const cpp_token *token;
   int prev_white = 0;
 
   /* The first token after the macro's name.  */
@@ -360,34 +359,91 @@ parse_define (pfile)
 
   /* Constraint 6.10.3.5  */
   if (is__va_args__ (pfile, token - 1))
-    return 0;
+    return 1;
 
   while (token->type == CPP_COMMENT)
     token++, prev_white = 1;
-  first_param = token + 1;
+  prev_white |= token->flags & PREV_WHITE;
 
-  /* Assume object-like macro.  */
-  info.paramc = -1;
-  info.paramlen = 0;
-  info.flags = 0;
+  if (token->type == CPP_OPEN_PAREN && !prev_white)
+    {
+      /* A function-like macro.  */
+      info->first_param = token + 1;
+      count_params (pfile, info);
+      if (info->first[-1].type != CPP_CLOSE_PAREN)
+	return 1;
+    }
+  else
+    {
+      /* An object-like macro.  */
+      info->paramc = -1;
+      info->paramlen = 0;
+      info->flags = 0;
+      info->first = token;
+      if (!prev_white && token->type != CPP_EOF)
+	cpp_pedwarn (pfile, "ISO C requires whitespace after the macro name");
+    }
 
-  if (!prev_white && !(token->flags & PREV_WHITE))
+  /* Count tokens in expansion.  We drop paste tokens, and stringize
+     tokens, so don't count them.  */
+  info->ntokens = 0;
+  info->len = 0;
+  for (token = info->first; token->type != CPP_EOF; token++)
     {
-      if (token->type == CPP_OPEN_PAREN)
+      const char *msg;
+
+      if (token->type == CPP_PASTE)
 	{
-	  token = count_params (pfile, first_param, &info);
-	  if (token->type != CPP_CLOSE_PAREN)
-	    return 0;
-	  token++;
+	  /* Token-paste ##, but is a normal token if traditional.  */
+	  if (! CPP_TRADITIONAL (pfile))
+	    {
+	      msg = "\"##\" cannot appear at either end of a macro expansion";
+	      /* Constraint 6.10.3.3.1  */
+	      if (token == info->first || token[1].type == CPP_EOF)
+		goto error;
+	      continue;
+	    }
+	}
+      else if (token->type == CPP_HASH)
+	{
+	  /* Stringifying #, but is a normal character if traditional,
+	     or in object-like macros.  Constraint 6.10.3.2.1.  */
+	  if (info->paramc >= 0 && ! CPP_TRADITIONAL (pfile))
+	    {
+	      if (token[1].type == CPP_NAME
+		  && find_param (info->first_param, token + 1))
+		continue;
+	      if (! CPP_OPTION (pfile, lang_asm))
+		{
+		  msg = "'#' is not followed by a macro parameter";
+		error:
+		  cpp_error_with_line (pfile, token->line, token->col, msg);
+		  return 1;
+		}
+	    }
 	}
-      else if (token->type != CPP_EOF)
-	cpp_pedwarn (pfile,
-		     "ISO C requires whitespace after the macro name");
+      else if (token->type == CPP_NAME)
+	{
+	  /* Constraint 6.10.3.5  */
+	  if (!(info->flags & VAR_ARGS) && is__va_args__ (pfile, token))
+	    return 1;
+	  /* It might be worth doing a check here that we aren't a
+	     macro argument, since we don't store the text of macro
+	     arguments.  This would reduce "len" and save space.  */
+	}
+      info->ntokens++;
+      if (TOKEN_SPELL (token) == SPELL_STRING)
+	info->len += token->val.str.len;
     }
+  
+  /* Empty macros become a single placemarker token.  */
+  if (info->ntokens == 0)
+    info->ntokens = 1;
 
-  return save_expansion (pfile, token, first_param, &info);
+  return 0;
 }
 
+/* Returns non-zero if a macro redefinition is trivial.  */
 static int
 check_macro_redefinition (pfile, hp, list2)
      cpp_reader *pfile;
@@ -434,28 +490,27 @@ struct toklist_dummy
    reasons.  Therefore, this token list cannot be expanded like a
    normal token list.  Try to do so, and you lose.  */
 static cpp_toklist *
-alloc_macro (pfile, info, ntokens, len)
+alloc_macro (pfile, info)
      cpp_reader *pfile;
      struct macro_info *info;
-     unsigned int ntokens, len;
 {
   unsigned int size;
   struct toklist_dummy *dummy;
   cpp_toklist *list;
 
   size = sizeof (struct toklist_dummy);
-  size += (ntokens - 1) * sizeof(cpp_token);
-  size += len + info->paramlen;
+  size += (info->ntokens - 1) * sizeof(cpp_token);
+  size += info->len + info->paramlen;
 
   dummy = (struct toklist_dummy *) xmalloc (size);
   list = (cpp_toklist *) dummy;
   
   /* Initialize the monster.  */
   list->tokens = &dummy->first_token;
-  list->tokens_used = list->tokens_cap = ntokens;
+  list->tokens_used = list->tokens_cap = info->ntokens;
 
-  list->namebuf = (unsigned char *) &list->tokens[ntokens];
-  list->name_used = list->name_cap = len + info->paramlen;
+  list->namebuf = (unsigned char *) &list->tokens[info->ntokens];
+  list->name_used = list->name_cap = info->len + info->paramlen;
 
   list->directive = 0;
   list->line = pfile->token_list.line;
@@ -466,98 +521,33 @@ alloc_macro (pfile, info, ntokens, len)
 
   return list;
 }
-
-/* Free a macro allocated by allocate_macro.  */
-static void
-free_macro (list)
-     const cpp_toklist *list;
-{
-  free ((PTR) list);
-}
 
-/* Copy the tokens of the expansion, beginning with FIRST until
-   CPP_EOF.  For a function-like macro, FIRST_PARAM points to the
-   first parameter.  INFO contains information about the macro.
+/* Copy the tokens of the expansion, beginning with info->first until
+   CPP_EOF.  INFO contains information about the macro.
 
    Change the type of macro arguments in the expansion from CPP_NAME
    to CPP_MACRO_ARG.  Remove #'s that represent stringification,
    flagging the CPP_MACRO_ARG it operates on STRINGIFY.  Remove ##'s,
    flagging the token on its immediate left PASTE_LEFT.  Returns the
-   token list for the macro expansion, or 0 on error.  */
+   token list for the macro expansion.  */
 static const cpp_toklist *
-save_expansion (pfile, first, first_param, info)
+save_expansion (pfile, info)
      cpp_reader *pfile;
-     const cpp_token *first;
-     const cpp_token *first_param;
      struct macro_info *info;
 {
   const cpp_token *token;
   cpp_toklist *list;
   cpp_token *dest;
-  unsigned int len, ntokens;
   unsigned char *buf;
       
-  /* Count tokens in expansion.  We drop paste tokens, and stringize
-     tokens, so don't count them.  */
-  ntokens = len = 0;
-  for (token = first; token->type != CPP_EOF; token++)
-    {
-      const char *msg;
-
-      if (token->type == CPP_PASTE)
-	{
-	  /* Token-paste ##, but is a normal token if traditional.  */
-	  if (! CPP_TRADITIONAL (pfile))
-	    {
-	      msg = "\"##\" cannot appear at either end of a macro expansion";
-	      /* Constraint 6.10.3.3.1  */
-	      if (token == first || token[1].type == CPP_EOF)
-		goto error;
-	      continue;
-	    }
-	}
-      else if (token->type == CPP_HASH)
-	{
-	  /* Stringifying #, but is a normal character if traditional,
-	     or in object-like macros.  Constraint 6.10.3.2.1.  */
-	  if (info->paramc >= 0 && ! CPP_TRADITIONAL (pfile))
-	    {
-	      if (token[1].type == CPP_NAME
-		  && find_param (first_param, token + 1))
-		continue;
-	      if (! CPP_OPTION (pfile, lang_asm))
-		{
-		  msg = "'#' is not followed by a macro parameter";
-		error:
-		  cpp_error_with_line (pfile, token->line, token->col, msg);
-		  return 0;
-		}
-	    }
-	}
-      else if (token->type == CPP_NAME)
-	{
-	  /* Constraint 6.10.3.5  */
-	  if (!(info->flags & VAR_ARGS) && is__va_args__ (pfile, token))
-	    return 0;
-	  /* It might be worth doing a check here that we aren't a
-	     macro argument, since we don't store the text of macro
-	     arguments.  This would reduce "len" and save space.  */
-	}
-      ntokens++;
-      if (TOKEN_SPELL (token) == SPELL_STRING)
-	len += token->val.str.len;
-    }
-
-  if (ntokens == 0)
-    ntokens++;
-  list = alloc_macro (pfile, info, ntokens, len);
+  list = alloc_macro (pfile, info);
   buf = list->namebuf;
 
   /* Store the null-terminated parameter spellings of a macro, to
      provide pedantic warnings to satisfy 6.10.3.2, or for use when
      dumping macro definitions.  They must go first.  */
   if (list->params_len)
-    for (token = first_param; token < first; token++)
+    for (token = info->first_param; token < info->first; token++)
       if (token->type == CPP_NAME)
 	{
 	  /* Copy null too.  */
@@ -566,7 +556,7 @@ save_expansion (pfile, first, first_para
 	}
 
   dest = list->tokens;
-  for (token = first; token->type != CPP_EOF; token++)
+  for (token = info->first; token->type != CPP_EOF; token++)
     {
       unsigned int param_no;
 
@@ -577,7 +567,7 @@ save_expansion (pfile, first, first_para
 	    break;
 
 	  /* Check if the name is a macro parameter.  */
-	  param_no = find_param (first_param, token);
+	  param_no = find_param (info->first_param, token);
 	  if (param_no == 0)
 	    break;
 	  dest->val.aux = param_no - 1;
@@ -602,7 +592,7 @@ save_expansion (pfile, first, first_para
 	  /* Stringifying #.  Constraint 6.10.3.2.1  */
 	  if (list->paramc >= 0 && ! CPP_TRADITIONAL (pfile)
 	      && token[1].type == CPP_NAME
-	      && find_param (first_param, token + 1))
+	      && find_param (info->first_param, token + 1))
 	    continue;
 	  break;
 
@@ -630,16 +620,18 @@ save_expansion (pfile, first, first_para
   return list;
 }
 
+/* Parse a macro and save its expansion.  Returns non-zero on success.  */
 int
 _cpp_create_definition (pfile, hp)
      cpp_reader *pfile;
      cpp_hashnode *hp;
 {
+  struct macro_info info;
   const cpp_toklist *list;
 
-  list = parse_define (pfile);
-  if (!list)
+  if (parse_define (pfile, &info))
     return 0;
+  list = save_expansion (pfile, &info);
 
   /* Check for a redefinition.  Redefinition of a macro is allowed if
      and only if the old and new definitions are the same.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]