OSDN Git Service

* cpphash.h (struct cpp_buffer): Move saved_flags from cpp_reader.
[pf3gnuchains/gcc-fork.git] / gcc / cpplex.c
index 68ceb36..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,14 +673,14 @@ 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
             multiple lines.  In Standard C, neither may strings.
             Unfortunately, we accept multiline strings as an
-            extension.  */
-         if (terminator != '"')
+            extension, except in #include family directives.  */
+         if (terminator != '"' || pfile->state.angled_headers)
            {
              unterminated (pfile, terminator);
              break;
@@ -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;
@@ -844,13 +848,17 @@ _cpp_lex_token (pfile, result)
      cpp_token *result;
 {
   cppchar_t c;
-  cpp_buffer *buffer = pfile->buffer;
+  cpp_buffer *buffer;
   const unsigned char *comment_start;
-  unsigned char was_skip_newlines = pfile->state.skip_newlines;
-  unsigned char newline_in_args = 0;
-
-  pfile->state.skip_newlines = 0;
-  result->flags = 0;
+  unsigned char bol;
+
+ skip:
+  bol = pfile->state.next_bol;
+ done_directive:
+  buffer = pfile->buffer;
+  pfile->state.next_bol = 0;
+  result->flags = buffer->saved_flags;
+  buffer->saved_flags = 0;
  next_char:
   pfile->lexer_pos.line = buffer->lineno;
  next_char2:
@@ -872,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);
@@ -882,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 '\\':
@@ -1010,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,
@@ -1040,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)
@@ -1160,19 +1157,54 @@ _cpp_lex_token (pfile, result)
       break;
          
     case '#':
-      if (get_effective_char (buffer) == '#')
-       ACCEPT_CHAR (CPP_PASTE);
+      c = buffer->extra_char;  /* Can be set by error condition below.  */
+      if (c != EOF)
+       {
+         buffer->read_ahead = c;
+         buffer->extra_char = EOF;
+       }
       else
+       c = get_effective_char (buffer);
+
+      if (c == '#')
        {
-         result->type = CPP_HASH;
-       do_hash:
-         /* CPP_DHASH is the hash introducing a directive.  */
-         if (was_skip_newlines || newline_in_args)
+         ACCEPT_CHAR (CPP_PASTE);
+         break;
+       }
+
+      result->type = CPP_HASH;
+    do_hash:
+      if (bol)
+       {
+         if (pfile->state.parsing_args)
            {
-             result->type = CPP_DHASH;
+             /* 6.10.3 paragraph 11: If there are sequences of
+                preprocessing tokens within the list of arguments that
+                would otherwise act as preprocessing directives, the
+                behavior is undefined.
+
+                This implementation will report a hard error, terminate
+                the macro invocation, and proceed to process the
+                directive.  */
+             cpp_error (pfile,
+                        "directives may not be used inside a macro argument");
+
+             /* Put a '#' in lookahead, return CPP_EOF for parse_arg.  */
+             buffer->extra_char = buffer->read_ahead;
+             buffer->read_ahead = '#';
+             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
+           {
+             /* This is the hash introducing a directive.  */
+             if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE))
+               goto done_directive; /* bol still 1.  */
+             /* This is in fact an assembler #.  */
            }
        }
       break;
@@ -1241,9 +1273,16 @@ _cpp_lex_token (pfile, result)
     random_char:
     default:
       result->type = CPP_OTHER;
-      result->val.aux = c;
+      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,
@@ -1321,7 +1360,7 @@ cpp_spell_token (pfile, token, buffer)
       break;
 
     case SPELL_CHAR:
-      *buffer++ = token->val.aux;
+      *buffer++ = token->val.c;
       break;
 
     case SPELL_NONE:
@@ -1340,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';
@@ -1410,7 +1449,7 @@ cpp_output_token (token, fp)
       break;
 
     case SPELL_CHAR:
-      putc (token->val.aux, fp);
+      putc (token->val.c, fp);
       break;
 
     case SPELL_NONE:
@@ -1431,9 +1470,9 @@ _cpp_equiv_tokens (a, b)
       case SPELL_OPERATOR:
        return 1;
       case SPELL_CHAR:
-       return a->val.aux == b->val.aux; /* Character.  */
+       return a->val.c == b->val.c; /* Character.  */
       case SPELL_NONE:
-       return (a->type != CPP_MACRO_ARG || a->val.aux == b->val.aux);
+       return (a->type != CPP_MACRO_ARG || a->val.arg_no == b->val.arg_no);
       case SPELL_IDENT:
        return a->val.node == b->val.node;
       case SPELL_STRING:
@@ -1565,7 +1604,7 @@ cpp_can_paste (pfile, token1, token2, digraph)
       break;
 
     case CPP_OTHER:
-      if (CPP_OPTION (pfile, objc) && token1->val.aux == '@')
+      if (CPP_OPTION (pfile, objc) && token1->val.c == '@')
        {
          if (b == CPP_NAME)    return CPP_NAME;
          if (b == CPP_STRING)  return CPP_OSTRING;
@@ -1618,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))
@@ -1627,7 +1666,7 @@ cpp_avoid_paste (pfile, token1, token2)
     case CPP_NUMBER:   return (b == CPP_NUMBER || b == CPP_NAME
                                || c == '.' || c == '+' || c == '-');
     case CPP_OTHER:    return (CPP_OPTION (pfile, objc)
-                               && token1->val.aux == '@'
+                               && token1->val.c == '@'
                                && (b == CPP_NAME || b == CPP_STRING));
     default:           break;
     }
@@ -1644,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);