This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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",

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]