From: Alexandre Petit-Bianco Date: Thu, 30 Dec 1999 22:36:25 +0000 (+0000) Subject: class.c (class_depth): Return -1 if the class doesn't load properly. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e920ebc9311d99636a40f1ff229ecd4167f46166;p=gcc.git class.c (class_depth): Return -1 if the class doesn't load properly. 1999-12-14 Alexandre Petit-Bianco * 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 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 --- diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index e0238576790..f27b2bcdbc4 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,28 @@ +1999-12-14 Alexandre Petit-Bianco + + * 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 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 * gjavah.c (decode_signature_piece): Print "::" in JArray<>. This diff --git a/gcc/java/class.c b/gcc/java/class.c index 66941bd4967..e042c131931 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -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++; diff --git a/gcc/java/expr.c b/gcc/java/expr.c index c7332a52b07..d789efb6292 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -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 diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index 2f7cc090aea..c1827893911 100644 --- a/gcc/java/jcf-parse.c +++ b/gcc/java/jcf-parse.c @@ -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 diff --git a/gcc/java/parse.h b/gcc/java/parse.h index 4d3b9ee98e3..2cfbedaf602 100644 --- a/gcc/java/parse.h +++ b/gcc/java/parse.h @@ -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)); diff --git a/gcc/java/parse.y b/gcc/java/parse.y index cb1c43de45f..e5853a7061a 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -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 (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 */ - 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 */ - 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 . Return a non zero value if + 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 */ + 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 */ + 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 { diff --git a/gcc/java/typeck.c b/gcc/java/typeck.c index 331de1c9fb6..213a3899fbc 100644 --- a/gcc/java/typeck.c +++ b/gcc/java/typeck.c @@ -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; }