OSDN Git Service

PR java/15543
[pf3gnuchains/gcc-fork.git] / gcc / java / lex.c
index 0b7e93d..712ffc2 100644 (file)
@@ -1,21 +1,22 @@
 /* Language lexer for the GNU compiler for the Java(TM) language.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+   Free Software Foundation, Inc.
    Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
+GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
-GNU CC is distributed in the hope that it will be useful,
+GCC is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
+along with GCC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA. 
 
@@ -37,37 +38,38 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "keyword.h"
 #include "flags.h"
 #include "chartables.h"
+#ifndef JC1_LITE
+#include "timevar.h"
+#endif
 
-/* Function declaration  */
-static char *java_sprint_unicode PARAMS ((struct java_line *, int));
-static void java_unicode_2_utf8 PARAMS ((unicode_t));
-static void java_lex_error PARAMS ((const char *, int));
+/* Function declarations.  */
+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
-static int java_is_eol PARAMS ((FILE *, int));
-static tree build_wfl_node PARAMS ((tree));
+static int do_java_lex (YYSTYPE *);
+static int java_lex (YYSTYPE *);
+static int java_is_eol (FILE *, int);
+static tree build_wfl_node (tree);
 #endif
-static void java_store_unicode PARAMS ((struct java_line *, unicode_t, int));
-static int java_parse_escape_sequence PARAMS ((void));
-static int java_start_char_p PARAMS ((unicode_t));
-static int java_part_char_p PARAMS ((unicode_t));
-static int java_parse_doc_section PARAMS ((int));
-static void java_parse_end_comment PARAMS ((int));
-static int java_get_unicode PARAMS ((void));
-static int java_read_unicode PARAMS ((java_lexer *, int *));
-static int java_read_unicode_collapsing_terminators PARAMS ((java_lexer *,
-                                                            int *));
-static void java_store_unicode PARAMS ((struct java_line *, unicode_t, int));
-static int java_read_char PARAMS ((java_lexer *));
-static void java_allocate_new_line PARAMS ((void));
-static void java_unget_unicode PARAMS ((void));
-static unicode_t java_sneak_unicode PARAMS ((void));
+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 *);
 #ifndef JC1_LITE
-static int utf8_cmp PARAMS ((const unsigned char *, int, const char *));
+static int utf8_cmp (const unsigned char *, int, const char *);
 #endif
 
-java_lexer *java_new_lexer PARAMS ((FILE *, const char *));
+java_lexer *java_new_lexer (FILE *, const char *);
 #ifndef JC1_LITE
-static void error_if_numeric_overflow PARAMS ((tree));
+static void error_if_numeric_overflow (tree);
 #endif
 
 #ifdef HAVE_ICONV
@@ -82,19 +84,13 @@ static int need_byteswap = 0;
 #endif
 
 void
