�
Merge from Cygnus internal source tree. From-SVN: r23025
This commit is contained in:
parent
8376a32eb1
commit
e4de5a1022
10 changed files with 1787 additions and 562 deletions
|
@ -148,10 +148,12 @@ ALL_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) $(XCFLAGS)
|
|||
# Likewise.
|
||||
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.
|
||||
|
||||
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`
|
||||
|
||||
# How to link with both our special library facilities
|
||||
|
@ -226,19 +228,22 @@ RTL_H = $(srcdir)/../rtl.h $(srcdir)/../rtl.def \
|
|||
$(srcdir)/../machmode.h $(srcdir)/../machmode.def
|
||||
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_C = $(srcdir)/parse.c
|
||||
PARSE_SCAN_C = $(srcdir)/parse-scan.c
|
||||
|
||||
$(PARSE_C): $(srcdir)/parse.y $(srcdir)/lex.c $(PARSE_H) $(srcdir)/lex.h
|
||||
$(BISON) -t -v $(BISONFLAGS) $(JAVABISONFLAGS) -o $(PARSE_C) \
|
||||
$(srcdir)/parse.y
|
||||
$(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
|
||||
|
||||
lex.c: keyword.h lex.h
|
||||
|
||||
lang.o: $(srcdir)/java-tree.def
|
||||
|
||||
keyword.h: keyword.gperf
|
||||
gperf -L KR-C -F ', 0' -p -t -j1 -i 1 -g -o -N java_keyword -k1,3,$$ \
|
||||
keyword.gperf > keyword.h
|
||||
|
@ -258,8 +263,9 @@ TAGS: force
|
|||
mostlyclean:
|
||||
rm -f *.o
|
||||
|
||||
# CYGNUS LOCAL: Remove these files, as they are in the build dir.
|
||||
clean: mostlyclean
|
||||
rm -f parse.c
|
||||
rm -f parse.c parse-scan.c
|
||||
|
||||
force:
|
||||
|
||||
|
|
|
@ -36,6 +36,9 @@ struct buffer
|
|||
|
||||
#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_RESET(BUFP) ((BUFP)->ptr = (BUFP)->data)
|
||||
|
|
|
@ -161,6 +161,12 @@ method_init_exceptions ()
|
|||
whole_range.first_child = NULL;
|
||||
whole_range.next_sibling = NULL;
|
||||
cache_range_start = 0xFFFFFF;
|
||||
java_set_exception_lang_code ();
|
||||
}
|
||||
|
||||
void
|
||||
java_set_exception_lang_code ()
|
||||
{
|
||||
set_exception_lang_code (EH_LANG_Java);
|
||||
set_exception_version_code (1);
|
||||
}
|
||||
|
@ -183,6 +189,32 @@ expand_start_java_handler (range)
|
|||
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,
|
||||
and then all handler blocks */
|
||||
void
|
||||
|
@ -193,24 +225,8 @@ expand_end_java_handler (range)
|
|||
expand_start_all_catch ();
|
||||
for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler))
|
||||
{
|
||||
tree type = TREE_PURPOSE (handler);
|
||||
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 ();
|
||||
start_catch_handler (exp);
|
||||
start_catch_handler (prepare_eh_table_type (TREE_PURPOSE (handler)));
|
||||
/* Push the thrown object on the top of the stack */
|
||||
expand_goto (TREE_VALUE (handler));
|
||||
}
|
||||
expand_end_all_catch ();
|
||||
|
|
142
gcc/java/expr.c
142
gcc/java/expr.c
|
@ -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
|
||||
build_java_athrow (node)
|
||||
|
@ -526,15 +526,16 @@ decode_newarray_type (int atype)
|
|||
}
|
||||
}
|
||||
|
||||
/* Build a call to soft_badarrayindex(), the ArrayIndexOfBoundsException
|
||||
exception handler. */
|
||||
/* Build a call to _Jv_ThrowBadArrayIndex(), the
|
||||
ArrayIndexOfBoundsException exception handler. */
|
||||
|
||||
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,
|
||||
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 */
|
||||
return (node);
|
||||
}
|
||||
|
@ -629,7 +630,7 @@ build_java_arrayaccess (array, type, index)
|
|||
if (! integer_zerop (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 */
|
||||
TREE_SIDE_EFFECTS( throw ) = 1;
|
||||
}
|
||||
|
@ -677,7 +678,7 @@ build_java_check_indexed_type (array_node, 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
|
||||
the size of the dimmension. */
|
||||
|
||||
|
@ -706,7 +707,7 @@ build_anewarray (class_type, length)
|
|||
tree class_type;
|
||||
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_INT_CST_LOW (length)
|
||||
: -1);
|
||||
|
@ -719,9 +720,9 @@ build_anewarray (class_type, length)
|
|||
NULL_TREE);
|
||||
}
|
||||
|
||||
/* Generates a call to multianewarray. multianewarray expects a class pointer,
|
||||
a number of dimensions and the matching number of dimensions. The argument
|
||||
list is NULL terminated. */
|
||||
/* Generates a call to _Jv_NewMultiArray. multianewarray expects a
|
||||
class pointer, a number of dimensions and the matching number of
|
||||
dimensions. The argument list is NULL terminated. */
|
||||
|
||||
void
|
||||
expand_java_multianewarray (class_type, ndim)
|
||||
|
@ -829,8 +830,8 @@ expand_java_array_length ()
|
|||
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
|
||||
soft_monitorenter_node or soft_monitorexit_node. */
|
||||
/* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
|
||||
either soft_monitorenter_node or soft_monitorexit_node. */
|
||||
|
||||
tree
|
||||
build_java_monitor (call, object)
|
||||
|
@ -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
|
||||
create_label_decl (name)
|
||||
tree name;
|
||||
|
@ -1175,7 +1188,6 @@ note_label (current_pc, target_pc)
|
|||
/* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
|
||||
where CONDITION is one of one the compare operators. */
|
||||
|
||||
|
||||
void
|
||||
expand_compare (condition, value1, value2, target_pc)
|
||||
enum tree_code condition;
|
||||
|
@ -1279,7 +1291,14 @@ pop_arguments (arg_types)
|
|||
if (TREE_CODE (arg_types) == TREE_LIST)
|
||||
{
|
||||
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 ();
|
||||
}
|
||||
|
@ -1490,17 +1509,6 @@ expand_invoke (opcode, method_ref_index, nargs)
|
|||
arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
|
||||
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;
|
||||
if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
|
||||
|| (opcode == OPCODE_invokevirtual
|
||||
|
@ -1515,9 +1523,9 @@ expand_invoke (opcode, method_ref_index, nargs)
|
|||
func = build_invokevirtual (dtable, method);
|
||||
else
|
||||
{
|
||||
/* We expand invokeinterface here. soft_lookupinterfacemethod () will
|
||||
ensure that the selected method exists, is public and not abstract
|
||||
nor static. */
|
||||
/* We expand invokeinterface here.
|
||||
_Jv_LookupInterfaceMethod() will ensure that the selected
|
||||
method exists, is public and not abstract nor static. */
|
||||
|
||||
tree lookup_arg;
|
||||
|
||||
|
@ -1543,12 +1551,6 @@ expand_invoke (opcode, method_ref_index, nargs)
|
|||
call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
|
||||
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)
|
||||
expand_expr_stmt (call);
|
||||
else
|
||||
|
@ -1600,7 +1602,7 @@ expand_java_field_op (is_static, is_putting, field_ref_index)
|
|||
if (is_error)
|
||||
{
|
||||
if (! is_putting)
|
||||
push_value (convert (promote_type (field_type), integer_zero_node));
|
||||
push_value (convert (field_type, integer_zero_node));
|
||||
flush_quick_stack ();
|
||||
return;
|
||||
}
|
||||
|
@ -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
|
||||
of these fields in libjava. */
|
||||
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)
|
||||
{
|
||||
char *class_name = self_name+10;
|
||||
|
@ -1693,6 +1695,8 @@ java_lang_expand_expr (exp, target, tmode, modifier)
|
|||
tree type = TREE_TYPE (exp);
|
||||
register enum machine_mode mode = TYPE_MODE (type);
|
||||
int unsignedp = TREE_UNSIGNED (type);
|
||||
tree node, current;
|
||||
int has_finally_p;
|
||||
|
||||
switch (TREE_CODE (exp))
|
||||
{
|
||||
|
@ -1719,6 +1723,61 @@ java_lang_expand_expr (exp, target, tmode, modifier)
|
|||
}
|
||||
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:
|
||||
fatal ("Can't expand '%s' tree - java_lang_expand_expr",
|
||||
tree_code_name [TREE_CODE (exp)]);
|
||||
|
@ -1984,6 +2043,15 @@ process_jvm_instruction (PC, byte_ops, length)
|
|||
{
|
||||
char *opname; /* Temporary ??? */
|
||||
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++])
|
||||
{
|
||||
#define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
|
||||
|
|
|
@ -84,11 +84,21 @@ static JCF_u2 last_access;
|
|||
|
||||
#define ACC_VISIBILITY (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED)
|
||||
|
||||
int seen_fields = 0;
|
||||
/* We keep a linked list of all method names we have seen. This lets
|
||||
us determine if a method name and a field name are in conflict. */
|
||||
struct method_name
|
||||
{
|
||||
unsigned char *name;
|
||||
int length;
|
||||
struct method_name *next;
|
||||
};
|
||||
|
||||
/* List of method names we've seen. */
|
||||
static struct method_name *method_name_list;
|
||||
|
||||
static void print_field_info PROTO ((FILE *, JCF*, int, int, JCF_u2));
|
||||
static void print_method_info PROTO ((FILE *, JCF*, int, int, JCF_u2));
|
||||
static void print_c_decl PROTO ((FILE*, JCF*, int, int, JCF_u2, int));
|
||||
static void print_c_decl PROTO ((FILE*, JCF*, int, int, JCF_u2, int, char *));
|
||||
|
||||
JCF_u2 current_field_name;
|
||||
JCF_u2 current_field_value;
|
||||
|
@ -99,9 +109,15 @@ JCF_u2 current_field_flags;
|
|||
( current_field_name = (NAME), current_field_signature = (SIGNATURE), \
|
||||
current_field_flags = (ACCESS_FLAGS), current_field_value = 0)
|
||||
|
||||
/* We pass over fields twice. The first time we just note the start
|
||||
of the methods. Then we go back and parse the fields for real.
|
||||
This is ugly. */
|
||||
static int field_pass;
|
||||
|
||||
#define HANDLE_END_FIELD() \
|
||||
print_field_info (out, jcf, current_field_name, current_field_signature, \
|
||||
current_field_flags);
|
||||
if (field_pass) print_field_info (out, jcf, current_field_name, \
|
||||
current_field_signature, \
|
||||
current_field_flags);
|
||||
|
||||
#define HANDLE_CONSTANTVALUE(VALUEINDEX) current_field_value = (VALUEINDEX)
|
||||
|
||||
|
@ -242,11 +258,29 @@ generate_access (stream, flags)
|
|||
}
|
||||
}
|
||||
|
||||
/* See if NAME is already the name of a method. */
|
||||
static int
|
||||
name_is_method_p (name, length)
|
||||
unsigned char *name;
|
||||
int length;
|
||||
{
|
||||
struct method_name *p;
|
||||
|
||||
for (p = method_name_list; p != NULL; p = p->next)
|
||||
{
|
||||
if (p->length == length && ! memcmp (p->name, name, length))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
DEFUN(print_field_info, (stream, jcf, name_index, sig_index, flags),
|
||||
FILE *stream AND JCF* jcf
|
||||
AND int name_index AND int sig_index AND JCF_u2 flags)
|
||||
{
|
||||
char *override = NULL;
|
||||
|
||||
if (flags & ACC_FINAL)
|
||||
{
|
||||
if (current_field_value > 0)
|
||||
|
@ -305,12 +339,42 @@ DEFUN(print_field_info, (stream, jcf, name_index, sig_index, flags),
|
|||
|
||||
generate_access (stream, flags);
|
||||
fputs (" ", out);
|
||||
if (flags & ACC_STATIC)
|
||||
if ((flags & ACC_STATIC))
|
||||
fputs ("static ", out);
|
||||
print_c_decl (out, jcf, name_index, sig_index, flags, 0);
|
||||
|
||||
if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
|
||||
{
|
||||
fprintf (stream, "<not a UTF8 constant>");
|
||||
found_error = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char *name = JPOOL_UTF_DATA (jcf, name_index);
|
||||
int length = JPOOL_UTF_LENGTH (jcf, name_index);
|
||||
|
||||
if (name_is_method_p (name, length))
|
||||
{
|
||||
/* This field name matches a method. So override the name
|
||||
with a dummy name. This is yucky, but it isn't clear
|
||||
what else to do. FIXME: if the field is static, then
|
||||
we'll be in real trouble. */
|
||||
if ((flags & ACC_STATIC))
|
||||
{
|
||||
fprintf (stderr, "static field has same name as method\n");
|
||||
found_error = 1;
|
||||
}
|
||||
|
||||
override = (char *) malloc (length + 3);
|
||||
memcpy (override, name, length);
|
||||
strcpy (override + length, "__");
|
||||
}
|
||||
}
|
||||
|
||||
print_c_decl (out, jcf, name_index, sig_index, flags, 0, override);
|
||||
fputs (";\n", out);
|
||||
if (! (flags & ACC_STATIC))
|
||||
seen_fields++;
|
||||
|
||||
if (override)
|
||||
free (override);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -320,6 +384,7 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
|
|||
{
|
||||
unsigned char *str;
|
||||
int length, is_init = 0;
|
||||
char *override = NULL;
|
||||
|
||||
if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
|
||||
fprintf (stream, "<not a UTF8 constant>");
|
||||
|
@ -334,13 +399,33 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
|
|||
else
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct method_name *nn;
|
||||
|
||||
nn = (struct method_name *) malloc (sizeof (struct method_name));
|
||||
nn->name = (char *) malloc (length);
|
||||
memcpy (nn->name, str, length);
|
||||
nn->length = length;
|
||||
nn->next = method_name_list;
|
||||
method_name_list = nn;
|
||||
}
|
||||
|
||||
/* We can't generate a method whose name is a C++ reserved word.
|
||||
For now the only problem has been `delete'; add more here as
|
||||
required. FIXME: we need a better solution than just ignoring
|
||||
the method. */
|
||||
required. We can't just ignore the function, because that will
|
||||
cause incorrect code to be generated if the function is virtual
|
||||
(not only for calls to this function for for other functions
|
||||
after it in the vtbl). So we give it a dummy name instead. */
|
||||
if (! utf8_cmp (str, length, "delete"))
|
||||
return;
|
||||
{
|
||||
/* If the method is static, we can safely skip it. If we don't
|
||||
skip it then we'll have problems since the mangling will be
|
||||
wrong. FIXME. */
|
||||
if ((flags & ACC_STATIC))
|
||||
return;
|
||||
override = "__dummy_delete";
|
||||
}
|
||||
|
||||
generate_access (stream, flags);
|
||||
|
||||
|
@ -353,7 +438,7 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
|
|||
if (! is_init)
|
||||
fputs ("virtual ", out);
|
||||
}
|
||||
print_c_decl (out, jcf, name_index, sig_index, flags, is_init);
|
||||
print_c_decl (out, jcf, name_index, sig_index, flags, is_init, override);
|
||||
|
||||
/* FIXME: it would be nice to decompile small methods here. That
|
||||
would allow for inlining. */
|
||||
|
@ -361,154 +446,185 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
|
|||
fprintf(out, ";\n");
|
||||
}
|
||||
|
||||
/* Print one piece of a signature. Returns pointer to next parseable
|
||||
character on success, NULL on error. */
|
||||
static unsigned char *
|
||||
decode_signature_piece (stream, signature, limit, need_space)
|
||||
FILE *stream;
|
||||
unsigned char *signature, *limit;
|
||||
int *need_space;
|
||||
{
|
||||
char *ctype;
|
||||
|
||||
switch (signature[0])
|
||||
{
|
||||
case '[':
|
||||
for (signature++; (signature < limit
|
||||
&& *signature >= '0'
|
||||
&& *signature <= '9'); signature++)
|
||||
;
|
||||
switch (*signature)
|
||||
{
|
||||
case 'B': ctype = "jbyteArray"; goto printit;
|
||||
case 'C': ctype = "jcharArray"; goto printit;
|
||||
case 'D': ctype = "jdoubleArray"; goto printit;
|
||||
case 'F': ctype = "jfloatArray"; goto printit;
|
||||
case 'I': ctype = "jintArray"; goto printit;
|
||||
case 'S': ctype = "jshortArray"; goto printit;
|
||||
case 'J': ctype = "jlongArray"; goto printit;
|
||||
case 'Z': ctype = "jbooleanArray"; goto printit;
|
||||
case '[': ctype = "jobjectArray"; goto printit;
|
||||
case 'L':
|
||||
/* We have to generate a reference to JArray here,
|
||||
so that our output matches what the compiler
|
||||
does. */
|
||||
++signature;
|
||||
fputs ("JArray<", stream);
|
||||
while (signature < limit && *signature != ';')
|
||||
{
|
||||
int ch = UTF8_GET (signature, limit);
|
||||
if (ch == '/')
|
||||
fputs ("::", stream);
|
||||
else
|
||||
jcf_print_char (stream, ch);
|
||||
}
|
||||
fputs (" *> *", stream);
|
||||
*need_space = 0;
|
||||
++signature;
|
||||
break;
|
||||
default:
|
||||
/* Unparseable signature. */
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case '(':
|
||||
case ')':
|
||||
/* This shouldn't happen. */
|
||||
return NULL;
|
||||
|
||||
case 'B': ctype = "jbyte"; goto printit;
|
||||
case 'C': ctype = "jchar"; goto printit;
|
||||
case 'D': ctype = "jdouble"; goto printit;
|
||||
case 'F': ctype = "jfloat"; goto printit;
|
||||
case 'I': ctype = "jint"; goto printit;
|
||||
case 'J': ctype = "jlong"; goto printit;
|
||||
case 'S': ctype = "jshort"; goto printit;
|
||||
case 'Z': ctype = "jboolean"; goto printit;
|
||||
case 'V': ctype = "void"; goto printit;
|
||||
case 'L':
|
||||
++signature;
|
||||
while (*signature && *signature != ';')
|
||||
{
|
||||
int ch = UTF8_GET (signature, limit);
|
||||
if (ch == '/')
|
||||
fputs ("::", stream);
|
||||
else
|
||||
jcf_print_char (stream, ch);
|
||||
}
|
||||
fputs (" *", stream);
|
||||
if (*signature == ';')
|
||||
signature++;
|
||||
*need_space = 0;
|
||||
break;
|
||||
default:
|
||||
*need_space = 1;
|
||||
jcf_print_char (stream, *signature++);
|
||||
break;
|
||||
printit:
|
||||
signature++;
|
||||
*need_space = 1;
|
||||
fputs (ctype, stream);
|
||||
break;
|
||||
}
|
||||
|
||||
return signature;
|
||||
}
|
||||
|
||||
static void
|
||||
DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, flags, is_init),
|
||||
DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, flags, is_init,
|
||||
name_override),
|
||||
FILE* stream AND JCF* jcf
|
||||
AND int name_index AND int signature_index AND JCF_u2 flags
|
||||
AND int is_init)
|
||||
AND int is_init AND char *name_override)
|
||||
{
|
||||
if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
|
||||
fprintf (stream, "<not a UTF8 constant>");
|
||||
{
|
||||
fprintf (stream, "<not a UTF8 constant>");
|
||||
found_error = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int length = JPOOL_UTF_LENGTH (jcf, signature_index);
|
||||
unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
|
||||
register unsigned char *str = str0;
|
||||
unsigned char *limit = str + length;
|
||||
int j;
|
||||
char *ctype;
|
||||
int need_space = 0;
|
||||
int is_method = str[0] == '(';
|
||||
unsigned char *next;
|
||||
|
||||
if (is_method)
|
||||
/* If printing a method, skip to the return signature and print
|
||||
that first. However, there is no return value if this is a
|
||||
constructor. */
|
||||
if (is_method && ! is_init)
|
||||
{
|
||||
/* Skip to the return signature, and print that first.
|
||||
However, don't do this is we are printing a construtcor.
|
||||
*/
|
||||
if (is_init)
|
||||
while (str < limit)
|
||||
{
|
||||
str = str0 + 1;
|
||||
/* FIXME: Most programmers love Celtic knots because
|
||||
they see their own code in the interconnected loops.
|
||||
That is, this is spaghetti. */
|
||||
goto have_constructor;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (str < limit)
|
||||
{
|
||||
int ch = *str++;
|
||||
if (ch == ')')
|
||||
break;
|
||||
}
|
||||
int ch = *str++;
|
||||
if (ch == ')')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
again:
|
||||
while (str < limit)
|
||||
/* If printing a field or an ordinary method, then print the
|
||||
"return value" now. */
|
||||
if (! is_method || ! is_init)
|
||||
{
|
||||
switch (str[0])
|
||||
next = decode_signature_piece (stream, str, limit, &need_space);
|
||||
if (! next)
|
||||
{
|
||||
case '[':
|
||||
for (str++; str < limit && *str >= '0' && *str <= '9'; str++)
|
||||
;
|
||||
switch (*str)
|
||||
{
|
||||
case 'B': ctype = "jbyteArray"; goto printit;
|
||||
case 'C': ctype = "jcharArray"; goto printit;
|
||||
case 'D': ctype = "jdoubleArray"; goto printit;
|
||||
case 'F': ctype = "jfloatArray"; goto printit;
|
||||
case 'I': ctype = "jintArray"; goto printit;
|
||||
case 'S': ctype = "jshortArray"; goto printit;
|
||||
case 'J': ctype = "jlongArray"; goto printit;
|
||||
case 'Z': ctype = "jbooleanArray"; goto printit;
|
||||
case '[': ctype = "jobjectArray"; goto printit;
|
||||
case 'L':
|
||||
/* We have to generate a reference to JArray here,
|
||||
so that our output matches what the compiler
|
||||
does. */
|
||||
++str;
|
||||
fputs ("JArray<", out);
|
||||
while (str < limit && *str != ';')
|
||||
{
|
||||
int ch = UTF8_GET (str, limit);
|
||||
if (ch == '/')
|
||||
fputs ("::", stream);
|
||||
else
|
||||
jcf_print_char (stream, ch);
|
||||
}
|
||||
fputs (" *> *", out);
|
||||
need_space = 0;
|
||||
++str;
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "unparseable signature `%s'\n", str0);
|
||||
found_error = 1;
|
||||
ctype = "???"; goto printit;
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
fputc (*str++, stream);
|
||||
continue;
|
||||
case ')':
|
||||
fputc (*str++, stream);
|
||||
/* the return signature was printed in the first pass. */
|
||||
fprintf (stderr, "unparseable signature: `%s'\n", str0);
|
||||
found_error = 1;
|
||||
return;
|
||||
case 'B': ctype = "jbyte"; goto printit;
|
||||
case 'C': ctype = "jchar"; goto printit;
|
||||
case 'D': ctype = "jdouble"; goto printit;
|
||||
case 'F': ctype = "jfloat"; goto printit;
|
||||
case 'I': ctype = "jint"; goto printit;
|
||||
case 'J': ctype = "jlong"; goto printit;
|
||||
case 'S': ctype = "jshort"; goto printit;
|
||||
case 'Z': ctype = "jboolean"; goto printit;
|
||||
case 'V': ctype = "void"; goto printit;
|
||||
case 'L':
|
||||
++str;
|
||||
while (*str && *str != ';')
|
||||
{
|
||||
int ch = UTF8_GET (str, limit);
|
||||
if (ch == '/')
|
||||
fputs ("::", stream);
|
||||
else
|
||||
jcf_print_char (stream, ch);
|
||||
}
|
||||
fputs (" *", stream);
|
||||
if (*str == ';')
|
||||
str++;
|
||||
need_space = 0;
|
||||
break;
|
||||
default:
|
||||
need_space = 1;
|
||||
jcf_print_char (stream, *str++);
|
||||
break;
|
||||
printit:
|
||||
str++;
|
||||
need_space = 1;
|
||||
fputs (ctype, stream);
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_method && str < limit && *str != ')')
|
||||
fputs (", ", stream);
|
||||
}
|
||||
have_constructor:
|
||||
if (name_index)
|
||||
|
||||
/* Now print the name of the thing. */
|
||||
if (need_space)
|
||||
fputs (" ", stream);
|
||||
if (name_override)
|
||||
fputs (name_override, stream);
|
||||
else if (name_index)
|
||||
{
|
||||
if (need_space)
|
||||
fprintf (stream, " ");
|
||||
/* Declare constructors specially. */
|
||||
if (is_init)
|
||||
print_base_classname (stream, jcf, jcf->this_class);
|
||||
else
|
||||
print_name (stream, jcf, name_index);
|
||||
}
|
||||
|
||||
if (is_method)
|
||||
{
|
||||
/* Have a method or a constructor. Print signature pieces
|
||||
until done. */
|
||||
fputs (" (", stream);
|
||||
/* Go to beginning, skipping '('. */
|
||||
str = str0 + 1;
|
||||
goto again; /* To handle argument signatures. */
|
||||
while (str < limit && *str != ')')
|
||||
{
|
||||
next = decode_signature_piece (stream, str, limit, &need_space);
|
||||
if (! next)
|
||||
{
|
||||
fprintf (stderr, "unparseable signature: `%s'\n", str0);
|
||||
found_error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (next < limit && *next != ')')
|
||||
fputs (", ", stream);
|
||||
str = next;
|
||||
}
|
||||
|
||||
fputs (")", stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -613,6 +729,7 @@ DEFUN(process_file, (jcf, out),
|
|||
JCF *jcf AND FILE *out)
|
||||
{
|
||||
int code, i;
|
||||
uint32 field_start, method_end;
|
||||
|
||||
current_jcf = main_jcf = jcf;
|
||||
|
||||
|
@ -700,8 +817,22 @@ DEFUN(process_file, (jcf, out),
|
|||
as we see them. We have to list the methods in the same order
|
||||
that they appear in the class file, so that the Java and C++
|
||||
vtables have the same layout. */
|
||||
/* We want to parse the methods first. But we need to find where
|
||||
they start. So first we skip the fields, then parse the
|
||||
methods. Then we parse the fields and skip the methods. FIXME:
|
||||
this is ugly. */
|
||||
field_pass = 0;
|
||||
field_start = JCF_TELL (jcf);
|
||||
jcf_parse_fields (jcf);
|
||||
|
||||
jcf_parse_methods (jcf);
|
||||
method_end = JCF_TELL (jcf);
|
||||
|
||||
field_pass = 1;
|
||||
JCF_SEEK (jcf, field_start);
|
||||
jcf_parse_fields (jcf);
|
||||
JCF_SEEK (jcf, method_end);
|
||||
|
||||
jcf_parse_final_attributes (jcf);
|
||||
|
||||
/* Generate friend decl if we still must. */
|
||||
|
|
|
@ -408,7 +408,7 @@ get_class_constant (JCF *jcf , int i)
|
|||
char *name = JPOOL_UTF_DATA (jcf, name_index);
|
||||
int nlength = JPOOL_UTF_LENGTH (jcf, name_index);
|
||||
if (name[0] == '[') /* Handle array "classes". */
|
||||
type = parse_signature_string (name, nlength);
|
||||
type = TREE_TYPE (parse_signature_string (name, nlength));
|
||||
else
|
||||
{
|
||||
tree cname = unmangle_classname (name, nlength);
|
||||
|
|
1619
gcc/java/jcf-write.c
1619
gcc/java/jcf-write.c
File diff suppressed because it is too large
Load diff
|
@ -32,6 +32,40 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
|||
#include "jcf.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;
|
||||
|
||||
char *language_string = "GNU Java";
|
||||
|
@ -320,6 +354,20 @@ lang_init ()
|
|||
current_jcf = main_jcf;
|
||||
|
||||
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
|
||||
|
|
|
@ -148,22 +148,32 @@ extern tree stabilize_reference PROTO ((tree));
|
|||
EXPR_WFL_EMIT_LINE_NOTE (node) = 1, node : node)
|
||||
|
||||
/* Types classification, according to the JLS, section 4.2 */
|
||||
#define JFLOAT_TYPE_P(TYPE) (TREE_CODE ((TYPE)) == REAL_TYPE)
|
||||
#define JINTEGRAL_TYPE_P(TYPE) ((TREE_CODE ((TYPE)) == INTEGER_TYPE) \
|
||||
|| (TREE_CODE ((TYPE)) == CHAR_TYPE))
|
||||
#define JNUMERIC_TYPE_P(TYPE) (JFLOAT_TYPE_P ((TYPE)) \
|
||||
|| JINTEGRAL_TYPE_P ((TYPE)))
|
||||
#define JPRIMITIVE_TYPE_P(TYPE) (JNUMERIC_TYPE_P ((TYPE)) \
|
||||
|| (TREE_CODE ((TYPE)) == BOOLEAN_TYPE))
|
||||
#define JFLOAT_TYPE_P(TYPE) (TYPE && TREE_CODE ((TYPE)) == REAL_TYPE)
|
||||
#define JINTEGRAL_TYPE_P(TYPE) ((TYPE) \
|
||||
&& (TREE_CODE ((TYPE)) == INTEGER_TYPE \
|
||||
|| TREE_CODE ((TYPE)) == CHAR_TYPE))
|
||||
#define JNUMERIC_TYPE_P(TYPE) ((TYPE) \
|
||||
&& (JFLOAT_TYPE_P ((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 */
|
||||
#define JSTRING_TYPE_P(TYPE) ((TYPE) == string_type_node || \
|
||||
(TREE_CODE (TYPE) == POINTER_TYPE && \
|
||||
TREE_TYPE (op1_type) == string_type_node))
|
||||
#define JSTRING_TYPE_P(TYPE) ((TYPE) \
|
||||
&& ((TYPE) == string_type_node || \
|
||||
(TREE_CODE (TYPE) == POINTER_TYPE && \
|
||||
TREE_TYPE (TYPE) == string_type_node)))
|
||||
#define JSTRING_P(NODE) ((NODE) \
|
||||
&& (TREE_CODE (NODE) == STRING_CST \
|
||||
|| IS_CRAFTED_STRING_BUFFER_P (NODE) \
|
||||
|| JSTRING_TYPE_P (TREE_TYPE (NODE))))
|
||||
|
||||
#define JREFERENCE_TYPE_P(TYPE) (TREE_CODE (TYPE) == RECORD_TYPE || \
|
||||
(TREE_CODE (TYPE) == POINTER_TYPE && \
|
||||
TREE_CODE (TREE_TYPE (TYPE)) == RECORD_TYPE))
|
||||
#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 */
|
||||
#define DECL_P(NODE) (NODE && (TREE_CODE (NODE) == PARM_DECL \
|
||||
|
@ -198,12 +208,12 @@ extern tree stabilize_reference PROTO ((tree));
|
|||
|
||||
#define ERROR_VARIABLE_NOT_INITIALIZED(WFL, V) \
|
||||
parse_error_context \
|
||||
((WFL), "Variable `%s' may not have been initialized", \
|
||||
((WFL), "Variable `%s' may not have been initialized", \
|
||||
IDENTIFIER_POINTER (V))
|
||||
|
||||
/* Definition for loop handling. This Java's own definition of a loop
|
||||
body. See parse.y for documentation. It's valid once you hold a
|
||||
loop's body (LOOP_EXPR_BODY) */
|
||||
/* Definition for loop handling. This is Java's own definition of a
|
||||
loop body. See parse.y for documentation. It's valid once you hold
|
||||
a loop's body (LOOP_EXPR_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)
|
||||
|
@ -252,7 +262,6 @@ extern tree stabilize_reference PROTO ((tree));
|
|||
}
|
||||
#define POP_LOOP() ctxp->current_loop = TREE_CHAIN (ctxp->current_loop)
|
||||
|
||||
|
||||
/* Invocation modes, as returned by invocation_mode (). */
|
||||
enum {
|
||||
INVOKE_STATIC,
|
||||
|
@ -414,6 +423,14 @@ static jdeplist *reverse_jdep_list ();
|
|||
#define COMPLETE_CHECK_OP_0(NODE) COMPLETE_CHECK_OP(NODE, 0)
|
||||
#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. */
|
||||
struct parser_ctxt {
|
||||
|
||||
|
@ -472,7 +489,8 @@ struct parser_ctxt {
|
|||
#ifndef JC1_LITE
|
||||
static char *java_accstring_lookup PROTO ((int));
|
||||
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 tree create_class PROTO ((int, tree, tree, tree));
|
||||
static tree create_interface PROTO ((int, tree, tree));
|
||||
|
@ -490,6 +508,7 @@ static tree method_header PROTO ((int, tree, tree, tree));
|
|||
static tree method_declarator PROTO ((tree, tree));
|
||||
static void parse_error_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 int process_imports PROTO ((void));
|
||||
static void read_import_dir PROTO ((tree));
|
||||
|
@ -514,7 +533,9 @@ static tree resolve_and_layout PROTO ((tree, tree));
|
|||
static tree resolve_no_layout PROTO ((tree, tree));
|
||||
static int identical_subpath_p PROTO ((tree, tree));
|
||||
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 lookup_method_invoke PROTO ((int, tree, 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 *));
|
|||
static void create_jdep_list PROTO ((struct parser_ctxt *));
|
||||
static tree build_expr_block PROTO ((tree, tree));
|
||||
static tree enter_block PROTO ((void));
|
||||
static tree enter_a_block PROTO ((tree));
|
||||
static tree exit_block PROTO ((void));
|
||||
static tree lookup_name_in_blocks PROTO ((tree));
|
||||
static void maybe_absorb_scoping_blocks PROTO ((void));
|
||||
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_binop PROTO ((enum tree_code, int, tree, tree));
|
||||
static tree patch_assignment PROTO ((tree, tree, tree ));
|
||||
|
@ -539,7 +562,11 @@ static tree patch_unaryop PROTO ((tree, tree));
|
|||
static tree build_cast PROTO ((int, tree, tree));
|
||||
static tree patch_cast PROTO ((tree, tree, tree));
|
||||
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_array_ref PROTO ((int, tree, tree));
|
||||
static tree patch_array_ref PROTO ((tree, tree, 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 patch_if_else_statement PROTO ((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 build_labeled_block PROTO ((int, tree, tree));
|
||||
static tree generate_labeled_block PROTO (());
|
||||
|
@ -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 build_debugable_stmt PROTO ((int, 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 java_complete_class PROTO ((void));
|
||||
|
@ -586,6 +622,8 @@ void java_check_methods PROTO ((void));
|
|||
void java_layout_classes PROTO ((void));
|
||||
tree java_method_add_stmt PROTO ((tree, tree));
|
||||
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 */
|
||||
|
||||
/* Always in use, no matter what you compile */
|
||||
|
|
|
@ -930,14 +930,14 @@ verify_jvm_instructions (jcf, byte_ops, length)
|
|||
case OPCODE_instanceof:
|
||||
pop_type (ptr_type_node);
|
||||
get_class_constant (current_jcf, IMMEDIATE_u2);
|
||||
push_type (integer_type_node);
|
||||
push_type (int_type_node);
|
||||
break;
|
||||
|
||||
case OPCODE_tableswitch:
|
||||
{
|
||||
jint default_val, low, high;
|
||||
|
||||
pop_type (integer_type_node);
|
||||
pop_type (int_type_node);
|
||||
while (PC%4)
|
||||
{
|
||||
if (byte_ops[PC++])
|
||||
|
@ -959,7 +959,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
|
|||
{
|
||||
jint npairs, last, not_registered = 1;
|
||||
|
||||
pop_type (integer_type_node);
|
||||
pop_type (int_type_node);
|
||||
while (PC%4)
|
||||
{
|
||||
if (byte_ops[PC++])
|
||||
|
|
Loading…
Add table
Reference in a new issue