diff options
Diffstat (limited to 'gcc/java')
-rw-r--r-- | gcc/java/ChangeLog | 63 | ||||
-rw-r--r-- | gcc/java/jcf-parse.c | 64 | ||||
-rw-r--r-- | gcc/java/jv-scan.c | 30 | ||||
-rw-r--r-- | gcc/java/lex.c | 964 | ||||
-rw-r--r-- | gcc/java/lex.h | 121 | ||||
-rw-r--r-- | gcc/java/parse.h | 61 | ||||
-rw-r--r-- | gcc/java/parse.y | 504 |
7 files changed, 1081 insertions, 726 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 0935ecd..17faa13 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,5 +1,66 @@ 2004-09-30 Per Bothner <per@bothner.com> + Simplify lexer. Implement --enable-mapped-location support. + * jcf-parse.c (parse_class_file): Use linemap_line_start. + (parse_source_file_1): Pass filename as extra parameter, so we can call + linemap_add and set input_location here, rather than in both callers. + (read_class): Pass copied filename to parse_source_file_1. + Don't initialize wfl_operator - only needed for source compilation. + (read_class, jcf_parse): Call linemap_add with LC_LEAVE. + * lex.h: Remove a bunch of debugging macros. + * lex.h (struct_java_line, struct java_error): Remove types. + (JAVA_COLUMN_DELTA): Remove - use java_lexer.next_colums instead. + (struct java_lc_s): Remove prev_col field. + (struct java_lexer): New fields next_unicode, next_columns, and + avail_unicode. New position field, and maybe token_start field. + Don't need hit_eof field - use next_unicode == -1 instead. + (JAVA_INTEGERAL_RANGE_ERROR): Rename to JAVA_RANGE_ERROR. + (JAVA_RANGE_ERROR, JAVA_FLOAT_ANGE_ERROR): Update accordingly. + * parse.h: Various changes for USE_MAPPED_LOCATION. + (EXPR_WFL_EMIT_LINE_NOTE): XXX + (BUILD_EXPR_WFL, EXPR_WFL_ADD_COL): Remove no-longer-used macros. + (struct parser_ctxt): New file_start_location field. + Remove p_line, c_line fields since we no longer save lines. + Remove elc, lineno, and current_jcf fields - no longer used. + * parse.y: Updates for USE_MAPPED_LOCATION and new lexer. + Don't use EXPR_WFL_ADD_COL since that isn't trivial with + source_location and is probably not needed anymore anyway. + Use new expr_add_Location function. + (SET_EXPR_LOCATION_FROM_TOKEN): New convenience macro. + (java_pop_parser_context): Minor cleanup. + (java_parser_context_save_global, java_parser_context_restore_global, + java_pop_parser_context): Save/restore input_location as a unit. + (issue_warning_error_from_context): If USE_MAPPED_LOCATION take + a source_location instead of a wfl context node. + (check_class_interface_creation): input_filename is not addressable. + (create_artificial_method): Calling java_parser_context_save_global + and java_parser_context_restore_global is overkill. Instead, + temporarily set input_location from class decl. + (java_layout_seen_class_methods): Set input_location from method decl. + (fix_constructors): Make more robust if no EXPR_WITH_FILE_LOCATION. + (finish_loop_body): Likewise. + * lex.c: Updates for USE_MAPPED_LOCATION. Use build_unknwon_wfl. + (java_sprint_unicode): Take a character, not index in line. + (java_sneak_uncode): Replaced by java_peek_unicode. + (java_unget_unicode): No longer used. + (java_allocate_new_line. java_store_unicode): Removed, since we + no longer remember "lines". + (java_new_lexer): Update for new data structures. + (java_read_char): Move unget_value checking to java_read_unicode. + (java_get_unicode, java_peek_unicode, java_next_unicode): New more + efficient functions that are used directly when lexing. + (java_read_unicode_collapsing_terminators): No longer needed. + (java_parse_end_comment, java_parse_escape_sequence, do_java_lex): + Re-organize to use java_peek_unicode to avoid java_unget_unicode. + (java_parse_escape_sequence): Rewrite to be simpler / more efficient. + (do_java_lex): Lots of movings around to avoid java_unget_unicode, + combine switch branches, and test for common token kinds earlier. + (java_lex_error): Rewrite. + * jv-scan.c (expand_location): New function, copied from tree.c. + (main): Set ctxp->filename instead of setting input_filename directly. + +2004-09-30 Per Bothner <per@bothner.com> + More cleanup for --enable-mapped-location. * class.c (push_class): If USE_MAPPED_LOCATION don't set input_location here. Instead do it in give_name_to_class. @@ -30,7 +91,7 @@ 2004-09-29 Per Bothner <per@bothner.com> - * java-tree.h: Redefine some macros and add soem declaration + * java-tree.h: Redefine some macros and add some declaration to handle the USE_MAPPED_LOCATION case. * parse.h (EXPR_WFL_QUALIFICATION): Use operand 1, not 2. * java-tree.h (EXPR_WFL_FILENAME_NODE): Use operand 2, not 1. diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index 031cedc..74f45de 100644 --- a/gcc/java/jcf-parse.c +++ b/gcc/java/jcf-parse.c @@ -98,7 +98,7 @@ static char *compute_class_name (struct ZipDirectory *zdir); static int classify_zip_file (struct ZipDirectory *zdir); static void parse_zip_file_entries (void); static void process_zip_dir (FILE *); -static void parse_source_file_1 (tree, FILE *); +static void parse_source_file_1 (tree, const char *, FILE *); static void parse_source_file_2 (void); static void parse_source_file_3 (void); static void parse_class_file (void); @@ -544,27 +544,27 @@ read_class (tree name) java_push_parser_context (); given_file = get_identifier (filename); + filename = IDENTIFIER_POINTER (given_file); real_file = get_identifier (lrealpath (filename)); generate = IS_A_COMMAND_LINE_FILENAME_P (given_file); - if (wfl_operator == NULL_TREE) - wfl_operator = build_expr_wfl (NULL_TREE, NULL, 0, 0); - EXPR_WFL_FILENAME_NODE (wfl_operator) = given_file; - input_filename = ggc_strdup (filename); output_class = current_class = NULL_TREE; current_function_decl = NULL_TREE; if (! HAS_BEEN_ALREADY_PARSED_P (real_file)) { - if (! (finput = fopen (input_filename, "r"))) - fatal_error ("can't reopen %s: %m", input_filename); + if (! (finput = fopen (filename, "r"))) + fatal_error ("can't reopen %s: %m", filename); - parse_source_file_1 (real_file, finput); + parse_source_file_1 (real_file, filename, finput); parse_source_file_2 (); parse_source_file_3 (); if (fclose (finput)) fatal_error ("can't close %s: %m", input_filename); +#ifdef USE_MAPPED_LOCATION + linemap_add (&line_table, LC_LEAVE, false, NULL, 0); +#endif } JCF_FINISH (current_jcf); java_pop_parser_context (generate); @@ -577,7 +577,7 @@ read_class (tree name) java_parser_context_save_global (); java_push_parser_context (); output_class = current_class = class; - input_filename = current_jcf->filename; + ctxp->save_location = input_location; if (JCF_SEEN_IN_ZIP (current_jcf)) read_zip_member(current_jcf, current_jcf->zipd, current_jcf->zipd->zipf); @@ -710,6 +710,9 @@ jcf_parse (JCF* jcf) code = jcf_parse_final_attributes (jcf); if (code != 0) fatal_error ("error while parsing final attributes"); +#ifdef USE_MAPPED_LOCATION + linemap_add (&line_table, LC_LEAVE, false, NULL, 0); +#endif /* The fields of class_type_node are already in correct order. */ if (current_class != class_type_node && current_class != object_type_node) @@ -804,10 +807,11 @@ parse_class_file (void) continue; } - input_line = 0; + input_location = file_start_location; if (DECL_LINENUMBERS_OFFSET (method)) { int i; + int min_line = 0; unsigned char *ptr; JCF_SEEK (jcf, DECL_LINENUMBERS_OFFSET (method)); linenumber_count = i = JCF_readu2 (jcf); @@ -818,9 +822,16 @@ parse_class_file (void) int line = GET_u2 (ptr); /* Set initial input_line to smallest linenumber. * Needs to be set before init_function_start. */ - if (input_line == 0 || line < input_line) - input_line = line; - } + if (min_line == 0 || line < min_line) + min_line = line; + } +#ifdef USE_MAPPED_LOCATION + if (min_line != 0) + input_location = linemap_line_start (&line_table, min_line, 1); +#else + if (min_line != 0) + input_line = min_line; +#endif } else { @@ -845,22 +856,20 @@ parse_class_file (void) finish_class (); - (*debug_hooks->end_source_file) (save_location.line); + (*debug_hooks->end_source_file) (LOCATION_LINE (save_location)); input_location = save_location; } /* Parse a source file, as pointed by the current value of INPUT_FILENAME. */ static void -parse_source_file_1 (tree real_file, FILE *finput) +parse_source_file_1 (tree real_file, const char *filename, FILE *finput) { int save_error_count = java_error_count; /* Mark the file as parsed. */ HAS_BEEN_ALREADY_PARSED_P (real_file) = 1; - jcf_dependency_add_file (input_filename, 0); - lang_init_source (1); /* Error msgs have no method prototypes */ /* There's no point in trying to find the current encoding unless we @@ -874,6 +883,18 @@ parse_source_file_1 (tree real_file, FILE *finput) if (current_encoding == NULL || *current_encoding == '\0') current_encoding = DEFAULT_ENCODING; +#ifdef USE_MAPPED_LOCATION + linemap_add (&line_table, LC_ENTER, false, filename, 0); + input_location = linemap_line_start (&line_table, 0, 125); +#else + input_filename = filename; + input_line = 0; +#endif + ctxp->file_start_location = input_location; + ctxp->filename = filename; + + jcf_dependency_add_file (input_filename, 0); + /* Initialize the parser */ java_init_lex (finput, current_encoding); java_parse_abort_on_error (); @@ -1147,21 +1168,24 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) java_push_parser_context (); java_parser_context_save_global (); - parse_source_file_1 (real_file, finput); + parse_source_file_1 (real_file, filename, finput); java_parser_context_restore_global (); java_pop_parser_context (1); +#ifdef USE_MAPPED_LOCATION + linemap_add (&line_table, LC_LEAVE, false, NULL, 0); +#endif } } for (ctxp = ctxp_for_generation; ctxp; ctxp = ctxp->next) { - input_filename = ctxp->filename; + input_location = ctxp->file_start_location; parse_source_file_2 (); } for (ctxp = ctxp_for_generation; ctxp; ctxp = ctxp->next) { - input_filename = ctxp->filename; + input_location = ctxp->file_start_location; parse_source_file_3 (); } diff --git a/gcc/java/jv-scan.c b/gcc/java/jv-scan.c index 77320e6..9892605 100644 --- a/gcc/java/jv-scan.c +++ b/gcc/java/jv-scan.c @@ -59,6 +59,8 @@ FILE *finput, *out; /* Executable name. */ char *exec_name; +struct line_maps line_table; + /* Flags matching command line options. */ int flag_find_main = 0; int flag_dump_class = 0; @@ -129,6 +131,29 @@ version (void) exit (0); } +#ifdef USE_MAPPED_LOCATION +/* FIXME - this is the same as the function in tree.c, which is awkward. + Probably the cleanest solution is to move the function to line-map.c. + This is difficult as long as we still support --disable-mapped-location, + since whether expanded_location has a column fields depends on + USE_MAPPED_LOCATION. */ + +expanded_location +expand_location (source_location loc) +{ + expanded_location xloc; + if (loc == 0) { xloc.file = NULL; xloc.line = 0; xloc.column = 0; } + else + { + const struct line_map *map = linemap_lookup (&line_table, loc); + xloc.file = map->to_file; + xloc.line = SOURCE_LINE (map, loc); + xloc.column = SOURCE_COLUMN (map, loc); + }; + return xloc; +} +#endif + /* jc1-lite main entry point */ int main (int argc, char **argv) @@ -198,8 +223,8 @@ main (int argc, char **argv) for ( i = optind; i < argc; i++ ) if (argv [i]) { - input_filename = argv [i]; - if ( (finput = fopen (argv [i], "r")) ) + char *filename = argv[i]; + if ( (finput = fopen (filename, "r")) ) { /* There's no point in trying to find the current encoding unless we are going to do something intelligent with it @@ -213,6 +238,7 @@ main (int argc, char **argv) encoding = DEFAULT_ENCODING; java_init_lex (finput, encoding); + ctxp->filename = filename; yyparse (); report (); if (ftell (out) != ft) diff --git a/gcc/java/lex.c b/gcc/java/lex.c index aa3efcc..2b299ee 100644 --- a/gcc/java/lex.c +++ b/gcc/java/lex.c @@ -43,7 +43,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #endif /* Function declarations. */ -static char *java_sprint_unicode (struct java_line *, int); +static char *java_sprint_unicode (int); static void java_unicode_2_utf8 (unicode_t); static void java_lex_error (const char *, int); #ifndef JC1_LITE @@ -52,21 +52,17 @@ static int java_lex (YYSTYPE *); static int java_is_eol (FILE *, int); static tree build_wfl_node (tree); #endif -static void java_store_unicode (struct java_line *, unicode_t, int); static int java_parse_escape_sequence (void); static int java_start_char_p (unicode_t); static int java_part_char_p (unicode_t); static int java_space_char_p (unicode_t); static void java_parse_doc_section (int); static void java_parse_end_comment (int); +static int java_read_char (java_lexer *); static int java_get_unicode (void); +static int java_peek_unicode (void); +static void java_next_unicode (void); static int java_read_unicode (java_lexer *, int *); -static int java_read_unicode_collapsing_terminators (java_lexer *, int *); -static void java_store_unicode (struct java_line *, unicode_t, int); -static int java_read_char (java_lexer *); -static void java_allocate_new_line (void); -static void java_unget_unicode (void); -static unicode_t java_sneak_unicode (void); #ifndef JC1_LITE static int utf8_cmp (const unsigned char *, int, const char *); #endif @@ -102,8 +98,8 @@ java_init_lex (FILE *finput, const char *encoding) if (!java_lang_imported) { - tree node = build_tree_list - (build_expr_wfl (java_lang_id, NULL, 0, 0), NULL_TREE); + tree node = build_tree_list (build_unknown_wfl (java_lang_id), + NULL_TREE); read_import_dir (TREE_PURPOSE (node)); TREE_CHAIN (node) = ctxp->import_demand_list; ctxp->import_demand_list = node; @@ -111,111 +107,52 @@ java_init_lex (FILE *finput, const char *encoding) } if (!wfl_operator) - wfl_operator = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0); + { +#ifdef USE_MAPPED_LOCATION + wfl_operator = build_expr_wfl (NULL_TREE, input_location); +#else + wfl_operator = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0); +#endif + } if (!label_id) label_id = get_identifier ("$L"); if (!wfl_append) - wfl_append = build_expr_wfl (get_identifier ("append"), NULL, 0, 0); + wfl_append = build_unknown_wfl (get_identifier ("append")); if (!wfl_string_buffer) wfl_string_buffer = - build_expr_wfl (get_identifier (flag_emit_class_files + build_unknown_wfl (get_identifier (flag_emit_class_files ? "java.lang.StringBuffer" - : "gnu.gcj.runtime.StringBuffer"), - NULL, 0, 0); + : "gnu.gcj.runtime.StringBuffer")); if (!wfl_to_string) - wfl_to_string = build_expr_wfl (get_identifier ("toString"), NULL, 0, 0); + wfl_to_string = build_unknown_wfl (get_identifier ("toString")); CPC_INITIALIZER_LIST (ctxp) = CPC_STATIC_INITIALIZER_LIST (ctxp) = CPC_INSTANCE_INITIALIZER_LIST (ctxp) = NULL_TREE; memset (ctxp->modifier_ctx, 0, sizeof (ctxp->modifier_ctx)); - current_jcf = ggc_alloc_cleared (sizeof (JCF)); ctxp->current_parsed_class = NULL; ctxp->package = NULL_TREE; #endif - ctxp->filename = input_filename; - ctxp->lineno = input_line = 0; - ctxp->p_line = NULL; - ctxp->c_line = NULL; + ctxp->save_location = input_location; ctxp->java_error_flag = 0; ctxp->lexer = java_new_lexer (finput, encoding); } static char * -java_sprint_unicode (struct java_line *line, int i) +java_sprint_unicode (int c) { static char buffer [10]; - if (line->unicode_escape_p [i] || line->line [i] > 128) - sprintf (buffer, "\\u%04x", line->line [i]); + if (c < ' ' || c >= 127) + sprintf (buffer, "\\u%04x", c); else { - buffer [0] = line->line [i]; + buffer [0] = c; buffer [1] = '\0'; } return buffer; } -static unicode_t -java_sneak_unicode (void) -{ - return (ctxp->c_line->line [ctxp->c_line->current]); -} - -static void -java_unget_unicode (void) -{ - if (!ctxp->c_line->current) - /* Can't unget unicode. */ - abort (); - - ctxp->c_line->current--; - ctxp->c_line->char_col -= JAVA_COLUMN_DELTA (0); -} - -static void -java_allocate_new_line (void) -{ - unicode_t ahead = (ctxp->c_line ? ctxp->c_line->ahead[0] : '\0'); - char ahead_escape_p = (ctxp->c_line ? - ctxp->c_line->unicode_escape_ahead_p : 0); - - if (ctxp->c_line && !ctxp->c_line->white_space_only) - { - if (ctxp->p_line) - { - free (ctxp->p_line->unicode_escape_p); - free (ctxp->p_line->line); - free (ctxp->p_line); - } - ctxp->p_line = ctxp->c_line; - ctxp->c_line = NULL; /* Reallocated. */ - } - - if (!ctxp->c_line) - { - ctxp->c_line = xmalloc (sizeof (struct java_line)); - ctxp->c_line->max = JAVA_LINE_MAX; - ctxp->c_line->line = xmalloc (sizeof (unicode_t)*ctxp->c_line->max); - ctxp->c_line->unicode_escape_p = - xmalloc (sizeof (char)*ctxp->c_line->max); - ctxp->c_line->white_space_only = 0; - } - - ctxp->c_line->line [0] = ctxp->c_line->size = 0; - ctxp->c_line->char_col = ctxp->c_line->current = 0; - if (ahead) - { - ctxp->c_line->line [ctxp->c_line->size] = ahead; - ctxp->c_line->unicode_escape_p [ctxp->c_line->size] = ahead_escape_p; - ctxp->c_line->size++; - } - ctxp->c_line->ahead [0] = 0; - ctxp->c_line->unicode_escape_ahead_p = 0; - ctxp->c_line->lineno = ++input_line; - ctxp->c_line->white_space_only = 1; -} - /* Create a new lexer object. */ java_lexer * @@ -227,8 +164,20 @@ java_new_lexer (FILE *finput, const char *encoding) lex->finput = finput; lex->bs_count = 0; lex->unget_value = 0; - lex->hit_eof = 0; + lex->next_unicode = 0; + lex->avail_unicode = 0; + lex->next_columns = 1; lex->encoding = encoding; + lex->position.line = 1; + lex->position.col = 1; +#ifndef JC1_LITE +#ifdef USE_MAPPED_LOCATION + input_location + = linemap_line_start (&line_table, 1, 120); +#else + input_line = 1; +#endif +#endif #ifdef HAVE_ICONV lex->handle = iconv_open ("UCS-2", encoding); @@ -322,13 +271,6 @@ java_destroy_lexer (java_lexer *lex) static int java_read_char (java_lexer *lex) { - if (lex->unget_value) - { - unicode_t r = lex->unget_value; - lex->unget_value = 0; - return r; - } - #ifdef HAVE_ICONV if (! lex->use_fallback) { @@ -513,26 +455,19 @@ java_read_char (java_lexer *lex) return UEOF; } -static void -java_store_unicode (struct java_line *l, unicode_t c, int unicode_escape_p) -{ - if (l->size == l->max) - { - l->max += JAVA_LINE_MAX; - l->line = xrealloc (l->line, sizeof (unicode_t)*l->max); - l->unicode_escape_p = xrealloc (l->unicode_escape_p, - sizeof (char)*l->max); - } - l->line [l->size] = c; - l->unicode_escape_p [l->size++] = unicode_escape_p; -} - static int java_read_unicode (java_lexer *lex, int *unicode_escape_p) { int c; - c = java_read_char (lex); + if (lex->unget_value) + { + c = lex->unget_value; + lex->unget_value = 0; + } + else + c = java_read_char (lex); + *unicode_escape_p = 0; if (c != '\\') @@ -589,72 +524,111 @@ java_read_unicode (java_lexer *lex, int *unicode_escape_p) return (unicode_t) '\\'; } +/* Get the next Unicode character (post-Unicode-escape-handling). + Move the current position to just after returned character. */ + +static int +java_get_unicode (void) +{ + int next = java_peek_unicode (); + java_next_unicode (); + return next; +} + +/* Return the next Unicode character (post-Unicode-escape-handling). + Do not move the current position, which remains just before + the returned character. */ + static int -java_read_unicode_collapsing_terminators (java_lexer *lex, - int *unicode_escape_p) +java_peek_unicode (void) { - int c = java_read_unicode (lex, unicode_escape_p); + int unicode_escape_p; + java_lexer *lex = ctxp->lexer; + if (lex->avail_unicode) + return lex->next_unicode; + int next; - if (c == '\r') + next = java_read_unicode (lex, &unicode_escape_p); + + if (next == '\r') { - /* We have to read ahead to see if we got \r\n. In that case we - return a single line terminator. */ + /* We have to read ahead to see if we got \r\n. + In that case we return a single line terminator. */ int dummy; - c = java_read_unicode (lex, &dummy); - if (c != '\n' && c != UEOF) - lex->unget_value = c; + next = java_read_unicode (lex, &dummy); + if (next != '\n' && next != UEOF) + lex->unget_value = next; /* In either case we must return a newline. */ - c = '\n'; + next = '\n'; } - return c; -} + lex->next_unicode = next; + lex->avail_unicode = 1; -static int -java_get_unicode (void) -{ - /* It's time to read a line when... */ - if (!ctxp->c_line || ctxp->c_line->current == ctxp->c_line->size) + if (next == UEOF) { - int c; - int found_chars = 0; + lex->next_columns = 0; + return next; + } - if (ctxp->lexer->hit_eof) - return UEOF; + if (next == '\n') + { + lex->next_columns = 1 - lex->position.col; + } + else if (next == '\t') + { + int cur_col = lex->position.col; + lex->next_columns = ((cur_col + 7) & ~7) + 1 - cur_col; + + } + else + { + lex->next_columns = 1; + } + if (unicode_escape_p) + lex->next_columns = 6; + return next; +} - java_allocate_new_line (); - if (ctxp->c_line->line[0] != '\n') - { - for (;;) - { - int unicode_escape_p; - c = java_read_unicode_collapsing_terminators (ctxp->lexer, - &unicode_escape_p); - if (c != UEOF) - { - found_chars = 1; - java_store_unicode (ctxp->c_line, c, unicode_escape_p); - if (ctxp->c_line->white_space_only - && !JAVA_WHITE_SPACE_P (c) - && c != '\n') - ctxp->c_line->white_space_only = 0; - } - if ((c == '\n') || (c == UEOF)) - break; - } +/* Move forward one Unicode character (post-Unicode-escape-handling). + Only allowed after java_peek_unicode. The combination java_peek_uncode + followed by java_next_unicode is equivalent to java_get_unicode. */ - if (c == UEOF && ! found_chars) - { - ctxp->lexer->hit_eof = 1; - return UEOF; - } - } +static void java_next_unicode (void) +{ + struct java_lexer *lex = ctxp->lexer; + lex->position.col += lex->next_columns; + if (lex->next_unicode == '\n') + { + lex->position.line++; +#ifndef JC1_LITE +#ifdef USE_MAPPED_LOCATION + input_location + = linemap_line_start (&line_table, lex->position.line, 120); +#else + input_line = lex->position.line; +#endif +#endif } - ctxp->c_line->char_col += JAVA_COLUMN_DELTA (0); - JAVA_LEX_CHAR (ctxp->c_line->line [ctxp->c_line->current]); - return ctxp->c_line->line [ctxp->c_line->current++]; + lex->avail_unicode = 0; } +#if 0 +/* The inverse of java_next_unicode. + Not currently used, but could be if it would be cleaner or faster. + java_peek_unicode == java_get_unicode + java_unget_unicode. + java_get_unicode == java_peek_unicode + java_next_unicode. +*/ +static void java_unget_unicode () +{ + struct java_lexer *lex = ctxp->lexer; + if (lex->avail_unicode) + fatal_error ("internal error - bad unget"); + lex->avail_unicode = 1; + lex->position.col -= lex->next_columns; +} +#endif + /* Parse the end of a C style comment. * C is the first character following the '/' and '*'. */ static void @@ -668,15 +642,16 @@ java_parse_end_comment (int c) java_lex_error ("Comment not terminated at end of input", 0); return; case '*': - switch (c = java_get_unicode ()) + switch (c = java_peek_unicode ()) { case UEOF: java_lex_error ("Comment not terminated at end of input", 0); return; case '/': + java_next_unicode (); return; case '*': /* Reparse only '*'. */ - java_unget_unicode (); + ; } } } @@ -832,7 +807,6 @@ java_space_char_p (unicode_t c) static int java_parse_escape_sequence (void) { - unicode_t char_lit; int c; switch (c = java_get_unicode ()) @@ -856,33 +830,31 @@ java_parse_escape_sequence (void) case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': { - int octal_escape[3]; - int octal_escape_index = 0; - int max = 3; - int i, shift; + int more = 3; + unicode_t char_lit = 0; - for (; octal_escape_index < max && RANGE (c, '0', '7'); - c = java_get_unicode ()) + if (c > '3') { - if (octal_escape_index == 0 && c > '3') - { - /* According to the grammar, `\477' has a well-defined - meaning -- it is `\47' followed by `7'. */ - --max; - } - octal_escape [octal_escape_index++] = c; + /* According to the grammar, `\477' has a well-defined + meaning -- it is `\47' followed by `7'. */ + --more; + } + char_lit = 0; + for (;;) + { + char_lit = 8 * char_lit + c - '0'; + if (--more == 0) + break; + c = java_peek_unicode (); + if (! RANGE (c, '0', '7')) + break; + java_next_unicode (); } - - java_unget_unicode (); - - for (char_lit=0, i = 0, shift = 3*(octal_escape_index-1); - i < octal_escape_index; i++, shift -= 3) - char_lit |= (octal_escape [i] - '0') << shift; return char_lit; } default: - java_lex_error ("Invalid character in escape sequence", 0); + java_lex_error ("Invalid character in escape sequence", -1); return JAVA_CHAR_ERROR; } } @@ -932,10 +904,10 @@ java_perform_atof (YYSTYPE *java_lval, char *literal_token, int fflag, } if (! really_zero) { - int i = ctxp->c_line->current; - ctxp->c_line->current = number_beginning; + int save_col = ctxp->lexer->position.col; + ctxp->lexer->position.col = number_beginning; java_lex_error ("Floating point literal underflow", 0); - ctxp->c_line->current = i; + ctxp->lexer->position.col = save_col; } } @@ -953,89 +925,32 @@ do_java_lex (YYSTYPE *java_lval) #endif { int c; - unicode_t first_unicode; - int ascii_index, all_ascii; char *string; /* Translation of the Unicode escape in the raw stream of Unicode characters. Takes care of line terminator. */ step1: /* Skip white spaces: SP, TAB and FF or ULT. */ - for (c = java_get_unicode (); - c == '\n' || JAVA_WHITE_SPACE_P (c); c = java_get_unicode ()) - if (c == '\n') - { - ctxp->elc.line = ctxp->c_line->lineno; - ctxp->elc.col = ctxp->c_line->char_col-2; - } - - ctxp->elc.col = (ctxp->elc.col < 0 ? 0 : ctxp->elc.col); - - if (c == 0x1a) /* CTRL-Z. */ + for (;;) { - if ((c = java_get_unicode ()) == UEOF) - return 0; /* Ok here. */ - else - java_unget_unicode (); /* Caught later, at the end of the - function. */ + c = java_peek_unicode (); + if (c != '\n' && ! JAVA_WHITE_SPACE_P (c)) + break; + java_next_unicode (); } + /* Handle EOF here. */ if (c == UEOF) /* Should probably do something here... */ return 0; - /* Take care of eventual comments. */ - if (c == '/') - { - switch (c = java_get_unicode ()) - { - case '/': - for (;;) - { - c = java_get_unicode (); - if (c == UEOF) - { - /* It is ok to end a `//' comment with EOF, unless - we're being pedantic. */ - if (pedantic) - java_lex_error ("Comment not terminated at end of input", - 0); - return 0; - } - if (c == '\n') /* ULT */ - goto step1; - } - break; - - case '*': - if ((c = java_get_unicode ()) == '*') - { - c = java_get_unicode (); - if (c == '/') - { - /* Empty documentation comment. We have to reset - the deprecation marker as only the most recent - doc comment applies. */ - ctxp->deprecated = 0; - } - else - java_parse_doc_section (c); - } - else - java_parse_end_comment ((c = java_get_unicode ())); - goto step1; - break; - default: - java_unget_unicode (); - c = '/'; - break; - } - } - - ctxp->elc.line = ctxp->c_line->lineno; - ctxp->elc.prev_col = ctxp->elc.col; - ctxp->elc.col = ctxp->c_line->char_col - JAVA_COLUMN_DELTA (-1); - if (ctxp->elc.col < 0) - abort (); +#ifndef JC1_LITE +#ifdef USE_MAPPED_LOCATION + LINEMAP_POSITION_FOR_COLUMN (input_location, &line_table, + ctxp->lexer->position.col); +#else + ctxp->lexer->token_start = ctxp->lexer->position; +#endif +#endif /* Numeric literals. */ if (JAVA_ASCII_DIGIT (c) || (c == '.')) @@ -1047,62 +962,54 @@ do_java_lex (YYSTYPE *java_lval) /* End borrowed section. */ char literal_token [256]; int literal_index = 0, radix = 10, long_suffix = 0, overflow = 0, bytes; - int found_hex_digits = 0, found_non_octal_digits = 0; + int found_hex_digits = 0, found_non_octal_digits = -1; int i; #ifndef JC1_LITE - int number_beginning = ctxp->c_line->current; + int number_beginning = ctxp->lexer->position.col; tree value; #endif - - /* We might have a . separator instead of a FP like .[0-9]*. */ - if (c == '.') - { - unicode_t peep = java_sneak_unicode (); - - if (!JAVA_ASCII_DIGIT (peep)) - { - JAVA_LEX_SEP('.'); - BUILD_OPERATOR (DOT_TK); - } - } - + for (i = 0; i < TOTAL_PARTS; i++) parts [i] = 0; if (c == '0') { - c = java_get_unicode (); + java_next_unicode (); + c = java_peek_unicode (); if (c == 'x' || c == 'X') { radix = 16; - c = java_get_unicode (); + java_next_unicode (); + c = java_peek_unicode (); } else if (JAVA_ASCII_DIGIT (c)) - radix = 8; + { + literal_token [literal_index++] = '0'; + radix = 8; + } else if (c == '.' || c == 'e' || c =='E') { - /* Push the '.', 'e', or 'E' back and prepare for a FP - parsing... */ - java_unget_unicode (); - c = '0'; + literal_token [literal_index++] = '0'; + /* Handle C during floating-point parsing. */ } else { /* We have a zero literal: 0, 0{l,L}, 0{f,F}, 0{d,D}. */ - JAVA_LEX_LIT ("0", 10); switch (c) { case 'L': case 'l': + java_next_unicode (); SET_LVAL_NODE (long_zero_node); return (INT_LIT_TK); case 'f': case 'F': + java_next_unicode (); SET_LVAL_NODE (float_zero_node); return (FP_LIT_TK); case 'd': case 'D': + java_next_unicode (); SET_LVAL_NODE (double_zero_node); return (FP_LIT_TK); default: - java_unget_unicode (); SET_LVAL_NODE (integer_zero_node); return (INT_LIT_TK); } @@ -1110,8 +1017,7 @@ do_java_lex (YYSTYPE *java_lval) } /* Parse the first part of the literal, until we find something which is not a number. */ - while ((radix == 16 && JAVA_ASCII_HEXDIGIT (c)) || - JAVA_ASCII_DIGIT (c)) + while (radix == 16 ? JAVA_ASCII_HEXDIGIT (c) : JAVA_ASCII_DIGIT (c)) { /* We store in a string (in case it turns out to be a FP) and in PARTS if we have to process a integer literal. */ @@ -1122,8 +1028,8 @@ do_java_lex (YYSTYPE *java_lval) if (radix == 16) found_hex_digits = 1; /* Remember when we find an invalid octal digit. */ - else if (radix == 8 && !JAVA_ASCII_OCTDIGIT (c)) - found_non_octal_digits = 1; + else if (radix == 8 && numeric >= 8 && found_non_octal_digits < 0) + found_non_octal_digits = literal_index; literal_token [literal_index++] = c; /* This section of code if borrowed from gcc/c-lex.c. */ @@ -1141,13 +1047,20 @@ do_java_lex (YYSTYPE *java_lval) if (parts [TOTAL_PARTS-1] != 0) overflow = 1; /* End borrowed section. */ - c = java_get_unicode (); + java_next_unicode (); + c = java_peek_unicode (); } /* If we have something from the FP char set but not a digit, parse a FP literal. */ if (JAVA_ASCII_FPCHAR (c) && !JAVA_ASCII_DIGIT (c)) { + /* stage==0: seen digits only + * stage==1: seen '.' + * stage==2: seen 'e' or 'E'. + * stage==3: seen '+' or '-' after 'e' or 'E'. + * stage==4: seen type suffix ('f'/'F'/'d'/'D') + */ int stage = 0; int seen_digit = (literal_index ? 1 : 0); int seen_exponent = 0; @@ -1168,7 +1081,10 @@ do_java_lex (YYSTYPE *java_lval) { stage = 1; literal_token [literal_index++ ] = c; - c = java_get_unicode (); + java_next_unicode (); + c = java_peek_unicode (); + if (literal_index == 1 && !JAVA_ASCII_DIGIT (c)) + BUILD_OPERATOR (DOT_TK); } else java_lex_error ("Invalid character in FP literal", 0); @@ -1186,7 +1102,8 @@ do_java_lex (YYSTYPE *java_lval) seen_exponent = 1; stage = 2; literal_token [literal_index++] = c; - c = java_get_unicode (); + java_next_unicode (); + c = java_peek_unicode (); } else java_lex_error ("Invalid character in FP literal", 0); @@ -1201,7 +1118,8 @@ do_java_lex (YYSTYPE *java_lval) { stage = 3; literal_token [literal_index++] = c; - c = java_get_unicode (); + java_next_unicode (); + c = java_peek_unicode (); } if ((stage == 0 && JAVA_ASCII_FPCHAR (c)) || @@ -1214,12 +1132,13 @@ do_java_lex (YYSTYPE *java_lval) if (stage == 2) stage = 3; literal_token [literal_index++ ] = c; - c = java_get_unicode (); + java_next_unicode (); + c = java_peek_unicode (); } else { - if (stage != 4) /* Don't push back fF/dD. */ - java_unget_unicode (); + if (stage == 4) /* Don't push back fF/dD. */ + java_next_unicode (); /* An exponent (if any) must have seen a digit. */ if (seen_exponent && !seen_digit) @@ -1227,7 +1146,6 @@ do_java_lex (YYSTYPE *java_lval) ("Invalid FP literal, exponent must have digit", 0); literal_token [literal_index] = '\0'; - JAVA_LEX_LIT (literal_token, radix); #ifndef JC1_LITE java_perform_atof (java_lval, literal_token, @@ -1242,17 +1160,19 @@ do_java_lex (YYSTYPE *java_lval) if (radix == 16 && ! found_hex_digits) java_lex_error ("0x must be followed by at least one hexadecimal digit", 0); - else if (radix == 8 && found_non_octal_digits) - java_lex_error ("Octal literal contains digit out of range", 0); + else if (radix == 8 && found_non_octal_digits >= 0) + { + int back = literal_index - found_non_octal_digits; + ctxp->lexer->position.col -= back; + java_lex_error ("Octal literal contains digit out of range", 0); + ctxp->lexer->position.col += back; + } else if (c == 'L' || c == 'l') - long_suffix = 1; - else - java_unget_unicode (); + { + java_next_unicode (); + long_suffix = 1; + } -#ifdef JAVA_LEX_DEBUG - literal_token [literal_index] = '\0'; /* So JAVA_LEX_LIT is safe. */ - JAVA_LEX_LIT (literal_token, radix); -#endif /* This section of code is borrowed from gcc/c-lex.c. */ if (!overflow) { @@ -1294,9 +1214,9 @@ do_java_lex (YYSTYPE *java_lval) value))) { if (long_suffix) - JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `long' literal"); + JAVA_RANGE_ERROR ("Numeric overflow for 'long' literal"); else - JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `int' literal"); + JAVA_RANGE_ERROR ("Numeric overflow for 'int' literal"); } /* Sign extend the value. */ @@ -1315,6 +1235,112 @@ do_java_lex (YYSTYPE *java_lval) return INT_LIT_TK; } + /* We may have an ID here. */ + if (JAVA_START_CHAR_P (c)) + { + int ascii_index = 0, all_ascii = 1; + + /* Keyword, boolean literal or null literal. */ + while (c != UEOF && JAVA_PART_CHAR_P (c)) + { + java_unicode_2_utf8 (c); + if (c >= 128) + all_ascii = 0; + java_next_unicode (); + ascii_index++; + c = java_peek_unicode (); + } + + obstack_1grow (&temporary_obstack, '\0'); + string = obstack_finish (&temporary_obstack); + + /* If we have something all ascii, we consider a keyword, a boolean + literal, a null literal or an all ASCII identifier. Otherwise, + this is an identifier (possibly not respecting formation rule). */ + if (all_ascii) + { + const struct java_keyword *kw; + if ((kw=java_keyword (string, ascii_index))) + { + switch (kw->token) + { + case PUBLIC_TK: case PROTECTED_TK: case STATIC_TK: + case ABSTRACT_TK: case FINAL_TK: case NATIVE_TK: + case SYNCHRONIZED_TK: case TRANSIENT_TK: case VOLATILE_TK: + case PRIVATE_TK: case STRICT_TK: + SET_MODIFIER_CTX (kw->token); + return MODIFIER_TK; + case FLOAT_TK: + SET_LVAL_NODE (float_type_node); + return FP_TK; + case DOUBLE_TK: + SET_LVAL_NODE (double_type_node); + return FP_TK; + case BOOLEAN_TK: + SET_LVAL_NODE (boolean_type_node); + return BOOLEAN_TK; + case BYTE_TK: + SET_LVAL_NODE (byte_type_node); + return INTEGRAL_TK; + case SHORT_TK: + SET_LVAL_NODE (short_type_node); + return INTEGRAL_TK; + case INT_TK: + SET_LVAL_NODE (int_type_node); + return INTEGRAL_TK; + case LONG_TK: + SET_LVAL_NODE (long_type_node); + return INTEGRAL_TK; + case CHAR_TK: + SET_LVAL_NODE (char_type_node); + return INTEGRAL_TK; + + /* Keyword based literals. */ + case TRUE_TK: + case FALSE_TK: + SET_LVAL_NODE ((kw->token == TRUE_TK ? + boolean_true_node : boolean_false_node)); + return BOOL_LIT_TK; + case NULL_TK: + SET_LVAL_NODE (null_pointer_node); + return NULL_TK; + + case ASSERT_TK: + if (flag_assert) + { + BUILD_OPERATOR (kw->token); + return kw->token; + } + else + break; + + /* Some keyword we want to retain information on the location + they where found. */ + case CASE_TK: + case DEFAULT_TK: + case SUPER_TK: + case THIS_TK: + case RETURN_TK: + case BREAK_TK: + case CONTINUE_TK: + case TRY_TK: + case CATCH_TK: + case THROW_TK: + case INSTANCEOF_TK: + BUILD_OPERATOR (kw->token); + + default: + return kw->token; + } + } + } + + java_lval->node = BUILD_ID_WFL (GET_IDENTIFIER (string)); + return ID_TK; + } + + java_next_unicode (); + /* Character literals. */ if (c == '\'') { @@ -1339,7 +1365,6 @@ do_java_lex (YYSTYPE *java_lval) if (char_lit == JAVA_CHAR_ERROR) char_lit = 0; /* We silently convert it to zero. */ - JAVA_LEX_CHAR_LIT (char_lit); SET_LVAL_NODE (build_int_cst (char_type_node, char_lit)); return CHAR_LIT_TK; } @@ -1347,12 +1372,20 @@ do_java_lex (YYSTYPE *java_lval) /* String literals. */ if (c == '"') { - int no_error; + int no_error = 1; char *string; - for (no_error = 1, c = java_get_unicode (); - c != UEOF && c != '"' && c != '\n'; c = java_get_unicode ()) + for (;;) { + c = java_peek_unicode (); + if (c == '\n' || c == UEOF) /* ULT. */ + { + java_lex_error ("String not terminated at end of line", 0); + break; + } + java_next_unicode (); + if (c == '"') + break; if (c == '\\') c = java_parse_escape_sequence (); if (c == JAVA_CHAR_ERROR) @@ -1362,12 +1395,6 @@ do_java_lex (YYSTYPE *java_lval) } java_unicode_2_utf8 (c); } - if (c == '\n' || c == UEOF) /* ULT. */ - { - input_line--; /* Refer to the line where the terminator was seen. */ - java_lex_error ("String not terminated at end of line", 0); - input_line++; - } obstack_1grow (&temporary_obstack, '\0'); string = obstack_finish (&temporary_obstack); @@ -1382,51 +1409,108 @@ do_java_lex (YYSTYPE *java_lval) return STRING_LIT_TK; } - /* Separator. */ switch (c) { + case '/': + /* Check for comment. */ + switch (c = java_peek_unicode ()) + { + case '/': + java_next_unicode (); + for (;;) + { + c = java_get_unicode (); + if (c == UEOF) + { + /* It is ok to end a `//' comment with EOF, unless + we're being pedantic. */ + if (pedantic) + java_lex_error ("Comment not terminated at end of input", + 0); + return 0; + } + if (c == '\n') /* ULT */ + goto step1; + } + break; + + case '*': + java_next_unicode (); + if ((c = java_get_unicode ()) == '*') + { + c = java_get_unicode (); + if (c == '/') + { + /* Empty documentation comment. We have to reset + the deprecation marker as only the most recent + doc comment applies. */ + ctxp->deprecated = 0; + } + else + java_parse_doc_section (c); + } + else + java_parse_end_comment ((c = java_get_unicode ())); + goto step1; + break; + + case '=': + java_next_unicode (); + BUILD_OPERATOR2 (DIV_ASSIGN_TK); + + default: + BUILD_OPERATOR (DIV_TK); + } + case '(': - JAVA_LEX_SEP (c); BUILD_OPERATOR (OP_TK); case ')': - JAVA_LEX_SEP (c); return CP_TK; case '{': - JAVA_LEX_SEP (c); +#ifndef JC1_LITE + java_lval->operator.token = OCB_TK; + java_lval->operator.location = BUILD_LOCATION(); +#endif +#ifdef USE_MAPPED_LOCATION + if (ctxp->ccb_indent == 1) + ctxp->first_ccb_indent1 = input_location; +#else if (ctxp->ccb_indent == 1) ctxp->first_ccb_indent1 = input_line; +#endif ctxp->ccb_indent++; - BUILD_OPERATOR (OCB_TK); + return OCB_TK; case '}': - JAVA_LEX_SEP (c); +#ifndef JC1_LITE + java_lval->operator.token = CCB_TK; + java_lval->operator.location = BUILD_LOCATION(); +#endif ctxp->ccb_indent--; +#ifdef USE_MAPPED_LOCATION + if (ctxp->ccb_indent == 1) + ctxp->last_ccb_indent1 = input_location; +#else if (ctxp->ccb_indent == 1) ctxp->last_ccb_indent1 = input_line; - BUILD_OPERATOR (CCB_TK); +#endif + return CCB_TK; case '[': - JAVA_LEX_SEP (c); BUILD_OPERATOR (OSB_TK); case ']': - JAVA_LEX_SEP (c); return CSB_TK; case ';': - JAVA_LEX_SEP (c); return SC_TK; case ',': - JAVA_LEX_SEP (c); return C_TK; case '.': - JAVA_LEX_SEP (c); BUILD_OPERATOR (DOT_TK); - /* return DOT_TK; */ - } - /* Operators. */ - switch (c) - { + /* Operators. */ case '=': - if ((c = java_get_unicode ()) == '=') + c = java_peek_unicode (); + if (c == '=') { + java_next_unicode (); BUILD_OPERATOR (EQ_TK); } else @@ -1435,283 +1519,178 @@ do_java_lex (YYSTYPE *java_lval) variable_declarator: rule, it has to be seen as '=' as opposed to being seen as an ordinary assignment operator in assignment_operators: rule. */ - java_unget_unicode (); BUILD_OPERATOR (ASSIGN_TK); } case '>': - switch ((c = java_get_unicode ())) + switch ((c = java_peek_unicode ())) { case '=': + java_next_unicode (); BUILD_OPERATOR (GTE_TK); case '>': - switch ((c = java_get_unicode ())) + java_next_unicode (); + switch ((c = java_peek_unicode ())) { case '>': - if ((c = java_get_unicode ()) == '=') + java_next_unicode (); + c = java_peek_unicode (); + if (c == '=') { + java_next_unicode (); BUILD_OPERATOR2 (ZRS_ASSIGN_TK); } else { - java_unget_unicode (); BUILD_OPERATOR (ZRS_TK); } case '=': + java_next_unicode (); BUILD_OPERATOR2 (SRS_ASSIGN_TK); default: - java_unget_unicode (); BUILD_OPERATOR (SRS_TK); } default: - java_unget_unicode (); BUILD_OPERATOR (GT_TK); } case '<': - switch ((c = java_get_unicode ())) + switch ((c = java_peek_unicode ())) { case '=': + java_next_unicode (); BUILD_OPERATOR (LTE_TK); case '<': - if ((c = java_get_unicode ()) == '=') + java_next_unicode (); + if ((c = java_peek_unicode ()) == '=') { + java_next_unicode (); BUILD_OPERATOR2 (LS_ASSIGN_TK); } else { - java_unget_unicode (); BUILD_OPERATOR (LS_TK); } default: - java_unget_unicode (); BUILD_OPERATOR (LT_TK); } case '&': - switch ((c = java_get_unicode ())) + switch ((c = java_peek_unicode ())) { case '&': + java_next_unicode (); BUILD_OPERATOR (BOOL_AND_TK); case '=': + java_next_unicode (); BUILD_OPERATOR2 (AND_ASSIGN_TK); default: - java_unget_unicode (); BUILD_OPERATOR (AND_TK); } case '|': - switch ((c = java_get_unicode ())) + switch ((c = java_peek_unicode ())) { case '|': + java_next_unicode (); BUILD_OPERATOR (BOOL_OR_TK); case '=': + java_next_unicode (); BUILD_OPERATOR2 (OR_ASSIGN_TK); default: - java_unget_unicode (); BUILD_OPERATOR (OR_TK); } case '+': - switch ((c = java_get_unicode ())) + switch ((c = java_peek_unicode ())) { case '+': + java_next_unicode (); BUILD_OPERATOR (INCR_TK); case '=': + java_next_unicode (); BUILD_OPERATOR2 (PLUS_ASSIGN_TK); default: - java_unget_unicode (); BUILD_OPERATOR (PLUS_TK); } case '-': - switch ((c = java_get_unicode ())) + switch ((c = java_peek_unicode ())) { case '-': + java_next_unicode (); BUILD_OPERATOR (DECR_TK); case '=': + java_next_unicode (); BUILD_OPERATOR2 (MINUS_ASSIGN_TK); default: - java_unget_unicode (); BUILD_OPERATOR (MINUS_TK); } case '*': - if ((c = java_get_unicode ()) == '=') + if ((c = java_peek_unicode ()) == '=') { + java_next_unicode (); BUILD_OPERATOR2 (MULT_ASSIGN_TK); } else { - java_unget_unicode (); BUILD_OPERATOR (MULT_TK); } - case '/': - if ((c = java_get_unicode ()) == '=') - { - BUILD_OPERATOR2 (DIV_ASSIGN_TK); - } - else - { - java_unget_unicode (); - BUILD_OPERATOR (DIV_TK); - } - case '^': - if ((c = java_get_unicode ()) == '=') + if ((c = java_peek_unicode ()) == '=') { + java_next_unicode (); BUILD_OPERATOR2 (XOR_ASSIGN_TK); } else { - java_unget_unicode (); BUILD_OPERATOR (XOR_TK); } case '%': - if ((c = java_get_unicode ()) == '=') + if ((c = java_peek_unicode ()) == '=') { + java_next_unicode (); BUILD_OPERATOR2 (REM_ASSIGN_TK); } else { - java_unget_unicode (); BUILD_OPERATOR (REM_TK); } case '!': - if ((c = java_get_unicode()) == '=') + if ((c = java_peek_unicode()) == '=') { + java_next_unicode (); BUILD_OPERATOR (NEQ_TK); } else { - java_unget_unicode (); BUILD_OPERATOR (NEG_TK); } case '?': - JAVA_LEX_OP ("?"); BUILD_OPERATOR (REL_QM_TK); case ':': - JAVA_LEX_OP (":"); BUILD_OPERATOR (REL_CL_TK); case '~': BUILD_OPERATOR (NOT_TK); } - /* Keyword, boolean literal or null literal. */ - for (first_unicode = c, all_ascii = 1, ascii_index = 0; - c != UEOF && JAVA_PART_CHAR_P (c); c = java_get_unicode ()) - { - java_unicode_2_utf8 (c); - if (all_ascii && c >= 128) - all_ascii = 0; - ascii_index++; - } - - obstack_1grow (&temporary_obstack, '\0'); - string = obstack_finish (&temporary_obstack); - if (c != UEOF) - java_unget_unicode (); - - /* If we have something all ascii, we consider a keyword, a boolean - literal, a null literal or an all ASCII identifier. Otherwise, - this is an identifier (possibly not respecting formation rule). */ - if (all_ascii) - { - const struct java_keyword *kw; - if ((kw=java_keyword (string, ascii_index))) - { - JAVA_LEX_KW (string); - switch (kw->token) - { - case PUBLIC_TK: case PROTECTED_TK: case STATIC_TK: - case ABSTRACT_TK: case FINAL_TK: case NATIVE_TK: - case SYNCHRONIZED_TK: case TRANSIENT_TK: case VOLATILE_TK: - case PRIVATE_TK: case STRICT_TK: - SET_MODIFIER_CTX (kw->token); - return MODIFIER_TK; - case FLOAT_TK: - SET_LVAL_NODE (float_type_node); - return FP_TK; - case DOUBLE_TK: - SET_LVAL_NODE (double_type_node); - return FP_TK; - case BOOLEAN_TK: - SET_LVAL_NODE (boolean_type_node); - return BOOLEAN_TK; - case BYTE_TK: - SET_LVAL_NODE (byte_type_node); - return INTEGRAL_TK; - case SHORT_TK: - SET_LVAL_NODE (short_type_node); - return INTEGRAL_TK; - case INT_TK: - SET_LVAL_NODE (int_type_node); - return INTEGRAL_TK; - case LONG_TK: - SET_LVAL_NODE (long_type_node); - return INTEGRAL_TK; - case CHAR_TK: - SET_LVAL_NODE (char_type_node); - return INTEGRAL_TK; - - /* Keyword based literals. */ - case TRUE_TK: - case FALSE_TK: - SET_LVAL_NODE ((kw->token == TRUE_TK ? - boolean_true_node : boolean_false_node)); - return BOOL_LIT_TK; - case NULL_TK: - SET_LVAL_NODE (null_pointer_node); - return NULL_TK; - - case ASSERT_TK: - if (flag_assert) - { - BUILD_OPERATOR (kw->token); - return kw->token; - } - else - break; - - /* Some keyword we want to retain information on the location - they where found. */ - case CASE_TK: - case DEFAULT_TK: - case SUPER_TK: - case THIS_TK: - case RETURN_TK: - case BREAK_TK: - case CONTINUE_TK: - case TRY_TK: - case CATCH_TK: - case THROW_TK: - case INSTANCEOF_TK: - BUILD_OPERATOR (kw->token); - - default: - return kw->token; - } - } - } - - /* We may have an ID here. */ - if (JAVA_START_CHAR_P (first_unicode)) + if (c == 0x1a) /* CTRL-Z. */ { - JAVA_LEX_ID (string); - java_lval->node = BUILD_ID_WFL (GET_IDENTIFIER (string)); - return ID_TK; + if ((c = java_peek_unicode ()) == UEOF) + return 0; /* Ok here. */ } /* Everything else is an invalid character in the input. */ { char lex_error_buffer [128]; - sprintf (lex_error_buffer, "Invalid character `%s' in input", - java_sprint_unicode (ctxp->c_line, ctxp->c_line->current)); - java_lex_error (lex_error_buffer, 1); + sprintf (lex_error_buffer, "Invalid character '%s' in input", + java_sprint_unicode (c)); + java_lex_error (lex_error_buffer, -1); } return 0; } @@ -1742,9 +1721,9 @@ error_if_numeric_overflow (tree value) && tree_int_cst_sgn (value) < 0) { if (TREE_TYPE (value) == long_type_node) - java_lex_error ("Numeric overflow for `long' literal", 0); + java_lex_error ("Numeric overflow for 'long' literal", 0); else - java_lex_error ("Numeric overflow for `int' literal", 0); + java_lex_error ("Numeric overflow for 'int' literal", 0); } } @@ -1777,7 +1756,13 @@ java_unicode_2_utf8 (unicode_t unicode) static tree build_wfl_node (tree node) { - node = build_expr_wfl (node, ctxp->filename, ctxp->elc.line, ctxp->elc.col); +#ifdef USE_MAPPED_LOCATION + node = build_expr_wfl (node, input_location); +#else + node = build_expr_wfl (node, ctxp->filename, + ctxp->lexer->token_start.line, + ctxp->lexer->token_start.col); +#endif /* Prevent java_complete_lhs from short-circuiting node (if constant). */ TREE_TYPE (node) = NULL_TREE; return node; @@ -1788,13 +1773,28 @@ static void java_lex_error (const char *msg ATTRIBUTE_UNUSED, int forward ATTRIBUTE_UNUSED) { #ifndef JC1_LITE - ctxp->elc.line = ctxp->c_line->lineno; - ctxp->elc.col = ctxp->c_line->char_col-1+forward; + int col = (ctxp->lexer->position.col + + forward * ctxp->lexer->next_columns); +#if USE_MAPPED_LOCATION + source_location save_location = input_location; + LINEMAP_POSITION_FOR_COLUMN (input_location, &line_table, col); + + /* Might be caught in the middle of some error report. */ + ctxp->java_error_flag = 0; + java_error (NULL); + java_error (msg); + input_location = save_location; +#else + java_lc save = ctxp->lexer->token_start; + ctxp->lexer->token_start.line = ctxp->lexer->position.line; + ctxp->lexer->token_start.col = col; /* Might be caught in the middle of some error report. */ ctxp->java_error_flag = 0; java_error (NULL); java_error (msg); + ctxp->lexer->token_start = save; +#endif #endif } @@ -1880,11 +1880,11 @@ java_get_line_col (const char *filename ATTRIBUTE_UNUSED, /* Place the '^' a the right position. */ base = obstack_base (&temporary_obstack); - for (ccol = 1; ccol <= col+3; ccol++) + for (col += 2, ccol = 0; ccol < col; ccol++) { /* Compute \t when reaching first_non_space. */ char c = (first_non_space ? - (base [ccol-1] == '\t' ? '\t' : ' ') : ' '); + (base [ccol] == '\t' ? '\t' : ' ') : ' '); obstack_1grow (&temporary_obstack, c); } obstack_grow0 (&temporary_obstack, "^", 1); diff --git a/gcc/java/lex.h b/gcc/java/lex.h index bae5047..c9d5ac6 100644 --- a/gcc/java/lex.h +++ b/gcc/java/lex.h @@ -42,65 +42,9 @@ typedef unsigned short unicode_t; /* Default encoding to use if no encoding is specified. */ #define DEFAULT_ENCODING "UTF-8" -/* Debug macro to print-out what we match */ -#ifdef JAVA_LEX_DEBUG -#ifdef JAVA_LEX_DEBUG_CHAR -#define JAVA_LEX_CHAR(c) printf ("java_lex:%d: char '%c'.%d\n", \ - lineno, (c < 128 ? c : '.'), c); -#else -#define JAVA_LEX_CHAR(c) -#endif -#define JAVA_LEX_KW(c) printf ("java_lex:%d: keyword: '%s'\n", lineno,c) -#define JAVA_LEX_ID(s) printf ("java_lex:%d: ID: '%s'\n", \ - lineno, \ - (all_ascii ? s : "<U>")) -#define JAVA_LEX_LIT(s, r) printf ("java_lex:%d: literal '%s'_%d\n", \ - lineno, s, r) -#define JAVA_LEX_CHAR_LIT(s) printf ("java_lex:%d: literal '%d'\n", lineno, s) -#define JAVA_LEX_STR_LIT(s) { \ - int i; \ - printf ("java_lex:%d: literal '%s'\n", \ - lineno, s); \ - } -#define JAVA_LEX_SEP(c) printf ("java_lex:%d: separator '%c'\n",lineno,c) -#define JAVA_LEX_OP(c) printf ("java_lex:%d: operator '%s'\n", lineno,c) -#else -#define JAVA_LEX_CHAR(c) -#define JAVA_LEX_KW(c) -#define JAVA_LEX_ID(s) -#define JAVA_LEX_LIT(s,r) -#define JAVA_LEX_CHAR_LIT(s) -#define JAVA_LEX_STR_LIT(s) -#define JAVA_LEX_SEP(c) -#define JAVA_LEX_OP(s) -#endif - -/* Line information containers */ -struct java_line { - unicode_t *line; /* The line's unicode */ - char *unicode_escape_p; /* The matching char was a unicode escape */ - unicode_t ahead[1]; /* Character ahead */ - char unicode_escape_ahead_p; /* Character ahead is a unicode escape */ - int max; /* buffer's max size */ - int size; /* number of unicodes */ - int current; /* Current position, unicode based */ - int char_col; /* Current position, input char based */ - int lineno; /* Its line number */ - int white_space_only; /* If it contains only white spaces */ -}; -#define JAVA_COLUMN_DELTA(p) \ - (ctxp->c_line->unicode_escape_p [ctxp->c_line->current+(p)] ? 6 : \ - (ctxp->c_line->line [ctxp->c_line->current+(p)] == '\t' ? 8 : 1)) - -struct java_error { - struct java_line *line; - int error; -}; - typedef struct java_lc_s GTY(()) { - int line; - int prev_col; - int col; + int line; /* line number (1-based) */ + int col; /* column number number (1-based) */ } java_lc; struct java_lexer @@ -111,15 +55,33 @@ struct java_lexer /* Number of consecutive backslashes we've read. */ int bs_count; - /* If nonzero, a value that was pushed back. */ + /* Next available Unicode character. + * This is post-Unicode-escape-processing. -1 if EOF. */ + int next_unicode; + + /* True if next_unicode is next available character, or EOF. */ + bool avail_unicode; + + /* Number of source columns of the previous Unicode character (next_unicode). + If next_unicode==-2, then this is the number of columns of the previous + Unicode character (most recent result of java_{get,peek}_unicode). */ + int next_columns; + + /* If nonzero, a value that was pushed back. This is a unicode character, + but (unlike next_unicode) is pre-'\uXXXX'-processing. It is also used + when a '\r' is *not* followed by a '\n'. */ unicode_t unget_value; - /* If nonzero, we've hit EOF. Used only by java_get_unicode(). */ - unsigned int hit_eof : 1; - /* Name of the character encoding we're using. */ const char *encoding; + /* Current source position. */ + java_lc position; + +#ifndef USE_MAPPED_LOCATION + java_lc token_start; /* Error's line column info */ +#endif + #ifdef HAVE_ICONV /* Nonzero if we've read any bytes. We only recognize the byte-order-marker (BOM) as the first word. */ @@ -168,7 +130,12 @@ extern void java_destroy_lexer (java_lexer *); #define JAVA_LINE_MAX 80 /* Build a location compound integer */ -#define BUILD_LOCATION() ((ctxp->elc.line << 12) | (ctxp->elc.col & 0xfff)) +#ifdef USE_MAPPED_LOCATION +#define BUILD_LOCATION() input_location +#else +#define BUILD_LOCATION() ((ctxp->lexer->token_start.line << 12) \ + | (ctxp->lexer->token_start.col & 0xfff)) +#endif /* Those macros are defined differently if we compile jc1-lite (JC1_LITE defined) or jc1. */ @@ -190,7 +157,7 @@ extern void java_destroy_lexer (java_lexer *); #define SET_LVAL_NODE(NODE) #define BUILD_ID_WFL(EXP) (EXP) #define JAVA_FLOAT_RANGE_ERROR(S) {} -#define JAVA_INTEGRAL_RANGE_ERROR(S) do { } while (0) +#define JAVA_RANGE_ERROR(S) do { } while (0) #else @@ -227,21 +194,19 @@ extern void java_destroy_lexer (java_lexer *); /* Wrap identifier around a wfl */ #define BUILD_ID_WFL(EXP) build_wfl_node ((EXP)) /* Special ways to report error on numeric literals */ -#define JAVA_FLOAT_RANGE_ERROR(m) \ - { \ - char msg [1024]; \ - int i = ctxp->c_line->current; \ - ctxp->c_line->current = number_beginning; \ - sprintf (msg, "Floating point literal exceeds range of `%s'", (m)); \ - java_lex_error (msg, 0); \ - ctxp->c_line->current = i; \ +#define JAVA_FLOAT_RANGE_ERROR(m) \ + { \ + char *msg = xmalloc (100 + strlen (m)); \ + sprintf (msg, "Floating point literal exceeds range of `%s'", (m)); \ + JAVA_RANGE_ERROR(msg); \ + free (msg); \ } -#define JAVA_INTEGRAL_RANGE_ERROR(m) \ - do { \ - int i = ctxp->c_line->current; \ - ctxp->c_line->current = number_beginning; \ - java_lex_error (m, 0); \ - ctxp->c_line->current = i; \ +#define JAVA_RANGE_ERROR(msg) \ + do { \ + int save_col = ctxp->lexer->position.col; \ + ctxp->lexer->position.col = number_beginning; \ + java_lex_error (msg, 0); \ + ctxp->lexer->position.col = save_col; \ } while (0) #endif /* Definitions for jc1 compilation only */ diff --git a/gcc/java/parse.h b/gcc/java/parse.h index 95e4b23..b83d22e 100644 --- a/gcc/java/parse.h +++ b/gcc/java/parse.h @@ -89,6 +89,23 @@ extern tree stabilize_reference (tree); #define MODIFIER_WFL(M) (ctxp->modifier_ctx [(M) - PUBLIC_TK]) /* Check on modifiers */ +#ifdef USE_MAPPED_LOCATION +#define THIS_MODIFIER_ONLY(f, m, v, count, l) \ + if ((f) & (m)) \ + { \ + tree node = MODIFIER_WFL (v); \ + if (!l) \ + l = node; \ + else \ + { \ + expanded_location lloc = expand_location (EXPR_LOCATION (l)); \ + expanded_location nloc = expand_location (EXPR_LOCATION (node)); \ + if (nloc.column > lloc.column || nloc.line > lloc.line) \ + l = node; \ + } \ + count++; \ + } +#else #define THIS_MODIFIER_ONLY(f, m, v, count, l) \ if ((f) & (m)) \ { \ @@ -101,6 +118,7 @@ extern tree stabilize_reference (tree); l = node; \ count++; \ } +#endif #define ABSTRACT_CHECK(FLAG, V, CL, S) \ if ((FLAG) & (V)) \ @@ -163,11 +181,13 @@ extern tree stabilize_reference (tree); && !TREE_TYPE (NODE) \ && TREE_CODE (TYPE_NAME (NODE)) == IDENTIFIER_NODE) +#ifndef USE_MAPPED_LOCATION /* Set the EMIT_LINE_NOTE flag of a EXPR_WLF to 1 if debug information are requested. Works in the context of a parser rule. */ #define JAVA_MAYBE_GENERATE_DEBUG_INFO(node) \ - (debug_info_level != DINFO_LEVEL_NONE ? \ - EXPR_WFL_EMIT_LINE_NOTE (node) = 1, node : node) + do {if (debug_info_level != DINFO_LEVEL_NONE) \ + EXPR_WFL_EMIT_LINE_NOTE (node) = 1; } while (0) +#endif /* Types classification, according to the JLS, section 4.2 */ #define JFLOAT_TYPE_P(TYPE) (TYPE && TREE_CODE ((TYPE)) == REAL_TYPE) @@ -610,20 +630,14 @@ typedef struct jdeplist_s jdeplist; #define GET_CURRENT_BLOCK(F) ((F) ? DECL_FUNCTION_BODY ((F)) : \ current_static_block) +#ifndef USE_MAPPED_LOCATION /* Retrieve line/column from a WFL. */ #define EXPR_WFL_GET_LINECOL(V,LINE,COL) \ { \ (LINE) = (V) >> 12; \ (COL) = (V) & 0xfff; \ } -/* Add X to the column number information */ -#define EXPR_WFL_ADD_COL(V, X) \ - (V) = (((V) & 0xfffff000) | ((((V) & 0xfff) + (X)) & 0xfff)) - -/* Build a WFL for expression nodes */ -#define BUILD_EXPR_WFL(NODE, WFL) \ - build_expr_wfl ((NODE), input_filename, EXPR_WFL_LINENO ((WFL)), \ - EXPR_WFL_COLNO ((WFL))) +#endif #define EXPR_WFL_QUALIFICATION(WFL) TREE_OPERAND ((WFL), 1) #define QUAL_WFL(NODE) TREE_PURPOSE (NODE) @@ -671,10 +685,17 @@ typedef struct jdeplist_s jdeplist; } /* Set wfl_operator for the most accurate error location */ +#ifdef USE_MAPPED_LOCATION +#define SET_WFL_OPERATOR(WHICH, NODE, WFL) \ + SET_EXPR_LOCATION (WHICH, \ + (TREE_CODE (WFL) == EXPR_WITH_FILE_LOCATION ? \ + EXPR_LOCATION (WFL) : EXPR_LOCATION (NODE))) +#else #define SET_WFL_OPERATOR(WHICH, NODE, WFL) \ EXPR_WFL_LINECOL (WHICH) = \ (TREE_CODE (WFL) == EXPR_WITH_FILE_LOCATION ? \ EXPR_WFL_LINECOL (WFL) : EXPR_WFL_LINECOL (NODE)) +#endif #define PATCH_METHOD_RETURN_ERROR() \ { \ @@ -724,23 +745,23 @@ typedef struct jdeplist_s jdeplist; /* Parser context data structure. */ struct parser_ctxt GTY(()) { - - const char *filename; /* Current filename */ + const char *filename; /* Current filename */ + location_t file_start_location; + location_t save_location; struct parser_ctxt *next; java_lexer * GTY((skip)) lexer; /* Current lexer state */ char marker_begining; /* Marker. Should be a sub-struct */ - struct java_line * GTY ((skip)) p_line; /* Previous line */ - struct java_line * GTY ((skip)) c_line; /* Current line */ - java_lc elc; /* Error's line column info */ - int ccb_indent; /* Keep track of {} indent, lexer */ - int first_ccb_indent1; /* First { at ident level 1 */ - int last_ccb_indent1; /* Last } at ident level 1 */ + int ccb_indent; /* Number of unmatched { seen. */ + /* The next two fields are only source_location if USE_MAPPED_LOCATION. + Otherwise, they are integer line number, but we can't have #ifdefs + in GTY structures. */ + source_location first_ccb_indent1; /* First { at ident level 1 */ + source_location last_ccb_indent1; /* Last } at ident level 1 */ int parser_ccb_indent; /* Keep track of {} indent, parser */ int osb_depth; /* Current depth of [ in an expression */ int osb_limit; /* Limit of this depth */ int * GTY ((skip)) osb_number; /* Keep track of ['s */ - int lineno; /* Current lineno */ char marker_end; /* End marker. Should be a sub-struct */ /* The flags section */ @@ -763,8 +784,6 @@ struct parser_ctxt GTY(()) { tree class_type; /* Current class */ tree function_decl; /* Current function decl, save/restore */ - struct JCF * current_jcf; /* CU jcf */ - int prevent_ese; /* Prevent expression statement error */ int formal_parameter_number; /* Number of parameters found */ diff --git a/gcc/java/parse.y b/gcc/java/parse.y index e3dab6a..dc62f86 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -97,8 +97,13 @@ static void fix_method_argument_names (tree ,tree); static tree method_declarator (tree, tree); static void parse_warning_context (tree cl, const char *msg, ...) ATTRIBUTE_PRINTF_2; +#ifdef USE_MAPPED_LOCATION +static void issue_warning_error_from_context + (source_location, const char *msg, va_list) ATTRIBUTE_PRINTF (2, 0); +#else static void issue_warning_error_from_context (tree, const char *msg, va_list) ATTRIBUTE_PRINTF (2, 0); +#endif static void parse_ctor_invocation_error (void); static tree parse_jdk1_1_error (const char *); static void complete_class_report_errors (jdep *); @@ -175,7 +180,11 @@ static int build_type_name_from_array_name (tree, tree *); static tree build_array_from_name (tree, tree, tree, tree *); static tree build_array_ref (int, tree, tree); static tree patch_array_ref (tree); +#ifdef USE_MAPPED_LOCATION +static tree make_qualified_name (tree, tree, source_location); +#else static tree make_qualified_name (tree, tree, int); +#endif static tree merge_qualified_name (tree, tree); static tree make_qualified_primary (tree, tree, int); static int resolve_qualified_expression_name (tree, tree *, tree *, tree *); @@ -214,13 +223,21 @@ static tree build_string_concatenation (tree, tree); static tree patch_string_cst (tree); static tree patch_string (tree); static tree encapsulate_with_try_catch (int, tree, tree, tree); +#ifdef USE_MAPPED_LOCATION +static tree build_assertion (source_location, tree, tree); +#else static tree build_assertion (int, tree, tree); +#endif static tree build_try_statement (int, tree, tree); static tree build_try_finally_statement (int, tree, tree); static tree patch_try_statement (tree); static tree patch_synchronized_statement (tree, tree); static tree patch_throw_statement (tree, tree); +#ifdef USE_MAPPED_LOCATION +static void check_thrown_exceptions (source_location, tree, tree); +#else static void check_thrown_exceptions (int, tree, tree); +#endif static int check_thrown_exceptions_do (tree); static void purge_unchecked_exceptions (tree); static bool ctors_unchecked_throws_clause_p (tree); @@ -443,12 +460,24 @@ static GTY(()) tree src_parse_roots[1]; int sub_token; struct { int token; +#ifdef USE_MAPPED_LOCATION + source_location location; +#else int location; +#endif } operator; int value; } %{ +#ifdef USE_MAPPED_LOCATION +#define SET_EXPR_LOCATION_FROM_TOKEN(EXPR, TOKEN) \ + SET_EXPR_LOCATION(EXPR, (TOKEN).location) +#else +#define SET_EXPR_LOCATION_FROM_TOKEN(EXPR, TOKEN) \ + (EXPR_WFL_LINECOL (EXPR) = (TOKEN).location) +#endif + #include "lex.c" %} @@ -882,16 +911,14 @@ class_body: { /* Store the location of the `}' when doing xrefs */ if (flag_emit_xref) - DECL_END_SOURCE_LINE (GET_CPC ()) = - EXPR_WFL_ADD_COL ($2.location, 1); + DECL_END_SOURCE_LINE (GET_CPC ()) = $2.location; $$ = GET_CPC (); } | OCB_TK class_body_declarations CCB_TK { /* Store the location of the `}' when doing xrefs */ if (flag_emit_xref) - DECL_END_SOURCE_LINE (GET_CPC ()) = - EXPR_WFL_ADD_COL ($3.location, 1); + DECL_END_SOURCE_LINE (GET_CPC ()) = $3.location; $$ = GET_CPC (); } ; @@ -1055,7 +1082,7 @@ method_declarator: { $$ = method_declarator ($1, $3); } | method_declarator OSB_TK CSB_TK { - EXPR_WFL_LINECOL (wfl_operator) = $2.location; + SET_EXPR_LOCATION_FROM_TOKEN (wfl_operator, $2); TREE_PURPOSE ($1) = build_unresolved_array_type (TREE_PURPOSE ($1)); parse_warning_context @@ -1236,13 +1263,13 @@ this_or_super: /* Added, simplifies error diagnostics */ THIS_TK { tree wfl = build_wfl_node (this_identifier_node); - EXPR_WFL_LINECOL (wfl) = $1.location; + SET_EXPR_LOCATION_FROM_TOKEN (wfl, $1); $$ = wfl; } | SUPER_TK { tree wfl = build_wfl_node (super_identifier_node); - EXPR_WFL_LINECOL (wfl) = $1.location; + SET_EXPR_LOCATION_FROM_TOKEN (wfl, $1); $$ = wfl; } ; @@ -1369,8 +1396,7 @@ block_end: maybe_absorb_scoping_blocks (); /* Store the location of the `}' when doing xrefs */ if (current_function_decl && flag_emit_xref) - DECL_END_SOURCE_LINE (current_function_decl) = - EXPR_WFL_ADD_COL ($1.location, 1); + DECL_END_SOURCE_LINE (current_function_decl) = $1.location; $$ = exit_block (); if (!BLOCK_SUBBLOCKS ($$)) BLOCK_SUBBLOCKS ($$) = build_java_empty_stmt (); @@ -1449,7 +1475,11 @@ empty_statement: (DECL_CONTEXT (current_function_decl))))) { +#ifdef USE_MAPPED_LOCATION + SET_EXPR_LOCATION (wfl_operator, input_location); +#else EXPR_WFL_SET_LINECOL (wfl_operator, input_line, -1); +#endif parse_warning_context (wfl_operator, "An empty declaration is a deprecated feature that should not be used"); } $$ = build_java_empty_stmt (); @@ -1486,10 +1516,14 @@ expression_statement: { /* We have a statement. Generate a WFL around it so we can debug it */ +#ifdef USE_MAPPED_LOCATION + $$ = expr_add_location ($1, input_location, 1); +#else $$ = build_expr_wfl ($1, input_filename, input_line, 0); + JAVA_MAYBE_GENERATE_DEBUG_INFO ($$); +#endif /* We know we have a statement, so set the debug info to be eventually generate here. */ - $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$); } | error SC_TK { @@ -1587,7 +1621,7 @@ switch_expression: { $$ = build3 (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE, NULL_TREE); - EXPR_WFL_LINECOL ($$) = $2.location; + SET_EXPR_LOCATION_FROM_TOKEN ($$, $2); } | SWITCH_TK error {yyerror ("'(' expected"); RECOVER;} @@ -1629,13 +1663,13 @@ switch_label: CASE_TK constant_expression REL_CL_TK { tree lab = build1 (CASE_EXPR, NULL_TREE, $2); - EXPR_WFL_LINECOL (lab) = $1.location; + SET_EXPR_LOCATION_FROM_TOKEN (lab, $1); java_method_add_stmt (current_function_decl, lab); } | DEFAULT_TK REL_CL_TK { tree lab = make_node (DEFAULT_EXPR); - EXPR_WFL_LINECOL (lab) = $1.location; + SET_EXPR_LOCATION_FROM_TOKEN (lab, $1); java_method_add_stmt (current_function_decl, lab); } | CASE_TK error @@ -1814,7 +1848,7 @@ throw_statement: THROW_TK expression SC_TK { $$ = build1 (THROW_EXPR, NULL_TREE, $2); - EXPR_WFL_LINECOL ($$) = $1.location; + SET_EXPR_LOCATION_FROM_TOKEN ($$, $1); } | THROW_TK error {yyerror ("Missing term"); RECOVER;} @@ -1917,7 +1951,7 @@ catch_clause_parameter: build_tree_list (TREE_PURPOSE ($3), init)); $$ = build1 (JAVA_CATCH_EXPR, NULL_TREE, ccpb); - EXPR_WFL_LINECOL ($$) = $1.location; + SET_EXPR_LOCATION_FROM_TOKEN ($$, $1); } else { @@ -2225,7 +2259,7 @@ field_access: | SUPER_TK DOT_TK identifier { tree super_wfl = build_wfl_node (super_identifier_node); - EXPR_WFL_LINECOL (super_wfl) = $1.location; + SET_EXPR_LOCATION_FROM_TOKEN (super_wfl, $1); $$ = make_qualified_name (super_wfl, $3, $2.location); } | SUPER_TK error @@ -2609,7 +2643,7 @@ conditional_expression: /* Error handling here is weak */ | conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression { $$ = build3 (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5); - EXPR_WFL_LINECOL ($$) = $2.location; + SET_EXPR_LOCATION_FROM_TOKEN ($$, $2); } | conditional_or_expression REL_QM_TK REL_CL_TK error { @@ -2718,16 +2752,15 @@ void java_pop_parser_context (int generate) { tree current; - struct parser_ctxt *toFree, *next; + struct parser_ctxt *next; if (!ctxp) return; - toFree = ctxp; next = ctxp->next; if (next) { - input_line = ctxp->lineno; + input_location = ctxp->save_location; current_class = ctxp->class_type; } @@ -2740,19 +2773,19 @@ java_pop_parser_context (int generate) for (current = ctxp->import_list; current; current = TREE_CHAIN (current)) IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 0; - /* And restore those of the previous context */ - if ((ctxp = next)) /* Assignment is really meant here */ - for (current = ctxp->import_list; current; current = TREE_CHAIN (current)) - IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 1; - /* If we pushed a context to parse a class intended to be generated, we keep it so we can remember the class. What we could actually do is to just update a list of class names. */ if (generate) { - toFree->next = ctxp_for_generation; - ctxp_for_generation = toFree; + ctxp->next = ctxp_for_generation; + ctxp_for_generation = ctxp; } + + /* And restore those of the previous context */ + if ((ctxp = next)) /* Assignment is really meant here */ + for (current = ctxp->import_list; current; current = TREE_CHAIN (current)) + IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 1; } /* Create a parser context for the use of saving some global @@ -2775,9 +2808,8 @@ java_parser_context_save_global (void) ctxp->saved_data_ctx = 1; } - ctxp->lineno = input_line; + ctxp->save_location = input_location; ctxp->class_type = current_class; - ctxp->filename = input_filename; ctxp->function_decl = current_function_decl; ctxp->saved_data = 1; } @@ -2788,11 +2820,14 @@ java_parser_context_save_global (void) void java_parser_context_restore_global (void) { - input_line = ctxp->lineno; + input_location = ctxp->save_location; current_class = ctxp->class_type; - input_filename = ctxp->filename; if (wfl_operator) +#ifdef USE_MAPPED_LOCATION + SET_EXPR_LOCATION (wfl_operator, ctxp->save_location); +#else EXPR_WFL_FILENAME_NODE (wfl_operator) = get_identifier (input_filename); +#endif current_function_decl = ctxp->function_decl; ctxp->saved_data = 0; if (ctxp->saved_data_ctx) @@ -2960,8 +2995,6 @@ java_debug_context_do (int tab) TAB_CONTEXT (tab); fprintf (stderr, "filename: %s\n", copy->filename); TAB_CONTEXT (tab); - fprintf (stderr, "lineno: %d\n", copy->lineno); - TAB_CONTEXT (tab); fprintf (stderr, "package: %s\n", (copy->package ? IDENTIFIER_POINTER (copy->package) : "<none>")); @@ -3016,22 +3049,36 @@ static int do_warning = 0; void yyerror (const char *msg) { +#ifdef USE_MAPPED_LOCATION + static source_location elc; + expanded_location xloc = expand_location (input_location); + int current_line = xloc.line; +#else static java_lc elc; - static int prev_lineno; + int save_lineno; + int current_line = input_line; +#endif + static int prev_lineno; static const char *prev_msg; - int save_lineno; char *remainder, *code_from_source; - if (!force_error && prev_lineno == input_line) + if (!force_error && prev_lineno == current_line) return; +#ifndef USE_MAPPED_LOCATION + current_line = ctxp->lexer->token_start.line; +#endif /* Save current error location but report latter, when the context is richer. */ if (ctxp->java_error_flag == 0) { ctxp->java_error_flag = 1; - elc = ctxp->elc; +#ifdef USE_MAPPED_LOCATION + elc = input_location; +#else + elc = ctxp->lexer->token_start; +#endif /* Do something to use the previous line if we're reaching the end of the file... */ #ifdef VERBOSE_SKELETON @@ -3041,7 +3088,7 @@ yyerror (const char *msg) } /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */ - if (!force_error && msg == prev_msg && prev_lineno == elc.line) + if (!force_error && msg == prev_msg && prev_lineno == current_line) return; ctxp->java_error_flag = 0; @@ -3050,17 +3097,24 @@ yyerror (const char *msg) else java_error_count++; +#if 0 /* FIXME */ if (elc.col == 0 && msg && msg[1] == ';') - { - elc.col = ctxp->p_line->char_col-1; - elc.line = ctxp->p_line->lineno; - } + elc = ctxp->prev_line_end; +#endif - save_lineno = input_line; - prev_lineno = input_line = elc.line; prev_msg = msg; - code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col); +#ifdef USE_MAPPED_LOCATION + prev_lineno = current_line; + code_from_source = java_get_line_col (xloc.file, current_line, xloc.column); +#else + save_lineno = input_line; + prev_lineno = input_line = current_line; + code_from_source = java_get_line_col (input_filename, current_line, + ctxp->lexer->token_start.col); +#endif + + obstack_grow0 (&temporary_obstack, code_from_source, strlen (code_from_source)); remainder = obstack_finish (&temporary_obstack); @@ -3074,46 +3128,80 @@ yyerror (const char *msg) the same line. This occurs when we report an error but don't have a synchronization point other than ';', which expression_statement is the only one to take care of. */ - ctxp->prevent_ese = input_line = save_lineno; +#ifndef USE_MAPPED_LOCATION + input_line = save_lineno; +#endif + ctxp->prevent_ese = input_line; } static void -issue_warning_error_from_context (tree cl, const char *msg, va_list ap) +issue_warning_error_from_context ( +#ifdef USE_MAPPED_LOCATION + source_location cl, +#else + tree cl, +#endif + const char *msg, va_list ap) { - const char *saved, *saved_input_filename; +#ifdef USE_MAPPED_LOCATION + source_location saved_location = input_location; + expanded_location xloc = expand_location (cl); +#else + java_lc save_lc = ctxp->lexer->token_start; + const char *saved = ctxp->filename, *saved_input_filename; +#endif char buffer [4096]; vsprintf (buffer, msg, ap); force_error = 1; - ctxp->elc.line = EXPR_WFL_LINENO (cl); - ctxp->elc.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : - (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl))); +#ifdef USE_MAPPED_LOCATION + if (xloc.file != NULL) + { + ctxp->filename = xloc.file; + input_location = cl; + } +#else + ctxp->lexer->token_start.line = EXPR_WFL_LINENO (cl); + ctxp->lexer->token_start.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 + : EXPR_WFL_COLNO (cl) == 0xffe ? -2 + : EXPR_WFL_COLNO (cl)); /* We have a CL, that's a good reason for using it if it contains data */ - saved = ctxp->filename; if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl)) ctxp->filename = EXPR_WFL_FILENAME (cl); saved_input_filename = input_filename; input_filename = ctxp->filename; +#endif java_error (NULL); java_error (buffer); +#ifdef USE_MAPPED_LOCATION + input_location = saved_location; +#else ctxp->filename = saved; input_filename = saved_input_filename; + ctxp->lexer->token_start = save_lc; +#endif force_error = 0; } -/* Issue an error message at a current source line CL */ +/* Issue an error message at a current source line CL. + FUTURE/FIXME: change cl to be a source_location. */ void parse_error_context (tree cl, const char *msg, ...) { va_list ap; va_start (ap, msg); +#ifdef USE_MAPPED_LOCATION + issue_warning_error_from_context (EXPR_LOCATION (cl), msg, ap); +#else issue_warning_error_from_context (cl, msg, ap); +#endif va_end (ap); } -/* Issue a warning at a current source line CL */ +/* Issue a warning at a current source line CL. + FUTURE/FIXME: change cl to be a source_location. */ static void parse_warning_context (tree cl, const char *msg, ...) @@ -3121,9 +3209,13 @@ parse_warning_context (tree cl, const char *msg, ...) va_list ap; va_start (ap, msg); - force_error = do_warning = 1; + do_warning = 1; +#ifdef USE_MAPPED_LOCATION + issue_warning_error_from_context (EXPR_LOCATION (cl), msg, ap); +#else issue_warning_error_from_context (cl, msg, ap); - do_warning = force_error = 0; +#endif + do_warning = 0; va_end (ap); } @@ -3174,7 +3266,11 @@ find_expr_with_wfl (tree node) static void missing_return_error (tree method) { +#ifdef USE_MAPPED_LOCATION + SET_EXPR_LOCATION (wfl_operator, DECL_FUNCTION_LAST_LINE (method)); +#else EXPR_WFL_SET_LINECOL (wfl_operator, DECL_FUNCTION_LAST_LINE (method), -2); +#endif parse_error_context (wfl_operator, "Missing return statement"); } @@ -3192,7 +3288,11 @@ unreachable_stmt_error (tree node) if (node) { +#ifdef USE_MAPPED_LOCATION + SET_EXPR_LOCATION (wfl_operator, EXPR_LOCATION (node)); +#else EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2); +#endif parse_error_context (wfl_operator, "Unreachable statement"); } else @@ -3383,10 +3483,14 @@ build_unresolved_array_type (tree type_or_wfl) IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl))); obstack_grow0 (&temporary_obstack, "[]", 2); ptr = obstack_finish (&temporary_obstack); +#ifdef USE_MAPPED_LOCATION + wfl = build_expr_wfl (get_identifier (ptr), EXPR_LOCATION (type_or_wfl)); +#else wfl = build_expr_wfl (get_identifier (ptr), EXPR_WFL_FILENAME (type_or_wfl), EXPR_WFL_LINENO (type_or_wfl), EXPR_WFL_COLNO (type_or_wfl)); +#endif /* Re-install the existing qualifications so that the type can be resolved properly. */ EXPR_WFL_QUALIFICATION (wfl) = EXPR_WFL_QUALIFICATION (type_or_wfl); @@ -3446,13 +3550,14 @@ check_class_interface_creation (int is_interface, int flags, tree raw_name, when dealing with an inner class */ if (!CPC_INNER_P () && (flags & ACC_PUBLIC )) { + const char *fname = input_filename; const char *f; - for (f = &input_filename [strlen (input_filename)]; - f != input_filename && ! IS_DIR_SEPARATOR (f[0]); + for (f = fname + strlen (fname); + f != fname && ! IS_DIR_SEPARATOR (*f); f--) ; - if (IS_DIR_SEPARATOR (f[0])) + if (IS_DIR_SEPARATOR (*f)) f++; if (strncmp (IDENTIFIER_POINTER (raw_name), f , IDENTIFIER_LENGTH (raw_name)) || @@ -3650,7 +3755,7 @@ find_as_inner_class (tree enclosing, tree name, tree cl) else if (cl) qual = build_tree_list (cl, NULL_TREE); else - qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE); + qual = build_tree_list (build_unknown_wfl (name), NULL_TREE); if ((to_return = find_as_inner_class_do (qual, enclosing))) return to_return; @@ -3680,7 +3785,7 @@ find_as_inner_class (tree enclosing, tree name, tree cl) } /* Otherwise, create a qual for the other part of the resolution. */ else - qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE); + qual = build_tree_list (build_unknown_wfl (name), NULL_TREE); return find_as_inner_class_do (qual, enclosing); } @@ -3769,16 +3874,28 @@ maybe_create_class_interface_decl (tree decl, tree raw_name, decl = push_class (make_class (), qualified_name); /* Take care of the file and line business */ +#ifdef USE_MAPPED_LOCATION + DECL_SOURCE_LOCATION (decl) = EXPR_LOCATION (cl); +#else DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl); /* If we're emitting xrefs, store the line/col number information */ if (flag_emit_xref) DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl); else DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl); +#endif CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1; CLASS_PARSED_P (TREE_TYPE (decl)) = 1; +#ifdef USE_MAPPED_LOCATION + { + tree tmp = maybe_get_identifier (EXPR_FILENAME (cl)); + CLASS_FROM_CURRENTLY_COMPILED_P (TREE_TYPE (decl)) = + tmp && IS_A_COMMAND_LINE_FILENAME_P (tmp); + } +#else CLASS_FROM_CURRENTLY_COMPILED_P (TREE_TYPE (decl)) = IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl)); +#endif PUSH_CPC (decl, raw_name); DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT (); @@ -4298,7 +4415,7 @@ register_fields (int flags, tree type, tree variable_list) { tree current, saved_type; tree class_type = NULL_TREE; - int saved_lineno = input_line; + location_t saved_location = input_location; int must_chain = 0; tree wfl = NULL_TREE; @@ -4367,10 +4484,14 @@ register_fields (int flags, tree type, tree variable_list) /* Set input_line to the line the field was found and create a declaration for it. Eventually sets the @deprecated tag flag. */ +#ifdef USE_MAPPED_LOCATION + input_location = EXPR_LOCATION (cl); +#else if (flag_emit_xref) input_line = EXPR_WFL_LINECOL (cl); else input_line = EXPR_WFL_LINENO (cl); +#endif field_decl = add_field (class_type, current_name, real_type, flags); CHECK_DEPRECATED_NO_RESET (field_decl); @@ -4432,7 +4553,7 @@ register_fields (int flags, tree type, tree variable_list) } CLEAR_DEPRECATED; - input_line = saved_lineno; + input_location = saved_location; } /* Generate finit$, using the list of initialized fields to populate @@ -4553,7 +4674,7 @@ method_header (int flags, tree type, tree mdecl, tree throws) tree meth_name = NULL_TREE; tree current, orig_arg, this_class = NULL; tree id, meth; - int saved_lineno; + location_t saved_location; int constructor_ok = 0, must_chain; int count; @@ -4684,12 +4805,17 @@ method_header (int flags, tree type, tree mdecl, tree throws) else TREE_TYPE (meth) = type; - saved_lineno = input_line; + saved_location = input_location; /* When defining an abstract or interface method, the curly bracket at level 1 doesn't exist because there is no function body */ - input_line = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : - EXPR_WFL_LINENO (id)); +#ifdef USE_MAPPED_LOCATION + input_location = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : + EXPR_LOCATION (id)); +#else + input_line = (ctxp->first_ccb_indent1 ? (int) ctxp->first_ccb_indent1 : + EXPR_WFL_LINENO (id)); +#endif /* Remember the original argument list */ orig_arg = TYPE_ARG_TYPES (meth); @@ -4722,7 +4848,7 @@ method_header (int flags, tree type, tree mdecl, tree throws) /* Register the parameter number and re-install the current line number */ DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1; - input_line = saved_lineno; + input_location = saved_location; /* Register exception specified by the `throws' keyword for resolution and set the method decl appropriate field to the list. @@ -4763,7 +4889,13 @@ method_header (int flags, tree type, tree mdecl, tree throws) /* If doing xref, store column and line number information instead of the line number only. */ if (flag_emit_xref) - DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id); + { +#ifdef USE_MAPPED_LOCATION + DECL_SOURCE_LOCATION (meth) = EXPR_LOCATION (id); +#else + DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id); +#endif + } return meth; } @@ -6746,22 +6878,28 @@ lookup_java_method2 (tree clas, tree method_decl, int do_interface) } /* Return the line that matches DECL line number, and try its best to - position the column number. Used during error reports. */ + position the column number. Used during error reports. + FUTURE/FIXME: return source_location instead of node. */ static GTY(()) tree cl_v; static tree lookup_cl (tree decl) { +#ifndef USE_MAPPED_LOCATION char *line, *found; +#endif if (!decl) return NULL_TREE; if (cl_v == NULL_TREE) { - cl_v = build_expr_wfl (NULL_TREE, NULL, 0, 0); + cl_v = build_unknown_wfl (NULL_TREE); } +#ifdef USE_MAPPED_LOCATION + SET_EXPR_LOCATION (cl_v, DECL_SOURCE_LOCATION (decl)); +#else EXPR_WFL_FILENAME_NODE (cl_v) = get_identifier (DECL_SOURCE_FILE (decl)); EXPR_WFL_SET_LINECOL (cl_v, DECL_SOURCE_LINE (decl), -1); @@ -6772,6 +6910,7 @@ lookup_cl (tree decl) (const char *)IDENTIFIER_POINTER (DECL_NAME (decl))); if (found) EXPR_WFL_SET_LINECOL (cl_v, EXPR_WFL_LINENO (cl_v), found - line); +#endif return cl_v; } @@ -7026,7 +7165,7 @@ find_in_imports_on_demand (tree enclosing_type, tree class_type) for (; import; import = TREE_CHAIN (import)) { - int saved_lineno = input_line; + location_t saved_location = input_location; int access_check; const char *id_name; tree decl, type_name_copy; @@ -7045,7 +7184,11 @@ find_in_imports_on_demand (tree enclosing_type, tree class_type) /* Setup input_line so that it refers to the line of the import (in case we parse a class file and encounter errors */ +#ifdef USE_MAPPED_LOCATION + input_location = EXPR_LOCATION (TREE_PURPOSE (import)); +#else input_line = EXPR_WFL_LINENO (TREE_PURPOSE (import)); +#endif type_name_copy = TYPE_NAME (class_type); TYPE_NAME (class_type) = node; @@ -7066,7 +7209,7 @@ find_in_imports_on_demand (tree enclosing_type, tree class_type) /* 6.6.1: Inner classes are subject to member access rules. */ access_check = 0; - input_line = saved_lineno; + input_location = saved_location; /* If the loaded class is not accessible or couldn't be loaded, we restore the original TYPE_NAME and process the next @@ -7363,8 +7506,13 @@ declare_local_variables (int modifier, tree type, tree vlist) /* If doing xreferencing, replace the line number with the WFL compound value */ +#ifdef USE_MAPPED_LOCATION + if (flag_emit_xref) + DECL_SOURCE_LOCATION (decl) = EXPR_LOCATION (wfl); +#else if (flag_emit_xref) DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl); +#endif /* Don't try to use an INIT statement when an error was found */ if (init && java_error_count) @@ -7462,9 +7610,9 @@ create_artificial_method (tree class, int flags, tree type, tree name, tree args) { tree mdecl; + location_t save_location = input_location; - java_parser_context_save_global (); - input_line = 0; + input_location = DECL_SOURCE_LOCATION (TYPE_NAME (class)); mdecl = make_node (FUNCTION_TYPE); TREE_TYPE (mdecl) = type; TYPE_ARG_TYPES (mdecl) = args; @@ -7473,7 +7621,7 @@ create_artificial_method (tree class, int flags, tree type, the type of the returned method, which trashes the cache in get_type_from_signature(). */ mdecl = add_method_1 (class, flags, name, mdecl); - java_parser_context_restore_global (); + input_location = save_location; DECL_ARTIFICIAL (mdecl) = 1; return mdecl; } @@ -7483,8 +7631,13 @@ create_artificial_method (tree class, int flags, tree type, static void start_artificial_method_body (tree mdecl) { +#ifdef USE_MAPPED_LOCATION + DECL_SOURCE_LOCATION (mdecl) = ctxp->file_start_location; + DECL_FUNCTION_LAST_LINE (mdecl) = ctxp->file_start_location; +#else DECL_SOURCE_LINE (mdecl) = 1; DECL_FUNCTION_LAST_LINE (mdecl) = 1; +#endif source_start_java_method (mdecl); enter_block (); } @@ -7528,7 +7681,11 @@ source_end_java_method (void) return; java_parser_context_save_global (); +#ifdef USE_MAPPED_LOCATION + input_location = ctxp->last_ccb_indent1; +#else input_line = ctxp->last_ccb_indent1; +#endif /* Turn function bodies with only a NOP expr null, so they don't get generated at all and we won't get warnings when using the -W @@ -7587,7 +7744,10 @@ java_layout_seen_class_methods (void) for (current = previous_list; current != end; current = TREE_CHAIN (current)) { - tree cls = TREE_TYPE (TREE_VALUE (current)); + tree decl = TREE_VALUE (current); + tree cls = TREE_TYPE (decl); + + input_location = DECL_SOURCE_LOCATION (decl); if (! CLASS_LOADED_P (cls)) load_class (cls, 0); @@ -8018,7 +8178,7 @@ start_complete_expand_method (tree mdecl) TREE_CHAIN (tem) = next; } pushdecl_force_head (DECL_ARGUMENTS (mdecl)); - input_line = DECL_SOURCE_LINE (mdecl); + input_location = DECL_SOURCE_LOCATION (mdecl); build_result_decl (mdecl); } @@ -8690,7 +8850,11 @@ build_thisn_assign (void) tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node), build_wfl_node (thisn), 0); tree rhs = build_wfl_node (thisn); +#ifdef USE_MAPPED_LOCATION + SET_EXPR_LOCATION (lhs, input_location); +#else EXPR_WFL_SET_LINECOL (lhs, input_line, 0); +#endif return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs); } return NULL_TREE; @@ -8714,7 +8878,11 @@ static tree build_dot_class_method (tree class) { #define BWF(S) build_wfl_node (get_identifier ((S))) +#ifdef USE_MAPPED_LOCATION +#define MQN(X,Y) make_qualified_name ((X), (Y), UNKNOWN_LOCATION) +#else #define MQN(X,Y) make_qualified_name ((X), (Y), 0) +#endif tree args, tmp, saved_current_function_decl, mdecl, qual_name; tree stmt, throw_stmt; @@ -8752,8 +8920,13 @@ build_dot_class_method (tree class) /* Now onto the catch block. We start by building the expression throwing a new exception: throw new NoClassDefFoundError (_.getMessage) */ +#ifdef USE_MAPPED_LOCATION + throw_stmt = make_qualified_name (build_wfl_node (wpv_id), + get_message_wfl, UNKNOWN_LOCATION); +#else throw_stmt = make_qualified_name (build_wfl_node (wpv_id), get_message_wfl, 0); +#endif throw_stmt = build_method_invocation (throw_stmt, NULL_TREE); /* Build new NoClassDefFoundError (_.getMessage) */ @@ -8818,7 +8991,7 @@ static void fix_constructors (tree mdecl) { tree iii; /* Instance Initializer Invocation */ - tree body = DECL_FUNCTION_BODY (mdecl); + tree *bodyp = &DECL_FUNCTION_BODY (mdecl); tree thisn_assign, compound = NULL_TREE; tree class_type = DECL_CONTEXT (mdecl); @@ -8826,7 +8999,7 @@ fix_constructors (tree mdecl) return; DECL_FIXED_CONSTRUCTOR_P (mdecl) = 1; - if (!body) + if (!*bodyp) { /* It is an error for the compiler to generate a default constructor if the superclass doesn't have a constructor that @@ -8870,31 +9043,30 @@ fix_constructors (tree mdecl) { int found = 0; int invokes_this = 0; - tree found_call = NULL_TREE; - tree main_block = BLOCK_EXPR_BODY (body); + tree main_block = BLOCK_EXPR_BODY (*bodyp); - while (body) - switch (TREE_CODE (body)) - { - case CALL_EXPR: - found = CALL_EXPLICIT_CONSTRUCTOR_P (body); - if (CALL_THIS_CONSTRUCTOR_P (body)) - invokes_this = 1; - body = NULL_TREE; - break; - case COMPOUND_EXPR: - case EXPR_WITH_FILE_LOCATION: - found_call = body; - body = TREE_OPERAND (body, 0); - break; - case BLOCK: - found_call = body; - body = BLOCK_EXPR_BODY (body); - break; - default: - found = 0; - body = NULL_TREE; - } + while (*bodyp) + { + tree body = *bodyp; + switch (TREE_CODE (body)) + { + case CALL_EXPR: + found = CALL_EXPLICIT_CONSTRUCTOR_P (body); + if (CALL_THIS_CONSTRUCTOR_P (body)) + invokes_this = 1; + break; + case COMPOUND_EXPR: + case EXPR_WITH_FILE_LOCATION: + bodyp = &TREE_OPERAND (body, 0); + continue; + case BLOCK: + bodyp = &BLOCK_EXPR_BODY (body); + continue; + default: + break; + } + break; + } /* Generate the assignment to this$<n>, if necessary */ if ((thisn_assign = build_thisn_assign ())) @@ -8908,9 +9080,8 @@ fix_constructors (tree mdecl) instance initializer blocks. */ else { - compound = add_stmt_to_compound (compound, NULL_TREE, - TREE_OPERAND (found_call, 0)); - TREE_OPERAND (found_call, 0) = build_java_empty_stmt (); + compound = add_stmt_to_compound (compound, NULL_TREE, *bodyp); + *bodyp = build_java_empty_stmt (); } DECL_INIT_CALLS_THIS (mdecl) = invokes_this; @@ -8997,6 +9168,7 @@ java_expand_classes (void) return; java_layout_classes (); java_parse_abort_on_error (); + location_t save_location = input_location; for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next) { @@ -9010,12 +9182,12 @@ java_expand_classes (void) for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next) { ctxp = cur_ctxp; - input_filename = ctxp->filename; + input_location = ctxp->file_start_location; lang_init_source (2); /* Error msgs have method prototypes */ java_complete_expand_classes (); /* Complete and expand classes */ java_parse_abort_on_error (); } - input_filename = main_input_filename; + input_location = save_location; /* Find anonymous classes and expand their constructor. This extra pass is necessary because the constructor itself is only generated when the @@ -9227,11 +9399,17 @@ merge_qualified_name (tree left, tree right) inherited from the location information of the `.' operator. */ static tree -make_qualified_name (tree left, tree right, int location) +make_qualified_name (tree left, tree right, +#ifdef USE_MAPPED_LOCATION + source_location location +#else + int location +#endif + ) { #ifdef USE_COMPONENT_REF tree node = build3 (COMPONENT_REF, NULL_TREE, left, right, NULL_TREE); - EXPR_WFL_LINECOL (node) = location; + SET_EXPR_LOCATION (node, location); return node; #else tree left_id = EXPR_WFL_NODE (left); @@ -9241,6 +9419,15 @@ make_qualified_name (tree left, tree right, int location) merge = merge_qualified_name (left_id, right_id); /* Left wasn't qualified and is now qualified */ +#ifdef USE_MAPPED_LOCATION + if (!QUALIFIED_P (left_id)) + { + tree wfl = build_expr_wfl (left_id, EXPR_LOCATION (left)); + EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE); + } + + wfl = build_expr_wfl (right_id, location); +#else if (!QUALIFIED_P (left_id)) { tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0); @@ -9250,8 +9437,8 @@ make_qualified_name (tree left, tree right, int location) wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0); EXPR_WFL_LINECOL (wfl) = location; +#endif chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE)); - EXPR_WFL_NODE (left) = merge; return left; #endif @@ -9523,7 +9710,11 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl, { tree qual_wfl = QUAL_WFL (q); tree ret_decl; /* for EH checking */ +#ifdef USE_MAPPED_LOCATION + source_location location; /* for EH checking */ +#else int location; /* for EH checking */ +#endif /* 15.10.1 Field Access Using a Primary */ switch (TREE_CODE (qual_wfl)) @@ -9569,8 +9760,14 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl, if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR) CALL_USING_SUPER (qual_wfl) = 1; +#ifdef USE_MAPPED_LOCATION + location = (TREE_CODE (qual_wfl) == CALL_EXPR + ? EXPR_LOCATION (TREE_OPERAND (qual_wfl, 0)) + : UNKNOWN_LOCATION); +#else location = (TREE_CODE (qual_wfl) == CALL_EXPR ? EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0); +#endif *where_found = patch_method_invocation (qual_wfl, decl, type, from_super, &is_static, &ret_decl); @@ -9602,7 +9799,11 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl, instantiation using a primary qualified by a `new' */ RESTORE_THIS_AND_CURRENT_CLASS; +#ifdef USE_MAPPED_LOCATION + if (location != UNKNOWN_LOCATION) +#else if (location) +#endif { tree arguments = NULL_TREE; if (TREE_CODE (qual_wfl) == CALL_EXPR @@ -11603,7 +11804,11 @@ java_complete_lhs (tree node) /* Only one default label is allowed per switch statement */ if (SWITCH_HAS_DEFAULT (nn)) { +#ifdef USE_MAPPED_LOCATION + SET_EXPR_LOCATION (wfl_operator, EXPR_LOCATION (node)); +#else EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node); +#endif parse_error_context (wfl_operator, "Duplicate case label: `default'"); return error_mark_node; @@ -11756,10 +11961,16 @@ java_complete_lhs (tree node) else { tree body; - int save_lineno = input_line; + location_t save_location = input_location; +#ifdef USE_MAPPED_LOCATION + input_location = EXPR_LOCATION (node); + if (input_location == UNKNOWN_LOCATION) + input_location = save_location; +#else input_line = EXPR_WFL_LINENO (node); +#endif body = java_complete_tree (EXPR_WFL_NODE (node)); - input_line = save_lineno; + input_location = save_location; EXPR_WFL_NODE (node) = body; TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body); CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body); @@ -11799,9 +12010,13 @@ java_complete_lhs (tree node) TREE_VALUE (cn) = dim; /* Setup the location of the current dimension, for later error report. */ +#ifdef USE_MAPPED_LOCATION + TREE_PURPOSE (cn) = expr_add_location (NULL_TREE, location, 0); +#else TREE_PURPOSE (cn) = build_expr_wfl (NULL_TREE, input_filename, 0, 0); EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location; +#endif } } /* They complete the array creation expression, if no errors @@ -11840,7 +12055,11 @@ java_complete_lhs (tree node) int from_super = (EXPR_WFL_NODE (TREE_OPERAND (node, 0)) == super_identifier_node); tree arguments; +#ifdef USE_MAPPED_LOCATION + source_location location = EXPR_LOCATION (node); +#else int location = EXPR_WFL_LINECOL (node); +#endif node = patch_method_invocation (node, NULL_TREE, NULL_TREE, from_super, 0, &decl); @@ -12204,10 +12423,14 @@ build_debugable_stmt (int location, tree stmt) { if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION) { +#ifdef USE_MAPPED_LOCATION + stmt = expr_add_location (stmt, location, 1); +#else stmt = build_expr_wfl (stmt, input_filename, 0, 0); EXPR_WFL_LINECOL (stmt) = location; + JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt); +#endif } - JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt); return stmt; } @@ -12335,9 +12558,15 @@ build_wfl_wrap (tree node, int location) if (TREE_CODE (node) == THIS_EXPR) node_to_insert = wfl = build_wfl_node (this_identifier_node); else +#ifdef USE_MAPPED_LOCATION + wfl = build_unknown_wfl (NULL_TREE); + + SET_EXPR_LOCATION (wfl, location); +#else wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0); EXPR_WFL_LINECOL (wfl) = location; +#endif EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE); return wfl; } @@ -14478,8 +14707,18 @@ static tree maybe_build_array_element_wfl (tree node) { if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION) - return build_expr_wfl (NULL_TREE, ctxp->filename, - ctxp->elc.line, ctxp->elc.prev_col); + { + /* FIXME - old code used "prev_lc.line" and "elc.prev_col */ + return build_expr_wfl (NULL_TREE, +#ifdef USE_MAPPED_LOCATION + input_location +#else + ctxp->filename, + ctxp->lexer->token_start.line, + ctxp->lexer->token_start.col +#endif + ); + } else return NULL_TREE; } @@ -14882,9 +15121,13 @@ finish_loop_body (int location, tree condition, tree body, int reversed) /* We wrapped the EXIT_EXPR around a WFL so we can debug it. The real EXIT_EXPR is one operand further. */ EXPR_WFL_LINECOL (cnode) = location; - /* This one is for accurate error reports */ - EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location; - TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition; + if (TREE_CODE (cnode) == EXPR_WITH_FILE_LOCATION) + { + cnode = EXPR_WFL_NODE (cnode); + /* This one is for accurate error reports */ + EXPR_WFL_LINECOL (cnode) = location; + } + TREE_OPERAND (cnode, 0) = condition; } LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body; POP_LOOP (); @@ -15212,7 +15455,13 @@ patch_switch_statement (tree node) /* Build an assertion expression for `assert CONDITION : VALUE'; VALUE might be NULL_TREE. */ static tree -build_assertion (int location, tree condition, tree value) +build_assertion ( +#ifdef USE_MAPPED_LOCATION + source_location location, +#else + int location, +#endif + tree condition, tree value) { tree node; tree klass = GET_CPC (); @@ -15636,7 +15885,14 @@ patch_throw_statement (tree node, tree wfl_op1) effectively caught from where DECL is invoked. THIS_EXPR is the expression that computes `this' for the method call. */ static void -check_thrown_exceptions (int location, tree decl, tree this_expr) +check_thrown_exceptions ( +#ifdef USE_MAPPED_LOCATION + source_location location, +#else + + int location, +#endif + tree decl, tree this_expr) { tree throws; int is_array_call = 0; @@ -15659,7 +15915,11 @@ check_thrown_exceptions (int location, tree decl, tree this_expr) if (is_array_call && DECL_NAME (decl) == get_identifier ("clone")) continue; +#ifdef USE_MAPPED_LOCATION + SET_EXPR_LOCATION (wfl_operator, location); +#else EXPR_WFL_LINECOL (wfl_operator) = location; +#endif if (DECL_FINIT_P (current_function_decl)) parse_error_context (wfl_operator, "Exception `%s' can't be thrown in initializer", |