+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.
build_mi_matrix (type);
push_class_decls (type);
free_mi_matrix ();
- if (current_class_depth == 1)
- previous_class_type = type;
}
else
{
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", "e", 2)
DEFTREECODE (CASE_LABEL, "case_label", "e", 2)
+DEFTREECODE (RETURN_INIT, "return_init", "e", 2)
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));
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
{
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
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. */
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))
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;
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;
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;
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));
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;
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 ();
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;
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);
}
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);
register tree val;
int yylex = 0;
tree from_obj = NULL_TREE;
+ tree locval, classval;
if (prefer_type == -2)
{
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);
{
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;
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;
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
{
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. */
/* 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);
}
}
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);
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)
{
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)
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)
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
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
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);
/* 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);
}
}
}
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)
{
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;
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);
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
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;
}
}
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 ();
DECL_INLINE (fndecl) = 1;
}
- input_filename = f;
extract_interface_info ();
if (nested)
pop_cp_function_context (context);
{
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;
}
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))
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
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);
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
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;
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);
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))
/* 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");
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);
+}
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;
}
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;
}
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);
}
/* 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;
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);
}
}
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);
}