/* 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
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;
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;
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;
/* 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)
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)
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;
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;
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;
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);
/* 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;
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':
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;
#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;
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);
/* 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;
#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))
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;