Commit 9ec819d4 by Per Bothner Committed by Per Bothner

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.

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