-java_init_lex (finput, encoding)
-     FILE *finput;
-     const char *encoding;
+java_init_lex (FILE *finput, const char *encoding)
 {
 #ifndef JC1_LITE
   int java_lang_imported = 0;
 
   if (!java_lang_id)
     java_lang_id = get_identifier ("java.lang");
-  if (!java_lang_cloneable)
-    java_lang_cloneable = get_identifier ("java.lang.Cloneable");
-  if (!java_io_serializable)
-    java_io_serializable = get_identifier ("java.io.Serializable");
   if (!inst_id)
     inst_id = get_identifier ("inst$");
   if (!wpv_id)
@@ -102,8 +98,8 @@ java_init_lex (finput, 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,125 +107,77 @@ java_init_lex (finput, 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 ("java.lang.StringBuffer"), NULL, 0, 0);
+      build_unknown_wfl (get_identifier (flag_emit_class_files
+                                     ? "java.lang.StringBuffer"
+                                        : "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 ((PTR) ctxp->modifier_ctx, 0, 11*sizeof (ctxp->modifier_ctx[0]));
-  memset ((PTR) current_jcf, 0, sizeof (JCF));
+  memset (ctxp->modifier_ctx, 0, sizeof (ctxp->modifier_ctx));
   ctxp->current_parsed_class = NULL;
   ctxp->package = NULL_TREE;
 #endif
 
-  ctxp->filename = input_filename;
-  ctxp->lineno = lineno = 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 (line, i)
-    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 ()
-{
-  return (ctxp->c_line->line [ctxp->c_line->current]);
-}
-
-static void
-java_unget_unicode ()
-{
-  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 ()
-{
-  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 = (struct java_line *)xmalloc (sizeof (struct java_line));
-      ctxp->c_line->max = JAVA_LINE_MAX;
-      ctxp->c_line->line = (unicode_t *)xmalloc 
-       (sizeof (unicode_t)*ctxp->c_line->max);
-      ctxp->c_line->unicode_escape_p = 
-         (char *)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 = ++lineno;
-  ctxp->c_line->white_space_only = 1;
-}
-
 /* Create a new lexer object.  */
 
 java_lexer *
-java_new_lexer (finput, encoding)
-     FILE *finput;
-     const char *encoding;
+java_new_lexer (FILE *finput, const char *encoding)
 {
-  java_lexer *lex = (java_lexer *) xmalloc (sizeof (java_lexer));
+  java_lexer *lex = xmalloc (sizeof (java_lexer));
   int enc_error = 0;
 
   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);
@@ -265,7 +213,7 @@ java_new_lexer (finput, encoding)
              in[1] = 0xbb;
              in[2] = 0xbf;
 
-             inp = in;
+             inp = (char *) in;
              inc = 3;
              outp = (char *) &result;
              outc = 2;
@@ -287,24 +235,31 @@ java_new_lexer (finput, encoding)
       /* If iconv failed, use the internal decoder if the default
         encoding was requested.  This code is used on platforms where
         iconv exists but is insufficient for our needs.  For
-        instance, on Solaris 2.5 iconv cannot handle UTF-8 or UCS-2.  */
-      if (strcmp (encoding, DEFAULT_ENCODING))
+        instance, on Solaris 2.5 iconv cannot handle UTF-8 or UCS-2.
+
+        On Solaris the default encoding, as returned by nl_langinfo(),
+        is `646' (aka ASCII), but the Solaris iconv_open() doesn't
+        understand that.  We work around that by pretending
+        `646' to be the same as UTF-8.   */
+      if (strcmp (encoding, DEFAULT_ENCODING) && strcmp (encoding, "646"))
        enc_error = 1;
 #ifdef HAVE_ICONV
       else
-       lex->use_fallback = 1;
+        {
+         lex->use_fallback = 1;
+         lex->encoding = "UTF-8";
+       }
 #endif /* HAVE_ICONV */
     }
 
   if (enc_error)
-    fatal_error ("unknown encoding: `%s'\nThis might mean that your locale's encoding is not supported\nby your system's iconv(3) implementation.  If you aren't trying\nto use a particular encoding for your input file, try the\n`--encoding=UTF-8' option", encoding);
+    fatal_error ("unknown encoding: %qs\nThis might mean that your locale's encoding is not supported\nby your system's iconv(3) implementation.  If you aren't trying\nto use a particular encoding for your input file, try the\n%<--encoding=UTF-8%> option", encoding);
 
   return lex;
 }
 
 void
-java_destroy_lexer (lex)
-     java_lexer *lex;
+java_destroy_lexer (java_lexer *lex)
 {
 #ifdef HAVE_ICONV
   if (! lex->use_fallback)
@@ -314,16 +269,8 @@ java_destroy_lexer (lex)
 }
 
 static int
-java_read_char (lex)
-     java_lexer *lex;
+java_read_char (java_lexer *lex)
 {
-  if (lex->unget_value)
-    {
-      unicode_t r = lex->unget_value;
-      lex->unget_value = 0;
-      return r;
-    }
-
 #ifdef HAVE_ICONV
   if (! lex->use_fallback)
     {
@@ -372,7 +319,7 @@ java_read_char (lex)
              in_save = inbytesleft;
              out_save = out_count;
              inp = &lex->buffer[lex->first];
-             outp = &lex->out_buffer[lex->out_last];
+             outp = (char *) &lex->out_buffer[lex->out_last];
              ir = iconv (lex->handle, (ICONV_CONST char **) &inp,
                          &inbytesleft, &outp, &out_count);
 
@@ -429,8 +376,11 @@ java_read_char (lex)
                  else
                    {
                      /* A more serious error.  */
-                     java_lex_error ("unrecognized character in input stream",
-                                     0);
+                     char buffer[128];
+                     sprintf (buffer,
+                              "Unrecognized character for encoding '%s'", 
+                              lex->encoding);
+                     java_lex_error (buffer, 0);
                      return UEOF;
                    }
                }
@@ -486,8 +436,8 @@ java_read_char (lex)
                                                 + (c2 & 0x3f));
                      /* Check for valid 3-byte characters.
                         Don't allow surrogate, \ufffe or \uffff.  */
-                     if (r >= 0x800 && r <= 0xffff
-                         && ! (r >= 0xd800 && r <= 0xdfff)
+                     if (IN_RANGE (r, 0x800, 0xffff)
+                         && ! IN_RANGE (r, 0xd800, 0xdfff)
                          && r != 0xfffe && r != 0xffff)
                        return r;
                    }
@@ -505,31 +455,19 @@ java_read_char (lex)
   return UEOF;
 }
 
-static void
-java_store_unicode (l, c, unicode_escape_p)
-    struct java_line *l;
-    unicode_t c;
-    int unicode_escape_p;
-{
-  if (l->size == l->max)
-    {
-      l->max += JAVA_LINE_MAX;
-      l->line = (unicode_t *) xrealloc (l->line, sizeof (unicode_t)*l->max);
-      l->unicode_escape_p = (char *) 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 (lex, unicode_escape_p)
-     java_lexer *lex;
-     int *unicode_escape_p;
+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 != '\\')
@@ -552,25 +490,31 @@ java_read_unicode (lex, unicode_escape_p)
          while ((c = java_read_char (lex)) == 'u')
            ;
 
-         /* Unget the most recent character as it is not a `u'.  */
-         if (c == UEOF)
-           return UEOF;
-         lex->unget_value = c;
-
-         /* Next should be 4 hex digits, otherwise it's an error.
-            The hex value is converted into the unicode, pushed into
-            the Unicode stream.  */
-         for (shift = 12; shift >= 0; shift -= 4)
+         shift = 12;
+         do
            {
-             if ((c = java_read_char (lex)) == UEOF)
-               return UEOF;
-             if (ISDIGIT (c))
-               unicode |= (unicode_t)((c-'0') << shift);
-             else if ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
-               unicode |= (unicode_t)((10+(c | 0x20)-'a') << shift);
+             if (c == UEOF)
+               {
+                 java_lex_error ("prematurely terminated \\u sequence", 0);
+                 return UEOF;
+               }
+
+             if (hex_p (c))
+               unicode |= (unicode_t)(hex_value (c) << shift);
              else
-               java_lex_error ("Non hex digit in Unicode escape sequence", 0);
+               {
+                 java_lex_error ("non-hex digit in \\u sequence", 0);
+                 break;
+               }
+
+             c = java_read_char (lex);
+             shift -= 4;
            }
+         while (shift >= 0);
+
+         if (c != UEOF)
+           lex->unget_value = c;
+
          lex->bs_count = 0;
          *unicode_escape_p = 1;
          return unicode;
@@ -580,78 +524,116 @@ java_read_unicode (lex, 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 (lex, unicode_escape_p)
-     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;
+  int next;
 
-  if (c == '\r')
+  if (lex->avail_unicode)
+    return lex->next_unicode;
+
+  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')
-       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 ()
-{
-  /* 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_unicode
+   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 '*'. */
+ * C is the first character following the '/' and '*'.  */
 static void
-java_parse_end_comment (c)
-     int c;
+java_parse_end_comment (int c)
 {
   for ( ;; c = java_get_unicode ())
     {
@@ -661,15 +643,16 @@ java_parse_end_comment (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 ();
+           case '*':   /* Reparse only '*'.  */
+             ;
            }
        }
     }
@@ -679,69 +662,106 @@ java_parse_end_comment (c)
    of a documentation comment line (ignoring white space and any `*'
    character). Parsed keyword(s): @DEPRECATED.  */
 
-static int
-java_parse_doc_section (c)
-     int c;
+static void
+java_parse_doc_section (int c)
 {
-  int valid_tag = 0, seen_star = 0;
+  int last_was_star;
 
-  while (JAVA_WHITE_SPACE_P (c) || (c == '*') || c == '\n')
+  /* We reset this here, because only the most recent doc comment
+     applies to the following declaration.  */
+  ctxp->deprecated = 0;
+
+  /* We loop over all the lines of the comment.  We'll eventually exit
+     if we hit EOF prematurely, or when we see the comment
+     terminator.  */
+  while (1)
     {
-      switch (c)
+      /* These first steps need only be done if we're still looking
+        for the deprecated tag.  If we've already seen it, we might
+        as well skip looking for it again.  */
+      if (! ctxp->deprecated)
        {
-       case '*':
-         seen_star = 1;
-         break;
-       case '\n': /* ULT */
-         valid_tag = 1;
-       default:
-         seen_star = 0;
-       }
-      c = java_get_unicode();
-    }
+         /* Skip whitespace and '*'s.  We must also check for the end
+            of the comment here.  */
+         while (JAVA_WHITE_SPACE_P (c) || c == '*')
+           {
+             last_was_star = (c == '*');
+             c = java_get_unicode ();
+             if (last_was_star && c == '/')
+               {
+                 /* We just saw the comment terminator.  */
+                 return;
+               }
+           }
 
-  if (c == UEOF)
-    java_lex_error ("Comment not terminated at end of input", 0);
+         if (c == UEOF)
+           goto eof;
 
-  if (seen_star && (c == '/'))
-    return 1;                  /* Goto step1 in caller */
+         if (c == '@')
+           {
+             const char *deprecated = "@deprecated";
+             int i;
 
-  /* We're parsing @deprecated */
-  if (valid_tag && (c == '@'))
-    {
-      char tag [11];
-      int  tag_index = 0;
+             for (i = 0; deprecated[i]; ++i)
+               {
+                 if (c != deprecated[i])
+                   break;
+                 /* We write the code in this way, with the
+                    update at the end, so that after the loop
+                    we're left with the next character in C.  */
+                 c = java_get_unicode ();
+               }
 
-      while (tag_index < 10 && c != UEOF && c != ' ' && c != '\n')
+             if (c == UEOF)
+               goto eof;
+
+             /* @deprecated must be followed by a space or newline.
+                We also allow a '*' in case it appears just before
+                the end of a comment.  In this position only we also
+                must allow any Unicode space character.  */
+             if (c == ' ' || c == '\n' || c == '*' || java_space_char_p (c))
+               {
+                 if (! deprecated[i])
+                   ctxp->deprecated = 1;
+               }
+           }
+       }
+
+      /* We've examined the relevant content from this line.  Now we
+        skip the remaining characters and start over with the next
+        line.  We also check for end of comment here.  */
+      while (c != '\n' && c != UEOF)
        {
+         last_was_star = (c == '*');
          c = java_get_unicode ();
-         tag [tag_index++] = c;
+         if (last_was_star && c == '/')
+           return;
        }
 
       if (c == UEOF)
-       java_lex_error ("Comment not terminated at end of input", 0);
-      tag [tag_index] = '\0';
-
-      if (!strcmp (tag, "deprecated"))
-       ctxp->deprecated = 1;
+       goto eof;
+      /* We have to advance past the \n.  */
+      c = java_get_unicode ();
+      if (c == UEOF)
+       goto eof;
     }
-  java_unget_unicode ();
-  return 0;
+
+ eof:
+  java_lex_error ("Comment not terminated at end of input", 0);
 }
 
 /* Return true if C is a valid start character for a Java identifier.
    This is only called if C >= 128 -- smaller values are handled
    inline.  However, this function handles all values anyway.  */
 static int
-java_start_char_p (c)
-     unicode_t c;
+java_start_char_p (unicode_t c)
 {
   unsigned int hi = c / 256;
-  char *page = type_table[hi];
+  const char *const page = type_table[hi];
   unsigned long val = (unsigned long) page;
   int flags;
 
-  if ((val & ~ (LETTER_PART | LETTER_START)) != 0)
+  if ((val & ~ LETTER_MASK) != 0)
     flags = page[c & 255];
   else
     flags = val;
@@ -753,15 +773,14 @@ java_start_char_p (c)
    This is only called if C >= 128 -- smaller values are handled
    inline.  However, this function handles all values anyway.  */
 static int
-java_part_char_p (c)
-     unicode_t c;
+java_part_char_p (unicode_t c)
 {
   unsigned int hi = c / 256;
-  char *page = type_table[hi];
+  const char *const page = type_table[hi];
   unsigned long val = (unsigned long) page;
   int flags;
 
-  if ((val & ~ (LETTER_PART | LETTER_START)) != 0)
+  if ((val & ~ LETTER_MASK) != 0)
     flags = page[c & 255];
   else
     flags = val;
@@ -769,10 +788,26 @@ java_part_char_p (c)
   return flags & LETTER_PART;
 }
 
+/* Return true if C is whitespace.  */
+static int
+java_space_char_p (unicode_t c)
+{
+  unsigned int hi = c / 256;
+  const char *const page = type_table[hi];
+  unsigned long val = (unsigned long) page;
+  int flags;
+
+  if ((val & ~ LETTER_MASK) != 0)
+    flags = page[c & 255];
+  else
+    flags = val;
+
+  return flags & LETTER_SPACE;
+}
+
 static int
-java_parse_escape_sequence ()
+java_parse_escape_sequence (void)
 {
-  unicode_t char_lit;
   int c;
 
   switch (c = java_get_unicode ())
@@ -796,73 +831,59 @@ java_parse_escape_sequence ()
     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;
     }
 }
 
-/* Isolate the code which may raise an arithmetic exception in its
-   own function.  */
-
 #ifndef JC1_LITE
-struct jpa_args
-{
-  YYSTYPE *java_lval;
-  char *literal_token;
-  int fflag;
-  int number_beginning;
-};
+#define IS_ZERO(X) REAL_VALUES_EQUAL (X, dconst0)
 
-#ifdef REAL_ARITHMETIC
-#define IS_ZERO(X) (ereal_cmp (X, dconst0) == 0)
-#else
-#define IS_ZERO(X) ((X) == 0)
-#endif
+/* Subroutine of java_lex: converts floating-point literals to tree
+   nodes.  LITERAL_TOKEN is the input literal, JAVA_LVAL is where to
+   store the result.  FFLAG indicates whether the literal was tagged
+   with an 'f', indicating it is of type 'float'; NUMBER_BEGINNING
+   is the line number on which to report any error.  */
 
-static void java_perform_atof  PARAMS ((PTR));
+static void java_perform_atof (YYSTYPE *, char *, int, int);
 
 static void
-java_perform_atof (av)
-     PTR av;
+java_perform_atof (YYSTYPE *java_lval, char *literal_token, int fflag,
+                  int number_beginning)
 {
-  struct jpa_args *a = (struct jpa_args *)av;
-  YYSTYPE *java_lval = a->java_lval;
-  int number_beginning = a->number_beginning;
   REAL_VALUE_TYPE value;
-  tree type = (a->fflag ? FLOAT_TYPE_NODE : DOUBLE_TYPE_NODE);
+  tree type = (fflag ? FLOAT_TYPE_NODE : DOUBLE_TYPE_NODE);
 
   SET_REAL_VALUE_ATOF (value,
-                      REAL_VALUE_ATOF (a->literal_token, TYPE_MODE (type)));
+                      REAL_VALUE_ATOF (literal_token, TYPE_MODE (type)));
 
   if (REAL_VALUE_ISINF (value) || REAL_VALUE_ISNAN (value))
     {
-      JAVA_FLOAT_RANGE_ERROR ((a->fflag ? "float" : "double"));
+      JAVA_FLOAT_RANGE_ERROR (fflag ? "float" : "double");
       value = DCONST0;
     }
   else if (IS_ZERO (value))
@@ -870,7 +891,7 @@ java_perform_atof (av)
       /* We check to see if the value is really 0 or if we've found an
         underflow.  We do this in the most primitive imaginable way.  */
       int really_zero = 1;
-      char *p = a->literal_token;
+      char *p = literal_token;
       if (*p == '-')
        ++p;
       while (*p && *p != 'e' && *p != 'E')
@@ -884,170 +905,112 @@ java_perform_atof (av)
        }
       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;
        }
     }
 
-  SET_LVAL_NODE_TYPE (build_real (type, value), type);
+  SET_LVAL_NODE (build_real (type, value));
 }
 #endif
 
-static int yylex               PARAMS ((YYSTYPE *));
+static int yylex (YYSTYPE *);
 
 static int
 #ifdef JC1_LITE
-yylex (java_lval)
+yylex (YYSTYPE *java_lval)
 #else
-java_lex (java_lval)
+do_java_lex (YYSTYPE *java_lval)
 #endif
-     YYSTYPE *java_lval;
 {
   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 */
+  /* Skip white spaces: SP, TAB and FF or ULT.  */ 
+  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 ()) == '*')
-           {
-             if ((c = java_get_unicode ()) == '/')
-               goto step1;     /* Empy documentation comment  */
-             else if (java_parse_doc_section (c))
-               goto step1;
-           }
-
-         java_parse_end_comment ((c = java_get_unicode ()));
-         goto step1;
-         break;
-       default:
-         java_unget_unicode ();
-         c = '/';
-         break;
-       }
-    }
+  /* Handle EOF here.  */
+  if (c == UEOF)       /* Should probably do something here...  */
+    return 0;
 
-  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 */
+  /* Numeric literals */
   if (JAVA_ASCII_DIGIT (c) || (c == '.'))
     {
-      /* This section of code is borrowed from gcc/c-lex.c  */
+      /* This section of code is borrowed from gcc/c-lex.c.  */
 #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
       int parts[TOTAL_PARTS];
       HOST_WIDE_INT high, low;
-      /* End borrowed section  */
+      /* End borrowed section.  */
       char literal_token [256];
       int  literal_index = 0, radix = 10, long_suffix = 0, overflow = 0, bytes;
-      int  found_hex_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;
-         else if (c == '.')
            {
-             /* Push the '.' back and prepare for a FP parsing... */
-             java_unget_unicode ();
-             c = '0';
+             literal_token [literal_index++] = '0';
+             radix = 8;
+           }
+         else if (c == '.' || c == 'e' || c =='E')
+           {
+             literal_token [literal_index++] = '0';
+             /* Handle C during floating-point parsing.  */
            }
          else
            {
-             /* We have a zero literal: 0, 0{f,F}, 0{d,D} */
-             JAVA_LEX_LIT ("0", 10);
+             /* We have a zero literal: 0, 0{l,L}, 0{f,F}, 0{d,D}.  */
               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);
                }
@@ -1055,21 +1018,22 @@ java_lex (java_lval)
        }
       /* Parse the first part of the literal, until we find something
         which is not a number.  */
-      while ((radix == 10 && JAVA_ASCII_DIGIT (c)) ||
-            (radix == 16 && JAVA_ASCII_HEXDIGIT (c)) ||
-            (radix == 8  && JAVA_ASCII_OCTDIGIT (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.  */
-         int numeric = (ISDIGIT (c) ? c-'0' : 10 +(c|0x20)-'a');
+         int numeric = hex_value (c);
          int count;
 
-         /* Remember when we find a valid hexadecimal digit */
+         /* Remember when we find a valid hexadecimal digit */
          if (radix == 16)
            found_hex_digits = 1;
+          /* Remember when we find an invalid octal digit.  */
+          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  */
+         /* This section of code if borrowed from gcc/c-lex.c.  */
          for (count = 0; count < TOTAL_PARTS; count++)
            {
              parts[count] *= radix;
@@ -1084,18 +1048,25 @@ java_lex (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;
          int fflag = 0;        /* 1 for {f,F}, 0 for {d,D}. FP literal are
-                                  double unless specified. */
+                                  double unless specified.  */
 
          /* It is ok if the radix is 8 because this just means we've
             seen a leading `0'.  However, radix==16 is invalid.  */
@@ -1111,7 +1082,10 @@ java_lex (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);
@@ -1121,14 +1095,16 @@ java_lex (java_lval)
                {
                  if (stage < 2)
                    {
-                     /* {E,e} must have seen at list a digit */
+                     /* {E,e} must have seen at least a digit.  */
                      if (!seen_digit)
-                       java_lex_error ("Invalid FP literal", 0);
+                       java_lex_error
+                          ("Invalid FP literal, mantissa must have digit", 0);
                      seen_digit = 0;
                      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);
@@ -1136,14 +1112,15 @@ java_lex (java_lval)
              if ( c == 'f' || c == 'F' || c == 'd' || c == 'D')
                {
                  fflag = ((c == 'd') || (c == 'D')) ? 0 : 1;
-                 stage = 4;    /* So we fall through */
+                 stage = 4;    /* So we fall through */
                }
 
              if ((c=='-' || c =='+') && stage == 2)
                {
                  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)) ||
@@ -1153,61 +1130,51 @@ java_lex (java_lval)
                {
                  if (JAVA_ASCII_DIGIT (c))
                    seen_digit = 1;
+                  if (stage == 2)
+                    stage = 3;
                  literal_token [literal_index++ ] = c;
-                 c = java_get_unicode ();
+                 java_next_unicode ();
+                 c = java_peek_unicode ();
                }
              else
                {
-#ifndef JC1_LITE
-                 struct jpa_args a;
-#endif
-                 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)
-                   java_lex_error ("Invalid FP literal", 0);
+                   java_lex_error
+                      ("Invalid FP literal, exponent must have digit", 0);
 
                  literal_token [literal_index] = '\0';
-                 JAVA_LEX_LIT (literal_token, radix);
 
 #ifndef JC1_LITE
-                 a.literal_token = literal_token;
-                 a.fflag = fflag;
-                 a.java_lval = java_lval;
-                 a.number_beginning = number_beginning;
-                 if (do_float_handler (java_perform_atof, (PTR) &a))
-                   return FP_LIT_TK;
-
-                 JAVA_FLOAT_RANGE_ERROR ((fflag ? "float" : "double"));
-#else
-                 return FP_LIT_TK;
+                 java_perform_atof (java_lval, literal_token,
+                                    fflag, number_beginning);
 #endif
+                 return FP_LIT_TK;
                }
            }
-       } /* JAVA_ASCCI_FPCHAR (c) */
+       } /* JAVA_ASCII_FPCHAR (c) */
 
+      /* Here we get back to converting the integral literal.  */
       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 >= 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')
+       {
+         java_next_unicode ();
+         long_suffix = 1;
+       }
 
-      /* Here we get back to converting the integral literal.  */
-      if (c == 'L' || c == 'l')
-       long_suffix = 1;
-      else if (radix == 16 && JAVA_ASCII_LETTER (c))
-       java_lex_error ("Digit out of range in hexadecimal literal", 0);
-      else if (radix == 8  && JAVA_ASCII_DIGIT (c))
-       java_lex_error ("Digit out of range in octal literal", 0);
-      else if (radix == 16 && !literal_index)
-       java_lex_error ("No digit specified for hexadecimal literal", 0);
-      else
-       java_unget_unicode ();
-
-#ifdef JAVA_LEX_DEBUG
-      literal_token [literal_index] = '\0'; /* So JAVA_LEX_LIT is safe. */
-      JAVA_LEX_LIT (literal_token, radix);
-#endif
-      /* This section of code is borrowed from gcc/c-lex.c  */
+      /* This section of code is borrowed from gcc/c-lex.c.  */
       if (!overflow)
        {
          bytes = GET_TYPE_PRECISION (long_type_node);
@@ -1228,45 +1195,158 @@ java_lex (java_lval)
        }
       /* End borrowed section.  */
 
-      /* Range checking */
-      if (long_suffix)
+#ifndef JC1_LITE
+      /* Range checking.  */
+      /* Temporarily set type to unsigned.  */
+      value = build_int_cst_wide (long_suffix
+                                 ? unsigned_long_type_node
+                                 : unsigned_int_type_node, low, high);
+      SET_LVAL_NODE (value);
+
+      /* For base 10 numbers, only values up to the highest value
+        (plus one) can be written.  For instance, only ints up to
+        2147483648 can be written.  The special case of the largest
+        negative value is handled elsewhere.  For other bases, any
+        number can be represented.  */
+      if (overflow || (radix == 10
+                      && tree_int_cst_lt (long_suffix
+                                          ? decimal_long_max
+                                          : decimal_int_max,
+                                          value)))
        {
-         /* 9223372036854775808L is valid if operand of a '-'. Otherwise
-            9223372036854775807L is the biggest `long' literal that can be
-            expressed using a 10 radix. For other radixes, everything that
-            fits withing 64 bits is OK. */
-         int hb = (high >> 31);
-         if (overflow || (hb && low && radix == 10)
-             || (hb && high & 0x7fffffff && radix == 10))
-           JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `long' literal");
+         if (long_suffix)
+           JAVA_RANGE_ERROR ("Numeric overflow for 'long' literal");
+         else
+           JAVA_RANGE_ERROR ("Numeric overflow for 'int' literal");
        }
-      else
+
+      /* Sign extend the value.  */
+      value = build_int_cst_wide (long_suffix ? long_type_node : int_type_node,
+                                 low, high);
+      value = force_fit_type (value, 0, false, false);
+
+      if (radix != 10)
        {
-         /* 2147483648 is valid if operand of a '-'. Otherwise,
-            2147483647 is the biggest `int' literal that can be
-            expressed using a 10 radix. For other radixes, everything
-            that fits within 32 bits is OK.  As all literals are
-            signed, we sign extend here. */
-         int hb = (low >> 31) & 0x1;
-         if (overflow || high || (hb && low & 0x7fffffff && radix == 10))
-           JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `int' literal");
-         high = -hb;
+         value = copy_node (value);
+         JAVA_NOT_RADIX10_FLAG (value) = 1;
        }
-#ifndef JC1_LITE
-      value = build_int_2 (low, high);
-      JAVA_RADIX10_FLAG (value) = radix == 10;
-      SET_LVAL_NODE_TYPE (value, long_suffix ? long_type_node : int_type_node);
-#else
-      SET_LVAL_NODE_TYPE (build_int_2 (low, high),
-                         long_suffix ? long_type_node : int_type_node);
+      
+      SET_LVAL_NODE (value);
 #endif
       return INT_LIT_TK;
     }
 
-  /* Character literals */
+  /* 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 == '\'')
     {
       int char_lit;
+      
       if ((c = java_get_unicode ()) == '\\')
        char_lit = java_parse_escape_sequence ();
       else
@@ -1284,22 +1364,29 @@ java_lex (java_lval)
        java_lex_error ("Syntax error in character literal", 0);
 
       if (char_lit == JAVA_CHAR_ERROR)
-        char_lit = 0;          /* We silently convert it to zero */
+        char_lit = 0;          /* We silently convert it to zero */
 
-      JAVA_LEX_CHAR_LIT (char_lit);
-      SET_LVAL_NODE_TYPE (build_int_2 (char_lit, 0), char_type_node);
+      SET_LVAL_NODE (build_int_cst (char_type_node, char_lit));
       return CHAR_LIT_TK;
     }
 
-  /* String literals */
+  /* 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)
@@ -1309,18 +1396,13 @@ java_lex (java_lval)
            }
          java_unicode_2_utf8 (c);
        }
-      if (c == '\n' || c == UEOF) /* ULT */
-       {
-         lineno--;             /* Refer to the line the terminator was seen */
-         java_lex_error ("String not terminated at end of line", 0);
-         lineno++;
-       }
 
       obstack_1grow (&temporary_obstack, '\0');
       string = obstack_finish (&temporary_obstack);
 #ifndef JC1_LITE
       if (!no_error || (c != '"'))
-       java_lval->node = error_mark_node; /* Requires futher testing FIXME */
+       java_lval->node = error_mark_node; /* FIXME: Requires further
+                                              testing.  */
       else
        java_lval->node = build_string (strlen (string), string);
 #endif
@@ -1328,51 +1410,108 @@ java_lex (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 = lineno;
+       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 = lineno;
-      BUILD_OPERATOR (CCB_TK);
+        ctxp->last_ccb_indent1 = input_location;
+#else
+      if (ctxp->ccb_indent == 1)
+        ctxp->last_ccb_indent1 = input_line;
+#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
@@ -1381,311 +1520,218 @@ java_lex (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; 
-       JAVA_PART_CHAR_P (c); c = java_get_unicode ())
+  if (c == 0x1a)               /* CTRL-Z.  */
     {
-      java_unicode_2_utf8 (c);
-      if (all_ascii && c >= 128)
-        all_ascii = 0;
-      ascii_index++;
+      if ((c = java_peek_unicode ()) == UEOF)
+       return 0;               /* Ok here.  */
     }
 
-  obstack_1grow (&temporary_obstack, '\0');
-  string = obstack_finish (&temporary_obstack);
-  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)
-    {
-      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;
-
-             /* Some keyword we want to retain information on the location
-                they where found */
-           case CASE_TK:
-           case DEFAULT_TK:
-           case SUPER_TK:
-           case THIS_TK:
-           case RETURN_TK:
-           case BREAK_TK:
-           case CONTINUE_TK:
-           case TRY_TK:
-           case CATCH_TK:
-           case THROW_TK:
-           case INSTANCEOF_TK:
-             BUILD_OPERATOR (kw->token);
-
-           default:
-             return kw->token;
-           }
-       }
-    }
-  
-  /* We may have an ID here */
-  if (JAVA_START_CHAR_P (first_unicode))
-    {
-      JAVA_LEX_ID (string);
-      java_lval->node = BUILD_ID_WFL (GET_IDENTIFIER (string));
-      return ID_TK;
-    }
-
-  /* Everything else is an invalid character in the input */
+  /* Everything else is an invalid character in the input.  */
   {
     char lex_error_buffer [128];
-    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;
 }
 
 #ifndef JC1_LITE
+
+/* The exported interface to the lexer.  */
+static int
+java_lex (YYSTYPE *java_lval)
+{
+  int r;
+
+  timevar_push (TV_LEX);
+  r = do_java_lex (java_lval);
+  timevar_pop (TV_LEX);
+  return r;
+}
+
 /* This is called by the parser to see if an error should be generated
    due to numeric overflow.  This function only handles the particular
    case of the largest negative value, and is only called in the case
-   where this value is not preceeded by `-'.  */
+   where this value is not preceded by `-'.  */
 static void
-error_if_numeric_overflow (value)
-     tree value;
+error_if_numeric_overflow (tree value)
 {
-  if (TREE_CODE (value) == INTEGER_CST && JAVA_RADIX10_FLAG (value))
+  if (TREE_CODE (value) == INTEGER_CST
+      && !JAVA_NOT_RADIX10_FLAG (value)
+      && tree_int_cst_sgn (value) < 0)
     {
-      unsigned HOST_WIDE_INT lo, hi;
-
-      lo = TREE_INT_CST_LOW (value);
-      hi = TREE_INT_CST_HIGH (value);
       if (TREE_TYPE (value) == long_type_node)
-       {
-         int hb = (hi >> 31);
-         if (hb && !(hi & 0x7fffffff))
-           java_lex_error ("Numeric overflow for `long' literal", 0);
-       }
+       java_lex_error ("Numeric overflow for 'long' literal", 0);
       else
-       {
-         int hb = (lo >> 31) & 0x1;
-         if (hb && !(lo & 0x7fffffff))
-           java_lex_error ("Numeric overflow for `int' literal", 0);
-       }
+       java_lex_error ("Numeric overflow for 'int' literal", 0);
     }
 }
