OSDN Git Service

* cpphash.h (struct cpp_buffer): Move saved_flags from cpp_reader.
[pf3gnuchains/gcc-fork.git] / gcc / cpplex.c
index fb5eec5..3ff23b4 100644 (file)
@@ -159,9 +159,13 @@ trigraph_ok (pfile, from_char)
                               "trigraph ??%c converted to %c",
                               (int) from_char,
                               (int) _cpp_trigraph_map[from_char]);
-      else
-       cpp_warning_with_line (pfile, buffer->lineno, CPP_BUF_COL (buffer) - 2,
-                              "trigraph ??%c ignored", (int) from_char);
+      else if (buffer->cur != buffer->last_Wtrigraphs)
+       {
+         buffer->last_Wtrigraphs = buffer->cur;
+         cpp_warning_with_line (pfile, buffer->lineno,
+                                CPP_BUF_COL (buffer) - 2,
+                                "trigraph ??%c ignored", (int) from_char);
+       }
     }
 
   return accept;
@@ -242,7 +246,7 @@ skip_escaped_newlines (buffer, next)
              break;
            }
 
-         if (space)
+         if (space && !buffer->pfile->state.lexing_comment)
            cpp_warning (buffer->pfile,
                         "backslash and newline separated by space");
 
@@ -517,10 +521,10 @@ parse_identifier (pfile, c)
        cpp_error (pfile, "attempt to use poisoned \"%s\"", result->name);
 
       /* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the
-        replacement list of a variable-arguments macro.  */
+        replacement list of a variadic macro.  */
       if (result == pfile->spec_nodes.n__VA_ARGS__
          && !pfile->state.va_args_ok)
-       cpp_pedwarn (pfile, "__VA_ARGS__ can only appear in the expansion of a C99 variable-argument macro");
+       cpp_pedwarn (pfile, "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro");
     }
 
   return result;
