diff libcpp/directives.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
line wrap: on
line diff
--- a/libcpp/directives.c	Fri Oct 27 22:46:09 2017 +0900
+++ b/libcpp/directives.c	Thu Oct 25 07:37:49 2018 +0900
@@ -1,5 +1,5 @@
 /* CPP Library. (Directive handling.)
-   Copyright (C) 1986-2017 Free Software Foundation, Inc.
+   Copyright (C) 1986-2018 Free Software Foundation, Inc.
    Contributed by Per Bothner, 1994-95.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -102,7 +102,8 @@
 static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *);
 static unsigned int read_flag (cpp_reader *, unsigned int);
 static bool strtolinenum (const uchar *, size_t, linenum_type *, bool *);
-static void do_diagnostic (cpp_reader *, int, int, int);
+static void do_diagnostic (cpp_reader *, enum cpp_diagnostic_level code,
+			   enum cpp_warning_reason reason, int);
 static cpp_hashnode *lex_macro_node (cpp_reader *, bool);
 static int undefine_macros (cpp_reader *, cpp_hashnode *, void *);
 static void do_include_common (cpp_reader *, enum include_type);
@@ -124,9 +125,9 @@
 static const cpp_token *get__Pragma_string (cpp_reader *);
 static void destringize_and_run (cpp_reader *, const cpp_string *,
 				 source_location);
-static int parse_answer (cpp_reader *, struct answer **, int, source_location);
-static cpp_hashnode *parse_assertion (cpp_reader *, struct answer **, int);
-static struct answer ** find_answer (cpp_hashnode *, const struct answer *);
+static bool parse_answer (cpp_reader *, int, source_location, cpp_macro **);
+static cpp_hashnode *parse_assertion (cpp_reader *, int, cpp_macro **);
+static cpp_macro **find_answer (cpp_hashnode *, const cpp_macro *);
 static void handle_assertion (cpp_reader *, const char *, int);
 static void do_pragma_push_macro (cpp_reader *);
 static void do_pragma_pop_macro (cpp_reader *);
@@ -227,7 +228,7 @@
 /* Helper function for check_oel.  */
 
 static void