+
 #endif /* JC1_LITE */
 
 static void
-java_unicode_2_utf8 (unicode)
-    unicode_t unicode;
+java_unicode_2_utf8 (unicode_t unicode)
 {
   if (RANGE (unicode, 0x01, 0x7f))
     obstack_1grow (&temporary_obstack, (char)unicode);
@@ -1696,7 +1742,7 @@ java_unicode_2_utf8 (unicode)
       obstack_1grow (&temporary_obstack,
                     (unsigned char)(0x80 | (unicode & 0x3f)));
     }
-  else                         /* Range 0x800-0xffff */
+  else                         /* Range 0x800-0xffff */
     {
       obstack_1grow (&temporary_obstack,
                     (unsigned char)(0xe0 | (unicode & 0xf000) >> 12));
@@ -1709,37 +1755,53 @@ java_unicode_2_utf8 (unicode)
 
 #ifndef JC1_LITE
 static tree
-build_wfl_node (node)
-     tree node;
+build_wfl_node (tree node)
 {
-  node = build_expr_wfl (node, ctxp->filename, ctxp->elc.line, ctxp->elc.col);
-  /* Prevent java_complete_lhs from short-circuiting node (if constant). */
+#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;
 }
 #endif
 
 static void
-java_lex_error (msg, forward)
-     const char *msg ATTRIBUTE_UNUSED;
-     int forward ATTRIBUTE_UNUSED;
+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 */
+  /* 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
 }
 
 #ifndef JC1_LITE
 static int
-java_is_eol (fp, c)
-  FILE *fp;
-  int c;
+java_is_eol (FILE *fp, int c)
 {
   int next;
   switch (c)
@@ -1758,18 +1820,17 @@ java_is_eol (fp, c)
 #endif
 
 char *
-java_get_line_col (filename, line, col)
-     const char *filename ATTRIBUTE_UNUSED;
-     int line ATTRIBUTE_UNUSED, col ATTRIBUTE_UNUSED;
+java_get_line_col (const char *filename ATTRIBUTE_UNUSED,
+                  int line ATTRIBUTE_UNUSED, int col ATTRIBUTE_UNUSED)
 {
 #ifdef JC1_LITE
   return 0;
 #else
-  /* Dumb implementation. Doesn't try to cache or optimize things. */
-  /* First line of the file is line 1, first column is 1 */
+  /* Dumb implementation. Doesn't try to cache or optimize things.  */
+  /* First line of the file is line 1, first column is 1 */
 
-  /* COL == -1 means, at the CR/LF in LINE */
-  /* COL == -2 means, at the first non space char in LINE */
+  /* COL == -1 means, at the CR/LF in LINE */
+  /* COL == -2 means, at the first non space char in LINE */
 
   FILE *fp;
   int c, ccol, cline = 1;
@@ -1778,7 +1839,7 @@ java_get_line_col (filename, line, col)
   char *base;
 
   if (!(fp = fopen (filename, "r")))
-    fatal_io_error ("can't open %s", filename);
+    fatal_error ("can't open %s: %m", filename);
 
   while (cline != line)
     {
@@ -1793,7 +1854,7 @@ java_get_line_col (filename, line, col)
        cline++;
     }
 
-  /* Gather the chars of the current line in a buffer */
+  /* Gather the chars of the current line in a buffer */
   for (;;)
     {
       c = getc (fp);
@@ -1818,13 +1879,13 @@ java_get_line_col (filename, line, col)
   else
     first_non_space = 0;
 
-  /* Place the '^' a the right position */
+  /* 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 */
+      /* 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);
@@ -1836,10 +1897,7 @@ java_get_line_col (filename, line, col)
 
 #ifndef JC1_LITE
 static int
-utf8_cmp (str, length, name)
-     const unsigned char *str;
-     int length;
-     const char *name;
+utf8_cmp (const unsigned char *str, int length, const char *name)
 {
   const unsigned char *limit = str + length;
   int i;
@@ -1967,9 +2025,7 @@ static const char *const cxx_keywords[] =
 /* Return true if NAME is a C++ keyword.  */
 
 int
-cxx_keyword_p (name, length)
-     const char *name;
-     int length;
+cxx_keyword_p (const char *name, int length)
 {
   int last = ARRAY_SIZE (cxx_keywords);
   int first = 0;
@@ -1982,13 +2038,12 @@ cxx_keyword_p (name, length)
     {
       int kwl = strlen (cxx_keywords[mid]);
       int min_length = kwl > length ? length : kwl;
-      int r = utf8_cmp (name, min_length, cxx_keywords[mid]);
+      int r = utf8_cmp ((const unsigned char *) name, min_length, cxx_keywords[mid]);
 
       if (r == 0)
        {
          int i;
-         /* We've found a match if all the remaining characters are
-            `$'.  */
+         /* We've found a match if all the remaining characters are `$'.  */
          for (i = min_length; i < length && name[i] == '$'; ++i)
            ;
          if (i == length)