OSDN Git Service

2002-03-03 Aldy Hernandez <aldyh@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / cpplex.c
index 45d28b6..c1dae50 100644 (file)
@@ -1,5 +1,5 @@
 /* CPP Library - lexical analysis.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002 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
@@ -97,7 +97,6 @@ static _cpp_buff *new_buff PARAMS ((size_t));
 
    Compares, the token TOKEN to the NUL-terminated string STRING.
    TOKEN must be a CPP_NAME.  Returns 1 for equal, 0 for unequal.  */
-
 int
 cpp_ideq (token, string)
      const cpp_token *token;
@@ -414,7 +413,6 @@ name_p (pfile, string)
    Poisson-like).  Second most common case is a new identifier, not
    split and no dollar sign.  The other possibilities are rare and
    have been relegated to parse_identifier_slow.  */
-
 static cpp_hashnode *
 parse_identifier (pfile)
      cpp_reader *pfile;
@@ -517,7 +515,9 @@ parse_identifier_slow (pfile, cur)
     ht_lookup (pfile->hash_table, obstack_finish (stack), len, HT_ALLOCED);
 }
 
-/* Parse a number, skipping embedded backslash-newlines.  */
+/* Parse a number, beginning with character C, skipping embedded
+   backslash-newlines.  LEADING_PERIOD is non-zero if there was a "."
+   before C.  Place the result in NUMBER.  */
 static void
 parse_number (pfile, number, c, leading_period)
      cpp_reader *pfile;
@@ -828,7 +828,10 @@ _cpp_lex_token (pfile)
          /* Is this a directive.  If _cpp_handle_directive returns
             false, it is an assembler #.  */
          if (result->type == CPP_HASH
-             && !pfile->state.parsing_args
+             /* 6.10.3 p 11: Directives in a list of macro arguments
+                gives undefined behavior.  This implementation
+                handles the directive as normal.  */
+             && pfile->state.parsing_args != 1
              && _cpp_handle_directive (pfile, result->flags & PREV_WHITE))
            continue;
          if (pfile->cb.line_change && !pfile->state.skipping)
@@ -1289,7 +1292,7 @@ _cpp_lex_direct (pfile)
   return result;
 }
 
-/* An upper bound on the number of bytes needed to spell a token,
+/* An upper bound on the number of bytes needed to spell TOKEN,
    including preceding whitespace.  */
 unsigned int
 cpp_token_len (token)
@@ -1383,8 +1386,8 @@ cpp_spell_token (pfile, token, buffer)
   return buffer;
 }
 
-/* Returns a token as a null-terminated string.  The string is
-   temporary, and automatically freed later.  Useful for diagnostics.  */
+/* Returns TOKEN spelt as a null-terminated string.  The string is
+   freed when the reader is destroyed.  Useful for diagnostics.  */
 unsigned char *
 cpp_token_as_text (pfile, token)
      cpp_reader *pfile;
@@ -1399,7 +1402,8 @@ cpp_token_as_text (pfile, token)
   return start;
 }
 
-/* Used by C front ends.  Should really move to using cpp_token_as_text.  */
+/* Used by C front ends, which really should move to using
+   cpp_token_as_text.  */
 const char *
 cpp_type2name (type)
      enum cpp_ttype type;
@@ -1508,7 +1512,6 @@ _cpp_equiv_tokens (a, b)
    accidental token paste for output.  For simplicity, it is
    conservative, and occasionally advises a space where one is not
    needed, e.g. "." and ".2".  */
-
 int
 cpp_avoid_paste (pfile, token1, token2)
      cpp_reader *pfile;
@@ -1632,7 +1635,7 @@ maybe_read_ucs (pfile, pstr, limit, pc)
     return 1;
 
   if (CPP_WTRADITIONAL (pfile))
-    cpp_warning (pfile, "the meaning of '\\%c' varies with -traditional", c);
+    cpp_warning (pfile, "the meaning of '\\%c' is different in traditional C", c);
 
   length = (c == 'u' ? 4: 8);
 
@@ -1685,18 +1688,15 @@ maybe_read_ucs (pfile, pstr, limit, pc)
 /* Interpret an escape sequence, and return its value.  PSTR points to
    the input pointer, which is just after the backslash.  LIMIT is how
    much text we have.  MASK is a bitmask for the precision for the
-   destination type (char or wchar_t).  TRADITIONAL, if true, does not
-   interpret escapes that did not exist in traditional C.
+   destination type (char or wchar_t).
 
    Handles all relevant diagnostics.  */
-
 unsigned int
-cpp_parse_escape (pfile, pstr, limit, mask, traditional)
+cpp_parse_escape (pfile, pstr, limit, mask)
      cpp_reader *pfile;
      const unsigned char **pstr;
      const unsigned char *limit;
      unsigned HOST_WIDE_INT mask;
