X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcpplex.c;h=e8d7b7e56d6544920d9a75e008613b6f1b03bf78;hb=eda6e89c15c0d5aff143fb57eb0a43eb8f3ffe67;hp=d3268985697b42bdfe6a94b1ea2f7ca1b81c3829;hpb=d507cd2fca73e8e258169f99831eb0bfd61b3188;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cpplex.c b/gcc/cpplex.c index d3268985697..e8d7b7e56d6 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,13 +73,14 @@ 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 *, cppchar_t *)); @@ -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) @@ -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++; } @@ -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; } @@ -1766,7 +1800,7 @@ cpp_parse_escape (pfile, pstr, limit, wide) "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': @@ -1861,10 +1895,9 @@ 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; { @@ -1884,13 +1917,13 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp) { width = CPP_OPTION (pfile, char_precision); max_chars = CPP_OPTION (pfile, int_precision) / width; - unsigned_p = CPP_OPTION (pfile, signed_char) == 0; + unsigned_p = CPP_OPTION (pfile, unsigned_char); } else { width = CPP_OPTION (pfile, wchar_precision); max_chars = 1; - unsigned_p = WCHAR_UNSIGNED; + unsigned_p = CPP_OPTION (pfile, unsigned_wchar); } if (width < BITS_PER_CPPCHAR_T) @@ -1927,14 +1960,13 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp) if (ISPRINT (c)) c = MAP_CHARACTER (c); #endif - + chars_seen++; - /* Sign-extend the character, scale result, and add the two. */ - if (!unsigned_p && (c & (1 << (width - 1)))) - c |= ~mask; + /* Truncate the character, scale the result and merge the two. */ + c &= mask; if (width < BITS_PER_CPPCHAR_T) - result = (result << width) + c; + result = (result << width) | c; else result = c; } @@ -1945,16 +1977,31 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp) { /* 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 (warn_multi) + else if (CPP_OPTION (pfile, warn_multichar)) cpp_error (pfile, DL_WARNING, "multi-character character constant"); } + /* 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) + { + mask = ((cppchar_t) 1 << width) - 1; + if (unsigned_p || !(result & (1 << (width - 1)))) + result &= mask; + else + result |= ~mask; + } + *pchars_seen = chars_seen; *unsignedp = unsigned_p; return result; @@ -1975,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 * @@ -1999,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);