OSDN Git Service

Simplify lexer. Implement --enable-mapped-location support.
authorbothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Sep 2004 23:35:07 +0000 (23:35 +0000)
committerbothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Sep 2004 23:35:07 +0000 (23:35 +0000)
* jcf-parse.c (parse_class_file):  Use linemap_line_start.
(parse_source_file_1): Pass filename as extra parameter, so we can call
linemap_add and set input_location here, rather than in both callers.
(read_class): Pass copied filename to parse_source_file_1.
Don't initialize wfl_operator - only needed for source compilation.
(read_class, jcf_parse):  Call linemap_add with LC_LEAVE.
* lex.h:  Remove a bunch of debugging macros.
* lex.h (struct_java_line, struct java_error):  Remove types.
(JAVA_COLUMN_DELTA):  Remove - use java_lexer.next_colums instead.
(struct java_lc_s):  Remove prev_col field.
(struct java_lexer):  New fields next_unicode, next_columns, and
avail_unicode.  New position field, and maybe token_start field.
Don't need hit_eof field - use next_unicode == -1 instead.
(JAVA_INTEGERAL_RANGE_ERROR):  Rename to JAVA_RANGE_ERROR.
(JAVA_RANGE_ERROR, JAVA_FLOAT_ANGE_ERROR):  Update accordingly.
* parse.h:  Various changes for USE_MAPPED_LOCATION.
(EXPR_WFL_EMIT_LINE_NOTE): XXX
(BUILD_EXPR_WFL, EXPR_WFL_ADD_COL): Remove no-longer-used macros.
(struct parser_ctxt):  New file_start_location field.
Remove p_line, c_line fields since we no longer save lines.
Remove elc, lineno, and current_jcf fields - no longer used.
* parse.y:  Updates for USE_MAPPED_LOCATION and new lexer.
Don't use EXPR_WFL_ADD_COL since that isn't trivial with
source_location and is probably not needed anymore anyway.
Use new expr_add_Location function.
(SET_EXPR_LOCATION_FROM_TOKEN):  New convenience macro.
(java_pop_parser_context):  Minor cleanup.
(java_parser_context_save_global, java_parser_context_restore_global,
java_pop_parser_context):  Save/restore input_location as a unit.
(issue_warning_error_from_context):  If USE_MAPPED_LOCATION take
a source_location instead of a wfl context node.
(check_class_interface_creation):  input_filename is not addressable.
(create_artificial_method):  Calling java_parser_context_save_global
and java_parser_context_restore_global is overkill.  Instead,
temporarily set input_location from class decl.
(java_layout_seen_class_methods): Set input_location from method decl.
(fix_constructors): Make more robust if no EXPR_WITH_FILE_LOCATION.
(finish_loop_body):  Likewise.
* lex.c: Updates for USE_MAPPED_LOCATION.  Use build_unknwon_wfl.
(java_sprint_unicode):  Take a character, not index in line.
(java_sneak_uncode):  Replaced by java_peek_unicode.
(java_unget_unicode):  No longer used.
(java_allocate_new_line. java_store_unicode):  Removed, since we
no longer remember "lines".
(java_new_lexer):  Update for new data structures.
(java_read_char):  Move unget_value checking to java_read_unicode.
(java_get_unicode, java_peek_unicode, java_next_unicode): New more
efficient functions that are used directly when lexing.
(java_read_unicode_collapsing_terminators):  No longer needed.
(java_parse_end_comment, java_parse_escape_sequence, do_java_lex):
Re-organize to use java_peek_unicode to avoid java_unget_unicode.
(java_parse_escape_sequence):  Rewrite to be simpler / more efficient.
(do_java_lex):  Lots of movings around to avoid java_unget_unicode,
combine switch branches, and test for common token kinds earlier.
(java_lex_error):  Rewrite.
* jv-scan.c (expand_location): New function, copied from tree.c.
(main): Set ctxp->filename instead of setting input_filename directly.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88367 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/java/ChangeLog
gcc/java/jcf-parse.c
gcc/java/jv-scan.c
gcc/java/lex.c
gcc/java/lex.h
gcc/java/parse.h
gcc/java/parse.y

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