Commit e4de5a10 by Per Bothner

Merge from Cygnus internal source tree.

From-SVN: r23025
parent 8376a32e
...@@ -148,10 +148,12 @@ ALL_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) $(XCFLAGS) ...@@ -148,10 +148,12 @@ ALL_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) $(XCFLAGS)
# Likewise. # Likewise.
ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS) ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS)
# CYGNUS LOCAL: SUBDIR_USE_ALLOCA is different from FSF.
# Even if ALLOCA is set, don't use it if compiling with GCC. # Even if ALLOCA is set, don't use it if compiling with GCC.
SUBDIR_OBSTACK = `if [ x$(OBSTACK) != x ]; then echo ../$(OBSTACK); else true; fi` SUBDIR_OBSTACK = `if [ x$(OBSTACK) != x ]; then echo ../$(OBSTACK); else true; fi`
SUBDIR_USE_ALLOCA = `case "${CC}" in "${OLDCC}") if [ x$(ALLOCA) != x ]; then echo ../$(ALLOCA); else true; fi ;; esac` #SUBDIR_USE_ALLOCA = `case "${CC}" in "${OLDCC}") if [ x$(ALLOCA) != x ]; then echo ../$(ALLOCA); else true; fi ;; esac`
SUBDIR_USE_ALLOCA = `if [ x$(ALLOCA) != x ]; then echo ../$(ALLOCA); else true; fi`
SUBDIR_MALLOC = `if [ x$(MALLOC) != x ]; then echo ../$(MALLOC); else true; fi` SUBDIR_MALLOC = `if [ x$(MALLOC) != x ]; then echo ../$(MALLOC); else true; fi`
# How to link with both our special library facilities # How to link with both our special library facilities
...@@ -226,19 +228,22 @@ RTL_H = $(srcdir)/../rtl.h $(srcdir)/../rtl.def \ ...@@ -226,19 +228,22 @@ RTL_H = $(srcdir)/../rtl.h $(srcdir)/../rtl.def \
$(srcdir)/../machmode.h $(srcdir)/../machmode.def $(srcdir)/../machmode.h $(srcdir)/../machmode.def
EXPR_H = $(srcdir)/../expr.h ../insn-codes.h EXPR_H = $(srcdir)/../expr.h ../insn-codes.h
# CYGNUS LOCAL: we put these files into the build dir.
PARSE_C = parse.c
PARSE_SCAN_C = parse-scan.c
PARSE_H = $(srcdir)/parse.h PARSE_H = $(srcdir)/parse.h
PARSE_C = $(srcdir)/parse.c
PARSE_SCAN_C = $(srcdir)/parse-scan.c
$(PARSE_C): $(srcdir)/parse.y $(srcdir)/lex.c $(PARSE_H) $(srcdir)/lex.h $(PARSE_C): $(srcdir)/parse.y $(srcdir)/lex.c $(PARSE_H) $(srcdir)/lex.h
$(BISON) -t -v $(BISONFLAGS) $(JAVABISONFLAGS) -o $(PARSE_C) \ $(BISON) -t -v $(BISONFLAGS) $(JAVABISONFLAGS) -o $(PARSE_C) \
$(srcdir)/parse.y $(srcdir)/parse.y
$(PARSE_SCAN_C): $(srcdir)/parse-scan.y $(srcdir)/lex.c $(PARSE_H) \ $(PARSE_SCAN_C): $(srcdir)/parse-scan.y $(srcdir)/lex.c $(PARSE_H) \
$(srcdir)/lex.h $(srcdir)/lex.h
$(BISON) -t -v $(BISONFLAGS) -o $(PARSE_SCAN_C) $(srcdir)/parse-scan.y $(BISON) -t -v $(BISONFLAGS) -o $(PARSE_SCAN_C) $(srcdir)/parse-scan.y
lex.c: keyword.h lex.h lex.c: keyword.h lex.h
lang.o: $(srcdir)/java-tree.def
keyword.h: keyword.gperf keyword.h: keyword.gperf
gperf -L KR-C -F ', 0' -p -t -j1 -i 1 -g -o -N java_keyword -k1,3,$$ \ gperf -L KR-C -F ', 0' -p -t -j1 -i 1 -g -o -N java_keyword -k1,3,$$ \
keyword.gperf > keyword.h keyword.gperf > keyword.h
...@@ -258,8 +263,9 @@ TAGS: force ...@@ -258,8 +263,9 @@ TAGS: force
mostlyclean: mostlyclean:
rm -f *.o rm -f *.o
# CYGNUS LOCAL: Remove these files, as they are in the build dir.
clean: mostlyclean clean: mostlyclean
rm -f parse.c rm -f parse.c parse-scan.c
force: force:
......
...@@ -36,6 +36,9 @@ struct buffer ...@@ -36,6 +36,9 @@ struct buffer
#define NULL_BUFFER { (void*) 0, (void*) 0, (void*) 0 } #define NULL_BUFFER { (void*) 0, (void*) 0, (void*) 0 }
#define BUFFER_INIT(BUFP) \
((BUFP)->data = NULL, (BUFP)->ptr = NULL, (BUFP)->limit = NULL)
#define BUFFER_LENGTH(BUFP) ((BUFP)->ptr - (BUFP)->data) #define BUFFER_LENGTH(BUFP) ((BUFP)->ptr - (BUFP)->data)
#define BUFFER_RESET(BUFP) ((BUFP)->ptr = (BUFP)->data) #define BUFFER_RESET(BUFP) ((BUFP)->ptr = (BUFP)->data)
......
...@@ -161,6 +161,12 @@ method_init_exceptions () ...@@ -161,6 +161,12 @@ method_init_exceptions ()
whole_range.first_child = NULL; whole_range.first_child = NULL;
whole_range.next_sibling = NULL; whole_range.next_sibling = NULL;
cache_range_start = 0xFFFFFF; cache_range_start = 0xFFFFFF;
java_set_exception_lang_code ();
}
void
java_set_exception_lang_code ()
{
set_exception_lang_code (EH_LANG_Java); set_exception_lang_code (EH_LANG_Java);
set_exception_version_code (1); set_exception_version_code (1);
} }
...@@ -183,6 +189,32 @@ expand_start_java_handler (range) ...@@ -183,6 +189,32 @@ expand_start_java_handler (range)
expand_eh_region_start (); expand_eh_region_start ();
} }
tree
prepare_eh_table_type (type)
tree type;
{
tree exp;
/* The "type" (metch_info) in a (Java) exception table is one:
* a) NULL - meaning match any type in a try-finally.
* b) a pointer to a (ccmpiled) class (low-order bit 0).
* c) a pointer to the Utf8Const name of the class, plus one
* (which yields a value with low-order bit 1). */
push_obstacks (&permanent_obstack, &permanent_obstack);
if (type == NULL_TREE)
exp = null_pointer_node;
else if (is_compiled_class (type))
exp = build_class_ref (type);
else
exp = fold (build
(PLUS_EXPR, ptr_type_node,
build_utf8_ref (build_internal_class_name (type)),
size_one_node));
pop_obstacks ();
return exp;
}
/* if there are any handlers for this range, isssue end of range, /* if there are any handlers for this range, isssue end of range,
and then all handler blocks */ and then all handler blocks */
void void
...@@ -193,24 +225,8 @@ expand_end_java_handler (range) ...@@ -193,24 +225,8 @@ expand_end_java_handler (range)
expand_start_all_catch (); expand_start_all_catch ();
for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler)) for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler))
{ {
tree type = TREE_PURPOSE (handler); start_catch_handler (prepare_eh_table_type (TREE_PURPOSE (handler)));
tree exp; /* Push the thrown object on the top of the stack */
/* The "type" (metch_info) in a (Java) exception table is one:
* a) NULL - meaning match any type in a try-finally.
* b) a pointer to a (ccmpiled) class (low-order bit 0).
* c) a pointer to the Utf8Const name of the class, plus one
* (which yields a value with low-order bit 1). */
push_obstacks (&permanent_obstack, &permanent_obstack);
if (type == NULL_TREE)
exp = null_pointer_node;
else if (is_compiled_class (type))
exp = build_class_ref (type);
else
exp = fold (build (PLUS_EXPR, ptr_type_node,
build_utf8_ref (build_internal_class_name (type)),
size_one_node));
pop_obstacks ();
start_catch_handler (exp);
expand_goto (TREE_VALUE (handler)); expand_goto (TREE_VALUE (handler));
} }
expand_end_all_catch (); expand_end_all_catch ();
......
...@@ -460,7 +460,7 @@ java_stack_dup (size, offset) ...@@ -460,7 +460,7 @@ java_stack_dup (size, offset)
} }
} }
/* Calls soft_athrow. Discard the contents of the value stack. */ /* Calls _Jv_Throw. Discard the contents of the value stack. */
tree tree
build_java_athrow (node) build_java_athrow (node)
...@@ -526,15 +526,16 @@ decode_newarray_type (int atype) ...@@ -526,15 +526,16 @@ decode_newarray_type (int atype)
} }
} }
/* Build a call to soft_badarrayindex(), the ArrayIndexOfBoundsException /* Build a call to _Jv_ThrowBadArrayIndex(), the
exception handler. */ ArrayIndexOfBoundsException exception handler. */
static tree static tree
build_java_throw_out_of_bounds_exception () build_java_throw_out_of_bounds_exception (index)
tree index;
{ {
tree node = build (CALL_EXPR, int_type_node, tree node = build (CALL_EXPR, int_type_node,
build_address_of (soft_badarrayindex_node), build_address_of (soft_badarrayindex_node),
NULL_TREE, NULL_TREE ); build_tree_list (NULL_TREE, index), NULL_TREE);
TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */ TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
return (node); return (node);
} }
...@@ -629,7 +630,7 @@ build_java_arrayaccess (array, type, index) ...@@ -629,7 +630,7 @@ build_java_arrayaccess (array, type, index)
if (! integer_zerop (test)) if (! integer_zerop (test))
{ {
throw = build (TRUTH_ANDIF_EXPR, int_type_node, test, throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
build_java_throw_out_of_bounds_exception ()); build_java_throw_out_of_bounds_exception (index));
/* allows expansion within COMPOUND */ /* allows expansion within COMPOUND */
TREE_SIDE_EFFECTS( throw ) = 1; TREE_SIDE_EFFECTS( throw ) = 1;
} }
...@@ -677,7 +678,7 @@ build_java_check_indexed_type (array_node, indexed_type) ...@@ -677,7 +678,7 @@ build_java_check_indexed_type (array_node, indexed_type)
return indexed_type; return indexed_type;
} }
/* newarray triggers a call to soft_newarray. This function should be called /* newarray triggers a call to _Jv_NewArray. This function should be called
with an integer code (the type of array to create) and get from the stack with an integer code (the type of array to create) and get from the stack
the size of the dimmension. */ the size of the dimmension. */
...@@ -706,7 +707,7 @@ build_anewarray (class_type, length) ...@@ -706,7 +707,7 @@ build_anewarray (class_type, length)
tree class_type; tree class_type;
tree length; tree length;
{ {
tree type = build_java_array_type (promote_type (class_type), tree type = build_java_array_type (class_type,
TREE_CODE (length) == INTEGER_CST TREE_CODE (length) == INTEGER_CST
? TREE_INT_CST_LOW (length) ? TREE_INT_CST_LOW (length)
: -1); : -1);
...@@ -719,9 +720,9 @@ build_anewarray (class_type, length) ...@@ -719,9 +720,9 @@ build_anewarray (class_type, length)
NULL_TREE); NULL_TREE);
} }
/* Generates a call to multianewarray. multianewarray expects a class pointer, /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
a number of dimensions and the matching number of dimensions. The argument class pointer, a number of dimensions and the matching number of
list is NULL terminated. */ dimensions. The argument list is NULL terminated. */
void void
expand_java_multianewarray (class_type, ndim) expand_java_multianewarray (class_type, ndim)
...@@ -829,8 +830,8 @@ expand_java_array_length () ...@@ -829,8 +830,8 @@ expand_java_array_length ()
push_value (build_java_arraynull_check (array, length, int_type_node)); push_value (build_java_arraynull_check (array, length, int_type_node));
} }
/* Emit code for the call to soft_monitor{enter,exit}. CALL can be either /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
soft_monitorenter_node or soft_monitorexit_node. */ either soft_monitorenter_node or soft_monitorexit_node. */
tree tree
build_java_monitor (call, object) build_java_monitor (call, object)
...@@ -1147,6 +1148,18 @@ lookup_label (pc) ...@@ -1147,6 +1148,18 @@ lookup_label (pc)
} }
} }
/* Generate a unique name for the purpose of loops and switches
labels, and try-catch-finally blocks label or temporary variables. */
tree
generate_name ()
{
static int l_number = 0;
char buff [20];
sprintf (buff, "$L%d", l_number++);
return get_identifier (buff);
}
tree tree
create_label_decl (name) create_label_decl (name)
tree name; tree name;
...@@ -1175,7 +1188,6 @@ note_label (current_pc, target_pc) ...@@ -1175,7 +1188,6 @@ note_label (current_pc, target_pc)
/* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2, /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
where CONDITION is one of one the compare operators. */ where CONDITION is one of one the compare operators. */
void void
expand_compare (condition, value1, value2, target_pc) expand_compare (condition, value1, value2, target_pc)
enum tree_code condition; enum tree_code condition;
...@@ -1279,7 +1291,14 @@ pop_arguments (arg_types) ...@@ -1279,7 +1291,14 @@ pop_arguments (arg_types)
if (TREE_CODE (arg_types) == TREE_LIST) if (TREE_CODE (arg_types) == TREE_LIST)
{ {
tree tail = pop_arguments (TREE_CHAIN (arg_types)); tree tail = pop_arguments (TREE_CHAIN (arg_types));
return tree_cons (NULL_TREE, pop_value (TREE_VALUE (arg_types)), tail); tree type = TREE_VALUE (arg_types);
tree arg = pop_value (type);
#ifdef PROMOTE_PROTOTYPES
if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
&& INTEGRAL_TYPE_P (type))
arg = convert (integer_type_node, arg);
#endif
return tree_cons (NULL_TREE, arg, tail);
} }
abort (); abort ();
} }
...@@ -1490,17 +1509,6 @@ expand_invoke (opcode, method_ref_index, nargs) ...@@ -1490,17 +1509,6 @@ expand_invoke (opcode, method_ref_index, nargs)
arg_list = pop_arguments (TYPE_ARG_TYPES (method_type)); arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
flush_quick_stack (); flush_quick_stack ();
if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
&& ! inherits_from_p (current_class, self_type))
{ /* FIXME probably not needed for invokespecial if done by NEW. */
/* Ensure self_type is initialized. */
func = build (CALL_EXPR, void_type_node, soft_initclass_node,
build_tree_list (NULL_TREE,
build_class_ref (self_type)),
NULL_TREE);
expand_expr_stmt (func);
}
func = NULL_TREE; func = NULL_TREE;
if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
|| (opcode == OPCODE_invokevirtual || (opcode == OPCODE_invokevirtual
...@@ -1515,9 +1523,9 @@ expand_invoke (opcode, method_ref_index, nargs) ...@@ -1515,9 +1523,9 @@ expand_invoke (opcode, method_ref_index, nargs)
func = build_invokevirtual (dtable, method); func = build_invokevirtual (dtable, method);
else else
{ {
/* We expand invokeinterface here. soft_lookupinterfacemethod () will /* We expand invokeinterface here.
ensure that the selected method exists, is public and not abstract _Jv_LookupInterfaceMethod() will ensure that the selected
nor static. */ method exists, is public and not abstract nor static. */
tree lookup_arg; tree lookup_arg;
...@@ -1543,12 +1551,6 @@ expand_invoke (opcode, method_ref_index, nargs) ...@@ -1543,12 +1551,6 @@ expand_invoke (opcode, method_ref_index, nargs)
call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE); call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1; TREE_SIDE_EFFECTS (call) = 1;
if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial)
{ /* FIXME probably not needed for invokespecial if done by NEW. */
/* Ensure self_type is initialized. */
call = build_class_init (self_type, call);
}
if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE) if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
expand_expr_stmt (call); expand_expr_stmt (call);
else else
...@@ -1600,7 +1602,7 @@ expand_java_field_op (is_static, is_putting, field_ref_index) ...@@ -1600,7 +1602,7 @@ expand_java_field_op (is_static, is_putting, field_ref_index)
if (is_error) if (is_error)
{ {
if (! is_putting) if (! is_putting)
push_value (convert (promote_type (field_type), integer_zero_node)); push_value (convert (field_type, integer_zero_node));
flush_quick_stack (); flush_quick_stack ();
return; return;
} }
...@@ -1610,7 +1612,7 @@ expand_java_field_op (is_static, is_putting, field_ref_index) ...@@ -1610,7 +1612,7 @@ expand_java_field_op (is_static, is_putting, field_ref_index)
this is also needed to avoid circularities in the implementation this is also needed to avoid circularities in the implementation
of these fields in libjava. */ of these fields in libjava. */
if (field_name == TYPE_identifier_node && ! is_putting if (field_name == TYPE_identifier_node && ! is_putting
&& field_type == class_type_node && field_type == class_ptr_type
&& strncmp (self_name, "java.lang.", 10) == 0) && strncmp (self_name, "java.lang.", 10) == 0)
{ {
char *class_name = self_name+10; char *class_name = self_name+10;
...@@ -1693,6 +1695,8 @@ java_lang_expand_expr (exp, target, tmode, modifier) ...@@ -1693,6 +1695,8 @@ java_lang_expand_expr (exp, target, tmode, modifier)
tree type = TREE_TYPE (exp); tree type = TREE_TYPE (exp);
register enum machine_mode mode = TYPE_MODE (type); register enum machine_mode mode = TYPE_MODE (type);
int unsignedp = TREE_UNSIGNED (type); int unsignedp = TREE_UNSIGNED (type);
tree node, current;
int has_finally_p;
switch (TREE_CODE (exp)) switch (TREE_CODE (exp))
{ {
...@@ -1719,6 +1723,61 @@ java_lang_expand_expr (exp, target, tmode, modifier) ...@@ -1719,6 +1723,61 @@ java_lang_expand_expr (exp, target, tmode, modifier)
} }
break; break;
case SWITCH_EXPR:
java_expand_switch (exp);
return const0_rtx;
case TRY_EXPR:
/* We expand a try[-catch][-finally] block */
/* Expand the try block */
expand_eh_region_start ();
expand_expr_stmt (TREE_OPERAND (exp, 0));
expand_start_all_catch ();
has_finally_p = (TREE_OPERAND (exp, 2) ? 1 : 0);
/* Expand all catch clauses (EH handlers) */
for (current = TREE_OPERAND (exp, 1); current;
current = TREE_CHAIN (current))
{
extern rtx return_label;
tree type;
/* If we have a finally, the last exception handler is the
one that is supposed to catch everything. */
if (has_finally_p && !TREE_CHAIN (current))
type = NULL_TREE;
else
{
tree catch = java_get_catch_block (current, has_finally_p);
tree decl = BLOCK_EXPR_DECLS (catch);
type = TREE_TYPE (TREE_TYPE (decl));
}
start_catch_handler (prepare_eh_table_type (type));
expand_expr_stmt (TREE_OPERAND (current, 0));
/* Need to expand a goto to the end of the function here,
but not for the catch everything handler. */
if (type)
{
if (return_label)
emit_jump (return_label);
else
fatal ("No return_label for this function - "
"java_lang_expand_expr");
}
end_catch_handler ();
}
/* Expand the finally block, if any */
if (has_finally_p)
{
tree finally = TREE_OPERAND (exp, 2);
emit_label (label_rtx (FINALLY_EXPR_LABEL (finally)));
expand_expr_stmt (FINALLY_EXPR_BLOCK (finally));
}
expand_end_all_catch ();
break;
default: default:
fatal ("Can't expand '%s' tree - java_lang_expand_expr", fatal ("Can't expand '%s' tree - java_lang_expand_expr",
tree_code_name [TREE_CODE (exp)]); tree_code_name [TREE_CODE (exp)]);
...@@ -1984,6 +2043,15 @@ process_jvm_instruction (PC, byte_ops, length) ...@@ -1984,6 +2043,15 @@ process_jvm_instruction (PC, byte_ops, length)
{ {
char *opname; /* Temporary ??? */ char *opname; /* Temporary ??? */
int oldpc = PC; /* PC at instruction start. */ int oldpc = PC; /* PC at instruction start. */
/* If the instruction is at the beginning of a exception handler,
replace the top of the stack with the thrown object reference */
if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
{
pop_value (ptr_type_node);
push_value (soft_exceptioninfo_call_node);
}
switch (byte_ops[PC++]) switch (byte_ops[PC++])
{ {
#define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \ #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
......
...@@ -408,7 +408,7 @@ get_class_constant (JCF *jcf , int i) ...@@ -408,7 +408,7 @@ get_class_constant (JCF *jcf , int i)
char *name = JPOOL_UTF_DATA (jcf, name_index); char *name = JPOOL_UTF_DATA (jcf, name_index);
int nlength = JPOOL_UTF_LENGTH (jcf, name_index); int nlength = JPOOL_UTF_LENGTH (jcf, name_index);
if (name[0] == '[') /* Handle array "classes". */ if (name[0] == '[') /* Handle array "classes". */
type = parse_signature_string (name, nlength); type = TREE_TYPE (parse_signature_string (name, nlength));
else else
{ {
tree cname = unmangle_classname (name, nlength); tree cname = unmangle_classname (name, nlength);
......
...@@ -32,6 +32,40 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ ...@@ -32,6 +32,40 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "jcf.h" #include "jcf.h"
#include "toplev.h" #include "toplev.h"
/* Table indexed by tree code giving a string containing a character
classifying the tree code. Possibilities are
t, d, s, c, r, <, 1 and 2. See java/java-tree.def for details. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
char java_tree_code_type[] = {
'x',
#include "java-tree.def"
};
#undef DEFTREECODE
/* Table indexed by tree code giving number of expression
operands beyond the fixed part of the node structure.
Not used for types or decls. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
int java_tree_code_length[] = {
0,
#include "java-tree.def"
};
#undef DEFTREECODE
/* Names of tree components.
Used for printing out the tree and error messages. */
#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
char *java_tree_code_name[] = {
"@@dummy",
#include "java-tree.def"
};
#undef DEFTREECODE
int compiling_from_source; int compiling_from_source;
char *language_string = "GNU Java"; char *language_string = "GNU Java";
...@@ -320,6 +354,20 @@ lang_init () ...@@ -320,6 +354,20 @@ lang_init ()
current_jcf = main_jcf; current_jcf = main_jcf;
flag_exceptions = 1; flag_exceptions = 1;
/* Append to Gcc tree node definition arrays */
bcopy (java_tree_code_type,
tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
(int)LAST_JAVA_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE);
bcopy ((char *)java_tree_code_length,
(char *)(tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE),
(LAST_JAVA_TREE_CODE -
(int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
bcopy ((char *)java_tree_code_name,
(char *)(tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE),
(LAST_JAVA_TREE_CODE -
(int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
} }
/* This doesn't do anything on purpose. It's used to satisfy the /* This doesn't do anything on purpose. It's used to satisfy the
......
...@@ -148,22 +148,32 @@ extern tree stabilize_reference PROTO ((tree)); ...@@ -148,22 +148,32 @@ extern tree stabilize_reference PROTO ((tree));
EXPR_WFL_EMIT_LINE_NOTE (node) = 1, node : node) EXPR_WFL_EMIT_LINE_NOTE (node) = 1, node : node)
/* Types classification, according to the JLS, section 4.2 */ /* Types classification, according to the JLS, section 4.2 */
#define JFLOAT_TYPE_P(TYPE) (TREE_CODE ((TYPE)) == REAL_TYPE) #define JFLOAT_TYPE_P(TYPE) (TYPE && TREE_CODE ((TYPE)) == REAL_TYPE)
#define JINTEGRAL_TYPE_P(TYPE) ((TREE_CODE ((TYPE)) == INTEGER_TYPE) \ #define JINTEGRAL_TYPE_P(TYPE) ((TYPE) \
|| (TREE_CODE ((TYPE)) == CHAR_TYPE)) && (TREE_CODE ((TYPE)) == INTEGER_TYPE \
#define JNUMERIC_TYPE_P(TYPE) (JFLOAT_TYPE_P ((TYPE)) \ || TREE_CODE ((TYPE)) == CHAR_TYPE))
|| JINTEGRAL_TYPE_P ((TYPE))) #define JNUMERIC_TYPE_P(TYPE) ((TYPE) \
#define JPRIMITIVE_TYPE_P(TYPE) (JNUMERIC_TYPE_P ((TYPE)) \ && (JFLOAT_TYPE_P ((TYPE)) \
|| (TREE_CODE ((TYPE)) == BOOLEAN_TYPE)) || JINTEGRAL_TYPE_P ((TYPE))))
#define JPRIMITIVE_TYPE_P(TYPE) ((TYPE) \
&& (JNUMERIC_TYPE_P ((TYPE)) \
|| TREE_CODE ((TYPE)) == BOOLEAN_TYPE))
/* Not defined in the LRM */ /* Not defined in the LRM */
#define JSTRING_TYPE_P(TYPE) ((TYPE) == string_type_node || \ #define JSTRING_TYPE_P(TYPE) ((TYPE) \
(TREE_CODE (TYPE) == POINTER_TYPE && \ && ((TYPE) == string_type_node || \
TREE_TYPE (op1_type) == string_type_node)) (TREE_CODE (TYPE) == POINTER_TYPE && \
TREE_TYPE (TYPE) == string_type_node)))
#define JREFERENCE_TYPE_P(TYPE) (TREE_CODE (TYPE) == RECORD_TYPE || \ #define JSTRING_P(NODE) ((NODE) \
(TREE_CODE (TYPE) == POINTER_TYPE && \ && (TREE_CODE (NODE) == STRING_CST \
TREE_CODE (TREE_TYPE (TYPE)) == RECORD_TYPE)) || IS_CRAFTED_STRING_BUFFER_P (NODE) \
|| JSTRING_TYPE_P (TREE_TYPE (NODE))))
#define JREFERENCE_TYPE_P(TYPE) ((TYPE) \
&& (TREE_CODE (TYPE) == RECORD_TYPE \
|| (TREE_CODE (TYPE) == POINTER_TYPE \
&& TREE_CODE (TREE_TYPE (TYPE)) == \
RECORD_TYPE)))
/* Other predicate */ /* Other predicate */
#define DECL_P(NODE) (NODE && (TREE_CODE (NODE) == PARM_DECL \ #define DECL_P(NODE) (NODE && (TREE_CODE (NODE) == PARM_DECL \
...@@ -198,12 +208,12 @@ extern tree stabilize_reference PROTO ((tree)); ...@@ -198,12 +208,12 @@ extern tree stabilize_reference PROTO ((tree));
#define ERROR_VARIABLE_NOT_INITIALIZED(WFL, V) \ #define ERROR_VARIABLE_NOT_INITIALIZED(WFL, V) \
parse_error_context \ parse_error_context \
((WFL), "Variable `%s' may not have been initialized", \ ((WFL), "Variable `%s' may not have been initialized", \
IDENTIFIER_POINTER (V)) IDENTIFIER_POINTER (V))
/* Definition for loop handling. This Java's own definition of a loop /* Definition for loop handling. This is Java's own definition of a
body. See parse.y for documentation. It's valid once you hold a loop body. See parse.y for documentation. It's valid once you hold
loop's body (LOOP_EXPR_BODY) */ a loop's body (LOOP_EXPR_BODY) */
/* The loop main block is the one hold the condition and the loop body */ /* The loop main block is the one hold the condition and the loop body */
#define LOOP_EXPR_BODY_MAIN_BLOCK(NODE) TREE_OPERAND (NODE, 0) #define LOOP_EXPR_BODY_MAIN_BLOCK(NODE) TREE_OPERAND (NODE, 0)
...@@ -252,7 +262,6 @@ extern tree stabilize_reference PROTO ((tree)); ...@@ -252,7 +262,6 @@ extern tree stabilize_reference PROTO ((tree));
} }
#define POP_LOOP() ctxp->current_loop = TREE_CHAIN (ctxp->current_loop) #define POP_LOOP() ctxp->current_loop = TREE_CHAIN (ctxp->current_loop)
/* Invocation modes, as returned by invocation_mode (). */ /* Invocation modes, as returned by invocation_mode (). */
enum { enum {
INVOKE_STATIC, INVOKE_STATIC,
...@@ -414,6 +423,14 @@ static jdeplist *reverse_jdep_list (); ...@@ -414,6 +423,14 @@ static jdeplist *reverse_jdep_list ();
#define COMPLETE_CHECK_OP_0(NODE) COMPLETE_CHECK_OP(NODE, 0) #define COMPLETE_CHECK_OP_0(NODE) COMPLETE_CHECK_OP(NODE, 0)
#define COMPLETE_CHECK_OP_1(NODE) COMPLETE_CHECK_OP(NODE, 1) #define COMPLETE_CHECK_OP_1(NODE) COMPLETE_CHECK_OP(NODE, 1)
/* Building invocations: append(ARG) and StringBuffer(ARG) */
#define BUILD_APPEND(ARG) \
build_method_invocation (wfl_append, \
(ARG ? build_tree_list (NULL, (ARG)): NULL_TREE))
#define BUILD_STRING_BUFFER(ARG) \
build_new_invocation (wfl_string_buffer, \
(ARG ? build_tree_list (NULL, (ARG)) : NULL_TREE))
/* Parser context data structure. */ /* Parser context data structure. */
struct parser_ctxt { struct parser_ctxt {
...@@ -472,7 +489,8 @@ struct parser_ctxt { ...@@ -472,7 +489,8 @@ struct parser_ctxt {
#ifndef JC1_LITE #ifndef JC1_LITE
static char *java_accstring_lookup PROTO ((int)); static char *java_accstring_lookup PROTO ((int));
static void parse_error PROTO ((char *)); static void parse_error PROTO ((char *));
static void redefinition_error PROTO ((char *,tree, tree, tree)); static void classitf_redefinition_error PROTO ((char *,tree, tree, tree));
static void variable_redefinition_error PROTO ((tree, tree, tree, int));
static void check_modifiers PROTO ((char *, int, int)); static void check_modifiers PROTO ((char *, int, int));
static tree create_class PROTO ((int, tree, tree, tree)); static tree create_class PROTO ((int, tree, tree, tree));
static tree create_interface PROTO ((int, tree, tree)); static tree create_interface PROTO ((int, tree, tree));
...@@ -490,6 +508,7 @@ static tree method_header PROTO ((int, tree, tree, tree)); ...@@ -490,6 +508,7 @@ static tree method_header PROTO ((int, tree, tree, tree));
static tree method_declarator PROTO ((tree, tree)); static tree method_declarator PROTO ((tree, tree));
static void parse_error_context VPROTO ((tree cl, char *msg, ...)); static void parse_error_context VPROTO ((tree cl, char *msg, ...));
static void parse_warning_context VPROTO ((tree cl, char *msg, ...)); static void parse_warning_context VPROTO ((tree cl, char *msg, ...));
static tree parse_jdk1_1_error PROTO ((char *));
static void complete_class_report_errors PROTO ((jdep *)); static void complete_class_report_errors PROTO ((jdep *));
static int process_imports PROTO ((void)); static int process_imports PROTO ((void));
static void read_import_dir PROTO ((tree)); static void read_import_dir PROTO ((tree));
...@@ -514,7 +533,9 @@ static tree resolve_and_layout PROTO ((tree, tree)); ...@@ -514,7 +533,9 @@ static tree resolve_and_layout PROTO ((tree, tree));
static tree resolve_no_layout PROTO ((tree, tree)); static tree resolve_no_layout PROTO ((tree, tree));
static int identical_subpath_p PROTO ((tree, tree)); static int identical_subpath_p PROTO ((tree, tree));
static int invocation_mode PROTO ((tree, int)); static int invocation_mode PROTO ((tree, int));
static tree refine_accessible_methods_list PROTO ((int, tree)); static tree find_applicable_accessible_methods_list PROTO ((tree, tree, tree));
static tree find_most_specific_methods_list PROTO ((tree));
static int argument_types_convertible PROTO ((tree, tree));
static tree patch_invoke PROTO ((tree, tree, tree, tree)); static tree patch_invoke PROTO ((tree, tree, tree, tree));
static tree lookup_method_invoke PROTO ((int, tree, tree, tree, tree)); static tree lookup_method_invoke PROTO ((int, tree, tree, tree, tree));
static tree register_incomplete_type PROTO ((int, tree, tree, tree)); static tree register_incomplete_type PROTO ((int, tree, tree, tree));
...@@ -525,10 +546,12 @@ static int unresolved_type_p PROTO ((tree, tree *)); ...@@ -525,10 +546,12 @@ static int unresolved_type_p PROTO ((tree, tree *));
static void create_jdep_list PROTO ((struct parser_ctxt *)); static void create_jdep_list PROTO ((struct parser_ctxt *));
static tree build_expr_block PROTO ((tree, tree)); static tree build_expr_block PROTO ((tree, tree));
static tree enter_block PROTO ((void)); static tree enter_block PROTO ((void));
static tree enter_a_block PROTO ((tree));
static tree exit_block PROTO ((void)); static tree exit_block PROTO ((void));
static tree lookup_name_in_blocks PROTO ((tree)); static tree lookup_name_in_blocks PROTO ((tree));
static void maybe_absorb_scoping_blocks PROTO ((void)); static void maybe_absorb_scoping_blocks PROTO ((void));
static tree build_method_invocation PROTO ((tree, tree)); static tree build_method_invocation PROTO ((tree, tree));
static tree build_new_invocation PROTO ((tree, tree));
static tree build_assignment PROTO ((int, int, tree, tree)); static tree build_assignment PROTO ((int, int, tree, tree));
static tree build_binop PROTO ((enum tree_code, int, tree, tree)); static tree build_binop PROTO ((enum tree_code, int, tree, tree));
static tree patch_assignment PROTO ((tree, tree, tree )); static tree patch_assignment PROTO ((tree, tree, tree ));
...@@ -539,7 +562,11 @@ static tree patch_unaryop PROTO ((tree, tree)); ...@@ -539,7 +562,11 @@ static tree patch_unaryop PROTO ((tree, tree));
static tree build_cast PROTO ((int, tree, tree)); static tree build_cast PROTO ((int, tree, tree));
static tree patch_cast PROTO ((tree, tree, tree)); static tree patch_cast PROTO ((tree, tree, tree));
static int valid_ref_assignconv_cast_p PROTO ((tree, tree, int)); static int valid_ref_assignconv_cast_p PROTO ((tree, tree, int));
static int can_cast_to_p PROTO ((tree, tree)); static int valid_builtin_assignconv_identity_widening_p PROTO ((tree, tree));
static int valid_cast_to_p PROTO ((tree, tree));
static int valid_method_invocation_conversion_p PROTO ((tree, tree));
static tree try_builtin_assignconv PROTO ((tree, tree, tree));
static tree try_reference_assignconv PROTO ((tree, tree));
static tree build_unresolved_array_type PROTO ((tree)); static tree build_unresolved_array_type PROTO ((tree));
static tree build_array_ref PROTO ((int, tree, tree)); static tree build_array_ref PROTO ((int, tree, tree));
static tree patch_array_ref PROTO ((tree, tree, tree)); static tree patch_array_ref PROTO ((tree, tree, tree));
...@@ -565,6 +592,7 @@ static int class_in_current_package PROTO ((tree)); ...@@ -565,6 +592,7 @@ static int class_in_current_package PROTO ((tree));
static tree build_if_else_statement PROTO ((int, tree, tree, tree)); static tree build_if_else_statement PROTO ((int, tree, tree, tree));
static tree patch_if_else_statement PROTO ((tree)); static tree patch_if_else_statement PROTO ((tree));
static tree add_stmt_to_compound PROTO ((tree, tree, tree)); static tree add_stmt_to_compound PROTO ((tree, tree, tree));
static tree add_stmt_to_block PROTO ((tree, tree, tree));
static tree patch_exit_expr PROTO ((tree)); static tree patch_exit_expr PROTO ((tree));
static tree build_labeled_block PROTO ((int, tree, tree)); static tree build_labeled_block PROTO ((int, tree, tree));
static tree generate_labeled_block PROTO (()); static tree generate_labeled_block PROTO (());
...@@ -577,6 +605,14 @@ static tree build_loop_body PROTO ((int, tree, int)); ...@@ -577,6 +605,14 @@ static tree build_loop_body PROTO ((int, tree, int));
static tree complete_loop_body PROTO ((int, tree, tree, int)); static tree complete_loop_body PROTO ((int, tree, tree, int));
static tree build_debugable_stmt PROTO ((int, tree)); static tree build_debugable_stmt PROTO ((int, tree));
static tree complete_for_loop PROTO ((int, tree, tree, tree)); static tree complete_for_loop PROTO ((int, tree, tree, tree));
static tree patch_switch_statement PROTO ((tree));
static tree string_constant_concatenation PROTO ((tree, tree));
static tree build_string_concatenation PROTO ((tree, tree));
static tree patch_string_cst PROTO ((tree));
static tree patch_string PROTO ((tree));
static tree build_jump_to_finally PROTO ((tree, tree, tree, tree));
static tree build_try_statement PROTO ((int, tree, tree, tree));
static tree patch_try_statement PROTO ((tree));
void safe_layout_class PROTO ((tree)); void safe_layout_class PROTO ((tree));
void java_complete_class PROTO ((void)); void java_complete_class PROTO ((void));
...@@ -586,6 +622,8 @@ void java_check_methods PROTO ((void)); ...@@ -586,6 +622,8 @@ void java_check_methods PROTO ((void));
void java_layout_classes PROTO ((void)); void java_layout_classes PROTO ((void));
tree java_method_add_stmt PROTO ((tree, tree)); tree java_method_add_stmt PROTO ((tree, tree));
char *java_get_line_col PROTO ((char *, int, int)); char *java_get_line_col PROTO ((char *, int, int));
void java_expand_switch PROTO ((tree));
tree java_get_catch_block PROTO ((tree, int));
#endif /* JC1_LITE */ #endif /* JC1_LITE */
/* Always in use, no matter what you compile */ /* Always in use, no matter what you compile */
......
...@@ -930,14 +930,14 @@ verify_jvm_instructions (jcf, byte_ops, length) ...@@ -930,14 +930,14 @@ verify_jvm_instructions (jcf, byte_ops, length)
case OPCODE_instanceof: case OPCODE_instanceof:
pop_type (ptr_type_node); pop_type (ptr_type_node);
get_class_constant (current_jcf, IMMEDIATE_u2); get_class_constant (current_jcf, IMMEDIATE_u2);
push_type (integer_type_node); push_type (int_type_node);
break; break;
case OPCODE_tableswitch: case OPCODE_tableswitch:
{ {
jint default_val, low, high; jint default_val, low, high;
pop_type (integer_type_node); pop_type (int_type_node);
while (PC%4) while (PC%4)
{ {
if (byte_ops[PC++]) if (byte_ops[PC++])
...@@ -959,7 +959,7 @@ verify_jvm_instructions (jcf, byte_ops, length) ...@@ -959,7 +959,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
{ {
jint npairs, last, not_registered = 1; jint npairs, last, not_registered = 1;
pop_type (integer_type_node); pop_type (int_type_node);
while (PC%4) while (PC%4)
{ {
if (byte_ops[PC++]) if (byte_ops[PC++])
......
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