This is the mail archive of the java@gcc.gnu.org mailing list for the Java 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]

lexer rewrite testing/timing help needed


I converted the Java front-end to support --enable-mapped-location.
This means that it uses source_location cookies managed by
libcpp/line-map.c to represent file/line/column numbers, just
like the C and C++ front=ends do.  This potentially will allow
us to get rid of a lot of the EXPR_WITH_FILE_LOCATION nodes,
which are now redundant to the extent they're just used for
line/column information.  (Unfortunately, EXPR_WITH_FILE_LOCATION
are also used by the name lookup code, so removing them
completely is more work.)

The are two known non-critical pieces of functionality missing:
(1) The SourceFile attribute in a .class file isn't being handled.
This is probably not a major amount of work, but I need to
understand the interactions better.
(2) The old code kept track of the previous line and previous
location.  The former appears to have been intended for better
error messages when seeing blank lines, and the latter has
something to column numbers for array declarations.

While doing this so I ended up essentially rewriting the Java lexer.
I.e. I moved a lot of code around and simplified the code paths
and data structures.  Hopefully the result is faster, but I don't
know.  And I'm heading off for a week's vacation/travelling.
Though I'm expecting WiFi access, that won't be until Friday
afternoon at best, plus I don't access to very fast hardware.
So this is where I'm asking for help.

Could someone try this patch, and compare:
(a) mainline without the patch with --disable-checking;
(b) mainline with the patch and --disable-checking;
(c) mainline with the patch and --enable-mapped-location and
--disable-checking.
I'd like a summary of testsuite results:  The immediate goal is
no regressions (a)->(b) and as few as possible (a)->(c)).  I also
want to know how the new lexer effects compile time, so I'm asking
for some timing tests on a fixed codebase, perhaps rebuilding
libjava.

The patch presumes a fix to gcc/profile.c.  In my testing I used
this patch:
http://gcc.gnu.org/bugzilla/attachment.cgi?id=7113&action=view
However, the following (which may be checked soon) is probably
better:
http://gcc.gnu.org/ml/gcc-patches/2004-09/msg01571.html

I would also be helpful if people could try out of there are
regressions in where the cursor ends up in error messages.
Specifically I'd like testcases to to help me implement (2) above,
if needed.  Possibly existing testcases will cover this.
--
	--Per Bothner
per@bothner.com   http://per.bothner.com/

? PATCHES
? jv-misc.patch
Index: check-init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/check-init.c,v
retrieving revision 1.57
diff -u -p -r1.57 check-init.c
--- check-init.c	29 May 2004 05:11:41 -0000	1.57
+++ check-init.c	16 Sep 2004 15:53:53 -0000
@@ -879,8 +879,12 @@ check_init (tree exp, words before)
 	if (IS_EMPTY_STMT (body))
 	  break;
 	wfl = exp;
+#ifdef USE_MAPPED_LOCATION
+	input_location = EXPR_LOCATION (exp);
+#else
 	input_filename = EXPR_WFL_FILENAME (exp);
 	input_line = EXPR_WFL_LINENO (exp);
+#endif
 	check_init (body, before);
 	input_location = saved_location;
 	wfl = saved_wfl;
