Commit fea2d5da by Per Bothner Committed by Per Bothner

Handle compiling multiple input files at once, and @FILE syntax. See ChangeLog.

From-SVN: r40024
parent 1aed31b6
2001-02-16 Per Bothner <per@bothner.com>
Handle compiling multiple input files at once, and @FILE syntax.
* java-tree.h (flag_filelist_file, init_src_parse): New declarations.
* jcf-parse.c (parse_source_file): Split into ...
(parse_source_file_1): New function - and:
(parse_source_file_2): New function.
(yyparse): On -ffilelist-file, open and scan named file.
On first pass over files, only do parse_source_file_1.
A new second pass calls parse_source_file_2 for each file to compile.
(init_jcf_parse): Call init_src_parse.
* jvspec.c (INDIRECT_FILE_ARG): New flag.
(lang_specific_driver): Support @FILELIST-FILE syntax, as well
as multiple input file combined in one compilation.
* lang-options.h: Add -ffilelist-file
* lang.c (flag_filelist_file): New flag variable.
(lang_f_options): Handle -ffilelist-file.
* lex.c (java_init_lex): Don't clear ctxp->incomplete_class.
* parse.h (struct parse_ctxt): Remove fields incomplete_class and
gclass_list - use global fields of src_parse_roots instead.
* parse.y (src_parse_roots): New array.
(incomplete_class_list, gclass_list): New macros.
(push_parser_context, java_pop_parser_context,
java_parser_context_resume): Don't fiddle with deleted fields.
(various): Use incomplete_class gclass_list and global macros
instead of parse_ctxt fields - the lists are global.
(init_src_parse): New function.
Fri Feb 23 15:28:39 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* decl.c (set_block): Set NAMES and BLOCKS from BLOCK.
......
......@@ -138,6 +138,8 @@ extern int flag_assume_compiled;
extern int flag_emit_class_files;
extern int flag_filelist_file;
/* When non zero, assume all native functions are implemented with
JNI, not CNI. */
......@@ -1111,6 +1113,7 @@ extern boolean java_hash_compare_tree_node PARAMS ((hash_table_key,
hash_table_key));
extern void java_check_methods PARAMS ((tree));
extern void init_jcf_parse PARAMS((void));
extern void init_src_parse PARAMS((void));
extern int cxx_keyword_p PARAMS ((const char *, int));
extern tree java_mangle_decl PARAMS ((struct obstack *, tree));
......
......@@ -89,7 +89,8 @@ static void handle_innerclass_attribute PARAMS ((int count, JCF *));
static tree give_name_to_class PARAMS ((JCF *jcf, int index));
static void parse_zip_file_entries PARAMS ((void));
static void process_zip_dir PARAMS ((FILE *));
static void parse_source_file PARAMS ((tree, FILE *));
static void parse_source_file_1 PARAMS ((tree, FILE *));
static void parse_source_file_2 PARAMS ((void));
static void jcf_parse_source PARAMS ((void));
static int jcf_figure_file_type PARAMS ((JCF *));
static void parse_class_file PARAMS ((void));
......@@ -641,7 +642,8 @@ jcf_parse_source ()
{
if (!(finput = fopen (input_filename, "r")))
fatal_io_error ("can't reopen %s", input_filename);
parse_source_file (file, finput);
parse_source_file_1 (file, finput);
parse_source_file_2 ();
if (fclose (finput))
fatal_io_error ("can't close %s", input_filename);
}
......@@ -822,7 +824,7 @@ parse_class_file ()
/* Parse a source file, as pointed by the current value of INPUT_FILENAME. */
static void
parse_source_file (file, finput)
parse_source_file_1 (file, finput)
tree file;
FILE *finput;
{
......@@ -853,6 +855,14 @@ parse_source_file (file, finput)
java_parse (); /* Parse and build partial tree nodes. */
java_parse_abort_on_error ();
}
/* Process a parsed source file, resolving names etc. */
static void
parse_source_file_2 ()
{
int save_error_count = java_error_count;
java_complete_class (); /* Parse unsatisfied class decl. */
java_parse_abort_on_error ();
java_check_circular_reference (); /* Check on circular references */
......@@ -876,18 +886,73 @@ predefined_filename_p (node)
int
yyparse ()
{
int several_files = 0;
char *list = xstrdup (input_filename), *next;
int filename_count = 0;
char *list, *next;
tree node;
FILE *finput;
if (flag_filelist_file)
{
int avail = 2000;
finput = fopen (input_filename, "r");
if (finput == NULL)
fatal_io_error ("can't open %s", input_filename);
list = xmalloc(avail);
next = list;
for (;;)
{
int count;
if (avail < 500)
{
count = next - list;
avail = 2 * (count + avail);
list = xrealloc (list, avail);
next = list + count;
avail = avail - count;
}
/* Subtract to to guarantee space for final '\0'. */
count = fread (next, 1, avail - 1, finput);
if (count == 0)
{
if (! feof (finput))
fatal_io_error ("error closing %s", input_filename);
*next = '\0';
break;
}
avail -= count;
next += count;
}
fclose (finput);
}
else
list = xstrdup (input_filename);
do
{
next = strchr (list, '&');
if (next)
for (next = list; ; )
{
*next++ = '\0';
several_files = 1;
char *ch = *next;
if (ch == '\n' || ch == '\r' || ch == '\t' || ch == ' '
|| ch == '&' /* FIXME */)
{
if (next == list)
{
next++;
list = next;
continue;
}
else
{
*next++ = '\0';
break;
}
}
if (ch == '\0')
{
next = NULL;
break;
}
next++;
}
if (list[0])
......@@ -898,12 +963,14 @@ yyparse ()
int len = strlen (list);
if (*list != '/' && several_files)
if (*list != '/' && filename_count > 0)
obstack_grow (&temporary_obstack, "./", 2);
obstack_grow0 (&temporary_obstack, list, len);
value = obstack_finish (&temporary_obstack);
filename_count++;
/* Exclude file that we see twice on the command line. For
all files except {Class,Error,Object,RuntimeException,String,
Throwable}.java we can rely on maybe_get_identifier. For
......@@ -943,6 +1010,9 @@ yyparse ()
}
while (next);
if (filename_count == 0)
warning ("no input file specified");
current_jcf = main_jcf;
current_file_list = nreverse (current_file_list);
for (node = current_file_list; node; node = TREE_CHAIN (node))
......@@ -985,13 +1055,18 @@ yyparse ()
case JCF_SOURCE:
java_push_parser_context ();
java_parser_context_save_global ();
parse_source_file (name, finput);
parse_source_file_1 (name, finput);
java_parser_context_restore_global ();
java_pop_parser_context (1);
break;
}
}
for (ctxp = ctxp_for_generation; ctxp; ctxp = ctxp->next)
{
parse_source_file_2 ();
}
java_expand_classes ();
if (!java_report_errors () && !flag_syntax_only)
emit_register_classes ();
......@@ -1137,4 +1212,6 @@ init_jcf_parse ()
ggc_add_tree_root (parse_roots, sizeof (parse_roots) / sizeof(tree));
ggc_add_root (&current_jcf, 1, sizeof (JCF), (void (*)(void *))ggc_mark_jcf);
init_src_parse ();
}
......@@ -38,6 +38,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#define JAVA_FILE_ARG (1<<3)
/* True if this arg is a .class input file name. */
#define CLASS_FILE_ARG (1<<4)
/* True if this arg is @FILE - where FILE contains a list of filenames. */
#define INDIRECT_FILE_ARG (1<<5)
static char *find_spec_file PARAMS ((const char *));
......@@ -47,11 +49,6 @@ int lang_specific_extra_outfiles = 0;
/* True if we should add -shared-libgcc to the command-line. */
int shared_libgcc = 1;
/* Once we have the proper support in jc1 (and gcc.c) working,
set COMBINE_INPUTS to one. This enables combining multiple *.java
and *.class input files to be passed to a single jc1 invocation. */
#define COMBINE_INPUTS 0
const char jvgenmain_spec[] =
"jvgenmain %{D*} %i %{!pipe:%umain.i} |\n\
cc1 %{!pipe:%Umain.i} %1 \
......@@ -108,7 +105,6 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
link in libgcj. */
int library = 1;
#if COMBINE_INPUTS
/* This will be 1 if multiple input files (.class and/or .java)
should be passed to a single jc1 invocation. */
int combine_inputs = 0;
......@@ -116,21 +112,20 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
/* Index of last .java or .class argument. */
int last_input_index;
/* A buffer containing the concatenation of the inputs files
(e.g. "foo.java&bar.class&baz.class"). if combine_inputs. */
char* combined_inputs_buffer;
/* Next available location in combined_inputs_buffer. */
int combined_inputs_pos;
/* Number of .java and .class source file arguments seen. */
int java_files_count = 0;
int class_files_count = 0;
/* Number of '@FILES' arguments seen. */
int indirect_files_count = 0;
/* Cumulative length of the .java and .class source file names. */
int java_files_length = 0;
int class_files_length = 0;
#endif
/* Name of file containing list of files to compile. */
char *filelist_filename;
FILE *filelist_file;
/* The number of arguments being added to what's in argv, other than
libraries. We use this to track the number of times we've inserted
......@@ -149,6 +144,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
already gave a language for the file. */
int saw_speclang = 0;
#if 0
/* "-lm" or "-lmath" if it appears on the command line. */
const char *saw_math ATTRIBUTE_UNUSED = 0;
......@@ -163,6 +159,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
/* Saw `-lgcj' on command line. */
int saw_libgcj ATTRIBUTE_UNUSED = 0;
#endif
/* Saw -C or -o option, respectively. */
int saw_C = 0;
......@@ -251,9 +248,6 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
{
saw_C = 1;
want_spec_file = 0;
#if COMBINE_INPUTS
combine_inputs = 1;
#endif
if (library != 0)
added -= 2;
library = 0;
......@@ -317,9 +311,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
}
else
{
#if COMBINE_INPUTS
int len;
#endif
if (saw_speclang)
{
......@@ -327,7 +319,12 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
continue;
}
#if COMBINE_INPUTS
if (argv[i][0] == '@')
{
args[i] |= INDIRECT_FILE_ARG;
indirect_files_count++;
}
len = strlen (argv[i]);
if (len > 5 && strcmp (argv[i] + len - 5, ".java") == 0)
{
......@@ -343,7 +340,6 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
class_files_length += len;
last_input_index = i;
}
#endif
}
}
......@@ -357,33 +353,34 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
if (saw_C)
{
num_args += 3;
#if COMBINE_INPUTS
class_files_length = 0;
num_args -= class_files_count;
if (class_files_count > 0)
{
error ("Warning: already-compiled .class files ignored with -C");
class_files_count = 0;
num_args -= class_files_count;
}
num_args += 2; /* For -o NONE. */
#endif
if (saw_o)
fatal ("cannot specify both -C and -o");
}
#if COMBINE_INPUTS
if (saw_o && java_files_count + (saw_C ? 0 : class_files_count) > 1)
combine_inputs = 1;
if (class_files_count > 1)
combine_inputs = 1;
if (combine_inputs)
{
int len = java_files_length + java_files_count - 1;
num_args -= java_files_count;
filelist_filename = make_temp_file ("jx");
if (filelist_filename == NULL)
fatal ("cannot create temporary file");
record_temp_file (filelist_filename, 1, 0);
filelist_file = fopen (filelist_filename, "w");
if (filelist_file == NULL)
pfatal_with_name (filelist_filename);
num_args -= java_files_count + class_files_count;
num_args++; /* Add one for the combined arg. */
if (class_files_length > 0)
{
len += class_files_length + class_files_count - 1;
num_args -= class_files_count;
}
combined_inputs_buffer = (char*) xmalloc (len);
combined_inputs_pos = 0;
}
/* If we know we don't have to do anything, bail now. */
#endif
#if 0
if (! added && ! library && main_class_name == NULL && ! saw_C)
{
......@@ -400,6 +397,11 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
num_args++;
num_args++;
if (combine_inputs || indirect_files_count > 0)
num_args += 2;
if (combine_inputs && indirect_files_count > 0)
fatal("using both @FILE with multiple files not implemented");
/* There's no point adding -shared-libgcc if we don't have a shared
libgcc. */
#ifndef ENABLE_SHARED_LIBGCC
......@@ -409,9 +411,16 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
num_args += shared_libgcc;
arglist = (const char **) xmalloc ((num_args + 1) * sizeof (char *));
j = 0;
for (i = 0, j = 0; i < argc; i++, j++)
for (i = 0; i < argc; i++, j++)
{
if (i == 1 && (combine_inputs || indirect_files_count > 0))
{
arglist[j++] = "-ffilelist-file";
arglist[j++] = "-xjava";
}
arglist[j] = argv[i];
if ((args[i] & PARAM_ARG) || i == 0)
......@@ -449,35 +458,32 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
continue;
}
if ((args[i] & INDIRECT_FILE_ARG) != 0)
{
arglist[j] = argv[i]+1; /* Drop '@'. */
}
if ((args[i] & CLASS_FILE_ARG) && saw_C)
{
--j;
continue;
}
#if COMBINE_INPUTS
if (combine_inputs && (args[i] & (CLASS_FILE_ARG|JAVA_FILE_ARG)) != 0)
{
if (combined_inputs_pos > 0)
combined_inputs_buffer[combined_inputs_pos++] = '&';
strcpy (&combined_inputs_buffer[combined_inputs_pos], argv[i]);
combined_inputs_pos += strlen (argv[i]);
fputs (argv[i], filelist_file);
fputc ('\n', filelist_file);
--j;
continue;
}
#endif
}
#if COMBINE_INPUTS
if (combine_inputs)
{
combined_inputs_buffer[combined_inputs_pos] = '\0';
#if 0
if (! saw_C)
#endif
arglist[j++] = combined_inputs_buffer;
if (fclose (filelist_file))
pfatal_with_name (filelist_filename);
arglist[j++] = filelist_filename;
}
#endif
/* If we saw no -O or -g option, default to -g1, for javac compatibility. */
if (saw_g + saw_O == 0)
......@@ -494,10 +500,8 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
arglist[j++] = "-fsyntax-only";
arglist[j++] = "-femit-class-files";
arglist[j++] = "-S";
#if COMBINE_INPUTS
arglist[j++] = "-o";
arglist[j++] = "NONE";
#endif
}
if (shared_libgcc)
......
......@@ -33,6 +33,7 @@ DEFINE_LANG_NAME ("Java")
{ "-fno-assume-compiled", "" },
{ "-femit-class-file", "" },
{ "-femit-class-files", "Dump class files to <name>.class" },
{ "-ffilelist-file", "input file is list of file names to compile" },
{ "-fuse-boehm-gc", "Generate code for Boehm GC" },
{ "-fhash-synchronization", "Don't put synchronization structure in each object" },
{ "-fjni", "Assume native functions are implemented using JNI" },
......
......@@ -105,6 +105,10 @@ int flag_assume_compiled = 1;
int flag_emit_class_files = 0;
/* Nonzero if input file is a file with a list of filenames to compile. */
int flag_filelist_file = 0;
/* When non zero, we emit xref strings. Values of the flag for xref
backends are defined in xref_flag_table, xref.c. */
......@@ -156,6 +160,7 @@ lang_f_options[] =
{
{"emit-class-file", &flag_emit_class_files, 1},
{"emit-class-files", &flag_emit_class_files, 1},
{"filelist-file", &flag_filelist_file, 1},
{"use-divide-subroutine", &flag_use_divide_subroutine, 1},
{"use-boehm-gc", &flag_use_boehm_gc, 1},
{"hash-synchronization", &flag_hash_synchronization, 1},
......
......@@ -120,7 +120,7 @@ java_init_lex (finput, encoding)
wfl_to_string = build_expr_wfl (get_identifier ("toString"), NULL, 0, 0);
CPC_INITIALIZER_LIST (ctxp) = CPC_STATIC_INITIALIZER_LIST (ctxp) =
CPC_INSTANCE_INITIALIZER_LIST (ctxp) = ctxp->incomplete_class = NULL_TREE;
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));
......
......@@ -348,7 +348,7 @@ static int in_instance_initializer;
struct parser_ctxt *ctxp;
/* List of things that were analyzed for which code will be generated */
static struct parser_ctxt *ctxp_for_generation = NULL;
struct parser_ctxt *ctxp_for_generation = NULL;
/* binop_lookup maps token to tree_code. It is used where binary
operations are involved and required by the parser. RDIV_EXPR
......@@ -411,6 +411,14 @@ static tree current_this;
the list of the catch clauses of the currently analysed try block. */
static tree currently_caught_type_list;
static tree src_parse_roots[2] = { NULL_TREE, NULL_TREE };
/* All classes seen from source code */
#define gclass_list src_parse_roots[0]
/* List of non-complete classes */
#define incomplete_class_list src_parse_roots[1]
/* Check modifiers. If one doesn't fit, retrieve it in its declaration
line and point it out. */
/* Should point out the one that don't fit. ASCII/unicode, going
......@@ -2640,11 +2648,6 @@ void
java_push_parser_context ()
{
create_new_parser_context (0);
if (ctxp->next)
{
ctxp->incomplete_class = ctxp->next->incomplete_class;
ctxp->gclass_list = ctxp->next->gclass_list;
}
}
void
......@@ -2661,8 +2664,6 @@ java_pop_parser_context (generate)
next = ctxp->next;
if (next)
{
next->incomplete_class = ctxp->incomplete_class;
next->gclass_list = ctxp->gclass_list;
lineno = ctxp->lineno;
current_class = ctxp->class_type;
}
......@@ -2776,8 +2777,6 @@ java_parser_context_resume ()
struct parser_ctxt *restored = saver->next; /* This one is the old current */
/* We need to inherit the list of classes to complete/generate */
restored->incomplete_class = old->incomplete_class;
restored->gclass_list = old->gclass_list;
restored->classd_list = old->classd_list;
restored->class_list = old->class_list;
......@@ -3652,7 +3651,7 @@ maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
ctxp->class_list = decl;
/* Create a new nodes in the global lists */
ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
gclass_list = tree_cons (NULL_TREE, decl, gclass_list);
all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
/* Install a new dependency list element */
......@@ -4991,7 +4990,7 @@ obtain_incomplete_type (type_name)
else
abort ();
for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
for (ptr = incomplete_class_list; ptr; ptr = TREE_CHAIN (ptr))
if (TYPE_NAME (ptr) == name)
break;
......@@ -4999,8 +4998,8 @@ obtain_incomplete_type (type_name)
{
BUILD_PTR_FROM_NAME (ptr, name);
layout_type (ptr);
TREE_CHAIN (ptr) = ctxp->incomplete_class;
ctxp->incomplete_class = ptr;
TREE_CHAIN (ptr) = incomplete_class_list;
incomplete_class_list = ptr;
}
return ptr;
......@@ -7285,7 +7284,7 @@ java_reorder_fields ()
initialized_p = 1;
}
for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
for (current = gclass_list; current; current = TREE_CHAIN (current))
{
current_class = TREE_TYPE (TREE_VALUE (current));
......@@ -7315,11 +7314,11 @@ java_reorder_fields ()
}
}
}
stop_reordering = TREE_TYPE (TREE_VALUE (ctxp->gclass_list));
stop_reordering = TREE_TYPE (TREE_VALUE (gclass_list));
}
/* Layout the methods of all classes loaded in one way on an
other. Check methods of source parsed classes. Then reorder the
/* Layout the methods of all classes loaded in one way or another.
Check methods of source parsed classes. Then reorder the
fields and layout the classes or the type of all source parsed
classes */
......@@ -7335,12 +7334,12 @@ java_layout_classes ()
all_class_list = NULL_TREE;
/* Then check the methods of all parsed classes */
for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
for (current = gclass_list; current; current = TREE_CHAIN (current))
if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
java_check_methods (TREE_VALUE (current));
java_parse_abort_on_error ();
for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
for (current = gclass_list; current; current = TREE_CHAIN (current))
{
current_class = TREE_TYPE (TREE_VALUE (current));
layout_class (current_class);
......@@ -15688,8 +15687,6 @@ mark_parser_ctxt (p)
ggc_mark_tree (pc->class_type);
ggc_mark_tree (pc->function_decl);
ggc_mark_tree (pc->package);
ggc_mark_tree (pc->incomplete_class);
ggc_mark_tree (pc->gclass_list);
ggc_mark_tree (pc->class_list);
ggc_mark_tree (pc->current_parsed_class);
ggc_mark_tree (pc->current_parsed_class_un);
......@@ -15705,3 +15702,10 @@ mark_parser_ctxt (p)
if (pc->next)
mark_parser_ctxt (&pc->next);
}
void
init_src_parse ()
{
/* Register roots with the garbage collector. */
ggc_add_tree_root (src_parse_roots, sizeof (src_parse_roots) / sizeof(tree));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment