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


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

[PATCH]: Java front-end improvement patch.



I just checked in an other front-end improvement patch. This one
does:

  - a better job at picking up source/class files during the type
    dependencies resolution. The limitation was originally removed with 
    this patch http://gcc.gnu.org/ml/gcc-patches/1999-12/msg00181.html, but
    took some tune up,

  - provide better handling of the situation where a source file is
    newer than its matching class file. A warning is still issued, but
    the source file is parsed instead. I plan on introducing a flag to
    force class files to be picked up preferably, since it might help
    people in certain situations.

./A

Fri Dec 24 00:25:29 1999  Alexandre Petit-Bianco  <apbianco@cygnus.com>

	* Makefile.in (LIBDEPS): Added gcc's errors.o
	(../jcf-dump$(exeext):): Link with gcc's errors.o
	(../gcjh$(exeext):): Likewise.
	* expr.c (expand_java_NEW): Layout the entire target type instead of
 	laying out its methods only.
	(lookup_field): Layout the class after having loaded it.
	* java-tree.h (java_debug_context): Declared.
	* jcf-io.c (toplev.h): Included.
	(find_class): Removed assignment to jcf's outofsynch
 	field. Force source file to be read if newer than its matching
 	class file. Tweaked debug messages.
	* jcf-parse.c (jcf_out_of_synch): Deleted.
	(read_class): Call to jcf_out_of_synch removed.
	* jcf.h (typedef struct JCF): Field `outofsynch' deleted.
	(jcf_out_of_synch): Prototype deleted.
	* parse.h (struct parser_ctxt): `minus_seen', `java_error_flag',
 	`deprecated' and `class_err': integer turned into bit fields.
	New bit fields `saved_data_ctx' and `saved_data'. Fixed comments.
	* parse.y (package_list): New global.
	(package_declaration:): Record newly parsed package name.
	(extra_ctxp_pushed_p): Static global deleted.
	(java_parser_context_save_global): Create buffer context for the
 	purpose of saving globals, if necessary.
	(java_parser_context_restore_global): Pop context pushed for the
 	purpose of saving globals, if necessary.
	(java_debug_context_do): New prototype and function.
	(java_debug_context): Likewise.
	(do_resolve_class): Use already parsed package names to qualify
 	and lookup class candidate. 
	(java_pre_expand_clinit): Removed unnecessary local variable.	

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/Makefile.in,v
retrieving revision 1.44
diff -u -p -r1.44 Makefile.in
--- Makefile.in	1999/09/20 16:27:29	1.44
+++ Makefile.in	2000/01/06 21:32:54
@@ -144,7 +144,7 @@ LIBIBERTY = ../../libiberty/libiberty.a
 # How to link with both our special library facilities
 # and the system's installed libraries.
 LIBS = $(LIBIBERTY) $(CLIB)
-LIBDEPS = $(LIBIBERTY)
+LIBDEPS = $(LIBIBERTY) ../errors.o
 
 # Specify the directories to be searched for header files.
 # Both . and srcdir are used, in that order,