Index: class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/class.c,v
retrieving revision 1.207
diff -u -p -r1.207 class.c
--- class.c	14 Sep 2004 01:50:12 -0000	1.207
+++ class.c	16 Sep 2004 15:53:54 -0000
@@ -428,10 +428,12 @@ push_class (tree class_type, tree class_
 {
   tree decl, signature;
   location_t saved_loc = input_location;
+#ifndef USE_MAPPED_LOCATION
   tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
-  CLASS_P (class_type) = 1;
   input_filename = IDENTIFIER_POINTER (source_name);
   input_line = 0;
+#endif
+  CLASS_P (class_type) = 1;
   decl = build_decl (TYPE_DECL, class_name, class_type);
 
   /* dbxout needs a DECL_SIZE if in gstabs mode */
@@ -1037,6 +1039,7 @@ build_class_ref (tree type)
 	      TREE_STATIC (decl) = 1;
 	      TREE_PUBLIC (decl) = 1;
 	      DECL_EXTERNAL (decl) = 1;
+	      DECL_ARTIFICIAL (decl) = 1;
 	      make_decl_rtl (decl);
 	      pushdecl_top_level (decl);
 	    }
@@ -1996,9 +1999,14 @@ maybe_layout_super_class (tree super_cla
 	  if (this_class)
 	    {
 	      tree this_decl = TYPE_NAME (this_class);
+#ifdef USE_MAPPED_LOCATION
+	      this_wrap = build_expr_wfl (this_class,
+					  DECL_SOURCE_LOCATION (this_decl));
+#else
 	      this_wrap = build_expr_wfl (this_class,
 					  DECL_SOURCE_FILE (this_decl),
 					  DECL_SOURCE_LINE (this_decl), 0);
+#endif
 	    }
 	  super_class = do_resolve_class (NULL_TREE, /* FIXME? */
 					  super_class, NULL_TREE, this_wrap);
Index: decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/decl.c,v
retrieving revision 1.197
diff -u -p -r1.197 decl.c
--- decl.c	25 Aug 2004 09:52:50 -0000	1.197
+++ decl.c	16 Sep 2004 15:53:55 -0000
@@ -1952,8 +1952,12 @@ finish_method (tree fndecl)
     cfun = DECL_STRUCT_FUNCTION (fndecl);
   else
     allocate_struct_function (fndecl);
+#ifdef USE_MAPPED_LOCATION
+  cfun->function_end_locus = DECL_FUNCTION_LAST_LINE (fndecl);
+#else
   cfun->function_end_locus.file = DECL_SOURCE_FILE (fndecl);
   cfun->function_end_locus.line = DECL_FUNCTION_LAST_LINE (fndecl);
+#endif
 
   /* Defer inlining and expansion to the cgraph optimizers.  */
   cgraph_finalize_function (fndecl, false);
@@ -2021,7 +2025,7 @@ tree
 java_add_stmt (tree stmt)
 {
   if (input_filename)
-    annotate_with_locus (stmt, input_location);
+    SET_EXPR_LOCATION (stmt, input_location);
   
   return current_binding_level->stmts 
     = add_stmt_to_compound (current_binding_level->stmts, 
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.204
diff -u -p -r1.204 expr.c
--- expr.c	25 Aug 2004 09:52:50 -0000	1.204
+++ expr.c	16 Sep 2004 15:53:56 -0000
@@ -2695,7 +2695,12 @@ expand_byte_code (JCF *jcf, tree method)
 	      linenumber_pointer += 4;
 	      if (pc == PC)
 		{
-		  input_location.line = GET_u2 (linenumber_pointer - 2);
+		  int line = GET_u2 (linenumber_pointer - 2);
+#ifdef USE_MAPPED_LOCATION
+		  input_location = linemap_line_start (&line_table, line, 1);
+#else
+		  input_location.line = line;
+#endif
 		  if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
 		    break;
 		}
@@ -3224,21 +3229,48 @@ force_evaluation_order (tree node)
    recursively more than one file (Java is one of them).  */
 
 tree
-build_expr_wfl (tree node, const char *file, int line, int col)
+build_expr_wfl (tree node,
+#ifdef USE_MAPPED_LOCATION
+		source_location location
+#else
+		const char *file, int line, int col
+#endif
+)
 {
+  tree wfl;
+#ifdef USE_MAPPED_LOCATION
+#if 0
+  /* FIXME - is this safe? */
+  if (node)
+    {
+      source_location node_loc = EXPR_LOCATION (node);
+      if (node_loc == location)
+	return node;
+      if (node_loc == UNKNOWN_LOCATION
+	  && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (node))))
+	{
+	  SET_EXPR_LOCATION (node, location);
+	  return node;
+	}
+    }
+#endif
+  wfl = make_node (EXPR_WITH_FILE_LOCATION);
+  SET_EXPR_LOCATION (wfl, location);
+#else
+  wfl = make_node (EXPR_WITH_FILE_LOCATION);
+
   static const char *last_file = 0;
   static tree last_filenode = NULL_TREE;
-  tree wfl = make_node (EXPR_WITH_FILE_LOCATION);
 
-  EXPR_WFL_NODE (wfl) = node;
   EXPR_WFL_SET_LINECOL (wfl, line, col);
   if (file != last_file)
     {
       last_file = file;
       last_filenode = file ? get_identifier (file) : NULL_TREE;
     }
-
   EXPR_WFL_FILENAME_NODE (wfl) = last_filenode;
+#endif
+  EXPR_WFL_NODE (wfl) = node;
   if (node)
     {
       if (IS_NON_TYPE_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (node))))
Index: java-gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-gimplify.c,v
retrieving revision 1.13
diff -u -p -r1.13 java-gimplify.c
--- java-gimplify.c	25 Aug 2004 09:52:51 -0000	1.13
+++ java-gimplify.c	16 Sep 2004 15:53:56 -0000
@@ -69,10 +69,14 @@ java_gimplify_expr (tree *expr_p, tree *
       break;
 
     case EXPR_WITH_FILE_LOCATION:
+#ifdef USE_MAPPED_LOCATION
+      input_location = EXPR_LOCATION (*expr_p);
+#else
       input_location.file = EXPR_WFL_FILENAME (*expr_p);
       input_location.line = EXPR_WFL_LINENO (*expr_p);
+#endif
       *expr_p = EXPR_WFL_NODE (*expr_p);
-      annotate_with_locus (*expr_p, input_location);
+      SET_EXPR_LOCATION (*expr_p, input_location);
       break;
 
     case CASE_EXPR:
Index: java-tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.def,v
retrieving revision 1.18
diff -u -p -r1.18 java-tree.def
--- java-tree.def	13 May 2004 06:40:35 -0000	1.18
+++ java-tree.def	16 Sep 2004 15:53:56 -0000
@@ -96,7 +96,11 @@ DEFTREECODE (JAVA_EXC_OBJ_EXPR, "java_ex
    (EXPR_WFL_LINENO); and column number (EXPR_WFL_COLNO).  It is
    expanded as the contained node (EXPR_WFL_NODE);  a line note should
    be emitted first if EXPR_WFL_EMIT_LINE_NOTE.  */
+#ifdef USE_MAPPED_LOCATION
+DEFTREECODE (EXPR_WITH_FILE_LOCATION, "expr_with_file_location", 'e', 2)
+#else
 DEFTREECODE (EXPR_WITH_FILE_LOCATION, "expr_with_file_location", 'e', 3)
+#endif
 
 /*
 Local variables:
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.216
diff -u -p -r1.216 java-tree.h
--- java-tree.h	10 Aug 2004 04:29:16 -0000	1.216
+++ java-tree.h	16 Sep 2004 15:53:57 -0000
@@ -52,17 +52,15 @@ struct JCF;
       COMPOUND_ASSIGN_P (in EXPR (binop_*))
       LOCAL_CLASS_P (in RECORD_TYPE)
       BLOCK_IS_IMPLICIT (in BLOCK)
-      JAVA_FILE_P (in TREE_LIST in current_file_list)
    2: RETURN_MAP_ADJUSTED (in TREE_VEC).
       QUALIFIED_P (in IDENTIFIER_NODE)
       PRIMARY_P (in EXPR_WITH_FILE_LOCATION)
       MODIFY_EXPR_FROM_INITIALIZATION_P (in MODIFY_EXPR)
       CLASS_METHOD_CHECKED_P (in RECORD_TYPE) 
-      CLASS_FILE_P (in TREE_LIST in current_file_list)
+      CLASS_FILE_P (in a TRANSLATION_UNIT_DECL in current_file_list)
    3: IS_AN_IMPORT_ON_DEMAND_P (in IDENTIFIER_NODE)
       RESOLVE_PACKAGE_NAME_P (in EXPR_WITH_FILE_LOCATION)
       SWITCH_HAS_DEFAULT (in SWITCH_EXPR)
-      ZIP_FILE_P (in TREE_LIST in current_file_list)
       HAS_FINALIZER (in RECORD_TYPE)
    4: IS_A_COMMAND_LINE_FILENAME_P (in IDENTIFIER_NODE)
       RESOLVE_TYPE_NAME_P (in EXPR_WITH_FILE_LOCATION)
@@ -756,7 +754,7 @@ union lang_tree_node 
 /* Number of local variable slots needed for the arguments of this function. */
 #define DECL_ARG_SLOT_COUNT(DECL) \
   (DECL_LANG_SPECIFIC(DECL)->u.f.arg_slot_count)
-/* Line number of end of function. */
+/* Source location of end of function. */
 #define DECL_FUNCTION_LAST_LINE(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.last_line)
 /* Information on declaration location */
 #define DECL_FUNCTION_WFL(DECL)  (DECL_LANG_SPECIFIC(DECL)->u.f.wfl)
@@ -958,7 +956,9 @@ struct lang_decl_func GTY(())
   int max_locals;
   int max_stack;
   int arg_slot_count;
-  int last_line; 		/* End line number for a function decl */
+  /* A temportary lie for the sake of ggc.  Actually, last_line is
+  * only a source_location if USE_MAPPED_LOCATION.  FIXME. */
+  source_location last_line;	/* End line number for a function decl */
   tree wfl;			/* Information on the original location */
   tree throws_list;		/* Exception specified by `throws' */
   tree function_decl_body;	/* Hold all function's statements */
@@ -1378,9 +1378,7 @@ extern tree builtin_function (const char
 #define METHOD_INVISIBLE(DECL) \
   (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->u.f.invisible)
 
-#define JAVA_FILE_P(NODE) TREE_LANG_FLAG_2 (NODE)
 #define CLASS_FILE_P(NODE) TREE_LANG_FLAG_3 (NODE)
-#define ZIP_FILE_P(NODE) TREE_LANG_FLAG_4 (NODE)
 
 /* Other predicates on method decls  */
 
@@ -1824,19 +1822,28 @@ enum
 #undef EXPR_WFL_NODE
 #define EXPR_WFL_NODE(NODE) \
   TREE_OPERAND (EXPR_WITH_FILE_LOCATION_CHECK (NODE), 0)
+#ifdef USE_MAPPED_LOCATION
+#define EXPR_WFL_LINECOL(NODE) ((NODE)->exp.locus)
+#define EXPR_WFL_FILENAME(NODE) EXPR_FILENAME (NODE)
+#define EXPR_WFL_LINENO(NODE) EXPR_LINENO (NODE)
+extern tree build_expr_wfl              PARAMS ((tree, source_location));
+#define build_unknown_wfl(NODE) build_expr_wfl(NODE, UNKNOWN_LOCATION)
+#else
+#define EXPR_WFL_LINECOL(NODE) (EXPR_CHECK (NODE)->exp.complexity)
+#define EXPR_WFL_LINENO(NODE) (EXPR_WFL_LINECOL (NODE) >> 12)
+#define EXPR_WFL_COLNO(NODE) (EXPR_WFL_LINECOL (NODE) & 0xfff)
 #undef EXPR_WFL_FILENAME_NODE
 #define EXPR_WFL_FILENAME_NODE(NODE) \
-  TREE_OPERAND (EXPR_WITH_FILE_LOCATION_CHECK (NODE), 1)
+  TREE_OPERAND (EXPR_WITH_FILE_LOCATION_CHECK (NODE), 2)
 #define EXPR_WFL_FILENAME(NODE) \
   IDENTIFIER_POINTER (EXPR_WFL_FILENAME_NODE (NODE))
 /* ??? Java uses this in all expressions.  */
-#define EXPR_WFL_LINECOL(NODE) (EXPR_CHECK (NODE)->exp.complexity)
-#define EXPR_WFL_LINENO(NODE) (EXPR_WFL_LINECOL (NODE) >> 12)
-#define EXPR_WFL_COLNO(NODE) (EXPR_WFL_LINECOL (NODE) & 0xfff)
 #define EXPR_WFL_SET_LINECOL(NODE, LINE, COL) \
   (EXPR_WFL_LINECOL(NODE) = ((LINE) << 12) | ((COL) & 0xfff))
 
 extern tree build_expr_wfl              PARAMS ((tree, const char *, int, int));
+#define build_unknown_wfl(NODE) build_expr_wfl(NODE, NULL, 0, 0)
+#endif
 
 extern void java_genericize		PARAMS ((tree));
 extern int java_gimplify_expr		PARAMS ((tree *, tree *, tree *));
Index: jcf-parse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-parse.c,v
retrieving revision 1.169
diff -u -p -r1.169 jcf-parse.c
--- jcf-parse.c	25 Aug 2004 09:52:51 -0000	1.169
+++ jcf-parse.c	16 Sep 2004 15:53:57 -0000
@@ -80,9 +80,12 @@ static GTY(()) tree parse_roots[3];
 /* The METHOD_DECL for the current method.  */
 #define current_method parse_roots[1]
 
-/* A list of file names.  */
+/* A list of TRANSLATION_UNIT_DECLs for the files to be compiled.  */
 #define current_file_list parse_roots[2]
 
+/* Line 0 in current file, if compiling from bytecode. */
+location_t file_start_location;
+
 /* The Java archive that provides main_class;  the main input file. */
 static GTY(()) struct JCF * main_jcf;
 
@@ -95,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);
@@ -128,21 +131,31 @@ set_source_filename (JCF *jcf, int index
 {
   tree sfname_id = get_name_constant (jcf, index);
   const char *sfname = IDENTIFIER_POINTER (sfname_id);
-  if (input_filename != NULL)
+  const char *old_filename = input_filename;
+  if (old_filename != NULL)
     {
-      int old_len = strlen (input_filename);
+      int old_len = strlen (old_filename);
       int new_len = IDENTIFIER_LENGTH (sfname_id);
       /* Use the current input_filename (derived from the class name)
 	 if it has a directory prefix, but otherwise matches sfname. */
       if (old_len > new_len
-	  && strcmp (sfname, input_filename + old_len - new_len) == 0
-	  && (input_filename[old_len - new_len - 1] == '/'
-	      || input_filename[old_len - new_len - 1] == '\\'))
+	  && strcmp (sfname, old_filename + old_len - new_len) == 0
+	  && (old_filename[old_len - new_len - 1] == '/'
+	      || old_filename[old_len - new_len - 1] == '\\'))
 	return;
     }
+#if 0
+  /* should smash filename in line_table FIXME */
+#ifdef USE_MAPPED_LOCATION
+  linemap_add (&line_table, LC_RENAME, false, sfname, 0);
+  input_location = linemap_line_start (&line_table, 0, 1);
+#else
   input_filename = sfname;
-  DECL_SOURCE_FILE (TYPE_NAME (current_class)) = sfname;
-  if (current_class == main_class) main_input_filename = input_filename;
+#endif
+  file_start_location = input_location;
+  DECL_SOURCE_LOCATION (TYPE_NAME (current_class)) = input_location;
+#endif
+  if (current_class == main_class) main_input_filename = sfname;
 }
 
 #define HANDLE_SOURCEFILE(INDEX) set_source_filename (jcf, INDEX)
@@ -414,10 +427,22 @@ give_name_to_class (JCF *jcf, int i)
       tree class_name = unmangle_classname ((const char *) JPOOL_UTF_DATA (jcf, j),
 					    JPOOL_UTF_LENGTH (jcf, j));
       this_class = lookup_class (class_name);
-      input_filename = DECL_SOURCE_FILE (TYPE_NAME (this_class));
-      input_line = 0;
+#ifdef USE_MAPPED_LOCATION
+      {
+      tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
+      const char *sfname = IDENTIFIER_POINTER (source_name);
+      linemap_add (&line_table, LC_ENTER, false, sfname, 0);
+      input_location = linemap_line_start (&line_table, 0, 1);
+      file_start_location = input_location;
+      DECL_SOURCE_LOCATION (TYPE_NAME (this_class)) = input_location;
+      if (main_input_filename == NULL && jcf == main_jcf)
+	main_input_filename = sfname;
+      }
+#else
+      input_location = DECL_SOURCE_LOCATION (TYPE_NAME (this_class));
       if (main_input_filename == NULL && jcf == main_jcf)
 	main_input_filename = input_filename;
+#endif
 
       jcf->cpool.data[i].t = this_class;
       JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
@@ -502,27 +527,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);
@@ -535,7 +560,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);
@@ -601,6 +626,11 @@ load_class (tree class_or_name, int verb
 	  *separator = '\0';
 	  name = get_identifier (IDENTIFIER_POINTER (name));
 	  *separator = c;
+
+	  /* Otherwise we might get infinite recursion, if say we have
+	     String.class but not String$CaseInsensitiveComparator.class. */
+	  if (current_jcf && current_jcf->java_source == 0)
+	    break;
 	}
       /* Otherwise, we failed, we bail. */
       else
@@ -662,6 +692,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)
@@ -706,8 +739,7 @@ parse_class_file (void)
 
   java_layout_seen_class_methods ();
 
-  input_filename = DECL_SOURCE_FILE (TYPE_NAME (current_class));
-  input_line = 0;
+  input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class));
   (*debug_hooks->start_source_file) (input_line, input_filename);
 
   /* Currently we always have to emit calls to _Jv_InitClass when
@@ -757,10 +789,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);
@@ -771,9 +804,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
 	{
@@ -798,22 +838,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
@@ -827,6 +865,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 ();
@@ -894,6 +944,7 @@ void
 java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
 {
   int filename_count = 0;
+  location_t save_location = input_location;
   char *list, *next;
   tree node;
   FILE *finput = NULL;
@@ -902,7 +953,7 @@ java_parse_file (int set_yydebug ATTRIBU
   if (flag_filelist_file)
     {
       int avail = 2000;
-      finput = fopen (input_filename, "r");
+      finput = fopen (main_input_filename, "r");
       if (finput == NULL)
 	fatal_error ("can't open %s: %m", input_filename);
       list = xmalloc(avail);
@@ -934,7 +985,7 @@ java_parse_file (int set_yydebug ATTRIBU
       finput = NULL;
     }
   else
-    list = input_filename ? xstrdup (input_filename) : 0;
+    list = (char *) main_input_filename;
 
   while (list)
     {
@@ -976,51 +1027,32 @@ java_parse_file (int set_yydebug ATTRIBU
 
       if (list[0]) 
 	{
-	  char *value;
-	  tree id;
-	  int twice = 0;
-
-	  int len = strlen (list);
-
-	  obstack_grow0 (&temporary_obstack, list, len);
-	  value = obstack_finish (&temporary_obstack);
+	  node = get_identifier (list);
 
 	  filename_count++;
 
-	  /* Exclude file that we see twice on the command line. For
-	     all files except {Class,Error,Object,RuntimeException,String,
-	     Throwable}.java we can rely on maybe_get_identifier. For
-	     these files, we need to do a linear search of
-	     current_file_list. This search happens only for these
-	     files, presumably only when we're recompiling libgcj. */
+	  /* Exclude file that we see twice on the command line. */
 	     
