X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcpplex.c;h=169730d53aec29bb1d23454c8f2b5b63405d3f77;hb=df034f844ad35169ff0b9bc32ec6968b1d7d39cb;hp=0a260490af7e590ecc46e9d0228779efd64724f4;hpb=13c457e1923eefa04f4b52e5321ef6e2379d6a8b;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 0a260490af7..169730d53ae 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -22,6 +22,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "cpplib.h" #include "cpphash.h" @@ -71,16 +73,17 @@ static void adjust_column PARAMS ((cpp_reader *)); static int skip_whitespace PARAMS ((cpp_reader *, cppchar_t)); static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *)); static uchar *parse_slow PARAMS ((cpp_reader *, const uchar *, int, - unsigned int *)); + unsigned int *)); static void parse_number PARAMS ((cpp_reader *, cpp_string *, int)); static int unescaped_terminator_p PARAMS ((cpp_reader *, const uchar *)); static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t)); static bool trigraph_p PARAMS ((cpp_reader *)); static void save_comment PARAMS ((cpp_reader *, cpp_token *, const uchar *, cppchar_t)); +static bool continue_after_nul PARAMS ((cpp_reader *)); static int name_p PARAMS ((cpp_reader *, const cpp_string *)); static int maybe_read_ucs PARAMS ((cpp_reader *, const unsigned char **, - const unsigned char *, unsigned int *)); + const unsigned char *, cppchar_t *)); static tokenrun *next_tokenrun PARAMS ((tokenrun *)); static unsigned int hex_digit_value PARAMS ((unsigned int)); @@ -111,7 +114,7 @@ handle_newline (pfile) cpp_buffer *buffer = pfile->buffer; /* Handle CR-LF and LF-CR. Most other implementations (e.g. java) - only accept CR-LF; maybe we should fall back to that behaviour? */ + only accept CR-LF; maybe we should fall back to that behavior? */ if (buffer->cur[-1] + buffer->cur[0] == '\r' + '\n') buffer->cur++; @@ -125,7 +128,7 @@ handle_newline (pfile) the second '?'. Warn if necessary, and returns true if the sequence forms a - trigraph and the trigraph should be honoured. */ + trigraph and the trigraph should be honored. */ static bool trigraph_p (pfile) cpp_reader *pfile; @@ -246,12 +249,12 @@ get_effective_char (pfile) if (__builtin_expect (next == '?' || next == '\\', 0)) next = skip_escaped_newlines (pfile); - return next; + return next; } /* Skip a C-style block comment. We find the end of the comment by seeing if an asterisk is before every '/' we encounter. Returns - non-zero if comment terminated by EOF, zero otherwise. */ + nonzero if comment terminated by EOF, zero otherwise. */ static int skip_block_comment (pfile) cpp_reader *pfile; @@ -296,7 +299,7 @@ skip_block_comment (pfile) } /* Skip a C++ line comment, leaving buffer->cur pointing to the - terminating newline. Handles escaped newlines. Returns non-zero + terminating newline. Handles escaped newlines. Returns nonzero if a multiline comment. */ static int skip_line_comment (pfile) @@ -423,7 +426,7 @@ name_p (pfile, string) if (!is_idchar (string->text[i])) return 0; - return 1; + return 1; } /* Parse an identifier, skipping embedded backslash-newlines. This is @@ -532,15 +535,15 @@ parse_slow (pfile, cur, number_p, plen) /* Handle normal identifier characters in this loop. */ do - { + { prevc = c; - obstack_1grow (stack, c); + obstack_1grow (stack, c); - if (c == '$') - saw_dollar++; + if (c == '$') + saw_dollar++; - c = *buffer->cur++; - } + c = *buffer->cur++; + } while (is_idchar (c)); } @@ -560,7 +563,7 @@ parse_slow (pfile, cur, number_p, plen) } /* Parse a number, beginning with character C, skipping embedded - backslash-newlines. LEADING_PERIOD is non-zero if there was a "." + backslash-newlines. LEADING_PERIOD is nonzero if there was a "." before C. Place the result in NUMBER. */ static void parse_number (pfile, number, leading_period) @@ -604,7 +607,7 @@ unescaped_terminator_p (pfile, dest) { const unsigned char *start, *temp; - /* In #include-style directives, terminators are not escapeable. */ + /* In #include-style directives, terminators are not escapable. */ if (pfile->state.angled_headers) return 1; @@ -664,7 +667,7 @@ parse_string (pfile, token, terminator) if (char_len == -1) { cpp_error (pfile, DL_WARNING, - "ignoring invalid multibyte character"); + "ignoring invalid multibyte character"); char_len = 1; c = *buffer->cur++; } @@ -695,7 +698,7 @@ parse_string (pfile, token, terminator) unterminated: if (CPP_OPTION (pfile, lang) != CLK_ASM || terminator == '>') cpp_error (pfile, DL_ERROR, "missing terminating %c character", - terminator); + (int) terminator); buffer->cur--; break; } @@ -738,7 +741,7 @@ save_comment (pfile, token, from, type) { unsigned char *buffer; unsigned int len, clen; - + len = pfile->buffer->cur - from + 1; /* + 1 for the initial '/'. */ /* C++ comments probably (not definitely) have moved past a new @@ -755,7 +758,7 @@ save_comment (pfile, token, from, type) clen = (pfile->state.in_directive && type == '/') ? len + 2 : len; buffer = _cpp_unaligned_alloc (pfile, clen); - + token->type = CPP_COMMENT; token->val.str.len = clen; token->val.str.text = buffer; @@ -877,6 +880,57 @@ _cpp_lex_token (pfile) return result; } +/* A NUL terminates the current buffer. For ISO preprocessing this is + EOF, but for traditional preprocessing it indicates we need a line + refill. Returns TRUE to continue preprocessing a new buffer, FALSE + to return a CPP_EOF to the caller. */ +static bool +continue_after_nul (pfile) + cpp_reader *pfile; +{ + cpp_buffer *buffer = pfile->buffer; + bool more = false; + + buffer->saved_flags = BOL; + if (CPP_OPTION (pfile, traditional)) + { + if (pfile->state.in_directive) + return false; + + _cpp_remove_overlay (pfile); + more = _cpp_read_logical_line_trad (pfile); + _cpp_overlay_buffer (pfile, pfile->out.base, + pfile->out.cur - pfile->out.base); + pfile->line = pfile->out.first_line; + } + else + { + /* Stop parsing arguments with a CPP_EOF. When we finally come + back here, do the work of popping the buffer. */ + if (!pfile->state.parsing_args) + { + if (buffer->cur != buffer->line_base) + { + /* Non-empty files should end in a newline. Don't warn + for command line and _Pragma buffers. */ + if (!buffer->from_stage3) + cpp_error (pfile, DL_PEDWARN, "no newline at end of file"); + handle_newline (pfile); + } + + /* Similarly, finish an in-progress directive with CPP_EOF + before popping the buffer. */ + if (!pfile->state.in_directive && buffer->prev) + { + more = !buffer->return_at_eof; + _cpp_pop_buffer (pfile); + } + } + } + + return more; +} + #define IF_NEXT_IS(CHAR, THEN_TYPE, ELSE_TYPE) \ do { \ if (get_effective_char (pfile) == CHAR) \ @@ -927,30 +981,10 @@ _cpp_lex_direct (pfile) if (skip_whitespace (pfile, c)) goto skipped_white; - /* EOF. */ + /* End of buffer. */ buffer->cur--; - buffer->saved_flags = BOL; - if (!pfile->state.parsing_args && !pfile->state.in_directive) - { - if (buffer->cur != buffer->line_base) - { - /* Non-empty files should end in a newline. Don't warn - for command line and _Pragma buffers. */ - if (!buffer->from_stage3) - cpp_error (pfile, DL_PEDWARN, "no newline at end of file"); - handle_newline (pfile); - } - - /* Don't pop the last buffer. */ - if (buffer->prev) - { - unsigned char stop = buffer->return_at_eof; - - _cpp_pop_buffer (pfile); - if (!stop) - goto fresh_line; - } - } + if (continue_after_nul (pfile)) + goto fresh_line; result->type = CPP_EOF; break; @@ -1006,19 +1040,19 @@ _cpp_lex_direct (pfile) case 'L': /* 'L' may introduce wide characters or strings. */ - { - const unsigned char *pos = buffer->cur; + { + const unsigned char *pos = buffer->cur; - c = get_effective_char (pfile); - if (c == '\'' || c == '"') - { - result->type = (c == '"' ? CPP_WSTRING: CPP_WCHAR); - parse_string (pfile, result, c); - break; - } - buffer->cur = pos; - } - /* Fall through. */ + c = get_effective_char (pfile); + if (c == '\'' || c == '"') + { + result->type = (c == '"' ? CPP_WSTRING: CPP_WCHAR); + parse_string (pfile, result, c); + break; + } + buffer->cur = pos; + } + /* Fall through. */ start_ident: case '_': @@ -1039,7 +1073,7 @@ _cpp_lex_direct (pfile) if (result->val.node->flags & NODE_OPERATOR) { result->flags |= NAMED_OP; - result->type = result->val.node->value.operator; + result->type = result->val.node->directive_index; } break; @@ -1068,7 +1102,7 @@ _cpp_lex_direct (pfile) && ! buffer->warned_cplusplus_comments) { cpp_error (pfile, DL_PEDWARN, - "C++ style comments are not allowed in ISO C89"); + "C++ style comments are not allowed in ISO C90"); cpp_error (pfile, DL_PEDWARN, "(this will be reported only once per input file)"); buffer->warned_cplusplus_comments = 1; @@ -1251,7 +1285,7 @@ _cpp_lex_direct (pfile) result->type = CPP_AND; } break; - + case '|': c = get_effective_char (pfile); if (c == '|') @@ -1297,7 +1331,7 @@ _cpp_lex_direct (pfile) case '}': result->type = CPP_CLOSE_BRACE; break; case ';': result->type = CPP_SEMICOLON; break; - /* @ is a punctuator in Objective C. */ + /* @ is a punctuator in Objective-C. */ case '@': result->type = CPP_ATSIGN; break; case '$': @@ -1358,7 +1392,7 @@ cpp_spell_token (pfile, token, buffer) goto spell_ident; else spelling = TOKEN_NAME (token); - + while ((c = *spelling++) != '\0') *buffer++ = c; } @@ -1648,7 +1682,7 @@ maybe_read_ucs (pfile, pstr, limit, pc) cpp_reader *pfile; const unsigned char **pstr; const unsigned char *limit; - unsigned int *pc; + cppchar_t *pc; { const unsigned char *p = *pstr; unsigned int code = 0; @@ -1763,10 +1797,10 @@ cpp_parse_escape (pfile, pstr, limit, wide) case 'e': case 'E': if (CPP_PEDANTIC (pfile)) cpp_error (pfile, DL_PEDWARN, - "non-ISO-standard escape sequence, '\\%c'", c); + "non-ISO-standard escape sequence, '\\%c'", (int) c); c = TARGET_ESC; break; - + case 'u': case 'U': unknown = maybe_read_ucs (pfile, &str, limit, &c); break; @@ -1776,33 +1810,33 @@ cpp_parse_escape (pfile, pstr, limit, wide) cpp_error (pfile, DL_WARNING, "the meaning of '\\x' is different in traditional C"); - { - cppchar_t i = 0, overflow = 0; - int digits_found = 0; + { + cppchar_t i = 0, overflow = 0; + int digits_found = 0; - while (str < limit) - { - c = *str; - if (! ISXDIGIT (c)) - break; - str++; - overflow |= i ^ (i << 4 >> 4); - i = (i << 4) + hex_digit_value (c); - digits_found = 1; - } + while (str < limit) + { + c = *str; + if (! ISXDIGIT (c)) + break; + str++; + overflow |= i ^ (i << 4 >> 4); + i = (i << 4) + hex_digit_value (c); + digits_found = 1; + } - if (!digits_found) - cpp_error (pfile, DL_ERROR, + if (!digits_found) + cpp_error (pfile, DL_ERROR, "\\x used with no following hex digits"); - if (overflow | (i != (i & mask))) - { - cpp_error (pfile, DL_PEDWARN, - "hex escape sequence out of range"); - i &= mask; - } - c = i; - } + if (overflow | (i != (i & mask))) + { + cpp_error (pfile, DL_PEDWARN, + "hex escape sequence out of range"); + i &= mask; + } + c = i; + } break; case '0': case '1': case '2': case '3': @@ -1838,14 +1872,16 @@ cpp_parse_escape (pfile, pstr, limit, wide) if (unknown) { if (ISGRAPH (c)) - cpp_error (pfile, DL_PEDWARN, "unknown escape sequence '\\%c'", c); + cpp_error (pfile, DL_PEDWARN, + "unknown escape sequence '\\%c'", (int) c); else - cpp_error (pfile, DL_PEDWARN, "unknown escape sequence: '\\%03o'", c); + cpp_error (pfile, DL_PEDWARN, + "unknown escape sequence: '\\%03o'", (int) c); } if (c > mask) { - cpp_error (pfile, DL_PEDWARN, "escape sequence out of range for type"); + cpp_error (pfile, DL_PEDWARN, "escape sequence out of range for its type"); c &= mask; } @@ -1859,17 +1895,16 @@ cpp_parse_escape (pfile, pstr, limit, wide) characters seen, and UNSIGNEDP to a variable that indicates whether the result has signed type. */ cppchar_t -cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp) +cpp_interpret_charconst (pfile, token, pchars_seen, unsignedp) cpp_reader *pfile; const cpp_token *token; - int warn_multi; unsigned int *pchars_seen; int *unsignedp; { const unsigned char *str = token->val.str.text; const unsigned char *limit = str + token->val.str.len; unsigned int chars_seen = 0; - unsigned int width, max_chars; + size_t width, max_chars; cppchar_t c, mask, result = 0; bool unsigned_p; @@ -1881,19 +1916,20 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp) if (token->type == CPP_CHAR) { width = CPP_OPTION (pfile, char_precision); - unsigned_p = CPP_OPTION (pfile, signed_char) == 0; + max_chars = CPP_OPTION (pfile, int_precision) / width; + unsigned_p = CPP_OPTION (pfile, unsigned_char); } else { width = CPP_OPTION (pfile, wchar_precision); - unsigned_p = WCHAR_UNSIGNED; + max_chars = 1; + unsigned_p = CPP_OPTION (pfile, unsigned_wchar); } if (width < BITS_PER_CPPCHAR_T) mask = ((cppchar_t) 1 << width) - 1; else mask = ~0; - max_chars = BITS_PER_CPPCHAR_T / width; while (str < limit) { @@ -1901,7 +1937,7 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp) wchar_t wc; int char_len; - char_len = local_mbtowc (&wc, str, limit - str); + char_len = local_mbtowc (&wc, (const char *)str, limit - str); if (char_len == -1) { cpp_error (pfile, DL_WARNING, @@ -1924,34 +1960,43 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp) if (ISPRINT (c)) c = MAP_CHARACTER (c); #endif - - /* Merge character into result; ignore excess chars. */ - if (++chars_seen <= max_chars) - { - if (width < BITS_PER_CPPCHAR_T) - result = (result << width) | (c & mask); - else - result = c; - } + + chars_seen++; + + /* Truncate the character, scale the result and merge the two. */ + c &= mask; + if (width < BITS_PER_CPPCHAR_T) + result = (result << width) | c; + else + result = c; } if (chars_seen == 0) cpp_error (pfile, DL_ERROR, "empty character constant"); - else if (chars_seen > max_chars) + else if (chars_seen > 1) { - chars_seen = max_chars; - cpp_error (pfile, DL_WARNING, "character constant too long"); + /* Multichar charconsts are of type int and therefore signed. */ + unsigned_p = 0; + + if (chars_seen > max_chars) + { + chars_seen = max_chars; + cpp_error (pfile, DL_WARNING, + "character constant too long for its type"); + } + else if (CPP_OPTION (pfile, warn_multichar)) + cpp_error (pfile, DL_WARNING, "multi-character character constant"); } - else if (chars_seen > 1 && warn_multi) - cpp_error (pfile, DL_WARNING, "multi-character character constant"); - /* If relevant type is signed, sign-extend the constant. */ - if (chars_seen) + /* Sign-extend or truncate the constant to cppchar_t. The value is + in WIDTH bits, but for multi-char charconsts it's value is the + full target type's width. */ + if (chars_seen > 1) + width *= max_chars; + if (width < BITS_PER_CPPCHAR_T) { - unsigned int nbits = chars_seen * width; - - mask = (cppchar_t) ~0 >> (BITS_PER_CPPCHAR_T - nbits); - if (unsigned_p || ((result >> (nbits - 1)) & 1) == 0) + mask = ((cppchar_t) 1 << width) - 1; + if (unsigned_p || !(result & (1 << (width - 1)))) result &= mask; else result |= ~mask; @@ -1977,19 +2022,6 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp) #error BUFF_SIZE_UPPER_BOUND must be at least as large as MIN_BUFF_SIZE! #endif -struct dummy -{ - char c; - union - { - double d; - int *p; - } u; -}; - -#define DEFAULT_ALIGNMENT (offsetof (struct dummy, u)) -#define CPP_ALIGN(size, align) (((size) + ((align) - 1)) & ~((align) - 1)) - /* Create a new allocation buffer. Place the control block at the end of the buffer, so that buffer overflows will cause immediate chaos. */ static _cpp_buff * @@ -2001,7 +2033,7 @@ new_buff (len) if (len < MIN_BUFF_SIZE) len = MIN_BUFF_SIZE; - len = CPP_ALIGN (len, DEFAULT_ALIGNMENT); + len = CPP_ALIGN (len); base = xmalloc (len + sizeof (_cpp_buff)); result = (_cpp_buff *) (base + len);