-     int traditional;
 {
   int unknown = 0;
   const unsigned char *str = *pstr;
@@ -1720,9 +1720,8 @@ cpp_parse_escape (pfile, pstr, limit, mask, traditional)
 
     case 'a':
       if (CPP_WTRADITIONAL (pfile))
-       cpp_warning (pfile, "the meaning of '\\a' varies with -traditional");
-      if (!traditional)
-       c = TARGET_BELL;
+       cpp_warning (pfile, "the meaning of '\\a' is different in traditional C");
+      c = TARGET_BELL;
       break;
 
     case 'e': case 'E':
@@ -1737,9 +1736,8 @@ cpp_parse_escape (pfile, pstr, limit, mask, traditional)
 
     case 'x':
       if (CPP_WTRADITIONAL (pfile))
-       cpp_warning (pfile, "the meaning of '\\x' varies with -traditional");
+       cpp_warning (pfile, "the meaning of '\\x' is different in traditional C");
 
-      if (!traditional)
        {
          unsigned int i = 0, overflow = 0;
          int digits_found = 0;
@@ -1820,16 +1818,13 @@ cpp_parse_escape (pfile, pstr, limit, mask, traditional)
 #endif
 
 /* Interpret a (possibly wide) character constant in TOKEN.
-   WARN_MULTI warns about multi-character charconsts, if not
-   TRADITIONAL.  TRADITIONAL also indicates not to interpret escapes
-   that did not exist in traditional C.  PCHARS_SEEN points to a
-   variable that is filled in with the number of characters seen.  */
+   WARN_MULTI warns about multi-character charconsts.  PCHARS_SEEN points
+   to a variable that is filled in with the number of characters seen.  */
 HOST_WIDE_INT
-cpp_interpret_charconst (pfile, token, warn_multi, traditional, pchars_seen)
+cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen)
      cpp_reader *pfile;
      const cpp_token *token;
      int warn_multi;
-     int traditional;
      unsigned int *pchars_seen;
 {
   const unsigned char *str = token->val.str.text;
@@ -1838,6 +1833,7 @@ cpp_interpret_charconst (pfile, token, warn_multi, traditional, pchars_seen)
   unsigned int width, max_chars, c;
   unsigned HOST_WIDE_INT mask;
   HOST_WIDE_INT result = 0;
+  bool unsigned_p;
 
 #ifdef MULTIBYTE_CHARS
   (void) local_mbtowc (NULL, NULL, 0);
@@ -1845,9 +1841,15 @@ cpp_interpret_charconst (pfile, token, warn_multi, traditional, pchars_seen)
 
   /* Width in bits.  */
   if (token->type == CPP_CHAR)
-    width = MAX_CHAR_TYPE_SIZE;
+    {
+      width = MAX_CHAR_TYPE_SIZE;
+      unsigned_p = CPP_OPTION (pfile, signed_char) == 0;
+    }
   else
-    width = MAX_WCHAR_TYPE_SIZE;
+    {
+      width = MAX_WCHAR_TYPE_SIZE;
+      unsigned_p = WCHAR_UNSIGNED;
+    }
 
   if (width < HOST_BITS_PER_WIDE_INT)
     mask = ((unsigned HOST_WIDE_INT) 1 << width) - 1;
@@ -1877,7 +1879,7 @@ cpp_interpret_charconst (pfile, token, warn_multi, traditional, pchars_seen)
 #endif
 
       if (c == '\\')
-       c = cpp_parse_escape (pfile, &str, limit, mask, traditional);
+       c = cpp_parse_escape (pfile, &str, limit, mask);
 
 #ifdef MAP_CHARACTER
       if (ISPRINT (c))
@@ -1901,18 +1903,16 @@ cpp_interpret_charconst (pfile, token, warn_multi, traditional, pchars_seen)
       chars_seen = max_chars;
       cpp_warning (pfile, "character constant too long");
     }
-  else if (chars_seen > 1 && !traditional && warn_multi)
+  else if (chars_seen > 1 && warn_multi)
     cpp_warning (pfile, "multi-character character constant");
 
-  /* If char type is signed, sign-extend the constant.  The
-     __CHAR_UNSIGNED__ macro is set by the driver if appropriate.  */
-  if (token->type == CPP_CHAR && chars_seen)
+  /* If relevant type is signed, sign-extend the constant.  */
+  if (chars_seen)
     {
       unsigned int nbits = chars_seen * width;
 
       mask = (unsigned HOST_WIDE_INT) ~0 >> (HOST_BITS_PER_WIDE_INT - nbits);
-      if (pfile->spec_nodes.n__CHAR_UNSIGNED__->type == NT_MACRO
-         || ((result >> (nbits - 1)) & 1) == 0)
+      if (unsigned_p || ((result >> (nbits - 1)) & 1) == 0)
        result &= mask;
       else
        result |= ~mask;