-	  if ((id = maybe_get_identifier (value)))
-	    {
-	      if (predefined_filename_p (id))
-		{
-		  tree c;
-		  for (c = current_file_list; c; c = TREE_CHAIN (c))
-		    if (TREE_VALUE (c) == id)
-		      twice = 1;
-		}
-	      else
-		twice = 1;
-	    }
-
-	  if (twice)
+	  if (IS_A_COMMAND_LINE_FILENAME_P (node))
 	    {
 	      location_t warn_loc;
-	      warn_loc.file = value;
+#ifdef USE_MAPPED_LOCATION
+	      linemap_add (&line_table, LC_RENAME, 0,
+			   IDENTIFIER_POINTER (node), 0);
+	      warn_loc = linemap_line_start (&line_table, 0, 1);
+#else
+	      warn_loc.file = IDENTIFIER_POINTER (node);
 	      warn_loc.line = 0;
+#endif
 	      warning ("%Hsource file seen twice on command line and "
 		       "will be compiled only once", &warn_loc);
 	    }
 	  else
 	    {
-	      node = get_identifier (value);
+	      tree file_decl = build_decl (TRANSLATION_UNIT_DECL, node, NULL);
+	      TREE_CHAIN (file_decl) = current_file_list;
+	      current_file_list = file_decl;
 	      IS_A_COMMAND_LINE_FILENAME_P (node) = 1;
-	      current_file_list = tree_cons (NULL_TREE, node, 
-					     current_file_list);
 	    }
 	}
       list = next;
