+2000-08-10 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (maybe_layout_super_class): Fixed indentation.
+ * java-tree.h (CLASS_METHOD_CHECKED_P): New macro.
+ (java_check_methods): New function declaration.
+ * jcf-parse.c (get_constant): Let `char_len' go up to 3. Use `str'
+ instead of `str_ptr'.
+ * jcf-write.c (generate_bytecode_insns): Emit number the of args
+ of a `invokeinterface' at the right time.
+ * parse.h (WFL_STRIP_BRACKET): New macro.
+ (SET_TYPE_FOR_RESOLUTION): Use it.
+ * parse.y (build_unresolved_array_type): Reuse `type_or_wfl.'
+ (check_class_interface_creation): Don't check for cross package
+ innerclass name clashes.
+ (method_header): Behave properly if MDECL is `error_mark_node.'
+ (method_declarator): Return `error_mark_node' if bogus current
+ class.
+ (resolve_class): Apply WFL_STRIP_BRACKET on `cl' if necessary.
+ (resolve_and_layout): New local `decl_type', set and used. Call
+ java_check_methods.
+ (java_check_methods): New method.
+ (java_layout_classes): Use it.
+ (resolve_qualified_expression_name): No EH check necessary in
+ access$<n>.
+ (java_complete_lhs): Use VAR_DECL's DECL_INITIAL when evaluating
+ `case' statement.
+ (patch_assignment): Set DECL_INITIAL on integral final local.
+
2000-08-07 Alexandre Petit-Bianco <apbianco@cygnus.com
* parse.y (build_dot_class_method_invocation): Changed parameter
java.lang.Object. */
#define SET_TYPE_FOR_RESOLUTION(TYPE, SAVE, CHAIN) \
{ \
- tree returned_type; \
+ tree _returned_type; \
(CHAIN) = 0; \
if (TREE_TYPE (GET_CPC ()) == object_type_node \
- && TREE_CODE (TYPE) == EXPR_WITH_FILE_LOCATION \
+ && TREE_CODE (TYPE) == EXPR_WITH_FILE_LOCATION \
&& EXPR_WFL_NODE (TYPE) == unqualified_object_id_node) \
(TYPE) = object_type_node; \
else \
{ \
- if (unresolved_type_p (type, &returned_type)) \
+ if (unresolved_type_p (type, &_returned_type)) \
{ \
- if (returned_type) \
- (TYPE) = returned_type; \
+ if (_returned_type) \
+ (TYPE) = _returned_type; \
else \
{ \
- (SAVE) = (TYPE); \
+ tree _type; \
+ WFL_STRIP_BRACKET (_type, TYPE); \
+ (SAVE) = (_type); \
(TYPE) = obtain_incomplete_type (TYPE); \
CHAIN = 1; \
} \
} \
} \
}
+
+#define WFL_STRIP_BRACKET(TARGET, TYPE) \
+{ \
+ tree __type = (TYPE); \
+ if (TYPE && TREE_CODE (TYPE) == EXPR_WITH_FILE_LOCATION) \
+ { \
+ tree _node = EXPR_WFL_NODE (TYPE); \
+ const char *_ptr = IDENTIFIER_POINTER (_node); \
+ const char *_ref = _ptr; \
+ while (_ptr[0] == '[') \
+ _ptr++; \
+ if (_ref != _ptr) \
+ { \
+ tree _new = copy_node (TYPE); \
+ EXPR_WFL_NODE (_new) = get_identifier (_ptr); \
+ __type = _new; \
+ } \
+ } \
+ (TARGET) = __type; \
+}
+
/* Promote a type if it won't be registered as a patch */
#define PROMOTE_RECORD_IF_COMPLETE(TYPE, IS_INCOMPLETE) \
{ \
IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
ptr = obstack_finish (&temporary_obstack);
- return build_expr_wfl (get_identifier (ptr),
- EXPR_WFL_FILENAME (type_or_wfl),
- EXPR_WFL_LINENO (type_or_wfl),
- EXPR_WFL_COLNO (type_or_wfl));
+ EXPR_WFL_NODE (type_or_wfl) = get_identifier (ptr);
+ return type_or_wfl;
}
static void
- Can't be imported by a single type import
- Can't already exists in the package */
if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
- && (node = find_name_in_single_imports (raw_name)))
+ && (node = find_name_in_single_imports (raw_name))
+ && !CPC_INNER_P ())
{
parse_error_context
(cl, "%s name `%s' clashes with imported type `%s'",
int flags;
tree type, mdecl, throws;
{
- tree meth = TREE_VALUE (mdecl);
- tree id = TREE_PURPOSE (mdecl);
tree type_wfl = NULL_TREE;
tree meth_name = NULL_TREE;
tree current, orig_arg, this_class = NULL;
+ tree id, meth;
int saved_lineno;
int constructor_ok = 0, must_chain;
int count;
+
+ if (mdecl == error_mark_node)
+ return error_mark_node;
+ meth = TREE_VALUE (mdecl);
+ id = TREE_PURPOSE (mdecl);
check_modifiers_consistency (flags);
patch_stage = JDEP_NO_PATCH;
+ if (GET_CPC () == error_mark_node)
+ return error_mark_node;
+
/* If we're dealing with an inner class constructor, we hide the
this$<n> decl in the name field of its parameter declaration. We
also might have to hide the outer context local alias
while (name[0] == '[')
name++;
if (base != name)
- TYPE_NAME (class_type) = get_identifier (name);
+ {
+ TYPE_NAME (class_type) = get_identifier (name);
+ WFL_STRIP_BRACKET (cl, cl);
+ }
/* 2- Resolve the bare type */
if (!(resolved_type_decl = do_resolve_class (enclosing, class_type,
tree something;
tree cl;
{
- tree decl;
+ tree decl, decl_type;
/* Don't do that on the current class */
if (something == current_class)
return NULL_TREE;
/* Resolve and layout if necessary */
- layout_class_methods (TREE_TYPE (decl));
- /* Check methods, but only once */
- if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl))
- && !CLASS_LOADED_P (TREE_TYPE (decl)))
- CHECK_METHODS (decl);
- if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl)))
- safe_layout_class (TREE_TYPE (decl));
+ decl_type = TREE_TYPE (decl);
+ layout_class_methods (decl_type);
+ /* Check methods */
+ if (CLASS_FROM_SOURCE_P (decl_type))
+ java_check_methods (decl);
+ /* Layout the type if necessary */
+ if (decl_type != current_class && !CLASS_LOADED_P (decl_type))
+ safe_layout_class (decl_type);
return decl;
}
return 1;
}
+/* Visible interface to check methods contained in CLASS_DECL */
+
+void
+java_check_methods (class_decl)
+ tree class_decl;
+{
+ if (CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)))
+ return;
+
+ if (CLASS_INTERFACE (class_decl))
+ java_check_abstract_methods (class_decl);
+ else
+ java_check_regular_methods (class_decl);
+
+ CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)) = 1;
+}
+
/* Check all the methods of CLASS_DECL. Methods are first completed
then checked according to regular method existance rules. If no
constructor for CLASS_DECL were encountered, then build its
/* Then check the methods of all parsed classes */
for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
- CHECK_METHODS (TREE_VALUE (current));
+ java_check_methods (TREE_VALUE (current));
java_parse_abort_on_error ();
for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
instantiation using a primary qualified by a `new' */
RESTORE_THIS_AND_CURRENT_CLASS;
- /* EH check */
- if (location)
+ /* EH check. No check on access$<n> functions */
+ if (location
+ && !OUTER_FIELD_ACCESS_IDENTIFIER_P
+ (DECL_NAME (current_function_decl)))
check_thrown_exceptions (location, ret_decl);
/* If the previous call was static and this one is too,
/* Multiple instance of a case label bearing the same
value is checked during code generation. The case
expression is allright so far. */
+ if (TREE_CODE (cn) == VAR_DECL)
+ cn = DECL_INITIAL (cn);
TREE_OPERAND (node, 0) = cn;
TREE_TYPE (node) = void_type_node;
CAN_COMPLETE_NORMALLY (node) = 1;
}
}
+ /* Final locals can be used as case values in switch
+ statement. Prepare them for this eventuality. */
+ if (TREE_CODE (lvalue) == VAR_DECL
+ && LOCAL_FINAL (lvalue)
+ && TREE_CONSTANT (new_rhs)
+ && IDENTIFIER_LOCAL_VALUE (DECL_NAME (lvalue))
+ && JINTEGRAL_TYPE_P (TREE_TYPE (lvalue))
+ )
+ {
+ TREE_CONSTANT (lvalue) = 1;
+ DECL_INITIAL (lvalue) = new_rhs;
+ }
+
TREE_OPERAND (node, 0) = lvalue;
TREE_OPERAND (node, 1) = new_rhs;
TREE_TYPE (node) = lhs_type;