/* 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
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); \
fprintf (out, "\nAttributes (count: %d):\n", attributes_count);
#include "javaop.h"
-#include "jcf-reader.c"
static void
DEFUN(print_constant_ref, (stream, jcf, index),
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, "<constant pool index %d not in range>", index);
+ else if (JPOOL_TAG (jcf, index) != expected)
{
fprintf (out, "<Unexpected constant type ");
print_constant (out, jcf, index, 1);
}
}
+
+static void
+DEFUN(print_exception_table, (jcf, entries, count),
+ JCF *jcf AND unsigned char *entries AND int count)
+{
+ /* Print exception table. */
+ int i = count;
+ if (i > 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, (), )
{
#undef PTR
int PC;
int i;
+ int saw_wide = 0;
if (flag_disassemble_methods == 0)
return;
#define BCODE byte_ops
/* 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. */
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) \
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 */
TEST(OPERAND_TYPE, OPERAND_VALUE)
#include "javaop.def"
- 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);
+ load_store:
+ if (oldpc+1 == PC) /* nothing - local index implied by opcode */;
else
{
- fputc('=', out);
- print_constant_terse (out, jcf, catch_type, CONSTANT_Class);
+ saw_wide = 0;
+ fprintf (out, " %d", INT_temp);
}
fputc ('\n', out);
+ break;
+
+ default:
+ fprintf (out, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
}
}
}
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++)
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)
/* 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;
&& (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. */
if (strncmp (argv[i], "-fmain=", 7) == 0)
{
+ if (! will_link)
+ (*fn) ("cannot specify `main' class when not linking");
--j;
continue;
}
/* 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", "" },
#include <unistd.h>
#endif
+#ifndef JC1_LITE
+extern struct obstack *expression_obstack;
+#endif
+
void
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;
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 */
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:
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;
}
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)
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. */
parse_signature_type (ptr, limit)
const unsigned char **ptr, *limit;
{
+ tree type;
if ((*ptr) >= limit)
fatal ("bad signature string");
switch (*(*ptr))
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);
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,
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));
}
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. */