summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1996-03-08 00:38:10 +0000
committerMike Stump <mrs@gcc.gnu.org>1996-03-08 00:38:10 +0000
commite76a26469d6b464cf25d43af1eb4f1ebbc4c72a0 (patch)
tree938d65a89cf25e2714899dccc47ec5021d7a0de1 /gcc/cp
parent838b5ca862aea53720a1a3b788a2e9f80226aa25 (diff)
downloadgcc-e76a26469d6b464cf25d43af1eb4f1ebbc4c72a0.tar.gz
85th Cygnus<->FSF merge
From-SVN: r11497
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog114
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-tree.def1
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/cvt.c8
-rw-r--r--gcc/cp/decl.c119
-rw-r--r--gcc/cp/decl2.c8
-rw-r--r--gcc/cp/error.c31
-rw-r--r--gcc/cp/gxxint.texi18
-rw-r--r--gcc/cp/init.c19
-rw-r--r--gcc/cp/lex.c6
-rw-r--r--gcc/cp/method.c20
-rw-r--r--gcc/cp/parse.y2
-rw-r--r--gcc/cp/pt.c17
-rw-r--r--gcc/cp/sig.c5
-rw-r--r--gcc/cp/tree.c54
-rw-r--r--gcc/cp/typeck.c18
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);
}