From 44a8d0b35727556fe4a7ac43706a3c233112fa9b Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Tue, 18 Apr 1995 19:23:38 +0000 Subject: [PATCH] 65th Cygnus<->FSF merge From-SVN: r9412 --- gcc/cp/ChangeLog | 80 ++++++++++++++++++++++++++++++++++++++++++++++ gcc/cp/Makefile.in | 2 +- gcc/cp/class.c | 19 ++++++----- gcc/cp/cp-tree.h | 2 -- gcc/cp/decl.c | 8 +++-- gcc/cp/decl2.c | 48 +++++++++++++++------------- gcc/cp/init.c | 11 ++----- gcc/cp/parse.y | 12 +++---- gcc/cp/pt.c | 29 ++++++----------- gcc/cp/repo.c | 53 ++++++++++++++++++++++++------ gcc/cp/search.c | 3 +- gcc/cp/typeck.c | 16 ++++++---- 12 files changed, 193 insertions(+), 90 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 719db74a7ae..f8268ecc521 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,83 @@ +Tue Apr 18 03:57:35 1995 Michael Meissner (meissner@cygnus.com) + + * Makefile.in (lex.o): Add dependency on c-pragma.h. + + * lex.c (handle_sysv_pragma): Use NULL_PTR and NULL_TREE as + appropriate, instead of 0. + +Mon Apr 17 12:28:42 1995 Jason Merrill + + * decl.c (pushdecl): Use decls_match, not duplicate_decls, for + comparing local and global decls. + +Fri Apr 14 01:46:52 1995 Jason Merrill + + * typeck.c (convert_arguments): Only prohibit passing to ... of + types with non-trivial copy constructors. + + * repo.c (repo_template_used): Don't try to mess with no id. + +Fri Apr 14 23:32:50 1995 Per Bothner + + * decl.c (duplicate_decls): Use cp_warning_at for redundant-decls. + +Thu Apr 13 15:37:42 1995 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-tree.h (current_tinst_level): Delete declaration, since it's + static inside pt.c. + + * typeck.c (build_modify_expr): Catch incompatible array assignment. + + * parse.y (attribute_list, attrib): Rewrite actions to feed the + right stuff to decl_attributes. + +Thu Apr 13 11:24:10 1995 Jason Merrill + + * search.c (dfs_debug_mark): Check for magic virtual like + import_export_vtable. + + * typeck.c (build_binary_op_nodefault): Don't call cp_pedwarn with + four args. + +Wed Apr 12 12:02:57 1995 Jason Merrill + + * decl2.c (finish_file): Move prevtable pass before needs_messing_up + decision. + +Tue Apr 11 11:20:27 1995 Jason Merrill + + * decl.c (finish_decl): If we're writing out a static data member of + a class, we want the debug info for that class. + + * gc.c (build_t_desc): Check linkage of a class properly. + + * class.c (finish_struct): Set the 'headof' offset for the main + vtable properly. + (prepare_fresh_vtable): Fix typeinfo pointer here. + (modify_one_vtable): Instead of here. + +Mon Apr 10 12:15:59 1995 Jason Merrill + + * repo.c (repo_get_id): New function to return the interesting + identifier for a repo entity. + (repo_template_used): Use it. + (repo_template_instantiated): Mark the id as chosen. + (init_repo): Record whether or not the id was chosen. + (finish_repo): Note if an id was newly chosen. + + * pt.c (do_function_instantiation): Call repo_template_instantiated. + (do_type_instantiation): Ditto. Don't diagnose multiple + instantiation. + + * decl2.c (finish_file): Use DECL_NOT_REALLY_EXTERN when deciding + whether or not to synthesize a method. + + Undo these changes: + * class.c (finish_vtbls): build more vtables if flag_rtti is on. + * class.c (modify_all_direct_vtables): ditto. + * init.c (expand_direct_vtbls_init): expand more vtables if + flag_rtti is on. + Sat Apr 8 17:45:41 1995 Mike Stump * gc.c (build_headof): Use ptrdiff_type_node instead of diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in index 52f6186c33c..4ef9c0a6c44 100644 --- a/gcc/cp/Makefile.in +++ b/gcc/cp/Makefile.in @@ -247,7 +247,7 @@ pt.o : pt.c $(CONFIG_H) $(CXX_TREE_H) decl.h $(PARSE_H) error.o : error.c $(CONFIG_H) $(CXX_TREE_H) errfn.o : errfn.c $(CONFIG_H) $(CXX_TREE_H) sig.o : sig.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h -repo.o : repo.c $(CONFIG.H) $(CXX_TREE_H) +repo.o : repo.c $(CONFIG_H) $(CXX_TREE_H) # These exist for maintenance purposes. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index d6e23156dc6..a4d9b6b170c 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -691,7 +691,7 @@ prepare_fresh_vtable (binfo, for_type) if (flag_rtti) TREE_VALUE (BINFO_VIRTUALS (binfo)) = build_vtable_entry (size_binop (MINUS_EXPR, integer_zero_node, offset), - FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (BINFO_VIRTUALS (binfo)))); + build_t_desc (for_type, 0)); #ifdef GATHER_STATISTICS n_vtables += 1; @@ -2115,7 +2115,7 @@ finish_vtbls (binfo, do_self, t) { base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t)); } - finish_vtbls (base_binfo, (is_not_base_vtable || flag_rtti), t); + finish_vtbls (base_binfo, is_not_base_vtable, t); } } @@ -2250,11 +2250,6 @@ modify_one_vtable (binfo, t, fndecl, pfn) if (! BINFO_NEW_VTABLE_MARKED (binfo)) prepare_fresh_vtable (binfo, t); } - old_rtti = get_vtable_entry_n (BINFO_VIRTUALS (binfo), 0); - if (old_rtti) - TREE_VALUE (old_rtti) = build_vtable_entry ( - DELTA_FROM_VTABLE_ENTRY (TREE_VALUE (old_rtti)), - build_t_desc (t, 0)); } if (fndecl == NULL_TREE) return; @@ -2343,7 +2338,7 @@ modify_all_direct_vtables (binfo, do_self, t, fndecl, pfn) int is_not_base_vtable = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); if (! TREE_VIA_VIRTUAL (base_binfo)) - modify_all_direct_vtables (base_binfo, (is_not_base_vtable || flag_rtti), t, fndecl, pfn); + modify_all_direct_vtables (base_binfo, is_not_base_vtable, t, fndecl, pfn); } } @@ -3794,8 +3789,12 @@ finish_struct (t, list_of_fieldlists, warn_anon) /* Update the rtti pointer for this class. */ if (flag_rtti) - TREE_VALUE (TYPE_BINFO_VIRTUALS (t)) - = build_vtable_entry (integer_zero_node, build_t_desc (t, 0)); + { + tree offset = get_derived_offset (TYPE_BINFO (t), NULL_TREE); + offset = size_binop (MINUS_EXPR, integer_zero_node, offset); + TREE_VALUE (TYPE_BINFO_VIRTUALS (t)) + = build_vtable_entry (offset, build_t_desc (t, 0)); + } } /* If this type has basetypes with constructors, then those diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5dd853aff73..a5f761baab3 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1500,8 +1500,6 @@ struct tinst_level struct tinst_level *next; }; -extern struct tinst_level *current_tinst_level; - /* in class.c */ extern tree current_class_name; extern tree current_class_type; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 86534edeff8..d288048f4b5 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2395,7 +2395,7 @@ duplicate_decls (newdecl, olddecl) && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl))) { cp_warning ("redundant redeclaration of `%D' in same scope", newdecl); - cp_warning ("previous declaration of `%D'", olddecl); + cp_warning_at ("previous declaration of `%D'", olddecl); } /* Copy all the DECL_... slots specified in the new decl @@ -2971,7 +2971,7 @@ pushdecl (x) && TREE_CODE (oldglobal) == FUNCTION_DECL) { /* We have one. Their types must agree. */ - if (duplicate_decls (x, oldglobal)) + if (decls_match (x, oldglobal)) /* OK */; else { @@ -6231,6 +6231,10 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags) /* Let debugger know it should output info for this type. */ note_debug_info_needed (ttype); + if (TREE_STATIC (decl) && DECL_CONTEXT (decl) + && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't') + note_debug_info_needed (DECL_CONTEXT (decl)); + if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl)) && DECL_SIZE (decl) != NULL_TREE && ! TREE_CONSTANT (DECL_SIZE (decl))) diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index bb2bf538c42..7e3528c7ee0 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2794,7 +2794,7 @@ finish_file () int start_time, this_time; tree fnname; - tree vars = static_aggregates; + tree vars; int needs_cleaning = 0, needs_messing_up = 0; if (flag_detailed_statistics) @@ -2810,27 +2810,6 @@ finish_file () we'll need here. */ push_lang_context (lang_name_c); - if (static_ctors || vars || might_have_exceptions_p ()) - needs_messing_up = 1; - if (static_dtors) - needs_cleaning = 1; - - /* See if we really need the hassle. */ - while (vars && needs_cleaning == 0) - { - tree decl = TREE_VALUE (vars); - tree type = TREE_TYPE (decl); - if (TYPE_NEEDS_DESTRUCTOR (type)) - { - needs_cleaning = 1; - needs_messing_up = 1; - break; - } - else - needs_messing_up |= TYPE_NEEDS_CONSTRUCTING (type); - vars = TREE_CHAIN (vars); - } - /* Otherwise, GDB can get confused, because in only knows about source for LINENO-1 lines. */ lineno -= 1; @@ -2867,6 +2846,29 @@ finish_file () that we can pick up any other tdecls that those routines need. */ walk_vtables ((void (*)())0, finish_prevtable_vardecl); + vars = static_aggregates; + + if (static_ctors || vars || might_have_exceptions_p ()) + needs_messing_up = 1; + if (static_dtors) + needs_cleaning = 1; + + /* See if we really need the hassle. */ + while (vars && needs_cleaning == 0) + { + tree decl = TREE_VALUE (vars); + tree type = TREE_TYPE (decl); + if (TYPE_NEEDS_DESTRUCTOR (type)) + { + needs_cleaning = 1; + needs_messing_up = 1; + break; + } + else + needs_messing_up |= TYPE_NEEDS_CONSTRUCTING (type); + vars = TREE_CHAIN (vars); + } + if (needs_cleaning == 0) goto mess_up; @@ -3101,7 +3103,7 @@ finish_file () if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl)) { if (TREE_USED (decl) - || (TREE_PUBLIC (decl) && ! DECL_EXTERNAL (decl))) + || (TREE_PUBLIC (decl) && DECL_NOT_REALLY_EXTERN (decl))) synthesize_method (decl); else { diff --git a/gcc/cp/init.c b/gcc/cp/init.c index ee99ba2eb56..b601d3d18b8 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -125,7 +125,6 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr) tree real_binfos = BINFO_BASETYPES (real_binfo); tree binfos = BINFO_BASETYPES (binfo); int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0; - int has_expanded = 0; for (i = 0; i < n_baselinks; i++) { @@ -134,12 +133,8 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr) int is_not_base_vtable = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo)); if (! TREE_VIA_VIRTUAL (real_base_binfo)) - { - expand_direct_vtbls_init (real_base_binfo, base_binfo, - (is_not_base_vtable || flag_rtti), can_elide, addr); - if (is_not_base_vtable && flag_rtti) - has_expanded = 1; - } + expand_direct_vtbls_init (real_base_binfo, base_binfo, + is_not_base_vtable, can_elide, addr); } #if 0 /* Before turning this on, make sure it is correct. */ @@ -147,7 +142,7 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr) return; #endif /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (init_self && !has_expanded && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo))) + if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo))) { tree base_ptr = convert_pointer_to_real (binfo, addr); expand_virtual_init (real_binfo, base_ptr); diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index b28d9a137bd..48c2ae87321 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -2085,22 +2085,22 @@ attribute: attribute_list: attrib - { $$ = build_tree_list (NULL_TREE, $1); } + { $$ = $1; } | attribute_list ',' attrib - { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } + { $$ = chainon ($1, $3); } ; attrib: /* empty */ { $$ = NULL_TREE; } | any_word - { $$ = $1; } + { $$ = build_tree_list ($1, NULL_TREE); } | any_word '(' IDENTIFIER ')' - { $$ = tree_cons ($1, NULL_TREE, build_tree_list (NULL_TREE, $3)); } + { $$ = build_tree_list ($1, build_tree_list (NULL_TREE, $3)); } | any_word '(' IDENTIFIER ',' nonnull_exprlist ')' - { $$ = tree_cons ($1, NULL_TREE, tree_cons (NULL_TREE, $3, $5)); } + { $$ = build_tree_list ($1, tree_cons (NULL_TREE, $3, $5)); } | any_word '(' nonnull_exprlist ')' - { $$ = tree_cons ($1, NULL_TREE, $3); } + { $$ = build_tree_list ($1, $3); } ; /* This still leaves out most reserved keywords, diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5b5dceb7962..f7ec05d0913 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2559,6 +2559,7 @@ do_function_instantiation (declspecs, declarator, storage) cp_error ("storage class `%D' applied to template instantiation", storage); mark_function_instantiated (result, extern_p); + repo_template_instantiated (result, extern_p); } void @@ -2608,15 +2609,15 @@ do_type_instantiation (name, storage) } /* We've already instantiated this. */ - if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t)) - { - if (! extern_p) - cp_pedwarn ("multiple explicit instantiation of `%#T'", t); - return; - } + if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t) + && extern_p) + return; if (! CLASSTYPE_TEMPLATE_SPECIALIZATION (t)) - mark_class_instantiated (t, extern_p); + { + mark_class_instantiated (t, extern_p); + repo_template_instantiated (t, extern_p); + } { tree tmp; @@ -2632,18 +2633,8 @@ do_type_instantiation (name, storage) tmp = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0); for (; tmp; tmp = TREE_CHAIN (tmp)) { - if (DECL_TEMPLATE_SPECIALIZATION (tmp) - || (DECL_USE_TEMPLATE (tmp) == 0 - && CLASSTYPE_TEMPLATE_SPECIALIZATION (t))) - continue; - - SET_DECL_EXPLICIT_INSTANTIATION (tmp); - TREE_PUBLIC (tmp) = 1; - if (! extern_p) - { - DECL_INTERFACE_KNOWN (tmp) = 1; - DECL_NOT_REALLY_EXTERN (tmp) = 1; - } + mark_function_instantiated (tmp, extern_p); + repo_template_instantiated (tmp, extern_p); } #if 0 diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c index bc27a27cbcb..6b5f2496948 100644 --- a/gcc/cp/repo.c +++ b/gcc/cp/repo.c @@ -79,6 +79,19 @@ repo_class_defined (t) tree t; {} +tree +repo_get_id (t) + tree t; +{ + if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') + { + t = TYPE_BINFO_VTABLE (t); + if (t == NULL_TREE) + return t; + } + return DECL_ASSEMBLER_NAME (t); +} + /* Note that a template has been used. If we can see the definition, offer to emit it. */ @@ -91,18 +104,17 @@ repo_template_used (t) if (! flag_use_repository) return; + id = repo_get_id (t); + if (id == NULL_TREE) + return; + if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') { - id = TYPE_BINFO_VTABLE (t); - if (id == NULL_TREE) - return; - id = DECL_ASSEMBLER_NAME (id); if (IDENTIFIER_REPO_CHOSEN (id)) mark_class_instantiated (t, 0); } else if (TREE_CODE_CLASS (TREE_CODE (t)) == 'd') { - id = DECL_ASSEMBLER_NAME (t); if (IDENTIFIER_REPO_CHOSEN (id)) mark_function_instantiated (t, 0); } @@ -157,6 +169,19 @@ repo_tinfo_used (ti) { } +void +repo_template_instantiated (t, extern_p) + tree t; + int extern_p; +{ + if (! extern_p) + { + tree id = repo_get_id (t); + if (id) + IDENTIFIER_REPO_CHOSEN (id) = 1; + } +} + static char * save_string (s, len) char *s; @@ -270,15 +295,21 @@ init_repo (filename) case 'O': { char *q; - tree id; + tree id, orig; for (q = &buf[2]; *q && *q != ' ' && *q != '\n'; ++q) ; q = save_string (&buf[2], q - &buf[2]); id = get_identifier (q); if (buf[0] == 'C') - IDENTIFIER_REPO_CHOSEN (id) = 1; - original_repo = perm_tree_cons (NULL_TREE, id, original_repo); + { + IDENTIFIER_REPO_CHOSEN (id) = 1; + orig = integer_one_node; + } + else + orig = NULL_TREE; + + original_repo = perm_tree_cons (orig, id, original_repo); } break; default: @@ -315,11 +346,13 @@ finish_repo () /* Do we have to write out a new info file? */ - /* Are there any old templates that aren't used any longer? */ + /* Are there any old templates that aren't used any longer or that are + newly chosen? */ for (t = original_repo; t; t = TREE_CHAIN (t)) { - if (! IDENTIFIER_REPO_USED (TREE_VALUE (t))) + if (! IDENTIFIER_REPO_USED (TREE_VALUE (t)) + || (! TREE_PURPOSE (t) && IDENTIFIER_REPO_CHOSEN (TREE_VALUE (t)))) { repo_changed = 1; break; diff --git a/gcc/cp/search.c b/gcc/cp/search.c index c0f2f2f8771..7d7d2ff5a55 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2427,8 +2427,7 @@ dfs_debug_mark (binfo) while (methods) { if (DECL_VINDEX (methods) - && DECL_SAVED_INSNS (methods) == 0 - && DECL_PENDING_INLINE_INFO (methods) == 0 + && DECL_THIS_INLINE (methods) == 0 && DECL_ABSTRACT_VIRTUAL_P (methods) == 0) { /* Somebody, somewhere is going to have to define this diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d26be492652..0384d7abff0 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2665,8 +2665,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) /* Convert `float' to `double'. */ result = tree_cons (NULL_TREE, convert (double_type_node, val), result); else if (TYPE_LANG_SPECIFIC (TREE_TYPE (val)) - && (TYPE_HAS_INIT_REF (TREE_TYPE (val)) - || TYPE_HAS_ASSIGN_REF (TREE_TYPE (val)))) + && (! TYPE_HAS_INIT_REF (TREE_TYPE (val)) + || TYPE_HAS_COMPLEX_INIT_REF (TREE_TYPE (val)))) { cp_warning ("cannot pass objects of type `%T' through `...'", TREE_TYPE (val)); @@ -3147,11 +3147,6 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) && tree_int_cst_lt (TYPE_SIZE (type1), TYPE_SIZE (type0))) pedwarn ("ANSI C++ forbids comparison of `void *' with function pointer"); } - else if ((TYPE_SIZE (tt0) != 0) != (TYPE_SIZE (tt1) != 0)) - cp_pedwarn ("comparison of %scomplete and %scomplete pointers `%T' and `%T'", - TYPE_SIZE (tt0) == 0 ? "in" : "", - TYPE_SIZE (tt1) == 0 ? "in" : "", - type0, type1); else cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast", type0, type1); @@ -5931,6 +5926,13 @@ build_modify_expr (lhs, modifycode, rhs) { int from_array; + if (! comptypes (lhstype, TREE_TYPE (rhs), 0)) + { + cp_error ("incompatible types in assignment of `%T' to `%T'", + TREE_TYPE (rhs), lhstype); + return error_mark_node; + } + /* Allow array assignment in compiler-generated code. */ if (pedantic && ! DECL_ARTIFICIAL (current_function_decl)) pedwarn ("ANSI C++ forbids assignment of arrays");