-check_eol_1 (cpp_reader *pfile, bool expand, int reason)
+check_eol_1 (cpp_reader *pfile, bool expand, enum cpp_warning_reason reason)
 {
   if (! SEEN_EOL () && (expand
 			? cpp_get_token (pfile)
@@ -527,10 +528,10 @@
 	      source_range misspelled_token_range
 		= get_range_from_loc (pfile->line_table, dname->src_loc);
 	      richloc.add_fixit_replace (misspelled_token_range, hint);
-	      cpp_error_at_richloc (pfile, CPP_DL_ERROR, &richloc,
-				    "invalid preprocessing directive #%s;"
-				    " did you mean #%s?",
-				    unrecognized, hint);
+	      cpp_error_at (pfile, CPP_DL_ERROR, &richloc,
+			    "invalid preprocessing directive #%s;"
+			    " did you mean #%s?",
+			    unrecognized, hint);
 	    }
 	  else
 	    cpp_error (pfile, CPP_DL_ERROR,
@@ -665,12 +666,12 @@
 
       /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified
 	 identifier is not currently defined as a macro name.  */
-      if (node->type == NT_MACRO)
+      if (cpp_macro_p (node))
 	{
 	  if (node->flags & NODE_WARN)
 	    cpp_error (pfile, CPP_DL_WARNING,
 		       "undefining \"%s\"", NODE_NAME (node));
-	  else if ((node->flags & NODE_BUILTIN)
+	  else if (cpp_builtin_macro_p (node)
 		   && CPP_OPTION (pfile, warn_builtin_macro_redefined))
 	    cpp_warning_with_line (pfile, CPP_W_BUILTIN_MACRO_REDEFINED,
 				   pfile->directive_line, 0,
@@ -695,7 +696,8 @@
   /* Body of _cpp_free_definition inlined here for speed.
      Macros and assertions no longer have anything to free.  */
   h->type = NT_VOID;
-  h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED);
+  h->value.answers = NULL;
+  h->flags &= ~(NODE_POISONED|NODE_DISABLED|NODE_USED);
   return 1;
 }
 
@@ -1088,10 +1090,10 @@
       /* Reread map since cpp_get_token can invalidate it with a
 	 reallocation.  */
       map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
-      const line_map_ordinary *from;      
+      const line_map_ordinary *from
+	= linemap_included_from_linemap (line_table, map);
       if (MAIN_FILE_P (map)
-	  || (new_file
-	      && (from = INCLUDED_FROM (pfile->line_table, map)) != NULL
+	  || (from
 	      && filename_cmp (ORDINARY_MAP_FILE_NAME (from), new_file) != 0))
 	{
 	  cpp_warning (pfile, CPP_W_NONE,
@@ -1139,7 +1141,8 @@
 /* Report a warning or error detected by the program we are
    processing.  Use the directive's tokens in the error message.  */
 static void
-do_diagnostic (cpp_reader *pfile, int code, int reason, int print_dir)
+do_diagnostic (cpp_reader *pfile, enum cpp_diagnostic_level code,
+	       enum cpp_warning_reason reason, int print_dir)
 {
   const unsigned char *dir_name;
   unsigned char *line;
@@ -1165,7 +1168,7 @@
 static void
 do_error (cpp_reader *pfile)
 {
-  do_diagnostic (pfile, CPP_DL_ERROR, 0, 1);
+  do_diagnostic (pfile, CPP_DL_ERROR, CPP_W_NONE, 1);
 }
 
 static void
@@ -1666,7 +1669,7 @@
       if (hp->flags & NODE_POISONED)
 	continue;
 
-      if (hp->type == NT_MACRO)
+      if (cpp_macro_p (hp))
 	cpp_error (pfile, CPP_DL_WARNING, "poisoning existing macro \"%s\"",
 		   NODE_NAME (hp));
       _cpp_free_definition (hp);
@@ -1719,7 +1722,7 @@
       if (cpp_get_token (pfile)->type != CPP_EOF)
 	{
 	  _cpp_backup_tokens (pfile, 1);
-	  do_diagnostic (pfile, CPP_DL_WARNING, 0, 0);
+	  do_diagnostic (pfile, CPP_DL_WARNING, CPP_W_NONE, 0);
 	}
     }
 
@@ -1960,26 +1963,9 @@
 	     the powerpc and spu ports using conditional macros for 'vector',
 	     'bool', and 'pixel' to act as conditional keywords.  This messes
 	     up tests like #ifndef bool.  */
-	  skip = (node->type != NT_MACRO
-		  || ((node->flags & NODE_CONDITIONAL) != 0));
+	  skip = !cpp_macro_p (node) || (node->flags & NODE_CONDITIONAL);
 	  _cpp_mark_macro_used (node);
-	  if (!(node->flags & NODE_USED))
-	    {
-	      node->flags |= NODE_USED;
-	      if (node->type == NT_MACRO)
-		{
-		  if ((node->flags & NODE_BUILTIN)
-		      && pfile->cb.user_builtin_macro)
-		    pfile->cb.user_builtin_macro (pfile, node);
-		  if (pfile->cb.used_define)
-		    pfile->cb.used_define (pfile, pfile->directive_line, node);
-		}
-	      else
-		{
-		  if (pfile->cb.used_undef)
-		    pfile->cb.used_undef (pfile, pfile->directive_line, node);
-		}
-	    }
+	  _cpp_maybe_notify_macro_use (pfile, node);
 	  if (pfile->cb.used)
 	    pfile->cb.used (pfile, pfile->directive_line, node);
 	  check_eol (pfile, false);
@@ -2006,26 +1992,10 @@
 	     the powerpc and spu ports using conditional macros for 'vector',
 	     'bool', and 'pixel' to act as conditional keywords.  This messes
 	     up tests like #ifndef bool.  */
-	  skip = (node->type == NT_MACRO
-		  && ((node->flags & NODE_CONDITIONAL) == 0));
+	  skip = (cpp_macro_p (node)
+		  && !(node->flags & NODE_CONDITIONAL));
 	  _cpp_mark_macro_used (node);
-	  if (!(node->flags & NODE_USED))
-	    {
-	      node->flags |= NODE_USED;
-	      if (node->type == NT_MACRO)
-		{
-		  if ((node->flags & NODE_BUILTIN)
-		      && pfile->cb.user_builtin_macro)
-		    pfile->cb.user_builtin_macro (pfile, node);
-		  if (pfile->cb.used_define)
-		    pfile->cb.used_define (pfile, pfile->directive_line, node);
-		}
-	      else
-		{
-		  if (pfile->cb.used_undef)
-		    pfile->cb.used_undef (pfile, pfile->directive_line, node);
-		}
-	    }
+	  _cpp_maybe_notify_macro_use (pfile, node);
 	  if (pfile->cb.used)
 	    pfile->cb.used (pfile, pfile->directive_line, node);
 	  check_eol (pfile, false);
@@ -2182,17 +2152,13 @@
    storage, i.e. the #assert case.  Returns 0 on success, and sets
    ANSWERP to point to the answer.  PRED_LOC is the location of the
    predicate.  */
-static int
-parse_answer (cpp_reader *pfile, struct answer **answerp, int type,
-	      source_location pred_loc)
+static bool
+parse_answer (cpp_reader *pfile, int type, source_location pred_loc,
+	      cpp_macro **answer_ptr)
 {
-  const cpp_token *paren;
-  struct answer *answer;
-  unsigned int acount;
-
   /* In a conditional, it is legal to not have an open paren.  We
      should save the following token in this case.  */
-  paren = cpp_get_token (pfile);
+  const cpp_token *paren = cpp_get_token (pfile);
 
   /* If not a paren, see if we're OK.  */
   if (paren->type != CPP_OPEN_PAREN)
@@ -2202,23 +2168,26 @@
       if (type == T_IF)
 	{
 	  _cpp_backup_tokens (pfile, 1);
-	  return 0;
+	  return true;
 	}
 
       /* #unassert with no answer is valid - it removes all answers.  */
       if (type == T_UNASSERT && paren->type == CPP_EOF)
-	return 0;
+	return true;
 
       cpp_error_with_line (pfile, CPP_DL_ERROR, pred_loc, 0,
 			   "missing '(' after predicate");
-      return 1;
+      return false;
     }
 
-  for (acount = 0;; acount++)
+  cpp_macro *answer = _cpp_new_macro (pfile, cmk_assert,
+				      _cpp_reserve_room (pfile, 0,
+							 sizeof (cpp_macro)));
+  answer->parm.next = NULL;
+  unsigned count = 0;
+  for (;;)
     {
-      size_t room_needed;
       const cpp_token *token = cpp_get_token (pfile);
-      cpp_token *dest;
 
       if (token->type == CPP_CLOSE_PAREN)
 	break;
@@ -2226,57 +2195,52 @@
       if (token->type == CPP_EOF)
 	{
 	  cpp_error (pfile, CPP_DL_ERROR, "missing ')' to complete answer");
-	  return 1;
+	  return false;
 	}
 
-      /* struct answer includes the space for one token.  */
-      room_needed = (sizeof (struct answer) + acount * sizeof (cpp_token));
-
-      if (BUFF_ROOM (pfile->a_buff) < room_needed)
-	_cpp_extend_buff (pfile, &pfile->a_buff, sizeof (struct answer));
-
-      dest = &((struct answer *) BUFF_FRONT (pfile->a_buff))->first[acount];
-      *dest = *token;
-
-      /* Drop whitespace at start, for answer equivalence purposes.  */
-      if (acount == 0)
-	dest->flags &= ~PREV_WHITE;
+      answer = (cpp_macro *)_cpp_reserve_room
+	(pfile, sizeof (cpp_macro) + count * sizeof (cpp_token),
+	 sizeof (cpp_token));
+      answer->exp.tokens[count++] = *token;
     }
 
-  if (acount == 0)
+  if (!count)
     {
       cpp_error (pfile, CPP_DL_ERROR, "predicate's answer is empty");
-      return 1;
+      return false;
     }
 
-  answer = (struct answer *) BUFF_FRONT (pfile->a_buff);
-  answer->count = acount;
-  answer->next = NULL;
-  *answerp = answer;
+  /* Drop whitespace at start, for answer equivalence purposes.  */
+  answer->exp.tokens[0].flags &= ~PREV_WHITE;
 
-  return 0;
+  answer->count = count;
+  *answer_ptr = answer;
+
+  return true;
 }
 
 /* Parses an assertion directive of type TYPE, returning a pointer to
-   the hash node of the predicate, or 0 on error.  If an answer was
-   supplied, it is placed in ANSWERP, otherwise it is set to 0.  */
+   the hash node of the predicate, or 0 on error.  The node is
+   guaranteed to be disjoint from the macro namespace, so can only
+   have type 'NT_VOID'.  If an answer was supplied, it is placed in
+   *ANSWER_PTR, which is otherwise set to 0.  */
 static cpp_hashnode *
-parse_assertion (cpp_reader *pfile, struct answer **answerp, int type)
+parse_assertion (cpp_reader *pfile, int type, cpp_macro **answer_ptr)
 {
   cpp_hashnode *result = 0;
-  const cpp_token *predicate;
 
   /* We don't expand predicates or answers.  */
   pfile->state.prevent_expansion++;
 
-  *answerp = 0;
-  predicate = cpp_get_token (pfile);
+  *answer_ptr = NULL;
+
+  const cpp_token *predicate = cpp_get_token (pfile);
   if (predicate->type == CPP_EOF)
     cpp_error (pfile, CPP_DL_ERROR, "assertion without predicate");
   else if (predicate->type != CPP_NAME)
     cpp_error_with_line (pfile, CPP_DL_ERROR, predicate->src_loc, 0,
 			 "predicate must be an identifier");
-  else if (parse_answer (pfile, answerp, type, predicate->src_loc) == 0)
+  else if (parse_answer (pfile, type, predicate->src_loc, answer_ptr))
     {
       unsigned int len = NODE_LEN (predicate->val.node.node);
       unsigned char *sym = (unsigned char *) alloca (len + 1);
@@ -2288,25 +2252,27 @@
     }
 
   pfile->state.prevent_expansion--;
+
   return result;
 }
 
 /* Returns a pointer to the pointer to CANDIDATE in the answer chain,
    or a pointer to NULL if the answer is not in the chain.  */
-static struct answer **
-find_answer (cpp_hashnode *node, const struct answer *candidate)
+static cpp_macro **
+find_answer (cpp_hashnode *node, const cpp_macro *candidate)
 {
   unsigned int i;
-  struct answer **result;
+  cpp_macro **result = NULL;
 
-  for (result = &node->value.answers; *result; result = &(*result)->next)
+  for (result = &node->value.answers; *result; result = &(*result)->parm.next)
     {
-      struct answer *answer = *result;
+      cpp_macro *answer = *result;
 
       if (answer->count == candidate->count)
 	{
 	  for (i = 0; i < answer->count; i++)
-	    if (! _cpp_equiv_tokens (&answer->first[i], &candidate->first[i]))
+	    if (!_cpp_equiv_tokens (&answer->exp.tokens[i],
+				    &candidate->exp.tokens[i]))
 	      break;
 
 	  if (i == answer->count)
@@ -2323,18 +2289,18 @@
 int
 _cpp_test_assertion (cpp_reader *pfile, unsigned int *value)
 {
-  struct answer *answer;
-  cpp_hashnode *node;
-
-  node = parse_assertion (pfile, &answer, T_IF);
+  cpp_macro *answer;
+  cpp_hashnode *node = parse_assertion (pfile, T_IF, &answer);
 
   /* For recovery, an erroneous assertion expression is handled as a
      failing assertion.  */
   *value = 0;
 
   if (node)
-    *value = (node->type == NT_ASSERTION &&
-	      (answer == 0 || *find_answer (node, answer) != 0));
+    {
+      if (node->value.answers)
+	*value = !answer || *find_answer (node, answer);
+    }
   else if (pfile->cur_token[-1].type == CPP_EOF)
     _cpp_backup_tokens (pfile, 1);
 
@@ -2346,43 +2312,29 @@
 static void
 do_assert (cpp_reader *pfile)
 {
-  struct answer *new_answer;
-  cpp_hashnode *node;
+  cpp_macro *answer;
+  cpp_hashnode *node = parse_assertion (pfile, T_ASSERT, &answer);
 
-  node = parse_assertion (pfile, &new_answer, T_ASSERT);
   if (node)
     {
-      size_t answer_size;
-
       /* Place the new answer in the answer list.  First check there
          is not a duplicate.  */
-      new_answer->next = 0;
-      if (node->type == NT_ASSERTION)
+      if (*find_answer (node, answer))
 	{
-	  if (*find_answer (node, new_answer))
-	    {
-	      cpp_error (pfile, CPP_DL_WARNING, "\"%s\" re-asserted",
-			 NODE_NAME (node) + 1);
-	      return;
-	    }
-	  new_answer->next = node->value.answers;
+	  cpp_error (pfile, CPP_DL_WARNING, "\"%s\" re-asserted",
+		     NODE_NAME (node) + 1);
+	  return;
 	}
 
-      answer_size = sizeof (struct answer) + ((new_answer->count - 1)
-					      * sizeof (cpp_token));
-      /* Commit or allocate storage for the object.  */
-      if (pfile->hash_table->alloc_subobject)
-	{
-	  struct answer *temp_answer = new_answer;
-	  new_answer = (struct answer *) pfile->hash_table->alloc_subobject
-            (answer_size);
-	  memcpy (new_answer, temp_answer, answer_size);
-	}
-      else
-	BUFF_FRONT (pfile->a_buff) += answer_size;
+      /* Commit or allocate storage for the answer.  */
+      answer = (cpp_macro *)_cpp_commit_buff
+	(pfile, sizeof (cpp_macro) - sizeof (cpp_token)
+	 + sizeof (cpp_token) * answer->count);
 
-      node->type = NT_ASSERTION;
-      node->value.answers = new_answer;
+      /* Chain into the list.  */
+      answer->parm.next = node->value.answers;
+      node->value.answers = answer;
+
       check_eol (pfile, false);
     }
 }
@@ -2391,25 +2343,19 @@
 static void
 do_unassert (cpp_reader *pfile)
 {
-  cpp_hashnode *node;
-  struct answer *answer;
+  cpp_macro *answer;
+  cpp_hashnode *node = parse_assertion (pfile, T_UNASSERT, &answer);
 
-  node = parse_assertion (pfile, &answer, T_UNASSERT);
   /* It isn't an error to #unassert something that isn't asserted.  */
-  if (node && node->type == NT_ASSERTION)
+  if (node)
     {
       if (answer)
 	{
-	  struct answer **p = find_answer (node, answer), *temp;
+	  cpp_macro **p = find_answer (node, answer);
 
-	  /* Remove the answer from the list.  */
-	  temp = *p;
-	  if (temp)
-	    *p = temp->next;
-
-	  /* Did we free the last answer?  */
-	  if (node->value.answers == 0)
-	    node->type = NT_VOID;
+	  /* Remove the assert from the list.  */
+	  if (cpp_macro *temp = *p)
+	    *p = temp->parm.next;
 
 	  check_eol (pfile, false);
 	}
@@ -2508,18 +2454,18 @@
   if (pfile->cb.before_define)
     pfile->cb.before_define (pfile);
 
-  if (node->type == NT_MACRO)
+  if (cpp_macro_p (node))
     {
       if (pfile->cb.undef)
 	pfile->cb.undef (pfile, pfile->directive_line, node);
       if (CPP_OPTION (pfile, warn_unused_macros))
 	_cpp_warn_if_unused_macro (pfile, node, NULL);
+      _cpp_free_definition (node);
     }
-  if (node->type != NT_VOID)
-    _cpp_free_definition (node);
 
   if (c->is_undef)
     return;
+
   {
     size_t namelen;
     const uchar *dn;
@@ -2530,8 +2476,6 @@
     h = cpp_lookup (pfile, c->definition, namelen);
     dn = c->definition + namelen;
 
-    h->type = NT_VOID;
-    h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED);
     nbuf = cpp_push_buffer (pfile, dn, ustrchr (dn, '\n') - dn, true);
     if (nbuf != NULL)
       {