Commit e920ebc9 by Alexandre Petit-Bianco Committed by Alexandre Petit-Bianco

class.c (class_depth): Return -1 if the class doesn't load properly.

1999-12-14  Alexandre Petit-Bianco  <apbianco@cygnus.com>

        * class.c (class_depth): Return -1 if the class doesn't load
        properly.
        * expr.c (can_widen_reference_to): Check for errors during depth
        computation and return 0 accordingly.
        * jcf-parse.c (parse_source_file): Call java_fix_constructors to
        create default constructors and add an other error check.
        * parse.h (java_fix_constructors): Prototyped.
        * parse.y (java_pre_expand_clinit): Likewise.
        (build_super_invocation): Re-prototyped to feature one argument.
        (java_check_circular_reference): Directly use `current'.
        (java_fix_constructors): New function.
        (java_check_regular_methods): Don't create default constructors
        here, but abort if none were found.
        (java_complete_expand_methods): Pre-process <clinit> calling
        java_pre_expand_clinit.
        (java_pre_expand_clinit): New function.
        (fix_constructors): build_super_invocation invoked with the
        current method declaration as an argument.
        (build_super_invocation): Use the context of the processed method
        decl argument instead of current_class.
        * typeck.c (lookup_java_method): Take WFLs in method names into
        account.

From-SVN: r31144
parent f0353e33
1999-12-14 Alexandre Petit-Bianco <apbianco@cygnus.com>
* class.c (class_depth): Return -1 if the class doesn't load
properly.
* expr.c (can_widen_reference_to): Check for errors during depth
computation and return 0 accordingly.
* jcf-parse.c (parse_source_file): Call java_fix_constructors to
create default constructors and add an other error check.
* parse.h (java_fix_constructors): Prototyped.
* parse.y (java_pre_expand_clinit): Likewise.
(build_super_invocation): Re-prototyped to feature one argument.
(java_check_circular_reference): Directly use `current'.
(java_fix_constructors): New function.
(java_check_regular_methods): Don't create default constructors
here, but abort if none were found.
(java_complete_expand_methods): Pre-process <clinit> calling
java_pre_expand_clinit.
(java_pre_expand_clinit): New function.
(fix_constructors): build_super_invocation invoked with the
current method declaration as an argument.
(build_super_invocation): Use the context of the processed method
decl argument instead of current_class.
* typeck.c (lookup_java_method): Take WFLs in method names into
account.
1999-12-17 Tom Tromey <tromey@cygnus.com>
* gjavah.c (decode_signature_piece): Print "::" in JArray<>. This
......
......@@ -403,6 +403,8 @@ class_depth (clas)
int depth = 0;
if (! CLASS_LOADED_P (clas))
load_class (clas, 1);
if (TYPE_SIZE (clas) == error_mark_node)
return -1;
while (clas != object_type_node)
{
depth++;
......
......@@ -386,6 +386,10 @@ can_widen_reference_to (source_type, target_type)
int source_depth = class_depth (source_type);
int target_depth = class_depth (target_type);
/* class_depth can return a negative depth if an error occurred */
if (source_depth < 0 || target_depth < 0)
return 0;
if (CLASS_INTERFACE (TYPE_NAME (target_type)))
{
/* target_type is OK if source_type or source_type ancestors
......
......@@ -756,6 +756,8 @@ parse_source_file (file)
java_parse_abort_on_error ();
java_check_circular_reference (); /* Check on circular references */
java_parse_abort_on_error ();
java_fix_constructors (); /* Fix the constructors */
java_parse_abort_on_error ();
}
static int
......
......@@ -662,6 +662,7 @@ struct parser_ctxt {
void safe_layout_class PROTO ((tree));
void java_complete_class PROTO ((void));
void java_check_circular_reference PROTO ((void));
void java_fix_constructors PROTO ((void));
void java_check_final PROTO ((void));
void java_layout_classes PROTO ((void));
tree java_method_add_stmt PROTO ((tree, tree));
......
......@@ -134,6 +134,7 @@ static tree register_incomplete_type PROTO ((int, tree, tree, tree));
static tree obtain_incomplete_type PROTO ((tree));
static tree java_complete_lhs PROTO ((tree));
static tree java_complete_tree PROTO ((tree));
static int java_pre_expand_clinit PROTO ((tree));
static void java_complete_expand_method PROTO ((tree));
static int unresolved_type_p PROTO ((tree, tree *));
static void create_jdep_list PROTO ((struct parser_ctxt *));
......@@ -216,7 +217,7 @@ static int check_thrown_exceptions_do PROTO ((tree));
static void purge_unchecked_exceptions PROTO ((tree));
static void check_throws_clauses PROTO ((tree, tree, tree));
static void finish_method_declaration PROTO ((tree));
static tree build_super_invocation PROTO ((void));
static tree build_super_invocation PROTO ((tree));
static int verify_constructor_circularity PROTO ((tree, tree));
static char *constructor_circularity_msg PROTO ((tree, tree));
static tree build_this_super_qualified_invocation PROTO ((int, tree, tree,
......@@ -3985,7 +3986,7 @@ java_check_circular_reference ()
for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
{
tree type = TREE_TYPE (current);
if (CLASS_INTERFACE (TYPE_NAME (type)))
if (CLASS_INTERFACE (current))
{
/* Check all interfaces this class extends */
tree basetype_vec = TYPE_BINFO_BASETYPES (type);
......@@ -4010,6 +4011,44 @@ java_check_circular_reference ()
}
}
/* Fix the constructors. This will be called right after circular
references have been checked. It is necessary to fix constructors
early even if no code generation will take place for that class:
some generated constructor might be required by the class whose
compilation triggered this one to be simply loaded. */
void
java_fix_constructors ()
{
tree current;
for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
{
tree decl;
tree class_type = TREE_TYPE (current);
int saw_ctor = 0;
for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
{
if (DECL_CONSTRUCTOR_P (decl))
{
fix_constructors (decl);
saw_ctor = 1;
}
}
if (!saw_ctor)
{
int flags = (get_access_flags_from_decl (current) & ACC_PUBLIC ?
ACC_PUBLIC : 0);
decl = create_artificial_method (class_type, flags, void_type_node,
init_identifier_node,
end_params_node);
DECL_CONSTRUCTOR_P (decl) = 1;
}
}
}
/* safe_layout_class just makes sure that we can load a class without
disrupting the current_class, input_file, lineno, etc, information
about the class processed currently. */
......@@ -4916,24 +4955,7 @@ java_check_regular_methods (class_decl)
java_check_abstract_method_definitions (class_decl);
if (!saw_constructor)
{
/* No constructor seen, we craft one, at line 0. Since this
operation takes place after we laid methods out
(layout_class_methods), we prepare the its DECL
appropriately. */
int flags;
tree decl;
/* If the class is declared PUBLIC, the default constructor is
PUBLIC otherwise it has default access implied by no access
modifiers. */
flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
ACC_PUBLIC : 0);
decl = create_artificial_method (class, flags, void_type_node,
init_identifier_node, end_params_node);
DECL_CONSTRUCTOR_P (decl) = 1;
layout_class_method (TREE_TYPE (class_decl), NULL_TREE, decl, NULL_TREE);
}
fatal ("No constructor found");
}
/* Return a non zero value if the `throws' clause of METHOD (if any)
......@@ -5999,7 +6021,7 @@ java_complete_expand_methods ()
{
int is_interface;
tree class_type = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
tree decl;
tree decl, prev_decl;
current_class = TREE_TYPE (current);
is_interface = CLASS_INTERFACE (TYPE_NAME (current_class));
......@@ -6008,42 +6030,21 @@ java_complete_expand_methods ()
init_outgoing_cpool ();
/* We want <clinit> (if any) to be processed first. */
decl = tree_last (TYPE_METHODS (class_type));
if (IS_CLINIT (decl))
{
tree fbody = DECL_FUNCTION_BODY (decl);
tree list;
if (fbody != NULL_TREE)
{
/* First check if we can ignore empty <clinit> */
tree block_body = BLOCK_EXPR_BODY (fbody);
current_this = NULL_TREE;
current_function_decl = decl;
if (block_body != NULL_TREE)
{
/* Prevent the use of `this' inside <clinit> */
ctxp->explicit_constructor_p = 1;
for (prev_decl = NULL_TREE, decl = TYPE_METHODS (class_type);
decl; prev_decl= decl, decl = TREE_CHAIN (decl))
if (IS_CLINIT (decl))
{
if (!java_pre_expand_clinit (decl))
{
if (prev_decl)
TREE_CHAIN (prev_decl) = TREE_CHAIN (decl);
else
TYPE_METHODS (class_type) = TREE_CHAIN (decl);
}
break;
}
block_body = java_complete_tree (block_body);
ctxp->explicit_constructor_p = 0;
BLOCK_EXPR_BODY (fbody) = block_body;
if (block_body != NULL_TREE
&& TREE_CODE (block_body) == BLOCK
&& BLOCK_EXPR_BODY (block_body) == empty_stmt_node)
decl = NULL_TREE;
}
}
list = nreverse (TREE_CHAIN (nreverse (TYPE_METHODS (class_type))));
if (decl != NULL_TREE)
{
TREE_CHAIN (decl) = list;
TYPE_METHODS (class_type) = decl;
}
else
TYPE_METHODS (class_type) = list;
}
/* Now go on for regular business. */
for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
{
current_function_decl = decl;
......@@ -6092,6 +6093,40 @@ java_complete_expand_methods ()
the list of the catch clauses of the currently analysed try block. */
static tree currently_caught_type_list;
/* Complete and expand <clinit>. Return a non zero value if <clinit>
is worth keeping. */
static int
java_pre_expand_clinit (decl)
tree decl;
{
tree fbody = DECL_FUNCTION_BODY (decl);
tree list;
int to_return = 1;
if (fbody != NULL_TREE)
{
/* First check if we can ignore empty <clinit> */
tree block_body = BLOCK_EXPR_BODY (fbody);
current_this = NULL_TREE;
current_function_decl = decl;
if (block_body != NULL_TREE)
{
/* Prevent the use of `this' inside <clinit> */
ctxp->explicit_constructor_p = 1;
block_body = java_complete_tree (block_body);
ctxp->explicit_constructor_p = 0;
BLOCK_EXPR_BODY (fbody) = block_body;
if (block_body != NULL_TREE && TREE_CODE (block_body) == BLOCK
&& BLOCK_EXPR_BODY (block_body) == empty_stmt_node)
to_return = 0;
}
}
return to_return;
}
/* Complete and expand a method. */
static void
......@@ -6197,7 +6232,7 @@ fix_constructors (mdecl)
/* We don't generate a super constructor invocation if we're
compiling java.lang.Object. build_super_invocation takes care
of that. */
compound = java_method_add_stmt (mdecl, build_super_invocation ());
compound = java_method_add_stmt (mdecl, build_super_invocation (mdecl));
end_artificial_method_body (mdecl);
}
......@@ -6229,7 +6264,7 @@ fix_constructors (mdecl)
/* The constructor is missing an invocation of super() */
if (!found)
compound = add_stmt_to_compound (compound, NULL_TREE,
build_super_invocation ());
build_super_invocation (mdecl));
/* Fix the constructor main block if we're adding extra stmts */
if (compound)
......@@ -8923,9 +8958,10 @@ maybe_absorb_scoping_blocks ()
we're currently dealing with the class java.lang.Object. */
static tree
build_super_invocation ()
build_super_invocation (mdecl)
tree mdecl;
{
if (current_class == object_type_node)
if (DECL_CONTEXT (mdecl) == object_type_node)
return empty_stmt_node;
else
{
......
......@@ -755,7 +755,10 @@ lookup_java_method (searched_class, method_name, method_signature)
method != NULL_TREE; method = TREE_CHAIN (method))
{
tree method_sig = build_java_signature (TREE_TYPE (method));
if (DECL_NAME (method) == method_name
tree name = DECL_NAME (method);
if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
EXPR_WFL_NODE (name) : name) == method_name
&& method_sig == method_signature)
return method;
}
......@@ -788,8 +791,10 @@ lookup_java_method (searched_class, method_name, method_signature)
method != NULL_TREE; method = TREE_CHAIN (method))
{
tree method_sig = build_java_signature (TREE_TYPE (method));
tree name = DECL_NAME (method);
if (DECL_NAME (method) == method_name
if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
EXPR_WFL_NODE (name) : name) == method_name
&& method_sig == method_signature)
return method;
}
......
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