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