@@ -1036,7 +1068,7 @@ java_parse_file (int set_yydebug ATTRIBU
       /* Only one resource file may be compiled at a time.  */
       assert (TREE_CHAIN (current_file_list) == NULL);
 
-      resource_filename = IDENTIFIER_POINTER (TREE_VALUE (current_file_list));
+      resource_filename = IDENTIFIER_POINTER (DECL_NAME (current_file_list));
       compile_resource_file (resource_name, resource_filename);
 
       goto finish;
@@ -1048,27 +1080,27 @@ java_parse_file (int set_yydebug ATTRIBU
     {
       unsigned char magic_string[4];
       uint32 magic = 0;
-      tree name = TREE_VALUE (node);
+      tree name = DECL_NAME (node);
       tree real_file;
+      const char *filename = IDENTIFIER_POINTER (name);
 
       /* Skip already parsed files */
-      real_file = get_identifier (lrealpath (IDENTIFIER_POINTER (name)));
+      real_file = get_identifier (lrealpath (filename));
       if (HAS_BEEN_ALREADY_PARSED_P (real_file))
 	continue;
-      
+     
       /* Close previous descriptor, if any */
       if (finput && fclose (finput))
 	fatal_error ("can't close input file %s: %m", main_input_filename);
       
-      finput = fopen (IDENTIFIER_POINTER (name), "rb");
+      finput = fopen (filename, "rb");
       if (finput == NULL)
-	fatal_error ("can't open %s: %m", IDENTIFIER_POINTER (name));
+	fatal_error ("can't open %s: %m", filename);
 
 #ifdef IO_BUFFER_SIZE
       setvbuf (finput, xmalloc (IO_BUFFER_SIZE),
 	       _IOFBF, IO_BUFFER_SIZE);
 #endif
-      input_filename = IDENTIFIER_POINTER (name);
 
       /* Figure what kind of file we're dealing with */
       if (fread (magic_string, 1, 4, finput) == 4)
@@ -1084,22 +1116,29 @@ java_parse_file (int set_yydebug ATTRIBU
 	  current_jcf->read_state = finput;
 	  current_jcf->filbuf = jcf_filbuf_from_stdio;
 	  jcf_parse (current_jcf);
+	  DECL_SOURCE_LOCATION (node) = file_start_location;
 	  TYPE_JCF (current_class) = current_jcf;
 	  CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
-	  TREE_PURPOSE (node) = current_class;
+	  TREE_TYPE (node) = current_class;
 	}
       else if (magic == (JCF_u4)ZIPMAGIC)
 	{
-	  ZIP_FILE_P (node) = 1;
 	  main_jcf = ggc_alloc (sizeof (JCF));
 	  JCF_ZERO (main_jcf);
 	  main_jcf->read_state = finput;
 	  main_jcf->filbuf = jcf_filbuf_from_stdio;
-	  if (open_in_zip (main_jcf, input_filename, NULL, 0) <  0)
-	    fatal_error ("bad zip/jar file %s", IDENTIFIER_POINTER (name));
+#ifdef USE_MAPPED_LOCATION
+	  linemap_add (&line_table, LC_ENTER, false, filename, 0);
+	  input_location = linemap_line_start (&line_table, 0, 1);
+#endif
+	  if (open_in_zip (main_jcf, filename, NULL, 0) <  0)
+	    fatal_error ("bad zip/jar file %s", filename);
 	  localToFile = SeenZipFiles;
 	  /* Register all the classes defined there.  */
 	  process_zip_dir (main_jcf->read_state);
+#ifdef USE_MAPPED_LOCATION
+	  linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
+#endif
 	  parse_zip_file_entries ();
 	  /*
 	  for (each entry)
@@ -1108,34 +1147,36 @@ java_parse_file (int set_yydebug ATTRIBU
 	}
       else
 	{
-	  JAVA_FILE_P (node) = 1;
 	  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 ();
     }
 
   for (node = current_file_list; node; node = TREE_CHAIN (node))
     {
-      input_filename = IDENTIFIER_POINTER (TREE_VALUE (node));
+      input_location = DECL_SOURCE_LOCATION (node);
       if (CLASS_FILE_P (node))
 	{
-	  output_class = current_class = TREE_PURPOSE (node);
+	  output_class = current_class = TREE_TYPE (node);
 	  current_jcf = TYPE_JCF (current_class);
 	  layout_class (current_class);
 	  load_inner_classes (current_class);
@@ -1143,7 +1184,7 @@ java_parse_file (int set_yydebug ATTRIBU
 	  JCF_FINISH (current_jcf);
 	}
     }
-  input_filename = main_input_filename;
+  input_location = save_location;
 
   java_expand_classes ();
   if (java_report_errors () || flag_syntax_only)
@@ -1243,7 +1284,6 @@ parse_zip_file_entries (void)
 
 	    if (TYPE_SIZE (current_class) != error_mark_node)
 	      {
-		input_filename = current_jcf->filename;
 		parse_class_file ();
 		FREE (current_jcf->buffer); /* No longer necessary */
 		/* Note: there is a way to free this buffer right after a
Index: jcf-write.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-write.c,v
retrieving revision 1.155
diff -u -p -r1.155 jcf-write.c
--- jcf-write.c	16 Aug 2004 13:03:51 -0000	1.155
+++ jcf-write.c	16 Sep 2004 15:53:58 -0000
@@ -1479,8 +1479,12 @@ generate_bytecode_insns (tree exp, int t
 	tree body = EXPR_WFL_NODE (exp);
 	if (IS_EMPTY_STMT (body))
 	  break;
+#ifdef USE_MAPPED_LOCATION
+	input_location = EXPR_LOCATION (exp);
+#else
 	input_filename = EXPR_WFL_FILENAME (exp);
 	input_line = EXPR_WFL_LINENO (exp);
+#endif
 	if (EXPR_WFL_EMIT_LINE_NOTE (exp) && input_line > 0
 	    && debug_info_level > DINFO_LEVEL_NONE)
 	  put_linenumber (input_line, state);
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	16 Sep 2004 15:53:58 -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: lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lang.c,v
retrieving revision 1.158
diff -u -p -r1.158 lang.c
--- lang.c	17 Aug 2004 12:51:01 -0000	1.158
+++ lang.c	16 Sep 2004 15:53:58 -0000
@@ -670,6 +670,10 @@ java_post_options (const char **pfilenam
 	    }
 	}
     }
+#ifdef USE_MAPPED_LOCATION
+  linemap_add (&line_table, LC_ENTER, false, filename, 0);
+  linemap_add (&line_table, LC_RENAME, false, "<built-in>", 0);
+#endif
 
   /* Initialize the compiler back end.  */
   return false;
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	16 Sep 2004 15:53:59 -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,7 +52,6 @@ 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);
@@ -60,13 +59,10 @@ 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_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,53 @@ 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->filename = input_filename;*/
+  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 +165,19 @@ 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 = -2;
+  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 != '\\')
@@ -590,71 +525,95 @@ java_read_unicode (java_lexer *lex, int 
 }
 
 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;
+}
+
+static int
+java_peek_unicode (void)
+{
+  int unicode_escape_p;
+  java_lexer *lex = ctxp->lexer;
+  int next = lex->next_unicode;
+  if (next >= -1)
+    return next;
+
+  next = java_read_unicode (lex, &unicode_escape_p);
 
-  if (c == '\r')
+  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;
 
-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;
-
-      if (ctxp->lexer->hit_eof)
-	return UEOF;
+      lex->next_columns = 0;
+      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;
-	    }
+  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
+    {
+      if (lex->white_space_only && !JAVA_WHITE_SPACE_P (next))
+	lex->white_space_only = 0;
+      lex->next_columns = 1;
+    }
+  if (unicode_escape_p)
+    lex->next_columns = 6;
+  return next;
+}
 
