diff options
author | Mike Stump <mrs@gcc.gnu.org> | 1996-03-08 00:38:10 +0000 |
---|---|---|
committer | Mike Stump <mrs@gcc.gnu.org> | 1996-03-08 00:38:10 +0000 |
commit | e76a26469d6b464cf25d43af1eb4f1ebbc4c72a0 (patch) | |
tree | 938d65a89cf25e2714899dccc47ec5021d7a0de1 /gcc/cp | |
parent | 838b5ca862aea53720a1a3b788a2e9f80226aa25 (diff) | |
download | gcc-e76a26469d6b464cf25d43af1eb4f1ebbc4c72a0.tar.gz |
85th Cygnus<->FSF merge
From-SVN: r11497
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 114 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 1 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 8 | ||||
-rw-r--r-- | gcc/cp/decl.c | 119 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 8 | ||||
-rw-r--r-- | gcc/cp/error.c | 31 | ||||
-rw-r--r-- | gcc/cp/gxxint.texi | 18 | ||||
-rw-r--r-- | gcc/cp/init.c | 19 | ||||
-rw-r--r-- | gcc/cp/lex.c | 6 | ||||
-rw-r--r-- | gcc/cp/method.c | 20 | ||||
-rw-r--r-- | gcc/cp/parse.y | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 17 | ||||
-rw-r--r-- | gcc/cp/sig.c | 5 | ||||
-rw-r--r-- | gcc/cp/tree.c | 54 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 18 |
17 files changed, 340 insertions, 103 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3c862ca46f4..42ac898b237 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,117 @@ +Thu Mar 7 14:11:49 1996 Jason Merrill <jason@yorick.cygnus.com> + + * tree.def: Add RETURN_INIT. + * pt.c (instantiate_decl): Handle RETURN_INIT. + * decl.c (store_return_init): Handle minimal_parse_mode. + + * tree.c (cp_build_type_variant): Just return an error_mark_node. + * decl.c (make_typename_type): Don't try to get the file and line + of an identifier. + * typeck.c (comptypes): Handle TYPENAME_TYPE. + +Wed Mar 6 18:47:50 1996 Per Bothner <bothner@kalessin.cygnus.com> + + * decl.c (poplevel): Make sure we clear out and restore old local + non-VAR_DECL values by default when they go out of scope. + +Wed Mar 6 09:57:36 1996 Jason Merrill <jason@yorick.cygnus.com> + + * method.c (build_overload_value): Use DECL_ASSEMBLER_NAME in + referring to addresses of variables and functions. + + * error.c (dump_expr): Support SIZEOF_EXPR. + + * init.c (do_friend): Use the return value of check_classfn. + + * typeck.c (convert_arguments): Call complete_type. + + * method.c (hack_identifier): After giving an error, set value to + error_mark_node. + +Tue Mar 5 16:00:15 1996 Jason Merrill <jason@yorick.cygnus.com> + + * tree.c (hack_decl_function_context): Kludge around DECL_CONTEXT + lossage for local classes. + * cp-tree.h: Declare it. + * decl.c (lookup_name_real): Evil, painful hack for local classes. + (grokfndecl): Set DECL_CLASS_CONTEXT and DECL_NO_STATIC_CHAIN here. + Use hack_decl_function_context. + (grokdeclarator): Don't set DECL_NO_STATIC_CHAIN here. + (start_function): Use hack_decl_function_context. + (finish_function): Ditto. + * method.c (synthesize_method): Ditto. + * lex.c (process_next_inline): Ditto. + (do_pending_inlines): Ditto. + * decl2.c (finish_file): Unset DECL_STATIC_FUNCTION_P when we're + done with it. + +Mon Mar 4 22:38:39 1996 Gerald Baumgartner <gb@alexander.cs.purdue.edu> + + * sig.c (build_signature_pointer_or_reference_type): Align + signature pointers/references on 8-byte boundaries so they can be + grabbed 2 words at a time on a Sparc. + +Tue Mar 5 10:21:01 1996 Jason Merrill <jason@yorick.cygnus.com> + + * method.c (hack_identifier): Requiring a static chain is now a + hard error. + * decl.c (grokdeclarator): Set DECL_NO_STATIC_CHAIN on nested + functions. + +Mon Mar 4 20:03:33 1996 Jason Merrill <jason@yorick.cygnus.com> + + * init.c (build_offset_ref): Call complete_type. + + * decl.c (pop_from_top_level): Always pop previous_class_type. + + * parse.y: Handle multiple decls in a for-init-statement. + * pt.c (tsubst_expr): Ditto. + + * pt.c (tsubst): Use tsubst_expr for the second operand of an + ARRAY_REF. + + * decl.c (maybe_push_to_top_level): Don't save previous_class_type. + (poplevel_class): Set it here. + (pop_from_top_level): Pop it here if we're returning to class scope. + * class.c (pushclass): Don't set it here. + + * decl.c (maybe_push_to_top_level): Save current_template_parms, + and clear it if !pseudo. + (pop_from_top_level): Restore it. + + * decl2.c (finish_file): Push the dummy each time we walk the list + of vtables. + + * error.c (dump_expr): Support LOOKUP_EXPR and actually do + something for CAST_EXPR. + +Mon Feb 19 14:49:18 1996 Rusty Russell <rusty@adelaide.maptek.com.au> + + * cvt.c (cp_convert): Warn about implicit conversion of the + address of a function to bool, as it is always true. + +Fri Feb 23 23:06:01 1996 Rusty Russell <rusty@adelaide.maptek.com.au> + + * typeck.c (c_expand_return): Fix warning for local externs returned. + +Mon Mar 4 15:03:11 1996 Jason Merrill <jason@yorick.cygnus.com> + + * tree.c (mapcar): Propagate const and volatile properly. + + * typeck.c (complete_type): Be sure to instantiate the + MAIN_VARIANT of the type. + + * method.c (synthesize_method): Class interface hackery does not + apply to synthesized methods. + +Mon Mar 4 14:05:23 1996 Jason Merrill <jason@yorick.cygnus.com> + + * pt.c (comp_template_args): Use comptypes rather than just + checking for TEMPLATE_TYPE_PARM equivalence. + + * typeck.c (build_x_function_call): Call complete_type before + checking TYPE_OVERLOADS_CALL_EXPR. + Mon Mar 4 18:48:30 1996 Manfred Hollstein <manfred@lts.sel.alcatel.de> * g++.c (main): Check also for new define ALT_LIBM. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index e5ce5baa224..beb333076a3 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4660,8 +4660,6 @@ pushclass (type, modify) build_mi_matrix (type); push_class_decls (type); free_mi_matrix (); - if (current_class_depth == 1) - previous_class_type = type; } else { diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index d965783188a..2a07e2ef6b7 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -137,3 +137,4 @@ DEFTREECODE (GOTO_STMT, "goto_stmt", "e", 1) DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", "e", 2) DEFTREECODE (CASE_LABEL, "case_label", "e", 2) +DEFTREECODE (RETURN_INIT, "return_init", "e", 2) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 83df1852731..49443387267 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2402,6 +2402,7 @@ extern tree build_unsave_expr PROTO((tree)); extern tree unsave_expr PROTO((tree)); extern int cp_expand_decl_cleanup PROTO((tree, tree)); extern tree get_type_decl PROTO((tree)); +extern tree hack_decl_function_context PROTO((tree)); /* in typeck.c */ extern tree condition_conversion PROTO((tree)); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index b537fdfc1a5..bd9399c79a7 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -1257,7 +1257,13 @@ cp_convert (type, expr, convtype, flags) return error_mark_node; } if (code == BOOLEAN_TYPE) - return truthvalue_conversion (e); + { + /* Common Ada/Pascal programmer's mistake. We always warn + about this since it is so bad. */ + if (TREE_CODE (expr) == FUNCTION_DECL) + cp_warning ("the address of `%D', will always be `true'", expr); + return truthvalue_conversion (e); + } return fold (convert_to_integer (type, e)); } if (code == POINTER_TYPE || code == REFERENCE_TYPE diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8e7bb51a555..c9d5c42286c 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1074,6 +1074,8 @@ poplevel (keep, reverse, functionbody) { if (TREE_CODE (link) == VAR_DECL) DECL_DEAD_FOR_LOCAL (link) = 1; + else + IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE; } /* Save declarations made in a 'for' statement so we can support pre-ANSI @@ -1084,11 +1086,16 @@ poplevel (keep, reverse, functionbody) tree id = TREE_PURPOSE (link); tree decl = IDENTIFIER_LOCAL_VALUE (id); - /* In this case keep the dead for-decl visible, - but remember what (if anything) it shadowed. */ - DECL_SHADOWED_FOR_VAR (decl) = TREE_VALUE (link); - TREE_CHAIN (decl) = outer->dead_vars_from_for; - outer->dead_vars_from_for = decl; + if (decl && DECL_DEAD_FOR_LOCAL (decl)) + { + /* In this case keep the dead for-decl visible, + but remember what (if anything) it shadowed. */ + DECL_SHADOWED_FOR_VAR (decl) = TREE_VALUE (link); + TREE_CHAIN (decl) = outer->dead_vars_from_for; + outer->dead_vars_from_for = decl; + } + else + IDENTIFIER_LOCAL_VALUE (id) = TREE_VALUE (link); } } else /* Not special for scope. */ @@ -1399,7 +1406,10 @@ poplevel_class (force) else /* Remember to save what IDENTIFIER's were bound in this scope so we can recover from cache misses. */ - previous_class_values = class_binding_level->class_shadowed; + { + previous_class_type = current_class_type; + previous_class_values = class_binding_level->class_shadowed; + } for (shadowed = level->type_shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) @@ -1730,12 +1740,12 @@ struct saved_scope { tree class_name, class_type, function_decl; tree base_init_list, member_init_list; struct binding_level *class_bindings; - tree previous_class_type, previous_class_values; tree *lang_base, *lang_stack, lang_name; int lang_stacksize; tree named_labels; int minimal_parse_mode; tree last_function_parms; + tree template_parms; }; static struct saved_scope *current_saved_scope; extern tree prev_class_type; @@ -1811,13 +1821,6 @@ maybe_push_to_top_level (pseudo) for (t = b->type_shadowed; t; t = TREE_CHAIN (t)) SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t)); } - /* Clear out class-level bindings cache. */ - if (current_binding_level == global_binding_level - && previous_class_type != NULL_TREE) - { - popclass (-1); - previous_class_type = NULL_TREE; - } s->old_binding_level = current_binding_level; current_binding_level = b; @@ -1828,8 +1831,6 @@ maybe_push_to_top_level (pseudo) s->base_init_list = current_base_init_list; s->member_init_list = current_member_init_list; s->class_bindings = class_binding_level; - s->previous_class_type = previous_class_type; - s->previous_class_values = previous_class_values; s->lang_stack = current_lang_stack; s->lang_base = current_lang_base; s->lang_stacksize = current_lang_stacksize; @@ -1837,10 +1838,10 @@ maybe_push_to_top_level (pseudo) s->named_labels = named_labels; s->minimal_parse_mode = minimal_parse_mode; s->last_function_parms = last_function_parms; + s->template_parms = current_template_parms; current_class_name = current_class_type = NULL_TREE; current_function_decl = NULL_TREE; class_binding_level = (struct binding_level *)0; - previous_class_type = NULL_TREE; current_lang_stacksize = 10; current_lang_stack = current_lang_base = (tree *) xmalloc (current_lang_stacksize * sizeof (tree)); @@ -1848,6 +1849,8 @@ maybe_push_to_top_level (pseudo) strict_prototype = strict_prototypes_lang_cplusplus; named_labels = NULL_TREE; minimal_parse_mode = 0; + if (!pseudo) + current_template_parms = NULL_TREE; s->prev = current_saved_scope; s->old_bindings = old_bindings; @@ -1869,8 +1872,12 @@ pop_from_top_level () struct saved_scope *s = current_saved_scope; tree t; + /* Clear out class-level bindings cache. */ if (previous_class_type) - previous_class_type = NULL_TREE; + { + popclass (-1); + previous_class_type = NULL_TREE; + } pop_obstacks (); @@ -1892,8 +1899,6 @@ pop_from_top_level () current_member_init_list = s->member_init_list; current_function_decl = s->function_decl; class_binding_level = s->class_bindings; - previous_class_type = s->previous_class_type; - previous_class_values = s->previous_class_values; free (current_lang_base); current_lang_base = s->lang_base; current_lang_stack = s->lang_stack; @@ -1906,6 +1911,7 @@ pop_from_top_level () named_labels = s->named_labels; minimal_parse_mode = s->minimal_parse_mode; last_function_parms = s->last_function_parms; + current_template_parms = s->template_parms; free (s); } @@ -4317,7 +4323,7 @@ make_typename_type (context, name) t = lookup_field (context, name, 0, 1); if (t == NULL_TREE) { - cp_error_at ("no type matching `%#T' in `%#T'", name, context); + cp_error ("no type named `%#T' in `%#T'", name, context); return error_mark_node; } return TREE_TYPE (t); @@ -4359,6 +4365,7 @@ lookup_name_real (name, prefer_type, nonclass) register tree val; int yylex = 0; tree from_obj = NULL_TREE; + tree locval, classval; if (prefer_type == -2) { @@ -4425,30 +4432,59 @@ lookup_name_real (name, prefer_type, nonclass) else if (got_object && val && TREE_CODE (val) == TYPE_DECL) from_obj = val; } - + + locval = classval = NULL_TREE; + if (current_binding_level != global_binding_level && IDENTIFIER_LOCAL_VALUE (name)) - val = IDENTIFIER_LOCAL_VALUE (name); + locval = IDENTIFIER_LOCAL_VALUE (name); + /* In C++ class fields are between local and global scope, just before the global scope. */ - else if (current_class_type && ! nonclass) + if (current_class_type && ! nonclass) { - val = IDENTIFIER_CLASS_VALUE (name); - if (val == NULL_TREE && TYPE_BEING_DEFINED (current_class_type)) + classval = IDENTIFIER_CLASS_VALUE (name); + if (classval == NULL_TREE && TYPE_BEING_DEFINED (current_class_type)) /* Try to find values from base classes if we are presently defining a type. We are presently only interested in TYPE_DECLs. */ - val = lookup_field (current_class_type, name, 0, 1); + classval = lookup_field (current_class_type, name, 0, 1); /* yylex() calls this with -2, since we should never start digging for the nested name at the point where we haven't even, for example, created the COMPONENT_REF or anything like that. */ - if (val == NULL_TREE) - val = lookup_nested_field (name, ! yylex); + if (classval == NULL_TREE) + classval = lookup_nested_field (name, ! yylex); + } - if (val == NULL_TREE) - val = IDENTIFIER_GLOBAL_VALUE (name); + if (locval && classval) + { + if (current_scope () == current_function_decl + && ! hack_decl_function_context (current_function_decl)) + /* Not in a nested function. */ + val = locval; + else + { + /* This is incredibly horrible. The whole concept of + IDENTIFIER_LOCAL_VALUE / IDENTIFIER_CLASS_VALUE / + IDENTIFIER_GLOBAL_VALUE needs to be scrapped for local + classes. */ + tree lctx = hack_decl_function_context (locval); + tree cctx = hack_decl_function_context (classval); + + if (lctx == current_scope ()) + val = locval; + else if (lctx == cctx) + val = classval; + else + /* I don't know which is right; let's just guess for now. */ + val = locval; + } } + else if (locval) + val = locval; + else if (classval) + val = classval; else val = IDENTIFIER_GLOBAL_VALUE (name); @@ -7085,9 +7121,11 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals, { DECL_STATIC_FUNCTION_P (decl) = 1; DECL_CONTEXT (decl) = ctype; - DECL_CLASS_CONTEXT (decl) = ctype; } + if (ctype) + DECL_CLASS_CONTEXT (decl) = ctype; + /* All function decls start out public; we'll fix their linkage later (at definition or EOF) if appropriate. */ TREE_PUBLIC (decl) = 1; @@ -7119,6 +7157,9 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals, if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))) grok_op_properties (decl, virtualp, check < 0); + if (ctype && hack_decl_function_context (decl)) + DECL_NO_STATIC_CHAIN (decl) = 1; + /* Caller will do the rest of this. */ if (check < 0) return decl; @@ -11092,7 +11133,7 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p) if ((DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1)) && ! DECL_INTERFACE_KNOWN (decl1) /* Don't try to defer nested functions for now. */ - && ! decl_function_context (decl1)) + && ! hack_decl_function_context (decl1)) DECL_DEFER_OUTPUT (decl1) = 1; else { @@ -11425,8 +11466,7 @@ store_return_init (return_id, init) DECL_ASSEMBLER_NAME (decl) = return_id; } else - error ("return identifier `%s' already in place", - IDENTIFIER_POINTER (DECL_NAME (decl))); + cp_error ("return identifier `%D' already in place", decl); } /* Can't let this happen for constructors. */ @@ -11450,7 +11490,12 @@ store_return_init (return_id, init) /* Let `cp_finish_decl' know that this initializer is ok. */ DECL_INITIAL (decl) = init; pushdecl (decl); - cp_finish_decl (decl, init, NULL_TREE, 0, LOOKUP_ONLYCONVERTING); + + if (minimal_parse_mode) + add_tree (build_min_nt (RETURN_INIT, return_id, + copy_to_permanent (init))); + else + cp_finish_decl (decl, init, NULL_TREE, 0, LOOKUP_ONLYCONVERTING); } } @@ -11485,7 +11530,7 @@ finish_function (lineno, call_poplevel, nested) if (fndecl == NULL_TREE) return; - if (! nested && decl_function_context (fndecl) != NULL_TREE) + if (! nested && hack_decl_function_context (fndecl) != NULL_TREE) nested = 1; fntype = TREE_TYPE (fndecl); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index e137f7e6acb..23926d62cd2 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2991,6 +2991,7 @@ finish_file () expand_assignment (decl, init, 0, 0); DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE; + DECL_STATIC_FUNCTION_P (current_function_decl) = 0; } else if (TREE_CODE (decl) == SAVE_EXPR) { @@ -3099,6 +3100,13 @@ finish_file () tree *p = &saved_inlines; reconsider = 0; + /* We need to do this each time so that newly completed template + types don't wind up at the front of the list. Sigh. */ + vars = build_decl (TYPE_DECL, make_anon_name (), integer_type_node); + DECL_IGNORED_P (vars) = 1; + SET_DECL_ARTIFICIAL (vars); + pushdecl (vars); + walk_vtables ((void (*)())0, finish_vtable_vardecl); while (*p) diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 99f72fba9df..7931ede3d9d 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1285,7 +1285,36 @@ dump_expr (t, nop) break; case CAST_EXPR: - break; /* XXX */ + if (TREE_CHAIN (TREE_OPERAND (t, 0))) + { + dump_type (TREE_TYPE (t), 0); + OB_PUTC ('('); + dump_expr_list (TREE_OPERAND (t, 0), 0); + OB_PUTC (')'); + } + else + { + OB_PUTC ('('); + dump_type (TREE_TYPE (t), 0); + OB_PUTC (')'); + OB_PUTC ('('); + dump_expr_list (TREE_OPERAND (t, 0)); + OB_PUTC (')'); + } + break; + + case LOOKUP_EXPR: + OB_PUTID (TREE_OPERAND (t, 0)); + break; + + case SIZEOF_EXPR: + OB_PUTS ("sizeof ("); + if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't') + dump_type (TREE_OPERAND (t, 0), 0); + else + dump_unary_op ("*", t, 0); + OB_PUTC (')'); + break; case TREE_LIST: if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL) diff --git a/gcc/cp/gxxint.texi b/gcc/cp/gxxint.texi index 54581f283ea..64ffb84068a 100644 --- a/gcc/cp/gxxint.texi +++ b/gcc/cp/gxxint.texi @@ -1169,9 +1169,10 @@ thrown is used instead. All code that originates exceptions, even code that throws exceptions as a side effect, like dynamic casting, and all code that catches exceptions must be compiled with either -frtti, or -fno-rtti. It is not possible to mix rtti base exception handling -objects with code that doesn't use rtti. The exceptions to this, are -code that doesn't catch or throw exceptions, catch (...), and code that -just rethrows an exception. +objects with code that doesn't use rtti. Also, -frtti can alter the +binary layout of classes, so mixing -frtti code and -fno-rtti code can +be dangerous. The exceptions to this, are code that doesn't catch or +throw exceptions, catch (...), and code that just rethrows an exception. Currently we use the normal mangling used in building functions names (int's are "i", const char * is PCc) to build the non-rtti base type @@ -1225,9 +1226,14 @@ stands. Only exact type matching or reference matching of throw types works when -fno-rtti is used. Only works on a SPARC (like Suns), i386, arm, -rs6000, Alpha and mips machines. Partial support is in for all other -machines, but a stack unwinder called __unwind_function has to be -written, and added to libgcc2 for them. See below for details on +rs6000, PowerPC, Alpha, mips and VAX machines. Partial support is in +for all other machines, but a stack unwinder called __unwind_function +has to be written, and added to libgcc2 for them. The new EH code +doesn't rely upon the __unwind_function for C++ code, instead it creates +per function unwinders right inside the function, unfortunately, on many +platforms the definition of RETURN_ADDR_RTX in the tm.h file for the +machine port is wrong. The HPPA has a brain dead abi that prevents +exception handling from just working. See below for details on __unwind_function. Don't expect exception handling to work right if you optimize, in fact the compiler will probably core dump. RTL_EXPRs for EH cond variables for && and || exprs should probably be wrapped in diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 036fe27fbd4..863b2ccd55a 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1815,7 +1815,7 @@ build_offset_ref (type, name) if (name == constructor_name_full (type)) name = constructor_name (type); - if (TYPE_SIZE (type) == 0) + if (TYPE_SIZE (complete_type (type)) == 0) { if (type == current_class_type) t = IDENTIFIER_CLASS_VALUE (name); @@ -2432,25 +2432,16 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag) /* This will set up DECL_ARGUMENTS for us. */ grokclassfn (ctype, cname, decl, flags, quals); if (TYPE_SIZE (ctype) != 0) - check_classfn (ctype, decl); + decl = check_classfn (ctype, decl); if (TREE_TYPE (decl) != error_mark_node) { if (TYPE_SIZE (ctype)) - { - /* We don't call pushdecl here yet, or ever on this - actual FUNCTION_DECL. We must preserve its TREE_CHAIN - until the end. */ - make_decl_rtl (decl, NULL_PTR, 1); - add_friend (current_class_type, decl); - } + add_friend (current_class_type, decl); else { - register char *classname - = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (ctype))); - - error ("member declared as friend before type `%s' defined", - classname); + cp_error ("member `%D' declared as friend before type `%T' defined", + decl, ctype); } } } diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 17cdef0abff..b42be21db33 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -1128,7 +1128,7 @@ do_pending_inlines () return; /* Now start processing the first inline function. */ - context = decl_function_context (t->fndecl); + context = hack_decl_function_context (t->fndecl); if (context) push_cp_function_context (context); if (t->len > 0) @@ -1167,7 +1167,7 @@ process_next_inline (t) { tree context; struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t); - context = decl_function_context (i->fndecl); + context = hack_decl_function_context (i->fndecl); if (context) pop_cp_function_context (context); i = i->next; @@ -1191,7 +1191,7 @@ process_next_inline (t) to_be_restored = 0; if (i && i->fndecl != NULL_TREE) { - context = decl_function_context (i->fndecl); + context = hack_decl_function_context (i->fndecl); if (context) push_cp_function_context (context); feed_input (i->buf, i->len, i->can_free ? &inline_text_obstack : 0); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 6b45ff4008e..68addefd1b3 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -539,13 +539,13 @@ build_overload_value (type, value) if (TREE_CODE (value) == VAR_DECL) { my_friendly_assert (DECL_NAME (value) != 0, 245); - build_overload_identifier (DECL_NAME (value)); + build_overload_identifier (DECL_ASSEMBLER_NAME (value)); return; } else if (TREE_CODE (value) == FUNCTION_DECL) { my_friendly_assert (DECL_NAME (value) != 0, 246); - build_overload_identifier (DECL_NAME (value)); + build_overload_identifier (DECL_ASSEMBLER_NAME (value)); return; } else @@ -1591,17 +1591,17 @@ hack_identifier (value, name) else mark_used (value); - if (pedantic - && (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL)) + if (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL) { tree context = decl_function_context (value); if (context != NULL_TREE && context != current_function_decl && ! TREE_STATIC (value)) { - cp_pedwarn ("use of %s from containing function", + cp_error ("use of %s from containing function", (TREE_CODE (value) == VAR_DECL ? "`auto' variable" : "parameter")); - cp_pedwarn_at (" `%#D' declared here", value); + cp_error_at (" `%#D' declared here", value); + value = error_mark_node; } } @@ -2265,16 +2265,13 @@ synthesize_method (fndecl) tree fndecl; { int nested = (current_function_decl != NULL_TREE); - tree context = decl_function_context (fndecl); - char *f = input_filename; + tree context = hack_decl_function_context (fndecl); tree base = DECL_CLASS_CONTEXT (fndecl); if (nested) push_cp_function_context (context); - input_filename = DECL_SOURCE_FILE (fndecl); - interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (base); - interface_only = CLASSTYPE_INTERFACE_ONLY (base); + interface_unknown = 1; start_function (NULL_TREE, fndecl, NULL_TREE, NULL_TREE, 1); store_parm_decls (); @@ -2305,7 +2302,6 @@ synthesize_method (fndecl) DECL_INLINE (fndecl) = 1; } - input_filename = f; extract_interface_info (); if (nested) pop_cp_function_context (context); diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index c53bef3b6be..1c11f283905 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -3318,7 +3318,7 @@ simple_stmt: { if (last_tree != $<ttype>2) { - TREE_OPERAND ($<ttype>2, 0) = last_tree; + TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2); TREE_CHAIN ($<ttype>2) = NULL_TREE; last_tree = $<ttype>2; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 02e2822144e..13fd6ba1fda 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -453,8 +453,7 @@ comp_template_args (oldargs, newargs) continue; if (TREE_CODE (nt) != TREE_CODE (ot)) return 0; - if (TREE_CODE (ot) == TEMPLATE_TYPE_PARM - && comptypes (ot, nt, 1)) + if (TREE_CODE_CLASS (TREE_CODE (ot)) == 't' && comptypes (ot, nt, 1)) continue; if (TREE_CODE (ot) == TEMPLATE_CONST_PARM && TEMPLATE_CONST_IDX (nt) == TEMPLATE_CONST_IDX (ot)) @@ -1775,7 +1774,7 @@ tsubst (t, args, nargs, in_decl) case ARRAY_REF: return build_parse_node (ARRAY_REF, tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl), - tsubst (TREE_OPERAND (t, 1), args, nargs, in_decl)); + tsubst_expr (TREE_OPERAND (t, 1), args, nargs, in_decl)); case CALL_EXPR: return build_parse_node @@ -2085,7 +2084,8 @@ tsubst_expr (t, args, nargs, in_decl) emit_line_note (input_filename, lineno); if (init_scope) do_pushlevel (); - tsubst_expr (TREE_OPERAND (t, 0), args, nargs, in_decl); + for (tmp = TREE_OPERAND (t, 0); tmp; tmp = TREE_CHAIN (tmp)) + tsubst_expr (tmp, args, nargs, in_decl); emit_nop (); emit_line_note (input_filename, lineno); expand_start_loop_continue_elsewhere (1); @@ -2972,6 +2972,15 @@ instantiate_decl (d) start_function (NULL_TREE, d, NULL_TREE, NULL_TREE, 1); store_parm_decls (); + if (t && TREE_CODE (t) == RETURN_INIT) + { + store_return_init + (TREE_OPERAND (t, 0), + tsubst_expr (TREE_OPERAND (t, 1), &TREE_VEC_ELT (args, 0), + TREE_VEC_LENGTH (args), tmpl)); + t = TREE_CHAIN (t); + } + if (t && TREE_CODE (t) == CTOR_INITIALIZER) { current_member_init_list diff --git a/gcc/cp/sig.c b/gcc/cp/sig.c index de687e02a58..295e3dc3aa5 100644 --- a/gcc/cp/sig.c +++ b/gcc/cp/sig.c @@ -185,7 +185,10 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp) TREE_CHAIN (optr) = sptr; TYPE_FIELDS (t) = optr; - TYPE_ALIGN (t) = TYPE_ALIGN (optr_type); + /* Allow signature pointers/references to be grabbed 2 words at a time. + For this to work on a Sparc, we need 8-byte alignment. */ + TYPE_ALIGN (t) = MAX (TYPE_ALIGN (double_type_node), + TYPE_ALIGN (optr_type)); /* A signature pointer/reference type isn't a `real' class type. */ IS_AGGR_TYPE (t) = 0; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 8fbd59bcc9c..6334f3de4cb 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -442,6 +442,9 @@ cp_build_type_variant (type, constp, volatilep) tree type; int constp, volatilep; { + if (type == error_mark_node) + return type; + if (TREE_CODE (type) == ARRAY_TYPE) { tree real_main_variant = TYPE_MAIN_VARIANT (type); @@ -1578,27 +1581,32 @@ mapcar (t, func) return t; case POINTER_TYPE: - return build_pointer_type (mapcar (TREE_TYPE (t), func)); + tmp = build_pointer_type (mapcar (TREE_TYPE (t), func)); + return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case REFERENCE_TYPE: - return build_reference_type (mapcar (TREE_TYPE (t), func)); + tmp = build_reference_type (mapcar (TREE_TYPE (t), func)); + return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case FUNCTION_TYPE: - return build_function_type (mapcar (TREE_TYPE (t), func), - mapcar (TYPE_ARG_TYPES (t), func)); + tmp = build_function_type (mapcar (TREE_TYPE (t), func), + mapcar (TYPE_ARG_TYPES (t), func)); + return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case ARRAY_TYPE: - return build_array_type (mapcar (TREE_TYPE (t), func), - mapcar (TYPE_DOMAIN (t), func)); + tmp = build_array_type (mapcar (TREE_TYPE (t), func), + mapcar (TYPE_DOMAIN (t), func)); + return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case INTEGER_TYPE: - return build_index_type (mapcar (TYPE_MAX_VALUE (t), func)); - + tmp = build_index_type (mapcar (TYPE_MAX_VALUE (t), func)); + return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case OFFSET_TYPE: - return build_offset_type (mapcar (TYPE_OFFSET_BASETYPE (t), func), - mapcar (TREE_TYPE (t), func)); + tmp = build_offset_type (mapcar (TYPE_OFFSET_BASETYPE (t), func), + mapcar (TREE_TYPE (t), func)); + return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case METHOD_TYPE: - return build_method_type - (mapcar (TYPE_METHOD_BASETYPE (t), func), - build_function_type - (mapcar (TREE_TYPE (t), func), - mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func))); + tmp = build_cplus_method_type + (mapcar (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), func), + mapcar (TREE_TYPE (t), func), + mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func)); + return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t)); case RECORD_TYPE: if (TYPE_PTRMEMFUNC_P (t)) @@ -1607,7 +1615,7 @@ mapcar (t, func) /* else fall through */ /* This list is incomplete, but should suffice for now. - It is very important that `sorry' does not call + It is very important that `sorry' not call `report_error_function'. That could cause an infinite loop. */ default: sorry ("initializer contains unrecognized tree code"); @@ -1988,3 +1996,17 @@ vec_binfo_member (elem, vec) return TREE_VEC_ELT (vec, i); return NULL_TREE; } + +/* Kludge around the fact that DECL_CONTEXT for virtual functions returns + the wrong thing for decl_function_context. Hopefully the uses in the + backend won't matter, since we don't need a static chain for local class + methods. FIXME! */ + +tree +hack_decl_function_context (decl) + tree decl; +{ + if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (decl)) + return decl_function_context (TYPE_MAIN_DECL (DECL_CLASS_CONTEXT (decl))); + return decl_function_context (decl); +} diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index e4b944b4784..c3fdb798d6b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -134,7 +134,7 @@ complete_type (type) type = build_cplus_array_type (t, TYPE_DOMAIN (type)); } else if (IS_AGGR_TYPE (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type)) - instantiate_class_template (type); + instantiate_class_template (TYPE_MAIN_VARIANT (type)); return type; } @@ -796,6 +796,11 @@ comptypes (type1, type2, strict) case TEMPLATE_TYPE_PARM: return TEMPLATE_TYPE_IDX (t1) == TEMPLATE_TYPE_IDX (t2); + + case TYPENAME_TYPE: + if (TYPE_IDENTIFIER (t1) != TYPE_IDENTIFIER (t2)) + return 0; + return comptypes (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2), 1); } return attrval == 2 && val == 1 ? 2 : val; } @@ -2350,7 +2355,8 @@ build_x_function_call (function, params, decl) if (TREE_CODE (type) == REFERENCE_TYPE) type = TREE_TYPE (type); - if (TYPE_LANG_SPECIFIC (type) && TYPE_OVERLOADS_CALL_EXPR (type)) + if (TYPE_LANG_SPECIFIC (type) + && TYPE_OVERLOADS_CALL_EXPR (complete_type (type))) return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, function, params, NULL_TREE); } @@ -2778,7 +2784,7 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) /* Formal parm type is specified by a function prototype. */ tree parmval; - if (TYPE_SIZE (type) == 0) + if (TYPE_SIZE (complete_type (type)) == 0) { error ("parameter type of called function is incomplete"); parmval = val; @@ -6920,7 +6926,8 @@ c_expand_return (retval) if (TEMP_NAME_P (DECL_NAME (whats_returned))) warning ("reference to non-lvalue returned"); else if (! TREE_STATIC (whats_returned) - && IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned))) + && IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned)) + && !TREE_PUBLIC (whats_returned)) cp_warning_at ("reference to local variable `%D' returned", whats_returned); } } @@ -6931,7 +6938,8 @@ c_expand_return (retval) if (TREE_CODE (whats_returned) == VAR_DECL && DECL_NAME (whats_returned) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned)) - && !TREE_STATIC (whats_returned)) + && !TREE_STATIC (whats_returned) + && !TREE_PUBLIC (whats_returned)) cp_warning_at ("address of local variable `%D' returned", whats_returned); } |