@@ -184,7 +184,7 @@ compiler: ../jc1$(exeext) ../jv-scan$(ex
 ../jcf-dump$(exeext): jcf-dump.o jcf-io.o jcf-depend.o jcf-path.o \
 		zextract.o $(LIBDEPS)
 	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ jcf-dump.o jcf-io.o \
-	  jcf-depend.o jcf-path.o zextract.o $(LIBS)
+	  jcf-depend.o jcf-path.o zextract.o $(LIBS) ../errors.o
 
 # Dependencies here must be kept in sync with dependencies in Make-lang.in.
 ../jvgenmain$(exeext):  jvgenmain.o mangle.o $(LIBDEPS)
@@ -193,7 +193,7 @@ compiler: ../jc1$(exeext) ../jv-scan$(ex
 ../gcjh$(exeext): gjavah.o jcf-io.o jcf-depend.o jcf-path.o \
 		zextract.o $(LIBDEPS)
 	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gjavah.o jcf-io.o \
-	  jcf-depend.o jcf-path.o zextract.o $(LIBS)
+	  jcf-depend.o jcf-path.o zextract.o $(LIBS) ../errors.o
 
 Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure
 	cd ..; $(SHELL) config.status
Index: expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/expr.c,v
retrieving revision 1.53
diff -u -p -r1.53 expr.c
--- expr.c	1999/12/31 03:30:22	1.53
+++ expr.c	2000/01/06 21:33:02
@@ -1010,7 +1010,7 @@ expand_java_NEW (type)
 {
   if (! CLASS_LOADED_P (type))
     load_class (type, 1);
-  layout_class_methods (type);
+  safe_layout_class (type);
   push_value (build (CALL_EXPR, promote_type (type),
 		     build_address_of (alloc_object_node),
 		     tree_cons (NULL_TREE, build_class_ref (type),
@@ -1230,6 +1230,7 @@ lookup_field (typep, name)
   if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
     {
       load_class (*typep, 1);
+      safe_layout_class (*typep);
       if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
 	return error_mark_node;
     }
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/java-tree.h,v
retrieving revision 1.49
diff -u -p -r1.49 java-tree.h
--- java-tree.h	1999/12/10 16:06:23	1.49
+++ java-tree.h	2000/01/06 21:33:07
@@ -637,6 +637,7 @@ extern char* open_class PROTO ((char *, 
 extern char* open_class PROTO ((char *, struct JCF *, int, const char *));
 # endif /* JCF_USE_STDIO */
 #endif
+void java_debug_context PROTO ((void));
 
 /* We use ARGS_SIZE_RTX to indicate that gcc/expr.h has been included
    to declare `enum expand_modifier'. */
Index: jcf-io.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/jcf-io.c,v
retrieving revision 1.19
diff -u -p -r1.19 jcf-io.c
--- jcf-io.c	1999/09/16 15:45:10	1.19
+++ jcf-io.c	2000/01/06 21:33:07
@@ -27,6 +27,7 @@ The Free Software Foundation is independ
 
 #include "jcf.h"
 #include "tree.h"
+#include "toplev.h"
 #include "java-tree.h"
 
 /* DOS brain-damage */
@@ -286,7 +287,7 @@ DEFUN(find_class, (classname, classname_
 
   java_buffer = (char *) alloca (buflen);
 
-  jcf->java_source = jcf->outofsynch = 0;
+  jcf->java_source = 0;
 
   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
     {
@@ -352,8 +353,24 @@ DEFUN(find_class, (classname, classname_
 	}
     }
 
+  /* We preferably pick a class file if we have a chance. If the source
+     file is newer than the class file, we issue a warning and parse the
+     source file instead.
+     There should be a flag to allow people have the class file picked
+     up no matter what. FIXME. */
   if (! java && ! class && java_buf.st_mtime >= class_buf.st_mtime)
-    jcf->outofsynch = 1;
+    {
+      char *stripped_class_name = xstrdup (classname);
+      int i = strlen (stripped_class_name);
+      
+      while (stripped_class_name [i] != '.')
+	i--;
+      
+      stripped_class_name [i] = '\0';
+      warning ("Source file for class `%s' is newer than its matching class file. Source file used instead", stripped_class_name);
+      free (stripped_class_name);
+      class = -1;
+    }
 
   if (! java)
     dep_file = java_buffer;
@@ -382,7 +399,10 @@ DEFUN(find_class, (classname, classname_
 #else
   if (!class)
     {
-      SOURCE_FRONTEND_DEBUG (("Trying %s", buffer));
+      SOURCE_FRONTEND_DEBUG ((stderr, "[Class selected: %s]\n",
+			      classname+classname_length-
+			      (classname_length <= 30 ? 
+			       classname_length : 30)));
       fd = open (buffer, O_RDONLY | O_BINARY);
       if (fd >= 0)
 	goto found;
@@ -391,7 +411,10 @@ DEFUN(find_class, (classname, classname_
   if (!java)
     {
       strcpy (buffer, java_buffer);
-      SOURCE_FRONTEND_DEBUG (("Trying %s", buffer));
+      SOURCE_FRONTEND_DEBUG ((stderr, "[Source selected: %s]\n",
+			      classname+classname_length-
+			      (classname_length <= 30 ? 
+			       classname_length : 30)));
       fd = open (buffer, O_RDONLY);
       if (fd >= 0)
 	{
Index: jcf-parse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/jcf-parse.c,v
retrieving revision 1.39
diff -u -p -r1.39 jcf-parse.c
--- jcf-parse.c	1999/12/31 03:30:22	1.39
+++ jcf-parse.c	2000/01/06 21:33:10
@@ -440,22 +440,6 @@ get_class_constant (JCF *jcf , int i)
   return type;
 }
 
-void
-DEFUN(jcf_out_of_synch, (jcf),
-      JCF *jcf)
-{
-  char *source = xstrdup (jcf->filename);
-  int i = strlen (source);
-
-  while (source[i] != '.')
-    i--;
-
-  source [i] = '\0';
-  warning ("Class file `%s' out of synch with `%s.java'", 
-	   jcf->filename, source);
-  free (source);
-}
-
 /* Read a class with the fully qualified-name NAME.
    Return 1 iff we read the requested file.
    (It is still possible we failed if the file did not
@@ -488,8 +472,6 @@ read_class (name)
 	{
 	  this_jcf.seen_in_zip = 0;
 	  current_jcf = &this_jcf;
-	  if (this_jcf.outofsynch)
-	    jcf_out_of_synch (current_jcf);
 	}
     }
   else
Index: jcf.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/jcf.h,v
retrieving revision 1.12
diff -u -p -r1.12 jcf.h
--- jcf.h	1999/09/16 15:45:10	1.12
+++ jcf.h	2000/01/06 21:33:11
@@ -92,8 +92,6 @@ typedef struct JCF {
   unsigned char *read_end;
   int seen_in_zip;
   int java_source;
-  int  outofsynch;		/* Found a class file out of synch
-				   with the matching source file. */
   long zip_offset;    
   jcf_filbuf_t filbuf;
   void *read_state;
@@ -226,7 +224,6 @@ typedef struct JCF {
 extern const char *find_class PROTO ((const char *, int, JCF*, int));
 extern const char *find_classfile PROTO ((char *, JCF*, const char *));
 extern int jcf_filbuf_from_stdio PROTO ((JCF *jcf, int count));
-extern void jcf_out_of_synch PROTO((JCF *));
 extern int jcf_unexpected_eof PROTO ((JCF*, int)) ATTRIBUTE_NORETURN;
 
 /* Extract a character from a Java-style Utf8 string.
Index: parse.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/parse.h,v
retrieving revision 1.41
diff -u -p -r1.41 parse.h
--- parse.h	1999/12/31 03:30:21	1.41
+++ parse.h	2000/01/06 21:33:13
@@ -605,11 +605,25 @@ struct parser_ctxt {
   int osb_depth;		     /* Current depth of [ in an expression */
   int osb_limit;		     /* Limit of this depth */
   int *osb_number;		     /* Keep track of ['s */
-  int minus_seen;		     /* Integral literal overflow */
   int lineno;			     /* Current lineno */
-  int java_error_flag;		     /* Report error when true */
-  int deprecated;		     /* @deprecated tag seen */
 
+  /* The flags section */
+
+  /* Indicates a context used for saving the parser status. The
+     context must be popped when the status is restored. */
+  unsigned saved_data_ctx:1;	
+  /* Indicates that a context already contains saved data and that the
+     next save operation will require a new context to be created. */
+  unsigned saved_data:1;
+  /* Integral literal overflow */
+  unsigned minus_seen:1;
+  /* Report error when true */
+  unsigned java_error_flag:1;
+  /* @deprecated tag seen */
+  unsigned deprecated:1;
+  /* Flag to report certain errors (fix this documentation. FIXME) */
+  unsigned class_err:1;
+
   /* This section is defined only if we compile jc1 */
 #ifndef JC1_LITE
   tree modifier_ctx [11];	    /* WFL of modifiers */
@@ -619,7 +633,6 @@ struct parser_ctxt {
   struct JCF *current_jcf;	    /* CU jcf */
 
   int prevent_ese;	            /* Prevent expression statement error */
-  int class_err;		    /* Flag to report certain errors */
 
   int formal_parameter_number;	    /* Number of parameters found */
   int interface_number;		    /* # itfs declared to extend an itf def */
@@ -650,7 +663,7 @@ struct parser_ctxt {
 
   int pending_block;		    /* Pending block to close */
 
-  int explicit_constructor_p;	    /* True when processing an explicit
+  int explicit_constructor_p;	    /* >0 when processing an explicit
 				       constructor. This flag is used to trap
 				       illegal argument usage during an
 				       explicit constructor invocation. */
Index: parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/parse.y,v
retrieving revision 1.126
diff -u -p -r1.126 parse.y
--- parse.y	1999/12/31 03:30:21	1.126
+++ parse.y	2000/01/06 21:33:57
@@ -266,6 +266,7 @@ static tree search_loop PROTO ((tree));
 static int labeled_block_contains_loop_p PROTO ((tree, tree));
 static void check_abstract_method_definitions PROTO ((int, tree, tree));
 static void java_check_abstract_method_definitions PROTO ((tree));
+static void java_debug_context_do PROTO ((int));
 
 /* Number of error found so far. */
 int java_error_count; 
@@ -326,6 +327,9 @@ static tree java_lang_cloneable = NULL_T
 /* Context and flag for static blocks */
 static tree current_static_block = NULL_TREE;
 
+/* The list of all packages we've seen so far */
+static tree package_list = NULL_TREE;
+
 %}
 
 %union {
@@ -591,7 +595,10 @@ type_declarations:
 
 package_declaration:
 	PACKAGE_TK name SC_TK
-		{ ctxp->package = EXPR_WFL_NODE ($2); }
+		{ 
+		  ctxp->package = EXPR_WFL_NODE ($2);
+		  package_list = tree_cons (ctxp->package, NULL, package_list);
+		}
 |	PACKAGE_TK error
 		{yyerror ("Missing name"); RECOVER;}
 |	PACKAGE_TK name error
@@ -2368,25 +2375,30 @@ java_push_parser_context ()
     }
 }  
 
-/* If the first file of a file list was a class file, no context
-   exists for a source file to be parsed. This boolean remembers that
-   java_parser_context_save_global might have created a dummy one, so
-   that java_parser_context_restore_global can pop it.  */
-static int extra_ctxp_pushed_p = 0;
-
 void
 java_parser_context_save_global ()
 {
   if (!ctxp)
     {
       java_push_parser_context ();
-      extra_ctxp_pushed_p = 1;
+      ctxp->saved_data_ctx = 1;
+    }
+  else if (ctxp->saved_data)
+    {
+      struct parser_ctxt *new = 
+	(struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
+      bzero ((PTR)new, sizeof (struct parser_ctxt));
+      memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
+      new->next = ctxp;
+      ctxp = new;
+      ctxp->saved_data_ctx = 1;
     }
   ctxp->finput = finput;
   ctxp->lineno = lineno;
   ctxp->current_class = current_class;
   ctxp->filename = input_filename;
   ctxp->current_function_decl = current_function_decl;
+  ctxp->saved_data = 1;
 }
 
 void
@@ -2396,12 +2408,10 @@ java_parser_context_restore_global ()
   lineno = ctxp->lineno;
   current_class = ctxp->current_class;
   input_filename = ctxp->filename;
+  ctxp->saved_data = 0;
   current_function_decl = ctxp->current_function_decl;
-  if (!ctxp->next && extra_ctxp_pushed_p)
-    {
-      java_pop_parser_context (0);
-      extra_ctxp_pushed_p = 0;
-    }
+  if (ctxp->saved_data_ctx)
+    java_pop_parser_context (0);
 }
 
 void 
@@ -2444,6 +2454,44 @@ java_pop_parser_context (generate)
     free (toFree);
 }
 
+/* Dump the stacked up parser contexts. Intended to be called from a
+   debugger.  */
+
+static void
+java_debug_context_do (tab)
+     int tab;
+{
+#define JAVA_TAB_CONTEXT(C) \
+  {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
+
+  struct parser_ctxt *copy = ctxp;
+  while (copy)
+    {
+      JAVA_TAB_CONTEXT (tab);
+      fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
+      JAVA_TAB_CONTEXT (tab);
+      fprintf (stderr, "filename: %s\n", copy->filename);
+      JAVA_TAB_CONTEXT (tab);
+      fprintf (stderr, "package: %s\n",
+	       (copy->package ? 
+		IDENTIFIER_POINTER (copy->package) : "<none>"));
+      JAVA_TAB_CONTEXT (tab);
+      fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
+      JAVA_TAB_CONTEXT (tab);
+      fprintf (stderr, "saved data: %d\n", copy->saved_data);
+      copy = copy->next;
+      tab += 2;
+    }
+#undef JAVA_TAB_CONTEXT
+}
+
+void
+java_debug_context ()
+{
+  java_debug_context_do (0);
+}
+
+
 /* Reporting an constructor invocation error.  */
 static void
 parse_ctor_invocation_error ()
@@ -4311,7 +4359,7 @@ do_resolve_class (class_type, decl, cl)
     return NULL_TREE;
 
   /* 2- And check for the type in the current compilation unit. If it fails,
-     try with a name qualified with the package name if appropriate. */
+     try with a name qualified with the package name we've seen so far */
   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
     {
       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
@@ -4321,40 +4369,29 @@ do_resolve_class (class_type, decl, cl)
     }
 
   original_name = TYPE_NAME (class_type);
-  if (!QUALIFIED_P (TYPE_NAME (class_type)) && ctxp->package)
-    TYPE_NAME (class_type) = merge_qualified_name (ctxp->package, 
-						   TYPE_NAME (class_type));
-#if 1
-  if (!(new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
-    load_class (TYPE_NAME (class_type), 0);
-  if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
-    {
-      if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
-	  !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
-	load_class (TYPE_NAME (class_type), 0);
-      return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
-    }
-#else
-  new_name = TYPE_NAME (class_type);
-  if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_name)) != NULL_TREE)
-    {
-      if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
-          !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
-        load_class (new_name, 0);
-      return IDENTIFIER_CLASS_VALUE (new_name);
-    }
-  else
+  if (!QUALIFIED_P (TYPE_NAME (class_type)))
     {
-      tree class = read_class (new_name);
-      if (class != NULL_TREE)
+      tree package;
+      for (package = package_list; package; package = TREE_CHAIN (package))
 	{
-	  tree decl = IDENTIFIER_CLASS_VALUE (new_name);
-	  if (decl == NULL_TREE)
-	    decl = push_class (class, new_name);
-	  return decl;
+	  tree new_qualified;
+	  
+	  new_qualified = merge_qualified_name (TREE_PURPOSE (package),
+						original_name);
+	  TYPE_NAME (class_type) = new_qualified;
+	  new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
+	  if (!new_class_decl)
+	    load_class (TYPE_NAME (class_type), 0);
+	  new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
+	  if (new_class_decl)
+	    {
+	      if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
+		  !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
+		load_class (TYPE_NAME (class_type), 0);
+	      return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
+	    }
 	}
     }
-#endif
   TYPE_NAME (class_type) = original_name;
 
   /* 3- Check an other compilation unit that bears the name of type */
@@ -6079,7 +6116,6 @@ java_pre_expand_clinit (decl)
      tree decl;
 {
   tree fbody = DECL_FUNCTION_BODY (decl);
-  tree list;
   int to_return = 1;
 
   if (fbody != NULL_TREE)

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