-	  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++; 
+      lex->white_space_only = 1;
+#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->next_unicode = -2;
 }
 
+#if 0 /* not used */
+static void java_unget_unicode (int next)
+{
+  if (lex->next_unicode >= -2)
+    fatal_error ("internal error - bad unget");
+  lex->next_unicode = next;
+  lex->position.col -= lex->unicode_columns;
+}
+#endif
+
 /* Parse the end of a C style comment.
  * C is the first character following the '/' and '*'.  */
 static void
@@ -668,15 +627,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 +792,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 +815,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 +889,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 +910,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 == '.'))
@@ -1050,59 +950,50 @@ do_java_lex (YYSTYPE *java_lval)
       int  found_hex_digits = 0, found_non_octal_digits = 0;
       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;
+	    {
+	      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 +1001,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 +1012,12 @@ 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)
+	    {
+	      if (! found_non_octal_digits)
+		java_lex_error ("Octal literal contains digit out of range", 0);
+	      found_non_octal_digits = 1;
+	    }
 
 	  literal_token [literal_index++] = c;
 	  /* This section of code if borrowed from gcc/c-lex.c.  */
@@ -1141,13 +1035,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 +1069,13 @@ 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))
+			{
+			  JAVA_LEX_SEP('.');
+			  BUILD_OPERATOR (DOT_TK);
+			}
 		    }
 		  else
 		    java_lex_error ("Invalid character in FP literal", 0);