@@ -535,7 +539,7 @@ parse_number (pfile, number, c, leading_period)
      int leading_period;
 {
   cpp_buffer *buffer = pfile->buffer;
-  cpp_pool *pool = pfile->string_pool;
+  cpp_pool *pool = &pfile->ident_pool;
   unsigned char *dest, *limit;
 
   dest = POOL_FRONT (pool);
@@ -614,7 +618,7 @@ unescaped_terminator_p (pfile, dest)
   if (pfile->state.angled_headers)
     return 1;
 
-  start = POOL_FRONT (pfile->string_pool);
+  start = POOL_FRONT (&pfile->ident_pool);
 
   /* An odd number of consecutive backslashes represents an escaped
      terminator.  */
@@ -636,7 +640,7 @@ parse_string (pfile, token, terminator)
      cppchar_t terminator;
 {
   cpp_buffer *buffer = pfile->buffer;
-  cpp_pool *pool = pfile->string_pool;
+  cpp_pool *pool = &pfile->ident_pool;
   unsigned char *dest, *limit;
   cppchar_t c;
   unsigned int nulls = 0;
@@ -669,7 +673,7 @@ parse_string (pfile, token, terminator)
          /* In assembly language, silently terminate string and
             character literals at end of line.  This is a kludge
             around not knowing where comments are.  */
-         if (CPP_OPTION (pfile, lang_asm) && terminator != '>')
+         if (CPP_OPTION (pfile, lang) == CLK_ASM && terminator != '>')
            break;
 
          /* Character constants and header names may not extend over
@@ -734,7 +738,7 @@ save_comment (pfile, token, from)
      line, which we don't want to save in the comment.  */
   if (pfile->buffer->read_ahead != EOF)
     len--;
-  buffer = _cpp_pool_alloc (pfile->string_pool, len);
+  buffer = _cpp_pool_alloc (&pfile->ident_pool, len);
   
   token->type = CPP_COMMENT;
   token->val.str.len = len;
@@ -846,13 +850,15 @@ _cpp_lex_token (pfile, result)
   cppchar_t c;
   cpp_buffer *buffer;
   const unsigned char *comment_start;
-  unsigned char was_skip_newlines = pfile->state.skip_newlines;
-  unsigned char newline_in_args = 0;
+  unsigned char bol;
 
+ skip:
+  bol = pfile->state.next_bol;
  done_directive:
   buffer = pfile->buffer;
-  pfile->state.skip_newlines = 0;
-  result->flags = 0;
+  pfile->state.next_bol = 0;
+  result->flags = buffer->saved_flags;
+  buffer->saved_flags = 0;
  next_char:
   pfile->lexer_pos.line = buffer->lineno;
  next_char2:
@@ -874,9 +880,11 @@ _cpp_lex_token (pfile, result)
         line and _Pragma buffers.  */
       if (pfile->lexer_pos.col != 0 && !buffer->from_stage3)
        cpp_pedwarn (pfile, "no newline at end of file");
-      pfile->state.skip_newlines = 1;
+      pfile->state.next_bol = 1;
+      pfile->skipping = 0;     /* In case missing #endif.  */
       result->type = CPP_EOF;
-      break;
+      /* Don't do MI optimisation.  */
+      return;
 
     case ' ': case '\t': case '\f': case '\v': case '\0':
       skip_whitespace (pfile, c);
@@ -884,36 +892,24 @@ _cpp_lex_token (pfile, result)
       goto next_char2;
 
     case '\n': case '\r':
-      /* Don't let directives spill over to the next line.  */
-      if (pfile->state.in_directive)
-       buffer->read_ahead = c;
-      else
+      if (!pfile->state.in_directive)
        {
          handle_newline (buffer, c);
-
+         bol = 1;
          pfile->lexer_pos.output_line = buffer->lineno;
-
-         /* Skip newlines in macro arguments (except in directives).  */
-         if (pfile->state.parsing_args)
-           {
-             /* Set the whitespace flag.   */
-             newline_in_args = 1;
-             result->flags |= PREV_WHITE;
-             goto next_char;
-           }
-
-         if (was_skip_newlines)
-           {
-             /* Clear any whitespace flag.   */
-             result->flags &= ~PREV_WHITE;
-             goto next_char;
-           }
+         /* This is a new line, so clear any white space flag.
+            Newlines in arguments are white space (6.10.3.10);
+            parse_arg takes care of that.  */
+         result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
+         goto next_char;
        }
 
-      /* Next we're at BOL, so skip new lines.  */
-      pfile->state.skip_newlines = 1;
+      /* Don't let directives spill over to the next line.  */
+      buffer->read_ahead = c;
+      pfile->state.next_bol = 1;
       result->type = CPP_EOF;
-      break;
+      /* Don't break; pfile->skipping might be true.  */
+      return;
 
     case '?':
     case '\\':
@@ -1012,11 +1008,9 @@ _cpp_lex_token (pfile, result)
              && !CPP_IN_SYSTEM_HEADER (pfile))
            break;
 
-         /* We silently allow C++ comments in system headers,
-            irrespective of conformance mode, because lots of
-            broken systems do that and trying to clean it up in
-            fixincludes is a nightmare.  */
-         if (CPP_OPTION (pfile, c89) && CPP_PEDANTIC (pfile)
+         /* Warn about comments only if pedantically GNUC89, and not
+            in system headers.  */
+         if (CPP_OPTION (pfile, lang) == CLK_GNUC89 && CPP_PEDANTIC (pfile)
              && ! buffer->warned_cplusplus_comments)
            {
              cpp_pedwarn (pfile,
@@ -1042,7 +1036,8 @@ _cpp_lex_token (pfile, result)
 
       /* Save the comment as a token in its own right.  */
       save_comment (pfile, result, comment_start);
-      break;
+      /* Don't do MI optimisation.  */
+      return;
 
     case '<':
       if (pfile->state.angled_headers)
@@ -1172,12 +1167,16 @@ _cpp_lex_token (pfile, result)
        c = get_effective_char (buffer);
 
       if (c == '#')
-       ACCEPT_CHAR (CPP_PASTE);
-      else
        {
-         result->type = CPP_HASH;
-       do_hash:
-         if (newline_in_args)
+         ACCEPT_CHAR (CPP_PASTE);
+         break;
+       }
+
+      result->type = CPP_HASH;
+    do_hash:
+      if (bol)
+       {
+         if (pfile->state.parsing_args)
            {
              /* 6.10.3 paragraph 11: If there are sequences of
                 preprocessing tokens within the list of arguments that
@@ -1193,18 +1192,18 @@ _cpp_lex_token (pfile, result)
              /* Put a '#' in lookahead, return CPP_EOF for parse_arg.  */
              buffer->extra_char = buffer->read_ahead;
              buffer->read_ahead = '#';
-             pfile->state.skip_newlines = 1;
+             pfile->state.next_bol = 1;
              result->type = CPP_EOF;
 
              /* Get whitespace right - newline_in_args sets it.  */
              if (pfile->lexer_pos.col == 1)
-               result->flags &= ~PREV_WHITE;
+               result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
            }
-         else if (was_skip_newlines)
+         else
            {
              /* This is the hash introducing a directive.  */
              if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE))
-               goto done_directive; /* was_skip_newlines still 1.  */
+               goto done_directive; /* bol still 1.  */
              /* This is in fact an assembler #.  */
            }
        }
@@ -1277,6 +1276,13 @@ _cpp_lex_token (pfile, result)
       result->val.c = c;
       break;
     }
+
+  if (pfile->skipping)
+    goto skip;
+
+  /* If not in a directive, this token invalidates controlling macros.  */
+  if (!pfile->state.in_directive)
+    pfile->mi_state = MI_FAILED;
 }
 
 /* An upper bound on the number of bytes needed to spell a token,
@@ -1373,7 +1379,7 @@ cpp_token_as_text (pfile, token)
      const cpp_token *token;
 {
   unsigned int len = cpp_token_len (token);
-  unsigned char *start = _cpp_pool_alloc (&pfile->temp_string_pool, len), *end;
+  unsigned char *start = _cpp_pool_alloc (&pfile->ident_pool, len), *end;
 
   end = cpp_spell_token (pfile, token, start);
   end[0] = '\0';
@@ -1651,7 +1657,7 @@ cpp_avoid_paste (pfile, token1, token2)
     case CPP_OR:       return c == '|';
     case CPP_COLON:    return c == ':' || c == '>';
     case CPP_DEREF:    return c == '*';
-    case CPP_DOT:      return c == '.' || c == '%';
+    case CPP_DOT:      return c == '.' || c == '%' || b == CPP_NUMBER;
     case CPP_HASH:     return c == '#' || c == '%'; /* Digraph form.  */
     case CPP_NAME:     return ((b == CPP_NUMBER
                                 && name_p (pfile, &token2->val.str))
@@ -1677,12 +1683,12 @@ cpp_output_line (pfile, fp)
 {
   cpp_token token;
 
-  _cpp_get_token (pfile, &token);
+  cpp_get_token (pfile, &token);
   token.flags &= ~PREV_WHITE;
   while (token.type != CPP_EOF)
     {
       cpp_output_token (&token, fp);
-      _cpp_get_token (pfile, &token);
+      cpp_get_token (pfile, &token);
     }
 
   putc ('\n', fp);