X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-lex.c;h=b9c219091529c31582e4dd616ba36195a961b7b0;hb=a5b6178ad69416a75e853de5e30edf2da815af22;hp=8f8c64a6731601c882784d9797b734f8177b1177;hpb=8fd543444c6157056c671f2f9b373dedfcec51ab;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-lex.c b/gcc/c-lex.c index 8f8c64a6731..b9c21909152 100644 --- a/gcc/c-lex.c +++ b/gcc/c-lex.c @@ -1,5 +1,5 @@ /* Lexical analyzer for C and Objective C. - Copyright (C) 1987, 88, 89, 92, 94, 1995 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 89, 92, 94, 95, 1996 Free Software Foundation, Inc. This file is part of GNU CC. @@ -15,7 +15,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ #include @@ -30,6 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "c-tree.h" #include "flags.h" #include "c-parse.h" +#include "c-pragma.h" #include @@ -396,14 +398,30 @@ check_newline () && getc (finput) == 'a' && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n')) { + while (c == ' ' || c == '\t') + c = getc (finput); + if (c == '\n') + return c; #ifdef HANDLE_SYSV_PRAGMA - return handle_sysv_pragma (finput, c); + ungetc (c, finput); + token = yylex (); + if (token != IDENTIFIER) + goto skipline; + return handle_sysv_pragma (finput, token); #else /* !HANDLE_SYSV_PRAGMA */ #ifdef HANDLE_PRAGMA - HANDLE_PRAGMA (finput); + ungetc (c, finput); + token = yylex (); + if (token != IDENTIFIER) + goto skipline; + if (HANDLE_PRAGMA (finput, yylval.ttype)) + { + c = getc (finput); + return c; + } #endif /* HANDLE_PRAGMA */ - goto skipline; #endif /* !HANDLE_SYSV_PRAGMA */ + goto skipline; } } @@ -416,11 +434,8 @@ check_newline () && getc (finput) == 'e' && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n')) { -#ifdef DWARF_DEBUGGING_INFO - if ((debug_info_level == DINFO_LEVEL_VERBOSE) - && (write_symbols == DWARF_DEBUG)) - dwarfout_define (lineno, get_directive_line (finput)); -#endif /* DWARF_DEBUGGING_INFO */ + if (c != '\n') + debug_define (lineno, get_directive_line (finput)); goto skipline; } } @@ -432,11 +447,8 @@ check_newline () && getc (finput) == 'f' && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n')) { -#ifdef DWARF_DEBUGGING_INFO - if ((debug_info_level == DINFO_LEVEL_VERBOSE) - && (write_symbols == DWARF_DEBUG)) - dwarfout_undef (lineno, get_directive_line (finput)); -#endif /* DWARF_DEBUGGING_INFO */ + if (c != '\n') + debug_undef (lineno, get_directive_line (finput)); goto skipline; } } @@ -588,12 +600,7 @@ linenum: p->name = input_filename; input_file_stack = p; input_file_stack_tick++; -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_start_new_source_file (input_filename); -#endif /* DWARF_DEBUGGING_INFO */ - + debug_start_source_file (input_filename); used_up = 1; } else if (TREE_INT_CST_LOW (yylval.ttype) == 2) @@ -605,11 +612,7 @@ linenum: input_file_stack = p->next; free (p); input_file_stack_tick++; -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_resume_previous_source_file (input_file_stack->line); -#endif /* DWARF_DEBUGGING_INFO */ + debug_end_source_file (input_file_stack->line); } else error ("#-lines for entering and leaving files don't match"); @@ -664,37 +667,30 @@ linenum: /* skip the rest of this line. */ skipline: - if (c == '\n') - return c; - while ((c = getc (finput)) != EOF && c != '\n'); + while (c != '\n' && c != EOF) + c = getc (finput); return c; } #ifdef HANDLE_SYSV_PRAGMA /* Handle a #pragma directive. INPUT is the current input stream, - and C is a character to reread. Processes the entire input line - and returns a character for the caller to reread: either \n or EOF. */ + and TOKEN is the token we read after `#pragma'. Processes the entire input + line and returns a character for the caller to reread: either \n or EOF. */ /* This function has to be in this file, in order to get at the token types. */ int -handle_sysv_pragma (input, c) +handle_sysv_pragma (input, token) FILE *input; - int c; + register int token; { + register int c; + for (;;) { - while (c == ' ' || c == '\t') - c = getc (input); - if (c == '\n' || c == EOF) - { - handle_pragma_token (0, 0); - return c; - } - ungetc (c, input); - switch (yylex ()) + switch (token) { case IDENTIFIER: case TYPENAME: @@ -705,10 +701,21 @@ handle_sysv_pragma (input, c) default: handle_pragma_token (token_buffer, 0); } + if (nextchar >= 0) c = nextchar, nextchar = -1; else c = getc (input); + + while (c == ' ' || c == '\t') + c = getc (input); + if (c == '\n' || c == EOF) + { + handle_pragma_token (0, 0); + return c; + } + ungetc (c, input); + token = yylex (); } } @@ -954,11 +961,6 @@ yylex () value = ENDFILE; break; - case '$': - if (dollars_in_ident) - goto letter; - return '$'; - case 'L': /* Capital L may start a wide-string or wide-character constant. */ { @@ -993,7 +995,7 @@ yylex () goto string_constant; } ungetc(c, finput); - /* Fall through to treat '@' as the start of an indentifier. */ + /* Fall through to treat '@' as the start of an identifier. */ } case 'A': case 'B': case 'C': case 'D': case 'E': @@ -1009,6 +1011,7 @@ yylex () case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case '_': + case '$': letter: p = token_buffer; while (isalnum (c) || c == '_' || c == '$' || c == '@') @@ -1016,8 +1019,13 @@ yylex () /* Make sure this char really belongs in an identifier. */ if (c == '@' && ! doing_objc_thang) break; - if (c == '$' && ! dollars_in_ident) - break; + if (c == '$') + { + if (! dollars_in_ident) + error ("`$' in identifier"); + else if (pedantic) + pedwarn ("`$' in identifier"); + } if (p >= token_buffer + maxtoken) p = extend_token_buffer (p); @@ -1107,7 +1115,23 @@ yylex () break; - case '0': case '1': case '2': case '3': case '4': + case '0': case '1': + { + int next_c; + /* Check first for common special case: single-digit 0 or 1. */ + + next_c = getc (finput); + ungetc (next_c, finput); /* Always undo this lookahead. */ + if (!isalnum (next_c) && next_c != '.') + { + token_buffer[0] = (char)c, token_buffer[1] = '\0'; + yylval.ttype = (c == '0') ? integer_zero_node : integer_one_node; + value = CONSTANT; + break; + } + /*FALLTHRU*/ + } + case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': { @@ -1272,7 +1296,7 @@ yylex () if (floatflag != NOT_FLOAT) { tree type = double_type_node; - int garbage_chars = 0, exceeds_double = 0; + int exceeds_double = 0; int imag = 0; REAL_VALUE_TYPE value; jmp_buf handler; @@ -1408,19 +1432,6 @@ yylex () } } #endif - garbage_chars = 0; - while (isalnum (c) || c == '.' || c == '_' - || (!flag_traditional && (c == '+' || c == '-') - && (p[-1] == 'e' || p[-1] == 'E'))) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getc (finput); - garbage_chars++; - } - if (garbage_chars > 0) - error ("garbage at end of number"); /* If the result is not a number, assume it must have been due to some error message above, so silently convert @@ -1430,13 +1441,11 @@ yylex () /* Create a node with determined type and value. */ if (imag) - yylval.ttype = build_complex (convert (type, integer_zero_node), + yylval.ttype = build_complex (NULL_TREE, + convert (type, integer_zero_node), build_real (type, value)); else yylval.ttype = build_real (type, value); - - ungetc (c, finput); - *p = 0; } else { @@ -1477,32 +1486,13 @@ yylex () spec_imag = 1; } else - { - if (isalnum (c) || c == '.' || c == '_' - || (!flag_traditional && (c == '+' || c == '-') - && (p[-1] == 'e' || p[-1] == 'E'))) - { - error ("garbage at end of number"); - while (isalnum (c) || c == '.' || c == '_' - || (!flag_traditional && (c == '+' || c == '-') - && (p[-1] == 'e' || p[-1] == 'E'))) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getc (finput); - } - } - break; - } + break; if (p >= token_buffer + maxtoken - 3) p = extend_token_buffer (p); *p++ = c; c = getc (finput); } - ungetc (c, finput); - /* If the constant is not long long and it won't fit in an unsigned long, or if the constant is long long and won't fit in an unsigned long long, then warn that the constant is out @@ -1621,8 +1611,9 @@ yylex () if (TYPE_PRECISION (type) <= TYPE_PRECISION (integer_type_node)) yylval.ttype - = build_complex (integer_zero_node, - convert (integer_type_node, yylval.ttype)); + = build_complex (NULL_TREE, integer_zero_node, + convert (integer_type_node, + yylval.ttype)); else error ("complex integer constant is too wide for `complex int'"); } @@ -1638,10 +1629,16 @@ yylex () } else TREE_TYPE (yylval.ttype) = type; - - *p = 0; } + ungetc (c, finput); + *p = 0; + + if (isalnum (c) || c == '.' || c == '_' || c == '$' + || (!flag_traditional && (c == '-' || c == '+') + && (p[-1] == 'e' || p[-1] == 'E'))) + error ("missing white space after number `%s'", token_buffer); + value = CONSTANT; break; } @@ -1879,6 +1876,7 @@ yylex () case '-': case '&': case '|': + case ':': case '<': case '>': case '*': @@ -1956,8 +1954,28 @@ yylex () c = RSHIFT; goto combine; } - else if ((c == '-') && (c1 == '>')) - { value = POINTSAT; goto done; } + else + switch (c) + { + case '-': + if (c1 == '>') + { value = POINTSAT; goto done; } + break; + case ':': + if (c1 == '>') + { value = ']'; goto done; } + break; + case '<': + if (c1 == '%') + { value = '{'; goto done; } + if (c1 == ':') + { value = '['; goto done; } + break; + case '%': + if (c1 == '>') + { value = '}'; goto done; } + break; + } ungetc (c1, finput); token_buffer[1] = 0;