@@ -1186,7 +1093,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 +1109,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 +1123,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 +1137,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,12 +1151,11 @@ 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 (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.  */
@@ -1294,9 +1202,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 +1223,114 @@ 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)))
+	    {
+	      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;
+		}
+	    }
+	}
+
+      JAVA_LEX_ID (string);
+      java_lval->node = BUILD_ID_WFL (GET_IDENTIFIER (string));
+      return ID_TK;
+    }
+
+  java_next_unicode ();
+
   /* Character literals.  */
   if (c == '\'')
     {
@@ -1347,12 +1363,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 +1386,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,9 +1400,59 @@ 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);
@@ -1393,16 +1461,34 @@ do_java_lex (YYSTYPE *java_lval)
       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);
@@ -1418,15 +1504,13 @@ do_java_lex (YYSTYPE *java_lval)
     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,159 +1519,155 @@ 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);
 	}
 	  
@@ -1601,117 +1681,18 @@ do_java_lex (YYSTYPE *java_lval)
       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);
+	     java_sprint_unicode (c));
+    java_lex_error (lex_error_buffer, -1);
   }
   return 0;
 }
@@ -1777,7 +1758,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 +1775,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 +1882,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	16 Sep 2004 15:53:59 -0000
@@ -54,8 +54,6 @@ typedef unsigned short unicode_t;
 #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;					 \
