diff --git a/gcc/java/java-tree.def b/gcc/java/java-tree.def index a05b92d0aac..2ded69cf002 100644 --- a/gcc/java/java-tree.def +++ b/gcc/java/java-tree.def @@ -1,12 +1,57 @@ /* Shift right, logical. */ -DEFTREECODE (URSHIFT_EXPR, "urshift_expr", "2", 2) +DEFTREECODE (URSHIFT_EXPR, "urshift_expr", '2', 2) /* Return -1, 0, 1 depending on whether the first argument is less, equal, or greater to the second argument. */ -DEFTREECODE (COMPARE_EXPR, "compare_expr", "2", 2) +DEFTREECODE (COMPARE_EXPR, "compare_expr", '2', 2) /* Same as COMPARE_EXPR, but if either value is NaN, the result is -1. */ -DEFTREECODE (COMPARE_L_EXPR, "compare_l_expr", "2", 2) +DEFTREECODE (COMPARE_L_EXPR, "compare_l_expr", '2', 2) /* Same as COMPARE_EXPR, but if either value is NaN, the result is 1. */ -DEFTREECODE (COMPARE_G_EXPR, "compare_g_expr", "2", 2) +DEFTREECODE (COMPARE_G_EXPR, "compare_g_expr", '2', 2) + +/* Unary plus. Operand 0 is the expression the unary plus is applied + to */ +DEFTREECODE (UNARY_PLUS_EXPR, "unary_plus_expr", '1', 1) + +/* New array creation expression. + Operand 0 is the array base type. + Operand 1 is the list of dimension expressions. + Operand 2 is the number of other dimensions of unspecified range. + Once patched, the node will bear the type of the created array. */ +DEFTREECODE (NEW_ARRAY_EXPR, "new_array_expr", 'e', 3) + +/* New class creation expression. + Operand 0 is the name of the class to be created + Operand 1 is the argument list used to select a constructor. + There is no operand 2. That slot is used for the + CALL_EXPR_RTL macro (see preexpand_calls). + The type should be the one of the created class. */ +DEFTREECODE (NEW_CLASS_EXPR, "new_class_expr", 'e', 3) + +/* Defines `this' as an expression. */ +DEFTREECODE (THIS_EXPR, "this", '1', 0) + +/* Case statement expression. + Operand 1 is the case value. */ +DEFTREECODE (CASE_EXPR, "case", '1', 1) + +/* Default statement expression. */ +DEFTREECODE (DEFAULT_EXPR, "default", '1', 0) + +/* Try expression + Operand 0 is the tried block, + Operand 1 contains chained catch nodes + Operand 2 contains the finally clause. */ +DEFTREECODE (TRY_EXPR, "try-catch-finally", 'e', 3) + +/* Catch clause. + Operand 0 is the catch clause block, which contains the declaration of + the catch clause parameter. */ +DEFTREECODE (CATCH_EXPR, "catch", '1', 1) + +/* Finally clause. + Operand 0 is the finally label. + Operand 1 is the finally block. */ +DEFTREECODE (FINALLY_EXPR, "finally", 'e', 2) \ No newline at end of file diff --git a/gcc/java/jcf-dump.c b/gcc/java/jcf-dump.c index 749aa82146f..9e36b457bc3 100644 --- a/gcc/java/jcf-dump.c +++ b/gcc/java/jcf-dump.c @@ -239,6 +239,9 @@ DEFUN(utf8_equal_string, (jcf, index, value), MAX_STACK, MAX_LOCALS, CODE_LENGTH); \ disassemble_method (jcf, jcf->read_ptr, CODE_LENGTH); } +#define HANDLE_EXCEPTION_TABLE(ENTRIES, COUNT) \ + print_exception_table (jcf, ENTRIES, COUNT) + #define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \ { int n = (COUNT); int i; \ COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length); \ @@ -286,7 +289,6 @@ DEFUN(utf8_equal_string, (jcf, index, value), fprintf (out, "\nAttributes (count: %d):\n", attributes_count); #include "javaop.h" -#include "jcf-reader.c" static void DEFUN(print_constant_ref, (stream, jcf, index), @@ -336,7 +338,9 @@ void DEFUN(print_constant_terse, (out, jcf, index, expected), FILE *out AND JCF *jcf AND int index AND int expected) { - if (JPOOL_TAG (jcf, index) != expected) + if (! CPOOL_INDEX_IN_RANGE (&jcf->cpool, index)) + fprintf (out, "", index); + else if (JPOOL_TAG (jcf, index) != expected) { fprintf (out, " 0) + { + unsigned char *ptr = entries; + fprintf (out, "Exceptions (count: %d):\n", i); + for (; --i >= 0; ptr+= 8) + { + int start_pc = GET_u2 (ptr); + int end_pc = GET_u2 (ptr+2); + int handler_pc = GET_u2 (ptr+4); + int catch_type = GET_u2 (ptr+6); + fprintf (out, " start: %d, end: %d, handler: %d, type: %d", + start_pc, end_pc, handler_pc, catch_type); + if (catch_type == 0) + fputs (" /* finally */", out); + else + { + fputc('=', out); + print_constant_terse (out, jcf, catch_type, CONSTANT_Class); + } + fputc ('\n', out); + } + } +} + +#include "jcf-reader.c" + int DEFUN (usage, (), ) { @@ -876,6 +913,7 @@ DEFUN(disassemble_method, (jcf, byte_ops, len), #undef PTR int PC; int i; + int saw_wide = 0; if (flag_disassemble_methods == 0) return; #define BCODE byte_ops @@ -923,9 +961,7 @@ DEFUN(disassemble_method, (jcf, byte_ops, len), /* Print out operand (a local variable index) for LOAD opcodes. These all push local variable onto the opcode stack. */ #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \ - INT_temp = (OPERAND_VALUE); \ - if (oldpc+1 == PC) /* nothing - local index implied by opcode */; \ - else fprintf (out, " %d", INT_temp); + INT_temp = saw_wide ? IMMEDIATE_u2 : (OPERAND_VALUE); goto load_store; /* Handle STORE opcodes same as LOAD opcodes. These all store a value from the opcode stack in a local variable. */ @@ -994,7 +1030,8 @@ DEFUN(disassemble_method, (jcf, byte_ops, len), fprintf (out, " %d", saw_index ? INT_temp : oldpc + INT_temp) #define RET(OPERAND_TYPE, OPERAND_VALUE) \ - INT_temp = (OPERAND_VALUE); \ + INT_temp = saw_wide ? IMMEDIATE_u2 : (OPERAND_VALUE); \ + saw_wide = 0; \ fprintf (out, " %d", INT_temp); #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \ @@ -1022,11 +1059,14 @@ DEFUN(disassemble_method, (jcf, byte_ops, len), SPECIAL_##OPERAND_VALUE(OPERAND_TYPE) #define SPECIAL_IINC(OPERAND_TYPE) \ - INT_temp = IMMEDIATE_u1; \ - fprintf (out, "%d %d", INT_temp, IMMEDIATE_s1) + INT_temp = saw_wide ? IMMEDIATE_u2 : IMMEDIATE_u1; \ + fprintf (out, " %d", INT_temp); \ + INT_temp = saw_wide ? IMMEDIATE_s2 : IMMEDIATE_s1; \ + saw_wide = 0; \ + fprintf (out, " %d", INT_temp) #define SPECIAL_WIDE(OPERAND_TYPE) \ - INT_temp = IMMEDIATE_u1; fprintf (out, "%d", INT_temp) + saw_wide = 1; #define SPECIAL_EXIT(OPERAND_TYPE) /* nothing */ #define SPECIAL_ENTER(OPERAND_TYPE) /* nothing */ @@ -1040,33 +1080,19 @@ DEFUN(disassemble_method, (jcf, byte_ops, len), TEST(OPERAND_TYPE, OPERAND_VALUE) #include "javaop.def" + + load_store: + if (oldpc+1 == PC) /* nothing - local index implied by opcode */; + else + { + saw_wide = 0; + fprintf (out, " %d", INT_temp); + } + fputc ('\n', out); + break; + default: fprintf (out, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]); } } - - /* Print exception table. */ - i = GET_u2(byte_ops+len); - if (i > 0) - { - unsigned char *ptr = byte_ops+len+2; - fprintf (out, "Exceptions (count: %d):\n", i); - for (; --i >= 0; ptr+= 8) - { - int start_pc = GET_u2 (ptr); - int end_pc = GET_u2 (ptr+2); - int handler_pc = GET_u2 (ptr+4); - int catch_type = GET_u2 (ptr+6); - fprintf (out, " start: %d, end: %d, handler: %d, type: %d", - start_pc, end_pc, handler_pc, catch_type); - if (catch_type == 0) - fputs (" /* finally */", out); - else - { - fputc('=', out); - print_constant_terse (out, jcf, catch_type, CONSTANT_Class); - } - fputc ('\n', out); - } - } } diff --git a/gcc/java/jcf-reader.c b/gcc/java/jcf-reader.c index cf5c0427789..9816ce329c8 100644 --- a/gcc/java/jcf-reader.c +++ b/gcc/java/jcf-reader.c @@ -83,6 +83,9 @@ DEFUN(get_attribute, (jcf), exception_table_length = JCF_readu2 (jcf); if (code_length + 8 * exception_table_length + 12 > attribute_length) return -1; +#ifdef HANDLE_EXCEPTION_TABLE + HANDLE_EXCEPTION_TABLE (jcf->read_ptr, exception_table_length); +#endif JCF_SKIP (jcf, 2 * 4 * exception_table_length); attributes_count = JCF_readu2 (jcf); for (j = 0; j < attributes_count; j++) diff --git a/gcc/java/jvspec.c b/gcc/java/jvspec.c index 5f9381167d8..7b86b135664 100644 --- a/gcc/java/jvspec.c +++ b/gcc/java/jvspec.c @@ -60,15 +60,15 @@ char *main_class_name = NULL; int lang_specific_extra_outfiles = 0; char jvgenmain_spec[] = - "jvgenmain %i %{!pipe:%g.i} |\n\ - cc1 %{!pipe:%g.i} %1 \ + "jvgenmain %i %{!pipe:%u.i} |\n\ + cc1 %{!pipe:%U.i} %1 \ %{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a*}\ %{g*} %{O*} \ %{v:-version} %{pg:-p} %{p} %{f*}\ %{aux-info*}\ %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %a %Y -o %w%b%O %{!pipe:%g.s} %A\n }"; + %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%U.s}} |\n\ + %{!S:as %a %Y -o %d%w%u%O %{!pipe:%U.s} %A\n }"; void lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) @@ -141,6 +141,9 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) /* The total number of arguments with the new stuff. */ int num_args = 1; + /* Non-zero if linking is supposed to happen. */ + int will_link = 1; + argc = *in_argc; argv = *in_argv; added_libraries = *in_added_libraries; @@ -210,14 +213,18 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) && (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL) || strcmp (argv[i], "-Tdata") == 0)) quote = argv[i]; - else if (library != 0 && ((argv[i][2] == '\0' - && (char *) strchr ("cSEM", argv[i][1]) != NULL) - || strcmp (argv[i], "-MM") == 0)) + else if (library != 0 + && ((argv[i][2] == '\0' + && (char *) strchr ("cSEM", argv[i][1]) != NULL) + || strcmp (argv[i], "-MM") == 0)) { /* Don't specify libraries if we won't link, since that would cause a warning. */ library = 0; added -= 2; + + /* Remember this so we can confirm -fmain option. */ + will_link = 0; } else /* Pass other options through. */ @@ -270,6 +277,8 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) if (strncmp (argv[i], "-fmain=", 7) == 0) { + if (! will_link) + (*fn) ("cannot specify `main' class when not linking"); --j; continue; } diff --git a/gcc/java/lang-options.h b/gcc/java/lang-options.h index f421e6a16c7..c08510577dd 100644 --- a/gcc/java/lang-options.h +++ b/gcc/java/lang-options.h @@ -25,6 +25,9 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ /* This is the contribution to the `lang_options' array in gcc.c for java. */ +/* CYGNUS LOCAL - the format of this file has been changed to + allow cc1 to implement --help. nickc/--help */ + DEFINE_LANG_NAME ("Java") { "-fbounds-check", "" }, diff --git a/gcc/java/lex.c b/gcc/java/lex.c index 50999654766..a54688b7f44 100644 --- a/gcc/java/lex.c +++ b/gcc/java/lex.c @@ -51,6 +51,10 @@ Addison Wesley 1996" (http://java.sun.com/docs/books/jls/html/3.doc.html) */ #include #endif +#ifndef JC1_LITE +extern struct obstack *expression_obstack; +#endif + void java_init_lex () { @@ -71,6 +75,13 @@ java_init_lex () wfl_operator = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0); if (!label_id) label_id = get_identifier ("$L"); + if (!wfl_append) + wfl_append = build_expr_wfl (get_identifier ("append"), NULL, 0, 0); + if (!wfl_string_buffer) + wfl_string_buffer = + build_expr_wfl (get_identifier ("java.lang.StringBuffer"), NULL, 0, 0); + if (!wfl_to_string) + wfl_to_string = build_expr_wfl (get_identifier ("toString"), NULL, 0, 0); ctxp->static_initialized = ctxp->non_static_initialized = ctxp->incomplete_class = NULL_TREE; @@ -885,27 +896,20 @@ java_lex (java_lval) obstack_1grow (&temporary_obstack, '\0'); string = obstack_finish (&temporary_obstack); - if (!no_error || (c != '"')) - *string = '\0'; /* Silently turns the string to an empty one */ - - JAVA_LEX_STR_LIT (string) - #ifndef JC1_LITE - if (*string) + if (!no_error || (c != '"')) + java_lval->node = error_mark_node; /* Requires futher testing FIXME */ + else { - extern struct obstack *expression_obstack; tree s = make_node (STRING_CST); TREE_STRING_LENGTH (s) = strlen (string); TREE_STRING_POINTER (s) = - obstack_alloc (expression_obstack, strlen (string)); + obstack_alloc (expression_obstack, TREE_STRING_LENGTH (s)+1); strcpy (TREE_STRING_POINTER (s), string); java_lval->node = s; } - else - java_lval->node = error_mark_node; #endif return STRING_LIT_TK; - } /* Separator */ @@ -1194,12 +1198,17 @@ java_lex (java_lval) SET_LVAL_NODE (null_pointer_node); return NULL_TK; - /* We build an operator for SUPER, so we can keep its position */ + /* Some keyword we want to retain information on the location + they where found */ + case CASE_TK: + case DEFAULT_TK: case SUPER_TK: case THIS_TK: case RETURN_TK: case BREAK_TK: case CONTINUE_TK: + case TRY_TK: + case CATCH_TK: BUILD_OPERATOR (kw->token); default: diff --git a/gcc/java/typeck.c b/gcc/java/typeck.c index b388ff7b44d..08acf126497 100644 --- a/gcc/java/typeck.c +++ b/gcc/java/typeck.c @@ -135,14 +135,6 @@ type_for_mode (mode, unsignedp) if (mode == TYPE_MODE (double_type_node)) return double_type_node; -#if 0 - if (mode == TYPE_MODE (build_pointer_type (char_type_node))) - return build_pointer_type (char_type_node); - - if (mode == TYPE_MODE (build_pointer_type (integer_type_node))) - return build_pointer_type (integer_type_node); -#endif - return 0; } @@ -331,9 +323,9 @@ build_java_array_type (element_type, length) buf, 0, 0, ""); t = IDENTIFIER_SIGNATURE_TYPE (sig); if (t != NULL_TREE) - return t; + return TREE_TYPE (t); t = make_class (); - IDENTIFIER_SIGNATURE_TYPE (sig) = t; + IDENTIFIER_SIGNATURE_TYPE (sig) = build_pointer_type (t); TYPE_ARRAY_P (t) = 1; if (TREE_CODE (el_name) == POINTER_TYPE) @@ -345,6 +337,8 @@ build_java_array_type (element_type, length) set_java_signature (t, sig); set_super_info (0, t, object_type_node, 0); + if (TREE_CODE (element_type) == RECORD_TYPE) + element_type = promote_type (element_type); TYPE_ARRAY_ELEMENT (t) = element_type; /* Add length pseudo-field. */ @@ -411,6 +405,7 @@ static tree parse_signature_type (ptr, limit) const unsigned char **ptr, *limit; { + tree type; if ((*ptr) >= limit) fatal ("bad signature string"); switch (*(*ptr)) @@ -426,12 +421,9 @@ parse_signature_type (ptr, limit) case 'V': (*ptr)++; return void_type_node; case '[': for ((*ptr)++; (*ptr) < limit && isdigit (**ptr); ) (*ptr)++; - { - tree element_type = parse_signature_type (ptr, limit); - if (TREE_CODE (element_type) == RECORD_TYPE) - element_type = promote_type (element_type); - return build_java_array_type (element_type, -1); - } + type = parse_signature_type (ptr, limit); + type = build_java_array_type (type, -1); + break; case 'L': { const unsigned char *start = ++(*ptr); @@ -444,11 +436,13 @@ parse_signature_type (ptr, limit) break; } *ptr = str+1; - return lookup_class (unmangle_classname (start, str - start)); + type = lookup_class (unmangle_classname (start, str - start)); + break; } default: fatal ("unrecognized signature string"); } + return promote_type (type); } /* Parse a Java "mangled" signature string, starting at SIG_STRING, @@ -471,12 +465,12 @@ parse_signature_string (sig_string, sig_length) str++; while (str < limit && str[0] != ')') { - tree argtype = promote_type (parse_signature_type (&str, limit)); + tree argtype = parse_signature_type (&str, limit); argtype_list = tree_cons (NULL_TREE, argtype, argtype_list); } if (str++, str >= limit) fatal ("bad signature string"); - result_type = promote_type (parse_signature_type (&str, limit)); + result_type = parse_signature_type (&str, limit); result_type = build_function_type (result_type, nreverse (argtype_list)); } @@ -700,32 +694,6 @@ lookup_java_method (clas, method_name, method_signature) return NULL_TREE; } -/* Search in class CLAS (and its superclasses) for methods matching - METHOD_NAME and METHOD_SIGNATURE. Return a list of FUNCTION_DECLs. - When called from here, build_java_signature doesn't take the - returned type into account. */ - -tree -match_java_method (clas, method_name, method_signature) - tree clas, method_name, method_signature; -{ - tree method; - tree list = NULL_TREE; - while (clas != NULL_TREE) - { - for (method = TYPE_METHODS (clas); - method != NULL_TREE; method = TREE_CHAIN (method)) - { - tree method_sig = build_java_argument_signature (TREE_TYPE (method)); - if (DECL_NAME (method) == method_name - && method_sig == method_signature) - list = tree_cons (NULL_TREE, method, list); - } - clas = CLASSTYPE_SUPER (clas); - } - return list; -} - /* Search in class CLAS for a constructor matching METHOD_SIGNATURE. Return a FUNCTION_DECL on success, or NULL_TREE if none found. */