@@ -68,39 +66,16 @@ typedef unsigned short unicode_t;
 #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 prev_col;*/
+  int col;		/* column number number (1-based) */
 } java_lc;
 
 struct java_lexer
@@ -111,15 +86,31 @@ struct java_lexer
   /* Number of consecutive backslashes we've read.  */
   int bs_count;
 
+  /* Next available Unicode character.
+   * This is post-Unicode-escape-processing.
+   * -1 if EOF; -2 if there is no available char. */
+  int next_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 (mostrecent resilt of java_{get,peek}_unicode). */
+  int next_columns;
+
   /* If nonzero, a value that was pushed back.  */
   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
+
+  int white_space_only;		/* If current line contains only white space */
+
 #ifdef HAVE_ICONV
   /* Nonzero if we've read any bytes.  We only recognize the
      byte-order-marker (BOM) as the first word.  */
@@ -168,7 +159,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 +186,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 +223,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.100
diff -u -p -r1.100 parse.h
--- parse.h	19 Aug 2004 10:36:07 -0000	1.100
+++ parse.h	16 Sep 2004 15:53:59 -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))						\
@@ -610,22 +628,16 @@ 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), 2)
+#define EXPR_WFL_QUALIFICATION(WFL) TREE_OPERAND ((WFL), 1)
 #define QUAL_WFL(NODE) TREE_PURPOSE (NODE)
 #define QUAL_RESOLUTION(NODE) TREE_VALUE (NODE)
 #define QUAL_DECL_TYPE(NODE) GET_SKIP_TYPE (NODE)
@@ -671,10 +683,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 +743,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,7 +782,7 @@ struct parser_ctxt GTY(()) {
   tree class_type;		    /* Current class */
   tree function_decl;	            /* Current function decl, save/restore */
 
-  struct JCF * current_jcf;	    /* CU jcf */
+  /*struct JCF * current_jcf;	     CU jcf */
 
   int prevent_ese;	            /* Prevent expression statement error */
 
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.504
diff -u -p -r1.504 parse.y
--- parse.y	25 Aug 2004 09:52:52 -0000	1.504
+++ parse.y	16 Sep 2004 15:54:04 -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,7 +1516,11 @@ expression_statement:
 		{
 		  /* We have a statement. Generate a WFL around it so
 		     we can debug it */
+#ifdef USE_MAPPED_LOCATION
+		  $$ = build_expr_wfl ($1, input_location);
+#else
 		  $$ = build_expr_wfl ($1, input_filename, input_line, 0);
+#endif
 		  /* We know we have a statement, so set the debug
                      info to be eventually generate here. */
 		  $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
@@ -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
                     {
@@ -2220,7 +2254,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
@@ -2603,7 +2637,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
 		{
@@ -2712,16 +2746,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;
     }
 
@@ -2734,19 +2767,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
@@ -2769,9 +2802,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;
 }
@@ -2782,11 +2814,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)
@@ -2954,8 +2989,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>"));
@@ -3010,22 +3043,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
@@ -3035,7 +3082,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;
@@ -3044,17 +3091,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);
@@ -3068,46 +3122,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, ...)
@@ -3115,9 +3203,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);
 }
 
@@ -3167,7 +3259,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");
 }
 
@@ -3185,7 +3281,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
@@ -3376,10 +3476,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);
@@ -3439,13 +3543,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)) ||
@@ -3643,7 +3748,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;
@@ -3673,7 +3778,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);
 }
@@ -3762,16 +3867,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 ();
@@ -4291,7 +4408,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;
 
@@ -4360,10 +4477,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);
 
@@ -4425,7 +4546,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
@@ -4546,7 +4667,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;
 
@@ -4677,12 +4798,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);
@@ -4715,7 +4841,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.
@@ -4756,7 +4882,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;
 }
@@ -6739,32 +6871,38 @@ 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);
 
   line = java_get_line_col (EXPR_WFL_FILENAME (cl_v),
 			    EXPR_WFL_LINENO (cl_v), EXPR_WFL_COLNO (cl_v));
-
   found = strstr ((const char *)line,
 		  (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;
 }
@@ -7019,7 +7157,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;
@@ -7038,7 +7176,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;
@@ -7059,7 +7201,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
@@ -7356,8 +7498,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)
@@ -7455,14 +7602,14 @@ 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;
   mdecl = add_method (class, flags, name, build_java_signature (mdecl));
-  java_parser_context_restore_global ();
+  input_location = save_location;
   DECL_ARTIFICIAL (mdecl) = 1;
   return mdecl;
 }
@@ -7472,8 +7619,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 ();
 }
@@ -7517,7 +7669,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
@@ -7576,7 +7732,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);
@@ -8007,7 +8166,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);
 }
 
@@ -8679,7 +8838,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;
@@ -8703,7 +8866,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;
 
@@ -8741,8 +8908,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) */
@@ -8986,6 +9158,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)
     {
@@ -8999,12 +9172,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
@@ -9216,11 +9389,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);
@@ -9230,6 +9409,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);
@@ -9239,8 +9427,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
@@ -9512,7 +9700,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 = UNKNOWN_LOCATION;  /* for EH checking */
+#else
       int location;		/* for EH checking */
+#endif
 
       /* 15.10.1 Field Access Using a Primary */
       switch (TREE_CODE (qual_wfl))
@@ -9558,8 +9750,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);
@@ -9591,7 +9789,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
@@ -11589,7 +11791,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;
@@ -11733,10 +11939,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);
@@ -11776,9 +11988,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) = build_expr_wfl (NULL_TREE, location);
+#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
@@ -11817,7 +12033,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);
@@ -12181,8 +12401,12 @@ build_debugable_stmt (int location, tree
 {
   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
     {
+#ifdef USE_MAPPED_LOCATION
+      stmt = build_expr_wfl (stmt, location);
+#else
       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
       EXPR_WFL_LINECOL (stmt) = location;
+#endif
     }
   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
   return stmt;
@@ -12312,9 +12536,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;
 }
@@ -14458,8 +14688,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;
 }
@@ -15193,7 +15433,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 ();
@@ -15617,7 +15863,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;
@@ -15640,7 +15893,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]